progmodes/cc-fonts.el (c-font-lock-declarators): Remove check for
[emacs.git] / src / xdisp.c
blobfe16b2c6a0723d3f2df81ded924f9eb8de6a1e07
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 /* Forget any previous info about this row being reversed. */
2975 if (it->glyph_row)
2976 it->glyph_row->reversed_p = 0;
2978 /* Get the dimensions of the display area. The display area
2979 consists of the visible window area plus a horizontally scrolled
2980 part to the left of the window. All x-values are relative to the
2981 start of this total display area. */
2982 if (base_face_id != DEFAULT_FACE_ID)
2984 /* Mode lines, menu bar in terminal frames. */
2985 it->first_visible_x = 0;
2986 it->last_visible_x = WINDOW_PIXEL_WIDTH (w);
2988 else
2990 it->first_visible_x
2991 = window_hscroll_limited (it->w, it->f) * FRAME_COLUMN_WIDTH (it->f);
2992 it->last_visible_x = (it->first_visible_x
2993 + window_box_width (w, TEXT_AREA));
2995 /* If we truncate lines, leave room for the truncation glyph(s) at
2996 the right margin. Otherwise, leave room for the continuation
2997 glyph(s). Done only if the window has no fringes. Since we
2998 don't know at this point whether there will be any R2L lines in
2999 the window, we reserve space for truncation/continuation glyphs
3000 even if only one of the fringes is absent. */
3001 if (WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
3002 || (it->bidi_p && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0))
3004 if (it->line_wrap == TRUNCATE)
3005 it->last_visible_x -= it->truncation_pixel_width;
3006 else
3007 it->last_visible_x -= it->continuation_pixel_width;
3010 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
3011 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
3014 /* Leave room for a border glyph. */
3015 if (!FRAME_WINDOW_P (it->f)
3016 && !WINDOW_RIGHTMOST_P (it->w))
3017 it->last_visible_x -= 1;
3019 it->last_visible_y = window_text_bottom_y (w);
3021 /* For mode lines and alike, arrange for the first glyph having a
3022 left box line if the face specifies a box. */
3023 if (base_face_id != DEFAULT_FACE_ID)
3025 struct face *face;
3027 it->face_id = remapped_base_face_id;
3029 /* If we have a boxed mode line, make the first character appear
3030 with a left box line. */
3031 face = FACE_FROM_ID (it->f, remapped_base_face_id);
3032 if (face && face->box != FACE_NO_BOX)
3033 it->start_of_box_run_p = true;
3036 /* If a buffer position was specified, set the iterator there,
3037 getting overlays and face properties from that position. */
3038 if (charpos >= BUF_BEG (current_buffer))
3040 it->stop_charpos = charpos;
3041 it->end_charpos = ZV;
3042 eassert (charpos == BYTE_TO_CHAR (bytepos));
3043 IT_CHARPOS (*it) = charpos;
3044 IT_BYTEPOS (*it) = bytepos;
3046 /* We will rely on `reseat' to set this up properly, via
3047 handle_face_prop. */
3048 it->face_id = it->base_face_id;
3050 it->start = it->current;
3051 /* Do we need to reorder bidirectional text? Not if this is a
3052 unibyte buffer: by definition, none of the single-byte
3053 characters are strong R2L, so no reordering is needed. And
3054 bidi.c doesn't support unibyte buffers anyway. Also, don't
3055 reorder while we are loading loadup.el, since the tables of
3056 character properties needed for reordering are not yet
3057 available. */
3058 it->bidi_p =
3059 NILP (Vpurify_flag)
3060 && !NILP (BVAR (current_buffer, bidi_display_reordering))
3061 && it->multibyte_p;
3063 /* If we are to reorder bidirectional text, init the bidi
3064 iterator. */
3065 if (it->bidi_p)
3067 /* Note the paragraph direction that this buffer wants to
3068 use. */
3069 if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
3070 Qleft_to_right))
3071 it->paragraph_embedding = L2R;
3072 else if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
3073 Qright_to_left))
3074 it->paragraph_embedding = R2L;
3075 else
3076 it->paragraph_embedding = NEUTRAL_DIR;
3077 bidi_unshelve_cache (NULL, 0);
3078 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
3079 &it->bidi_it);
3082 /* Compute faces etc. */
3083 reseat (it, it->current.pos, 1);
3086 CHECK_IT (it);
3090 /* Initialize IT for the display of window W with window start POS. */
3092 void
3093 start_display (struct it *it, struct window *w, struct text_pos pos)
3095 struct glyph_row *row;
3096 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
3098 row = w->desired_matrix->rows + first_vpos;
3099 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
3100 it->first_vpos = first_vpos;
3102 /* Don't reseat to previous visible line start if current start
3103 position is in a string or image. */
3104 if (it->method == GET_FROM_BUFFER && it->line_wrap != TRUNCATE)
3106 int start_at_line_beg_p;
3107 int first_y = it->current_y;
3109 /* If window start is not at a line start, skip forward to POS to
3110 get the correct continuation lines width. */
3111 start_at_line_beg_p = (CHARPOS (pos) == BEGV
3112 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
3113 if (!start_at_line_beg_p)
3115 int new_x;
3117 reseat_at_previous_visible_line_start (it);
3118 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
3120 new_x = it->current_x + it->pixel_width;
3122 /* If lines are continued, this line may end in the middle
3123 of a multi-glyph character (e.g. a control character
3124 displayed as \003, or in the middle of an overlay
3125 string). In this case move_it_to above will not have
3126 taken us to the start of the continuation line but to the
3127 end of the continued line. */
3128 if (it->current_x > 0
3129 && it->line_wrap != TRUNCATE /* Lines are continued. */
3130 && (/* And glyph doesn't fit on the line. */
3131 new_x > it->last_visible_x
3132 /* Or it fits exactly and we're on a window
3133 system frame. */
3134 || (new_x == it->last_visible_x
3135 && FRAME_WINDOW_P (it->f)
3136 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
3137 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
3138 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
3140 if ((it->current.dpvec_index >= 0
3141 || it->current.overlay_string_index >= 0)
3142 /* If we are on a newline from a display vector or
3143 overlay string, then we are already at the end of
3144 a screen line; no need to go to the next line in
3145 that case, as this line is not really continued.
3146 (If we do go to the next line, C-e will not DTRT.) */
3147 && it->c != '\n')
3149 set_iterator_to_next (it, 1);
3150 move_it_in_display_line_to (it, -1, -1, 0);
3153 it->continuation_lines_width += it->current_x;
3155 /* If the character at POS is displayed via a display
3156 vector, move_it_to above stops at the final glyph of
3157 IT->dpvec. To make the caller redisplay that character
3158 again (a.k.a. start at POS), we need to reset the
3159 dpvec_index to the beginning of IT->dpvec. */
3160 else if (it->current.dpvec_index >= 0)
3161 it->current.dpvec_index = 0;
3163 /* We're starting a new display line, not affected by the
3164 height of the continued line, so clear the appropriate
3165 fields in the iterator structure. */
3166 it->max_ascent = it->max_descent = 0;
3167 it->max_phys_ascent = it->max_phys_descent = 0;
3169 it->current_y = first_y;
3170 it->vpos = 0;
3171 it->current_x = it->hpos = 0;
3177 /* Return 1 if POS is a position in ellipses displayed for invisible
3178 text. W is the window we display, for text property lookup. */
3180 static int
3181 in_ellipses_for_invisible_text_p (struct display_pos *pos, struct window *w)
3183 Lisp_Object prop, window;
3184 int ellipses_p = 0;
3185 ptrdiff_t charpos = CHARPOS (pos->pos);
3187 /* If POS specifies a position in a display vector, this might
3188 be for an ellipsis displayed for invisible text. We won't
3189 get the iterator set up for delivering that ellipsis unless
3190 we make sure that it gets aware of the invisible text. */
3191 if (pos->dpvec_index >= 0
3192 && pos->overlay_string_index < 0
3193 && CHARPOS (pos->string_pos) < 0
3194 && charpos > BEGV
3195 && (XSETWINDOW (window, w),
3196 prop = Fget_char_property (make_number (charpos),
3197 Qinvisible, window),
3198 !TEXT_PROP_MEANS_INVISIBLE (prop)))
3200 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
3201 window);
3202 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
3205 return ellipses_p;
3209 /* Initialize IT for stepping through current_buffer in window W,
3210 starting at position POS that includes overlay string and display
3211 vector/ control character translation position information. Value
3212 is zero if there are overlay strings with newlines at POS. */
3214 static int
3215 init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos)
3217 ptrdiff_t charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
3218 int i, overlay_strings_with_newlines = 0;
3220 /* If POS specifies a position in a display vector, this might
3221 be for an ellipsis displayed for invisible text. We won't
3222 get the iterator set up for delivering that ellipsis unless
3223 we make sure that it gets aware of the invisible text. */
3224 if (in_ellipses_for_invisible_text_p (pos, w))
3226 --charpos;
3227 bytepos = 0;
3230 /* Keep in mind: the call to reseat in init_iterator skips invisible
3231 text, so we might end up at a position different from POS. This
3232 is only a problem when POS is a row start after a newline and an
3233 overlay starts there with an after-string, and the overlay has an
3234 invisible property. Since we don't skip invisible text in
3235 display_line and elsewhere immediately after consuming the
3236 newline before the row start, such a POS will not be in a string,
3237 but the call to init_iterator below will move us to the
3238 after-string. */
3239 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
3241 /* This only scans the current chunk -- it should scan all chunks.
3242 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
3243 to 16 in 22.1 to make this a lesser problem. */
3244 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
3246 const char *s = SSDATA (it->overlay_strings[i]);
3247 const char *e = s + SBYTES (it->overlay_strings[i]);
3249 while (s < e && *s != '\n')
3250 ++s;
3252 if (s < e)
3254 overlay_strings_with_newlines = 1;
3255 break;
3259 /* If position is within an overlay string, set up IT to the right
3260 overlay string. */
3261 if (pos->overlay_string_index >= 0)
3263 int relative_index;
3265 /* If the first overlay string happens to have a `display'
3266 property for an image, the iterator will be set up for that
3267 image, and we have to undo that setup first before we can
3268 correct the overlay string index. */
3269 if (it->method == GET_FROM_IMAGE)
3270 pop_it (it);
3272 /* We already have the first chunk of overlay strings in
3273 IT->overlay_strings. Load more until the one for
3274 pos->overlay_string_index is in IT->overlay_strings. */
3275 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
3277 ptrdiff_t n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
3278 it->current.overlay_string_index = 0;
3279 while (n--)
3281 load_overlay_strings (it, 0);
3282 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
3286 it->current.overlay_string_index = pos->overlay_string_index;
3287 relative_index = (it->current.overlay_string_index
3288 % OVERLAY_STRING_CHUNK_SIZE);
3289 it->string = it->overlay_strings[relative_index];
3290 eassert (STRINGP (it->string));
3291 it->current.string_pos = pos->string_pos;
3292 it->method = GET_FROM_STRING;
3293 it->end_charpos = SCHARS (it->string);
3294 /* Set up the bidi iterator for this overlay string. */
3295 if (it->bidi_p)
3297 it->bidi_it.string.lstring = it->string;
3298 it->bidi_it.string.s = NULL;
3299 it->bidi_it.string.schars = SCHARS (it->string);
3300 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
3301 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
3302 it->bidi_it.string.unibyte = !it->multibyte_p;
3303 it->bidi_it.w = it->w;
3304 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3305 FRAME_WINDOW_P (it->f), &it->bidi_it);
3307 /* Synchronize the state of the bidi iterator with
3308 pos->string_pos. For any string position other than
3309 zero, this will be done automagically when we resume
3310 iteration over the string and get_visually_first_element
3311 is called. But if string_pos is zero, and the string is
3312 to be reordered for display, we need to resync manually,
3313 since it could be that the iteration state recorded in
3314 pos ended at string_pos of 0 moving backwards in string. */
3315 if (CHARPOS (pos->string_pos) == 0)
3317 get_visually_first_element (it);
3318 if (IT_STRING_CHARPOS (*it) != 0)
3319 do {
3320 /* Paranoia. */
3321 eassert (it->bidi_it.charpos < it->bidi_it.string.schars);
3322 bidi_move_to_visually_next (&it->bidi_it);
3323 } while (it->bidi_it.charpos != 0);
3325 eassert (IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
3326 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos);
3330 if (CHARPOS (pos->string_pos) >= 0)
3332 /* Recorded position is not in an overlay string, but in another
3333 string. This can only be a string from a `display' property.
3334 IT should already be filled with that string. */
3335 it->current.string_pos = pos->string_pos;
3336 eassert (STRINGP (it->string));
3337 if (it->bidi_p)
3338 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3339 FRAME_WINDOW_P (it->f), &it->bidi_it);
3342 /* Restore position in display vector translations, control
3343 character translations or ellipses. */
3344 if (pos->dpvec_index >= 0)
3346 if (it->dpvec == NULL)
3347 get_next_display_element (it);
3348 eassert (it->dpvec && it->current.dpvec_index == 0);
3349 it->current.dpvec_index = pos->dpvec_index;
3352 CHECK_IT (it);
3353 return !overlay_strings_with_newlines;
3357 /* Initialize IT for stepping through current_buffer in window W
3358 starting at ROW->start. */
3360 static void
3361 init_to_row_start (struct it *it, struct window *w, struct glyph_row *row)
3363 init_from_display_pos (it, w, &row->start);
3364 it->start = row->start;
3365 it->continuation_lines_width = row->continuation_lines_width;
3366 CHECK_IT (it);
3370 /* Initialize IT for stepping through current_buffer in window W
3371 starting in the line following ROW, i.e. starting at ROW->end.
3372 Value is zero if there are overlay strings with newlines at ROW's
3373 end position. */
3375 static int
3376 init_to_row_end (struct it *it, struct window *w, struct glyph_row *row)
3378 int success = 0;
3380 if (init_from_display_pos (it, w, &row->end))
3382 if (row->continued_p)
3383 it->continuation_lines_width
3384 = row->continuation_lines_width + row->pixel_width;
3385 CHECK_IT (it);
3386 success = 1;
3389 return success;
3395 /***********************************************************************
3396 Text properties
3397 ***********************************************************************/
3399 /* Called when IT reaches IT->stop_charpos. Handle text property and
3400 overlay changes. Set IT->stop_charpos to the next position where
3401 to stop. */
3403 static void
3404 handle_stop (struct it *it)
3406 enum prop_handled handled;
3407 int handle_overlay_change_p;
3408 struct props *p;
3410 it->dpvec = NULL;
3411 it->current.dpvec_index = -1;
3412 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
3413 it->ignore_overlay_strings_at_pos_p = 0;
3414 it->ellipsis_p = 0;
3416 /* Use face of preceding text for ellipsis (if invisible) */
3417 if (it->selective_display_ellipsis_p)
3418 it->saved_face_id = it->face_id;
3422 handled = HANDLED_NORMALLY;
3424 /* Call text property handlers. */
3425 for (p = it_props; p->handler; ++p)
3427 handled = p->handler (it);
3429 if (handled == HANDLED_RECOMPUTE_PROPS)
3430 break;
3431 else if (handled == HANDLED_RETURN)
3433 /* We still want to show before and after strings from
3434 overlays even if the actual buffer text is replaced. */
3435 if (!handle_overlay_change_p
3436 || it->sp > 1
3437 /* Don't call get_overlay_strings_1 if we already
3438 have overlay strings loaded, because doing so
3439 will load them again and push the iterator state
3440 onto the stack one more time, which is not
3441 expected by the rest of the code that processes
3442 overlay strings. */
3443 || (it->current.overlay_string_index < 0
3444 ? !get_overlay_strings_1 (it, 0, 0)
3445 : 0))
3447 if (it->ellipsis_p)
3448 setup_for_ellipsis (it, 0);
3449 /* When handling a display spec, we might load an
3450 empty string. In that case, discard it here. We
3451 used to discard it in handle_single_display_spec,
3452 but that causes get_overlay_strings_1, above, to
3453 ignore overlay strings that we must check. */
3454 if (STRINGP (it->string) && !SCHARS (it->string))
3455 pop_it (it);
3456 return;
3458 else if (STRINGP (it->string) && !SCHARS (it->string))
3459 pop_it (it);
3460 else
3462 it->ignore_overlay_strings_at_pos_p = true;
3463 it->string_from_display_prop_p = 0;
3464 it->from_disp_prop_p = 0;
3465 handle_overlay_change_p = 0;
3467 handled = HANDLED_RECOMPUTE_PROPS;
3468 break;
3470 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
3471 handle_overlay_change_p = 0;
3474 if (handled != HANDLED_RECOMPUTE_PROPS)
3476 /* Don't check for overlay strings below when set to deliver
3477 characters from a display vector. */
3478 if (it->method == GET_FROM_DISPLAY_VECTOR)
3479 handle_overlay_change_p = 0;
3481 /* Handle overlay changes.
3482 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
3483 if it finds overlays. */
3484 if (handle_overlay_change_p)
3485 handled = handle_overlay_change (it);
3488 if (it->ellipsis_p)
3490 setup_for_ellipsis (it, 0);
3491 break;
3494 while (handled == HANDLED_RECOMPUTE_PROPS);
3496 /* Determine where to stop next. */
3497 if (handled == HANDLED_NORMALLY)
3498 compute_stop_pos (it);
3502 /* Compute IT->stop_charpos from text property and overlay change
3503 information for IT's current position. */
3505 static void
3506 compute_stop_pos (struct it *it)
3508 register INTERVAL iv, next_iv;
3509 Lisp_Object object, limit, position;
3510 ptrdiff_t charpos, bytepos;
3512 if (STRINGP (it->string))
3514 /* Strings are usually short, so don't limit the search for
3515 properties. */
3516 it->stop_charpos = it->end_charpos;
3517 object = it->string;
3518 limit = Qnil;
3519 charpos = IT_STRING_CHARPOS (*it);
3520 bytepos = IT_STRING_BYTEPOS (*it);
3522 else
3524 ptrdiff_t pos;
3526 /* If end_charpos is out of range for some reason, such as a
3527 misbehaving display function, rationalize it (Bug#5984). */
3528 if (it->end_charpos > ZV)
3529 it->end_charpos = ZV;
3530 it->stop_charpos = it->end_charpos;
3532 /* If next overlay change is in front of the current stop pos
3533 (which is IT->end_charpos), stop there. Note: value of
3534 next_overlay_change is point-max if no overlay change
3535 follows. */
3536 charpos = IT_CHARPOS (*it);
3537 bytepos = IT_BYTEPOS (*it);
3538 pos = next_overlay_change (charpos);
3539 if (pos < it->stop_charpos)
3540 it->stop_charpos = pos;
3542 /* Set up variables for computing the stop position from text
3543 property changes. */
3544 XSETBUFFER (object, current_buffer);
3545 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3548 /* Get the interval containing IT's position. Value is a null
3549 interval if there isn't such an interval. */
3550 position = make_number (charpos);
3551 iv = validate_interval_range (object, &position, &position, 0);
3552 if (iv)
3554 Lisp_Object values_here[LAST_PROP_IDX];
3555 struct props *p;
3557 /* Get properties here. */
3558 for (p = it_props; p->handler; ++p)
3559 values_here[p->idx] = textget (iv->plist, *p->name);
3561 /* Look for an interval following iv that has different
3562 properties. */
3563 for (next_iv = next_interval (iv);
3564 (next_iv
3565 && (NILP (limit)
3566 || XFASTINT (limit) > next_iv->position));
3567 next_iv = next_interval (next_iv))
3569 for (p = it_props; p->handler; ++p)
3571 Lisp_Object new_value;
3573 new_value = textget (next_iv->plist, *p->name);
3574 if (!EQ (values_here[p->idx], new_value))
3575 break;
3578 if (p->handler)
3579 break;
3582 if (next_iv)
3584 if (INTEGERP (limit)
3585 && next_iv->position >= XFASTINT (limit))
3586 /* No text property change up to limit. */
3587 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3588 else
3589 /* Text properties change in next_iv. */
3590 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3594 if (it->cmp_it.id < 0)
3596 ptrdiff_t stoppos = it->end_charpos;
3598 if (it->bidi_p && it->bidi_it.scan_dir < 0)
3599 stoppos = -1;
3600 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
3601 stoppos, it->string);
3604 eassert (STRINGP (it->string)
3605 || (it->stop_charpos >= BEGV
3606 && it->stop_charpos >= IT_CHARPOS (*it)));
3610 /* Return the position of the next overlay change after POS in
3611 current_buffer. Value is point-max if no overlay change
3612 follows. This is like `next-overlay-change' but doesn't use
3613 xmalloc. */
3615 static ptrdiff_t
3616 next_overlay_change (ptrdiff_t pos)
3618 ptrdiff_t i, noverlays;
3619 ptrdiff_t endpos;
3620 Lisp_Object *overlays;
3622 /* Get all overlays at the given position. */
3623 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
3625 /* If any of these overlays ends before endpos,
3626 use its ending point instead. */
3627 for (i = 0; i < noverlays; ++i)
3629 Lisp_Object oend;
3630 ptrdiff_t oendpos;
3632 oend = OVERLAY_END (overlays[i]);
3633 oendpos = OVERLAY_POSITION (oend);
3634 endpos = min (endpos, oendpos);
3637 return endpos;
3640 /* How many characters forward to search for a display property or
3641 display string. Searching too far forward makes the bidi display
3642 sluggish, especially in small windows. */
3643 #define MAX_DISP_SCAN 250
3645 /* Return the character position of a display string at or after
3646 position specified by POSITION. If no display string exists at or
3647 after POSITION, return ZV. A display string is either an overlay
3648 with `display' property whose value is a string, or a `display'
3649 text property whose value is a string. STRING is data about the
3650 string to iterate; if STRING->lstring is nil, we are iterating a
3651 buffer. FRAME_WINDOW_P is non-zero when we are displaying a window
3652 on a GUI frame. DISP_PROP is set to zero if we searched
3653 MAX_DISP_SCAN characters forward without finding any display
3654 strings, non-zero otherwise. It is set to 2 if the display string
3655 uses any kind of `(space ...)' spec that will produce a stretch of
3656 white space in the text area. */
3657 ptrdiff_t
3658 compute_display_string_pos (struct text_pos *position,
3659 struct bidi_string_data *string,
3660 struct window *w,
3661 int frame_window_p, int *disp_prop)
3663 /* OBJECT = nil means current buffer. */
3664 Lisp_Object object, object1;
3665 Lisp_Object pos, spec, limpos;
3666 int string_p = (string && (STRINGP (string->lstring) || string->s));
3667 ptrdiff_t eob = string_p ? string->schars : ZV;
3668 ptrdiff_t begb = string_p ? 0 : BEGV;
3669 ptrdiff_t bufpos, charpos = CHARPOS (*position);
3670 ptrdiff_t lim =
3671 (charpos < eob - MAX_DISP_SCAN) ? charpos + MAX_DISP_SCAN : eob;
3672 struct text_pos tpos;
3673 int rv = 0;
3675 if (string && STRINGP (string->lstring))
3676 object1 = object = string->lstring;
3677 else if (w && !string_p)
3679 XSETWINDOW (object, w);
3680 object1 = Qnil;
3682 else
3683 object1 = object = Qnil;
3685 *disp_prop = 1;
3687 if (charpos >= eob
3688 /* We don't support display properties whose values are strings
3689 that have display string properties. */
3690 || string->from_disp_str
3691 /* C strings cannot have display properties. */
3692 || (string->s && !STRINGP (object)))
3694 *disp_prop = 0;
3695 return eob;
3698 /* If the character at CHARPOS is where the display string begins,
3699 return CHARPOS. */
3700 pos = make_number (charpos);
3701 if (STRINGP (object))
3702 bufpos = string->bufpos;
3703 else
3704 bufpos = charpos;
3705 tpos = *position;
3706 if (!NILP (spec = Fget_char_property (pos, Qdisplay, object))
3707 && (charpos <= begb
3708 || !EQ (Fget_char_property (make_number (charpos - 1), Qdisplay,
3709 object),
3710 spec))
3711 && (rv = handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
3712 frame_window_p)))
3714 if (rv == 2)
3715 *disp_prop = 2;
3716 return charpos;
3719 /* Look forward for the first character with a `display' property
3720 that will replace the underlying text when displayed. */
3721 limpos = make_number (lim);
3722 do {
3723 pos = Fnext_single_char_property_change (pos, Qdisplay, object1, limpos);
3724 CHARPOS (tpos) = XFASTINT (pos);
3725 if (CHARPOS (tpos) >= lim)
3727 *disp_prop = 0;
3728 break;
3730 if (STRINGP (object))
3731 BYTEPOS (tpos) = string_char_to_byte (object, CHARPOS (tpos));
3732 else
3733 BYTEPOS (tpos) = CHAR_TO_BYTE (CHARPOS (tpos));
3734 spec = Fget_char_property (pos, Qdisplay, object);
3735 if (!STRINGP (object))
3736 bufpos = CHARPOS (tpos);
3737 } while (NILP (spec)
3738 || !(rv = handle_display_spec (NULL, spec, object, Qnil, &tpos,
3739 bufpos, frame_window_p)));
3740 if (rv == 2)
3741 *disp_prop = 2;
3743 return CHARPOS (tpos);
3746 /* Return the character position of the end of the display string that
3747 started at CHARPOS. If there's no display string at CHARPOS,
3748 return -1. A display string is either an overlay with `display'
3749 property whose value is a string or a `display' text property whose
3750 value is a string. */
3751 ptrdiff_t
3752 compute_display_string_end (ptrdiff_t charpos, struct bidi_string_data *string)
3754 /* OBJECT = nil means current buffer. */
3755 Lisp_Object object =
3756 (string && STRINGP (string->lstring)) ? string->lstring : Qnil;
3757 Lisp_Object pos = make_number (charpos);
3758 ptrdiff_t eob =
3759 (STRINGP (object) || (string && string->s)) ? string->schars : ZV;
3761 if (charpos >= eob || (string->s && !STRINGP (object)))
3762 return eob;
3764 /* It could happen that the display property or overlay was removed
3765 since we found it in compute_display_string_pos above. One way
3766 this can happen is if JIT font-lock was called (through
3767 handle_fontified_prop), and jit-lock-functions remove text
3768 properties or overlays from the portion of buffer that includes
3769 CHARPOS. Muse mode is known to do that, for example. In this
3770 case, we return -1 to the caller, to signal that no display
3771 string is actually present at CHARPOS. See bidi_fetch_char for
3772 how this is handled.
3774 An alternative would be to never look for display properties past
3775 it->stop_charpos. But neither compute_display_string_pos nor
3776 bidi_fetch_char that calls it know or care where the next
3777 stop_charpos is. */
3778 if (NILP (Fget_char_property (pos, Qdisplay, object)))
3779 return -1;
3781 /* Look forward for the first character where the `display' property
3782 changes. */
3783 pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil);
3785 return XFASTINT (pos);
3790 /***********************************************************************
3791 Fontification
3792 ***********************************************************************/
3794 /* Handle changes in the `fontified' property of the current buffer by
3795 calling hook functions from Qfontification_functions to fontify
3796 regions of text. */
3798 static enum prop_handled
3799 handle_fontified_prop (struct it *it)
3801 Lisp_Object prop, pos;
3802 enum prop_handled handled = HANDLED_NORMALLY;
3804 if (!NILP (Vmemory_full))
3805 return handled;
3807 /* Get the value of the `fontified' property at IT's current buffer
3808 position. (The `fontified' property doesn't have a special
3809 meaning in strings.) If the value is nil, call functions from
3810 Qfontification_functions. */
3811 if (!STRINGP (it->string)
3812 && it->s == NULL
3813 && !NILP (Vfontification_functions)
3814 && !NILP (Vrun_hooks)
3815 && (pos = make_number (IT_CHARPOS (*it)),
3816 prop = Fget_char_property (pos, Qfontified, Qnil),
3817 /* Ignore the special cased nil value always present at EOB since
3818 no amount of fontifying will be able to change it. */
3819 NILP (prop) && IT_CHARPOS (*it) < Z))
3821 ptrdiff_t count = SPECPDL_INDEX ();
3822 Lisp_Object val;
3823 struct buffer *obuf = current_buffer;
3824 ptrdiff_t begv = BEGV, zv = ZV;
3825 bool old_clip_changed = current_buffer->clip_changed;
3827 val = Vfontification_functions;
3828 specbind (Qfontification_functions, Qnil);
3830 eassert (it->end_charpos == ZV);
3832 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3833 safe_call1 (val, pos);
3834 else
3836 Lisp_Object fns, fn;
3837 struct gcpro gcpro1, gcpro2;
3839 fns = Qnil;
3840 GCPRO2 (val, fns);
3842 for (; CONSP (val); val = XCDR (val))
3844 fn = XCAR (val);
3846 if (EQ (fn, Qt))
3848 /* A value of t indicates this hook has a local
3849 binding; it means to run the global binding too.
3850 In a global value, t should not occur. If it
3851 does, we must ignore it to avoid an endless
3852 loop. */
3853 for (fns = Fdefault_value (Qfontification_functions);
3854 CONSP (fns);
3855 fns = XCDR (fns))
3857 fn = XCAR (fns);
3858 if (!EQ (fn, Qt))
3859 safe_call1 (fn, pos);
3862 else
3863 safe_call1 (fn, pos);
3866 UNGCPRO;
3869 unbind_to (count, Qnil);
3871 /* Fontification functions routinely call `save-restriction'.
3872 Normally, this tags clip_changed, which can confuse redisplay
3873 (see discussion in Bug#6671). Since we don't perform any
3874 special handling of fontification changes in the case where
3875 `save-restriction' isn't called, there's no point doing so in
3876 this case either. So, if the buffer's restrictions are
3877 actually left unchanged, reset clip_changed. */
3878 if (obuf == current_buffer)
3880 if (begv == BEGV && zv == ZV)
3881 current_buffer->clip_changed = old_clip_changed;
3883 /* There isn't much we can reasonably do to protect against
3884 misbehaving fontification, but here's a fig leaf. */
3885 else if (BUFFER_LIVE_P (obuf))
3886 set_buffer_internal_1 (obuf);
3888 /* The fontification code may have added/removed text.
3889 It could do even a lot worse, but let's at least protect against
3890 the most obvious case where only the text past `pos' gets changed',
3891 as is/was done in grep.el where some escapes sequences are turned
3892 into face properties (bug#7876). */
3893 it->end_charpos = ZV;
3895 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3896 something. This avoids an endless loop if they failed to
3897 fontify the text for which reason ever. */
3898 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3899 handled = HANDLED_RECOMPUTE_PROPS;
3902 return handled;
3907 /***********************************************************************
3908 Faces
3909 ***********************************************************************/
3911 /* Set up iterator IT from face properties at its current position.
3912 Called from handle_stop. */
3914 static enum prop_handled
3915 handle_face_prop (struct it *it)
3917 int new_face_id;
3918 ptrdiff_t next_stop;
3920 if (!STRINGP (it->string))
3922 new_face_id
3923 = face_at_buffer_position (it->w,
3924 IT_CHARPOS (*it),
3925 &next_stop,
3926 (IT_CHARPOS (*it)
3927 + TEXT_PROP_DISTANCE_LIMIT),
3928 0, it->base_face_id);
3930 /* Is this a start of a run of characters with box face?
3931 Caveat: this can be called for a freshly initialized
3932 iterator; face_id is -1 in this case. We know that the new
3933 face will not change until limit, i.e. if the new face has a
3934 box, all characters up to limit will have one. But, as
3935 usual, we don't know whether limit is really the end. */
3936 if (new_face_id != it->face_id)
3938 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3939 /* If it->face_id is -1, old_face below will be NULL, see
3940 the definition of FACE_FROM_ID. This will happen if this
3941 is the initial call that gets the face. */
3942 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3944 /* If the value of face_id of the iterator is -1, we have to
3945 look in front of IT's position and see whether there is a
3946 face there that's different from new_face_id. */
3947 if (!old_face && IT_CHARPOS (*it) > BEG)
3949 int prev_face_id = face_before_it_pos (it);
3951 old_face = FACE_FROM_ID (it->f, prev_face_id);
3954 /* If the new face has a box, but the old face does not,
3955 this is the start of a run of characters with box face,
3956 i.e. this character has a shadow on the left side. */
3957 it->start_of_box_run_p = (new_face->box != FACE_NO_BOX
3958 && (old_face == NULL || !old_face->box));
3959 it->face_box_p = new_face->box != FACE_NO_BOX;
3962 else
3964 int base_face_id;
3965 ptrdiff_t bufpos;
3966 int i;
3967 Lisp_Object from_overlay
3968 = (it->current.overlay_string_index >= 0
3969 ? it->string_overlays[it->current.overlay_string_index
3970 % OVERLAY_STRING_CHUNK_SIZE]
3971 : Qnil);
3973 /* See if we got to this string directly or indirectly from
3974 an overlay property. That includes the before-string or
3975 after-string of an overlay, strings in display properties
3976 provided by an overlay, their text properties, etc.
3978 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
3979 if (! NILP (from_overlay))
3980 for (i = it->sp - 1; i >= 0; i--)
3982 if (it->stack[i].current.overlay_string_index >= 0)
3983 from_overlay
3984 = it->string_overlays[it->stack[i].current.overlay_string_index
3985 % OVERLAY_STRING_CHUNK_SIZE];
3986 else if (! NILP (it->stack[i].from_overlay))
3987 from_overlay = it->stack[i].from_overlay;
3989 if (!NILP (from_overlay))
3990 break;
3993 if (! NILP (from_overlay))
3995 bufpos = IT_CHARPOS (*it);
3996 /* For a string from an overlay, the base face depends
3997 only on text properties and ignores overlays. */
3998 base_face_id
3999 = face_for_overlay_string (it->w,
4000 IT_CHARPOS (*it),
4001 &next_stop,
4002 (IT_CHARPOS (*it)
4003 + TEXT_PROP_DISTANCE_LIMIT),
4005 from_overlay);
4007 else
4009 bufpos = 0;
4011 /* For strings from a `display' property, use the face at
4012 IT's current buffer position as the base face to merge
4013 with, so that overlay strings appear in the same face as
4014 surrounding text, unless they specify their own faces.
4015 For strings from wrap-prefix and line-prefix properties,
4016 use the default face, possibly remapped via
4017 Vface_remapping_alist. */
4018 /* Note that the fact that we use the face at _buffer_
4019 position means that a 'display' property on an overlay
4020 string will not inherit the face of that overlay string,
4021 but will instead revert to the face of buffer text
4022 covered by the overlay. This is visible, e.g., when the
4023 overlay specifies a box face, but neither the buffer nor
4024 the display string do. This sounds like a design bug,
4025 but Emacs always did that since v21.1, so changing that
4026 might be a big deal. */
4027 base_face_id = it->string_from_prefix_prop_p
4028 ? (!NILP (Vface_remapping_alist)
4029 ? lookup_basic_face (it->f, DEFAULT_FACE_ID)
4030 : DEFAULT_FACE_ID)
4031 : underlying_face_id (it);
4034 new_face_id = face_at_string_position (it->w,
4035 it->string,
4036 IT_STRING_CHARPOS (*it),
4037 bufpos,
4038 &next_stop,
4039 base_face_id, 0);
4041 /* Is this a start of a run of characters with box? Caveat:
4042 this can be called for a freshly allocated iterator; face_id
4043 is -1 is this case. We know that the new face will not
4044 change until the next check pos, i.e. if the new face has a
4045 box, all characters up to that position will have a
4046 box. But, as usual, we don't know whether that position
4047 is really the end. */
4048 if (new_face_id != it->face_id)
4050 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
4051 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
4053 /* If new face has a box but old face hasn't, this is the
4054 start of a run of characters with box, i.e. it has a
4055 shadow on the left side. */
4056 it->start_of_box_run_p
4057 = new_face->box && (old_face == NULL || !old_face->box);
4058 it->face_box_p = new_face->box != FACE_NO_BOX;
4062 it->face_id = new_face_id;
4063 return HANDLED_NORMALLY;
4067 /* Return the ID of the face ``underlying'' IT's current position,
4068 which is in a string. If the iterator is associated with a
4069 buffer, return the face at IT's current buffer position.
4070 Otherwise, use the iterator's base_face_id. */
4072 static int
4073 underlying_face_id (struct it *it)
4075 int face_id = it->base_face_id, i;
4077 eassert (STRINGP (it->string));
4079 for (i = it->sp - 1; i >= 0; --i)
4080 if (NILP (it->stack[i].string))
4081 face_id = it->stack[i].face_id;
4083 return face_id;
4087 /* Compute the face one character before or after the current position
4088 of IT, in the visual order. BEFORE_P non-zero means get the face
4089 in front (to the left in L2R paragraphs, to the right in R2L
4090 paragraphs) of IT's screen position. Value is the ID of the face. */
4092 static int
4093 face_before_or_after_it_pos (struct it *it, int before_p)
4095 int face_id, limit;
4096 ptrdiff_t next_check_charpos;
4097 struct it it_copy;
4098 void *it_copy_data = NULL;
4100 eassert (it->s == NULL);
4102 if (STRINGP (it->string))
4104 ptrdiff_t bufpos, charpos;
4105 int base_face_id;
4107 /* No face change past the end of the string (for the case
4108 we are padding with spaces). No face change before the
4109 string start. */
4110 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
4111 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
4112 return it->face_id;
4114 if (!it->bidi_p)
4116 /* Set charpos to the position before or after IT's current
4117 position, in the logical order, which in the non-bidi
4118 case is the same as the visual order. */
4119 if (before_p)
4120 charpos = IT_STRING_CHARPOS (*it) - 1;
4121 else if (it->what == IT_COMPOSITION)
4122 /* For composition, we must check the character after the
4123 composition. */
4124 charpos = IT_STRING_CHARPOS (*it) + it->cmp_it.nchars;
4125 else
4126 charpos = IT_STRING_CHARPOS (*it) + 1;
4128 else
4130 if (before_p)
4132 /* With bidi iteration, the character before the current
4133 in the visual order cannot be found by simple
4134 iteration, because "reverse" reordering is not
4135 supported. Instead, we need to use the move_it_*
4136 family of functions. */
4137 /* Ignore face changes before the first visible
4138 character on this display line. */
4139 if (it->current_x <= it->first_visible_x)
4140 return it->face_id;
4141 SAVE_IT (it_copy, *it, it_copy_data);
4142 /* Implementation note: Since move_it_in_display_line
4143 works in the iterator geometry, and thinks the first
4144 character is always the leftmost, even in R2L lines,
4145 we don't need to distinguish between the R2L and L2R
4146 cases here. */
4147 move_it_in_display_line (&it_copy, SCHARS (it_copy.string),
4148 it_copy.current_x - 1, MOVE_TO_X);
4149 charpos = IT_STRING_CHARPOS (it_copy);
4150 RESTORE_IT (it, it, it_copy_data);
4152 else
4154 /* Set charpos to the string position of the character
4155 that comes after IT's current position in the visual
4156 order. */
4157 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
4159 it_copy = *it;
4160 while (n--)
4161 bidi_move_to_visually_next (&it_copy.bidi_it);
4163 charpos = it_copy.bidi_it.charpos;
4166 eassert (0 <= charpos && charpos <= SCHARS (it->string));
4168 if (it->current.overlay_string_index >= 0)
4169 bufpos = IT_CHARPOS (*it);
4170 else
4171 bufpos = 0;
4173 base_face_id = underlying_face_id (it);
4175 /* Get the face for ASCII, or unibyte. */
4176 face_id = face_at_string_position (it->w,
4177 it->string,
4178 charpos,
4179 bufpos,
4180 &next_check_charpos,
4181 base_face_id, 0);
4183 /* Correct the face for charsets different from ASCII. Do it
4184 for the multibyte case only. The face returned above is
4185 suitable for unibyte text if IT->string is unibyte. */
4186 if (STRING_MULTIBYTE (it->string))
4188 struct text_pos pos1 = string_pos (charpos, it->string);
4189 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos1);
4190 int c, len;
4191 struct face *face = FACE_FROM_ID (it->f, face_id);
4193 c = string_char_and_length (p, &len);
4194 face_id = FACE_FOR_CHAR (it->f, face, c, charpos, it->string);
4197 else
4199 struct text_pos pos;
4201 if ((IT_CHARPOS (*it) >= ZV && !before_p)
4202 || (IT_CHARPOS (*it) <= BEGV && before_p))
4203 return it->face_id;
4205 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
4206 pos = it->current.pos;
4208 if (!it->bidi_p)
4210 if (before_p)
4211 DEC_TEXT_POS (pos, it->multibyte_p);
4212 else
4214 if (it->what == IT_COMPOSITION)
4216 /* For composition, we must check the position after
4217 the composition. */
4218 pos.charpos += it->cmp_it.nchars;
4219 pos.bytepos += it->len;
4221 else
4222 INC_TEXT_POS (pos, it->multibyte_p);
4225 else
4227 if (before_p)
4229 /* With bidi iteration, the character before the current
4230 in the visual order cannot be found by simple
4231 iteration, because "reverse" reordering is not
4232 supported. Instead, we need to use the move_it_*
4233 family of functions. */
4234 /* Ignore face changes before the first visible
4235 character on this display line. */
4236 if (it->current_x <= it->first_visible_x)
4237 return it->face_id;
4238 SAVE_IT (it_copy, *it, it_copy_data);
4239 /* Implementation note: Since move_it_in_display_line
4240 works in the iterator geometry, and thinks the first
4241 character is always the leftmost, even in R2L lines,
4242 we don't need to distinguish between the R2L and L2R
4243 cases here. */
4244 move_it_in_display_line (&it_copy, ZV,
4245 it_copy.current_x - 1, MOVE_TO_X);
4246 pos = it_copy.current.pos;
4247 RESTORE_IT (it, it, it_copy_data);
4249 else
4251 /* Set charpos to the buffer position of the character
4252 that comes after IT's current position in the visual
4253 order. */
4254 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
4256 it_copy = *it;
4257 while (n--)
4258 bidi_move_to_visually_next (&it_copy.bidi_it);
4260 SET_TEXT_POS (pos,
4261 it_copy.bidi_it.charpos, it_copy.bidi_it.bytepos);
4264 eassert (BEGV <= CHARPOS (pos) && CHARPOS (pos) <= ZV);
4266 /* Determine face for CHARSET_ASCII, or unibyte. */
4267 face_id = face_at_buffer_position (it->w,
4268 CHARPOS (pos),
4269 &next_check_charpos,
4270 limit, 0, -1);
4272 /* Correct the face for charsets different from ASCII. Do it
4273 for the multibyte case only. The face returned above is
4274 suitable for unibyte text if current_buffer is unibyte. */
4275 if (it->multibyte_p)
4277 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
4278 struct face *face = FACE_FROM_ID (it->f, face_id);
4279 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
4283 return face_id;
4288 /***********************************************************************
4289 Invisible text
4290 ***********************************************************************/
4292 /* Set up iterator IT from invisible properties at its current
4293 position. Called from handle_stop. */
4295 static enum prop_handled
4296 handle_invisible_prop (struct it *it)
4298 enum prop_handled handled = HANDLED_NORMALLY;
4299 int invis_p;
4300 Lisp_Object prop;
4302 if (STRINGP (it->string))
4304 Lisp_Object end_charpos, limit, charpos;
4306 /* Get the value of the invisible text property at the
4307 current position. Value will be nil if there is no such
4308 property. */
4309 charpos = make_number (IT_STRING_CHARPOS (*it));
4310 prop = Fget_text_property (charpos, Qinvisible, it->string);
4311 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4313 if (invis_p && IT_STRING_CHARPOS (*it) < it->end_charpos)
4315 /* Record whether we have to display an ellipsis for the
4316 invisible text. */
4317 int display_ellipsis_p = (invis_p == 2);
4318 ptrdiff_t len, endpos;
4320 handled = HANDLED_RECOMPUTE_PROPS;
4322 /* Get the position at which the next visible text can be
4323 found in IT->string, if any. */
4324 endpos = len = SCHARS (it->string);
4325 XSETINT (limit, len);
4328 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
4329 it->string, limit);
4330 if (INTEGERP (end_charpos))
4332 endpos = XFASTINT (end_charpos);
4333 prop = Fget_text_property (end_charpos, Qinvisible, it->string);
4334 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4335 if (invis_p == 2)
4336 display_ellipsis_p = true;
4339 while (invis_p && endpos < len);
4341 if (display_ellipsis_p)
4342 it->ellipsis_p = true;
4344 if (endpos < len)
4346 /* Text at END_CHARPOS is visible. Move IT there. */
4347 struct text_pos old;
4348 ptrdiff_t oldpos;
4350 old = it->current.string_pos;
4351 oldpos = CHARPOS (old);
4352 if (it->bidi_p)
4354 if (it->bidi_it.first_elt
4355 && it->bidi_it.charpos < SCHARS (it->string))
4356 bidi_paragraph_init (it->paragraph_embedding,
4357 &it->bidi_it, 1);
4358 /* Bidi-iterate out of the invisible text. */
4361 bidi_move_to_visually_next (&it->bidi_it);
4363 while (oldpos <= it->bidi_it.charpos
4364 && it->bidi_it.charpos < endpos);
4366 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
4367 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
4368 if (IT_CHARPOS (*it) >= endpos)
4369 it->prev_stop = endpos;
4371 else
4373 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
4374 compute_string_pos (&it->current.string_pos, old, it->string);
4377 else
4379 /* The rest of the string is invisible. If this is an
4380 overlay string, proceed with the next overlay string
4381 or whatever comes and return a character from there. */
4382 if (it->current.overlay_string_index >= 0
4383 && !display_ellipsis_p)
4385 next_overlay_string (it);
4386 /* Don't check for overlay strings when we just
4387 finished processing them. */
4388 handled = HANDLED_OVERLAY_STRING_CONSUMED;
4390 else
4392 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
4393 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
4398 else
4400 ptrdiff_t newpos, next_stop, start_charpos, tem;
4401 Lisp_Object pos, overlay;
4403 /* First of all, is there invisible text at this position? */
4404 tem = start_charpos = IT_CHARPOS (*it);
4405 pos = make_number (tem);
4406 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
4407 &overlay);
4408 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4410 /* If we are on invisible text, skip over it. */
4411 if (invis_p && start_charpos < it->end_charpos)
4413 /* Record whether we have to display an ellipsis for the
4414 invisible text. */
4415 int display_ellipsis_p = invis_p == 2;
4417 handled = HANDLED_RECOMPUTE_PROPS;
4419 /* Loop skipping over invisible text. The loop is left at
4420 ZV or with IT on the first char being visible again. */
4423 /* Try to skip some invisible text. Return value is the
4424 position reached which can be equal to where we start
4425 if there is nothing invisible there. This skips both
4426 over invisible text properties and overlays with
4427 invisible property. */
4428 newpos = skip_invisible (tem, &next_stop, ZV, it->window);
4430 /* If we skipped nothing at all we weren't at invisible
4431 text in the first place. If everything to the end of
4432 the buffer was skipped, end the loop. */
4433 if (newpos == tem || newpos >= ZV)
4434 invis_p = 0;
4435 else
4437 /* We skipped some characters but not necessarily
4438 all there are. Check if we ended up on visible
4439 text. Fget_char_property returns the property of
4440 the char before the given position, i.e. if we
4441 get invis_p = 0, this means that the char at
4442 newpos is visible. */
4443 pos = make_number (newpos);
4444 prop = Fget_char_property (pos, Qinvisible, it->window);
4445 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4448 /* If we ended up on invisible text, proceed to
4449 skip starting with next_stop. */
4450 if (invis_p)
4451 tem = next_stop;
4453 /* If there are adjacent invisible texts, don't lose the
4454 second one's ellipsis. */
4455 if (invis_p == 2)
4456 display_ellipsis_p = true;
4458 while (invis_p);
4460 /* The position newpos is now either ZV or on visible text. */
4461 if (it->bidi_p)
4463 ptrdiff_t bpos = CHAR_TO_BYTE (newpos);
4464 int on_newline
4465 = bpos == ZV_BYTE || FETCH_BYTE (bpos) == '\n';
4466 int after_newline
4467 = newpos <= BEGV || FETCH_BYTE (bpos - 1) == '\n';
4469 /* If the invisible text ends on a newline or on a
4470 character after a newline, we can avoid the costly,
4471 character by character, bidi iteration to NEWPOS, and
4472 instead simply reseat the iterator there. That's
4473 because all bidi reordering information is tossed at
4474 the newline. This is a big win for modes that hide
4475 complete lines, like Outline, Org, etc. */
4476 if (on_newline || after_newline)
4478 struct text_pos tpos;
4479 bidi_dir_t pdir = it->bidi_it.paragraph_dir;
4481 SET_TEXT_POS (tpos, newpos, bpos);
4482 reseat_1 (it, tpos, 0);
4483 /* If we reseat on a newline/ZV, we need to prep the
4484 bidi iterator for advancing to the next character
4485 after the newline/EOB, keeping the current paragraph
4486 direction (so that PRODUCE_GLYPHS does TRT wrt
4487 prepending/appending glyphs to a glyph row). */
4488 if (on_newline)
4490 it->bidi_it.first_elt = 0;
4491 it->bidi_it.paragraph_dir = pdir;
4492 it->bidi_it.ch = (bpos == ZV_BYTE) ? -1 : '\n';
4493 it->bidi_it.nchars = 1;
4494 it->bidi_it.ch_len = 1;
4497 else /* Must use the slow method. */
4499 /* With bidi iteration, the region of invisible text
4500 could start and/or end in the middle of a
4501 non-base embedding level. Therefore, we need to
4502 skip invisible text using the bidi iterator,
4503 starting at IT's current position, until we find
4504 ourselves outside of the invisible text.
4505 Skipping invisible text _after_ bidi iteration
4506 avoids affecting the visual order of the
4507 displayed text when invisible properties are
4508 added or removed. */
4509 if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV)
4511 /* If we were `reseat'ed to a new paragraph,
4512 determine the paragraph base direction. We
4513 need to do it now because
4514 next_element_from_buffer may not have a
4515 chance to do it, if we are going to skip any
4516 text at the beginning, which resets the
4517 FIRST_ELT flag. */
4518 bidi_paragraph_init (it->paragraph_embedding,
4519 &it->bidi_it, 1);
4523 bidi_move_to_visually_next (&it->bidi_it);
4525 while (it->stop_charpos <= it->bidi_it.charpos
4526 && it->bidi_it.charpos < newpos);
4527 IT_CHARPOS (*it) = it->bidi_it.charpos;
4528 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
4529 /* If we overstepped NEWPOS, record its position in
4530 the iterator, so that we skip invisible text if
4531 later the bidi iteration lands us in the
4532 invisible region again. */
4533 if (IT_CHARPOS (*it) >= newpos)
4534 it->prev_stop = newpos;
4537 else
4539 IT_CHARPOS (*it) = newpos;
4540 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
4543 /* If there are before-strings at the start of invisible
4544 text, and the text is invisible because of a text
4545 property, arrange to show before-strings because 20.x did
4546 it that way. (If the text is invisible because of an
4547 overlay property instead of a text property, this is
4548 already handled in the overlay code.) */
4549 if (NILP (overlay)
4550 && get_overlay_strings (it, it->stop_charpos))
4552 handled = HANDLED_RECOMPUTE_PROPS;
4553 if (it->sp > 0)
4555 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
4556 /* The call to get_overlay_strings above recomputes
4557 it->stop_charpos, but it only considers changes
4558 in properties and overlays beyond iterator's
4559 current position. This causes us to miss changes
4560 that happen exactly where the invisible property
4561 ended. So we play it safe here and force the
4562 iterator to check for potential stop positions
4563 immediately after the invisible text. Note that
4564 if get_overlay_strings returns non-zero, it
4565 normally also pushed the iterator stack, so we
4566 need to update the stop position in the slot
4567 below the current one. */
4568 it->stack[it->sp - 1].stop_charpos
4569 = CHARPOS (it->stack[it->sp - 1].current.pos);
4572 else if (display_ellipsis_p)
4574 /* Make sure that the glyphs of the ellipsis will get
4575 correct `charpos' values. If we would not update
4576 it->position here, the glyphs would belong to the
4577 last visible character _before_ the invisible
4578 text, which confuses `set_cursor_from_row'.
4580 We use the last invisible position instead of the
4581 first because this way the cursor is always drawn on
4582 the first "." of the ellipsis, whenever PT is inside
4583 the invisible text. Otherwise the cursor would be
4584 placed _after_ the ellipsis when the point is after the
4585 first invisible character. */
4586 if (!STRINGP (it->object))
4588 it->position.charpos = newpos - 1;
4589 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
4591 it->ellipsis_p = true;
4592 /* Let the ellipsis display before
4593 considering any properties of the following char.
4594 Fixes jasonr@gnu.org 01 Oct 07 bug. */
4595 handled = HANDLED_RETURN;
4600 return handled;
4604 /* Make iterator IT return `...' next.
4605 Replaces LEN characters from buffer. */
4607 static void
4608 setup_for_ellipsis (struct it *it, int len)
4610 /* Use the display table definition for `...'. Invalid glyphs
4611 will be handled by the method returning elements from dpvec. */
4612 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
4614 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
4615 it->dpvec = v->contents;
4616 it->dpend = v->contents + v->header.size;
4618 else
4620 /* Default `...'. */
4621 it->dpvec = default_invis_vector;
4622 it->dpend = default_invis_vector + 3;
4625 it->dpvec_char_len = len;
4626 it->current.dpvec_index = 0;
4627 it->dpvec_face_id = -1;
4629 /* Remember the current face id in case glyphs specify faces.
4630 IT's face is restored in set_iterator_to_next.
4631 saved_face_id was set to preceding char's face in handle_stop. */
4632 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
4633 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
4635 it->method = GET_FROM_DISPLAY_VECTOR;
4636 it->ellipsis_p = true;
4641 /***********************************************************************
4642 'display' property
4643 ***********************************************************************/
4645 /* Set up iterator IT from `display' property at its current position.
4646 Called from handle_stop.
4647 We return HANDLED_RETURN if some part of the display property
4648 overrides the display of the buffer text itself.
4649 Otherwise we return HANDLED_NORMALLY. */
4651 static enum prop_handled
4652 handle_display_prop (struct it *it)
4654 Lisp_Object propval, object, overlay;
4655 struct text_pos *position;
4656 ptrdiff_t bufpos;
4657 /* Nonzero if some property replaces the display of the text itself. */
4658 int display_replaced_p = 0;
4660 if (STRINGP (it->string))
4662 object = it->string;
4663 position = &it->current.string_pos;
4664 bufpos = CHARPOS (it->current.pos);
4666 else
4668 XSETWINDOW (object, it->w);
4669 position = &it->current.pos;
4670 bufpos = CHARPOS (*position);
4673 /* Reset those iterator values set from display property values. */
4674 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
4675 it->space_width = Qnil;
4676 it->font_height = Qnil;
4677 it->voffset = 0;
4679 /* We don't support recursive `display' properties, i.e. string
4680 values that have a string `display' property, that have a string
4681 `display' property etc. */
4682 if (!it->string_from_display_prop_p)
4683 it->area = TEXT_AREA;
4685 propval = get_char_property_and_overlay (make_number (position->charpos),
4686 Qdisplay, object, &overlay);
4687 if (NILP (propval))
4688 return HANDLED_NORMALLY;
4689 /* Now OVERLAY is the overlay that gave us this property, or nil
4690 if it was a text property. */
4692 if (!STRINGP (it->string))
4693 object = it->w->contents;
4695 display_replaced_p = handle_display_spec (it, propval, object, overlay,
4696 position, bufpos,
4697 FRAME_WINDOW_P (it->f));
4699 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
4702 /* Subroutine of handle_display_prop. Returns non-zero if the display
4703 specification in SPEC is a replacing specification, i.e. it would
4704 replace the text covered by `display' property with something else,
4705 such as an image or a display string. If SPEC includes any kind or
4706 `(space ...) specification, the value is 2; this is used by
4707 compute_display_string_pos, which see.
4709 See handle_single_display_spec for documentation of arguments.
4710 frame_window_p is non-zero if the window being redisplayed is on a
4711 GUI frame; this argument is used only if IT is NULL, see below.
4713 IT can be NULL, if this is called by the bidi reordering code
4714 through compute_display_string_pos, which see. In that case, this
4715 function only examines SPEC, but does not otherwise "handle" it, in
4716 the sense that it doesn't set up members of IT from the display
4717 spec. */
4718 static int
4719 handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4720 Lisp_Object overlay, struct text_pos *position,
4721 ptrdiff_t bufpos, int frame_window_p)
4723 int replacing_p = 0;
4724 int rv;
4726 if (CONSP (spec)
4727 /* Simple specifications. */
4728 && !EQ (XCAR (spec), Qimage)
4729 && !EQ (XCAR (spec), Qspace)
4730 && !EQ (XCAR (spec), Qwhen)
4731 && !EQ (XCAR (spec), Qslice)
4732 && !EQ (XCAR (spec), Qspace_width)
4733 && !EQ (XCAR (spec), Qheight)
4734 && !EQ (XCAR (spec), Qraise)
4735 /* Marginal area specifications. */
4736 && !(CONSP (XCAR (spec)) && EQ (XCAR (XCAR (spec)), Qmargin))
4737 && !EQ (XCAR (spec), Qleft_fringe)
4738 && !EQ (XCAR (spec), Qright_fringe)
4739 && !NILP (XCAR (spec)))
4741 for (; CONSP (spec); spec = XCDR (spec))
4743 if ((rv = handle_single_display_spec (it, XCAR (spec), object,
4744 overlay, position, bufpos,
4745 replacing_p, frame_window_p)))
4747 replacing_p = rv;
4748 /* If some text in a string is replaced, `position' no
4749 longer points to the position of `object'. */
4750 if (!it || STRINGP (object))
4751 break;
4755 else if (VECTORP (spec))
4757 ptrdiff_t i;
4758 for (i = 0; i < ASIZE (spec); ++i)
4759 if ((rv = handle_single_display_spec (it, AREF (spec, i), object,
4760 overlay, position, bufpos,
4761 replacing_p, frame_window_p)))
4763 replacing_p = rv;
4764 /* If some text in a string is replaced, `position' no
4765 longer points to the position of `object'. */
4766 if (!it || STRINGP (object))
4767 break;
4770 else
4772 if ((rv = handle_single_display_spec (it, spec, object, overlay,
4773 position, bufpos, 0,
4774 frame_window_p)))
4775 replacing_p = rv;
4778 return replacing_p;
4781 /* Value is the position of the end of the `display' property starting
4782 at START_POS in OBJECT. */
4784 static struct text_pos
4785 display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
4787 Lisp_Object end;
4788 struct text_pos end_pos;
4790 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
4791 Qdisplay, object, Qnil);
4792 CHARPOS (end_pos) = XFASTINT (end);
4793 if (STRINGP (object))
4794 compute_string_pos (&end_pos, start_pos, it->string);
4795 else
4796 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
4798 return end_pos;
4802 /* Set up IT from a single `display' property specification SPEC. OBJECT
4803 is the object in which the `display' property was found. *POSITION
4804 is the position in OBJECT at which the `display' property was found.
4805 BUFPOS is the buffer position of OBJECT (different from POSITION if
4806 OBJECT is not a buffer). DISPLAY_REPLACED_P non-zero means that we
4807 previously saw a display specification which already replaced text
4808 display with something else, for example an image; we ignore such
4809 properties after the first one has been processed.
4811 OVERLAY is the overlay this `display' property came from,
4812 or nil if it was a text property.
4814 If SPEC is a `space' or `image' specification, and in some other
4815 cases too, set *POSITION to the position where the `display'
4816 property ends.
4818 If IT is NULL, only examine the property specification in SPEC, but
4819 don't set up IT. In that case, FRAME_WINDOW_P non-zero means SPEC
4820 is intended to be displayed in a window on a GUI frame.
4822 Value is non-zero if something was found which replaces the display
4823 of buffer or string text. */
4825 static int
4826 handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4827 Lisp_Object overlay, struct text_pos *position,
4828 ptrdiff_t bufpos, int display_replaced_p,
4829 int frame_window_p)
4831 Lisp_Object form;
4832 Lisp_Object location, value;
4833 struct text_pos start_pos = *position;
4834 int valid_p;
4836 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4837 If the result is non-nil, use VALUE instead of SPEC. */
4838 form = Qt;
4839 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
4841 spec = XCDR (spec);
4842 if (!CONSP (spec))
4843 return 0;
4844 form = XCAR (spec);
4845 spec = XCDR (spec);
4848 if (!NILP (form) && !EQ (form, Qt))
4850 ptrdiff_t count = SPECPDL_INDEX ();
4851 struct gcpro gcpro1;
4853 /* Bind `object' to the object having the `display' property, a
4854 buffer or string. Bind `position' to the position in the
4855 object where the property was found, and `buffer-position'
4856 to the current position in the buffer. */
4858 if (NILP (object))
4859 XSETBUFFER (object, current_buffer);
4860 specbind (Qobject, object);
4861 specbind (Qposition, make_number (CHARPOS (*position)));
4862 specbind (Qbuffer_position, make_number (bufpos));
4863 GCPRO1 (form);
4864 form = safe_eval (form);
4865 UNGCPRO;
4866 unbind_to (count, Qnil);
4869 if (NILP (form))
4870 return 0;
4872 /* Handle `(height HEIGHT)' specifications. */
4873 if (CONSP (spec)
4874 && EQ (XCAR (spec), Qheight)
4875 && CONSP (XCDR (spec)))
4877 if (it)
4879 if (!FRAME_WINDOW_P (it->f))
4880 return 0;
4882 it->font_height = XCAR (XCDR (spec));
4883 if (!NILP (it->font_height))
4885 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4886 int new_height = -1;
4888 if (CONSP (it->font_height)
4889 && (EQ (XCAR (it->font_height), Qplus)
4890 || EQ (XCAR (it->font_height), Qminus))
4891 && CONSP (XCDR (it->font_height))
4892 && RANGED_INTEGERP (0, XCAR (XCDR (it->font_height)), INT_MAX))
4894 /* `(+ N)' or `(- N)' where N is an integer. */
4895 int steps = XINT (XCAR (XCDR (it->font_height)));
4896 if (EQ (XCAR (it->font_height), Qplus))
4897 steps = - steps;
4898 it->face_id = smaller_face (it->f, it->face_id, steps);
4900 else if (FUNCTIONP (it->font_height))
4902 /* Call function with current height as argument.
4903 Value is the new height. */
4904 Lisp_Object height;
4905 height = safe_call1 (it->font_height,
4906 face->lface[LFACE_HEIGHT_INDEX]);
4907 if (NUMBERP (height))
4908 new_height = XFLOATINT (height);
4910 else if (NUMBERP (it->font_height))
4912 /* Value is a multiple of the canonical char height. */
4913 struct face *f;
4915 f = FACE_FROM_ID (it->f,
4916 lookup_basic_face (it->f, DEFAULT_FACE_ID));
4917 new_height = (XFLOATINT (it->font_height)
4918 * XINT (f->lface[LFACE_HEIGHT_INDEX]));
4920 else
4922 /* Evaluate IT->font_height with `height' bound to the
4923 current specified height to get the new height. */
4924 ptrdiff_t count = SPECPDL_INDEX ();
4926 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
4927 value = safe_eval (it->font_height);
4928 unbind_to (count, Qnil);
4930 if (NUMBERP (value))
4931 new_height = XFLOATINT (value);
4934 if (new_height > 0)
4935 it->face_id = face_with_height (it->f, it->face_id, new_height);
4939 return 0;
4942 /* Handle `(space-width WIDTH)'. */
4943 if (CONSP (spec)
4944 && EQ (XCAR (spec), Qspace_width)
4945 && CONSP (XCDR (spec)))
4947 if (it)
4949 if (!FRAME_WINDOW_P (it->f))
4950 return 0;
4952 value = XCAR (XCDR (spec));
4953 if (NUMBERP (value) && XFLOATINT (value) > 0)
4954 it->space_width = value;
4957 return 0;
4960 /* Handle `(slice X Y WIDTH HEIGHT)'. */
4961 if (CONSP (spec)
4962 && EQ (XCAR (spec), Qslice))
4964 Lisp_Object tem;
4966 if (it)
4968 if (!FRAME_WINDOW_P (it->f))
4969 return 0;
4971 if (tem = XCDR (spec), CONSP (tem))
4973 it->slice.x = XCAR (tem);
4974 if (tem = XCDR (tem), CONSP (tem))
4976 it->slice.y = XCAR (tem);
4977 if (tem = XCDR (tem), CONSP (tem))
4979 it->slice.width = XCAR (tem);
4980 if (tem = XCDR (tem), CONSP (tem))
4981 it->slice.height = XCAR (tem);
4987 return 0;
4990 /* Handle `(raise FACTOR)'. */
4991 if (CONSP (spec)
4992 && EQ (XCAR (spec), Qraise)
4993 && CONSP (XCDR (spec)))
4995 if (it)
4997 if (!FRAME_WINDOW_P (it->f))
4998 return 0;
5000 #ifdef HAVE_WINDOW_SYSTEM
5001 value = XCAR (XCDR (spec));
5002 if (NUMBERP (value))
5004 struct face *face = FACE_FROM_ID (it->f, it->face_id);
5005 it->voffset = - (XFLOATINT (value)
5006 * (FONT_HEIGHT (face->font)));
5008 #endif /* HAVE_WINDOW_SYSTEM */
5011 return 0;
5014 /* Don't handle the other kinds of display specifications
5015 inside a string that we got from a `display' property. */
5016 if (it && it->string_from_display_prop_p)
5017 return 0;
5019 /* Characters having this form of property are not displayed, so
5020 we have to find the end of the property. */
5021 if (it)
5023 start_pos = *position;
5024 *position = display_prop_end (it, object, start_pos);
5026 value = Qnil;
5028 /* Stop the scan at that end position--we assume that all
5029 text properties change there. */
5030 if (it)
5031 it->stop_charpos = position->charpos;
5033 /* Handle `(left-fringe BITMAP [FACE])'
5034 and `(right-fringe BITMAP [FACE])'. */
5035 if (CONSP (spec)
5036 && (EQ (XCAR (spec), Qleft_fringe)
5037 || EQ (XCAR (spec), Qright_fringe))
5038 && CONSP (XCDR (spec)))
5040 int fringe_bitmap;
5042 if (it)
5044 if (!FRAME_WINDOW_P (it->f))
5045 /* If we return here, POSITION has been advanced
5046 across the text with this property. */
5048 /* Synchronize the bidi iterator with POSITION. This is
5049 needed because we are not going to push the iterator
5050 on behalf of this display property, so there will be
5051 no pop_it call to do this synchronization for us. */
5052 if (it->bidi_p)
5054 it->position = *position;
5055 iterate_out_of_display_property (it);
5056 *position = it->position;
5058 return 1;
5061 else if (!frame_window_p)
5062 return 1;
5064 #ifdef HAVE_WINDOW_SYSTEM
5065 value = XCAR (XCDR (spec));
5066 if (!SYMBOLP (value)
5067 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
5068 /* If we return here, POSITION has been advanced
5069 across the text with this property. */
5071 if (it && it->bidi_p)
5073 it->position = *position;
5074 iterate_out_of_display_property (it);
5075 *position = it->position;
5077 return 1;
5080 if (it)
5082 int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);;
5084 if (CONSP (XCDR (XCDR (spec))))
5086 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
5087 int face_id2 = lookup_derived_face (it->f, face_name,
5088 FRINGE_FACE_ID, 0);
5089 if (face_id2 >= 0)
5090 face_id = face_id2;
5093 /* Save current settings of IT so that we can restore them
5094 when we are finished with the glyph property value. */
5095 push_it (it, position);
5097 it->area = TEXT_AREA;
5098 it->what = IT_IMAGE;
5099 it->image_id = -1; /* no image */
5100 it->position = start_pos;
5101 it->object = NILP (object) ? it->w->contents : object;
5102 it->method = GET_FROM_IMAGE;
5103 it->from_overlay = Qnil;
5104 it->face_id = face_id;
5105 it->from_disp_prop_p = true;
5107 /* Say that we haven't consumed the characters with
5108 `display' property yet. The call to pop_it in
5109 set_iterator_to_next will clean this up. */
5110 *position = start_pos;
5112 if (EQ (XCAR (spec), Qleft_fringe))
5114 it->left_user_fringe_bitmap = fringe_bitmap;
5115 it->left_user_fringe_face_id = face_id;
5117 else
5119 it->right_user_fringe_bitmap = fringe_bitmap;
5120 it->right_user_fringe_face_id = face_id;
5123 #endif /* HAVE_WINDOW_SYSTEM */
5124 return 1;
5127 /* Prepare to handle `((margin left-margin) ...)',
5128 `((margin right-margin) ...)' and `((margin nil) ...)'
5129 prefixes for display specifications. */
5130 location = Qunbound;
5131 if (CONSP (spec) && CONSP (XCAR (spec)))
5133 Lisp_Object tem;
5135 value = XCDR (spec);
5136 if (CONSP (value))
5137 value = XCAR (value);
5139 tem = XCAR (spec);
5140 if (EQ (XCAR (tem), Qmargin)
5141 && (tem = XCDR (tem),
5142 tem = CONSP (tem) ? XCAR (tem) : Qnil,
5143 (NILP (tem)
5144 || EQ (tem, Qleft_margin)
5145 || EQ (tem, Qright_margin))))
5146 location = tem;
5149 if (EQ (location, Qunbound))
5151 location = Qnil;
5152 value = spec;
5155 /* After this point, VALUE is the property after any
5156 margin prefix has been stripped. It must be a string,
5157 an image specification, or `(space ...)'.
5159 LOCATION specifies where to display: `left-margin',
5160 `right-margin' or nil. */
5162 valid_p = (STRINGP (value)
5163 #ifdef HAVE_WINDOW_SYSTEM
5164 || ((it ? FRAME_WINDOW_P (it->f) : frame_window_p)
5165 && valid_image_p (value))
5166 #endif /* not HAVE_WINDOW_SYSTEM */
5167 || (CONSP (value) && EQ (XCAR (value), Qspace)));
5169 if (valid_p && !display_replaced_p)
5171 int retval = 1;
5173 if (!it)
5175 /* Callers need to know whether the display spec is any kind
5176 of `(space ...)' spec that is about to affect text-area
5177 display. */
5178 if (CONSP (value) && EQ (XCAR (value), Qspace) && NILP (location))
5179 retval = 2;
5180 return retval;
5183 /* Save current settings of IT so that we can restore them
5184 when we are finished with the glyph property value. */
5185 push_it (it, position);
5186 it->from_overlay = overlay;
5187 it->from_disp_prop_p = true;
5189 if (NILP (location))
5190 it->area = TEXT_AREA;
5191 else if (EQ (location, Qleft_margin))
5192 it->area = LEFT_MARGIN_AREA;
5193 else
5194 it->area = RIGHT_MARGIN_AREA;
5196 if (STRINGP (value))
5198 it->string = value;
5199 it->multibyte_p = STRING_MULTIBYTE (it->string);
5200 it->current.overlay_string_index = -1;
5201 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5202 it->end_charpos = it->string_nchars = SCHARS (it->string);
5203 it->method = GET_FROM_STRING;
5204 it->stop_charpos = 0;
5205 it->prev_stop = 0;
5206 it->base_level_stop = 0;
5207 it->string_from_display_prop_p = true;
5208 /* Say that we haven't consumed the characters with
5209 `display' property yet. The call to pop_it in
5210 set_iterator_to_next will clean this up. */
5211 if (BUFFERP (object))
5212 *position = start_pos;
5214 /* Force paragraph direction to be that of the parent
5215 object. If the parent object's paragraph direction is
5216 not yet determined, default to L2R. */
5217 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
5218 it->paragraph_embedding = it->bidi_it.paragraph_dir;
5219 else
5220 it->paragraph_embedding = L2R;
5222 /* Set up the bidi iterator for this display string. */
5223 if (it->bidi_p)
5225 it->bidi_it.string.lstring = it->string;
5226 it->bidi_it.string.s = NULL;
5227 it->bidi_it.string.schars = it->end_charpos;
5228 it->bidi_it.string.bufpos = bufpos;
5229 it->bidi_it.string.from_disp_str = 1;
5230 it->bidi_it.string.unibyte = !it->multibyte_p;
5231 it->bidi_it.w = it->w;
5232 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5235 else if (CONSP (value) && EQ (XCAR (value), Qspace))
5237 it->method = GET_FROM_STRETCH;
5238 it->object = value;
5239 *position = it->position = start_pos;
5240 retval = 1 + (it->area == TEXT_AREA);
5242 #ifdef HAVE_WINDOW_SYSTEM
5243 else
5245 it->what = IT_IMAGE;
5246 it->image_id = lookup_image (it->f, value);
5247 it->position = start_pos;
5248 it->object = NILP (object) ? it->w->contents : object;
5249 it->method = GET_FROM_IMAGE;
5251 /* Say that we haven't consumed the characters with
5252 `display' property yet. The call to pop_it in
5253 set_iterator_to_next will clean this up. */
5254 *position = start_pos;
5256 #endif /* HAVE_WINDOW_SYSTEM */
5258 return retval;
5261 /* Invalid property or property not supported. Restore
5262 POSITION to what it was before. */
5263 *position = start_pos;
5264 return 0;
5267 /* Check if PROP is a display property value whose text should be
5268 treated as intangible. OVERLAY is the overlay from which PROP
5269 came, or nil if it came from a text property. CHARPOS and BYTEPOS
5270 specify the buffer position covered by PROP. */
5273 display_prop_intangible_p (Lisp_Object prop, Lisp_Object overlay,
5274 ptrdiff_t charpos, ptrdiff_t bytepos)
5276 int frame_window_p = FRAME_WINDOW_P (XFRAME (selected_frame));
5277 struct text_pos position;
5279 SET_TEXT_POS (position, charpos, bytepos);
5280 return handle_display_spec (NULL, prop, Qnil, overlay,
5281 &position, charpos, frame_window_p);
5285 /* Return 1 if PROP is a display sub-property value containing STRING.
5287 Implementation note: this and the following function are really
5288 special cases of handle_display_spec and
5289 handle_single_display_spec, and should ideally use the same code.
5290 Until they do, these two pairs must be consistent and must be
5291 modified in sync. */
5293 static int
5294 single_display_spec_string_p (Lisp_Object prop, Lisp_Object string)
5296 if (EQ (string, prop))
5297 return 1;
5299 /* Skip over `when FORM'. */
5300 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
5302 prop = XCDR (prop);
5303 if (!CONSP (prop))
5304 return 0;
5305 /* Actually, the condition following `when' should be eval'ed,
5306 like handle_single_display_spec does, and we should return
5307 zero if it evaluates to nil. However, this function is
5308 called only when the buffer was already displayed and some
5309 glyph in the glyph matrix was found to come from a display
5310 string. Therefore, the condition was already evaluated, and
5311 the result was non-nil, otherwise the display string wouldn't
5312 have been displayed and we would have never been called for
5313 this property. Thus, we can skip the evaluation and assume
5314 its result is non-nil. */
5315 prop = XCDR (prop);
5318 if (CONSP (prop))
5319 /* Skip over `margin LOCATION'. */
5320 if (EQ (XCAR (prop), Qmargin))
5322 prop = XCDR (prop);
5323 if (!CONSP (prop))
5324 return 0;
5326 prop = XCDR (prop);
5327 if (!CONSP (prop))
5328 return 0;
5331 return EQ (prop, string) || (CONSP (prop) && EQ (XCAR (prop), string));
5335 /* Return 1 if STRING appears in the `display' property PROP. */
5337 static int
5338 display_prop_string_p (Lisp_Object prop, Lisp_Object string)
5340 if (CONSP (prop)
5341 && !EQ (XCAR (prop), Qwhen)
5342 && !(CONSP (XCAR (prop)) && EQ (Qmargin, XCAR (XCAR (prop)))))
5344 /* A list of sub-properties. */
5345 while (CONSP (prop))
5347 if (single_display_spec_string_p (XCAR (prop), string))
5348 return 1;
5349 prop = XCDR (prop);
5352 else if (VECTORP (prop))
5354 /* A vector of sub-properties. */
5355 ptrdiff_t i;
5356 for (i = 0; i < ASIZE (prop); ++i)
5357 if (single_display_spec_string_p (AREF (prop, i), string))
5358 return 1;
5360 else
5361 return single_display_spec_string_p (prop, string);
5363 return 0;
5366 /* Look for STRING in overlays and text properties in the current
5367 buffer, between character positions FROM and TO (excluding TO).
5368 BACK_P non-zero means look back (in this case, TO is supposed to be
5369 less than FROM).
5370 Value is the first character position where STRING was found, or
5371 zero if it wasn't found before hitting TO.
5373 This function may only use code that doesn't eval because it is
5374 called asynchronously from note_mouse_highlight. */
5376 static ptrdiff_t
5377 string_buffer_position_lim (Lisp_Object string,
5378 ptrdiff_t from, ptrdiff_t to, int back_p)
5380 Lisp_Object limit, prop, pos;
5381 int found = 0;
5383 pos = make_number (max (from, BEGV));
5385 if (!back_p) /* looking forward */
5387 limit = make_number (min (to, ZV));
5388 while (!found && !EQ (pos, limit))
5390 prop = Fget_char_property (pos, Qdisplay, Qnil);
5391 if (!NILP (prop) && display_prop_string_p (prop, string))
5392 found = 1;
5393 else
5394 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil,
5395 limit);
5398 else /* looking back */
5400 limit = make_number (max (to, BEGV));
5401 while (!found && !EQ (pos, limit))
5403 prop = Fget_char_property (pos, Qdisplay, Qnil);
5404 if (!NILP (prop) && display_prop_string_p (prop, string))
5405 found = 1;
5406 else
5407 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
5408 limit);
5412 return found ? XINT (pos) : 0;
5415 /* Determine which buffer position in current buffer STRING comes from.
5416 AROUND_CHARPOS is an approximate position where it could come from.
5417 Value is the buffer position or 0 if it couldn't be determined.
5419 This function is necessary because we don't record buffer positions
5420 in glyphs generated from strings (to keep struct glyph small).
5421 This function may only use code that doesn't eval because it is
5422 called asynchronously from note_mouse_highlight. */
5424 static ptrdiff_t
5425 string_buffer_position (Lisp_Object string, ptrdiff_t around_charpos)
5427 const int MAX_DISTANCE = 1000;
5428 ptrdiff_t found = string_buffer_position_lim (string, around_charpos,
5429 around_charpos + MAX_DISTANCE,
5432 if (!found)
5433 found = string_buffer_position_lim (string, around_charpos,
5434 around_charpos - MAX_DISTANCE, 1);
5435 return found;
5440 /***********************************************************************
5441 `composition' property
5442 ***********************************************************************/
5444 /* Set up iterator IT from `composition' property at its current
5445 position. Called from handle_stop. */
5447 static enum prop_handled
5448 handle_composition_prop (struct it *it)
5450 Lisp_Object prop, string;
5451 ptrdiff_t pos, pos_byte, start, end;
5453 if (STRINGP (it->string))
5455 unsigned char *s;
5457 pos = IT_STRING_CHARPOS (*it);
5458 pos_byte = IT_STRING_BYTEPOS (*it);
5459 string = it->string;
5460 s = SDATA (string) + pos_byte;
5461 it->c = STRING_CHAR (s);
5463 else
5465 pos = IT_CHARPOS (*it);
5466 pos_byte = IT_BYTEPOS (*it);
5467 string = Qnil;
5468 it->c = FETCH_CHAR (pos_byte);
5471 /* If there's a valid composition and point is not inside of the
5472 composition (in the case that the composition is from the current
5473 buffer), draw a glyph composed from the composition components. */
5474 if (find_composition (pos, -1, &start, &end, &prop, string)
5475 && composition_valid_p (start, end, prop)
5476 && (STRINGP (it->string) || (PT <= start || PT >= end)))
5478 if (start < pos)
5479 /* As we can't handle this situation (perhaps font-lock added
5480 a new composition), we just return here hoping that next
5481 redisplay will detect this composition much earlier. */
5482 return HANDLED_NORMALLY;
5483 if (start != pos)
5485 if (STRINGP (it->string))
5486 pos_byte = string_char_to_byte (it->string, start);
5487 else
5488 pos_byte = CHAR_TO_BYTE (start);
5490 it->cmp_it.id = get_composition_id (start, pos_byte, end - start,
5491 prop, string);
5493 if (it->cmp_it.id >= 0)
5495 it->cmp_it.ch = -1;
5496 it->cmp_it.nchars = COMPOSITION_LENGTH (prop);
5497 it->cmp_it.nglyphs = -1;
5501 return HANDLED_NORMALLY;
5506 /***********************************************************************
5507 Overlay strings
5508 ***********************************************************************/
5510 /* The following structure is used to record overlay strings for
5511 later sorting in load_overlay_strings. */
5513 struct overlay_entry
5515 Lisp_Object overlay;
5516 Lisp_Object string;
5517 EMACS_INT priority;
5518 int after_string_p;
5522 /* Set up iterator IT from overlay strings at its current position.
5523 Called from handle_stop. */
5525 static enum prop_handled
5526 handle_overlay_change (struct it *it)
5528 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
5529 return HANDLED_RECOMPUTE_PROPS;
5530 else
5531 return HANDLED_NORMALLY;
5535 /* Set up the next overlay string for delivery by IT, if there is an
5536 overlay string to deliver. Called by set_iterator_to_next when the
5537 end of the current overlay string is reached. If there are more
5538 overlay strings to display, IT->string and
5539 IT->current.overlay_string_index are set appropriately here.
5540 Otherwise IT->string is set to nil. */
5542 static void
5543 next_overlay_string (struct it *it)
5545 ++it->current.overlay_string_index;
5546 if (it->current.overlay_string_index == it->n_overlay_strings)
5548 /* No more overlay strings. Restore IT's settings to what
5549 they were before overlay strings were processed, and
5550 continue to deliver from current_buffer. */
5552 it->ellipsis_p = (it->stack[it->sp - 1].display_ellipsis_p != 0);
5553 pop_it (it);
5554 eassert (it->sp > 0
5555 || (NILP (it->string)
5556 && it->method == GET_FROM_BUFFER
5557 && it->stop_charpos >= BEGV
5558 && it->stop_charpos <= it->end_charpos));
5559 it->current.overlay_string_index = -1;
5560 it->n_overlay_strings = 0;
5561 it->overlay_strings_charpos = -1;
5562 /* If there's an empty display string on the stack, pop the
5563 stack, to resync the bidi iterator with IT's position. Such
5564 empty strings are pushed onto the stack in
5565 get_overlay_strings_1. */
5566 if (it->sp > 0 && STRINGP (it->string) && !SCHARS (it->string))
5567 pop_it (it);
5569 /* If we're at the end of the buffer, record that we have
5570 processed the overlay strings there already, so that
5571 next_element_from_buffer doesn't try it again. */
5572 if (NILP (it->string) && IT_CHARPOS (*it) >= it->end_charpos)
5573 it->overlay_strings_at_end_processed_p = true;
5575 else
5577 /* There are more overlay strings to process. If
5578 IT->current.overlay_string_index has advanced to a position
5579 where we must load IT->overlay_strings with more strings, do
5580 it. We must load at the IT->overlay_strings_charpos where
5581 IT->n_overlay_strings was originally computed; when invisible
5582 text is present, this might not be IT_CHARPOS (Bug#7016). */
5583 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
5585 if (it->current.overlay_string_index && i == 0)
5586 load_overlay_strings (it, it->overlay_strings_charpos);
5588 /* Initialize IT to deliver display elements from the overlay
5589 string. */
5590 it->string = it->overlay_strings[i];
5591 it->multibyte_p = STRING_MULTIBYTE (it->string);
5592 SET_TEXT_POS (it->current.string_pos, 0, 0);
5593 it->method = GET_FROM_STRING;
5594 it->stop_charpos = 0;
5595 it->end_charpos = SCHARS (it->string);
5596 if (it->cmp_it.stop_pos >= 0)
5597 it->cmp_it.stop_pos = 0;
5598 it->prev_stop = 0;
5599 it->base_level_stop = 0;
5601 /* Set up the bidi iterator for this overlay string. */
5602 if (it->bidi_p)
5604 it->bidi_it.string.lstring = it->string;
5605 it->bidi_it.string.s = NULL;
5606 it->bidi_it.string.schars = SCHARS (it->string);
5607 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
5608 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5609 it->bidi_it.string.unibyte = !it->multibyte_p;
5610 it->bidi_it.w = it->w;
5611 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5615 CHECK_IT (it);
5619 /* Compare two overlay_entry structures E1 and E2. Used as a
5620 comparison function for qsort in load_overlay_strings. Overlay
5621 strings for the same position are sorted so that
5623 1. All after-strings come in front of before-strings, except
5624 when they come from the same overlay.
5626 2. Within after-strings, strings are sorted so that overlay strings
5627 from overlays with higher priorities come first.
5629 2. Within before-strings, strings are sorted so that overlay
5630 strings from overlays with higher priorities come last.
5632 Value is analogous to strcmp. */
5635 static int
5636 compare_overlay_entries (const void *e1, const void *e2)
5638 struct overlay_entry const *entry1 = e1;
5639 struct overlay_entry const *entry2 = e2;
5640 int result;
5642 if (entry1->after_string_p != entry2->after_string_p)
5644 /* Let after-strings appear in front of before-strings if
5645 they come from different overlays. */
5646 if (EQ (entry1->overlay, entry2->overlay))
5647 result = entry1->after_string_p ? 1 : -1;
5648 else
5649 result = entry1->after_string_p ? -1 : 1;
5651 else if (entry1->priority != entry2->priority)
5653 if (entry1->after_string_p)
5654 /* After-strings sorted in order of decreasing priority. */
5655 result = entry2->priority < entry1->priority ? -1 : 1;
5656 else
5657 /* Before-strings sorted in order of increasing priority. */
5658 result = entry1->priority < entry2->priority ? -1 : 1;
5660 else
5661 result = 0;
5663 return result;
5667 /* Load the vector IT->overlay_strings with overlay strings from IT's
5668 current buffer position, or from CHARPOS if that is > 0. Set
5669 IT->n_overlays to the total number of overlay strings found.
5671 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
5672 a time. On entry into load_overlay_strings,
5673 IT->current.overlay_string_index gives the number of overlay
5674 strings that have already been loaded by previous calls to this
5675 function.
5677 IT->add_overlay_start contains an additional overlay start
5678 position to consider for taking overlay strings from, if non-zero.
5679 This position comes into play when the overlay has an `invisible'
5680 property, and both before and after-strings. When we've skipped to
5681 the end of the overlay, because of its `invisible' property, we
5682 nevertheless want its before-string to appear.
5683 IT->add_overlay_start will contain the overlay start position
5684 in this case.
5686 Overlay strings are sorted so that after-string strings come in
5687 front of before-string strings. Within before and after-strings,
5688 strings are sorted by overlay priority. See also function
5689 compare_overlay_entries. */
5691 static void
5692 load_overlay_strings (struct it *it, ptrdiff_t charpos)
5694 Lisp_Object overlay, window, str, invisible;
5695 struct Lisp_Overlay *ov;
5696 ptrdiff_t start, end;
5697 ptrdiff_t size = 20;
5698 ptrdiff_t n = 0, i, j;
5699 int invis_p;
5700 struct overlay_entry *entries = alloca (size * sizeof *entries);
5701 USE_SAFE_ALLOCA;
5703 if (charpos <= 0)
5704 charpos = IT_CHARPOS (*it);
5706 /* Append the overlay string STRING of overlay OVERLAY to vector
5707 `entries' which has size `size' and currently contains `n'
5708 elements. AFTER_P non-zero means STRING is an after-string of
5709 OVERLAY. */
5710 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
5711 do \
5713 Lisp_Object priority; \
5715 if (n == size) \
5717 struct overlay_entry *old = entries; \
5718 SAFE_NALLOCA (entries, 2, size); \
5719 memcpy (entries, old, size * sizeof *entries); \
5720 size *= 2; \
5723 entries[n].string = (STRING); \
5724 entries[n].overlay = (OVERLAY); \
5725 priority = Foverlay_get ((OVERLAY), Qpriority); \
5726 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
5727 entries[n].after_string_p = (AFTER_P); \
5728 ++n; \
5730 while (0)
5732 /* Process overlay before the overlay center. */
5733 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
5735 XSETMISC (overlay, ov);
5736 eassert (OVERLAYP (overlay));
5737 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5738 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5740 if (end < charpos)
5741 break;
5743 /* Skip this overlay if it doesn't start or end at IT's current
5744 position. */
5745 if (end != charpos && start != charpos)
5746 continue;
5748 /* Skip this overlay if it doesn't apply to IT->w. */
5749 window = Foverlay_get (overlay, Qwindow);
5750 if (WINDOWP (window) && XWINDOW (window) != it->w)
5751 continue;
5753 /* If the text ``under'' the overlay is invisible, both before-
5754 and after-strings from this overlay are visible; start and
5755 end position are indistinguishable. */
5756 invisible = Foverlay_get (overlay, Qinvisible);
5757 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5759 /* If overlay has a non-empty before-string, record it. */
5760 if ((start == charpos || (end == charpos && invis_p))
5761 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5762 && SCHARS (str))
5763 RECORD_OVERLAY_STRING (overlay, str, 0);
5765 /* If overlay has a non-empty after-string, record it. */
5766 if ((end == charpos || (start == charpos && invis_p))
5767 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5768 && SCHARS (str))
5769 RECORD_OVERLAY_STRING (overlay, str, 1);
5772 /* Process overlays after the overlay center. */
5773 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
5775 XSETMISC (overlay, ov);
5776 eassert (OVERLAYP (overlay));
5777 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5778 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5780 if (start > charpos)
5781 break;
5783 /* Skip this overlay if it doesn't start or end at IT's current
5784 position. */
5785 if (end != charpos && start != charpos)
5786 continue;
5788 /* Skip this overlay if it doesn't apply to IT->w. */
5789 window = Foverlay_get (overlay, Qwindow);
5790 if (WINDOWP (window) && XWINDOW (window) != it->w)
5791 continue;
5793 /* If the text ``under'' the overlay is invisible, it has a zero
5794 dimension, and both before- and after-strings apply. */
5795 invisible = Foverlay_get (overlay, Qinvisible);
5796 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5798 /* If overlay has a non-empty before-string, record it. */
5799 if ((start == charpos || (end == charpos && invis_p))
5800 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5801 && SCHARS (str))
5802 RECORD_OVERLAY_STRING (overlay, str, 0);
5804 /* If overlay has a non-empty after-string, record it. */
5805 if ((end == charpos || (start == charpos && invis_p))
5806 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5807 && SCHARS (str))
5808 RECORD_OVERLAY_STRING (overlay, str, 1);
5811 #undef RECORD_OVERLAY_STRING
5813 /* Sort entries. */
5814 if (n > 1)
5815 qsort (entries, n, sizeof *entries, compare_overlay_entries);
5817 /* Record number of overlay strings, and where we computed it. */
5818 it->n_overlay_strings = n;
5819 it->overlay_strings_charpos = charpos;
5821 /* IT->current.overlay_string_index is the number of overlay strings
5822 that have already been consumed by IT. Copy some of the
5823 remaining overlay strings to IT->overlay_strings. */
5824 i = 0;
5825 j = it->current.overlay_string_index;
5826 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
5828 it->overlay_strings[i] = entries[j].string;
5829 it->string_overlays[i++] = entries[j++].overlay;
5832 CHECK_IT (it);
5833 SAFE_FREE ();
5837 /* Get the first chunk of overlay strings at IT's current buffer
5838 position, or at CHARPOS if that is > 0. Value is non-zero if at
5839 least one overlay string was found. */
5841 static int
5842 get_overlay_strings_1 (struct it *it, ptrdiff_t charpos, int compute_stop_p)
5844 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
5845 process. This fills IT->overlay_strings with strings, and sets
5846 IT->n_overlay_strings to the total number of strings to process.
5847 IT->pos.overlay_string_index has to be set temporarily to zero
5848 because load_overlay_strings needs this; it must be set to -1
5849 when no overlay strings are found because a zero value would
5850 indicate a position in the first overlay string. */
5851 it->current.overlay_string_index = 0;
5852 load_overlay_strings (it, charpos);
5854 /* If we found overlay strings, set up IT to deliver display
5855 elements from the first one. Otherwise set up IT to deliver
5856 from current_buffer. */
5857 if (it->n_overlay_strings)
5859 /* Make sure we know settings in current_buffer, so that we can
5860 restore meaningful values when we're done with the overlay
5861 strings. */
5862 if (compute_stop_p)
5863 compute_stop_pos (it);
5864 eassert (it->face_id >= 0);
5866 /* Save IT's settings. They are restored after all overlay
5867 strings have been processed. */
5868 eassert (!compute_stop_p || it->sp == 0);
5870 /* When called from handle_stop, there might be an empty display
5871 string loaded. In that case, don't bother saving it. But
5872 don't use this optimization with the bidi iterator, since we
5873 need the corresponding pop_it call to resync the bidi
5874 iterator's position with IT's position, after we are done
5875 with the overlay strings. (The corresponding call to pop_it
5876 in case of an empty display string is in
5877 next_overlay_string.) */
5878 if (!(!it->bidi_p
5879 && STRINGP (it->string) && !SCHARS (it->string)))
5880 push_it (it, NULL);
5882 /* Set up IT to deliver display elements from the first overlay
5883 string. */
5884 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5885 it->string = it->overlay_strings[0];
5886 it->from_overlay = Qnil;
5887 it->stop_charpos = 0;
5888 eassert (STRINGP (it->string));
5889 it->end_charpos = SCHARS (it->string);
5890 it->prev_stop = 0;
5891 it->base_level_stop = 0;
5892 it->multibyte_p = STRING_MULTIBYTE (it->string);
5893 it->method = GET_FROM_STRING;
5894 it->from_disp_prop_p = 0;
5896 /* Force paragraph direction to be that of the parent
5897 buffer. */
5898 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
5899 it->paragraph_embedding = it->bidi_it.paragraph_dir;
5900 else
5901 it->paragraph_embedding = L2R;
5903 /* Set up the bidi iterator for this overlay string. */
5904 if (it->bidi_p)
5906 ptrdiff_t pos = (charpos > 0 ? charpos : IT_CHARPOS (*it));
5908 it->bidi_it.string.lstring = it->string;
5909 it->bidi_it.string.s = NULL;
5910 it->bidi_it.string.schars = SCHARS (it->string);
5911 it->bidi_it.string.bufpos = pos;
5912 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5913 it->bidi_it.string.unibyte = !it->multibyte_p;
5914 it->bidi_it.w = it->w;
5915 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5917 return 1;
5920 it->current.overlay_string_index = -1;
5921 return 0;
5924 static int
5925 get_overlay_strings (struct it *it, ptrdiff_t charpos)
5927 it->string = Qnil;
5928 it->method = GET_FROM_BUFFER;
5930 (void) get_overlay_strings_1 (it, charpos, 1);
5932 CHECK_IT (it);
5934 /* Value is non-zero if we found at least one overlay string. */
5935 return STRINGP (it->string);
5940 /***********************************************************************
5941 Saving and restoring state
5942 ***********************************************************************/
5944 /* Save current settings of IT on IT->stack. Called, for example,
5945 before setting up IT for an overlay string, to be able to restore
5946 IT's settings to what they were after the overlay string has been
5947 processed. If POSITION is non-NULL, it is the position to save on
5948 the stack instead of IT->position. */
5950 static void
5951 push_it (struct it *it, struct text_pos *position)
5953 struct iterator_stack_entry *p;
5955 eassert (it->sp < IT_STACK_SIZE);
5956 p = it->stack + it->sp;
5958 p->stop_charpos = it->stop_charpos;
5959 p->prev_stop = it->prev_stop;
5960 p->base_level_stop = it->base_level_stop;
5961 p->cmp_it = it->cmp_it;
5962 eassert (it->face_id >= 0);
5963 p->face_id = it->face_id;
5964 p->string = it->string;
5965 p->method = it->method;
5966 p->from_overlay = it->from_overlay;
5967 switch (p->method)
5969 case GET_FROM_IMAGE:
5970 p->u.image.object = it->object;
5971 p->u.image.image_id = it->image_id;
5972 p->u.image.slice = it->slice;
5973 break;
5974 case GET_FROM_STRETCH:
5975 p->u.stretch.object = it->object;
5976 break;
5978 p->position = position ? *position : it->position;
5979 p->current = it->current;
5980 p->end_charpos = it->end_charpos;
5981 p->string_nchars = it->string_nchars;
5982 p->area = it->area;
5983 p->multibyte_p = it->multibyte_p;
5984 p->avoid_cursor_p = it->avoid_cursor_p;
5985 p->space_width = it->space_width;
5986 p->font_height = it->font_height;
5987 p->voffset = it->voffset;
5988 p->string_from_display_prop_p = it->string_from_display_prop_p;
5989 p->string_from_prefix_prop_p = it->string_from_prefix_prop_p;
5990 p->display_ellipsis_p = 0;
5991 p->line_wrap = it->line_wrap;
5992 p->bidi_p = it->bidi_p;
5993 p->paragraph_embedding = it->paragraph_embedding;
5994 p->from_disp_prop_p = it->from_disp_prop_p;
5995 ++it->sp;
5997 /* Save the state of the bidi iterator as well. */
5998 if (it->bidi_p)
5999 bidi_push_it (&it->bidi_it);
6002 static void
6003 iterate_out_of_display_property (struct it *it)
6005 int buffer_p = !STRINGP (it->string);
6006 ptrdiff_t eob = (buffer_p ? ZV : it->end_charpos);
6007 ptrdiff_t bob = (buffer_p ? BEGV : 0);
6009 eassert (eob >= CHARPOS (it->position) && CHARPOS (it->position) >= bob);
6011 /* Maybe initialize paragraph direction. If we are at the beginning
6012 of a new paragraph, next_element_from_buffer may not have a
6013 chance to do that. */
6014 if (it->bidi_it.first_elt && it->bidi_it.charpos < eob)
6015 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
6016 /* prev_stop can be zero, so check against BEGV as well. */
6017 while (it->bidi_it.charpos >= bob
6018 && it->prev_stop <= it->bidi_it.charpos
6019 && it->bidi_it.charpos < CHARPOS (it->position)
6020 && it->bidi_it.charpos < eob)
6021 bidi_move_to_visually_next (&it->bidi_it);
6022 /* Record the stop_pos we just crossed, for when we cross it
6023 back, maybe. */
6024 if (it->bidi_it.charpos > CHARPOS (it->position))
6025 it->prev_stop = CHARPOS (it->position);
6026 /* If we ended up not where pop_it put us, resync IT's
6027 positional members with the bidi iterator. */
6028 if (it->bidi_it.charpos != CHARPOS (it->position))
6029 SET_TEXT_POS (it->position, it->bidi_it.charpos, it->bidi_it.bytepos);
6030 if (buffer_p)
6031 it->current.pos = it->position;
6032 else
6033 it->current.string_pos = it->position;
6036 /* Restore IT's settings from IT->stack. Called, for example, when no
6037 more overlay strings must be processed, and we return to delivering
6038 display elements from a buffer, or when the end of a string from a
6039 `display' property is reached and we return to delivering display
6040 elements from an overlay string, or from a buffer. */
6042 static void
6043 pop_it (struct it *it)
6045 struct iterator_stack_entry *p;
6046 int from_display_prop = it->from_disp_prop_p;
6048 eassert (it->sp > 0);
6049 --it->sp;
6050 p = it->stack + it->sp;
6051 it->stop_charpos = p->stop_charpos;
6052 it->prev_stop = p->prev_stop;
6053 it->base_level_stop = p->base_level_stop;
6054 it->cmp_it = p->cmp_it;
6055 it->face_id = p->face_id;
6056 it->current = p->current;
6057 it->position = p->position;
6058 it->string = p->string;
6059 it->from_overlay = p->from_overlay;
6060 if (NILP (it->string))
6061 SET_TEXT_POS (it->current.string_pos, -1, -1);
6062 it->method = p->method;
6063 switch (it->method)
6065 case GET_FROM_IMAGE:
6066 it->image_id = p->u.image.image_id;
6067 it->object = p->u.image.object;
6068 it->slice = p->u.image.slice;
6069 break;
6070 case GET_FROM_STRETCH:
6071 it->object = p->u.stretch.object;
6072 break;
6073 case GET_FROM_BUFFER:
6074 it->object = it->w->contents;
6075 break;
6076 case GET_FROM_STRING:
6078 struct face *face = FACE_FROM_ID (it->f, it->face_id);
6080 /* Restore the face_box_p flag, since it could have been
6081 overwritten by the face of the object that we just finished
6082 displaying. */
6083 if (face)
6084 it->face_box_p = face->box != FACE_NO_BOX;
6085 it->object = it->string;
6087 break;
6088 case GET_FROM_DISPLAY_VECTOR:
6089 if (it->s)
6090 it->method = GET_FROM_C_STRING;
6091 else if (STRINGP (it->string))
6092 it->method = GET_FROM_STRING;
6093 else
6095 it->method = GET_FROM_BUFFER;
6096 it->object = it->w->contents;
6099 it->end_charpos = p->end_charpos;
6100 it->string_nchars = p->string_nchars;
6101 it->area = p->area;
6102 it->multibyte_p = p->multibyte_p;
6103 it->avoid_cursor_p = p->avoid_cursor_p;
6104 it->space_width = p->space_width;
6105 it->font_height = p->font_height;
6106 it->voffset = p->voffset;
6107 it->string_from_display_prop_p = p->string_from_display_prop_p;
6108 it->string_from_prefix_prop_p = p->string_from_prefix_prop_p;
6109 it->line_wrap = p->line_wrap;
6110 it->bidi_p = p->bidi_p;
6111 it->paragraph_embedding = p->paragraph_embedding;
6112 it->from_disp_prop_p = p->from_disp_prop_p;
6113 if (it->bidi_p)
6115 bidi_pop_it (&it->bidi_it);
6116 /* Bidi-iterate until we get out of the portion of text, if any,
6117 covered by a `display' text property or by an overlay with
6118 `display' property. (We cannot just jump there, because the
6119 internal coherency of the bidi iterator state can not be
6120 preserved across such jumps.) We also must determine the
6121 paragraph base direction if the overlay we just processed is
6122 at the beginning of a new paragraph. */
6123 if (from_display_prop
6124 && (it->method == GET_FROM_BUFFER || it->method == GET_FROM_STRING))
6125 iterate_out_of_display_property (it);
6127 eassert ((BUFFERP (it->object)
6128 && IT_CHARPOS (*it) == it->bidi_it.charpos
6129 && IT_BYTEPOS (*it) == it->bidi_it.bytepos)
6130 || (STRINGP (it->object)
6131 && IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
6132 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos)
6133 || (CONSP (it->object) && it->method == GET_FROM_STRETCH));
6139 /***********************************************************************
6140 Moving over lines
6141 ***********************************************************************/
6143 /* Set IT's current position to the previous line start. */
6145 static void
6146 back_to_previous_line_start (struct it *it)
6148 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
6150 DEC_BOTH (cp, bp);
6151 IT_CHARPOS (*it) = find_newline_no_quit (cp, bp, -1, &IT_BYTEPOS (*it));
6155 /* Move IT to the next line start.
6157 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
6158 we skipped over part of the text (as opposed to moving the iterator
6159 continuously over the text). Otherwise, don't change the value
6160 of *SKIPPED_P.
6162 If BIDI_IT_PREV is non-NULL, store into it the state of the bidi
6163 iterator on the newline, if it was found.
6165 Newlines may come from buffer text, overlay strings, or strings
6166 displayed via the `display' property. That's the reason we can't
6167 simply use find_newline_no_quit.
6169 Note that this function may not skip over invisible text that is so
6170 because of text properties and immediately follows a newline. If
6171 it would, function reseat_at_next_visible_line_start, when called
6172 from set_iterator_to_next, would effectively make invisible
6173 characters following a newline part of the wrong glyph row, which
6174 leads to wrong cursor motion. */
6176 static int
6177 forward_to_next_line_start (struct it *it, int *skipped_p,
6178 struct bidi_it *bidi_it_prev)
6180 ptrdiff_t old_selective;
6181 int newline_found_p, n;
6182 const int MAX_NEWLINE_DISTANCE = 500;
6184 /* If already on a newline, just consume it to avoid unintended
6185 skipping over invisible text below. */
6186 if (it->what == IT_CHARACTER
6187 && it->c == '\n'
6188 && CHARPOS (it->position) == IT_CHARPOS (*it))
6190 if (it->bidi_p && bidi_it_prev)
6191 *bidi_it_prev = it->bidi_it;
6192 set_iterator_to_next (it, 0);
6193 it->c = 0;
6194 return 1;
6197 /* Don't handle selective display in the following. It's (a)
6198 unnecessary because it's done by the caller, and (b) leads to an
6199 infinite recursion because next_element_from_ellipsis indirectly
6200 calls this function. */
6201 old_selective = it->selective;
6202 it->selective = 0;
6204 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
6205 from buffer text. */
6206 for (n = newline_found_p = 0;
6207 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
6208 n += STRINGP (it->string) ? 0 : 1)
6210 if (!get_next_display_element (it))
6211 return 0;
6212 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
6213 if (newline_found_p && it->bidi_p && bidi_it_prev)
6214 *bidi_it_prev = it->bidi_it;
6215 set_iterator_to_next (it, 0);
6218 /* If we didn't find a newline near enough, see if we can use a
6219 short-cut. */
6220 if (!newline_found_p)
6222 ptrdiff_t bytepos, start = IT_CHARPOS (*it);
6223 ptrdiff_t limit = find_newline_no_quit (start, IT_BYTEPOS (*it),
6224 1, &bytepos);
6225 Lisp_Object pos;
6227 eassert (!STRINGP (it->string));
6229 /* If there isn't any `display' property in sight, and no
6230 overlays, we can just use the position of the newline in
6231 buffer text. */
6232 if (it->stop_charpos >= limit
6233 || ((pos = Fnext_single_property_change (make_number (start),
6234 Qdisplay, Qnil,
6235 make_number (limit)),
6236 NILP (pos))
6237 && next_overlay_change (start) == ZV))
6239 if (!it->bidi_p)
6241 IT_CHARPOS (*it) = limit;
6242 IT_BYTEPOS (*it) = bytepos;
6244 else
6246 struct bidi_it bprev;
6248 /* Help bidi.c avoid expensive searches for display
6249 properties and overlays, by telling it that there are
6250 none up to `limit'. */
6251 if (it->bidi_it.disp_pos < limit)
6253 it->bidi_it.disp_pos = limit;
6254 it->bidi_it.disp_prop = 0;
6256 do {
6257 bprev = it->bidi_it;
6258 bidi_move_to_visually_next (&it->bidi_it);
6259 } while (it->bidi_it.charpos != limit);
6260 IT_CHARPOS (*it) = limit;
6261 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6262 if (bidi_it_prev)
6263 *bidi_it_prev = bprev;
6265 *skipped_p = newline_found_p = true;
6267 else
6269 while (get_next_display_element (it)
6270 && !newline_found_p)
6272 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
6273 if (newline_found_p && it->bidi_p && bidi_it_prev)
6274 *bidi_it_prev = it->bidi_it;
6275 set_iterator_to_next (it, 0);
6280 it->selective = old_selective;
6281 return newline_found_p;
6285 /* Set IT's current position to the previous visible line start. Skip
6286 invisible text that is so either due to text properties or due to
6287 selective display. Caution: this does not change IT->current_x and
6288 IT->hpos. */
6290 static void
6291 back_to_previous_visible_line_start (struct it *it)
6293 while (IT_CHARPOS (*it) > BEGV)
6295 back_to_previous_line_start (it);
6297 if (IT_CHARPOS (*it) <= BEGV)
6298 break;
6300 /* If selective > 0, then lines indented more than its value are
6301 invisible. */
6302 if (it->selective > 0
6303 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6304 it->selective))
6305 continue;
6307 /* Check the newline before point for invisibility. */
6309 Lisp_Object prop;
6310 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
6311 Qinvisible, it->window);
6312 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6313 continue;
6316 if (IT_CHARPOS (*it) <= BEGV)
6317 break;
6320 struct it it2;
6321 void *it2data = NULL;
6322 ptrdiff_t pos;
6323 ptrdiff_t beg, end;
6324 Lisp_Object val, overlay;
6326 SAVE_IT (it2, *it, it2data);
6328 /* If newline is part of a composition, continue from start of composition */
6329 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
6330 && beg < IT_CHARPOS (*it))
6331 goto replaced;
6333 /* If newline is replaced by a display property, find start of overlay
6334 or interval and continue search from that point. */
6335 pos = --IT_CHARPOS (it2);
6336 --IT_BYTEPOS (it2);
6337 it2.sp = 0;
6338 bidi_unshelve_cache (NULL, 0);
6339 it2.string_from_display_prop_p = 0;
6340 it2.from_disp_prop_p = 0;
6341 if (handle_display_prop (&it2) == HANDLED_RETURN
6342 && !NILP (val = get_char_property_and_overlay
6343 (make_number (pos), Qdisplay, Qnil, &overlay))
6344 && (OVERLAYP (overlay)
6345 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
6346 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
6348 RESTORE_IT (it, it, it2data);
6349 goto replaced;
6352 /* Newline is not replaced by anything -- so we are done. */
6353 RESTORE_IT (it, it, it2data);
6354 break;
6356 replaced:
6357 if (beg < BEGV)
6358 beg = BEGV;
6359 IT_CHARPOS (*it) = beg;
6360 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
6364 it->continuation_lines_width = 0;
6366 eassert (IT_CHARPOS (*it) >= BEGV);
6367 eassert (IT_CHARPOS (*it) == BEGV
6368 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6369 CHECK_IT (it);
6373 /* Reseat iterator IT at the previous visible line start. Skip
6374 invisible text that is so either due to text properties or due to
6375 selective display. At the end, update IT's overlay information,
6376 face information etc. */
6378 void
6379 reseat_at_previous_visible_line_start (struct it *it)
6381 back_to_previous_visible_line_start (it);
6382 reseat (it, it->current.pos, 1);
6383 CHECK_IT (it);
6387 /* Reseat iterator IT on the next visible line start in the current
6388 buffer. ON_NEWLINE_P non-zero means position IT on the newline
6389 preceding the line start. Skip over invisible text that is so
6390 because of selective display. Compute faces, overlays etc at the
6391 new position. Note that this function does not skip over text that
6392 is invisible because of text properties. */
6394 static void
6395 reseat_at_next_visible_line_start (struct it *it, int on_newline_p)
6397 int newline_found_p, skipped_p = 0;
6398 struct bidi_it bidi_it_prev;
6400 newline_found_p = forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6402 /* Skip over lines that are invisible because they are indented
6403 more than the value of IT->selective. */
6404 if (it->selective > 0)
6405 while (IT_CHARPOS (*it) < ZV
6406 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6407 it->selective))
6409 eassert (IT_BYTEPOS (*it) == BEGV
6410 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6411 newline_found_p =
6412 forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6415 /* Position on the newline if that's what's requested. */
6416 if (on_newline_p && newline_found_p)
6418 if (STRINGP (it->string))
6420 if (IT_STRING_CHARPOS (*it) > 0)
6422 if (!it->bidi_p)
6424 --IT_STRING_CHARPOS (*it);
6425 --IT_STRING_BYTEPOS (*it);
6427 else
6429 /* We need to restore the bidi iterator to the state
6430 it had on the newline, and resync the IT's
6431 position with that. */
6432 it->bidi_it = bidi_it_prev;
6433 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
6434 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
6438 else if (IT_CHARPOS (*it) > BEGV)
6440 if (!it->bidi_p)
6442 --IT_CHARPOS (*it);
6443 --IT_BYTEPOS (*it);
6445 else
6447 /* We need to restore the bidi iterator to the state it
6448 had on the newline and resync IT with that. */
6449 it->bidi_it = bidi_it_prev;
6450 IT_CHARPOS (*it) = it->bidi_it.charpos;
6451 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6453 reseat (it, it->current.pos, 0);
6456 else if (skipped_p)
6457 reseat (it, it->current.pos, 0);
6459 CHECK_IT (it);
6464 /***********************************************************************
6465 Changing an iterator's position
6466 ***********************************************************************/
6468 /* Change IT's current position to POS in current_buffer. If FORCE_P
6469 is non-zero, always check for text properties at the new position.
6470 Otherwise, text properties are only looked up if POS >=
6471 IT->check_charpos of a property. */
6473 static void
6474 reseat (struct it *it, struct text_pos pos, int force_p)
6476 ptrdiff_t original_pos = IT_CHARPOS (*it);
6478 reseat_1 (it, pos, 0);
6480 /* Determine where to check text properties. Avoid doing it
6481 where possible because text property lookup is very expensive. */
6482 if (force_p
6483 || CHARPOS (pos) > it->stop_charpos
6484 || CHARPOS (pos) < original_pos)
6486 if (it->bidi_p)
6488 /* For bidi iteration, we need to prime prev_stop and
6489 base_level_stop with our best estimations. */
6490 /* Implementation note: Of course, POS is not necessarily a
6491 stop position, so assigning prev_pos to it is a lie; we
6492 should have called compute_stop_backwards. However, if
6493 the current buffer does not include any R2L characters,
6494 that call would be a waste of cycles, because the
6495 iterator will never move back, and thus never cross this
6496 "fake" stop position. So we delay that backward search
6497 until the time we really need it, in next_element_from_buffer. */
6498 if (CHARPOS (pos) != it->prev_stop)
6499 it->prev_stop = CHARPOS (pos);
6500 if (CHARPOS (pos) < it->base_level_stop)
6501 it->base_level_stop = 0; /* meaning it's unknown */
6502 handle_stop (it);
6504 else
6506 handle_stop (it);
6507 it->prev_stop = it->base_level_stop = 0;
6512 CHECK_IT (it);
6516 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
6517 IT->stop_pos to POS, also. */
6519 static void
6520 reseat_1 (struct it *it, struct text_pos pos, int set_stop_p)
6522 /* Don't call this function when scanning a C string. */
6523 eassert (it->s == NULL);
6525 /* POS must be a reasonable value. */
6526 eassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
6528 it->current.pos = it->position = pos;
6529 it->end_charpos = ZV;
6530 it->dpvec = NULL;
6531 it->current.dpvec_index = -1;
6532 it->current.overlay_string_index = -1;
6533 IT_STRING_CHARPOS (*it) = -1;
6534 IT_STRING_BYTEPOS (*it) = -1;
6535 it->string = Qnil;
6536 it->method = GET_FROM_BUFFER;
6537 it->object = it->w->contents;
6538 it->area = TEXT_AREA;
6539 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
6540 it->sp = 0;
6541 it->string_from_display_prop_p = 0;
6542 it->string_from_prefix_prop_p = 0;
6544 it->from_disp_prop_p = 0;
6545 it->face_before_selective_p = 0;
6546 if (it->bidi_p)
6548 bidi_init_it (IT_CHARPOS (*it), IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6549 &it->bidi_it);
6550 bidi_unshelve_cache (NULL, 0);
6551 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6552 it->bidi_it.string.s = NULL;
6553 it->bidi_it.string.lstring = Qnil;
6554 it->bidi_it.string.bufpos = 0;
6555 it->bidi_it.string.from_disp_str = 0;
6556 it->bidi_it.string.unibyte = 0;
6557 it->bidi_it.w = it->w;
6560 if (set_stop_p)
6562 it->stop_charpos = CHARPOS (pos);
6563 it->base_level_stop = CHARPOS (pos);
6565 /* This make the information stored in it->cmp_it invalidate. */
6566 it->cmp_it.id = -1;
6570 /* Set up IT for displaying a string, starting at CHARPOS in window W.
6571 If S is non-null, it is a C string to iterate over. Otherwise,
6572 STRING gives a Lisp string to iterate over.
6574 If PRECISION > 0, don't return more then PRECISION number of
6575 characters from the string.
6577 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
6578 characters have been returned. FIELD_WIDTH < 0 means an infinite
6579 field width.
6581 MULTIBYTE = 0 means disable processing of multibyte characters,
6582 MULTIBYTE > 0 means enable it,
6583 MULTIBYTE < 0 means use IT->multibyte_p.
6585 IT must be initialized via a prior call to init_iterator before
6586 calling this function. */
6588 static void
6589 reseat_to_string (struct it *it, const char *s, Lisp_Object string,
6590 ptrdiff_t charpos, ptrdiff_t precision, int field_width,
6591 int multibyte)
6593 /* No text property checks performed by default, but see below. */
6594 it->stop_charpos = -1;
6596 /* Set iterator position and end position. */
6597 memset (&it->current, 0, sizeof it->current);
6598 it->current.overlay_string_index = -1;
6599 it->current.dpvec_index = -1;
6600 eassert (charpos >= 0);
6602 /* If STRING is specified, use its multibyteness, otherwise use the
6603 setting of MULTIBYTE, if specified. */
6604 if (multibyte >= 0)
6605 it->multibyte_p = multibyte > 0;
6607 /* Bidirectional reordering of strings is controlled by the default
6608 value of bidi-display-reordering. Don't try to reorder while
6609 loading loadup.el, as the necessary character property tables are
6610 not yet available. */
6611 it->bidi_p =
6612 NILP (Vpurify_flag)
6613 && !NILP (BVAR (&buffer_defaults, bidi_display_reordering));
6615 if (s == NULL)
6617 eassert (STRINGP (string));
6618 it->string = string;
6619 it->s = NULL;
6620 it->end_charpos = it->string_nchars = SCHARS (string);
6621 it->method = GET_FROM_STRING;
6622 it->current.string_pos = string_pos (charpos, string);
6624 if (it->bidi_p)
6626 it->bidi_it.string.lstring = string;
6627 it->bidi_it.string.s = NULL;
6628 it->bidi_it.string.schars = it->end_charpos;
6629 it->bidi_it.string.bufpos = 0;
6630 it->bidi_it.string.from_disp_str = 0;
6631 it->bidi_it.string.unibyte = !it->multibyte_p;
6632 it->bidi_it.w = it->w;
6633 bidi_init_it (charpos, IT_STRING_BYTEPOS (*it),
6634 FRAME_WINDOW_P (it->f), &it->bidi_it);
6637 else
6639 it->s = (const unsigned char *) s;
6640 it->string = Qnil;
6642 /* Note that we use IT->current.pos, not it->current.string_pos,
6643 for displaying C strings. */
6644 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
6645 if (it->multibyte_p)
6647 it->current.pos = c_string_pos (charpos, s, 1);
6648 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
6650 else
6652 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
6653 it->end_charpos = it->string_nchars = strlen (s);
6656 if (it->bidi_p)
6658 it->bidi_it.string.lstring = Qnil;
6659 it->bidi_it.string.s = (const unsigned char *) s;
6660 it->bidi_it.string.schars = it->end_charpos;
6661 it->bidi_it.string.bufpos = 0;
6662 it->bidi_it.string.from_disp_str = 0;
6663 it->bidi_it.string.unibyte = !it->multibyte_p;
6664 it->bidi_it.w = it->w;
6665 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6666 &it->bidi_it);
6668 it->method = GET_FROM_C_STRING;
6671 /* PRECISION > 0 means don't return more than PRECISION characters
6672 from the string. */
6673 if (precision > 0 && it->end_charpos - charpos > precision)
6675 it->end_charpos = it->string_nchars = charpos + precision;
6676 if (it->bidi_p)
6677 it->bidi_it.string.schars = it->end_charpos;
6680 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
6681 characters have been returned. FIELD_WIDTH == 0 means don't pad,
6682 FIELD_WIDTH < 0 means infinite field width. This is useful for
6683 padding with `-' at the end of a mode line. */
6684 if (field_width < 0)
6685 field_width = INFINITY;
6686 /* Implementation note: We deliberately don't enlarge
6687 it->bidi_it.string.schars here to fit it->end_charpos, because
6688 the bidi iterator cannot produce characters out of thin air. */
6689 if (field_width > it->end_charpos - charpos)
6690 it->end_charpos = charpos + field_width;
6692 /* Use the standard display table for displaying strings. */
6693 if (DISP_TABLE_P (Vstandard_display_table))
6694 it->dp = XCHAR_TABLE (Vstandard_display_table);
6696 it->stop_charpos = charpos;
6697 it->prev_stop = charpos;
6698 it->base_level_stop = 0;
6699 if (it->bidi_p)
6701 it->bidi_it.first_elt = 1;
6702 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6703 it->bidi_it.disp_pos = -1;
6705 if (s == NULL && it->multibyte_p)
6707 ptrdiff_t endpos = SCHARS (it->string);
6708 if (endpos > it->end_charpos)
6709 endpos = it->end_charpos;
6710 composition_compute_stop_pos (&it->cmp_it, charpos, -1, endpos,
6711 it->string);
6713 CHECK_IT (it);
6718 /***********************************************************************
6719 Iteration
6720 ***********************************************************************/
6722 /* Map enum it_method value to corresponding next_element_from_* function. */
6724 static int (* get_next_element[NUM_IT_METHODS]) (struct it *it) =
6726 next_element_from_buffer,
6727 next_element_from_display_vector,
6728 next_element_from_string,
6729 next_element_from_c_string,
6730 next_element_from_image,
6731 next_element_from_stretch
6734 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
6737 /* Return 1 iff a character at CHARPOS (and BYTEPOS) is composed
6738 (possibly with the following characters). */
6740 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS) \
6741 ((IT)->cmp_it.id >= 0 \
6742 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
6743 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
6744 END_CHARPOS, (IT)->w, \
6745 FACE_FROM_ID ((IT)->f, (IT)->face_id), \
6746 (IT)->string)))
6749 /* Lookup the char-table Vglyphless_char_display for character C (-1
6750 if we want information for no-font case), and return the display
6751 method symbol. By side-effect, update it->what and
6752 it->glyphless_method. This function is called from
6753 get_next_display_element for each character element, and from
6754 x_produce_glyphs when no suitable font was found. */
6756 Lisp_Object
6757 lookup_glyphless_char_display (int c, struct it *it)
6759 Lisp_Object glyphless_method = Qnil;
6761 if (CHAR_TABLE_P (Vglyphless_char_display)
6762 && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display)) >= 1)
6764 if (c >= 0)
6766 glyphless_method = CHAR_TABLE_REF (Vglyphless_char_display, c);
6767 if (CONSP (glyphless_method))
6768 glyphless_method = FRAME_WINDOW_P (it->f)
6769 ? XCAR (glyphless_method)
6770 : XCDR (glyphless_method);
6772 else
6773 glyphless_method = XCHAR_TABLE (Vglyphless_char_display)->extras[0];
6776 retry:
6777 if (NILP (glyphless_method))
6779 if (c >= 0)
6780 /* The default is to display the character by a proper font. */
6781 return Qnil;
6782 /* The default for the no-font case is to display an empty box. */
6783 glyphless_method = Qempty_box;
6785 if (EQ (glyphless_method, Qzero_width))
6787 if (c >= 0)
6788 return glyphless_method;
6789 /* This method can't be used for the no-font case. */
6790 glyphless_method = Qempty_box;
6792 if (EQ (glyphless_method, Qthin_space))
6793 it->glyphless_method = GLYPHLESS_DISPLAY_THIN_SPACE;
6794 else if (EQ (glyphless_method, Qempty_box))
6795 it->glyphless_method = GLYPHLESS_DISPLAY_EMPTY_BOX;
6796 else if (EQ (glyphless_method, Qhex_code))
6797 it->glyphless_method = GLYPHLESS_DISPLAY_HEX_CODE;
6798 else if (STRINGP (glyphless_method))
6799 it->glyphless_method = GLYPHLESS_DISPLAY_ACRONYM;
6800 else
6802 /* Invalid value. We use the default method. */
6803 glyphless_method = Qnil;
6804 goto retry;
6806 it->what = IT_GLYPHLESS;
6807 return glyphless_method;
6810 /* Merge escape glyph face and cache the result. */
6812 static struct frame *last_escape_glyph_frame = NULL;
6813 static int last_escape_glyph_face_id = (1 << FACE_ID_BITS);
6814 static int last_escape_glyph_merged_face_id = 0;
6816 static int
6817 merge_escape_glyph_face (struct it *it)
6819 int face_id;
6821 if (it->f == last_escape_glyph_frame
6822 && it->face_id == last_escape_glyph_face_id)
6823 face_id = last_escape_glyph_merged_face_id;
6824 else
6826 /* Merge the `escape-glyph' face into the current face. */
6827 face_id = merge_faces (it->f, Qescape_glyph, 0, it->face_id);
6828 last_escape_glyph_frame = it->f;
6829 last_escape_glyph_face_id = it->face_id;
6830 last_escape_glyph_merged_face_id = face_id;
6832 return face_id;
6835 /* Likewise for glyphless glyph face. */
6837 static struct frame *last_glyphless_glyph_frame = NULL;
6838 static int last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
6839 static int last_glyphless_glyph_merged_face_id = 0;
6842 merge_glyphless_glyph_face (struct it *it)
6844 int face_id;
6846 if (it->f == last_glyphless_glyph_frame
6847 && it->face_id == last_glyphless_glyph_face_id)
6848 face_id = last_glyphless_glyph_merged_face_id;
6849 else
6851 /* Merge the `glyphless-char' face into the current face. */
6852 face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
6853 last_glyphless_glyph_frame = it->f;
6854 last_glyphless_glyph_face_id = it->face_id;
6855 last_glyphless_glyph_merged_face_id = face_id;
6857 return face_id;
6860 /* Load IT's display element fields with information about the next
6861 display element from the current position of IT. Value is zero if
6862 end of buffer (or C string) is reached. */
6864 static int
6865 get_next_display_element (struct it *it)
6867 /* Non-zero means that we found a display element. Zero means that
6868 we hit the end of what we iterate over. Performance note: the
6869 function pointer `method' used here turns out to be faster than
6870 using a sequence of if-statements. */
6871 int success_p;
6873 get_next:
6874 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
6876 if (it->what == IT_CHARACTER)
6878 /* UAX#9, L4: "A character is depicted by a mirrored glyph if
6879 and only if (a) the resolved directionality of that character
6880 is R..." */
6881 /* FIXME: Do we need an exception for characters from display
6882 tables? */
6883 if (it->bidi_p && it->bidi_it.type == STRONG_R)
6884 it->c = bidi_mirror_char (it->c);
6885 /* Map via display table or translate control characters.
6886 IT->c, IT->len etc. have been set to the next character by
6887 the function call above. If we have a display table, and it
6888 contains an entry for IT->c, translate it. Don't do this if
6889 IT->c itself comes from a display table, otherwise we could
6890 end up in an infinite recursion. (An alternative could be to
6891 count the recursion depth of this function and signal an
6892 error when a certain maximum depth is reached.) Is it worth
6893 it? */
6894 if (success_p && it->dpvec == NULL)
6896 Lisp_Object dv;
6897 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
6898 int nonascii_space_p = 0;
6899 int nonascii_hyphen_p = 0;
6900 int c = it->c; /* This is the character to display. */
6902 if (! it->multibyte_p && ! ASCII_CHAR_P (c))
6904 eassert (SINGLE_BYTE_CHAR_P (c));
6905 if (unibyte_display_via_language_environment)
6907 c = DECODE_CHAR (unibyte, c);
6908 if (c < 0)
6909 c = BYTE8_TO_CHAR (it->c);
6911 else
6912 c = BYTE8_TO_CHAR (it->c);
6915 if (it->dp
6916 && (dv = DISP_CHAR_VECTOR (it->dp, c),
6917 VECTORP (dv)))
6919 struct Lisp_Vector *v = XVECTOR (dv);
6921 /* Return the first character from the display table
6922 entry, if not empty. If empty, don't display the
6923 current character. */
6924 if (v->header.size)
6926 it->dpvec_char_len = it->len;
6927 it->dpvec = v->contents;
6928 it->dpend = v->contents + v->header.size;
6929 it->current.dpvec_index = 0;
6930 it->dpvec_face_id = -1;
6931 it->saved_face_id = it->face_id;
6932 it->method = GET_FROM_DISPLAY_VECTOR;
6933 it->ellipsis_p = 0;
6935 else
6937 set_iterator_to_next (it, 0);
6939 goto get_next;
6942 if (! NILP (lookup_glyphless_char_display (c, it)))
6944 if (it->what == IT_GLYPHLESS)
6945 goto done;
6946 /* Don't display this character. */
6947 set_iterator_to_next (it, 0);
6948 goto get_next;
6951 /* If `nobreak-char-display' is non-nil, we display
6952 non-ASCII spaces and hyphens specially. */
6953 if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
6955 if (c == 0xA0)
6956 nonascii_space_p = true;
6957 else if (c == 0xAD || c == 0x2010 || c == 0x2011)
6958 nonascii_hyphen_p = true;
6961 /* Translate control characters into `\003' or `^C' form.
6962 Control characters coming from a display table entry are
6963 currently not translated because we use IT->dpvec to hold
6964 the translation. This could easily be changed but I
6965 don't believe that it is worth doing.
6967 The characters handled by `nobreak-char-display' must be
6968 translated too.
6970 Non-printable characters and raw-byte characters are also
6971 translated to octal form. */
6972 if (((c < ' ' || c == 127) /* ASCII control chars. */
6973 ? (it->area != TEXT_AREA
6974 /* In mode line, treat \n, \t like other crl chars. */
6975 || (c != '\t'
6976 && it->glyph_row
6977 && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
6978 || (c != '\n' && c != '\t'))
6979 : (nonascii_space_p
6980 || nonascii_hyphen_p
6981 || CHAR_BYTE8_P (c)
6982 || ! CHAR_PRINTABLE_P (c))))
6984 /* C is a control character, non-ASCII space/hyphen,
6985 raw-byte, or a non-printable character which must be
6986 displayed either as '\003' or as `^C' where the '\\'
6987 and '^' can be defined in the display table. Fill
6988 IT->ctl_chars with glyphs for what we have to
6989 display. Then, set IT->dpvec to these glyphs. */
6990 Lisp_Object gc;
6991 int ctl_len;
6992 int face_id;
6993 int lface_id = 0;
6994 int escape_glyph;
6996 /* Handle control characters with ^. */
6998 if (ASCII_CHAR_P (c) && it->ctl_arrow_p)
7000 int g;
7002 g = '^'; /* default glyph for Control */
7003 /* Set IT->ctl_chars[0] to the glyph for `^'. */
7004 if (it->dp
7005 && (gc = DISP_CTRL_GLYPH (it->dp), GLYPH_CODE_P (gc)))
7007 g = GLYPH_CODE_CHAR (gc);
7008 lface_id = GLYPH_CODE_FACE (gc);
7011 face_id = (lface_id
7012 ? merge_faces (it->f, Qt, lface_id, it->face_id)
7013 : merge_escape_glyph_face (it));
7015 XSETINT (it->ctl_chars[0], g);
7016 XSETINT (it->ctl_chars[1], c ^ 0100);
7017 ctl_len = 2;
7018 goto display_control;
7021 /* Handle non-ascii space in the mode where it only gets
7022 highlighting. */
7024 if (nonascii_space_p && EQ (Vnobreak_char_display, Qt))
7026 /* Merge `nobreak-space' into the current face. */
7027 face_id = merge_faces (it->f, Qnobreak_space, 0,
7028 it->face_id);
7029 XSETINT (it->ctl_chars[0], ' ');
7030 ctl_len = 1;
7031 goto display_control;
7034 /* Handle sequences that start with the "escape glyph". */
7036 /* the default escape glyph is \. */
7037 escape_glyph = '\\';
7039 if (it->dp
7040 && (gc = DISP_ESCAPE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
7042 escape_glyph = GLYPH_CODE_CHAR (gc);
7043 lface_id = GLYPH_CODE_FACE (gc);
7046 face_id = (lface_id
7047 ? merge_faces (it->f, Qt, lface_id, it->face_id)
7048 : merge_escape_glyph_face (it));
7050 /* Draw non-ASCII hyphen with just highlighting: */
7052 if (nonascii_hyphen_p && EQ (Vnobreak_char_display, Qt))
7054 XSETINT (it->ctl_chars[0], '-');
7055 ctl_len = 1;
7056 goto display_control;
7059 /* Draw non-ASCII space/hyphen with escape glyph: */
7061 if (nonascii_space_p || nonascii_hyphen_p)
7063 XSETINT (it->ctl_chars[0], escape_glyph);
7064 XSETINT (it->ctl_chars[1], nonascii_space_p ? ' ' : '-');
7065 ctl_len = 2;
7066 goto display_control;
7070 char str[10];
7071 int len, i;
7073 if (CHAR_BYTE8_P (c))
7074 /* Display \200 instead of \17777600. */
7075 c = CHAR_TO_BYTE8 (c);
7076 len = sprintf (str, "%03o", c);
7078 XSETINT (it->ctl_chars[0], escape_glyph);
7079 for (i = 0; i < len; i++)
7080 XSETINT (it->ctl_chars[i + 1], str[i]);
7081 ctl_len = len + 1;
7084 display_control:
7085 /* Set up IT->dpvec and return first character from it. */
7086 it->dpvec_char_len = it->len;
7087 it->dpvec = it->ctl_chars;
7088 it->dpend = it->dpvec + ctl_len;
7089 it->current.dpvec_index = 0;
7090 it->dpvec_face_id = face_id;
7091 it->saved_face_id = it->face_id;
7092 it->method = GET_FROM_DISPLAY_VECTOR;
7093 it->ellipsis_p = 0;
7094 goto get_next;
7096 it->char_to_display = c;
7098 else if (success_p)
7100 it->char_to_display = it->c;
7104 #ifdef HAVE_WINDOW_SYSTEM
7105 /* Adjust face id for a multibyte character. There are no multibyte
7106 character in unibyte text. */
7107 if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
7108 && it->multibyte_p
7109 && success_p
7110 && FRAME_WINDOW_P (it->f))
7112 struct face *face = FACE_FROM_ID (it->f, it->face_id);
7114 if (it->what == IT_COMPOSITION && it->cmp_it.ch >= 0)
7116 /* Automatic composition with glyph-string. */
7117 Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id);
7119 it->face_id = face_for_font (it->f, LGSTRING_FONT (gstring), face);
7121 else
7123 ptrdiff_t pos = (it->s ? -1
7124 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
7125 : IT_CHARPOS (*it));
7126 int c;
7128 if (it->what == IT_CHARACTER)
7129 c = it->char_to_display;
7130 else
7132 struct composition *cmp = composition_table[it->cmp_it.id];
7133 int i;
7135 c = ' ';
7136 for (i = 0; i < cmp->glyph_len; i++)
7137 /* TAB in a composition means display glyphs with
7138 padding space on the left or right. */
7139 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
7140 break;
7142 it->face_id = FACE_FOR_CHAR (it->f, face, c, pos, it->string);
7145 #endif /* HAVE_WINDOW_SYSTEM */
7147 done:
7148 /* Is this character the last one of a run of characters with
7149 box? If yes, set IT->end_of_box_run_p to 1. */
7150 if (it->face_box_p
7151 && it->s == NULL)
7153 if (it->method == GET_FROM_STRING && it->sp)
7155 int face_id = underlying_face_id (it);
7156 struct face *face = FACE_FROM_ID (it->f, face_id);
7158 if (face)
7160 if (face->box == FACE_NO_BOX)
7162 /* If the box comes from face properties in a
7163 display string, check faces in that string. */
7164 int string_face_id = face_after_it_pos (it);
7165 it->end_of_box_run_p
7166 = (FACE_FROM_ID (it->f, string_face_id)->box
7167 == FACE_NO_BOX);
7169 /* Otherwise, the box comes from the underlying face.
7170 If this is the last string character displayed, check
7171 the next buffer location. */
7172 else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1)
7173 /* n_overlay_strings is unreliable unless
7174 overlay_string_index is non-negative. */
7175 && ((it->current.overlay_string_index >= 0
7176 && (it->current.overlay_string_index
7177 == it->n_overlay_strings - 1))
7178 /* A string from display property. */
7179 || it->from_disp_prop_p))
7181 ptrdiff_t ignore;
7182 int next_face_id;
7183 struct text_pos pos = it->current.pos;
7185 /* For a string from a display property, the next
7186 buffer position is stored in the 'position'
7187 member of the iteration stack slot below the
7188 current one, see handle_single_display_spec. By
7189 contrast, it->current.pos was is not yet updated
7190 to point to that buffer position; that will
7191 happen in pop_it, after we finish displaying the
7192 current string. Note that we already checked
7193 above that it->sp is positive, so subtracting one
7194 from it is safe. */
7195 if (it->from_disp_prop_p)
7196 pos = (it->stack + it->sp - 1)->position;
7197 else
7198 INC_TEXT_POS (pos, it->multibyte_p);
7200 if (CHARPOS (pos) >= ZV)
7201 it->end_of_box_run_p = true;
7202 else
7204 next_face_id = face_at_buffer_position
7205 (it->w, CHARPOS (pos), &ignore,
7206 CHARPOS (pos) + TEXT_PROP_DISTANCE_LIMIT, 0, -1);
7207 it->end_of_box_run_p
7208 = (FACE_FROM_ID (it->f, next_face_id)->box
7209 == FACE_NO_BOX);
7214 /* next_element_from_display_vector sets this flag according to
7215 faces of the display vector glyphs, see there. */
7216 else if (it->method != GET_FROM_DISPLAY_VECTOR)
7218 int face_id = face_after_it_pos (it);
7219 it->end_of_box_run_p
7220 = (face_id != it->face_id
7221 && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX);
7224 /* If we reached the end of the object we've been iterating (e.g., a
7225 display string or an overlay string), and there's something on
7226 IT->stack, proceed with what's on the stack. It doesn't make
7227 sense to return zero if there's unprocessed stuff on the stack,
7228 because otherwise that stuff will never be displayed. */
7229 if (!success_p && it->sp > 0)
7231 set_iterator_to_next (it, 0);
7232 success_p = get_next_display_element (it);
7235 /* Value is 0 if end of buffer or string reached. */
7236 return success_p;
7240 /* Move IT to the next display element.
7242 RESEAT_P non-zero means if called on a newline in buffer text,
7243 skip to the next visible line start.
7245 Functions get_next_display_element and set_iterator_to_next are
7246 separate because I find this arrangement easier to handle than a
7247 get_next_display_element function that also increments IT's
7248 position. The way it is we can first look at an iterator's current
7249 display element, decide whether it fits on a line, and if it does,
7250 increment the iterator position. The other way around we probably
7251 would either need a flag indicating whether the iterator has to be
7252 incremented the next time, or we would have to implement a
7253 decrement position function which would not be easy to write. */
7255 void
7256 set_iterator_to_next (struct it *it, int reseat_p)
7258 /* Reset flags indicating start and end of a sequence of characters
7259 with box. Reset them at the start of this function because
7260 moving the iterator to a new position might set them. */
7261 it->start_of_box_run_p = it->end_of_box_run_p = 0;
7263 switch (it->method)
7265 case GET_FROM_BUFFER:
7266 /* The current display element of IT is a character from
7267 current_buffer. Advance in the buffer, and maybe skip over
7268 invisible lines that are so because of selective display. */
7269 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
7270 reseat_at_next_visible_line_start (it, 0);
7271 else if (it->cmp_it.id >= 0)
7273 /* We are currently getting glyphs from a composition. */
7274 int i;
7276 if (! it->bidi_p)
7278 IT_CHARPOS (*it) += it->cmp_it.nchars;
7279 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
7280 if (it->cmp_it.to < it->cmp_it.nglyphs)
7282 it->cmp_it.from = it->cmp_it.to;
7284 else
7286 it->cmp_it.id = -1;
7287 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7288 IT_BYTEPOS (*it),
7289 it->end_charpos, Qnil);
7292 else if (! it->cmp_it.reversed_p)
7294 /* Composition created while scanning forward. */
7295 /* Update IT's char/byte positions to point to the first
7296 character of the next grapheme cluster, or to the
7297 character visually after the current composition. */
7298 for (i = 0; i < it->cmp_it.nchars; i++)
7299 bidi_move_to_visually_next (&it->bidi_it);
7300 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7301 IT_CHARPOS (*it) = it->bidi_it.charpos;
7303 if (it->cmp_it.to < it->cmp_it.nglyphs)
7305 /* Proceed to the next grapheme cluster. */
7306 it->cmp_it.from = it->cmp_it.to;
7308 else
7310 /* No more grapheme clusters in this composition.
7311 Find the next stop position. */
7312 ptrdiff_t stop = it->end_charpos;
7313 if (it->bidi_it.scan_dir < 0)
7314 /* Now we are scanning backward and don't know
7315 where to stop. */
7316 stop = -1;
7317 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7318 IT_BYTEPOS (*it), stop, Qnil);
7321 else
7323 /* Composition created while scanning backward. */
7324 /* Update IT's char/byte positions to point to the last
7325 character of the previous grapheme cluster, or the
7326 character visually after the current composition. */
7327 for (i = 0; i < it->cmp_it.nchars; i++)
7328 bidi_move_to_visually_next (&it->bidi_it);
7329 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7330 IT_CHARPOS (*it) = it->bidi_it.charpos;
7331 if (it->cmp_it.from > 0)
7333 /* Proceed to the previous grapheme cluster. */
7334 it->cmp_it.to = it->cmp_it.from;
7336 else
7338 /* No more grapheme clusters in this composition.
7339 Find the next stop position. */
7340 ptrdiff_t stop = it->end_charpos;
7341 if (it->bidi_it.scan_dir < 0)
7342 /* Now we are scanning backward and don't know
7343 where to stop. */
7344 stop = -1;
7345 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7346 IT_BYTEPOS (*it), stop, Qnil);
7350 else
7352 eassert (it->len != 0);
7354 if (!it->bidi_p)
7356 IT_BYTEPOS (*it) += it->len;
7357 IT_CHARPOS (*it) += 1;
7359 else
7361 int prev_scan_dir = it->bidi_it.scan_dir;
7362 /* If this is a new paragraph, determine its base
7363 direction (a.k.a. its base embedding level). */
7364 if (it->bidi_it.new_paragraph)
7365 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
7366 bidi_move_to_visually_next (&it->bidi_it);
7367 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7368 IT_CHARPOS (*it) = it->bidi_it.charpos;
7369 if (prev_scan_dir != it->bidi_it.scan_dir)
7371 /* As the scan direction was changed, we must
7372 re-compute the stop position for composition. */
7373 ptrdiff_t stop = it->end_charpos;
7374 if (it->bidi_it.scan_dir < 0)
7375 stop = -1;
7376 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7377 IT_BYTEPOS (*it), stop, Qnil);
7380 eassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
7382 break;
7384 case GET_FROM_C_STRING:
7385 /* Current display element of IT is from a C string. */
7386 if (!it->bidi_p
7387 /* If the string position is beyond string's end, it means
7388 next_element_from_c_string is padding the string with
7389 blanks, in which case we bypass the bidi iterator,
7390 because it cannot deal with such virtual characters. */
7391 || IT_CHARPOS (*it) >= it->bidi_it.string.schars)
7393 IT_BYTEPOS (*it) += it->len;
7394 IT_CHARPOS (*it) += 1;
7396 else
7398 bidi_move_to_visually_next (&it->bidi_it);
7399 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7400 IT_CHARPOS (*it) = it->bidi_it.charpos;
7402 break;
7404 case GET_FROM_DISPLAY_VECTOR:
7405 /* Current display element of IT is from a display table entry.
7406 Advance in the display table definition. Reset it to null if
7407 end reached, and continue with characters from buffers/
7408 strings. */
7409 ++it->current.dpvec_index;
7411 /* Restore face of the iterator to what they were before the
7412 display vector entry (these entries may contain faces). */
7413 it->face_id = it->saved_face_id;
7415 if (it->dpvec + it->current.dpvec_index >= it->dpend)
7417 int recheck_faces = it->ellipsis_p;
7419 if (it->s)
7420 it->method = GET_FROM_C_STRING;
7421 else if (STRINGP (it->string))
7422 it->method = GET_FROM_STRING;
7423 else
7425 it->method = GET_FROM_BUFFER;
7426 it->object = it->w->contents;
7429 it->dpvec = NULL;
7430 it->current.dpvec_index = -1;
7432 /* Skip over characters which were displayed via IT->dpvec. */
7433 if (it->dpvec_char_len < 0)
7434 reseat_at_next_visible_line_start (it, 1);
7435 else if (it->dpvec_char_len > 0)
7437 if (it->method == GET_FROM_STRING
7438 && it->current.overlay_string_index >= 0
7439 && it->n_overlay_strings > 0)
7440 it->ignore_overlay_strings_at_pos_p = true;
7441 it->len = it->dpvec_char_len;
7442 set_iterator_to_next (it, reseat_p);
7445 /* Maybe recheck faces after display vector. */
7446 if (recheck_faces)
7447 it->stop_charpos = IT_CHARPOS (*it);
7449 break;
7451 case GET_FROM_STRING:
7452 /* Current display element is a character from a Lisp string. */
7453 eassert (it->s == NULL && STRINGP (it->string));
7454 /* Don't advance past string end. These conditions are true
7455 when set_iterator_to_next is called at the end of
7456 get_next_display_element, in which case the Lisp string is
7457 already exhausted, and all we want is pop the iterator
7458 stack. */
7459 if (it->current.overlay_string_index >= 0)
7461 /* This is an overlay string, so there's no padding with
7462 spaces, and the number of characters in the string is
7463 where the string ends. */
7464 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7465 goto consider_string_end;
7467 else
7469 /* Not an overlay string. There could be padding, so test
7470 against it->end_charpos. */
7471 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7472 goto consider_string_end;
7474 if (it->cmp_it.id >= 0)
7476 int i;
7478 if (! it->bidi_p)
7480 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
7481 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
7482 if (it->cmp_it.to < it->cmp_it.nglyphs)
7483 it->cmp_it.from = it->cmp_it.to;
7484 else
7486 it->cmp_it.id = -1;
7487 composition_compute_stop_pos (&it->cmp_it,
7488 IT_STRING_CHARPOS (*it),
7489 IT_STRING_BYTEPOS (*it),
7490 it->end_charpos, it->string);
7493 else if (! it->cmp_it.reversed_p)
7495 for (i = 0; i < it->cmp_it.nchars; i++)
7496 bidi_move_to_visually_next (&it->bidi_it);
7497 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7498 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7500 if (it->cmp_it.to < it->cmp_it.nglyphs)
7501 it->cmp_it.from = it->cmp_it.to;
7502 else
7504 ptrdiff_t stop = it->end_charpos;
7505 if (it->bidi_it.scan_dir < 0)
7506 stop = -1;
7507 composition_compute_stop_pos (&it->cmp_it,
7508 IT_STRING_CHARPOS (*it),
7509 IT_STRING_BYTEPOS (*it), stop,
7510 it->string);
7513 else
7515 for (i = 0; i < it->cmp_it.nchars; i++)
7516 bidi_move_to_visually_next (&it->bidi_it);
7517 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7518 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7519 if (it->cmp_it.from > 0)
7520 it->cmp_it.to = it->cmp_it.from;
7521 else
7523 ptrdiff_t stop = it->end_charpos;
7524 if (it->bidi_it.scan_dir < 0)
7525 stop = -1;
7526 composition_compute_stop_pos (&it->cmp_it,
7527 IT_STRING_CHARPOS (*it),
7528 IT_STRING_BYTEPOS (*it), stop,
7529 it->string);
7533 else
7535 if (!it->bidi_p
7536 /* If the string position is beyond string's end, it
7537 means next_element_from_string is padding the string
7538 with blanks, in which case we bypass the bidi
7539 iterator, because it cannot deal with such virtual
7540 characters. */
7541 || IT_STRING_CHARPOS (*it) >= it->bidi_it.string.schars)
7543 IT_STRING_BYTEPOS (*it) += it->len;
7544 IT_STRING_CHARPOS (*it) += 1;
7546 else
7548 int prev_scan_dir = it->bidi_it.scan_dir;
7550 bidi_move_to_visually_next (&it->bidi_it);
7551 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7552 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7553 if (prev_scan_dir != it->bidi_it.scan_dir)
7555 ptrdiff_t stop = it->end_charpos;
7557 if (it->bidi_it.scan_dir < 0)
7558 stop = -1;
7559 composition_compute_stop_pos (&it->cmp_it,
7560 IT_STRING_CHARPOS (*it),
7561 IT_STRING_BYTEPOS (*it), stop,
7562 it->string);
7567 consider_string_end:
7569 if (it->current.overlay_string_index >= 0)
7571 /* IT->string is an overlay string. Advance to the
7572 next, if there is one. */
7573 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7575 it->ellipsis_p = 0;
7576 next_overlay_string (it);
7577 if (it->ellipsis_p)
7578 setup_for_ellipsis (it, 0);
7581 else
7583 /* IT->string is not an overlay string. If we reached
7584 its end, and there is something on IT->stack, proceed
7585 with what is on the stack. This can be either another
7586 string, this time an overlay string, or a buffer. */
7587 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
7588 && it->sp > 0)
7590 pop_it (it);
7591 if (it->method == GET_FROM_STRING)
7592 goto consider_string_end;
7595 break;
7597 case GET_FROM_IMAGE:
7598 case GET_FROM_STRETCH:
7599 /* The position etc with which we have to proceed are on
7600 the stack. The position may be at the end of a string,
7601 if the `display' property takes up the whole string. */
7602 eassert (it->sp > 0);
7603 pop_it (it);
7604 if (it->method == GET_FROM_STRING)
7605 goto consider_string_end;
7606 break;
7608 default:
7609 /* There are no other methods defined, so this should be a bug. */
7610 emacs_abort ();
7613 eassert (it->method != GET_FROM_STRING
7614 || (STRINGP (it->string)
7615 && IT_STRING_CHARPOS (*it) >= 0));
7618 /* Load IT's display element fields with information about the next
7619 display element which comes from a display table entry or from the
7620 result of translating a control character to one of the forms `^C'
7621 or `\003'.
7623 IT->dpvec holds the glyphs to return as characters.
7624 IT->saved_face_id holds the face id before the display vector--it
7625 is restored into IT->face_id in set_iterator_to_next. */
7627 static int
7628 next_element_from_display_vector (struct it *it)
7630 Lisp_Object gc;
7631 int prev_face_id = it->face_id;
7632 int next_face_id;
7634 /* Precondition. */
7635 eassert (it->dpvec && it->current.dpvec_index >= 0);
7637 it->face_id = it->saved_face_id;
7639 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
7640 That seemed totally bogus - so I changed it... */
7641 gc = it->dpvec[it->current.dpvec_index];
7643 if (GLYPH_CODE_P (gc))
7645 struct face *this_face, *prev_face, *next_face;
7647 it->c = GLYPH_CODE_CHAR (gc);
7648 it->len = CHAR_BYTES (it->c);
7650 /* The entry may contain a face id to use. Such a face id is
7651 the id of a Lisp face, not a realized face. A face id of
7652 zero means no face is specified. */
7653 if (it->dpvec_face_id >= 0)
7654 it->face_id = it->dpvec_face_id;
7655 else
7657 int lface_id = GLYPH_CODE_FACE (gc);
7658 if (lface_id > 0)
7659 it->face_id = merge_faces (it->f, Qt, lface_id,
7660 it->saved_face_id);
7663 /* Glyphs in the display vector could have the box face, so we
7664 need to set the related flags in the iterator, as
7665 appropriate. */
7666 this_face = FACE_FROM_ID (it->f, it->face_id);
7667 prev_face = FACE_FROM_ID (it->f, prev_face_id);
7669 /* Is this character the first character of a box-face run? */
7670 it->start_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX
7671 && (!prev_face
7672 || prev_face->box == FACE_NO_BOX));
7674 /* For the last character of the box-face run, we need to look
7675 either at the next glyph from the display vector, or at the
7676 face we saw before the display vector. */
7677 next_face_id = it->saved_face_id;
7678 if (it->current.dpvec_index < it->dpend - it->dpvec - 1)
7680 if (it->dpvec_face_id >= 0)
7681 next_face_id = it->dpvec_face_id;
7682 else
7684 int lface_id =
7685 GLYPH_CODE_FACE (it->dpvec[it->current.dpvec_index + 1]);
7687 if (lface_id > 0)
7688 next_face_id = merge_faces (it->f, Qt, lface_id,
7689 it->saved_face_id);
7692 next_face = FACE_FROM_ID (it->f, next_face_id);
7693 it->end_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX
7694 && (!next_face
7695 || next_face->box == FACE_NO_BOX));
7696 it->face_box_p = this_face && this_face->box != FACE_NO_BOX;
7698 else
7699 /* Display table entry is invalid. Return a space. */
7700 it->c = ' ', it->len = 1;
7702 /* Don't change position and object of the iterator here. They are
7703 still the values of the character that had this display table
7704 entry or was translated, and that's what we want. */
7705 it->what = IT_CHARACTER;
7706 return 1;
7709 /* Get the first element of string/buffer in the visual order, after
7710 being reseated to a new position in a string or a buffer. */
7711 static void
7712 get_visually_first_element (struct it *it)
7714 int string_p = STRINGP (it->string) || it->s;
7715 ptrdiff_t eob = (string_p ? it->bidi_it.string.schars : ZV);
7716 ptrdiff_t bob = (string_p ? 0 : BEGV);
7718 if (STRINGP (it->string))
7720 it->bidi_it.charpos = IT_STRING_CHARPOS (*it);
7721 it->bidi_it.bytepos = IT_STRING_BYTEPOS (*it);
7723 else
7725 it->bidi_it.charpos = IT_CHARPOS (*it);
7726 it->bidi_it.bytepos = IT_BYTEPOS (*it);
7729 if (it->bidi_it.charpos == eob)
7731 /* Nothing to do, but reset the FIRST_ELT flag, like
7732 bidi_paragraph_init does, because we are not going to
7733 call it. */
7734 it->bidi_it.first_elt = 0;
7736 else if (it->bidi_it.charpos == bob
7737 || (!string_p
7738 && (FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n'
7739 || FETCH_CHAR (it->bidi_it.bytepos) == '\n')))
7741 /* If we are at the beginning of a line/string, we can produce
7742 the next element right away. */
7743 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
7744 bidi_move_to_visually_next (&it->bidi_it);
7746 else
7748 ptrdiff_t orig_bytepos = it->bidi_it.bytepos;
7750 /* We need to prime the bidi iterator starting at the line's or
7751 string's beginning, before we will be able to produce the
7752 next element. */
7753 if (string_p)
7754 it->bidi_it.charpos = it->bidi_it.bytepos = 0;
7755 else
7756 it->bidi_it.charpos = find_newline_no_quit (IT_CHARPOS (*it),
7757 IT_BYTEPOS (*it), -1,
7758 &it->bidi_it.bytepos);
7759 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
7762 /* Now return to buffer/string position where we were asked
7763 to get the next display element, and produce that. */
7764 bidi_move_to_visually_next (&it->bidi_it);
7766 while (it->bidi_it.bytepos != orig_bytepos
7767 && it->bidi_it.charpos < eob);
7770 /* Adjust IT's position information to where we ended up. */
7771 if (STRINGP (it->string))
7773 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7774 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7776 else
7778 IT_CHARPOS (*it) = it->bidi_it.charpos;
7779 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7782 if (STRINGP (it->string) || !it->s)
7784 ptrdiff_t stop, charpos, bytepos;
7786 if (STRINGP (it->string))
7788 eassert (!it->s);
7789 stop = SCHARS (it->string);
7790 if (stop > it->end_charpos)
7791 stop = it->end_charpos;
7792 charpos = IT_STRING_CHARPOS (*it);
7793 bytepos = IT_STRING_BYTEPOS (*it);
7795 else
7797 stop = it->end_charpos;
7798 charpos = IT_CHARPOS (*it);
7799 bytepos = IT_BYTEPOS (*it);
7801 if (it->bidi_it.scan_dir < 0)
7802 stop = -1;
7803 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos, stop,
7804 it->string);
7808 /* Load IT with the next display element from Lisp string IT->string.
7809 IT->current.string_pos is the current position within the string.
7810 If IT->current.overlay_string_index >= 0, the Lisp string is an
7811 overlay string. */
7813 static int
7814 next_element_from_string (struct it *it)
7816 struct text_pos position;
7818 eassert (STRINGP (it->string));
7819 eassert (!it->bidi_p || EQ (it->string, it->bidi_it.string.lstring));
7820 eassert (IT_STRING_CHARPOS (*it) >= 0);
7821 position = it->current.string_pos;
7823 /* With bidi reordering, the character to display might not be the
7824 character at IT_STRING_CHARPOS. BIDI_IT.FIRST_ELT non-zero means
7825 that we were reseat()ed to a new string, whose paragraph
7826 direction is not known. */
7827 if (it->bidi_p && it->bidi_it.first_elt)
7829 get_visually_first_element (it);
7830 SET_TEXT_POS (position, IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it));
7833 /* Time to check for invisible text? */
7834 if (IT_STRING_CHARPOS (*it) < it->end_charpos)
7836 if (IT_STRING_CHARPOS (*it) >= it->stop_charpos)
7838 if (!(!it->bidi_p
7839 || BIDI_AT_BASE_LEVEL (it->bidi_it)
7840 || IT_STRING_CHARPOS (*it) == it->stop_charpos))
7842 /* With bidi non-linear iteration, we could find
7843 ourselves far beyond the last computed stop_charpos,
7844 with several other stop positions in between that we
7845 missed. Scan them all now, in buffer's logical
7846 order, until we find and handle the last stop_charpos
7847 that precedes our current position. */
7848 handle_stop_backwards (it, it->stop_charpos);
7849 return GET_NEXT_DISPLAY_ELEMENT (it);
7851 else
7853 if (it->bidi_p)
7855 /* Take note of the stop position we just moved
7856 across, for when we will move back across it. */
7857 it->prev_stop = it->stop_charpos;
7858 /* If we are at base paragraph embedding level, take
7859 note of the last stop position seen at this
7860 level. */
7861 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
7862 it->base_level_stop = it->stop_charpos;
7864 handle_stop (it);
7866 /* Since a handler may have changed IT->method, we must
7867 recurse here. */
7868 return GET_NEXT_DISPLAY_ELEMENT (it);
7871 else if (it->bidi_p
7872 /* If we are before prev_stop, we may have overstepped
7873 on our way backwards a stop_pos, and if so, we need
7874 to handle that stop_pos. */
7875 && IT_STRING_CHARPOS (*it) < it->prev_stop
7876 /* We can sometimes back up for reasons that have nothing
7877 to do with bidi reordering. E.g., compositions. The
7878 code below is only needed when we are above the base
7879 embedding level, so test for that explicitly. */
7880 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
7882 /* If we lost track of base_level_stop, we have no better
7883 place for handle_stop_backwards to start from than string
7884 beginning. This happens, e.g., when we were reseated to
7885 the previous screenful of text by vertical-motion. */
7886 if (it->base_level_stop <= 0
7887 || IT_STRING_CHARPOS (*it) < it->base_level_stop)
7888 it->base_level_stop = 0;
7889 handle_stop_backwards (it, it->base_level_stop);
7890 return GET_NEXT_DISPLAY_ELEMENT (it);
7894 if (it->current.overlay_string_index >= 0)
7896 /* Get the next character from an overlay string. In overlay
7897 strings, there is no field width or padding with spaces to
7898 do. */
7899 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7901 it->what = IT_EOB;
7902 return 0;
7904 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
7905 IT_STRING_BYTEPOS (*it),
7906 it->bidi_it.scan_dir < 0
7907 ? -1
7908 : SCHARS (it->string))
7909 && next_element_from_composition (it))
7911 return 1;
7913 else if (STRING_MULTIBYTE (it->string))
7915 const unsigned char *s = (SDATA (it->string)
7916 + IT_STRING_BYTEPOS (*it));
7917 it->c = string_char_and_length (s, &it->len);
7919 else
7921 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
7922 it->len = 1;
7925 else
7927 /* Get the next character from a Lisp string that is not an
7928 overlay string. Such strings come from the mode line, for
7929 example. We may have to pad with spaces, or truncate the
7930 string. See also next_element_from_c_string. */
7931 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7933 it->what = IT_EOB;
7934 return 0;
7936 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
7938 /* Pad with spaces. */
7939 it->c = ' ', it->len = 1;
7940 CHARPOS (position) = BYTEPOS (position) = -1;
7942 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
7943 IT_STRING_BYTEPOS (*it),
7944 it->bidi_it.scan_dir < 0
7945 ? -1
7946 : it->string_nchars)
7947 && next_element_from_composition (it))
7949 return 1;
7951 else if (STRING_MULTIBYTE (it->string))
7953 const unsigned char *s = (SDATA (it->string)
7954 + IT_STRING_BYTEPOS (*it));
7955 it->c = string_char_and_length (s, &it->len);
7957 else
7959 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
7960 it->len = 1;
7964 /* Record what we have and where it came from. */
7965 it->what = IT_CHARACTER;
7966 it->object = it->string;
7967 it->position = position;
7968 return 1;
7972 /* Load IT with next display element from C string IT->s.
7973 IT->string_nchars is the maximum number of characters to return
7974 from the string. IT->end_charpos may be greater than
7975 IT->string_nchars when this function is called, in which case we
7976 may have to return padding spaces. Value is zero if end of string
7977 reached, including padding spaces. */
7979 static int
7980 next_element_from_c_string (struct it *it)
7982 bool success_p = true;
7984 eassert (it->s);
7985 eassert (!it->bidi_p || it->s == it->bidi_it.string.s);
7986 it->what = IT_CHARACTER;
7987 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
7988 it->object = Qnil;
7990 /* With bidi reordering, the character to display might not be the
7991 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
7992 we were reseated to a new string, whose paragraph direction is
7993 not known. */
7994 if (it->bidi_p && it->bidi_it.first_elt)
7995 get_visually_first_element (it);
7997 /* IT's position can be greater than IT->string_nchars in case a
7998 field width or precision has been specified when the iterator was
7999 initialized. */
8000 if (IT_CHARPOS (*it) >= it->end_charpos)
8002 /* End of the game. */
8003 it->what = IT_EOB;
8004 success_p = 0;
8006 else if (IT_CHARPOS (*it) >= it->string_nchars)
8008 /* Pad with spaces. */
8009 it->c = ' ', it->len = 1;
8010 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
8012 else if (it->multibyte_p)
8013 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), &it->len);
8014 else
8015 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
8017 return success_p;
8021 /* Set up IT to return characters from an ellipsis, if appropriate.
8022 The definition of the ellipsis glyphs may come from a display table
8023 entry. This function fills IT with the first glyph from the
8024 ellipsis if an ellipsis is to be displayed. */
8026 static int
8027 next_element_from_ellipsis (struct it *it)
8029 if (it->selective_display_ellipsis_p)
8030 setup_for_ellipsis (it, it->len);
8031 else
8033 /* The face at the current position may be different from the
8034 face we find after the invisible text. Remember what it
8035 was in IT->saved_face_id, and signal that it's there by
8036 setting face_before_selective_p. */
8037 it->saved_face_id = it->face_id;
8038 it->method = GET_FROM_BUFFER;
8039 it->object = it->w->contents;
8040 reseat_at_next_visible_line_start (it, 1);
8041 it->face_before_selective_p = true;
8044 return GET_NEXT_DISPLAY_ELEMENT (it);
8048 /* Deliver an image display element. The iterator IT is already
8049 filled with image information (done in handle_display_prop). Value
8050 is always 1. */
8053 static int
8054 next_element_from_image (struct it *it)
8056 it->what = IT_IMAGE;
8057 it->ignore_overlay_strings_at_pos_p = 0;
8058 return 1;
8062 /* Fill iterator IT with next display element from a stretch glyph
8063 property. IT->object is the value of the text property. Value is
8064 always 1. */
8066 static int
8067 next_element_from_stretch (struct it *it)
8069 it->what = IT_STRETCH;
8070 return 1;
8073 /* Scan backwards from IT's current position until we find a stop
8074 position, or until BEGV. This is called when we find ourself
8075 before both the last known prev_stop and base_level_stop while
8076 reordering bidirectional text. */
8078 static void
8079 compute_stop_pos_backwards (struct it *it)
8081 const int SCAN_BACK_LIMIT = 1000;
8082 struct text_pos pos;
8083 struct display_pos save_current = it->current;
8084 struct text_pos save_position = it->position;
8085 ptrdiff_t charpos = IT_CHARPOS (*it);
8086 ptrdiff_t where_we_are = charpos;
8087 ptrdiff_t save_stop_pos = it->stop_charpos;
8088 ptrdiff_t save_end_pos = it->end_charpos;
8090 eassert (NILP (it->string) && !it->s);
8091 eassert (it->bidi_p);
8092 it->bidi_p = 0;
8095 it->end_charpos = min (charpos + 1, ZV);
8096 charpos = max (charpos - SCAN_BACK_LIMIT, BEGV);
8097 SET_TEXT_POS (pos, charpos, CHAR_TO_BYTE (charpos));
8098 reseat_1 (it, pos, 0);
8099 compute_stop_pos (it);
8100 /* We must advance forward, right? */
8101 if (it->stop_charpos <= charpos)
8102 emacs_abort ();
8104 while (charpos > BEGV && it->stop_charpos >= it->end_charpos);
8106 if (it->stop_charpos <= where_we_are)
8107 it->prev_stop = it->stop_charpos;
8108 else
8109 it->prev_stop = BEGV;
8110 it->bidi_p = true;
8111 it->current = save_current;
8112 it->position = save_position;
8113 it->stop_charpos = save_stop_pos;
8114 it->end_charpos = save_end_pos;
8117 /* Scan forward from CHARPOS in the current buffer/string, until we
8118 find a stop position > current IT's position. Then handle the stop
8119 position before that. This is called when we bump into a stop
8120 position while reordering bidirectional text. CHARPOS should be
8121 the last previously processed stop_pos (or BEGV/0, if none were
8122 processed yet) whose position is less that IT's current
8123 position. */
8125 static void
8126 handle_stop_backwards (struct it *it, ptrdiff_t charpos)
8128 int bufp = !STRINGP (it->string);
8129 ptrdiff_t where_we_are = (bufp ? IT_CHARPOS (*it) : IT_STRING_CHARPOS (*it));
8130 struct display_pos save_current = it->current;
8131 struct text_pos save_position = it->position;
8132 struct text_pos pos1;
8133 ptrdiff_t next_stop;
8135 /* Scan in strict logical order. */
8136 eassert (it->bidi_p);
8137 it->bidi_p = 0;
8140 it->prev_stop = charpos;
8141 if (bufp)
8143 SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos));
8144 reseat_1 (it, pos1, 0);
8146 else
8147 it->current.string_pos = string_pos (charpos, it->string);
8148 compute_stop_pos (it);
8149 /* We must advance forward, right? */
8150 if (it->stop_charpos <= it->prev_stop)
8151 emacs_abort ();
8152 charpos = it->stop_charpos;
8154 while (charpos <= where_we_are);
8156 it->bidi_p = true;
8157 it->current = save_current;
8158 it->position = save_position;
8159 next_stop = it->stop_charpos;
8160 it->stop_charpos = it->prev_stop;
8161 handle_stop (it);
8162 it->stop_charpos = next_stop;
8165 /* Load IT with the next display element from current_buffer. Value
8166 is zero if end of buffer reached. IT->stop_charpos is the next
8167 position at which to stop and check for text properties or buffer
8168 end. */
8170 static int
8171 next_element_from_buffer (struct it *it)
8173 bool success_p = true;
8175 eassert (IT_CHARPOS (*it) >= BEGV);
8176 eassert (NILP (it->string) && !it->s);
8177 eassert (!it->bidi_p
8178 || (EQ (it->bidi_it.string.lstring, Qnil)
8179 && it->bidi_it.string.s == NULL));
8181 /* With bidi reordering, the character to display might not be the
8182 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
8183 we were reseat()ed to a new buffer position, which is potentially
8184 a different paragraph. */
8185 if (it->bidi_p && it->bidi_it.first_elt)
8187 get_visually_first_element (it);
8188 SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8191 if (IT_CHARPOS (*it) >= it->stop_charpos)
8193 if (IT_CHARPOS (*it) >= it->end_charpos)
8195 int overlay_strings_follow_p;
8197 /* End of the game, except when overlay strings follow that
8198 haven't been returned yet. */
8199 if (it->overlay_strings_at_end_processed_p)
8200 overlay_strings_follow_p = 0;
8201 else
8203 it->overlay_strings_at_end_processed_p = true;
8204 overlay_strings_follow_p = get_overlay_strings (it, 0);
8207 if (overlay_strings_follow_p)
8208 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
8209 else
8211 it->what = IT_EOB;
8212 it->position = it->current.pos;
8213 success_p = 0;
8216 else if (!(!it->bidi_p
8217 || BIDI_AT_BASE_LEVEL (it->bidi_it)
8218 || IT_CHARPOS (*it) == it->stop_charpos))
8220 /* With bidi non-linear iteration, we could find ourselves
8221 far beyond the last computed stop_charpos, with several
8222 other stop positions in between that we missed. Scan
8223 them all now, in buffer's logical order, until we find
8224 and handle the last stop_charpos that precedes our
8225 current position. */
8226 handle_stop_backwards (it, it->stop_charpos);
8227 return GET_NEXT_DISPLAY_ELEMENT (it);
8229 else
8231 if (it->bidi_p)
8233 /* Take note of the stop position we just moved across,
8234 for when we will move back across it. */
8235 it->prev_stop = it->stop_charpos;
8236 /* If we are at base paragraph embedding level, take
8237 note of the last stop position seen at this
8238 level. */
8239 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
8240 it->base_level_stop = it->stop_charpos;
8242 handle_stop (it);
8243 return GET_NEXT_DISPLAY_ELEMENT (it);
8246 else if (it->bidi_p
8247 /* If we are before prev_stop, we may have overstepped on
8248 our way backwards a stop_pos, and if so, we need to
8249 handle that stop_pos. */
8250 && IT_CHARPOS (*it) < it->prev_stop
8251 /* We can sometimes back up for reasons that have nothing
8252 to do with bidi reordering. E.g., compositions. The
8253 code below is only needed when we are above the base
8254 embedding level, so test for that explicitly. */
8255 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
8257 if (it->base_level_stop <= 0
8258 || IT_CHARPOS (*it) < it->base_level_stop)
8260 /* If we lost track of base_level_stop, we need to find
8261 prev_stop by looking backwards. This happens, e.g., when
8262 we were reseated to the previous screenful of text by
8263 vertical-motion. */
8264 it->base_level_stop = BEGV;
8265 compute_stop_pos_backwards (it);
8266 handle_stop_backwards (it, it->prev_stop);
8268 else
8269 handle_stop_backwards (it, it->base_level_stop);
8270 return GET_NEXT_DISPLAY_ELEMENT (it);
8272 else
8274 /* No face changes, overlays etc. in sight, so just return a
8275 character from current_buffer. */
8276 unsigned char *p;
8277 ptrdiff_t stop;
8279 /* Maybe run the redisplay end trigger hook. Performance note:
8280 This doesn't seem to cost measurable time. */
8281 if (it->redisplay_end_trigger_charpos
8282 && it->glyph_row
8283 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
8284 run_redisplay_end_trigger_hook (it);
8286 stop = it->bidi_it.scan_dir < 0 ? -1 : it->end_charpos;
8287 if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it),
8288 stop)
8289 && next_element_from_composition (it))
8291 return 1;
8294 /* Get the next character, maybe multibyte. */
8295 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
8296 if (it->multibyte_p && !ASCII_CHAR_P (*p))
8297 it->c = STRING_CHAR_AND_LENGTH (p, it->len);
8298 else
8299 it->c = *p, it->len = 1;
8301 /* Record what we have and where it came from. */
8302 it->what = IT_CHARACTER;
8303 it->object = it->w->contents;
8304 it->position = it->current.pos;
8306 /* Normally we return the character found above, except when we
8307 really want to return an ellipsis for selective display. */
8308 if (it->selective)
8310 if (it->c == '\n')
8312 /* A value of selective > 0 means hide lines indented more
8313 than that number of columns. */
8314 if (it->selective > 0
8315 && IT_CHARPOS (*it) + 1 < ZV
8316 && indented_beyond_p (IT_CHARPOS (*it) + 1,
8317 IT_BYTEPOS (*it) + 1,
8318 it->selective))
8320 success_p = next_element_from_ellipsis (it);
8321 it->dpvec_char_len = -1;
8324 else if (it->c == '\r' && it->selective == -1)
8326 /* A value of selective == -1 means that everything from the
8327 CR to the end of the line is invisible, with maybe an
8328 ellipsis displayed for it. */
8329 success_p = next_element_from_ellipsis (it);
8330 it->dpvec_char_len = -1;
8335 /* Value is zero if end of buffer reached. */
8336 eassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
8337 return success_p;
8341 /* Run the redisplay end trigger hook for IT. */
8343 static void
8344 run_redisplay_end_trigger_hook (struct it *it)
8346 Lisp_Object args[3];
8348 /* IT->glyph_row should be non-null, i.e. we should be actually
8349 displaying something, or otherwise we should not run the hook. */
8350 eassert (it->glyph_row);
8352 /* Set up hook arguments. */
8353 args[0] = Qredisplay_end_trigger_functions;
8354 args[1] = it->window;
8355 XSETINT (args[2], it->redisplay_end_trigger_charpos);
8356 it->redisplay_end_trigger_charpos = 0;
8358 /* Since we are *trying* to run these functions, don't try to run
8359 them again, even if they get an error. */
8360 wset_redisplay_end_trigger (it->w, Qnil);
8361 Frun_hook_with_args (3, args);
8363 /* Notice if it changed the face of the character we are on. */
8364 handle_face_prop (it);
8368 /* Deliver a composition display element. Unlike the other
8369 next_element_from_XXX, this function is not registered in the array
8370 get_next_element[]. It is called from next_element_from_buffer and
8371 next_element_from_string when necessary. */
8373 static int
8374 next_element_from_composition (struct it *it)
8376 it->what = IT_COMPOSITION;
8377 it->len = it->cmp_it.nbytes;
8378 if (STRINGP (it->string))
8380 if (it->c < 0)
8382 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
8383 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
8384 return 0;
8386 it->position = it->current.string_pos;
8387 it->object = it->string;
8388 it->c = composition_update_it (&it->cmp_it, IT_STRING_CHARPOS (*it),
8389 IT_STRING_BYTEPOS (*it), it->string);
8391 else
8393 if (it->c < 0)
8395 IT_CHARPOS (*it) += it->cmp_it.nchars;
8396 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
8397 if (it->bidi_p)
8399 if (it->bidi_it.new_paragraph)
8400 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
8401 /* Resync the bidi iterator with IT's new position.
8402 FIXME: this doesn't support bidirectional text. */
8403 while (it->bidi_it.charpos < IT_CHARPOS (*it))
8404 bidi_move_to_visually_next (&it->bidi_it);
8406 return 0;
8408 it->position = it->current.pos;
8409 it->object = it->w->contents;
8410 it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
8411 IT_BYTEPOS (*it), Qnil);
8413 return 1;
8418 /***********************************************************************
8419 Moving an iterator without producing glyphs
8420 ***********************************************************************/
8422 /* Check if iterator is at a position corresponding to a valid buffer
8423 position after some move_it_ call. */
8425 #define IT_POS_VALID_AFTER_MOVE_P(it) \
8426 ((it)->method == GET_FROM_STRING \
8427 ? IT_STRING_CHARPOS (*it) == 0 \
8428 : 1)
8431 /* Move iterator IT to a specified buffer or X position within one
8432 line on the display without producing glyphs.
8434 OP should be a bit mask including some or all of these bits:
8435 MOVE_TO_X: Stop upon reaching x-position TO_X.
8436 MOVE_TO_POS: Stop upon reaching buffer or string position TO_CHARPOS.
8437 Regardless of OP's value, stop upon reaching the end of the display line.
8439 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
8440 This means, in particular, that TO_X includes window's horizontal
8441 scroll amount.
8443 The return value has several possible values that
8444 say what condition caused the scan to stop:
8446 MOVE_POS_MATCH_OR_ZV
8447 - when TO_POS or ZV was reached.
8449 MOVE_X_REACHED
8450 -when TO_X was reached before TO_POS or ZV were reached.
8452 MOVE_LINE_CONTINUED
8453 - when we reached the end of the display area and the line must
8454 be continued.
8456 MOVE_LINE_TRUNCATED
8457 - when we reached the end of the display area and the line is
8458 truncated.
8460 MOVE_NEWLINE_OR_CR
8461 - when we stopped at a line end, i.e. a newline or a CR and selective
8462 display is on. */
8464 static enum move_it_result
8465 move_it_in_display_line_to (struct it *it,
8466 ptrdiff_t to_charpos, int to_x,
8467 enum move_operation_enum op)
8469 enum move_it_result result = MOVE_UNDEFINED;
8470 struct glyph_row *saved_glyph_row;
8471 struct it wrap_it, atpos_it, atx_it, ppos_it;
8472 void *wrap_data = NULL, *atpos_data = NULL, *atx_data = NULL;
8473 void *ppos_data = NULL;
8474 int may_wrap = 0;
8475 enum it_method prev_method = it->method;
8476 ptrdiff_t closest_pos IF_LINT (= 0), prev_pos = IT_CHARPOS (*it);
8477 int saw_smaller_pos = prev_pos < to_charpos;
8479 /* Don't produce glyphs in produce_glyphs. */
8480 saved_glyph_row = it->glyph_row;
8481 it->glyph_row = NULL;
8483 /* Use wrap_it to save a copy of IT wherever a word wrap could
8484 occur. Use atpos_it to save a copy of IT at the desired buffer
8485 position, if found, so that we can scan ahead and check if the
8486 word later overshoots the window edge. Use atx_it similarly, for
8487 pixel positions. */
8488 wrap_it.sp = -1;
8489 atpos_it.sp = -1;
8490 atx_it.sp = -1;
8492 /* Use ppos_it under bidi reordering to save a copy of IT for the
8493 initial position. We restore that position in IT when we have
8494 scanned the entire display line without finding a match for
8495 TO_CHARPOS and all the character positions are greater than
8496 TO_CHARPOS. We then restart the scan from the initial position,
8497 and stop at CLOSEST_POS, which is a position > TO_CHARPOS that is
8498 the closest to TO_CHARPOS. */
8499 if (it->bidi_p)
8501 if ((op & MOVE_TO_POS) && IT_CHARPOS (*it) >= to_charpos)
8503 SAVE_IT (ppos_it, *it, ppos_data);
8504 closest_pos = IT_CHARPOS (*it);
8506 else
8507 closest_pos = ZV;
8510 #define BUFFER_POS_REACHED_P() \
8511 ((op & MOVE_TO_POS) != 0 \
8512 && BUFFERP (it->object) \
8513 && (IT_CHARPOS (*it) == to_charpos \
8514 || ((!it->bidi_p \
8515 || BIDI_AT_BASE_LEVEL (it->bidi_it)) \
8516 && IT_CHARPOS (*it) > to_charpos) \
8517 || (it->what == IT_COMPOSITION \
8518 && ((IT_CHARPOS (*it) > to_charpos \
8519 && to_charpos >= it->cmp_it.charpos) \
8520 || (IT_CHARPOS (*it) < to_charpos \
8521 && to_charpos <= it->cmp_it.charpos)))) \
8522 && (it->method == GET_FROM_BUFFER \
8523 || (it->method == GET_FROM_DISPLAY_VECTOR \
8524 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
8526 /* If there's a line-/wrap-prefix, handle it. */
8527 if (it->hpos == 0 && it->method == GET_FROM_BUFFER
8528 && it->current_y < it->last_visible_y)
8529 handle_line_prefix (it);
8531 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8532 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8534 while (1)
8536 int x, i, ascent = 0, descent = 0;
8538 /* Utility macro to reset an iterator with x, ascent, and descent. */
8539 #define IT_RESET_X_ASCENT_DESCENT(IT) \
8540 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
8541 (IT)->max_descent = descent)
8543 /* Stop if we move beyond TO_CHARPOS (after an image or a
8544 display string or stretch glyph). */
8545 if ((op & MOVE_TO_POS) != 0
8546 && BUFFERP (it->object)
8547 && it->method == GET_FROM_BUFFER
8548 && (((!it->bidi_p
8549 /* When the iterator is at base embedding level, we
8550 are guaranteed that characters are delivered for
8551 display in strictly increasing order of their
8552 buffer positions. */
8553 || BIDI_AT_BASE_LEVEL (it->bidi_it))
8554 && IT_CHARPOS (*it) > to_charpos)
8555 || (it->bidi_p
8556 && (prev_method == GET_FROM_IMAGE
8557 || prev_method == GET_FROM_STRETCH
8558 || prev_method == GET_FROM_STRING)
8559 /* Passed TO_CHARPOS from left to right. */
8560 && ((prev_pos < to_charpos
8561 && IT_CHARPOS (*it) > to_charpos)
8562 /* Passed TO_CHARPOS from right to left. */
8563 || (prev_pos > to_charpos
8564 && IT_CHARPOS (*it) < to_charpos)))))
8566 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8568 result = MOVE_POS_MATCH_OR_ZV;
8569 break;
8571 else if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8572 /* If wrap_it is valid, the current position might be in a
8573 word that is wrapped. So, save the iterator in
8574 atpos_it and continue to see if wrapping happens. */
8575 SAVE_IT (atpos_it, *it, atpos_data);
8578 /* Stop when ZV reached.
8579 We used to stop here when TO_CHARPOS reached as well, but that is
8580 too soon if this glyph does not fit on this line. So we handle it
8581 explicitly below. */
8582 if (!get_next_display_element (it))
8584 result = MOVE_POS_MATCH_OR_ZV;
8585 break;
8588 if (it->line_wrap == TRUNCATE)
8590 if (BUFFER_POS_REACHED_P ())
8592 result = MOVE_POS_MATCH_OR_ZV;
8593 break;
8596 else
8598 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
8600 if (IT_DISPLAYING_WHITESPACE (it))
8601 may_wrap = 1;
8602 else if (may_wrap)
8604 /* We have reached a glyph that follows one or more
8605 whitespace characters. If the position is
8606 already found, we are done. */
8607 if (atpos_it.sp >= 0)
8609 RESTORE_IT (it, &atpos_it, atpos_data);
8610 result = MOVE_POS_MATCH_OR_ZV;
8611 goto done;
8613 if (atx_it.sp >= 0)
8615 RESTORE_IT (it, &atx_it, atx_data);
8616 result = MOVE_X_REACHED;
8617 goto done;
8619 /* Otherwise, we can wrap here. */
8620 SAVE_IT (wrap_it, *it, wrap_data);
8621 may_wrap = 0;
8626 /* Remember the line height for the current line, in case
8627 the next element doesn't fit on the line. */
8628 ascent = it->max_ascent;
8629 descent = it->max_descent;
8631 /* The call to produce_glyphs will get the metrics of the
8632 display element IT is loaded with. Record the x-position
8633 before this display element, in case it doesn't fit on the
8634 line. */
8635 x = it->current_x;
8637 PRODUCE_GLYPHS (it);
8639 if (it->area != TEXT_AREA)
8641 prev_method = it->method;
8642 if (it->method == GET_FROM_BUFFER)
8643 prev_pos = IT_CHARPOS (*it);
8644 set_iterator_to_next (it, 1);
8645 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8646 SET_TEXT_POS (this_line_min_pos,
8647 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8648 if (it->bidi_p
8649 && (op & MOVE_TO_POS)
8650 && IT_CHARPOS (*it) > to_charpos
8651 && IT_CHARPOS (*it) < closest_pos)
8652 closest_pos = IT_CHARPOS (*it);
8653 continue;
8656 /* The number of glyphs we get back in IT->nglyphs will normally
8657 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
8658 character on a terminal frame, or (iii) a line end. For the
8659 second case, IT->nglyphs - 1 padding glyphs will be present.
8660 (On X frames, there is only one glyph produced for a
8661 composite character.)
8663 The behavior implemented below means, for continuation lines,
8664 that as many spaces of a TAB as fit on the current line are
8665 displayed there. For terminal frames, as many glyphs of a
8666 multi-glyph character are displayed in the current line, too.
8667 This is what the old redisplay code did, and we keep it that
8668 way. Under X, the whole shape of a complex character must
8669 fit on the line or it will be completely displayed in the
8670 next line.
8672 Note that both for tabs and padding glyphs, all glyphs have
8673 the same width. */
8674 if (it->nglyphs)
8676 /* More than one glyph or glyph doesn't fit on line. All
8677 glyphs have the same width. */
8678 int single_glyph_width = it->pixel_width / it->nglyphs;
8679 int new_x;
8680 int x_before_this_char = x;
8681 int hpos_before_this_char = it->hpos;
8683 for (i = 0; i < it->nglyphs; ++i, x = new_x)
8685 new_x = x + single_glyph_width;
8687 /* We want to leave anything reaching TO_X to the caller. */
8688 if ((op & MOVE_TO_X) && new_x > to_x)
8690 if (BUFFER_POS_REACHED_P ())
8692 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8693 goto buffer_pos_reached;
8694 if (atpos_it.sp < 0)
8696 SAVE_IT (atpos_it, *it, atpos_data);
8697 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8700 else
8702 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8704 it->current_x = x;
8705 result = MOVE_X_REACHED;
8706 break;
8708 if (atx_it.sp < 0)
8710 SAVE_IT (atx_it, *it, atx_data);
8711 IT_RESET_X_ASCENT_DESCENT (&atx_it);
8716 if (/* Lines are continued. */
8717 it->line_wrap != TRUNCATE
8718 && (/* And glyph doesn't fit on the line. */
8719 new_x > it->last_visible_x
8720 /* Or it fits exactly and we're on a window
8721 system frame. */
8722 || (new_x == it->last_visible_x
8723 && FRAME_WINDOW_P (it->f)
8724 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
8725 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8726 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
8728 if (/* IT->hpos == 0 means the very first glyph
8729 doesn't fit on the line, e.g. a wide image. */
8730 it->hpos == 0
8731 || (new_x == it->last_visible_x
8732 && FRAME_WINDOW_P (it->f)
8733 /* When word-wrap is ON and we have a valid
8734 wrap point, we don't allow the last glyph
8735 to "just barely fit" on the line. */
8736 && (it->line_wrap != WORD_WRAP
8737 || wrap_it.sp < 0)))
8739 ++it->hpos;
8740 it->current_x = new_x;
8742 /* The character's last glyph just barely fits
8743 in this row. */
8744 if (i == it->nglyphs - 1)
8746 /* If this is the destination position,
8747 return a position *before* it in this row,
8748 now that we know it fits in this row. */
8749 if (BUFFER_POS_REACHED_P ())
8751 if (it->line_wrap != WORD_WRAP
8752 || wrap_it.sp < 0)
8754 it->hpos = hpos_before_this_char;
8755 it->current_x = x_before_this_char;
8756 result = MOVE_POS_MATCH_OR_ZV;
8757 break;
8759 if (it->line_wrap == WORD_WRAP
8760 && atpos_it.sp < 0)
8762 SAVE_IT (atpos_it, *it, atpos_data);
8763 atpos_it.current_x = x_before_this_char;
8764 atpos_it.hpos = hpos_before_this_char;
8768 prev_method = it->method;
8769 if (it->method == GET_FROM_BUFFER)
8770 prev_pos = IT_CHARPOS (*it);
8771 set_iterator_to_next (it, 1);
8772 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8773 SET_TEXT_POS (this_line_min_pos,
8774 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8775 /* On graphical terminals, newlines may
8776 "overflow" into the fringe if
8777 overflow-newline-into-fringe is non-nil.
8778 On text terminals, and on graphical
8779 terminals with no right margin, newlines
8780 may overflow into the last glyph on the
8781 display line.*/
8782 if (!FRAME_WINDOW_P (it->f)
8783 || ((it->bidi_p
8784 && it->bidi_it.paragraph_dir == R2L)
8785 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8786 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
8787 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8789 if (!get_next_display_element (it))
8791 result = MOVE_POS_MATCH_OR_ZV;
8792 break;
8794 if (BUFFER_POS_REACHED_P ())
8796 if (ITERATOR_AT_END_OF_LINE_P (it))
8797 result = MOVE_POS_MATCH_OR_ZV;
8798 else
8799 result = MOVE_LINE_CONTINUED;
8800 break;
8802 if (ITERATOR_AT_END_OF_LINE_P (it)
8803 && (it->line_wrap != WORD_WRAP
8804 || wrap_it.sp < 0))
8806 result = MOVE_NEWLINE_OR_CR;
8807 break;
8812 else
8813 IT_RESET_X_ASCENT_DESCENT (it);
8815 if (wrap_it.sp >= 0)
8817 RESTORE_IT (it, &wrap_it, wrap_data);
8818 atpos_it.sp = -1;
8819 atx_it.sp = -1;
8822 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
8823 IT_CHARPOS (*it)));
8824 result = MOVE_LINE_CONTINUED;
8825 break;
8828 if (BUFFER_POS_REACHED_P ())
8830 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8831 goto buffer_pos_reached;
8832 if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8834 SAVE_IT (atpos_it, *it, atpos_data);
8835 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8839 if (new_x > it->first_visible_x)
8841 /* Glyph is visible. Increment number of glyphs that
8842 would be displayed. */
8843 ++it->hpos;
8847 if (result != MOVE_UNDEFINED)
8848 break;
8850 else if (BUFFER_POS_REACHED_P ())
8852 buffer_pos_reached:
8853 IT_RESET_X_ASCENT_DESCENT (it);
8854 result = MOVE_POS_MATCH_OR_ZV;
8855 break;
8857 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
8859 /* Stop when TO_X specified and reached. This check is
8860 necessary here because of lines consisting of a line end,
8861 only. The line end will not produce any glyphs and we
8862 would never get MOVE_X_REACHED. */
8863 eassert (it->nglyphs == 0);
8864 result = MOVE_X_REACHED;
8865 break;
8868 /* Is this a line end? If yes, we're done. */
8869 if (ITERATOR_AT_END_OF_LINE_P (it))
8871 /* If we are past TO_CHARPOS, but never saw any character
8872 positions smaller than TO_CHARPOS, return
8873 MOVE_POS_MATCH_OR_ZV, like the unidirectional display
8874 did. */
8875 if (it->bidi_p && (op & MOVE_TO_POS) != 0)
8877 if (!saw_smaller_pos && IT_CHARPOS (*it) > to_charpos)
8879 if (closest_pos < ZV)
8881 RESTORE_IT (it, &ppos_it, ppos_data);
8882 /* Don't recurse if closest_pos is equal to
8883 to_charpos, since we have just tried that. */
8884 if (closest_pos != to_charpos)
8885 move_it_in_display_line_to (it, closest_pos, -1,
8886 MOVE_TO_POS);
8887 result = MOVE_POS_MATCH_OR_ZV;
8889 else
8890 goto buffer_pos_reached;
8892 else if (it->line_wrap == WORD_WRAP && atpos_it.sp >= 0
8893 && IT_CHARPOS (*it) > to_charpos)
8894 goto buffer_pos_reached;
8895 else
8896 result = MOVE_NEWLINE_OR_CR;
8898 else
8899 result = MOVE_NEWLINE_OR_CR;
8900 break;
8903 prev_method = it->method;
8904 if (it->method == GET_FROM_BUFFER)
8905 prev_pos = IT_CHARPOS (*it);
8906 /* The current display element has been consumed. Advance
8907 to the next. */
8908 set_iterator_to_next (it, 1);
8909 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8910 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8911 if (IT_CHARPOS (*it) < to_charpos)
8912 saw_smaller_pos = 1;
8913 if (it->bidi_p
8914 && (op & MOVE_TO_POS)
8915 && IT_CHARPOS (*it) >= to_charpos
8916 && IT_CHARPOS (*it) < closest_pos)
8917 closest_pos = IT_CHARPOS (*it);
8919 /* Stop if lines are truncated and IT's current x-position is
8920 past the right edge of the window now. */
8921 if (it->line_wrap == TRUNCATE
8922 && it->current_x >= it->last_visible_x)
8924 if (!FRAME_WINDOW_P (it->f)
8925 || ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
8926 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8927 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
8928 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8930 int at_eob_p = 0;
8932 if ((at_eob_p = !get_next_display_element (it))
8933 || BUFFER_POS_REACHED_P ()
8934 /* If we are past TO_CHARPOS, but never saw any
8935 character positions smaller than TO_CHARPOS,
8936 return MOVE_POS_MATCH_OR_ZV, like the
8937 unidirectional display did. */
8938 || (it->bidi_p && (op & MOVE_TO_POS) != 0
8939 && !saw_smaller_pos
8940 && IT_CHARPOS (*it) > to_charpos))
8942 if (it->bidi_p
8943 && !BUFFER_POS_REACHED_P ()
8944 && !at_eob_p && closest_pos < ZV)
8946 RESTORE_IT (it, &ppos_it, ppos_data);
8947 if (closest_pos != to_charpos)
8948 move_it_in_display_line_to (it, closest_pos, -1,
8949 MOVE_TO_POS);
8951 result = MOVE_POS_MATCH_OR_ZV;
8952 break;
8954 if (ITERATOR_AT_END_OF_LINE_P (it))
8956 result = MOVE_NEWLINE_OR_CR;
8957 break;
8960 else if (it->bidi_p && (op & MOVE_TO_POS) != 0
8961 && !saw_smaller_pos
8962 && IT_CHARPOS (*it) > to_charpos)
8964 if (closest_pos < ZV)
8966 RESTORE_IT (it, &ppos_it, ppos_data);
8967 if (closest_pos != to_charpos)
8968 move_it_in_display_line_to (it, closest_pos, -1,
8969 MOVE_TO_POS);
8971 result = MOVE_POS_MATCH_OR_ZV;
8972 break;
8974 result = MOVE_LINE_TRUNCATED;
8975 break;
8977 #undef IT_RESET_X_ASCENT_DESCENT
8980 #undef BUFFER_POS_REACHED_P
8982 /* If we scanned beyond to_pos and didn't find a point to wrap at,
8983 restore the saved iterator. */
8984 if (atpos_it.sp >= 0)
8985 RESTORE_IT (it, &atpos_it, atpos_data);
8986 else if (atx_it.sp >= 0)
8987 RESTORE_IT (it, &atx_it, atx_data);
8989 done:
8991 if (atpos_data)
8992 bidi_unshelve_cache (atpos_data, 1);
8993 if (atx_data)
8994 bidi_unshelve_cache (atx_data, 1);
8995 if (wrap_data)
8996 bidi_unshelve_cache (wrap_data, 1);
8997 if (ppos_data)
8998 bidi_unshelve_cache (ppos_data, 1);
9000 /* Restore the iterator settings altered at the beginning of this
9001 function. */
9002 it->glyph_row = saved_glyph_row;
9003 return result;
9006 /* For external use. */
9007 void
9008 move_it_in_display_line (struct it *it,
9009 ptrdiff_t to_charpos, int to_x,
9010 enum move_operation_enum op)
9012 if (it->line_wrap == WORD_WRAP
9013 && (op & MOVE_TO_X))
9015 struct it save_it;
9016 void *save_data = NULL;
9017 int skip;
9019 SAVE_IT (save_it, *it, save_data);
9020 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
9021 /* When word-wrap is on, TO_X may lie past the end
9022 of a wrapped line. Then it->current is the
9023 character on the next line, so backtrack to the
9024 space before the wrap point. */
9025 if (skip == MOVE_LINE_CONTINUED)
9027 int prev_x = max (it->current_x - 1, 0);
9028 RESTORE_IT (it, &save_it, save_data);
9029 move_it_in_display_line_to
9030 (it, -1, prev_x, MOVE_TO_X);
9032 else
9033 bidi_unshelve_cache (save_data, 1);
9035 else
9036 move_it_in_display_line_to (it, to_charpos, to_x, op);
9040 /* Move IT forward until it satisfies one or more of the criteria in
9041 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
9043 OP is a bit-mask that specifies where to stop, and in particular,
9044 which of those four position arguments makes a difference. See the
9045 description of enum move_operation_enum.
9047 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
9048 screen line, this function will set IT to the next position that is
9049 displayed to the right of TO_CHARPOS on the screen.
9051 Return the maximum pixel length of any line scanned but never more
9052 than it.last_visible_x. */
9055 move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos, int op)
9057 enum move_it_result skip, skip2 = MOVE_X_REACHED;
9058 int line_height, line_start_x = 0, reached = 0;
9059 int max_current_x = 0;
9060 void *backup_data = NULL;
9062 for (;;)
9064 if (op & MOVE_TO_VPOS)
9066 /* If no TO_CHARPOS and no TO_X specified, stop at the
9067 start of the line TO_VPOS. */
9068 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
9070 if (it->vpos == to_vpos)
9072 reached = 1;
9073 break;
9075 else
9076 skip = move_it_in_display_line_to (it, -1, -1, 0);
9078 else
9080 /* TO_VPOS >= 0 means stop at TO_X in the line at
9081 TO_VPOS, or at TO_POS, whichever comes first. */
9082 if (it->vpos == to_vpos)
9084 reached = 2;
9085 break;
9088 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
9090 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
9092 reached = 3;
9093 break;
9095 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
9097 /* We have reached TO_X but not in the line we want. */
9098 skip = move_it_in_display_line_to (it, to_charpos,
9099 -1, MOVE_TO_POS);
9100 if (skip == MOVE_POS_MATCH_OR_ZV)
9102 reached = 4;
9103 break;
9108 else if (op & MOVE_TO_Y)
9110 struct it it_backup;
9112 if (it->line_wrap == WORD_WRAP)
9113 SAVE_IT (it_backup, *it, backup_data);
9115 /* TO_Y specified means stop at TO_X in the line containing
9116 TO_Y---or at TO_CHARPOS if this is reached first. The
9117 problem is that we can't really tell whether the line
9118 contains TO_Y before we have completely scanned it, and
9119 this may skip past TO_X. What we do is to first scan to
9120 TO_X.
9122 If TO_X is not specified, use a TO_X of zero. The reason
9123 is to make the outcome of this function more predictable.
9124 If we didn't use TO_X == 0, we would stop at the end of
9125 the line which is probably not what a caller would expect
9126 to happen. */
9127 skip = move_it_in_display_line_to
9128 (it, to_charpos, ((op & MOVE_TO_X) ? to_x : 0),
9129 (MOVE_TO_X | (op & MOVE_TO_POS)));
9131 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
9132 if (skip == MOVE_POS_MATCH_OR_ZV)
9133 reached = 5;
9134 else if (skip == MOVE_X_REACHED)
9136 /* If TO_X was reached, we want to know whether TO_Y is
9137 in the line. We know this is the case if the already
9138 scanned glyphs make the line tall enough. Otherwise,
9139 we must check by scanning the rest of the line. */
9140 line_height = it->max_ascent + it->max_descent;
9141 if (to_y >= it->current_y
9142 && to_y < it->current_y + line_height)
9144 reached = 6;
9145 break;
9147 SAVE_IT (it_backup, *it, backup_data);
9148 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
9149 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
9150 op & MOVE_TO_POS);
9151 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
9152 line_height = it->max_ascent + it->max_descent;
9153 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
9155 if (to_y >= it->current_y
9156 && to_y < it->current_y + line_height)
9158 /* If TO_Y is in this line and TO_X was reached
9159 above, we scanned too far. We have to restore
9160 IT's settings to the ones before skipping. But
9161 keep the more accurate values of max_ascent and
9162 max_descent we've found while skipping the rest
9163 of the line, for the sake of callers, such as
9164 pos_visible_p, that need to know the line
9165 height. */
9166 int max_ascent = it->max_ascent;
9167 int max_descent = it->max_descent;
9169 RESTORE_IT (it, &it_backup, backup_data);
9170 it->max_ascent = max_ascent;
9171 it->max_descent = max_descent;
9172 reached = 6;
9174 else
9176 skip = skip2;
9177 if (skip == MOVE_POS_MATCH_OR_ZV)
9178 reached = 7;
9181 else
9183 /* Check whether TO_Y is in this line. */
9184 line_height = it->max_ascent + it->max_descent;
9185 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
9187 if (to_y >= it->current_y
9188 && to_y < it->current_y + line_height)
9190 if (to_y > it->current_y)
9191 max_current_x = max (it->current_x, max_current_x);
9193 /* When word-wrap is on, TO_X may lie past the end
9194 of a wrapped line. Then it->current is the
9195 character on the next line, so backtrack to the
9196 space before the wrap point. */
9197 if (skip == MOVE_LINE_CONTINUED
9198 && it->line_wrap == WORD_WRAP)
9200 int prev_x = max (it->current_x - 1, 0);
9201 RESTORE_IT (it, &it_backup, backup_data);
9202 skip = move_it_in_display_line_to
9203 (it, -1, prev_x, MOVE_TO_X);
9206 reached = 6;
9210 if (reached)
9212 max_current_x = max (it->current_x, max_current_x);
9213 break;
9216 else if (BUFFERP (it->object)
9217 && (it->method == GET_FROM_BUFFER
9218 || it->method == GET_FROM_STRETCH)
9219 && IT_CHARPOS (*it) >= to_charpos
9220 /* Under bidi iteration, a call to set_iterator_to_next
9221 can scan far beyond to_charpos if the initial
9222 portion of the next line needs to be reordered. In
9223 that case, give move_it_in_display_line_to another
9224 chance below. */
9225 && !(it->bidi_p
9226 && it->bidi_it.scan_dir == -1))
9227 skip = MOVE_POS_MATCH_OR_ZV;
9228 else
9229 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
9231 switch (skip)
9233 case MOVE_POS_MATCH_OR_ZV:
9234 max_current_x = max (it->current_x, max_current_x);
9235 reached = 8;
9236 goto out;
9238 case MOVE_NEWLINE_OR_CR:
9239 max_current_x = max (it->current_x, max_current_x);
9240 set_iterator_to_next (it, 1);
9241 it->continuation_lines_width = 0;
9242 break;
9244 case MOVE_LINE_TRUNCATED:
9245 max_current_x = it->last_visible_x;
9246 it->continuation_lines_width = 0;
9247 reseat_at_next_visible_line_start (it, 0);
9248 if ((op & MOVE_TO_POS) != 0
9249 && IT_CHARPOS (*it) > to_charpos)
9251 reached = 9;
9252 goto out;
9254 break;
9256 case MOVE_LINE_CONTINUED:
9257 max_current_x = it->last_visible_x;
9258 /* For continued lines ending in a tab, some of the glyphs
9259 associated with the tab are displayed on the current
9260 line. Since it->current_x does not include these glyphs,
9261 we use it->last_visible_x instead. */
9262 if (it->c == '\t')
9264 it->continuation_lines_width += it->last_visible_x;
9265 /* When moving by vpos, ensure that the iterator really
9266 advances to the next line (bug#847, bug#969). Fixme:
9267 do we need to do this in other circumstances? */
9268 if (it->current_x != it->last_visible_x
9269 && (op & MOVE_TO_VPOS)
9270 && !(op & (MOVE_TO_X | MOVE_TO_POS)))
9272 line_start_x = it->current_x + it->pixel_width
9273 - it->last_visible_x;
9274 if (FRAME_WINDOW_P (it->f))
9276 struct face *face = FACE_FROM_ID (it->f, it->face_id);
9277 struct font *face_font = face->font;
9279 /* When display_line produces a continued line
9280 that ends in a TAB, it skips a tab stop that
9281 is closer than the font's space character
9282 width (see x_produce_glyphs where it produces
9283 the stretch glyph which represents a TAB).
9284 We need to reproduce the same logic here. */
9285 eassert (face_font);
9286 if (face_font)
9288 if (line_start_x < face_font->space_width)
9289 line_start_x
9290 += it->tab_width * face_font->space_width;
9293 set_iterator_to_next (it, 0);
9296 else
9297 it->continuation_lines_width += it->current_x;
9298 break;
9300 default:
9301 emacs_abort ();
9304 /* Reset/increment for the next run. */
9305 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
9306 it->current_x = line_start_x;
9307 line_start_x = 0;
9308 it->hpos = 0;
9309 it->current_y += it->max_ascent + it->max_descent;
9310 ++it->vpos;
9311 last_height = it->max_ascent + it->max_descent;
9312 it->max_ascent = it->max_descent = 0;
9315 out:
9317 /* On text terminals, we may stop at the end of a line in the middle
9318 of a multi-character glyph. If the glyph itself is continued,
9319 i.e. it is actually displayed on the next line, don't treat this
9320 stopping point as valid; move to the next line instead (unless
9321 that brings us offscreen). */
9322 if (!FRAME_WINDOW_P (it->f)
9323 && op & MOVE_TO_POS
9324 && IT_CHARPOS (*it) == to_charpos
9325 && it->what == IT_CHARACTER
9326 && it->nglyphs > 1
9327 && it->line_wrap == WINDOW_WRAP
9328 && it->current_x == it->last_visible_x - 1
9329 && it->c != '\n'
9330 && it->c != '\t'
9331 && it->vpos < it->w->window_end_vpos)
9333 it->continuation_lines_width += it->current_x;
9334 it->current_x = it->hpos = it->max_ascent = it->max_descent = 0;
9335 it->current_y += it->max_ascent + it->max_descent;
9336 ++it->vpos;
9337 last_height = it->max_ascent + it->max_descent;
9340 if (backup_data)
9341 bidi_unshelve_cache (backup_data, 1);
9343 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
9345 return max_current_x;
9349 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
9351 If DY > 0, move IT backward at least that many pixels. DY = 0
9352 means move IT backward to the preceding line start or BEGV. This
9353 function may move over more than DY pixels if IT->current_y - DY
9354 ends up in the middle of a line; in this case IT->current_y will be
9355 set to the top of the line moved to. */
9357 void
9358 move_it_vertically_backward (struct it *it, int dy)
9360 int nlines, h;
9361 struct it it2, it3;
9362 void *it2data = NULL, *it3data = NULL;
9363 ptrdiff_t start_pos;
9364 int nchars_per_row
9365 = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
9366 ptrdiff_t pos_limit;
9368 move_further_back:
9369 eassert (dy >= 0);
9371 start_pos = IT_CHARPOS (*it);
9373 /* Estimate how many newlines we must move back. */
9374 nlines = max (1, dy / default_line_pixel_height (it->w));
9375 if (it->line_wrap == TRUNCATE || nchars_per_row == 0)
9376 pos_limit = BEGV;
9377 else
9378 pos_limit = max (start_pos - nlines * nchars_per_row, BEGV);
9380 /* Set the iterator's position that many lines back. But don't go
9381 back more than NLINES full screen lines -- this wins a day with
9382 buffers which have very long lines. */
9383 while (nlines-- && IT_CHARPOS (*it) > pos_limit)
9384 back_to_previous_visible_line_start (it);
9386 /* Reseat the iterator here. When moving backward, we don't want
9387 reseat to skip forward over invisible text, set up the iterator
9388 to deliver from overlay strings at the new position etc. So,
9389 use reseat_1 here. */
9390 reseat_1 (it, it->current.pos, 1);
9392 /* We are now surely at a line start. */
9393 it->current_x = it->hpos = 0; /* FIXME: this is incorrect when bidi
9394 reordering is in effect. */
9395 it->continuation_lines_width = 0;
9397 /* Move forward and see what y-distance we moved. First move to the
9398 start of the next line so that we get its height. We need this
9399 height to be able to tell whether we reached the specified
9400 y-distance. */
9401 SAVE_IT (it2, *it, it2data);
9402 it2.max_ascent = it2.max_descent = 0;
9405 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
9406 MOVE_TO_POS | MOVE_TO_VPOS);
9408 while (!(IT_POS_VALID_AFTER_MOVE_P (&it2)
9409 /* If we are in a display string which starts at START_POS,
9410 and that display string includes a newline, and we are
9411 right after that newline (i.e. at the beginning of a
9412 display line), exit the loop, because otherwise we will
9413 infloop, since move_it_to will see that it is already at
9414 START_POS and will not move. */
9415 || (it2.method == GET_FROM_STRING
9416 && IT_CHARPOS (it2) == start_pos
9417 && SREF (it2.string, IT_STRING_BYTEPOS (it2) - 1) == '\n')));
9418 eassert (IT_CHARPOS (*it) >= BEGV);
9419 SAVE_IT (it3, it2, it3data);
9421 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
9422 eassert (IT_CHARPOS (*it) >= BEGV);
9423 /* H is the actual vertical distance from the position in *IT
9424 and the starting position. */
9425 h = it2.current_y - it->current_y;
9426 /* NLINES is the distance in number of lines. */
9427 nlines = it2.vpos - it->vpos;
9429 /* Correct IT's y and vpos position
9430 so that they are relative to the starting point. */
9431 it->vpos -= nlines;
9432 it->current_y -= h;
9434 if (dy == 0)
9436 /* DY == 0 means move to the start of the screen line. The
9437 value of nlines is > 0 if continuation lines were involved,
9438 or if the original IT position was at start of a line. */
9439 RESTORE_IT (it, it, it2data);
9440 if (nlines > 0)
9441 move_it_by_lines (it, nlines);
9442 /* The above code moves us to some position NLINES down,
9443 usually to its first glyph (leftmost in an L2R line), but
9444 that's not necessarily the start of the line, under bidi
9445 reordering. We want to get to the character position
9446 that is immediately after the newline of the previous
9447 line. */
9448 if (it->bidi_p
9449 && !it->continuation_lines_width
9450 && !STRINGP (it->string)
9451 && IT_CHARPOS (*it) > BEGV
9452 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9454 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
9456 DEC_BOTH (cp, bp);
9457 cp = find_newline_no_quit (cp, bp, -1, NULL);
9458 move_it_to (it, cp, -1, -1, -1, MOVE_TO_POS);
9460 bidi_unshelve_cache (it3data, 1);
9462 else
9464 /* The y-position we try to reach, relative to *IT.
9465 Note that H has been subtracted in front of the if-statement. */
9466 int target_y = it->current_y + h - dy;
9467 int y0 = it3.current_y;
9468 int y1;
9469 int line_height;
9471 RESTORE_IT (&it3, &it3, it3data);
9472 y1 = line_bottom_y (&it3);
9473 line_height = y1 - y0;
9474 RESTORE_IT (it, it, it2data);
9475 /* If we did not reach target_y, try to move further backward if
9476 we can. If we moved too far backward, try to move forward. */
9477 if (target_y < it->current_y
9478 /* This is heuristic. In a window that's 3 lines high, with
9479 a line height of 13 pixels each, recentering with point
9480 on the bottom line will try to move -39/2 = 19 pixels
9481 backward. Try to avoid moving into the first line. */
9482 && (it->current_y - target_y
9483 > min (window_box_height (it->w), line_height * 2 / 3))
9484 && IT_CHARPOS (*it) > BEGV)
9486 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
9487 target_y - it->current_y));
9488 dy = it->current_y - target_y;
9489 goto move_further_back;
9491 else if (target_y >= it->current_y + line_height
9492 && IT_CHARPOS (*it) < ZV)
9494 /* Should move forward by at least one line, maybe more.
9496 Note: Calling move_it_by_lines can be expensive on
9497 terminal frames, where compute_motion is used (via
9498 vmotion) to do the job, when there are very long lines
9499 and truncate-lines is nil. That's the reason for
9500 treating terminal frames specially here. */
9502 if (!FRAME_WINDOW_P (it->f))
9503 move_it_vertically (it, target_y - (it->current_y + line_height));
9504 else
9508 move_it_by_lines (it, 1);
9510 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
9517 /* Move IT by a specified amount of pixel lines DY. DY negative means
9518 move backwards. DY = 0 means move to start of screen line. At the
9519 end, IT will be on the start of a screen line. */
9521 void
9522 move_it_vertically (struct it *it, int dy)
9524 if (dy <= 0)
9525 move_it_vertically_backward (it, -dy);
9526 else
9528 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
9529 move_it_to (it, ZV, -1, it->current_y + dy, -1,
9530 MOVE_TO_POS | MOVE_TO_Y);
9531 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
9533 /* If buffer ends in ZV without a newline, move to the start of
9534 the line to satisfy the post-condition. */
9535 if (IT_CHARPOS (*it) == ZV
9536 && ZV > BEGV
9537 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9538 move_it_by_lines (it, 0);
9543 /* Move iterator IT past the end of the text line it is in. */
9545 void
9546 move_it_past_eol (struct it *it)
9548 enum move_it_result rc;
9550 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
9551 if (rc == MOVE_NEWLINE_OR_CR)
9552 set_iterator_to_next (it, 0);
9556 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
9557 negative means move up. DVPOS == 0 means move to the start of the
9558 screen line.
9560 Optimization idea: If we would know that IT->f doesn't use
9561 a face with proportional font, we could be faster for
9562 truncate-lines nil. */
9564 void
9565 move_it_by_lines (struct it *it, ptrdiff_t dvpos)
9568 /* The commented-out optimization uses vmotion on terminals. This
9569 gives bad results, because elements like it->what, on which
9570 callers such as pos_visible_p rely, aren't updated. */
9571 /* struct position pos;
9572 if (!FRAME_WINDOW_P (it->f))
9574 struct text_pos textpos;
9576 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
9577 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
9578 reseat (it, textpos, 1);
9579 it->vpos += pos.vpos;
9580 it->current_y += pos.vpos;
9582 else */
9584 if (dvpos == 0)
9586 /* DVPOS == 0 means move to the start of the screen line. */
9587 move_it_vertically_backward (it, 0);
9588 /* Let next call to line_bottom_y calculate real line height. */
9589 last_height = 0;
9591 else if (dvpos > 0)
9593 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
9594 if (!IT_POS_VALID_AFTER_MOVE_P (it))
9596 /* Only move to the next buffer position if we ended up in a
9597 string from display property, not in an overlay string
9598 (before-string or after-string). That is because the
9599 latter don't conceal the underlying buffer position, so
9600 we can ask to move the iterator to the exact position we
9601 are interested in. Note that, even if we are already at
9602 IT_CHARPOS (*it), the call below is not a no-op, as it
9603 will detect that we are at the end of the string, pop the
9604 iterator, and compute it->current_x and it->hpos
9605 correctly. */
9606 move_it_to (it, IT_CHARPOS (*it) + it->string_from_display_prop_p,
9607 -1, -1, -1, MOVE_TO_POS);
9610 else
9612 struct it it2;
9613 void *it2data = NULL;
9614 ptrdiff_t start_charpos, i;
9615 int nchars_per_row
9616 = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
9617 bool hit_pos_limit = false;
9618 ptrdiff_t pos_limit;
9620 /* Start at the beginning of the screen line containing IT's
9621 position. This may actually move vertically backwards,
9622 in case of overlays, so adjust dvpos accordingly. */
9623 dvpos += it->vpos;
9624 move_it_vertically_backward (it, 0);
9625 dvpos -= it->vpos;
9627 /* Go back -DVPOS buffer lines, but no farther than -DVPOS full
9628 screen lines, and reseat the iterator there. */
9629 start_charpos = IT_CHARPOS (*it);
9630 if (it->line_wrap == TRUNCATE || nchars_per_row == 0)
9631 pos_limit = BEGV;
9632 else
9633 pos_limit = max (start_charpos + dvpos * nchars_per_row, BEGV);
9635 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > pos_limit; --i)
9636 back_to_previous_visible_line_start (it);
9637 if (i > 0 && IT_CHARPOS (*it) <= pos_limit)
9638 hit_pos_limit = true;
9639 reseat (it, it->current.pos, 1);
9641 /* Move further back if we end up in a string or an image. */
9642 while (!IT_POS_VALID_AFTER_MOVE_P (it))
9644 /* First try to move to start of display line. */
9645 dvpos += it->vpos;
9646 move_it_vertically_backward (it, 0);
9647 dvpos -= it->vpos;
9648 if (IT_POS_VALID_AFTER_MOVE_P (it))
9649 break;
9650 /* If start of line is still in string or image,
9651 move further back. */
9652 back_to_previous_visible_line_start (it);
9653 reseat (it, it->current.pos, 1);
9654 dvpos--;
9657 it->current_x = it->hpos = 0;
9659 /* Above call may have moved too far if continuation lines
9660 are involved. Scan forward and see if it did. */
9661 SAVE_IT (it2, *it, it2data);
9662 it2.vpos = it2.current_y = 0;
9663 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
9664 it->vpos -= it2.vpos;
9665 it->current_y -= it2.current_y;
9666 it->current_x = it->hpos = 0;
9668 /* If we moved too far back, move IT some lines forward. */
9669 if (it2.vpos > -dvpos)
9671 int delta = it2.vpos + dvpos;
9673 RESTORE_IT (&it2, &it2, it2data);
9674 SAVE_IT (it2, *it, it2data);
9675 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
9676 /* Move back again if we got too far ahead. */
9677 if (IT_CHARPOS (*it) >= start_charpos)
9678 RESTORE_IT (it, &it2, it2data);
9679 else
9680 bidi_unshelve_cache (it2data, 1);
9682 else if (hit_pos_limit && pos_limit > BEGV
9683 && dvpos < 0 && it2.vpos < -dvpos)
9685 /* If we hit the limit, but still didn't make it far enough
9686 back, that means there's a display string with a newline
9687 covering a large chunk of text, and that caused
9688 back_to_previous_visible_line_start try to go too far.
9689 Punish those who commit such atrocities by going back
9690 until we've reached DVPOS, after lifting the limit, which
9691 could make it slow for very long lines. "If it hurts,
9692 don't do that!" */
9693 dvpos += it2.vpos;
9694 RESTORE_IT (it, it, it2data);
9695 for (i = -dvpos; i > 0; --i)
9697 back_to_previous_visible_line_start (it);
9698 it->vpos--;
9701 else
9702 RESTORE_IT (it, it, it2data);
9706 /* Return true if IT points into the middle of a display vector. */
9708 bool
9709 in_display_vector_p (struct it *it)
9711 return (it->method == GET_FROM_DISPLAY_VECTOR
9712 && it->current.dpvec_index > 0
9713 && it->dpvec + it->current.dpvec_index != it->dpend);
9716 DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_size, 0, 6, 0,
9717 doc: /* Return the size of the text of WINDOW's buffer in pixels.
9718 WINDOW must be a live window and defaults to the selected one. The
9719 return value is a cons of the maximum pixel-width of any text line and
9720 the maximum pixel-height of all text lines.
9722 The optional argument FROM, if non-nil, specifies the first text
9723 position and defaults to the minimum accessible position of the buffer.
9724 If FROM is t, use the minimum accessible position that is not a newline
9725 character. TO, if non-nil, specifies the last text position and
9726 defaults to the maximum accessible position of the buffer. If TO is t,
9727 use the maximum accessible position that is not a newline character.
9729 The optional argument X-LIMIT, if non-nil, specifies the maximum text
9730 width that can be returned. X-LIMIT nil or omitted, means to use the
9731 pixel-width of WINDOW's body; use this if you do not intend to change
9732 the width of WINDOW. Use the maximum width WINDOW may assume if you
9733 intend to change WINDOW's width. In any case, text whose x-coordinate
9734 is beyond X-LIMIT is ignored. Since calculating the width of long lines
9735 can take some time, it's always a good idea to make this argument as
9736 small as possible; in particular, if the buffer contains long lines that
9737 shall be truncated anyway.
9739 The optional argument Y-LIMIT, if non-nil, specifies the maximum text
9740 height that can be returned. Text lines whose y-coordinate is beyond
9741 Y-LIMIT are ignored. Since calculating the text height of a large
9742 buffer can take some time, it makes sense to specify this argument if
9743 the size of the buffer is unknown.
9745 Optional argument MODE-AND-HEADER-LINE nil or omitted means do not
9746 include the height of the mode- or header-line of WINDOW in the return
9747 value. If it is either the symbol `mode-line' or `header-line', include
9748 only the height of that line, if present, in the return value. If t,
9749 include the height of both, if present, in the return value. */)
9750 (Lisp_Object window, Lisp_Object from, Lisp_Object to, Lisp_Object x_limit, Lisp_Object y_limit,
9751 Lisp_Object mode_and_header_line)
9753 struct window *w = decode_live_window (window);
9754 Lisp_Object buf;
9755 struct buffer *b;
9756 struct it it;
9757 struct buffer *old_buffer = NULL;
9758 ptrdiff_t start, end, pos;
9759 struct text_pos startp;
9760 void *itdata = NULL;
9761 int c, max_y = -1, x = 0, y = 0;
9763 buf = w->contents;
9764 CHECK_BUFFER (buf);
9765 b = XBUFFER (buf);
9767 if (b != current_buffer)
9769 old_buffer = current_buffer;
9770 set_buffer_internal (b);
9773 if (NILP (from))
9774 start = BEGV;
9775 else if (EQ (from, Qt))
9777 start = pos = BEGV;
9778 while ((pos++ < ZV) && (c = FETCH_CHAR (pos))
9779 && (c == ' ' || c == '\t' || c == '\n' || c == '\r'))
9780 start = pos;
9781 while ((pos-- > BEGV) && (c = FETCH_CHAR (pos)) && (c == ' ' || c == '\t'))
9782 start = pos;
9784 else
9786 CHECK_NUMBER_COERCE_MARKER (from);
9787 start = min (max (XINT (from), BEGV), ZV);
9790 if (NILP (to))
9791 end = ZV;
9792 else if (EQ (to, Qt))
9794 end = pos = ZV;
9795 while ((pos-- > BEGV) && (c = FETCH_CHAR (pos))
9796 && (c == ' ' || c == '\t' || c == '\n' || c == '\r'))
9797 end = pos;
9798 while ((pos++ < ZV) && (c = FETCH_CHAR (pos)) && (c == ' ' || c == '\t'))
9799 end = pos;
9801 else
9803 CHECK_NUMBER_COERCE_MARKER (to);
9804 end = max (start, min (XINT (to), ZV));
9807 if (!NILP (y_limit))
9809 CHECK_NUMBER (y_limit);
9810 max_y = min (XINT (y_limit), INT_MAX);
9813 itdata = bidi_shelve_cache ();
9814 SET_TEXT_POS (startp, start, CHAR_TO_BYTE (start));
9815 start_display (&it, w, startp);
9817 if (NILP (x_limit))
9818 x = move_it_to (&it, end, -1, max_y, -1, MOVE_TO_POS | MOVE_TO_Y);
9819 else
9821 CHECK_NUMBER (x_limit);
9822 it.last_visible_x = min (XINT (x_limit), INFINITY);
9823 /* Actually, we never want move_it_to stop at to_x. But to make
9824 sure that move_it_in_display_line_to always moves far enough,
9825 we set it to INT_MAX and specify MOVE_TO_X. */
9826 x = move_it_to (&it, end, INT_MAX, max_y, -1,
9827 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
9830 y = it.current_y + it.max_ascent + it.max_descent;
9832 if (!EQ (mode_and_header_line, Qheader_line)
9833 && !EQ (mode_and_header_line, Qt))
9834 /* Do not count the header-line which was counted automatically by
9835 start_display. */
9836 y = y - WINDOW_HEADER_LINE_HEIGHT (w);
9838 if (EQ (mode_and_header_line, Qmode_line)
9839 || EQ (mode_and_header_line, Qt))
9840 /* Do count the mode-line which is not included automatically by
9841 start_display. */
9842 y = y + WINDOW_MODE_LINE_HEIGHT (w);
9844 bidi_unshelve_cache (itdata, 0);
9846 if (old_buffer)
9847 set_buffer_internal (old_buffer);
9849 return Fcons (make_number (x), make_number (y));
9852 /***********************************************************************
9853 Messages
9854 ***********************************************************************/
9857 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
9858 to *Messages*. */
9860 void
9861 add_to_log (const char *format, Lisp_Object arg1, Lisp_Object arg2)
9863 Lisp_Object args[3];
9864 Lisp_Object msg, fmt;
9865 char *buffer;
9866 ptrdiff_t len;
9867 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
9868 USE_SAFE_ALLOCA;
9870 fmt = msg = Qnil;
9871 GCPRO4 (fmt, msg, arg1, arg2);
9873 args[0] = fmt = build_string (format);
9874 args[1] = arg1;
9875 args[2] = arg2;
9876 msg = Fformat (3, args);
9878 len = SBYTES (msg) + 1;
9879 buffer = SAFE_ALLOCA (len);
9880 memcpy (buffer, SDATA (msg), len);
9882 message_dolog (buffer, len - 1, 1, 0);
9883 SAFE_FREE ();
9885 UNGCPRO;
9889 /* Output a newline in the *Messages* buffer if "needs" one. */
9891 void
9892 message_log_maybe_newline (void)
9894 if (message_log_need_newline)
9895 message_dolog ("", 0, 1, 0);
9899 /* Add a string M of length NBYTES to the message log, optionally
9900 terminated with a newline when NLFLAG is true. MULTIBYTE, if
9901 true, means interpret the contents of M as multibyte. This
9902 function calls low-level routines in order to bypass text property
9903 hooks, etc. which might not be safe to run.
9905 This may GC (insert may run before/after change hooks),
9906 so the buffer M must NOT point to a Lisp string. */
9908 void
9909 message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte)
9911 const unsigned char *msg = (const unsigned char *) m;
9913 if (!NILP (Vmemory_full))
9914 return;
9916 if (!NILP (Vmessage_log_max))
9918 struct buffer *oldbuf;
9919 Lisp_Object oldpoint, oldbegv, oldzv;
9920 int old_windows_or_buffers_changed = windows_or_buffers_changed;
9921 ptrdiff_t point_at_end = 0;
9922 ptrdiff_t zv_at_end = 0;
9923 Lisp_Object old_deactivate_mark;
9924 struct gcpro gcpro1;
9926 old_deactivate_mark = Vdeactivate_mark;
9927 oldbuf = current_buffer;
9929 /* Ensure the Messages buffer exists, and switch to it.
9930 If we created it, set the major-mode. */
9932 int newbuffer = 0;
9933 if (NILP (Fget_buffer (Vmessages_buffer_name))) newbuffer = 1;
9935 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
9937 if (newbuffer
9938 && !NILP (Ffboundp (intern ("messages-buffer-mode"))))
9939 call0 (intern ("messages-buffer-mode"));
9942 bset_undo_list (current_buffer, Qt);
9943 bset_cache_long_scans (current_buffer, Qnil);
9945 oldpoint = message_dolog_marker1;
9946 set_marker_restricted_both (oldpoint, Qnil, PT, PT_BYTE);
9947 oldbegv = message_dolog_marker2;
9948 set_marker_restricted_both (oldbegv, Qnil, BEGV, BEGV_BYTE);
9949 oldzv = message_dolog_marker3;
9950 set_marker_restricted_both (oldzv, Qnil, ZV, ZV_BYTE);
9951 GCPRO1 (old_deactivate_mark);
9953 if (PT == Z)
9954 point_at_end = 1;
9955 if (ZV == Z)
9956 zv_at_end = 1;
9958 BEGV = BEG;
9959 BEGV_BYTE = BEG_BYTE;
9960 ZV = Z;
9961 ZV_BYTE = Z_BYTE;
9962 TEMP_SET_PT_BOTH (Z, Z_BYTE);
9964 /* Insert the string--maybe converting multibyte to single byte
9965 or vice versa, so that all the text fits the buffer. */
9966 if (multibyte
9967 && NILP (BVAR (current_buffer, enable_multibyte_characters)))
9969 ptrdiff_t i;
9970 int c, char_bytes;
9971 char work[1];
9973 /* Convert a multibyte string to single-byte
9974 for the *Message* buffer. */
9975 for (i = 0; i < nbytes; i += char_bytes)
9977 c = string_char_and_length (msg + i, &char_bytes);
9978 work[0] = CHAR_TO_BYTE8 (c);
9979 insert_1_both (work, 1, 1, 1, 0, 0);
9982 else if (! multibyte
9983 && ! NILP (BVAR (current_buffer, enable_multibyte_characters)))
9985 ptrdiff_t i;
9986 int c, char_bytes;
9987 unsigned char str[MAX_MULTIBYTE_LENGTH];
9988 /* Convert a single-byte string to multibyte
9989 for the *Message* buffer. */
9990 for (i = 0; i < nbytes; i++)
9992 c = msg[i];
9993 MAKE_CHAR_MULTIBYTE (c);
9994 char_bytes = CHAR_STRING (c, str);
9995 insert_1_both ((char *) str, 1, char_bytes, 1, 0, 0);
9998 else if (nbytes)
9999 insert_1_both (m, chars_in_text (msg, nbytes), nbytes, 1, 0, 0);
10001 if (nlflag)
10003 ptrdiff_t this_bol, this_bol_byte, prev_bol, prev_bol_byte;
10004 printmax_t dups;
10006 insert_1_both ("\n", 1, 1, 1, 0, 0);
10008 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
10009 this_bol = PT;
10010 this_bol_byte = PT_BYTE;
10012 /* See if this line duplicates the previous one.
10013 If so, combine duplicates. */
10014 if (this_bol > BEG)
10016 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
10017 prev_bol = PT;
10018 prev_bol_byte = PT_BYTE;
10020 dups = message_log_check_duplicate (prev_bol_byte,
10021 this_bol_byte);
10022 if (dups)
10024 del_range_both (prev_bol, prev_bol_byte,
10025 this_bol, this_bol_byte, 0);
10026 if (dups > 1)
10028 char dupstr[sizeof " [ times]"
10029 + INT_STRLEN_BOUND (printmax_t)];
10031 /* If you change this format, don't forget to also
10032 change message_log_check_duplicate. */
10033 int duplen = sprintf (dupstr, " [%"pMd" times]", dups);
10034 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
10035 insert_1_both (dupstr, duplen, duplen, 1, 0, 1);
10040 /* If we have more than the desired maximum number of lines
10041 in the *Messages* buffer now, delete the oldest ones.
10042 This is safe because we don't have undo in this buffer. */
10044 if (NATNUMP (Vmessage_log_max))
10046 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
10047 -XFASTINT (Vmessage_log_max) - 1, 0);
10048 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
10051 BEGV = marker_position (oldbegv);
10052 BEGV_BYTE = marker_byte_position (oldbegv);
10054 if (zv_at_end)
10056 ZV = Z;
10057 ZV_BYTE = Z_BYTE;
10059 else
10061 ZV = marker_position (oldzv);
10062 ZV_BYTE = marker_byte_position (oldzv);
10065 if (point_at_end)
10066 TEMP_SET_PT_BOTH (Z, Z_BYTE);
10067 else
10068 /* We can't do Fgoto_char (oldpoint) because it will run some
10069 Lisp code. */
10070 TEMP_SET_PT_BOTH (marker_position (oldpoint),
10071 marker_byte_position (oldpoint));
10073 UNGCPRO;
10074 unchain_marker (XMARKER (oldpoint));
10075 unchain_marker (XMARKER (oldbegv));
10076 unchain_marker (XMARKER (oldzv));
10078 /* We called insert_1_both above with its 5th argument (PREPARE)
10079 zero, which prevents insert_1_both from calling
10080 prepare_to_modify_buffer, which in turns prevents us from
10081 incrementing windows_or_buffers_changed even if *Messages* is
10082 shown in some window. So we must manually set
10083 windows_or_buffers_changed here to make up for that. */
10084 windows_or_buffers_changed = old_windows_or_buffers_changed;
10085 bset_redisplay (current_buffer);
10087 set_buffer_internal (oldbuf);
10089 message_log_need_newline = !nlflag;
10090 Vdeactivate_mark = old_deactivate_mark;
10095 /* We are at the end of the buffer after just having inserted a newline.
10096 (Note: We depend on the fact we won't be crossing the gap.)
10097 Check to see if the most recent message looks a lot like the previous one.
10098 Return 0 if different, 1 if the new one should just replace it, or a
10099 value N > 1 if we should also append " [N times]". */
10101 static intmax_t
10102 message_log_check_duplicate (ptrdiff_t prev_bol_byte, ptrdiff_t this_bol_byte)
10104 ptrdiff_t i;
10105 ptrdiff_t len = Z_BYTE - 1 - this_bol_byte;
10106 int seen_dots = 0;
10107 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
10108 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
10110 for (i = 0; i < len; i++)
10112 if (i >= 3 && p1[i - 3] == '.' && p1[i - 2] == '.' && p1[i - 1] == '.')
10113 seen_dots = 1;
10114 if (p1[i] != p2[i])
10115 return seen_dots;
10117 p1 += len;
10118 if (*p1 == '\n')
10119 return 2;
10120 if (*p1++ == ' ' && *p1++ == '[')
10122 char *pend;
10123 intmax_t n = strtoimax ((char *) p1, &pend, 10);
10124 if (0 < n && n < INTMAX_MAX && strncmp (pend, " times]\n", 8) == 0)
10125 return n + 1;
10127 return 0;
10131 /* Display an echo area message M with a specified length of NBYTES
10132 bytes. The string may include null characters. If M is not a
10133 string, clear out any existing message, and let the mini-buffer
10134 text show through.
10136 This function cancels echoing. */
10138 void
10139 message3 (Lisp_Object m)
10141 struct gcpro gcpro1;
10143 GCPRO1 (m);
10144 clear_message (true, true);
10145 cancel_echoing ();
10147 /* First flush out any partial line written with print. */
10148 message_log_maybe_newline ();
10149 if (STRINGP (m))
10151 ptrdiff_t nbytes = SBYTES (m);
10152 bool multibyte = STRING_MULTIBYTE (m);
10153 USE_SAFE_ALLOCA;
10154 char *buffer = SAFE_ALLOCA (nbytes);
10155 memcpy (buffer, SDATA (m), nbytes);
10156 message_dolog (buffer, nbytes, 1, multibyte);
10157 SAFE_FREE ();
10159 message3_nolog (m);
10161 UNGCPRO;
10165 /* The non-logging version of message3.
10166 This does not cancel echoing, because it is used for echoing.
10167 Perhaps we need to make a separate function for echoing
10168 and make this cancel echoing. */
10170 void
10171 message3_nolog (Lisp_Object m)
10173 struct frame *sf = SELECTED_FRAME ();
10175 if (FRAME_INITIAL_P (sf))
10177 if (noninteractive_need_newline)
10178 putc ('\n', stderr);
10179 noninteractive_need_newline = 0;
10180 if (STRINGP (m))
10182 Lisp_Object s = ENCODE_SYSTEM (m);
10184 fwrite (SDATA (s), SBYTES (s), 1, stderr);
10186 if (cursor_in_echo_area == 0)
10187 fprintf (stderr, "\n");
10188 fflush (stderr);
10190 /* Error messages get reported properly by cmd_error, so this must be just an
10191 informative message; if the frame hasn't really been initialized yet, just
10192 toss it. */
10193 else if (INTERACTIVE && sf->glyphs_initialized_p)
10195 /* Get the frame containing the mini-buffer
10196 that the selected frame is using. */
10197 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
10198 Lisp_Object frame = XWINDOW (mini_window)->frame;
10199 struct frame *f = XFRAME (frame);
10201 if (FRAME_VISIBLE_P (sf) && !FRAME_VISIBLE_P (f))
10202 Fmake_frame_visible (frame);
10204 if (STRINGP (m) && SCHARS (m) > 0)
10206 set_message (m);
10207 if (minibuffer_auto_raise)
10208 Fraise_frame (frame);
10209 /* Assume we are not echoing.
10210 (If we are, echo_now will override this.) */
10211 echo_message_buffer = Qnil;
10213 else
10214 clear_message (true, true);
10216 do_pending_window_change (0);
10217 echo_area_display (1);
10218 do_pending_window_change (0);
10219 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
10220 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
10225 /* Display a null-terminated echo area message M. If M is 0, clear
10226 out any existing message, and let the mini-buffer text show through.
10228 The buffer M must continue to exist until after the echo area gets
10229 cleared or some other message gets displayed there. Do not pass
10230 text that is stored in a Lisp string. Do not pass text in a buffer
10231 that was alloca'd. */
10233 void
10234 message1 (const char *m)
10236 message3 (m ? build_unibyte_string (m) : Qnil);
10240 /* The non-logging counterpart of message1. */
10242 void
10243 message1_nolog (const char *m)
10245 message3_nolog (m ? build_unibyte_string (m) : Qnil);
10248 /* Display a message M which contains a single %s
10249 which gets replaced with STRING. */
10251 void
10252 message_with_string (const char *m, Lisp_Object string, int log)
10254 CHECK_STRING (string);
10256 if (noninteractive)
10258 if (m)
10260 /* ENCODE_SYSTEM below can GC and/or relocate the
10261 Lisp data, so make sure we don't use it here. */
10262 eassert (relocatable_string_data_p (m) != 1);
10264 if (noninteractive_need_newline)
10265 putc ('\n', stderr);
10266 noninteractive_need_newline = 0;
10267 fprintf (stderr, m, SDATA (ENCODE_SYSTEM (string)));
10268 if (!cursor_in_echo_area)
10269 fprintf (stderr, "\n");
10270 fflush (stderr);
10273 else if (INTERACTIVE)
10275 /* The frame whose minibuffer we're going to display the message on.
10276 It may be larger than the selected frame, so we need
10277 to use its buffer, not the selected frame's buffer. */
10278 Lisp_Object mini_window;
10279 struct frame *f, *sf = SELECTED_FRAME ();
10281 /* Get the frame containing the minibuffer
10282 that the selected frame is using. */
10283 mini_window = FRAME_MINIBUF_WINDOW (sf);
10284 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10286 /* Error messages get reported properly by cmd_error, so this must be
10287 just an informative message; if the frame hasn't really been
10288 initialized yet, just toss it. */
10289 if (f->glyphs_initialized_p)
10291 Lisp_Object args[2], msg;
10292 struct gcpro gcpro1, gcpro2;
10294 args[0] = build_string (m);
10295 args[1] = msg = string;
10296 GCPRO2 (args[0], msg);
10297 gcpro1.nvars = 2;
10299 msg = Fformat (2, args);
10301 if (log)
10302 message3 (msg);
10303 else
10304 message3_nolog (msg);
10306 UNGCPRO;
10308 /* Print should start at the beginning of the message
10309 buffer next time. */
10310 message_buf_print = 0;
10316 /* Dump an informative message to the minibuf. If M is 0, clear out
10317 any existing message, and let the mini-buffer text show through. */
10319 static void
10320 vmessage (const char *m, va_list ap)
10322 if (noninteractive)
10324 if (m)
10326 if (noninteractive_need_newline)
10327 putc ('\n', stderr);
10328 noninteractive_need_newline = 0;
10329 vfprintf (stderr, m, ap);
10330 if (cursor_in_echo_area == 0)
10331 fprintf (stderr, "\n");
10332 fflush (stderr);
10335 else if (INTERACTIVE)
10337 /* The frame whose mini-buffer we're going to display the message
10338 on. It may be larger than the selected frame, so we need to
10339 use its buffer, not the selected frame's buffer. */
10340 Lisp_Object mini_window;
10341 struct frame *f, *sf = SELECTED_FRAME ();
10343 /* Get the frame containing the mini-buffer
10344 that the selected frame is using. */
10345 mini_window = FRAME_MINIBUF_WINDOW (sf);
10346 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10348 /* Error messages get reported properly by cmd_error, so this must be
10349 just an informative message; if the frame hasn't really been
10350 initialized yet, just toss it. */
10351 if (f->glyphs_initialized_p)
10353 if (m)
10355 ptrdiff_t len;
10356 ptrdiff_t maxsize = FRAME_MESSAGE_BUF_SIZE (f);
10357 char *message_buf = alloca (maxsize + 1);
10359 len = doprnt (message_buf, maxsize, m, 0, ap);
10361 message3 (make_string (message_buf, len));
10363 else
10364 message1 (0);
10366 /* Print should start at the beginning of the message
10367 buffer next time. */
10368 message_buf_print = 0;
10373 void
10374 message (const char *m, ...)
10376 va_list ap;
10377 va_start (ap, m);
10378 vmessage (m, ap);
10379 va_end (ap);
10383 #if 0
10384 /* The non-logging version of message. */
10386 void
10387 message_nolog (const char *m, ...)
10389 Lisp_Object old_log_max;
10390 va_list ap;
10391 va_start (ap, m);
10392 old_log_max = Vmessage_log_max;
10393 Vmessage_log_max = Qnil;
10394 vmessage (m, ap);
10395 Vmessage_log_max = old_log_max;
10396 va_end (ap);
10398 #endif
10401 /* Display the current message in the current mini-buffer. This is
10402 only called from error handlers in process.c, and is not time
10403 critical. */
10405 void
10406 update_echo_area (void)
10408 if (!NILP (echo_area_buffer[0]))
10410 Lisp_Object string;
10411 string = Fcurrent_message ();
10412 message3 (string);
10417 /* Make sure echo area buffers in `echo_buffers' are live.
10418 If they aren't, make new ones. */
10420 static void
10421 ensure_echo_area_buffers (void)
10423 int i;
10425 for (i = 0; i < 2; ++i)
10426 if (!BUFFERP (echo_buffer[i])
10427 || !BUFFER_LIVE_P (XBUFFER (echo_buffer[i])))
10429 char name[30];
10430 Lisp_Object old_buffer;
10431 int j;
10433 old_buffer = echo_buffer[i];
10434 echo_buffer[i] = Fget_buffer_create
10435 (make_formatted_string (name, " *Echo Area %d*", i));
10436 bset_truncate_lines (XBUFFER (echo_buffer[i]), Qnil);
10437 /* to force word wrap in echo area -
10438 it was decided to postpone this*/
10439 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
10441 for (j = 0; j < 2; ++j)
10442 if (EQ (old_buffer, echo_area_buffer[j]))
10443 echo_area_buffer[j] = echo_buffer[i];
10448 /* Call FN with args A1..A2 with either the current or last displayed
10449 echo_area_buffer as current buffer.
10451 WHICH zero means use the current message buffer
10452 echo_area_buffer[0]. If that is nil, choose a suitable buffer
10453 from echo_buffer[] and clear it.
10455 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
10456 suitable buffer from echo_buffer[] and clear it.
10458 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
10459 that the current message becomes the last displayed one, make
10460 choose a suitable buffer for echo_area_buffer[0], and clear it.
10462 Value is what FN returns. */
10464 static int
10465 with_echo_area_buffer (struct window *w, int which,
10466 int (*fn) (ptrdiff_t, Lisp_Object),
10467 ptrdiff_t a1, Lisp_Object a2)
10469 Lisp_Object buffer;
10470 int this_one, the_other, clear_buffer_p, rc;
10471 ptrdiff_t count = SPECPDL_INDEX ();
10473 /* If buffers aren't live, make new ones. */
10474 ensure_echo_area_buffers ();
10476 clear_buffer_p = 0;
10478 if (which == 0)
10479 this_one = 0, the_other = 1;
10480 else if (which > 0)
10481 this_one = 1, the_other = 0;
10482 else
10484 this_one = 0, the_other = 1;
10485 clear_buffer_p = true;
10487 /* We need a fresh one in case the current echo buffer equals
10488 the one containing the last displayed echo area message. */
10489 if (!NILP (echo_area_buffer[this_one])
10490 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
10491 echo_area_buffer[this_one] = Qnil;
10494 /* Choose a suitable buffer from echo_buffer[] is we don't
10495 have one. */
10496 if (NILP (echo_area_buffer[this_one]))
10498 echo_area_buffer[this_one]
10499 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
10500 ? echo_buffer[the_other]
10501 : echo_buffer[this_one]);
10502 clear_buffer_p = true;
10505 buffer = echo_area_buffer[this_one];
10507 /* Don't get confused by reusing the buffer used for echoing
10508 for a different purpose. */
10509 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
10510 cancel_echoing ();
10512 record_unwind_protect (unwind_with_echo_area_buffer,
10513 with_echo_area_buffer_unwind_data (w));
10515 /* Make the echo area buffer current. Note that for display
10516 purposes, it is not necessary that the displayed window's buffer
10517 == current_buffer, except for text property lookup. So, let's
10518 only set that buffer temporarily here without doing a full
10519 Fset_window_buffer. We must also change w->pointm, though,
10520 because otherwise an assertions in unshow_buffer fails, and Emacs
10521 aborts. */
10522 set_buffer_internal_1 (XBUFFER (buffer));
10523 if (w)
10525 wset_buffer (w, buffer);
10526 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
10527 set_marker_both (w->old_pointm, buffer, BEG, BEG_BYTE);
10530 bset_undo_list (current_buffer, Qt);
10531 bset_read_only (current_buffer, Qnil);
10532 specbind (Qinhibit_read_only, Qt);
10533 specbind (Qinhibit_modification_hooks, Qt);
10535 if (clear_buffer_p && Z > BEG)
10536 del_range (BEG, Z);
10538 eassert (BEGV >= BEG);
10539 eassert (ZV <= Z && ZV >= BEGV);
10541 rc = fn (a1, a2);
10543 eassert (BEGV >= BEG);
10544 eassert (ZV <= Z && ZV >= BEGV);
10546 unbind_to (count, Qnil);
10547 return rc;
10551 /* Save state that should be preserved around the call to the function
10552 FN called in with_echo_area_buffer. */
10554 static Lisp_Object
10555 with_echo_area_buffer_unwind_data (struct window *w)
10557 int i = 0;
10558 Lisp_Object vector, tmp;
10560 /* Reduce consing by keeping one vector in
10561 Vwith_echo_area_save_vector. */
10562 vector = Vwith_echo_area_save_vector;
10563 Vwith_echo_area_save_vector = Qnil;
10565 if (NILP (vector))
10566 vector = Fmake_vector (make_number (11), Qnil);
10568 XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
10569 ASET (vector, i, Vdeactivate_mark); ++i;
10570 ASET (vector, i, make_number (windows_or_buffers_changed)); ++i;
10572 if (w)
10574 XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i;
10575 ASET (vector, i, w->contents); ++i;
10576 ASET (vector, i, make_number (marker_position (w->pointm))); ++i;
10577 ASET (vector, i, make_number (marker_byte_position (w->pointm))); ++i;
10578 ASET (vector, i, make_number (marker_position (w->old_pointm))); ++i;
10579 ASET (vector, i, make_number (marker_byte_position (w->old_pointm))); ++i;
10580 ASET (vector, i, make_number (marker_position (w->start))); ++i;
10581 ASET (vector, i, make_number (marker_byte_position (w->start))); ++i;
10583 else
10585 int end = i + 8;
10586 for (; i < end; ++i)
10587 ASET (vector, i, Qnil);
10590 eassert (i == ASIZE (vector));
10591 return vector;
10595 /* Restore global state from VECTOR which was created by
10596 with_echo_area_buffer_unwind_data. */
10598 static void
10599 unwind_with_echo_area_buffer (Lisp_Object vector)
10601 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
10602 Vdeactivate_mark = AREF (vector, 1);
10603 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
10605 if (WINDOWP (AREF (vector, 3)))
10607 struct window *w;
10608 Lisp_Object buffer;
10610 w = XWINDOW (AREF (vector, 3));
10611 buffer = AREF (vector, 4);
10613 wset_buffer (w, buffer);
10614 set_marker_both (w->pointm, buffer,
10615 XFASTINT (AREF (vector, 5)),
10616 XFASTINT (AREF (vector, 6)));
10617 set_marker_both (w->old_pointm, buffer,
10618 XFASTINT (AREF (vector, 7)),
10619 XFASTINT (AREF (vector, 8)));
10620 set_marker_both (w->start, buffer,
10621 XFASTINT (AREF (vector, 9)),
10622 XFASTINT (AREF (vector, 10)));
10625 Vwith_echo_area_save_vector = vector;
10629 /* Set up the echo area for use by print functions. MULTIBYTE_P
10630 non-zero means we will print multibyte. */
10632 void
10633 setup_echo_area_for_printing (int multibyte_p)
10635 /* If we can't find an echo area any more, exit. */
10636 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
10637 Fkill_emacs (Qnil);
10639 ensure_echo_area_buffers ();
10641 if (!message_buf_print)
10643 /* A message has been output since the last time we printed.
10644 Choose a fresh echo area buffer. */
10645 if (EQ (echo_area_buffer[1], echo_buffer[0]))
10646 echo_area_buffer[0] = echo_buffer[1];
10647 else
10648 echo_area_buffer[0] = echo_buffer[0];
10650 /* Switch to that buffer and clear it. */
10651 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
10652 bset_truncate_lines (current_buffer, Qnil);
10654 if (Z > BEG)
10656 ptrdiff_t count = SPECPDL_INDEX ();
10657 specbind (Qinhibit_read_only, Qt);
10658 /* Note that undo recording is always disabled. */
10659 del_range (BEG, Z);
10660 unbind_to (count, Qnil);
10662 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
10664 /* Set up the buffer for the multibyteness we need. */
10665 if (multibyte_p
10666 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
10667 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
10669 /* Raise the frame containing the echo area. */
10670 if (minibuffer_auto_raise)
10672 struct frame *sf = SELECTED_FRAME ();
10673 Lisp_Object mini_window;
10674 mini_window = FRAME_MINIBUF_WINDOW (sf);
10675 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
10678 message_log_maybe_newline ();
10679 message_buf_print = 1;
10681 else
10683 if (NILP (echo_area_buffer[0]))
10685 if (EQ (echo_area_buffer[1], echo_buffer[0]))
10686 echo_area_buffer[0] = echo_buffer[1];
10687 else
10688 echo_area_buffer[0] = echo_buffer[0];
10691 if (current_buffer != XBUFFER (echo_area_buffer[0]))
10693 /* Someone switched buffers between print requests. */
10694 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
10695 bset_truncate_lines (current_buffer, Qnil);
10701 /* Display an echo area message in window W. Value is non-zero if W's
10702 height is changed. If display_last_displayed_message_p is
10703 non-zero, display the message that was last displayed, otherwise
10704 display the current message. */
10706 static int
10707 display_echo_area (struct window *w)
10709 int i, no_message_p, window_height_changed_p;
10711 /* Temporarily disable garbage collections while displaying the echo
10712 area. This is done because a GC can print a message itself.
10713 That message would modify the echo area buffer's contents while a
10714 redisplay of the buffer is going on, and seriously confuse
10715 redisplay. */
10716 ptrdiff_t count = inhibit_garbage_collection ();
10718 /* If there is no message, we must call display_echo_area_1
10719 nevertheless because it resizes the window. But we will have to
10720 reset the echo_area_buffer in question to nil at the end because
10721 with_echo_area_buffer will sets it to an empty buffer. */
10722 i = display_last_displayed_message_p ? 1 : 0;
10723 no_message_p = NILP (echo_area_buffer[i]);
10725 window_height_changed_p
10726 = with_echo_area_buffer (w, display_last_displayed_message_p,
10727 display_echo_area_1,
10728 (intptr_t) w, Qnil);
10730 if (no_message_p)
10731 echo_area_buffer[i] = Qnil;
10733 unbind_to (count, Qnil);
10734 return window_height_changed_p;
10738 /* Helper for display_echo_area. Display the current buffer which
10739 contains the current echo area message in window W, a mini-window,
10740 a pointer to which is passed in A1. A2..A4 are currently not used.
10741 Change the height of W so that all of the message is displayed.
10742 Value is non-zero if height of W was changed. */
10744 static int
10745 display_echo_area_1 (ptrdiff_t a1, Lisp_Object a2)
10747 intptr_t i1 = a1;
10748 struct window *w = (struct window *) i1;
10749 Lisp_Object window;
10750 struct text_pos start;
10751 int window_height_changed_p = 0;
10753 /* Do this before displaying, so that we have a large enough glyph
10754 matrix for the display. If we can't get enough space for the
10755 whole text, display the last N lines. That works by setting w->start. */
10756 window_height_changed_p = resize_mini_window (w, 0);
10758 /* Use the starting position chosen by resize_mini_window. */
10759 SET_TEXT_POS_FROM_MARKER (start, w->start);
10761 /* Display. */
10762 clear_glyph_matrix (w->desired_matrix);
10763 XSETWINDOW (window, w);
10764 try_window (window, start, 0);
10766 return window_height_changed_p;
10770 /* Resize the echo area window to exactly the size needed for the
10771 currently displayed message, if there is one. If a mini-buffer
10772 is active, don't shrink it. */
10774 void
10775 resize_echo_area_exactly (void)
10777 if (BUFFERP (echo_area_buffer[0])
10778 && WINDOWP (echo_area_window))
10780 struct window *w = XWINDOW (echo_area_window);
10781 Lisp_Object resize_exactly = (minibuf_level == 0 ? Qt : Qnil);
10782 int resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
10783 (intptr_t) w, resize_exactly);
10784 if (resized_p)
10786 windows_or_buffers_changed = 42;
10787 update_mode_lines = 30;
10788 redisplay_internal ();
10794 /* Callback function for with_echo_area_buffer, when used from
10795 resize_echo_area_exactly. A1 contains a pointer to the window to
10796 resize, EXACTLY non-nil means resize the mini-window exactly to the
10797 size of the text displayed. A3 and A4 are not used. Value is what
10798 resize_mini_window returns. */
10800 static int
10801 resize_mini_window_1 (ptrdiff_t a1, Lisp_Object exactly)
10803 intptr_t i1 = a1;
10804 return resize_mini_window ((struct window *) i1, !NILP (exactly));
10808 /* Resize mini-window W to fit the size of its contents. EXACT_P
10809 means size the window exactly to the size needed. Otherwise, it's
10810 only enlarged until W's buffer is empty.
10812 Set W->start to the right place to begin display. If the whole
10813 contents fit, start at the beginning. Otherwise, start so as
10814 to make the end of the contents appear. This is particularly
10815 important for y-or-n-p, but seems desirable generally.
10817 Value is non-zero if the window height has been changed. */
10820 resize_mini_window (struct window *w, int exact_p)
10822 struct frame *f = XFRAME (w->frame);
10823 int window_height_changed_p = 0;
10825 eassert (MINI_WINDOW_P (w));
10827 /* By default, start display at the beginning. */
10828 set_marker_both (w->start, w->contents,
10829 BUF_BEGV (XBUFFER (w->contents)),
10830 BUF_BEGV_BYTE (XBUFFER (w->contents)));
10832 /* Don't resize windows while redisplaying a window; it would
10833 confuse redisplay functions when the size of the window they are
10834 displaying changes from under them. Such a resizing can happen,
10835 for instance, when which-func prints a long message while
10836 we are running fontification-functions. We're running these
10837 functions with safe_call which binds inhibit-redisplay to t. */
10838 if (!NILP (Vinhibit_redisplay))
10839 return 0;
10841 /* Nil means don't try to resize. */
10842 if (NILP (Vresize_mini_windows)
10843 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
10844 return 0;
10846 if (!FRAME_MINIBUF_ONLY_P (f))
10848 struct it it;
10849 int total_height = (WINDOW_PIXEL_HEIGHT (XWINDOW (FRAME_ROOT_WINDOW (f)))
10850 + WINDOW_PIXEL_HEIGHT (w));
10851 int unit = FRAME_LINE_HEIGHT (f);
10852 int height, max_height;
10853 struct text_pos start;
10854 struct buffer *old_current_buffer = NULL;
10856 if (current_buffer != XBUFFER (w->contents))
10858 old_current_buffer = current_buffer;
10859 set_buffer_internal (XBUFFER (w->contents));
10862 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
10864 /* Compute the max. number of lines specified by the user. */
10865 if (FLOATP (Vmax_mini_window_height))
10866 max_height = XFLOATINT (Vmax_mini_window_height) * total_height;
10867 else if (INTEGERP (Vmax_mini_window_height))
10868 max_height = XINT (Vmax_mini_window_height) * unit;
10869 else
10870 max_height = total_height / 4;
10872 /* Correct that max. height if it's bogus. */
10873 max_height = clip_to_bounds (unit, max_height, total_height);
10875 /* Find out the height of the text in the window. */
10876 if (it.line_wrap == TRUNCATE)
10877 height = unit;
10878 else
10880 last_height = 0;
10881 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
10882 if (it.max_ascent == 0 && it.max_descent == 0)
10883 height = it.current_y + last_height;
10884 else
10885 height = it.current_y + it.max_ascent + it.max_descent;
10886 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
10889 /* Compute a suitable window start. */
10890 if (height > max_height)
10892 height = (max_height / unit) * unit;
10893 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
10894 move_it_vertically_backward (&it, height - unit);
10895 start = it.current.pos;
10897 else
10898 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
10899 SET_MARKER_FROM_TEXT_POS (w->start, start);
10901 if (EQ (Vresize_mini_windows, Qgrow_only))
10903 /* Let it grow only, until we display an empty message, in which
10904 case the window shrinks again. */
10905 if (height > WINDOW_PIXEL_HEIGHT (w))
10907 int old_height = WINDOW_PIXEL_HEIGHT (w);
10909 FRAME_WINDOWS_FROZEN (f) = 1;
10910 grow_mini_window (w, height - WINDOW_PIXEL_HEIGHT (w), 1);
10911 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
10913 else if (height < WINDOW_PIXEL_HEIGHT (w)
10914 && (exact_p || BEGV == ZV))
10916 int old_height = WINDOW_PIXEL_HEIGHT (w);
10918 FRAME_WINDOWS_FROZEN (f) = 0;
10919 shrink_mini_window (w, 1);
10920 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
10923 else
10925 /* Always resize to exact size needed. */
10926 if (height > WINDOW_PIXEL_HEIGHT (w))
10928 int old_height = WINDOW_PIXEL_HEIGHT (w);
10930 FRAME_WINDOWS_FROZEN (f) = 1;
10931 grow_mini_window (w, height - WINDOW_PIXEL_HEIGHT (w), 1);
10932 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
10934 else if (height < WINDOW_PIXEL_HEIGHT (w))
10936 int old_height = WINDOW_PIXEL_HEIGHT (w);
10938 FRAME_WINDOWS_FROZEN (f) = 0;
10939 shrink_mini_window (w, 1);
10941 if (height)
10943 FRAME_WINDOWS_FROZEN (f) = 1;
10944 grow_mini_window (w, height - WINDOW_PIXEL_HEIGHT (w), 1);
10947 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
10951 if (old_current_buffer)
10952 set_buffer_internal (old_current_buffer);
10955 return window_height_changed_p;
10959 /* Value is the current message, a string, or nil if there is no
10960 current message. */
10962 Lisp_Object
10963 current_message (void)
10965 Lisp_Object msg;
10967 if (!BUFFERP (echo_area_buffer[0]))
10968 msg = Qnil;
10969 else
10971 with_echo_area_buffer (0, 0, current_message_1,
10972 (intptr_t) &msg, Qnil);
10973 if (NILP (msg))
10974 echo_area_buffer[0] = Qnil;
10977 return msg;
10981 static int
10982 current_message_1 (ptrdiff_t a1, Lisp_Object a2)
10984 intptr_t i1 = a1;
10985 Lisp_Object *msg = (Lisp_Object *) i1;
10987 if (Z > BEG)
10988 *msg = make_buffer_string (BEG, Z, 1);
10989 else
10990 *msg = Qnil;
10991 return 0;
10995 /* Push the current message on Vmessage_stack for later restoration
10996 by restore_message. Value is non-zero if the current message isn't
10997 empty. This is a relatively infrequent operation, so it's not
10998 worth optimizing. */
11000 bool
11001 push_message (void)
11003 Lisp_Object msg = current_message ();
11004 Vmessage_stack = Fcons (msg, Vmessage_stack);
11005 return STRINGP (msg);
11009 /* Restore message display from the top of Vmessage_stack. */
11011 void
11012 restore_message (void)
11014 eassert (CONSP (Vmessage_stack));
11015 message3_nolog (XCAR (Vmessage_stack));
11019 /* Handler for unwind-protect calling pop_message. */
11021 void
11022 pop_message_unwind (void)
11024 /* Pop the top-most entry off Vmessage_stack. */
11025 eassert (CONSP (Vmessage_stack));
11026 Vmessage_stack = XCDR (Vmessage_stack);
11030 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
11031 exits. If the stack is not empty, we have a missing pop_message
11032 somewhere. */
11034 void
11035 check_message_stack (void)
11037 if (!NILP (Vmessage_stack))
11038 emacs_abort ();
11042 /* Truncate to NCHARS what will be displayed in the echo area the next
11043 time we display it---but don't redisplay it now. */
11045 void
11046 truncate_echo_area (ptrdiff_t nchars)
11048 if (nchars == 0)
11049 echo_area_buffer[0] = Qnil;
11050 else if (!noninteractive
11051 && INTERACTIVE
11052 && !NILP (echo_area_buffer[0]))
11054 struct frame *sf = SELECTED_FRAME ();
11055 /* Error messages get reported properly by cmd_error, so this must be
11056 just an informative message; if the frame hasn't really been
11057 initialized yet, just toss it. */
11058 if (sf->glyphs_initialized_p)
11059 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil);
11064 /* Helper function for truncate_echo_area. Truncate the current
11065 message to at most NCHARS characters. */
11067 static int
11068 truncate_message_1 (ptrdiff_t nchars, Lisp_Object a2)
11070 if (BEG + nchars < Z)
11071 del_range (BEG + nchars, Z);
11072 if (Z == BEG)
11073 echo_area_buffer[0] = Qnil;
11074 return 0;
11077 /* Set the current message to STRING. */
11079 static void
11080 set_message (Lisp_Object string)
11082 eassert (STRINGP (string));
11084 message_enable_multibyte = STRING_MULTIBYTE (string);
11086 with_echo_area_buffer (0, -1, set_message_1, 0, string);
11087 message_buf_print = 0;
11088 help_echo_showing_p = 0;
11090 if (STRINGP (Vdebug_on_message)
11091 && STRINGP (string)
11092 && fast_string_match (Vdebug_on_message, string) >= 0)
11093 call_debugger (list2 (Qerror, string));
11097 /* Helper function for set_message. First argument is ignored and second
11098 argument has the same meaning as for set_message.
11099 This function is called with the echo area buffer being current. */
11101 static int
11102 set_message_1 (ptrdiff_t a1, Lisp_Object string)
11104 eassert (STRINGP (string));
11106 /* Change multibyteness of the echo buffer appropriately. */
11107 if (message_enable_multibyte
11108 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
11109 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
11111 bset_truncate_lines (current_buffer, message_truncate_lines ? Qt : Qnil);
11112 if (!NILP (BVAR (current_buffer, bidi_display_reordering)))
11113 bset_bidi_paragraph_direction (current_buffer, Qleft_to_right);
11115 /* Insert new message at BEG. */
11116 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
11118 /* This function takes care of single/multibyte conversion.
11119 We just have to ensure that the echo area buffer has the right
11120 setting of enable_multibyte_characters. */
11121 insert_from_string (string, 0, 0, SCHARS (string), SBYTES (string), 1);
11123 return 0;
11127 /* Clear messages. CURRENT_P non-zero means clear the current
11128 message. LAST_DISPLAYED_P non-zero means clear the message
11129 last displayed. */
11131 void
11132 clear_message (bool current_p, bool last_displayed_p)
11134 if (current_p)
11136 echo_area_buffer[0] = Qnil;
11137 message_cleared_p = true;
11140 if (last_displayed_p)
11141 echo_area_buffer[1] = Qnil;
11143 message_buf_print = 0;
11146 /* Clear garbaged frames.
11148 This function is used where the old redisplay called
11149 redraw_garbaged_frames which in turn called redraw_frame which in
11150 turn called clear_frame. The call to clear_frame was a source of
11151 flickering. I believe a clear_frame is not necessary. It should
11152 suffice in the new redisplay to invalidate all current matrices,
11153 and ensure a complete redisplay of all windows. */
11155 static void
11156 clear_garbaged_frames (void)
11158 if (frame_garbaged)
11160 Lisp_Object tail, frame;
11162 FOR_EACH_FRAME (tail, frame)
11164 struct frame *f = XFRAME (frame);
11166 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
11168 if (f->resized_p)
11169 redraw_frame (f);
11170 else
11171 clear_current_matrices (f);
11172 fset_redisplay (f);
11173 f->garbaged = false;
11174 f->resized_p = false;
11178 frame_garbaged = false;
11183 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
11184 is non-zero update selected_frame. Value is non-zero if the
11185 mini-windows height has been changed. */
11187 static int
11188 echo_area_display (int update_frame_p)
11190 Lisp_Object mini_window;
11191 struct window *w;
11192 struct frame *f;
11193 int window_height_changed_p = 0;
11194 struct frame *sf = SELECTED_FRAME ();
11196 mini_window = FRAME_MINIBUF_WINDOW (sf);
11197 w = XWINDOW (mini_window);
11198 f = XFRAME (WINDOW_FRAME (w));
11200 /* Don't display if frame is invisible or not yet initialized. */
11201 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
11202 return 0;
11204 #ifdef HAVE_WINDOW_SYSTEM
11205 /* When Emacs starts, selected_frame may be the initial terminal
11206 frame. If we let this through, a message would be displayed on
11207 the terminal. */
11208 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
11209 return 0;
11210 #endif /* HAVE_WINDOW_SYSTEM */
11212 /* Redraw garbaged frames. */
11213 clear_garbaged_frames ();
11215 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
11217 echo_area_window = mini_window;
11218 window_height_changed_p = display_echo_area (w);
11219 w->must_be_updated_p = true;
11221 /* Update the display, unless called from redisplay_internal.
11222 Also don't update the screen during redisplay itself. The
11223 update will happen at the end of redisplay, and an update
11224 here could cause confusion. */
11225 if (update_frame_p && !redisplaying_p)
11227 int n = 0;
11229 /* If the display update has been interrupted by pending
11230 input, update mode lines in the frame. Due to the
11231 pending input, it might have been that redisplay hasn't
11232 been called, so that mode lines above the echo area are
11233 garbaged. This looks odd, so we prevent it here. */
11234 if (!display_completed)
11235 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), false);
11237 if (window_height_changed_p
11238 /* Don't do this if Emacs is shutting down. Redisplay
11239 needs to run hooks. */
11240 && !NILP (Vrun_hooks))
11242 /* Must update other windows. Likewise as in other
11243 cases, don't let this update be interrupted by
11244 pending input. */
11245 ptrdiff_t count = SPECPDL_INDEX ();
11246 specbind (Qredisplay_dont_pause, Qt);
11247 windows_or_buffers_changed = 44;
11248 redisplay_internal ();
11249 unbind_to (count, Qnil);
11251 else if (FRAME_WINDOW_P (f) && n == 0)
11253 /* Window configuration is the same as before.
11254 Can do with a display update of the echo area,
11255 unless we displayed some mode lines. */
11256 update_single_window (w, 1);
11257 flush_frame (f);
11259 else
11260 update_frame (f, 1, 1);
11262 /* If cursor is in the echo area, make sure that the next
11263 redisplay displays the minibuffer, so that the cursor will
11264 be replaced with what the minibuffer wants. */
11265 if (cursor_in_echo_area)
11266 wset_redisplay (XWINDOW (mini_window));
11269 else if (!EQ (mini_window, selected_window))
11270 wset_redisplay (XWINDOW (mini_window));
11272 /* Last displayed message is now the current message. */
11273 echo_area_buffer[1] = echo_area_buffer[0];
11274 /* Inform read_char that we're not echoing. */
11275 echo_message_buffer = Qnil;
11277 /* Prevent redisplay optimization in redisplay_internal by resetting
11278 this_line_start_pos. This is done because the mini-buffer now
11279 displays the message instead of its buffer text. */
11280 if (EQ (mini_window, selected_window))
11281 CHARPOS (this_line_start_pos) = 0;
11283 return window_height_changed_p;
11286 /* Nonzero if W's buffer was changed but not saved. */
11288 static int
11289 window_buffer_changed (struct window *w)
11291 struct buffer *b = XBUFFER (w->contents);
11293 eassert (BUFFER_LIVE_P (b));
11295 return (((BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) != w->last_had_star));
11298 /* Nonzero if W has %c in its mode line and mode line should be updated. */
11300 static int
11301 mode_line_update_needed (struct window *w)
11303 return (w->column_number_displayed != -1
11304 && !(PT == w->last_point && !window_outdated (w))
11305 && (w->column_number_displayed != current_column ()));
11308 /* Nonzero if window start of W is frozen and may not be changed during
11309 redisplay. */
11311 static bool
11312 window_frozen_p (struct window *w)
11314 if (FRAME_WINDOWS_FROZEN (XFRAME (WINDOW_FRAME (w))))
11316 Lisp_Object window;
11318 XSETWINDOW (window, w);
11319 if (MINI_WINDOW_P (w))
11320 return 0;
11321 else if (EQ (window, selected_window))
11322 return 0;
11323 else if (MINI_WINDOW_P (XWINDOW (selected_window))
11324 && EQ (window, Vminibuf_scroll_window))
11325 /* This special window can't be frozen too. */
11326 return 0;
11327 else
11328 return 1;
11330 return 0;
11333 /***********************************************************************
11334 Mode Lines and Frame Titles
11335 ***********************************************************************/
11337 /* A buffer for constructing non-propertized mode-line strings and
11338 frame titles in it; allocated from the heap in init_xdisp and
11339 resized as needed in store_mode_line_noprop_char. */
11341 static char *mode_line_noprop_buf;
11343 /* The buffer's end, and a current output position in it. */
11345 static char *mode_line_noprop_buf_end;
11346 static char *mode_line_noprop_ptr;
11348 #define MODE_LINE_NOPROP_LEN(start) \
11349 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
11351 static enum {
11352 MODE_LINE_DISPLAY = 0,
11353 MODE_LINE_TITLE,
11354 MODE_LINE_NOPROP,
11355 MODE_LINE_STRING
11356 } mode_line_target;
11358 /* Alist that caches the results of :propertize.
11359 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
11360 static Lisp_Object mode_line_proptrans_alist;
11362 /* List of strings making up the mode-line. */
11363 static Lisp_Object mode_line_string_list;
11365 /* Base face property when building propertized mode line string. */
11366 static Lisp_Object mode_line_string_face;
11367 static Lisp_Object mode_line_string_face_prop;
11370 /* Unwind data for mode line strings */
11372 static Lisp_Object Vmode_line_unwind_vector;
11374 static Lisp_Object
11375 format_mode_line_unwind_data (struct frame *target_frame,
11376 struct buffer *obuf,
11377 Lisp_Object owin,
11378 int save_proptrans)
11380 Lisp_Object vector, tmp;
11382 /* Reduce consing by keeping one vector in
11383 Vwith_echo_area_save_vector. */
11384 vector = Vmode_line_unwind_vector;
11385 Vmode_line_unwind_vector = Qnil;
11387 if (NILP (vector))
11388 vector = Fmake_vector (make_number (10), Qnil);
11390 ASET (vector, 0, make_number (mode_line_target));
11391 ASET (vector, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
11392 ASET (vector, 2, mode_line_string_list);
11393 ASET (vector, 3, save_proptrans ? mode_line_proptrans_alist : Qt);
11394 ASET (vector, 4, mode_line_string_face);
11395 ASET (vector, 5, mode_line_string_face_prop);
11397 if (obuf)
11398 XSETBUFFER (tmp, obuf);
11399 else
11400 tmp = Qnil;
11401 ASET (vector, 6, tmp);
11402 ASET (vector, 7, owin);
11403 if (target_frame)
11405 /* Similarly to `with-selected-window', if the operation selects
11406 a window on another frame, we must restore that frame's
11407 selected window, and (for a tty) the top-frame. */
11408 ASET (vector, 8, target_frame->selected_window);
11409 if (FRAME_TERMCAP_P (target_frame))
11410 ASET (vector, 9, FRAME_TTY (target_frame)->top_frame);
11413 return vector;
11416 static void
11417 unwind_format_mode_line (Lisp_Object vector)
11419 Lisp_Object old_window = AREF (vector, 7);
11420 Lisp_Object target_frame_window = AREF (vector, 8);
11421 Lisp_Object old_top_frame = AREF (vector, 9);
11423 mode_line_target = XINT (AREF (vector, 0));
11424 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
11425 mode_line_string_list = AREF (vector, 2);
11426 if (! EQ (AREF (vector, 3), Qt))
11427 mode_line_proptrans_alist = AREF (vector, 3);
11428 mode_line_string_face = AREF (vector, 4);
11429 mode_line_string_face_prop = AREF (vector, 5);
11431 /* Select window before buffer, since it may change the buffer. */
11432 if (!NILP (old_window))
11434 /* If the operation that we are unwinding had selected a window
11435 on a different frame, reset its frame-selected-window. For a
11436 text terminal, reset its top-frame if necessary. */
11437 if (!NILP (target_frame_window))
11439 Lisp_Object frame
11440 = WINDOW_FRAME (XWINDOW (target_frame_window));
11442 if (!EQ (frame, WINDOW_FRAME (XWINDOW (old_window))))
11443 Fselect_window (target_frame_window, Qt);
11445 if (!NILP (old_top_frame) && !EQ (old_top_frame, frame))
11446 Fselect_frame (old_top_frame, Qt);
11449 Fselect_window (old_window, Qt);
11452 if (!NILP (AREF (vector, 6)))
11454 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
11455 ASET (vector, 6, Qnil);
11458 Vmode_line_unwind_vector = vector;
11462 /* Store a single character C for the frame title in mode_line_noprop_buf.
11463 Re-allocate mode_line_noprop_buf if necessary. */
11465 static void
11466 store_mode_line_noprop_char (char c)
11468 /* If output position has reached the end of the allocated buffer,
11469 increase the buffer's size. */
11470 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
11472 ptrdiff_t len = MODE_LINE_NOPROP_LEN (0);
11473 ptrdiff_t size = len;
11474 mode_line_noprop_buf =
11475 xpalloc (mode_line_noprop_buf, &size, 1, STRING_BYTES_BOUND, 1);
11476 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
11477 mode_line_noprop_ptr = mode_line_noprop_buf + len;
11480 *mode_line_noprop_ptr++ = c;
11484 /* Store part of a frame title in mode_line_noprop_buf, beginning at
11485 mode_line_noprop_ptr. STRING is the string to store. Do not copy
11486 characters that yield more columns than PRECISION; PRECISION <= 0
11487 means copy the whole string. Pad with spaces until FIELD_WIDTH
11488 number of characters have been copied; FIELD_WIDTH <= 0 means don't
11489 pad. Called from display_mode_element when it is used to build a
11490 frame title. */
11492 static int
11493 store_mode_line_noprop (const char *string, int field_width, int precision)
11495 const unsigned char *str = (const unsigned char *) string;
11496 int n = 0;
11497 ptrdiff_t dummy, nbytes;
11499 /* Copy at most PRECISION chars from STR. */
11500 nbytes = strlen (string);
11501 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
11502 while (nbytes--)
11503 store_mode_line_noprop_char (*str++);
11505 /* Fill up with spaces until FIELD_WIDTH reached. */
11506 while (field_width > 0
11507 && n < field_width)
11509 store_mode_line_noprop_char (' ');
11510 ++n;
11513 return n;
11516 /***********************************************************************
11517 Frame Titles
11518 ***********************************************************************/
11520 #ifdef HAVE_WINDOW_SYSTEM
11522 /* Set the title of FRAME, if it has changed. The title format is
11523 Vicon_title_format if FRAME is iconified, otherwise it is
11524 frame_title_format. */
11526 static void
11527 x_consider_frame_title (Lisp_Object frame)
11529 struct frame *f = XFRAME (frame);
11531 if (FRAME_WINDOW_P (f)
11532 || FRAME_MINIBUF_ONLY_P (f)
11533 || f->explicit_name)
11535 /* Do we have more than one visible frame on this X display? */
11536 Lisp_Object tail, other_frame, fmt;
11537 ptrdiff_t title_start;
11538 char *title;
11539 ptrdiff_t len;
11540 struct it it;
11541 ptrdiff_t count = SPECPDL_INDEX ();
11543 FOR_EACH_FRAME (tail, other_frame)
11545 struct frame *tf = XFRAME (other_frame);
11547 if (tf != f
11548 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
11549 && !FRAME_MINIBUF_ONLY_P (tf)
11550 && !EQ (other_frame, tip_frame)
11551 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
11552 break;
11555 /* Set global variable indicating that multiple frames exist. */
11556 multiple_frames = CONSP (tail);
11558 /* Switch to the buffer of selected window of the frame. Set up
11559 mode_line_target so that display_mode_element will output into
11560 mode_line_noprop_buf; then display the title. */
11561 record_unwind_protect (unwind_format_mode_line,
11562 format_mode_line_unwind_data
11563 (f, current_buffer, selected_window, 0));
11565 Fselect_window (f->selected_window, Qt);
11566 set_buffer_internal_1
11567 (XBUFFER (XWINDOW (f->selected_window)->contents));
11568 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
11570 mode_line_target = MODE_LINE_TITLE;
11571 title_start = MODE_LINE_NOPROP_LEN (0);
11572 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
11573 NULL, DEFAULT_FACE_ID);
11574 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
11575 len = MODE_LINE_NOPROP_LEN (title_start);
11576 title = mode_line_noprop_buf + title_start;
11577 unbind_to (count, Qnil);
11579 /* Set the title only if it's changed. This avoids consing in
11580 the common case where it hasn't. (If it turns out that we've
11581 already wasted too much time by walking through the list with
11582 display_mode_element, then we might need to optimize at a
11583 higher level than this.) */
11584 if (! STRINGP (f->name)
11585 || SBYTES (f->name) != len
11586 || memcmp (title, SDATA (f->name), len) != 0)
11587 x_implicitly_set_name (f, make_string (title, len), Qnil);
11591 #endif /* not HAVE_WINDOW_SYSTEM */
11594 /***********************************************************************
11595 Menu Bars
11596 ***********************************************************************/
11598 /* Non-zero if we will not redisplay all visible windows. */
11599 #define REDISPLAY_SOME_P() \
11600 ((windows_or_buffers_changed == 0 \
11601 || windows_or_buffers_changed == REDISPLAY_SOME) \
11602 && (update_mode_lines == 0 \
11603 || update_mode_lines == REDISPLAY_SOME))
11605 /* Prepare for redisplay by updating menu-bar item lists when
11606 appropriate. This can call eval. */
11608 static void
11609 prepare_menu_bars (void)
11611 bool all_windows = windows_or_buffers_changed || update_mode_lines;
11612 bool some_windows = REDISPLAY_SOME_P ();
11613 struct gcpro gcpro1, gcpro2;
11614 Lisp_Object tooltip_frame;
11616 #ifdef HAVE_WINDOW_SYSTEM
11617 tooltip_frame = tip_frame;
11618 #else
11619 tooltip_frame = Qnil;
11620 #endif
11622 if (FUNCTIONP (Vpre_redisplay_function))
11624 Lisp_Object windows = all_windows ? Qt : Qnil;
11625 if (all_windows && some_windows)
11627 Lisp_Object ws = window_list ();
11628 for (windows = Qnil; CONSP (ws); ws = XCDR (ws))
11630 Lisp_Object this = XCAR (ws);
11631 struct window *w = XWINDOW (this);
11632 if (w->redisplay
11633 || XFRAME (w->frame)->redisplay
11634 || XBUFFER (w->contents)->text->redisplay)
11636 windows = Fcons (this, windows);
11640 safe__call1 (true, Vpre_redisplay_function, windows);
11643 /* Update all frame titles based on their buffer names, etc. We do
11644 this before the menu bars so that the buffer-menu will show the
11645 up-to-date frame titles. */
11646 #ifdef HAVE_WINDOW_SYSTEM
11647 if (all_windows)
11649 Lisp_Object tail, frame;
11651 FOR_EACH_FRAME (tail, frame)
11653 struct frame *f = XFRAME (frame);
11654 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
11655 if (some_windows
11656 && !f->redisplay
11657 && !w->redisplay
11658 && !XBUFFER (w->contents)->text->redisplay)
11659 continue;
11661 if (!EQ (frame, tooltip_frame)
11662 && (FRAME_ICONIFIED_P (f)
11663 || FRAME_VISIBLE_P (f) == 1
11664 /* Exclude TTY frames that are obscured because they
11665 are not the top frame on their console. This is
11666 because x_consider_frame_title actually switches
11667 to the frame, which for TTY frames means it is
11668 marked as garbaged, and will be completely
11669 redrawn on the next redisplay cycle. This causes
11670 TTY frames to be completely redrawn, when there
11671 are more than one of them, even though nothing
11672 should be changed on display. */
11673 || (FRAME_VISIBLE_P (f) == 2 && FRAME_WINDOW_P (f))))
11674 x_consider_frame_title (frame);
11677 #endif /* HAVE_WINDOW_SYSTEM */
11679 /* Update the menu bar item lists, if appropriate. This has to be
11680 done before any actual redisplay or generation of display lines. */
11682 if (all_windows)
11684 Lisp_Object tail, frame;
11685 ptrdiff_t count = SPECPDL_INDEX ();
11686 /* 1 means that update_menu_bar has run its hooks
11687 so any further calls to update_menu_bar shouldn't do so again. */
11688 int menu_bar_hooks_run = 0;
11690 record_unwind_save_match_data ();
11692 FOR_EACH_FRAME (tail, frame)
11694 struct frame *f = XFRAME (frame);
11695 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
11697 /* Ignore tooltip frame. */
11698 if (EQ (frame, tooltip_frame))
11699 continue;
11701 if (some_windows
11702 && !f->redisplay
11703 && !w->redisplay
11704 && !XBUFFER (w->contents)->text->redisplay)
11705 continue;
11707 /* If a window on this frame changed size, report that to
11708 the user and clear the size-change flag. */
11709 if (FRAME_WINDOW_SIZES_CHANGED (f))
11711 Lisp_Object functions;
11713 /* Clear flag first in case we get an error below. */
11714 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
11715 functions = Vwindow_size_change_functions;
11716 GCPRO2 (tail, functions);
11718 while (CONSP (functions))
11720 if (!EQ (XCAR (functions), Qt))
11721 call1 (XCAR (functions), frame);
11722 functions = XCDR (functions);
11724 UNGCPRO;
11727 GCPRO1 (tail);
11728 menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
11729 #ifdef HAVE_WINDOW_SYSTEM
11730 update_tool_bar (f, 0);
11731 #endif
11732 #ifdef HAVE_NS
11733 if (windows_or_buffers_changed
11734 && FRAME_NS_P (f))
11735 ns_set_doc_edited
11736 (f, Fbuffer_modified_p (XWINDOW (f->selected_window)->contents));
11737 #endif
11738 UNGCPRO;
11741 unbind_to (count, Qnil);
11743 else
11745 struct frame *sf = SELECTED_FRAME ();
11746 update_menu_bar (sf, 1, 0);
11747 #ifdef HAVE_WINDOW_SYSTEM
11748 update_tool_bar (sf, 1);
11749 #endif
11754 /* Update the menu bar item list for frame F. This has to be done
11755 before we start to fill in any display lines, because it can call
11756 eval.
11758 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
11760 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
11761 already ran the menu bar hooks for this redisplay, so there
11762 is no need to run them again. The return value is the
11763 updated value of this flag, to pass to the next call. */
11765 static int
11766 update_menu_bar (struct frame *f, int save_match_data, int hooks_run)
11768 Lisp_Object window;
11769 register struct window *w;
11771 /* If called recursively during a menu update, do nothing. This can
11772 happen when, for instance, an activate-menubar-hook causes a
11773 redisplay. */
11774 if (inhibit_menubar_update)
11775 return hooks_run;
11777 window = FRAME_SELECTED_WINDOW (f);
11778 w = XWINDOW (window);
11780 if (FRAME_WINDOW_P (f)
11782 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11783 || defined (HAVE_NS) || defined (USE_GTK)
11784 FRAME_EXTERNAL_MENU_BAR (f)
11785 #else
11786 FRAME_MENU_BAR_LINES (f) > 0
11787 #endif
11788 : FRAME_MENU_BAR_LINES (f) > 0)
11790 /* If the user has switched buffers or windows, we need to
11791 recompute to reflect the new bindings. But we'll
11792 recompute when update_mode_lines is set too; that means
11793 that people can use force-mode-line-update to request
11794 that the menu bar be recomputed. The adverse effect on
11795 the rest of the redisplay algorithm is about the same as
11796 windows_or_buffers_changed anyway. */
11797 if (windows_or_buffers_changed
11798 /* This used to test w->update_mode_line, but we believe
11799 there is no need to recompute the menu in that case. */
11800 || update_mode_lines
11801 || window_buffer_changed (w))
11803 struct buffer *prev = current_buffer;
11804 ptrdiff_t count = SPECPDL_INDEX ();
11806 specbind (Qinhibit_menubar_update, Qt);
11808 set_buffer_internal_1 (XBUFFER (w->contents));
11809 if (save_match_data)
11810 record_unwind_save_match_data ();
11811 if (NILP (Voverriding_local_map_menu_flag))
11813 specbind (Qoverriding_terminal_local_map, Qnil);
11814 specbind (Qoverriding_local_map, Qnil);
11817 if (!hooks_run)
11819 /* Run the Lucid hook. */
11820 safe_run_hooks (Qactivate_menubar_hook);
11822 /* If it has changed current-menubar from previous value,
11823 really recompute the menu-bar from the value. */
11824 if (! NILP (Vlucid_menu_bar_dirty_flag))
11825 call0 (Qrecompute_lucid_menubar);
11827 safe_run_hooks (Qmenu_bar_update_hook);
11829 hooks_run = 1;
11832 XSETFRAME (Vmenu_updating_frame, f);
11833 fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f)));
11835 /* Redisplay the menu bar in case we changed it. */
11836 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11837 || defined (HAVE_NS) || defined (USE_GTK)
11838 if (FRAME_WINDOW_P (f))
11840 #if defined (HAVE_NS)
11841 /* All frames on Mac OS share the same menubar. So only
11842 the selected frame should be allowed to set it. */
11843 if (f == SELECTED_FRAME ())
11844 #endif
11845 set_frame_menubar (f, 0, 0);
11847 else
11848 /* On a terminal screen, the menu bar is an ordinary screen
11849 line, and this makes it get updated. */
11850 w->update_mode_line = 1;
11851 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11852 /* In the non-toolkit version, the menu bar is an ordinary screen
11853 line, and this makes it get updated. */
11854 w->update_mode_line = 1;
11855 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11857 unbind_to (count, Qnil);
11858 set_buffer_internal_1 (prev);
11862 return hooks_run;
11865 /***********************************************************************
11866 Tool-bars
11867 ***********************************************************************/
11869 #ifdef HAVE_WINDOW_SYSTEM
11871 /* Select `frame' temporarily without running all the code in
11872 do_switch_frame.
11873 FIXME: Maybe do_switch_frame should be trimmed down similarly
11874 when `norecord' is set. */
11875 static void
11876 fast_set_selected_frame (Lisp_Object frame)
11878 if (!EQ (selected_frame, frame))
11880 selected_frame = frame;
11881 selected_window = XFRAME (frame)->selected_window;
11885 /* Update the tool-bar item list for frame F. This has to be done
11886 before we start to fill in any display lines. Called from
11887 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
11888 and restore it here. */
11890 static void
11891 update_tool_bar (struct frame *f, int save_match_data)
11893 #if defined (USE_GTK) || defined (HAVE_NS)
11894 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
11895 #else
11896 int do_update = (WINDOWP (f->tool_bar_window)
11897 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0);
11898 #endif
11900 if (do_update)
11902 Lisp_Object window;
11903 struct window *w;
11905 window = FRAME_SELECTED_WINDOW (f);
11906 w = XWINDOW (window);
11908 /* If the user has switched buffers or windows, we need to
11909 recompute to reflect the new bindings. But we'll
11910 recompute when update_mode_lines is set too; that means
11911 that people can use force-mode-line-update to request
11912 that the menu bar be recomputed. The adverse effect on
11913 the rest of the redisplay algorithm is about the same as
11914 windows_or_buffers_changed anyway. */
11915 if (windows_or_buffers_changed
11916 || w->update_mode_line
11917 || update_mode_lines
11918 || window_buffer_changed (w))
11920 struct buffer *prev = current_buffer;
11921 ptrdiff_t count = SPECPDL_INDEX ();
11922 Lisp_Object frame, new_tool_bar;
11923 int new_n_tool_bar;
11924 struct gcpro gcpro1;
11926 /* Set current_buffer to the buffer of the selected
11927 window of the frame, so that we get the right local
11928 keymaps. */
11929 set_buffer_internal_1 (XBUFFER (w->contents));
11931 /* Save match data, if we must. */
11932 if (save_match_data)
11933 record_unwind_save_match_data ();
11935 /* Make sure that we don't accidentally use bogus keymaps. */
11936 if (NILP (Voverriding_local_map_menu_flag))
11938 specbind (Qoverriding_terminal_local_map, Qnil);
11939 specbind (Qoverriding_local_map, Qnil);
11942 GCPRO1 (new_tool_bar);
11944 /* We must temporarily set the selected frame to this frame
11945 before calling tool_bar_items, because the calculation of
11946 the tool-bar keymap uses the selected frame (see
11947 `tool-bar-make-keymap' in tool-bar.el). */
11948 eassert (EQ (selected_window,
11949 /* Since we only explicitly preserve selected_frame,
11950 check that selected_window would be redundant. */
11951 XFRAME (selected_frame)->selected_window));
11952 record_unwind_protect (fast_set_selected_frame, selected_frame);
11953 XSETFRAME (frame, f);
11954 fast_set_selected_frame (frame);
11956 /* Build desired tool-bar items from keymaps. */
11957 new_tool_bar
11958 = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
11959 &new_n_tool_bar);
11961 /* Redisplay the tool-bar if we changed it. */
11962 if (new_n_tool_bar != f->n_tool_bar_items
11963 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
11965 /* Redisplay that happens asynchronously due to an expose event
11966 may access f->tool_bar_items. Make sure we update both
11967 variables within BLOCK_INPUT so no such event interrupts. */
11968 block_input ();
11969 fset_tool_bar_items (f, new_tool_bar);
11970 f->n_tool_bar_items = new_n_tool_bar;
11971 w->update_mode_line = 1;
11972 unblock_input ();
11975 UNGCPRO;
11977 unbind_to (count, Qnil);
11978 set_buffer_internal_1 (prev);
11983 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
11985 /* Set F->desired_tool_bar_string to a Lisp string representing frame
11986 F's desired tool-bar contents. F->tool_bar_items must have
11987 been set up previously by calling prepare_menu_bars. */
11989 static void
11990 build_desired_tool_bar_string (struct frame *f)
11992 int i, size, size_needed;
11993 struct gcpro gcpro1, gcpro2, gcpro3;
11994 Lisp_Object image, plist, props;
11996 image = plist = props = Qnil;
11997 GCPRO3 (image, plist, props);
11999 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
12000 Otherwise, make a new string. */
12002 /* The size of the string we might be able to reuse. */
12003 size = (STRINGP (f->desired_tool_bar_string)
12004 ? SCHARS (f->desired_tool_bar_string)
12005 : 0);
12007 /* We need one space in the string for each image. */
12008 size_needed = f->n_tool_bar_items;
12010 /* Reuse f->desired_tool_bar_string, if possible. */
12011 if (size < size_needed || NILP (f->desired_tool_bar_string))
12012 fset_desired_tool_bar_string
12013 (f, Fmake_string (make_number (size_needed), make_number (' ')));
12014 else
12016 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
12017 Fremove_text_properties (make_number (0), make_number (size),
12018 props, f->desired_tool_bar_string);
12021 /* Put a `display' property on the string for the images to display,
12022 put a `menu_item' property on tool-bar items with a value that
12023 is the index of the item in F's tool-bar item vector. */
12024 for (i = 0; i < f->n_tool_bar_items; ++i)
12026 #define PROP(IDX) \
12027 AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
12029 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
12030 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
12031 int hmargin, vmargin, relief, idx, end;
12033 /* If image is a vector, choose the image according to the
12034 button state. */
12035 image = PROP (TOOL_BAR_ITEM_IMAGES);
12036 if (VECTORP (image))
12038 if (enabled_p)
12039 idx = (selected_p
12040 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
12041 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
12042 else
12043 idx = (selected_p
12044 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
12045 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
12047 eassert (ASIZE (image) >= idx);
12048 image = AREF (image, idx);
12050 else
12051 idx = -1;
12053 /* Ignore invalid image specifications. */
12054 if (!valid_image_p (image))
12055 continue;
12057 /* Display the tool-bar button pressed, or depressed. */
12058 plist = Fcopy_sequence (XCDR (image));
12060 /* Compute margin and relief to draw. */
12061 relief = (tool_bar_button_relief >= 0
12062 ? tool_bar_button_relief
12063 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
12064 hmargin = vmargin = relief;
12066 if (RANGED_INTEGERP (1, Vtool_bar_button_margin,
12067 INT_MAX - max (hmargin, vmargin)))
12069 hmargin += XFASTINT (Vtool_bar_button_margin);
12070 vmargin += XFASTINT (Vtool_bar_button_margin);
12072 else if (CONSP (Vtool_bar_button_margin))
12074 if (RANGED_INTEGERP (1, XCAR (Vtool_bar_button_margin),
12075 INT_MAX - hmargin))
12076 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
12078 if (RANGED_INTEGERP (1, XCDR (Vtool_bar_button_margin),
12079 INT_MAX - vmargin))
12080 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
12083 if (auto_raise_tool_bar_buttons_p)
12085 /* Add a `:relief' property to the image spec if the item is
12086 selected. */
12087 if (selected_p)
12089 plist = Fplist_put (plist, QCrelief, make_number (-relief));
12090 hmargin -= relief;
12091 vmargin -= relief;
12094 else
12096 /* If image is selected, display it pressed, i.e. with a
12097 negative relief. If it's not selected, display it with a
12098 raised relief. */
12099 plist = Fplist_put (plist, QCrelief,
12100 (selected_p
12101 ? make_number (-relief)
12102 : make_number (relief)));
12103 hmargin -= relief;
12104 vmargin -= relief;
12107 /* Put a margin around the image. */
12108 if (hmargin || vmargin)
12110 if (hmargin == vmargin)
12111 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
12112 else
12113 plist = Fplist_put (plist, QCmargin,
12114 Fcons (make_number (hmargin),
12115 make_number (vmargin)));
12118 /* If button is not enabled, and we don't have special images
12119 for the disabled state, make the image appear disabled by
12120 applying an appropriate algorithm to it. */
12121 if (!enabled_p && idx < 0)
12122 plist = Fplist_put (plist, QCconversion, Qdisabled);
12124 /* Put a `display' text property on the string for the image to
12125 display. Put a `menu-item' property on the string that gives
12126 the start of this item's properties in the tool-bar items
12127 vector. */
12128 image = Fcons (Qimage, plist);
12129 props = list4 (Qdisplay, image,
12130 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
12132 /* Let the last image hide all remaining spaces in the tool bar
12133 string. The string can be longer than needed when we reuse a
12134 previous string. */
12135 if (i + 1 == f->n_tool_bar_items)
12136 end = SCHARS (f->desired_tool_bar_string);
12137 else
12138 end = i + 1;
12139 Fadd_text_properties (make_number (i), make_number (end),
12140 props, f->desired_tool_bar_string);
12141 #undef PROP
12144 UNGCPRO;
12148 /* Display one line of the tool-bar of frame IT->f.
12150 HEIGHT specifies the desired height of the tool-bar line.
12151 If the actual height of the glyph row is less than HEIGHT, the
12152 row's height is increased to HEIGHT, and the icons are centered
12153 vertically in the new height.
12155 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
12156 count a final empty row in case the tool-bar width exactly matches
12157 the window width.
12160 static void
12161 display_tool_bar_line (struct it *it, int height)
12163 struct glyph_row *row = it->glyph_row;
12164 int max_x = it->last_visible_x;
12165 struct glyph *last;
12167 /* Don't extend on a previously drawn tool bar items (Bug#16058). */
12168 clear_glyph_row (row);
12169 row->enabled_p = true;
12170 row->y = it->current_y;
12172 /* Note that this isn't made use of if the face hasn't a box,
12173 so there's no need to check the face here. */
12174 it->start_of_box_run_p = 1;
12176 while (it->current_x < max_x)
12178 int x, n_glyphs_before, i, nglyphs;
12179 struct it it_before;
12181 /* Get the next display element. */
12182 if (!get_next_display_element (it))
12184 /* Don't count empty row if we are counting needed tool-bar lines. */
12185 if (height < 0 && !it->hpos)
12186 return;
12187 break;
12190 /* Produce glyphs. */
12191 n_glyphs_before = row->used[TEXT_AREA];
12192 it_before = *it;
12194 PRODUCE_GLYPHS (it);
12196 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
12197 i = 0;
12198 x = it_before.current_x;
12199 while (i < nglyphs)
12201 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
12203 if (x + glyph->pixel_width > max_x)
12205 /* Glyph doesn't fit on line. Backtrack. */
12206 row->used[TEXT_AREA] = n_glyphs_before;
12207 *it = it_before;
12208 /* If this is the only glyph on this line, it will never fit on the
12209 tool-bar, so skip it. But ensure there is at least one glyph,
12210 so we don't accidentally disable the tool-bar. */
12211 if (n_glyphs_before == 0
12212 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
12213 break;
12214 goto out;
12217 ++it->hpos;
12218 x += glyph->pixel_width;
12219 ++i;
12222 /* Stop at line end. */
12223 if (ITERATOR_AT_END_OF_LINE_P (it))
12224 break;
12226 set_iterator_to_next (it, 1);
12229 out:;
12231 row->displays_text_p = row->used[TEXT_AREA] != 0;
12233 /* Use default face for the border below the tool bar.
12235 FIXME: When auto-resize-tool-bars is grow-only, there is
12236 no additional border below the possibly empty tool-bar lines.
12237 So to make the extra empty lines look "normal", we have to
12238 use the tool-bar face for the border too. */
12239 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
12240 && !EQ (Vauto_resize_tool_bars, Qgrow_only))
12241 it->face_id = DEFAULT_FACE_ID;
12243 extend_face_to_end_of_line (it);
12244 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
12245 last->right_box_line_p = 1;
12246 if (last == row->glyphs[TEXT_AREA])
12247 last->left_box_line_p = 1;
12249 /* Make line the desired height and center it vertically. */
12250 if ((height -= it->max_ascent + it->max_descent) > 0)
12252 /* Don't add more than one line height. */
12253 height %= FRAME_LINE_HEIGHT (it->f);
12254 it->max_ascent += height / 2;
12255 it->max_descent += (height + 1) / 2;
12258 compute_line_metrics (it);
12260 /* If line is empty, make it occupy the rest of the tool-bar. */
12261 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row))
12263 row->height = row->phys_height = it->last_visible_y - row->y;
12264 row->visible_height = row->height;
12265 row->ascent = row->phys_ascent = 0;
12266 row->extra_line_spacing = 0;
12269 row->full_width_p = 1;
12270 row->continued_p = 0;
12271 row->truncated_on_left_p = 0;
12272 row->truncated_on_right_p = 0;
12274 it->current_x = it->hpos = 0;
12275 it->current_y += row->height;
12276 ++it->vpos;
12277 ++it->glyph_row;
12281 /* Value is the number of pixels needed to make all tool-bar items of
12282 frame F visible. The actual number of glyph rows needed is
12283 returned in *N_ROWS if non-NULL. */
12284 static int
12285 tool_bar_height (struct frame *f, int *n_rows, bool pixelwise)
12287 struct window *w = XWINDOW (f->tool_bar_window);
12288 struct it it;
12289 /* tool_bar_height is called from redisplay_tool_bar after building
12290 the desired matrix, so use (unused) mode-line row as temporary row to
12291 avoid destroying the first tool-bar row. */
12292 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
12294 /* Initialize an iterator for iteration over
12295 F->desired_tool_bar_string in the tool-bar window of frame F. */
12296 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
12297 it.first_visible_x = 0;
12298 it.last_visible_x = WINDOW_PIXEL_WIDTH (w);
12299 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
12300 it.paragraph_embedding = L2R;
12302 while (!ITERATOR_AT_END_P (&it))
12304 clear_glyph_row (temp_row);
12305 it.glyph_row = temp_row;
12306 display_tool_bar_line (&it, -1);
12308 clear_glyph_row (temp_row);
12310 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
12311 if (n_rows)
12312 *n_rows = it.vpos > 0 ? it.vpos : -1;
12314 if (pixelwise)
12315 return it.current_y;
12316 else
12317 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
12320 #endif /* !USE_GTK && !HAVE_NS */
12322 DEFUN ("tool-bar-height", Ftool_bar_height, Stool_bar_height,
12323 0, 2, 0,
12324 doc: /* Return the number of lines occupied by the tool bar of FRAME.
12325 If FRAME is nil or omitted, use the selected frame. Optional argument
12326 PIXELWISE non-nil means return the height of the tool bar in pixels. */)
12327 (Lisp_Object frame, Lisp_Object pixelwise)
12329 int height = 0;
12331 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
12332 struct frame *f = decode_any_frame (frame);
12334 if (WINDOWP (f->tool_bar_window)
12335 && WINDOW_PIXEL_HEIGHT (XWINDOW (f->tool_bar_window)) > 0)
12337 update_tool_bar (f, 1);
12338 if (f->n_tool_bar_items)
12340 build_desired_tool_bar_string (f);
12341 height = tool_bar_height (f, NULL, NILP (pixelwise) ? 0 : 1);
12344 #endif
12346 return make_number (height);
12350 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
12351 height should be changed. */
12352 static int
12353 redisplay_tool_bar (struct frame *f)
12355 #if defined (USE_GTK) || defined (HAVE_NS)
12357 if (FRAME_EXTERNAL_TOOL_BAR (f))
12358 update_frame_tool_bar (f);
12359 return 0;
12361 #else /* !USE_GTK && !HAVE_NS */
12363 struct window *w;
12364 struct it it;
12365 struct glyph_row *row;
12367 /* If frame hasn't a tool-bar window or if it is zero-height, don't
12368 do anything. This means you must start with tool-bar-lines
12369 non-zero to get the auto-sizing effect. Or in other words, you
12370 can turn off tool-bars by specifying tool-bar-lines zero. */
12371 if (!WINDOWP (f->tool_bar_window)
12372 || (w = XWINDOW (f->tool_bar_window),
12373 WINDOW_TOTAL_LINES (w) == 0))
12374 return 0;
12376 /* Set up an iterator for the tool-bar window. */
12377 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
12378 it.first_visible_x = 0;
12379 it.last_visible_x = WINDOW_PIXEL_WIDTH (w);
12380 row = it.glyph_row;
12382 /* Build a string that represents the contents of the tool-bar. */
12383 build_desired_tool_bar_string (f);
12384 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
12385 /* FIXME: This should be controlled by a user option. But it
12386 doesn't make sense to have an R2L tool bar if the menu bar cannot
12387 be drawn also R2L, and making the menu bar R2L is tricky due
12388 toolkit-specific code that implements it. If an R2L tool bar is
12389 ever supported, display_tool_bar_line should also be augmented to
12390 call unproduce_glyphs like display_line and display_string
12391 do. */
12392 it.paragraph_embedding = L2R;
12394 if (f->n_tool_bar_rows == 0)
12396 int new_height = tool_bar_height (f, &f->n_tool_bar_rows, 1);
12398 if (new_height != WINDOW_PIXEL_HEIGHT (w))
12400 x_change_tool_bar_height (f, new_height);
12401 /* Always do that now. */
12402 clear_glyph_matrix (w->desired_matrix);
12403 f->fonts_changed = 1;
12404 return 1;
12408 /* Display as many lines as needed to display all tool-bar items. */
12410 if (f->n_tool_bar_rows > 0)
12412 int border, rows, height, extra;
12414 if (TYPE_RANGED_INTEGERP (int, Vtool_bar_border))
12415 border = XINT (Vtool_bar_border);
12416 else if (EQ (Vtool_bar_border, Qinternal_border_width))
12417 border = FRAME_INTERNAL_BORDER_WIDTH (f);
12418 else if (EQ (Vtool_bar_border, Qborder_width))
12419 border = f->border_width;
12420 else
12421 border = 0;
12422 if (border < 0)
12423 border = 0;
12425 rows = f->n_tool_bar_rows;
12426 height = max (1, (it.last_visible_y - border) / rows);
12427 extra = it.last_visible_y - border - height * rows;
12429 while (it.current_y < it.last_visible_y)
12431 int h = 0;
12432 if (extra > 0 && rows-- > 0)
12434 h = (extra + rows - 1) / rows;
12435 extra -= h;
12437 display_tool_bar_line (&it, height + h);
12440 else
12442 while (it.current_y < it.last_visible_y)
12443 display_tool_bar_line (&it, 0);
12446 /* It doesn't make much sense to try scrolling in the tool-bar
12447 window, so don't do it. */
12448 w->desired_matrix->no_scrolling_p = 1;
12449 w->must_be_updated_p = 1;
12451 if (!NILP (Vauto_resize_tool_bars))
12453 int change_height_p = 0;
12455 /* If we couldn't display everything, change the tool-bar's
12456 height if there is room for more. */
12457 if (IT_STRING_CHARPOS (it) < it.end_charpos)
12458 change_height_p = 1;
12460 /* We subtract 1 because display_tool_bar_line advances the
12461 glyph_row pointer before returning to its caller. We want to
12462 examine the last glyph row produced by
12463 display_tool_bar_line. */
12464 row = it.glyph_row - 1;
12466 /* If there are blank lines at the end, except for a partially
12467 visible blank line at the end that is smaller than
12468 FRAME_LINE_HEIGHT, change the tool-bar's height. */
12469 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
12470 && row->height >= FRAME_LINE_HEIGHT (f))
12471 change_height_p = 1;
12473 /* If row displays tool-bar items, but is partially visible,
12474 change the tool-bar's height. */
12475 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12476 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
12477 change_height_p = 1;
12479 /* Resize windows as needed by changing the `tool-bar-lines'
12480 frame parameter. */
12481 if (change_height_p)
12483 int nrows;
12484 int new_height = tool_bar_height (f, &nrows, 1);
12486 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
12487 && !f->minimize_tool_bar_window_p)
12488 ? (new_height > WINDOW_PIXEL_HEIGHT (w))
12489 : (new_height != WINDOW_PIXEL_HEIGHT (w)));
12490 f->minimize_tool_bar_window_p = 0;
12492 if (change_height_p)
12494 x_change_tool_bar_height (f, new_height);
12495 clear_glyph_matrix (w->desired_matrix);
12496 f->n_tool_bar_rows = nrows;
12497 f->fonts_changed = 1;
12499 return 1;
12504 f->minimize_tool_bar_window_p = 0;
12505 return 0;
12507 #endif /* USE_GTK || HAVE_NS */
12510 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
12512 /* Get information about the tool-bar item which is displayed in GLYPH
12513 on frame F. Return in *PROP_IDX the index where tool-bar item
12514 properties start in F->tool_bar_items. Value is zero if
12515 GLYPH doesn't display a tool-bar item. */
12517 static int
12518 tool_bar_item_info (struct frame *f, struct glyph *glyph, int *prop_idx)
12520 Lisp_Object prop;
12521 int success_p;
12522 int charpos;
12524 /* This function can be called asynchronously, which means we must
12525 exclude any possibility that Fget_text_property signals an
12526 error. */
12527 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
12528 charpos = max (0, charpos);
12530 /* Get the text property `menu-item' at pos. The value of that
12531 property is the start index of this item's properties in
12532 F->tool_bar_items. */
12533 prop = Fget_text_property (make_number (charpos),
12534 Qmenu_item, f->current_tool_bar_string);
12535 if (INTEGERP (prop))
12537 *prop_idx = XINT (prop);
12538 success_p = 1;
12540 else
12541 success_p = 0;
12543 return success_p;
12547 /* Get information about the tool-bar item at position X/Y on frame F.
12548 Return in *GLYPH a pointer to the glyph of the tool-bar item in
12549 the current matrix of the tool-bar window of F, or NULL if not
12550 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
12551 item in F->tool_bar_items. Value is
12553 -1 if X/Y is not on a tool-bar item
12554 0 if X/Y is on the same item that was highlighted before.
12555 1 otherwise. */
12557 static int
12558 get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
12559 int *hpos, int *vpos, int *prop_idx)
12561 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12562 struct window *w = XWINDOW (f->tool_bar_window);
12563 int area;
12565 /* Find the glyph under X/Y. */
12566 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
12567 if (*glyph == NULL)
12568 return -1;
12570 /* Get the start of this tool-bar item's properties in
12571 f->tool_bar_items. */
12572 if (!tool_bar_item_info (f, *glyph, prop_idx))
12573 return -1;
12575 /* Is mouse on the highlighted item? */
12576 if (EQ (f->tool_bar_window, hlinfo->mouse_face_window)
12577 && *vpos >= hlinfo->mouse_face_beg_row
12578 && *vpos <= hlinfo->mouse_face_end_row
12579 && (*vpos > hlinfo->mouse_face_beg_row
12580 || *hpos >= hlinfo->mouse_face_beg_col)
12581 && (*vpos < hlinfo->mouse_face_end_row
12582 || *hpos < hlinfo->mouse_face_end_col
12583 || hlinfo->mouse_face_past_end))
12584 return 0;
12586 return 1;
12590 /* EXPORT:
12591 Handle mouse button event on the tool-bar of frame F, at
12592 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
12593 0 for button release. MODIFIERS is event modifiers for button
12594 release. */
12596 void
12597 handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
12598 int modifiers)
12600 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12601 struct window *w = XWINDOW (f->tool_bar_window);
12602 int hpos, vpos, prop_idx;
12603 struct glyph *glyph;
12604 Lisp_Object enabled_p;
12605 int ts;
12607 /* If not on the highlighted tool-bar item, and mouse-highlight is
12608 non-nil, return. This is so we generate the tool-bar button
12609 click only when the mouse button is released on the same item as
12610 where it was pressed. However, when mouse-highlight is disabled,
12611 generate the click when the button is released regardless of the
12612 highlight, since tool-bar items are not highlighted in that
12613 case. */
12614 frame_to_window_pixel_xy (w, &x, &y);
12615 ts = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
12616 if (ts == -1
12617 || (ts != 0 && !NILP (Vmouse_highlight)))
12618 return;
12620 /* When mouse-highlight is off, generate the click for the item
12621 where the button was pressed, disregarding where it was
12622 released. */
12623 if (NILP (Vmouse_highlight) && !down_p)
12624 prop_idx = f->last_tool_bar_item;
12626 /* If item is disabled, do nothing. */
12627 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
12628 if (NILP (enabled_p))
12629 return;
12631 if (down_p)
12633 /* Show item in pressed state. */
12634 if (!NILP (Vmouse_highlight))
12635 show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN);
12636 f->last_tool_bar_item = prop_idx;
12638 else
12640 Lisp_Object key, frame;
12641 struct input_event event;
12642 EVENT_INIT (event);
12644 /* Show item in released state. */
12645 if (!NILP (Vmouse_highlight))
12646 show_mouse_face (hlinfo, DRAW_IMAGE_RAISED);
12648 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
12650 XSETFRAME (frame, f);
12651 event.kind = TOOL_BAR_EVENT;
12652 event.frame_or_window = frame;
12653 event.arg = frame;
12654 kbd_buffer_store_event (&event);
12656 event.kind = TOOL_BAR_EVENT;
12657 event.frame_or_window = frame;
12658 event.arg = key;
12659 event.modifiers = modifiers;
12660 kbd_buffer_store_event (&event);
12661 f->last_tool_bar_item = -1;
12666 /* Possibly highlight a tool-bar item on frame F when mouse moves to
12667 tool-bar window-relative coordinates X/Y. Called from
12668 note_mouse_highlight. */
12670 static void
12671 note_tool_bar_highlight (struct frame *f, int x, int y)
12673 Lisp_Object window = f->tool_bar_window;
12674 struct window *w = XWINDOW (window);
12675 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
12676 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12677 int hpos, vpos;
12678 struct glyph *glyph;
12679 struct glyph_row *row;
12680 int i;
12681 Lisp_Object enabled_p;
12682 int prop_idx;
12683 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
12684 int mouse_down_p, rc;
12686 /* Function note_mouse_highlight is called with negative X/Y
12687 values when mouse moves outside of the frame. */
12688 if (x <= 0 || y <= 0)
12690 clear_mouse_face (hlinfo);
12691 return;
12694 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
12695 if (rc < 0)
12697 /* Not on tool-bar item. */
12698 clear_mouse_face (hlinfo);
12699 return;
12701 else if (rc == 0)
12702 /* On same tool-bar item as before. */
12703 goto set_help_echo;
12705 clear_mouse_face (hlinfo);
12707 /* Mouse is down, but on different tool-bar item? */
12708 mouse_down_p = (x_mouse_grabbed (dpyinfo)
12709 && f == dpyinfo->last_mouse_frame);
12711 if (mouse_down_p && f->last_tool_bar_item != prop_idx)
12712 return;
12714 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
12716 /* If tool-bar item is not enabled, don't highlight it. */
12717 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
12718 if (!NILP (enabled_p) && !NILP (Vmouse_highlight))
12720 /* Compute the x-position of the glyph. In front and past the
12721 image is a space. We include this in the highlighted area. */
12722 row = MATRIX_ROW (w->current_matrix, vpos);
12723 for (i = x = 0; i < hpos; ++i)
12724 x += row->glyphs[TEXT_AREA][i].pixel_width;
12726 /* Record this as the current active region. */
12727 hlinfo->mouse_face_beg_col = hpos;
12728 hlinfo->mouse_face_beg_row = vpos;
12729 hlinfo->mouse_face_beg_x = x;
12730 hlinfo->mouse_face_past_end = 0;
12732 hlinfo->mouse_face_end_col = hpos + 1;
12733 hlinfo->mouse_face_end_row = vpos;
12734 hlinfo->mouse_face_end_x = x + glyph->pixel_width;
12735 hlinfo->mouse_face_window = window;
12736 hlinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
12738 /* Display it as active. */
12739 show_mouse_face (hlinfo, draw);
12742 set_help_echo:
12744 /* Set help_echo_string to a help string to display for this tool-bar item.
12745 XTread_socket does the rest. */
12746 help_echo_object = help_echo_window = Qnil;
12747 help_echo_pos = -1;
12748 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
12749 if (NILP (help_echo_string))
12750 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
12753 #endif /* !USE_GTK && !HAVE_NS */
12755 #endif /* HAVE_WINDOW_SYSTEM */
12759 /************************************************************************
12760 Horizontal scrolling
12761 ************************************************************************/
12763 static int hscroll_window_tree (Lisp_Object);
12764 static int hscroll_windows (Lisp_Object);
12766 /* For all leaf windows in the window tree rooted at WINDOW, set their
12767 hscroll value so that PT is (i) visible in the window, and (ii) so
12768 that it is not within a certain margin at the window's left and
12769 right border. Value is non-zero if any window's hscroll has been
12770 changed. */
12772 static int
12773 hscroll_window_tree (Lisp_Object window)
12775 int hscrolled_p = 0;
12776 int hscroll_relative_p = FLOATP (Vhscroll_step);
12777 int hscroll_step_abs = 0;
12778 double hscroll_step_rel = 0;
12780 if (hscroll_relative_p)
12782 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
12783 if (hscroll_step_rel < 0)
12785 hscroll_relative_p = 0;
12786 hscroll_step_abs = 0;
12789 else if (TYPE_RANGED_INTEGERP (int, Vhscroll_step))
12791 hscroll_step_abs = XINT (Vhscroll_step);
12792 if (hscroll_step_abs < 0)
12793 hscroll_step_abs = 0;
12795 else
12796 hscroll_step_abs = 0;
12798 while (WINDOWP (window))
12800 struct window *w = XWINDOW (window);
12802 if (WINDOWP (w->contents))
12803 hscrolled_p |= hscroll_window_tree (w->contents);
12804 else if (w->cursor.vpos >= 0)
12806 int h_margin;
12807 int text_area_width;
12808 struct glyph_row *cursor_row;
12809 struct glyph_row *bottom_row;
12810 int row_r2l_p;
12812 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->desired_matrix, w);
12813 if (w->cursor.vpos < bottom_row - w->desired_matrix->rows)
12814 cursor_row = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
12815 else
12816 cursor_row = bottom_row - 1;
12818 if (!cursor_row->enabled_p)
12820 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12821 if (w->cursor.vpos < bottom_row - w->current_matrix->rows)
12822 cursor_row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
12823 else
12824 cursor_row = bottom_row - 1;
12826 row_r2l_p = cursor_row->reversed_p;
12828 text_area_width = window_box_width (w, TEXT_AREA);
12830 /* Scroll when cursor is inside this scroll margin. */
12831 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
12833 /* If the position of this window's point has explicitly
12834 changed, no more suspend auto hscrolling. */
12835 if (NILP (Fequal (Fwindow_point (window), Fwindow_old_point (window))))
12836 w->suspend_auto_hscroll = 0;
12838 /* Remember window point. */
12839 Fset_marker (w->old_pointm,
12840 ((w == XWINDOW (selected_window))
12841 ? make_number (BUF_PT (XBUFFER (w->contents)))
12842 : Fmarker_position (w->pointm)),
12843 w->contents);
12845 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->contents))
12846 && w->suspend_auto_hscroll == 0
12847 /* In some pathological cases, like restoring a window
12848 configuration into a frame that is much smaller than
12849 the one from which the configuration was saved, we
12850 get glyph rows whose start and end have zero buffer
12851 positions, which we cannot handle below. Just skip
12852 such windows. */
12853 && CHARPOS (cursor_row->start.pos) >= BUF_BEG (w->contents)
12854 /* For left-to-right rows, hscroll when cursor is either
12855 (i) inside the right hscroll margin, or (ii) if it is
12856 inside the left margin and the window is already
12857 hscrolled. */
12858 && ((!row_r2l_p
12859 && ((w->hscroll && w->cursor.x <= h_margin)
12860 || (cursor_row->enabled_p
12861 && cursor_row->truncated_on_right_p
12862 && (w->cursor.x >= text_area_width - h_margin))))
12863 /* For right-to-left rows, the logic is similar,
12864 except that rules for scrolling to left and right
12865 are reversed. E.g., if cursor.x <= h_margin, we
12866 need to hscroll "to the right" unconditionally,
12867 and that will scroll the screen to the left so as
12868 to reveal the next portion of the row. */
12869 || (row_r2l_p
12870 && ((cursor_row->enabled_p
12871 /* FIXME: It is confusing to set the
12872 truncated_on_right_p flag when R2L rows
12873 are actually truncated on the left. */
12874 && cursor_row->truncated_on_right_p
12875 && w->cursor.x <= h_margin)
12876 || (w->hscroll
12877 && (w->cursor.x >= text_area_width - h_margin))))))
12879 struct it it;
12880 ptrdiff_t hscroll;
12881 struct buffer *saved_current_buffer;
12882 ptrdiff_t pt;
12883 int wanted_x;
12885 /* Find point in a display of infinite width. */
12886 saved_current_buffer = current_buffer;
12887 current_buffer = XBUFFER (w->contents);
12889 if (w == XWINDOW (selected_window))
12890 pt = PT;
12891 else
12892 pt = clip_to_bounds (BEGV, marker_position (w->pointm), ZV);
12894 /* Move iterator to pt starting at cursor_row->start in
12895 a line with infinite width. */
12896 init_to_row_start (&it, w, cursor_row);
12897 it.last_visible_x = INFINITY;
12898 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
12899 current_buffer = saved_current_buffer;
12901 /* Position cursor in window. */
12902 if (!hscroll_relative_p && hscroll_step_abs == 0)
12903 hscroll = max (0, (it.current_x
12904 - (ITERATOR_AT_END_OF_LINE_P (&it)
12905 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
12906 : (text_area_width / 2))))
12907 / FRAME_COLUMN_WIDTH (it.f);
12908 else if ((!row_r2l_p
12909 && w->cursor.x >= text_area_width - h_margin)
12910 || (row_r2l_p && w->cursor.x <= h_margin))
12912 if (hscroll_relative_p)
12913 wanted_x = text_area_width * (1 - hscroll_step_rel)
12914 - h_margin;
12915 else
12916 wanted_x = text_area_width
12917 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
12918 - h_margin;
12919 hscroll
12920 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
12922 else
12924 if (hscroll_relative_p)
12925 wanted_x = text_area_width * hscroll_step_rel
12926 + h_margin;
12927 else
12928 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
12929 + h_margin;
12930 hscroll
12931 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
12933 hscroll = max (hscroll, w->min_hscroll);
12935 /* Don't prevent redisplay optimizations if hscroll
12936 hasn't changed, as it will unnecessarily slow down
12937 redisplay. */
12938 if (w->hscroll != hscroll)
12940 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
12941 w->hscroll = hscroll;
12942 hscrolled_p = 1;
12947 window = w->next;
12950 /* Value is non-zero if hscroll of any leaf window has been changed. */
12951 return hscrolled_p;
12955 /* Set hscroll so that cursor is visible and not inside horizontal
12956 scroll margins for all windows in the tree rooted at WINDOW. See
12957 also hscroll_window_tree above. Value is non-zero if any window's
12958 hscroll has been changed. If it has, desired matrices on the frame
12959 of WINDOW are cleared. */
12961 static int
12962 hscroll_windows (Lisp_Object window)
12964 int hscrolled_p = hscroll_window_tree (window);
12965 if (hscrolled_p)
12966 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
12967 return hscrolled_p;
12972 /************************************************************************
12973 Redisplay
12974 ************************************************************************/
12976 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
12977 to a non-zero value. This is sometimes handy to have in a debugger
12978 session. */
12980 #ifdef GLYPH_DEBUG
12982 /* First and last unchanged row for try_window_id. */
12984 static int debug_first_unchanged_at_end_vpos;
12985 static int debug_last_unchanged_at_beg_vpos;
12987 /* Delta vpos and y. */
12989 static int debug_dvpos, debug_dy;
12991 /* Delta in characters and bytes for try_window_id. */
12993 static ptrdiff_t debug_delta, debug_delta_bytes;
12995 /* Values of window_end_pos and window_end_vpos at the end of
12996 try_window_id. */
12998 static ptrdiff_t debug_end_vpos;
13000 /* Append a string to W->desired_matrix->method. FMT is a printf
13001 format string. If trace_redisplay_p is true also printf the
13002 resulting string to stderr. */
13004 static void debug_method_add (struct window *, char const *, ...)
13005 ATTRIBUTE_FORMAT_PRINTF (2, 3);
13007 static void
13008 debug_method_add (struct window *w, char const *fmt, ...)
13010 void *ptr = w;
13011 char *method = w->desired_matrix->method;
13012 int len = strlen (method);
13013 int size = sizeof w->desired_matrix->method;
13014 int remaining = size - len - 1;
13015 va_list ap;
13017 if (len && remaining)
13019 method[len] = '|';
13020 --remaining, ++len;
13023 va_start (ap, fmt);
13024 vsnprintf (method + len, remaining + 1, fmt, ap);
13025 va_end (ap);
13027 if (trace_redisplay_p)
13028 fprintf (stderr, "%p (%s): %s\n",
13029 ptr,
13030 ((BUFFERP (w->contents)
13031 && STRINGP (BVAR (XBUFFER (w->contents), name)))
13032 ? SSDATA (BVAR (XBUFFER (w->contents), name))
13033 : "no buffer"),
13034 method + len);
13037 #endif /* GLYPH_DEBUG */
13040 /* Value is non-zero if all changes in window W, which displays
13041 current_buffer, are in the text between START and END. START is a
13042 buffer position, END is given as a distance from Z. Used in
13043 redisplay_internal for display optimization. */
13045 static int
13046 text_outside_line_unchanged_p (struct window *w,
13047 ptrdiff_t start, ptrdiff_t end)
13049 int unchanged_p = 1;
13051 /* If text or overlays have changed, see where. */
13052 if (window_outdated (w))
13054 /* Gap in the line? */
13055 if (GPT < start || Z - GPT < end)
13056 unchanged_p = 0;
13058 /* Changes start in front of the line, or end after it? */
13059 if (unchanged_p
13060 && (BEG_UNCHANGED < start - 1
13061 || END_UNCHANGED < end))
13062 unchanged_p = 0;
13064 /* If selective display, can't optimize if changes start at the
13065 beginning of the line. */
13066 if (unchanged_p
13067 && INTEGERP (BVAR (current_buffer, selective_display))
13068 && XINT (BVAR (current_buffer, selective_display)) > 0
13069 && (BEG_UNCHANGED < start || GPT <= start))
13070 unchanged_p = 0;
13072 /* If there are overlays at the start or end of the line, these
13073 may have overlay strings with newlines in them. A change at
13074 START, for instance, may actually concern the display of such
13075 overlay strings as well, and they are displayed on different
13076 lines. So, quickly rule out this case. (For the future, it
13077 might be desirable to implement something more telling than
13078 just BEG/END_UNCHANGED.) */
13079 if (unchanged_p)
13081 if (BEG + BEG_UNCHANGED == start
13082 && overlay_touches_p (start))
13083 unchanged_p = 0;
13084 if (END_UNCHANGED == end
13085 && overlay_touches_p (Z - end))
13086 unchanged_p = 0;
13089 /* Under bidi reordering, adding or deleting a character in the
13090 beginning of a paragraph, before the first strong directional
13091 character, can change the base direction of the paragraph (unless
13092 the buffer specifies a fixed paragraph direction), which will
13093 require to redisplay the whole paragraph. It might be worthwhile
13094 to find the paragraph limits and widen the range of redisplayed
13095 lines to that, but for now just give up this optimization. */
13096 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
13097 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
13098 unchanged_p = 0;
13101 return unchanged_p;
13105 /* Do a frame update, taking possible shortcuts into account. This is
13106 the main external entry point for redisplay.
13108 If the last redisplay displayed an echo area message and that message
13109 is no longer requested, we clear the echo area or bring back the
13110 mini-buffer if that is in use. */
13112 void
13113 redisplay (void)
13115 redisplay_internal ();
13119 static Lisp_Object
13120 overlay_arrow_string_or_property (Lisp_Object var)
13122 Lisp_Object val;
13124 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
13125 return val;
13127 return Voverlay_arrow_string;
13130 /* Return 1 if there are any overlay-arrows in current_buffer. */
13131 static int
13132 overlay_arrow_in_current_buffer_p (void)
13134 Lisp_Object vlist;
13136 for (vlist = Voverlay_arrow_variable_list;
13137 CONSP (vlist);
13138 vlist = XCDR (vlist))
13140 Lisp_Object var = XCAR (vlist);
13141 Lisp_Object val;
13143 if (!SYMBOLP (var))
13144 continue;
13145 val = find_symbol_value (var);
13146 if (MARKERP (val)
13147 && current_buffer == XMARKER (val)->buffer)
13148 return 1;
13150 return 0;
13154 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
13155 has changed. */
13157 static int
13158 overlay_arrows_changed_p (void)
13160 Lisp_Object vlist;
13162 for (vlist = Voverlay_arrow_variable_list;
13163 CONSP (vlist);
13164 vlist = XCDR (vlist))
13166 Lisp_Object var = XCAR (vlist);
13167 Lisp_Object val, pstr;
13169 if (!SYMBOLP (var))
13170 continue;
13171 val = find_symbol_value (var);
13172 if (!MARKERP (val))
13173 continue;
13174 if (! EQ (COERCE_MARKER (val),
13175 Fget (var, Qlast_arrow_position))
13176 || ! (pstr = overlay_arrow_string_or_property (var),
13177 EQ (pstr, Fget (var, Qlast_arrow_string))))
13178 return 1;
13180 return 0;
13183 /* Mark overlay arrows to be updated on next redisplay. */
13185 static void
13186 update_overlay_arrows (int up_to_date)
13188 Lisp_Object vlist;
13190 for (vlist = Voverlay_arrow_variable_list;
13191 CONSP (vlist);
13192 vlist = XCDR (vlist))
13194 Lisp_Object var = XCAR (vlist);
13196 if (!SYMBOLP (var))
13197 continue;
13199 if (up_to_date > 0)
13201 Lisp_Object val = find_symbol_value (var);
13202 Fput (var, Qlast_arrow_position,
13203 COERCE_MARKER (val));
13204 Fput (var, Qlast_arrow_string,
13205 overlay_arrow_string_or_property (var));
13207 else if (up_to_date < 0
13208 || !NILP (Fget (var, Qlast_arrow_position)))
13210 Fput (var, Qlast_arrow_position, Qt);
13211 Fput (var, Qlast_arrow_string, Qt);
13217 /* Return overlay arrow string to display at row.
13218 Return integer (bitmap number) for arrow bitmap in left fringe.
13219 Return nil if no overlay arrow. */
13221 static Lisp_Object
13222 overlay_arrow_at_row (struct it *it, struct glyph_row *row)
13224 Lisp_Object vlist;
13226 for (vlist = Voverlay_arrow_variable_list;
13227 CONSP (vlist);
13228 vlist = XCDR (vlist))
13230 Lisp_Object var = XCAR (vlist);
13231 Lisp_Object val;
13233 if (!SYMBOLP (var))
13234 continue;
13236 val = find_symbol_value (var);
13238 if (MARKERP (val)
13239 && current_buffer == XMARKER (val)->buffer
13240 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
13242 if (FRAME_WINDOW_P (it->f)
13243 /* FIXME: if ROW->reversed_p is set, this should test
13244 the right fringe, not the left one. */
13245 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
13247 #ifdef HAVE_WINDOW_SYSTEM
13248 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
13250 int fringe_bitmap;
13251 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
13252 return make_number (fringe_bitmap);
13254 #endif
13255 return make_number (-1); /* Use default arrow bitmap. */
13257 return overlay_arrow_string_or_property (var);
13261 return Qnil;
13264 /* Return 1 if point moved out of or into a composition. Otherwise
13265 return 0. PREV_BUF and PREV_PT are the last point buffer and
13266 position. BUF and PT are the current point buffer and position. */
13268 static int
13269 check_point_in_composition (struct buffer *prev_buf, ptrdiff_t prev_pt,
13270 struct buffer *buf, ptrdiff_t pt)
13272 ptrdiff_t start, end;
13273 Lisp_Object prop;
13274 Lisp_Object buffer;
13276 XSETBUFFER (buffer, buf);
13277 /* Check a composition at the last point if point moved within the
13278 same buffer. */
13279 if (prev_buf == buf)
13281 if (prev_pt == pt)
13282 /* Point didn't move. */
13283 return 0;
13285 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
13286 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
13287 && composition_valid_p (start, end, prop)
13288 && start < prev_pt && end > prev_pt)
13289 /* The last point was within the composition. Return 1 iff
13290 point moved out of the composition. */
13291 return (pt <= start || pt >= end);
13294 /* Check a composition at the current point. */
13295 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
13296 && find_composition (pt, -1, &start, &end, &prop, buffer)
13297 && composition_valid_p (start, end, prop)
13298 && start < pt && end > pt);
13301 /* Reconsider the clip changes of buffer which is displayed in W. */
13303 static void
13304 reconsider_clip_changes (struct window *w)
13306 struct buffer *b = XBUFFER (w->contents);
13308 if (b->clip_changed
13309 && w->window_end_valid
13310 && w->current_matrix->buffer == b
13311 && w->current_matrix->zv == BUF_ZV (b)
13312 && w->current_matrix->begv == BUF_BEGV (b))
13313 b->clip_changed = 0;
13315 /* If display wasn't paused, and W is not a tool bar window, see if
13316 point has been moved into or out of a composition. In that case,
13317 we set b->clip_changed to 1 to force updating the screen. If
13318 b->clip_changed has already been set to 1, we can skip this
13319 check. */
13320 if (!b->clip_changed && w->window_end_valid)
13322 ptrdiff_t pt = (w == XWINDOW (selected_window)
13323 ? PT : marker_position (w->pointm));
13325 if ((w->current_matrix->buffer != b || pt != w->last_point)
13326 && check_point_in_composition (w->current_matrix->buffer,
13327 w->last_point, b, pt))
13328 b->clip_changed = 1;
13332 static void
13333 propagate_buffer_redisplay (void)
13334 { /* Resetting b->text->redisplay is problematic!
13335 We can't just reset it in the case that some window that displays
13336 it has not been redisplayed; and such a window can stay
13337 unredisplayed for a long time if it's currently invisible.
13338 But we do want to reset it at the end of redisplay otherwise
13339 its displayed windows will keep being redisplayed over and over
13340 again.
13341 So we copy all b->text->redisplay flags up to their windows here,
13342 such that mark_window_display_accurate can safely reset
13343 b->text->redisplay. */
13344 Lisp_Object ws = window_list ();
13345 for (; CONSP (ws); ws = XCDR (ws))
13347 struct window *thisw = XWINDOW (XCAR (ws));
13348 struct buffer *thisb = XBUFFER (thisw->contents);
13349 if (thisb->text->redisplay)
13350 thisw->redisplay = true;
13354 #define STOP_POLLING \
13355 do { if (! polling_stopped_here) stop_polling (); \
13356 polling_stopped_here = 1; } while (0)
13358 #define RESUME_POLLING \
13359 do { if (polling_stopped_here) start_polling (); \
13360 polling_stopped_here = 0; } while (0)
13363 /* Perhaps in the future avoid recentering windows if it
13364 is not necessary; currently that causes some problems. */
13366 static void
13367 redisplay_internal (void)
13369 struct window *w = XWINDOW (selected_window);
13370 struct window *sw;
13371 struct frame *fr;
13372 int pending;
13373 bool must_finish = 0, match_p;
13374 struct text_pos tlbufpos, tlendpos;
13375 int number_of_visible_frames;
13376 ptrdiff_t count;
13377 struct frame *sf;
13378 int polling_stopped_here = 0;
13379 Lisp_Object tail, frame;
13381 /* True means redisplay has to consider all windows on all
13382 frames. False, only selected_window is considered. */
13383 bool consider_all_windows_p;
13385 /* True means redisplay has to redisplay the miniwindow. */
13386 bool update_miniwindow_p = false;
13388 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
13390 /* No redisplay if running in batch mode or frame is not yet fully
13391 initialized, or redisplay is explicitly turned off by setting
13392 Vinhibit_redisplay. */
13393 if (FRAME_INITIAL_P (SELECTED_FRAME ())
13394 || !NILP (Vinhibit_redisplay))
13395 return;
13397 /* Don't examine these until after testing Vinhibit_redisplay.
13398 When Emacs is shutting down, perhaps because its connection to
13399 X has dropped, we should not look at them at all. */
13400 fr = XFRAME (w->frame);
13401 sf = SELECTED_FRAME ();
13403 if (!fr->glyphs_initialized_p)
13404 return;
13406 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
13407 if (popup_activated ())
13408 return;
13409 #endif
13411 /* I don't think this happens but let's be paranoid. */
13412 if (redisplaying_p)
13413 return;
13415 /* Record a function that clears redisplaying_p
13416 when we leave this function. */
13417 count = SPECPDL_INDEX ();
13418 record_unwind_protect_void (unwind_redisplay);
13419 redisplaying_p = 1;
13420 specbind (Qinhibit_free_realized_faces, Qnil);
13422 /* Record this function, so it appears on the profiler's backtraces. */
13423 record_in_backtrace (Qredisplay_internal, &Qnil, 0);
13425 FOR_EACH_FRAME (tail, frame)
13426 XFRAME (frame)->already_hscrolled_p = 0;
13428 retry:
13429 /* Remember the currently selected window. */
13430 sw = w;
13432 pending = 0;
13433 last_escape_glyph_frame = NULL;
13434 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
13435 last_glyphless_glyph_frame = NULL;
13436 last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
13438 /* If face_change_count is non-zero, init_iterator will free all
13439 realized faces, which includes the faces referenced from current
13440 matrices. So, we can't reuse current matrices in this case. */
13441 if (face_change_count)
13442 windows_or_buffers_changed = 47;
13444 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
13445 && FRAME_TTY (sf)->previous_frame != sf)
13447 /* Since frames on a single ASCII terminal share the same
13448 display area, displaying a different frame means redisplay
13449 the whole thing. */
13450 SET_FRAME_GARBAGED (sf);
13451 #ifndef DOS_NT
13452 set_tty_color_mode (FRAME_TTY (sf), sf);
13453 #endif
13454 FRAME_TTY (sf)->previous_frame = sf;
13457 /* Set the visible flags for all frames. Do this before checking for
13458 resized or garbaged frames; they want to know if their frames are
13459 visible. See the comment in frame.h for FRAME_SAMPLE_VISIBILITY. */
13460 number_of_visible_frames = 0;
13462 FOR_EACH_FRAME (tail, frame)
13464 struct frame *f = XFRAME (frame);
13466 if (FRAME_VISIBLE_P (f))
13468 ++number_of_visible_frames;
13469 /* Adjust matrices for visible frames only. */
13470 if (f->fonts_changed)
13472 adjust_frame_glyphs (f);
13473 f->fonts_changed = 0;
13475 /* If cursor type has been changed on the frame
13476 other than selected, consider all frames. */
13477 if (f != sf && f->cursor_type_changed)
13478 update_mode_lines = 31;
13480 clear_desired_matrices (f);
13483 /* Notice any pending interrupt request to change frame size. */
13484 do_pending_window_change (1);
13486 /* do_pending_window_change could change the selected_window due to
13487 frame resizing which makes the selected window too small. */
13488 if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw)
13489 sw = w;
13491 /* Clear frames marked as garbaged. */
13492 clear_garbaged_frames ();
13494 /* Build menubar and tool-bar items. */
13495 if (NILP (Vmemory_full))
13496 prepare_menu_bars ();
13498 reconsider_clip_changes (w);
13500 /* In most cases selected window displays current buffer. */
13501 match_p = XBUFFER (w->contents) == current_buffer;
13502 if (match_p)
13504 /* Detect case that we need to write or remove a star in the mode line. */
13505 if ((SAVE_MODIFF < MODIFF) != w->last_had_star)
13506 w->update_mode_line = 1;
13508 if (mode_line_update_needed (w))
13509 w->update_mode_line = 1;
13512 /* Normally the message* functions will have already displayed and
13513 updated the echo area, but the frame may have been trashed, or
13514 the update may have been preempted, so display the echo area
13515 again here. Checking message_cleared_p captures the case that
13516 the echo area should be cleared. */
13517 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
13518 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
13519 || (message_cleared_p
13520 && minibuf_level == 0
13521 /* If the mini-window is currently selected, this means the
13522 echo-area doesn't show through. */
13523 && !MINI_WINDOW_P (XWINDOW (selected_window))))
13525 int window_height_changed_p = echo_area_display (0);
13527 if (message_cleared_p)
13528 update_miniwindow_p = true;
13530 must_finish = 1;
13532 /* If we don't display the current message, don't clear the
13533 message_cleared_p flag, because, if we did, we wouldn't clear
13534 the echo area in the next redisplay which doesn't preserve
13535 the echo area. */
13536 if (!display_last_displayed_message_p)
13537 message_cleared_p = 0;
13539 if (window_height_changed_p)
13541 windows_or_buffers_changed = 50;
13543 /* If window configuration was changed, frames may have been
13544 marked garbaged. Clear them or we will experience
13545 surprises wrt scrolling. */
13546 clear_garbaged_frames ();
13549 else if (EQ (selected_window, minibuf_window)
13550 && (current_buffer->clip_changed || window_outdated (w))
13551 && resize_mini_window (w, 0))
13553 /* Resized active mini-window to fit the size of what it is
13554 showing if its contents might have changed. */
13555 must_finish = 1;
13557 /* If window configuration was changed, frames may have been
13558 marked garbaged. Clear them or we will experience
13559 surprises wrt scrolling. */
13560 clear_garbaged_frames ();
13563 if (windows_or_buffers_changed && !update_mode_lines)
13564 /* Code that sets windows_or_buffers_changed doesn't distinguish whether
13565 only the windows's contents needs to be refreshed, or whether the
13566 mode-lines also need a refresh. */
13567 update_mode_lines = (windows_or_buffers_changed == REDISPLAY_SOME
13568 ? REDISPLAY_SOME : 32);
13570 /* If specs for an arrow have changed, do thorough redisplay
13571 to ensure we remove any arrow that should no longer exist. */
13572 if (overlay_arrows_changed_p ())
13573 /* Apparently, this is the only case where we update other windows,
13574 without updating other mode-lines. */
13575 windows_or_buffers_changed = 49;
13577 consider_all_windows_p = (update_mode_lines
13578 || windows_or_buffers_changed);
13580 #define AINC(a,i) \
13581 if (VECTORP (a) && i >= 0 && i < ASIZE (a) && INTEGERP (AREF (a, i))) \
13582 ASET (a, i, make_number (1 + XINT (AREF (a, i))))
13584 AINC (Vredisplay__all_windows_cause, windows_or_buffers_changed);
13585 AINC (Vredisplay__mode_lines_cause, update_mode_lines);
13587 /* Optimize the case that only the line containing the cursor in the
13588 selected window has changed. Variables starting with this_ are
13589 set in display_line and record information about the line
13590 containing the cursor. */
13591 tlbufpos = this_line_start_pos;
13592 tlendpos = this_line_end_pos;
13593 if (!consider_all_windows_p
13594 && CHARPOS (tlbufpos) > 0
13595 && !w->update_mode_line
13596 && !current_buffer->clip_changed
13597 && !current_buffer->prevent_redisplay_optimizations_p
13598 && FRAME_VISIBLE_P (XFRAME (w->frame))
13599 && !FRAME_OBSCURED_P (XFRAME (w->frame))
13600 && !XFRAME (w->frame)->cursor_type_changed
13601 /* Make sure recorded data applies to current buffer, etc. */
13602 && this_line_buffer == current_buffer
13603 && match_p
13604 && !w->force_start
13605 && !w->optional_new_start
13606 /* Point must be on the line that we have info recorded about. */
13607 && PT >= CHARPOS (tlbufpos)
13608 && PT <= Z - CHARPOS (tlendpos)
13609 /* All text outside that line, including its final newline,
13610 must be unchanged. */
13611 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
13612 CHARPOS (tlendpos)))
13614 if (CHARPOS (tlbufpos) > BEGV
13615 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
13616 && (CHARPOS (tlbufpos) == ZV
13617 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
13618 /* Former continuation line has disappeared by becoming empty. */
13619 goto cancel;
13620 else if (window_outdated (w) || MINI_WINDOW_P (w))
13622 /* We have to handle the case of continuation around a
13623 wide-column character (see the comment in indent.c around
13624 line 1340).
13626 For instance, in the following case:
13628 -------- Insert --------
13629 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
13630 J_I_ ==> J_I_ `^^' are cursors.
13631 ^^ ^^
13632 -------- --------
13634 As we have to redraw the line above, we cannot use this
13635 optimization. */
13637 struct it it;
13638 int line_height_before = this_line_pixel_height;
13640 /* Note that start_display will handle the case that the
13641 line starting at tlbufpos is a continuation line. */
13642 start_display (&it, w, tlbufpos);
13644 /* Implementation note: It this still necessary? */
13645 if (it.current_x != this_line_start_x)
13646 goto cancel;
13648 TRACE ((stderr, "trying display optimization 1\n"));
13649 w->cursor.vpos = -1;
13650 overlay_arrow_seen = 0;
13651 it.vpos = this_line_vpos;
13652 it.current_y = this_line_y;
13653 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
13654 display_line (&it);
13656 /* If line contains point, is not continued,
13657 and ends at same distance from eob as before, we win. */
13658 if (w->cursor.vpos >= 0
13659 /* Line is not continued, otherwise this_line_start_pos
13660 would have been set to 0 in display_line. */
13661 && CHARPOS (this_line_start_pos)
13662 /* Line ends as before. */
13663 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
13664 /* Line has same height as before. Otherwise other lines
13665 would have to be shifted up or down. */
13666 && this_line_pixel_height == line_height_before)
13668 /* If this is not the window's last line, we must adjust
13669 the charstarts of the lines below. */
13670 if (it.current_y < it.last_visible_y)
13672 struct glyph_row *row
13673 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
13674 ptrdiff_t delta, delta_bytes;
13676 /* We used to distinguish between two cases here,
13677 conditioned by Z - CHARPOS (tlendpos) == ZV, for
13678 when the line ends in a newline or the end of the
13679 buffer's accessible portion. But both cases did
13680 the same, so they were collapsed. */
13681 delta = (Z
13682 - CHARPOS (tlendpos)
13683 - MATRIX_ROW_START_CHARPOS (row));
13684 delta_bytes = (Z_BYTE
13685 - BYTEPOS (tlendpos)
13686 - MATRIX_ROW_START_BYTEPOS (row));
13688 increment_matrix_positions (w->current_matrix,
13689 this_line_vpos + 1,
13690 w->current_matrix->nrows,
13691 delta, delta_bytes);
13694 /* If this row displays text now but previously didn't,
13695 or vice versa, w->window_end_vpos may have to be
13696 adjusted. */
13697 if (MATRIX_ROW_DISPLAYS_TEXT_P (it.glyph_row - 1))
13699 if (w->window_end_vpos < this_line_vpos)
13700 w->window_end_vpos = this_line_vpos;
13702 else if (w->window_end_vpos == this_line_vpos
13703 && this_line_vpos > 0)
13704 w->window_end_vpos = this_line_vpos - 1;
13705 w->window_end_valid = 0;
13707 /* Update hint: No need to try to scroll in update_window. */
13708 w->desired_matrix->no_scrolling_p = 1;
13710 #ifdef GLYPH_DEBUG
13711 *w->desired_matrix->method = 0;
13712 debug_method_add (w, "optimization 1");
13713 #endif
13714 #ifdef HAVE_WINDOW_SYSTEM
13715 update_window_fringes (w, 0);
13716 #endif
13717 goto update;
13719 else
13720 goto cancel;
13722 else if (/* Cursor position hasn't changed. */
13723 PT == w->last_point
13724 /* Make sure the cursor was last displayed
13725 in this window. Otherwise we have to reposition it. */
13727 /* PXW: Must be converted to pixels, probably. */
13728 && 0 <= w->cursor.vpos
13729 && w->cursor.vpos < WINDOW_TOTAL_LINES (w))
13731 if (!must_finish)
13733 do_pending_window_change (1);
13734 /* If selected_window changed, redisplay again. */
13735 if (WINDOWP (selected_window)
13736 && (w = XWINDOW (selected_window)) != sw)
13737 goto retry;
13739 /* We used to always goto end_of_redisplay here, but this
13740 isn't enough if we have a blinking cursor. */
13741 if (w->cursor_off_p == w->last_cursor_off_p)
13742 goto end_of_redisplay;
13744 goto update;
13746 /* If highlighting the region, or if the cursor is in the echo area,
13747 then we can't just move the cursor. */
13748 else if (NILP (Vshow_trailing_whitespace)
13749 && !cursor_in_echo_area)
13751 struct it it;
13752 struct glyph_row *row;
13754 /* Skip from tlbufpos to PT and see where it is. Note that
13755 PT may be in invisible text. If so, we will end at the
13756 next visible position. */
13757 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
13758 NULL, DEFAULT_FACE_ID);
13759 it.current_x = this_line_start_x;
13760 it.current_y = this_line_y;
13761 it.vpos = this_line_vpos;
13763 /* The call to move_it_to stops in front of PT, but
13764 moves over before-strings. */
13765 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
13767 if (it.vpos == this_line_vpos
13768 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
13769 row->enabled_p))
13771 eassert (this_line_vpos == it.vpos);
13772 eassert (this_line_y == it.current_y);
13773 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13774 #ifdef GLYPH_DEBUG
13775 *w->desired_matrix->method = 0;
13776 debug_method_add (w, "optimization 3");
13777 #endif
13778 goto update;
13780 else
13781 goto cancel;
13784 cancel:
13785 /* Text changed drastically or point moved off of line. */
13786 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, false);
13789 CHARPOS (this_line_start_pos) = 0;
13790 ++clear_face_cache_count;
13791 #ifdef HAVE_WINDOW_SYSTEM
13792 ++clear_image_cache_count;
13793 #endif
13795 /* Build desired matrices, and update the display. If
13796 consider_all_windows_p is non-zero, do it for all windows on all
13797 frames. Otherwise do it for selected_window, only. */
13799 if (consider_all_windows_p)
13801 FOR_EACH_FRAME (tail, frame)
13802 XFRAME (frame)->updated_p = 0;
13804 propagate_buffer_redisplay ();
13806 FOR_EACH_FRAME (tail, frame)
13808 struct frame *f = XFRAME (frame);
13810 /* We don't have to do anything for unselected terminal
13811 frames. */
13812 if ((FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
13813 && !EQ (FRAME_TTY (f)->top_frame, frame))
13814 continue;
13816 retry_frame:
13818 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
13820 bool gcscrollbars
13821 /* Only GC scrollbars when we redisplay the whole frame. */
13822 = f->redisplay || !REDISPLAY_SOME_P ();
13823 /* Mark all the scroll bars to be removed; we'll redeem
13824 the ones we want when we redisplay their windows. */
13825 if (gcscrollbars && FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
13826 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
13828 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
13829 redisplay_windows (FRAME_ROOT_WINDOW (f));
13830 /* Remember that the invisible frames need to be redisplayed next
13831 time they're visible. */
13832 else if (!REDISPLAY_SOME_P ())
13833 f->redisplay = true;
13835 /* The X error handler may have deleted that frame. */
13836 if (!FRAME_LIVE_P (f))
13837 continue;
13839 /* Any scroll bars which redisplay_windows should have
13840 nuked should now go away. */
13841 if (gcscrollbars && FRAME_TERMINAL (f)->judge_scroll_bars_hook)
13842 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
13844 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
13846 /* If fonts changed on visible frame, display again. */
13847 if (f->fonts_changed)
13849 adjust_frame_glyphs (f);
13850 f->fonts_changed = 0;
13851 goto retry_frame;
13854 /* See if we have to hscroll. */
13855 if (!f->already_hscrolled_p)
13857 f->already_hscrolled_p = 1;
13858 if (hscroll_windows (f->root_window))
13859 goto retry_frame;
13862 /* Prevent various kinds of signals during display
13863 update. stdio is not robust about handling
13864 signals, which can cause an apparent I/O error. */
13865 if (interrupt_input)
13866 unrequest_sigio ();
13867 STOP_POLLING;
13869 pending |= update_frame (f, 0, 0);
13870 f->cursor_type_changed = 0;
13871 f->updated_p = 1;
13876 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
13878 if (!pending)
13880 /* Do the mark_window_display_accurate after all windows have
13881 been redisplayed because this call resets flags in buffers
13882 which are needed for proper redisplay. */
13883 FOR_EACH_FRAME (tail, frame)
13885 struct frame *f = XFRAME (frame);
13886 if (f->updated_p)
13888 f->redisplay = false;
13889 mark_window_display_accurate (f->root_window, 1);
13890 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
13891 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
13896 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
13898 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
13899 struct frame *mini_frame;
13901 displayed_buffer = XBUFFER (XWINDOW (selected_window)->contents);
13902 /* Use list_of_error, not Qerror, so that
13903 we catch only errors and don't run the debugger. */
13904 internal_condition_case_1 (redisplay_window_1, selected_window,
13905 list_of_error,
13906 redisplay_window_error);
13907 if (update_miniwindow_p)
13908 internal_condition_case_1 (redisplay_window_1, mini_window,
13909 list_of_error,
13910 redisplay_window_error);
13912 /* Compare desired and current matrices, perform output. */
13914 update:
13915 /* If fonts changed, display again. */
13916 if (sf->fonts_changed)
13917 goto retry;
13919 /* Prevent various kinds of signals during display update.
13920 stdio is not robust about handling signals,
13921 which can cause an apparent I/O error. */
13922 if (interrupt_input)
13923 unrequest_sigio ();
13924 STOP_POLLING;
13926 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
13928 if (hscroll_windows (selected_window))
13929 goto retry;
13931 XWINDOW (selected_window)->must_be_updated_p = true;
13932 pending = update_frame (sf, 0, 0);
13933 sf->cursor_type_changed = 0;
13936 /* We may have called echo_area_display at the top of this
13937 function. If the echo area is on another frame, that may
13938 have put text on a frame other than the selected one, so the
13939 above call to update_frame would not have caught it. Catch
13940 it here. */
13941 mini_window = FRAME_MINIBUF_WINDOW (sf);
13942 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
13944 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
13946 XWINDOW (mini_window)->must_be_updated_p = true;
13947 pending |= update_frame (mini_frame, 0, 0);
13948 mini_frame->cursor_type_changed = 0;
13949 if (!pending && hscroll_windows (mini_window))
13950 goto retry;
13954 /* If display was paused because of pending input, make sure we do a
13955 thorough update the next time. */
13956 if (pending)
13958 /* Prevent the optimization at the beginning of
13959 redisplay_internal that tries a single-line update of the
13960 line containing the cursor in the selected window. */
13961 CHARPOS (this_line_start_pos) = 0;
13963 /* Let the overlay arrow be updated the next time. */
13964 update_overlay_arrows (0);
13966 /* If we pause after scrolling, some rows in the current
13967 matrices of some windows are not valid. */
13968 if (!WINDOW_FULL_WIDTH_P (w)
13969 && !FRAME_WINDOW_P (XFRAME (w->frame)))
13970 update_mode_lines = 36;
13972 else
13974 if (!consider_all_windows_p)
13976 /* This has already been done above if
13977 consider_all_windows_p is set. */
13978 if (XBUFFER (w->contents)->text->redisplay
13979 && buffer_window_count (XBUFFER (w->contents)) > 1)
13980 /* This can happen if b->text->redisplay was set during
13981 jit-lock. */
13982 propagate_buffer_redisplay ();
13983 mark_window_display_accurate_1 (w, 1);
13985 /* Say overlay arrows are up to date. */
13986 update_overlay_arrows (1);
13988 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
13989 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
13992 update_mode_lines = 0;
13993 windows_or_buffers_changed = 0;
13996 /* Start SIGIO interrupts coming again. Having them off during the
13997 code above makes it less likely one will discard output, but not
13998 impossible, since there might be stuff in the system buffer here.
13999 But it is much hairier to try to do anything about that. */
14000 if (interrupt_input)
14001 request_sigio ();
14002 RESUME_POLLING;
14004 /* If a frame has become visible which was not before, redisplay
14005 again, so that we display it. Expose events for such a frame
14006 (which it gets when becoming visible) don't call the parts of
14007 redisplay constructing glyphs, so simply exposing a frame won't
14008 display anything in this case. So, we have to display these
14009 frames here explicitly. */
14010 if (!pending)
14012 int new_count = 0;
14014 FOR_EACH_FRAME (tail, frame)
14016 if (XFRAME (frame)->visible)
14017 new_count++;
14020 if (new_count != number_of_visible_frames)
14021 windows_or_buffers_changed = 52;
14024 /* Change frame size now if a change is pending. */
14025 do_pending_window_change (1);
14027 /* If we just did a pending size change, or have additional
14028 visible frames, or selected_window changed, redisplay again. */
14029 if ((windows_or_buffers_changed && !pending)
14030 || (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw))
14031 goto retry;
14033 /* Clear the face and image caches.
14035 We used to do this only if consider_all_windows_p. But the cache
14036 needs to be cleared if a timer creates images in the current
14037 buffer (e.g. the test case in Bug#6230). */
14039 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
14041 clear_face_cache (0);
14042 clear_face_cache_count = 0;
14045 #ifdef HAVE_WINDOW_SYSTEM
14046 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
14048 clear_image_caches (Qnil);
14049 clear_image_cache_count = 0;
14051 #endif /* HAVE_WINDOW_SYSTEM */
14053 end_of_redisplay:
14054 if (interrupt_input && interrupts_deferred)
14055 request_sigio ();
14057 unbind_to (count, Qnil);
14058 RESUME_POLLING;
14062 /* Redisplay, but leave alone any recent echo area message unless
14063 another message has been requested in its place.
14065 This is useful in situations where you need to redisplay but no
14066 user action has occurred, making it inappropriate for the message
14067 area to be cleared. See tracking_off and
14068 wait_reading_process_output for examples of these situations.
14070 FROM_WHERE is an integer saying from where this function was
14071 called. This is useful for debugging. */
14073 void
14074 redisplay_preserve_echo_area (int from_where)
14076 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
14078 if (!NILP (echo_area_buffer[1]))
14080 /* We have a previously displayed message, but no current
14081 message. Redisplay the previous message. */
14082 display_last_displayed_message_p = 1;
14083 redisplay_internal ();
14084 display_last_displayed_message_p = 0;
14086 else
14087 redisplay_internal ();
14089 flush_frame (SELECTED_FRAME ());
14093 /* Function registered with record_unwind_protect in redisplay_internal. */
14095 static void
14096 unwind_redisplay (void)
14098 redisplaying_p = 0;
14102 /* Mark the display of leaf window W as accurate or inaccurate.
14103 If ACCURATE_P is non-zero mark display of W as accurate. If
14104 ACCURATE_P is zero, arrange for W to be redisplayed the next
14105 time redisplay_internal is called. */
14107 static void
14108 mark_window_display_accurate_1 (struct window *w, int accurate_p)
14110 struct buffer *b = XBUFFER (w->contents);
14112 w->last_modified = accurate_p ? BUF_MODIFF (b) : 0;
14113 w->last_overlay_modified = accurate_p ? BUF_OVERLAY_MODIFF (b) : 0;
14114 w->last_had_star = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b);
14116 if (accurate_p)
14118 b->clip_changed = false;
14119 b->prevent_redisplay_optimizations_p = false;
14120 eassert (buffer_window_count (b) > 0);
14121 /* Resetting b->text->redisplay is problematic!
14122 In order to make it safer to do it here, redisplay_internal must
14123 have copied all b->text->redisplay to their respective windows. */
14124 b->text->redisplay = false;
14126 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
14127 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
14128 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
14129 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
14131 w->current_matrix->buffer = b;
14132 w->current_matrix->begv = BUF_BEGV (b);
14133 w->current_matrix->zv = BUF_ZV (b);
14135 w->last_cursor_vpos = w->cursor.vpos;
14136 w->last_cursor_off_p = w->cursor_off_p;
14138 if (w == XWINDOW (selected_window))
14139 w->last_point = BUF_PT (b);
14140 else
14141 w->last_point = marker_position (w->pointm);
14143 w->window_end_valid = true;
14144 w->update_mode_line = false;
14147 w->redisplay = !accurate_p;
14151 /* Mark the display of windows in the window tree rooted at WINDOW as
14152 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
14153 windows as accurate. If ACCURATE_P is zero, arrange for windows to
14154 be redisplayed the next time redisplay_internal is called. */
14156 void
14157 mark_window_display_accurate (Lisp_Object window, int accurate_p)
14159 struct window *w;
14161 for (; !NILP (window); window = w->next)
14163 w = XWINDOW (window);
14164 if (WINDOWP (w->contents))
14165 mark_window_display_accurate (w->contents, accurate_p);
14166 else
14167 mark_window_display_accurate_1 (w, accurate_p);
14170 if (accurate_p)
14171 update_overlay_arrows (1);
14172 else
14173 /* Force a thorough redisplay the next time by setting
14174 last_arrow_position and last_arrow_string to t, which is
14175 unequal to any useful value of Voverlay_arrow_... */
14176 update_overlay_arrows (-1);
14180 /* Return value in display table DP (Lisp_Char_Table *) for character
14181 C. Since a display table doesn't have any parent, we don't have to
14182 follow parent. Do not call this function directly but use the
14183 macro DISP_CHAR_VECTOR. */
14185 Lisp_Object
14186 disp_char_vector (struct Lisp_Char_Table *dp, int c)
14188 Lisp_Object val;
14190 if (ASCII_CHAR_P (c))
14192 val = dp->ascii;
14193 if (SUB_CHAR_TABLE_P (val))
14194 val = XSUB_CHAR_TABLE (val)->contents[c];
14196 else
14198 Lisp_Object table;
14200 XSETCHAR_TABLE (table, dp);
14201 val = char_table_ref (table, c);
14203 if (NILP (val))
14204 val = dp->defalt;
14205 return val;
14210 /***********************************************************************
14211 Window Redisplay
14212 ***********************************************************************/
14214 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
14216 static void
14217 redisplay_windows (Lisp_Object window)
14219 while (!NILP (window))
14221 struct window *w = XWINDOW (window);
14223 if (WINDOWP (w->contents))
14224 redisplay_windows (w->contents);
14225 else if (BUFFERP (w->contents))
14227 displayed_buffer = XBUFFER (w->contents);
14228 /* Use list_of_error, not Qerror, so that
14229 we catch only errors and don't run the debugger. */
14230 internal_condition_case_1 (redisplay_window_0, window,
14231 list_of_error,
14232 redisplay_window_error);
14235 window = w->next;
14239 static Lisp_Object
14240 redisplay_window_error (Lisp_Object ignore)
14242 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
14243 return Qnil;
14246 static Lisp_Object
14247 redisplay_window_0 (Lisp_Object window)
14249 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
14250 redisplay_window (window, false);
14251 return Qnil;
14254 static Lisp_Object
14255 redisplay_window_1 (Lisp_Object window)
14257 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
14258 redisplay_window (window, true);
14259 return Qnil;
14263 /* Set cursor position of W. PT is assumed to be displayed in ROW.
14264 DELTA and DELTA_BYTES are the numbers of characters and bytes by
14265 which positions recorded in ROW differ from current buffer
14266 positions.
14268 Return 0 if cursor is not on this row, 1 otherwise. */
14270 static int
14271 set_cursor_from_row (struct window *w, struct glyph_row *row,
14272 struct glyph_matrix *matrix,
14273 ptrdiff_t delta, ptrdiff_t delta_bytes,
14274 int dy, int dvpos)
14276 struct glyph *glyph = row->glyphs[TEXT_AREA];
14277 struct glyph *end = glyph + row->used[TEXT_AREA];
14278 struct glyph *cursor = NULL;
14279 /* The last known character position in row. */
14280 ptrdiff_t last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
14281 int x = row->x;
14282 ptrdiff_t pt_old = PT - delta;
14283 ptrdiff_t pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
14284 ptrdiff_t pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
14285 struct glyph *glyph_before = glyph - 1, *glyph_after = end;
14286 /* A glyph beyond the edge of TEXT_AREA which we should never
14287 touch. */
14288 struct glyph *glyphs_end = end;
14289 /* Non-zero means we've found a match for cursor position, but that
14290 glyph has the avoid_cursor_p flag set. */
14291 int match_with_avoid_cursor = 0;
14292 /* Non-zero means we've seen at least one glyph that came from a
14293 display string. */
14294 int string_seen = 0;
14295 /* Largest and smallest buffer positions seen so far during scan of
14296 glyph row. */
14297 ptrdiff_t bpos_max = pos_before;
14298 ptrdiff_t bpos_min = pos_after;
14299 /* Last buffer position covered by an overlay string with an integer
14300 `cursor' property. */
14301 ptrdiff_t bpos_covered = 0;
14302 /* Non-zero means the display string on which to display the cursor
14303 comes from a text property, not from an overlay. */
14304 int string_from_text_prop = 0;
14306 /* Don't even try doing anything if called for a mode-line or
14307 header-line row, since the rest of the code isn't prepared to
14308 deal with such calamities. */
14309 eassert (!row->mode_line_p);
14310 if (row->mode_line_p)
14311 return 0;
14313 /* Skip over glyphs not having an object at the start and the end of
14314 the row. These are special glyphs like truncation marks on
14315 terminal frames. */
14316 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
14318 if (!row->reversed_p)
14320 while (glyph < end
14321 && INTEGERP (glyph->object)
14322 && glyph->charpos < 0)
14324 x += glyph->pixel_width;
14325 ++glyph;
14327 while (end > glyph
14328 && INTEGERP ((end - 1)->object)
14329 /* CHARPOS is zero for blanks and stretch glyphs
14330 inserted by extend_face_to_end_of_line. */
14331 && (end - 1)->charpos <= 0)
14332 --end;
14333 glyph_before = glyph - 1;
14334 glyph_after = end;
14336 else
14338 struct glyph *g;
14340 /* If the glyph row is reversed, we need to process it from back
14341 to front, so swap the edge pointers. */
14342 glyphs_end = end = glyph - 1;
14343 glyph += row->used[TEXT_AREA] - 1;
14345 while (glyph > end + 1
14346 && INTEGERP (glyph->object)
14347 && glyph->charpos < 0)
14349 --glyph;
14350 x -= glyph->pixel_width;
14352 if (INTEGERP (glyph->object) && glyph->charpos < 0)
14353 --glyph;
14354 /* By default, in reversed rows we put the cursor on the
14355 rightmost (first in the reading order) glyph. */
14356 for (g = end + 1; g < glyph; g++)
14357 x += g->pixel_width;
14358 while (end < glyph
14359 && INTEGERP ((end + 1)->object)
14360 && (end + 1)->charpos <= 0)
14361 ++end;
14362 glyph_before = glyph + 1;
14363 glyph_after = end;
14366 else if (row->reversed_p)
14368 /* In R2L rows that don't display text, put the cursor on the
14369 rightmost glyph. Case in point: an empty last line that is
14370 part of an R2L paragraph. */
14371 cursor = end - 1;
14372 /* Avoid placing the cursor on the last glyph of the row, where
14373 on terminal frames we hold the vertical border between
14374 adjacent windows. */
14375 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w))
14376 && !WINDOW_RIGHTMOST_P (w)
14377 && cursor == row->glyphs[LAST_AREA] - 1)
14378 cursor--;
14379 x = -1; /* will be computed below, at label compute_x */
14382 /* Step 1: Try to find the glyph whose character position
14383 corresponds to point. If that's not possible, find 2 glyphs
14384 whose character positions are the closest to point, one before
14385 point, the other after it. */
14386 if (!row->reversed_p)
14387 while (/* not marched to end of glyph row */
14388 glyph < end
14389 /* glyph was not inserted by redisplay for internal purposes */
14390 && !INTEGERP (glyph->object))
14392 if (BUFFERP (glyph->object))
14394 ptrdiff_t dpos = glyph->charpos - pt_old;
14396 if (glyph->charpos > bpos_max)
14397 bpos_max = glyph->charpos;
14398 if (glyph->charpos < bpos_min)
14399 bpos_min = glyph->charpos;
14400 if (!glyph->avoid_cursor_p)
14402 /* If we hit point, we've found the glyph on which to
14403 display the cursor. */
14404 if (dpos == 0)
14406 match_with_avoid_cursor = 0;
14407 break;
14409 /* See if we've found a better approximation to
14410 POS_BEFORE or to POS_AFTER. */
14411 if (0 > dpos && dpos > pos_before - pt_old)
14413 pos_before = glyph->charpos;
14414 glyph_before = glyph;
14416 else if (0 < dpos && dpos < pos_after - pt_old)
14418 pos_after = glyph->charpos;
14419 glyph_after = glyph;
14422 else if (dpos == 0)
14423 match_with_avoid_cursor = 1;
14425 else if (STRINGP (glyph->object))
14427 Lisp_Object chprop;
14428 ptrdiff_t glyph_pos = glyph->charpos;
14430 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
14431 glyph->object);
14432 if (!NILP (chprop))
14434 /* If the string came from a `display' text property,
14435 look up the buffer position of that property and
14436 use that position to update bpos_max, as if we
14437 actually saw such a position in one of the row's
14438 glyphs. This helps with supporting integer values
14439 of `cursor' property on the display string in
14440 situations where most or all of the row's buffer
14441 text is completely covered by display properties,
14442 so that no glyph with valid buffer positions is
14443 ever seen in the row. */
14444 ptrdiff_t prop_pos =
14445 string_buffer_position_lim (glyph->object, pos_before,
14446 pos_after, 0);
14448 if (prop_pos >= pos_before)
14449 bpos_max = prop_pos;
14451 if (INTEGERP (chprop))
14453 bpos_covered = bpos_max + XINT (chprop);
14454 /* If the `cursor' property covers buffer positions up
14455 to and including point, we should display cursor on
14456 this glyph. Note that, if a `cursor' property on one
14457 of the string's characters has an integer value, we
14458 will break out of the loop below _before_ we get to
14459 the position match above. IOW, integer values of
14460 the `cursor' property override the "exact match for
14461 point" strategy of positioning the cursor. */
14462 /* Implementation note: bpos_max == pt_old when, e.g.,
14463 we are in an empty line, where bpos_max is set to
14464 MATRIX_ROW_START_CHARPOS, see above. */
14465 if (bpos_max <= pt_old && bpos_covered >= pt_old)
14467 cursor = glyph;
14468 break;
14472 string_seen = 1;
14474 x += glyph->pixel_width;
14475 ++glyph;
14477 else if (glyph > end) /* row is reversed */
14478 while (!INTEGERP (glyph->object))
14480 if (BUFFERP (glyph->object))
14482 ptrdiff_t dpos = glyph->charpos - pt_old;
14484 if (glyph->charpos > bpos_max)
14485 bpos_max = glyph->charpos;
14486 if (glyph->charpos < bpos_min)
14487 bpos_min = glyph->charpos;
14488 if (!glyph->avoid_cursor_p)
14490 if (dpos == 0)
14492 match_with_avoid_cursor = 0;
14493 break;
14495 if (0 > dpos && dpos > pos_before - pt_old)
14497 pos_before = glyph->charpos;
14498 glyph_before = glyph;
14500 else if (0 < dpos && dpos < pos_after - pt_old)
14502 pos_after = glyph->charpos;
14503 glyph_after = glyph;
14506 else if (dpos == 0)
14507 match_with_avoid_cursor = 1;
14509 else if (STRINGP (glyph->object))
14511 Lisp_Object chprop;
14512 ptrdiff_t glyph_pos = glyph->charpos;
14514 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
14515 glyph->object);
14516 if (!NILP (chprop))
14518 ptrdiff_t prop_pos =
14519 string_buffer_position_lim (glyph->object, pos_before,
14520 pos_after, 0);
14522 if (prop_pos >= pos_before)
14523 bpos_max = prop_pos;
14525 if (INTEGERP (chprop))
14527 bpos_covered = bpos_max + XINT (chprop);
14528 /* If the `cursor' property covers buffer positions up
14529 to and including point, we should display cursor on
14530 this glyph. */
14531 if (bpos_max <= pt_old && bpos_covered >= pt_old)
14533 cursor = glyph;
14534 break;
14537 string_seen = 1;
14539 --glyph;
14540 if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
14542 x--; /* can't use any pixel_width */
14543 break;
14545 x -= glyph->pixel_width;
14548 /* Step 2: If we didn't find an exact match for point, we need to
14549 look for a proper place to put the cursor among glyphs between
14550 GLYPH_BEFORE and GLYPH_AFTER. */
14551 if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
14552 && BUFFERP (glyph->object) && glyph->charpos == pt_old)
14553 && !(bpos_max <= pt_old && pt_old <= bpos_covered))
14555 /* An empty line has a single glyph whose OBJECT is zero and
14556 whose CHARPOS is the position of a newline on that line.
14557 Note that on a TTY, there are more glyphs after that, which
14558 were produced by extend_face_to_end_of_line, but their
14559 CHARPOS is zero or negative. */
14560 int empty_line_p =
14561 (row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
14562 && INTEGERP (glyph->object) && glyph->charpos > 0
14563 /* On a TTY, continued and truncated rows also have a glyph at
14564 their end whose OBJECT is zero and whose CHARPOS is
14565 positive (the continuation and truncation glyphs), but such
14566 rows are obviously not "empty". */
14567 && !(row->continued_p || row->truncated_on_right_p);
14569 if (row->ends_in_ellipsis_p && pos_after == last_pos)
14571 ptrdiff_t ellipsis_pos;
14573 /* Scan back over the ellipsis glyphs. */
14574 if (!row->reversed_p)
14576 ellipsis_pos = (glyph - 1)->charpos;
14577 while (glyph > row->glyphs[TEXT_AREA]
14578 && (glyph - 1)->charpos == ellipsis_pos)
14579 glyph--, x -= glyph->pixel_width;
14580 /* That loop always goes one position too far, including
14581 the glyph before the ellipsis. So scan forward over
14582 that one. */
14583 x += glyph->pixel_width;
14584 glyph++;
14586 else /* row is reversed */
14588 ellipsis_pos = (glyph + 1)->charpos;
14589 while (glyph < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14590 && (glyph + 1)->charpos == ellipsis_pos)
14591 glyph++, x += glyph->pixel_width;
14592 x -= glyph->pixel_width;
14593 glyph--;
14596 else if (match_with_avoid_cursor)
14598 cursor = glyph_after;
14599 x = -1;
14601 else if (string_seen)
14603 int incr = row->reversed_p ? -1 : +1;
14605 /* Need to find the glyph that came out of a string which is
14606 present at point. That glyph is somewhere between
14607 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
14608 positioned between POS_BEFORE and POS_AFTER in the
14609 buffer. */
14610 struct glyph *start, *stop;
14611 ptrdiff_t pos = pos_before;
14613 x = -1;
14615 /* If the row ends in a newline from a display string,
14616 reordering could have moved the glyphs belonging to the
14617 string out of the [GLYPH_BEFORE..GLYPH_AFTER] range. So
14618 in this case we extend the search to the last glyph in
14619 the row that was not inserted by redisplay. */
14620 if (row->ends_in_newline_from_string_p)
14622 glyph_after = end;
14623 pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
14626 /* GLYPH_BEFORE and GLYPH_AFTER are the glyphs that
14627 correspond to POS_BEFORE and POS_AFTER, respectively. We
14628 need START and STOP in the order that corresponds to the
14629 row's direction as given by its reversed_p flag. If the
14630 directionality of characters between POS_BEFORE and
14631 POS_AFTER is the opposite of the row's base direction,
14632 these characters will have been reordered for display,
14633 and we need to reverse START and STOP. */
14634 if (!row->reversed_p)
14636 start = min (glyph_before, glyph_after);
14637 stop = max (glyph_before, glyph_after);
14639 else
14641 start = max (glyph_before, glyph_after);
14642 stop = min (glyph_before, glyph_after);
14644 for (glyph = start + incr;
14645 row->reversed_p ? glyph > stop : glyph < stop; )
14648 /* Any glyphs that come from the buffer are here because
14649 of bidi reordering. Skip them, and only pay
14650 attention to glyphs that came from some string. */
14651 if (STRINGP (glyph->object))
14653 Lisp_Object str;
14654 ptrdiff_t tem;
14655 /* If the display property covers the newline, we
14656 need to search for it one position farther. */
14657 ptrdiff_t lim = pos_after
14658 + (pos_after == MATRIX_ROW_END_CHARPOS (row) + delta);
14660 string_from_text_prop = 0;
14661 str = glyph->object;
14662 tem = string_buffer_position_lim (str, pos, lim, 0);
14663 if (tem == 0 /* from overlay */
14664 || pos <= tem)
14666 /* If the string from which this glyph came is
14667 found in the buffer at point, or at position
14668 that is closer to point than pos_after, then
14669 we've found the glyph we've been looking for.
14670 If it comes from an overlay (tem == 0), and
14671 it has the `cursor' property on one of its
14672 glyphs, record that glyph as a candidate for
14673 displaying the cursor. (As in the
14674 unidirectional version, we will display the
14675 cursor on the last candidate we find.) */
14676 if (tem == 0
14677 || tem == pt_old
14678 || (tem - pt_old > 0 && tem < pos_after))
14680 /* The glyphs from this string could have
14681 been reordered. Find the one with the
14682 smallest string position. Or there could
14683 be a character in the string with the
14684 `cursor' property, which means display
14685 cursor on that character's glyph. */
14686 ptrdiff_t strpos = glyph->charpos;
14688 if (tem)
14690 cursor = glyph;
14691 string_from_text_prop = 1;
14693 for ( ;
14694 (row->reversed_p ? glyph > stop : glyph < stop)
14695 && EQ (glyph->object, str);
14696 glyph += incr)
14698 Lisp_Object cprop;
14699 ptrdiff_t gpos = glyph->charpos;
14701 cprop = Fget_char_property (make_number (gpos),
14702 Qcursor,
14703 glyph->object);
14704 if (!NILP (cprop))
14706 cursor = glyph;
14707 break;
14709 if (tem && glyph->charpos < strpos)
14711 strpos = glyph->charpos;
14712 cursor = glyph;
14716 if (tem == pt_old
14717 || (tem - pt_old > 0 && tem < pos_after))
14718 goto compute_x;
14720 if (tem)
14721 pos = tem + 1; /* don't find previous instances */
14723 /* This string is not what we want; skip all of the
14724 glyphs that came from it. */
14725 while ((row->reversed_p ? glyph > stop : glyph < stop)
14726 && EQ (glyph->object, str))
14727 glyph += incr;
14729 else
14730 glyph += incr;
14733 /* If we reached the end of the line, and END was from a string,
14734 the cursor is not on this line. */
14735 if (cursor == NULL
14736 && (row->reversed_p ? glyph <= end : glyph >= end)
14737 && (row->reversed_p ? end > glyphs_end : end < glyphs_end)
14738 && STRINGP (end->object)
14739 && row->continued_p)
14740 return 0;
14742 /* A truncated row may not include PT among its character positions.
14743 Setting the cursor inside the scroll margin will trigger
14744 recalculation of hscroll in hscroll_window_tree. But if a
14745 display string covers point, defer to the string-handling
14746 code below to figure this out. */
14747 else if (row->truncated_on_left_p && pt_old < bpos_min)
14749 cursor = glyph_before;
14750 x = -1;
14752 else if ((row->truncated_on_right_p && pt_old > bpos_max)
14753 /* Zero-width characters produce no glyphs. */
14754 || (!empty_line_p
14755 && (row->reversed_p
14756 ? glyph_after > glyphs_end
14757 : glyph_after < glyphs_end)))
14759 cursor = glyph_after;
14760 x = -1;
14764 compute_x:
14765 if (cursor != NULL)
14766 glyph = cursor;
14767 else if (glyph == glyphs_end
14768 && pos_before == pos_after
14769 && STRINGP ((row->reversed_p
14770 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14771 : row->glyphs[TEXT_AREA])->object))
14773 /* If all the glyphs of this row came from strings, put the
14774 cursor on the first glyph of the row. This avoids having the
14775 cursor outside of the text area in this very rare and hard
14776 use case. */
14777 glyph =
14778 row->reversed_p
14779 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14780 : row->glyphs[TEXT_AREA];
14782 if (x < 0)
14784 struct glyph *g;
14786 /* Need to compute x that corresponds to GLYPH. */
14787 for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++)
14789 if (g >= row->glyphs[TEXT_AREA] + row->used[TEXT_AREA])
14790 emacs_abort ();
14791 x += g->pixel_width;
14795 /* ROW could be part of a continued line, which, under bidi
14796 reordering, might have other rows whose start and end charpos
14797 occlude point. Only set w->cursor if we found a better
14798 approximation to the cursor position than we have from previously
14799 examined candidate rows belonging to the same continued line. */
14800 if (/* We already have a candidate row. */
14801 w->cursor.vpos >= 0
14802 /* That candidate is not the row we are processing. */
14803 && MATRIX_ROW (matrix, w->cursor.vpos) != row
14804 /* Make sure cursor.vpos specifies a row whose start and end
14805 charpos occlude point, and it is valid candidate for being a
14806 cursor-row. This is because some callers of this function
14807 leave cursor.vpos at the row where the cursor was displayed
14808 during the last redisplay cycle. */
14809 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old
14810 && pt_old <= MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14811 && cursor_row_p (MATRIX_ROW (matrix, w->cursor.vpos)))
14813 struct glyph *g1
14814 = MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
14816 /* Don't consider glyphs that are outside TEXT_AREA. */
14817 if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
14818 return 0;
14819 /* Keep the candidate whose buffer position is the closest to
14820 point or has the `cursor' property. */
14821 if (/* Previous candidate is a glyph in TEXT_AREA of that row. */
14822 w->cursor.hpos >= 0
14823 && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
14824 && ((BUFFERP (g1->object)
14825 && (g1->charpos == pt_old /* An exact match always wins. */
14826 || (BUFFERP (glyph->object)
14827 && eabs (g1->charpos - pt_old)
14828 < eabs (glyph->charpos - pt_old))))
14829 /* Previous candidate is a glyph from a string that has
14830 a non-nil `cursor' property. */
14831 || (STRINGP (g1->object)
14832 && (!NILP (Fget_char_property (make_number (g1->charpos),
14833 Qcursor, g1->object))
14834 /* Previous candidate is from the same display
14835 string as this one, and the display string
14836 came from a text property. */
14837 || (EQ (g1->object, glyph->object)
14838 && string_from_text_prop)
14839 /* this candidate is from newline and its
14840 position is not an exact match */
14841 || (INTEGERP (glyph->object)
14842 && glyph->charpos != pt_old)))))
14843 return 0;
14844 /* If this candidate gives an exact match, use that. */
14845 if (!((BUFFERP (glyph->object) && glyph->charpos == pt_old)
14846 /* If this candidate is a glyph created for the
14847 terminating newline of a line, and point is on that
14848 newline, it wins because it's an exact match. */
14849 || (!row->continued_p
14850 && INTEGERP (glyph->object)
14851 && glyph->charpos == 0
14852 && pt_old == MATRIX_ROW_END_CHARPOS (row) - 1))
14853 /* Otherwise, keep the candidate that comes from a row
14854 spanning less buffer positions. This may win when one or
14855 both candidate positions are on glyphs that came from
14856 display strings, for which we cannot compare buffer
14857 positions. */
14858 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14859 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14860 < MATRIX_ROW_END_CHARPOS (row) - MATRIX_ROW_START_CHARPOS (row))
14861 return 0;
14863 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
14864 w->cursor.x = x;
14865 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
14866 w->cursor.y = row->y + dy;
14868 if (w == XWINDOW (selected_window))
14870 if (!row->continued_p
14871 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
14872 && row->x == 0)
14874 this_line_buffer = XBUFFER (w->contents);
14876 CHARPOS (this_line_start_pos)
14877 = MATRIX_ROW_START_CHARPOS (row) + delta;
14878 BYTEPOS (this_line_start_pos)
14879 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
14881 CHARPOS (this_line_end_pos)
14882 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
14883 BYTEPOS (this_line_end_pos)
14884 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
14886 this_line_y = w->cursor.y;
14887 this_line_pixel_height = row->height;
14888 this_line_vpos = w->cursor.vpos;
14889 this_line_start_x = row->x;
14891 else
14892 CHARPOS (this_line_start_pos) = 0;
14895 return 1;
14899 /* Run window scroll functions, if any, for WINDOW with new window
14900 start STARTP. Sets the window start of WINDOW to that position.
14902 We assume that the window's buffer is really current. */
14904 static struct text_pos
14905 run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
14907 struct window *w = XWINDOW (window);
14908 SET_MARKER_FROM_TEXT_POS (w->start, startp);
14910 eassert (current_buffer == XBUFFER (w->contents));
14912 if (!NILP (Vwindow_scroll_functions))
14914 run_hook_with_args_2 (Qwindow_scroll_functions, window,
14915 make_number (CHARPOS (startp)));
14916 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14917 /* In case the hook functions switch buffers. */
14918 set_buffer_internal (XBUFFER (w->contents));
14921 return startp;
14925 /* Make sure the line containing the cursor is fully visible.
14926 A value of 1 means there is nothing to be done.
14927 (Either the line is fully visible, or it cannot be made so,
14928 or we cannot tell.)
14930 If FORCE_P is non-zero, return 0 even if partial visible cursor row
14931 is higher than window.
14933 A value of 0 means the caller should do scrolling
14934 as if point had gone off the screen. */
14936 static int
14937 cursor_row_fully_visible_p (struct window *w, int force_p, int current_matrix_p)
14939 struct glyph_matrix *matrix;
14940 struct glyph_row *row;
14941 int window_height;
14943 if (!make_cursor_line_fully_visible_p)
14944 return 1;
14946 /* It's not always possible to find the cursor, e.g, when a window
14947 is full of overlay strings. Don't do anything in that case. */
14948 if (w->cursor.vpos < 0)
14949 return 1;
14951 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
14952 row = MATRIX_ROW (matrix, w->cursor.vpos);
14954 /* If the cursor row is not partially visible, there's nothing to do. */
14955 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
14956 return 1;
14958 /* If the row the cursor is in is taller than the window's height,
14959 it's not clear what to do, so do nothing. */
14960 window_height = window_box_height (w);
14961 if (row->height >= window_height)
14963 if (!force_p || MINI_WINDOW_P (w)
14964 || w->vscroll || w->cursor.vpos == 0)
14965 return 1;
14967 return 0;
14971 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
14972 non-zero means only WINDOW is redisplayed in redisplay_internal.
14973 TEMP_SCROLL_STEP has the same meaning as emacs_scroll_step, and is used
14974 in redisplay_window to bring a partially visible line into view in
14975 the case that only the cursor has moved.
14977 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
14978 last screen line's vertical height extends past the end of the screen.
14980 Value is
14982 1 if scrolling succeeded
14984 0 if scrolling didn't find point.
14986 -1 if new fonts have been loaded so that we must interrupt
14987 redisplay, adjust glyph matrices, and try again. */
14989 enum
14991 SCROLLING_SUCCESS,
14992 SCROLLING_FAILED,
14993 SCROLLING_NEED_LARGER_MATRICES
14996 /* If scroll-conservatively is more than this, never recenter.
14998 If you change this, don't forget to update the doc string of
14999 `scroll-conservatively' and the Emacs manual. */
15000 #define SCROLL_LIMIT 100
15002 static int
15003 try_scrolling (Lisp_Object window, int just_this_one_p,
15004 ptrdiff_t arg_scroll_conservatively, ptrdiff_t scroll_step,
15005 int temp_scroll_step, int last_line_misfit)
15007 struct window *w = XWINDOW (window);
15008 struct frame *f = XFRAME (w->frame);
15009 struct text_pos pos, startp;
15010 struct it it;
15011 int this_scroll_margin, scroll_max, rc, height;
15012 int dy = 0, amount_to_scroll = 0, scroll_down_p = 0;
15013 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
15014 Lisp_Object aggressive;
15015 /* We will never try scrolling more than this number of lines. */
15016 int scroll_limit = SCROLL_LIMIT;
15017 int frame_line_height = default_line_pixel_height (w);
15018 int window_total_lines
15019 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
15021 #ifdef GLYPH_DEBUG
15022 debug_method_add (w, "try_scrolling");
15023 #endif
15025 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15027 /* Compute scroll margin height in pixels. We scroll when point is
15028 within this distance from the top or bottom of the window. */
15029 if (scroll_margin > 0)
15030 this_scroll_margin = min (scroll_margin, window_total_lines / 4)
15031 * frame_line_height;
15032 else
15033 this_scroll_margin = 0;
15035 /* Force arg_scroll_conservatively to have a reasonable value, to
15036 avoid scrolling too far away with slow move_it_* functions. Note
15037 that the user can supply scroll-conservatively equal to
15038 `most-positive-fixnum', which can be larger than INT_MAX. */
15039 if (arg_scroll_conservatively > scroll_limit)
15041 arg_scroll_conservatively = scroll_limit + 1;
15042 scroll_max = scroll_limit * frame_line_height;
15044 else if (scroll_step || arg_scroll_conservatively || temp_scroll_step)
15045 /* Compute how much we should try to scroll maximally to bring
15046 point into view. */
15047 scroll_max = (max (scroll_step,
15048 max (arg_scroll_conservatively, temp_scroll_step))
15049 * frame_line_height);
15050 else if (NUMBERP (BVAR (current_buffer, scroll_down_aggressively))
15051 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively)))
15052 /* We're trying to scroll because of aggressive scrolling but no
15053 scroll_step is set. Choose an arbitrary one. */
15054 scroll_max = 10 * frame_line_height;
15055 else
15056 scroll_max = 0;
15058 too_near_end:
15060 /* Decide whether to scroll down. */
15061 if (PT > CHARPOS (startp))
15063 int scroll_margin_y;
15065 /* Compute the pixel ypos of the scroll margin, then move IT to
15066 either that ypos or PT, whichever comes first. */
15067 start_display (&it, w, startp);
15068 scroll_margin_y = it.last_visible_y - this_scroll_margin
15069 - frame_line_height * extra_scroll_margin_lines;
15070 move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
15071 (MOVE_TO_POS | MOVE_TO_Y));
15073 if (PT > CHARPOS (it.current.pos))
15075 int y0 = line_bottom_y (&it);
15076 /* Compute how many pixels below window bottom to stop searching
15077 for PT. This avoids costly search for PT that is far away if
15078 the user limited scrolling by a small number of lines, but
15079 always finds PT if scroll_conservatively is set to a large
15080 number, such as most-positive-fixnum. */
15081 int slack = max (scroll_max, 10 * frame_line_height);
15082 int y_to_move = it.last_visible_y + slack;
15084 /* Compute the distance from the scroll margin to PT or to
15085 the scroll limit, whichever comes first. This should
15086 include the height of the cursor line, to make that line
15087 fully visible. */
15088 move_it_to (&it, PT, -1, y_to_move,
15089 -1, MOVE_TO_POS | MOVE_TO_Y);
15090 dy = line_bottom_y (&it) - y0;
15092 if (dy > scroll_max)
15093 return SCROLLING_FAILED;
15095 if (dy > 0)
15096 scroll_down_p = 1;
15100 if (scroll_down_p)
15102 /* Point is in or below the bottom scroll margin, so move the
15103 window start down. If scrolling conservatively, move it just
15104 enough down to make point visible. If scroll_step is set,
15105 move it down by scroll_step. */
15106 if (arg_scroll_conservatively)
15107 amount_to_scroll
15108 = min (max (dy, frame_line_height),
15109 frame_line_height * arg_scroll_conservatively);
15110 else if (scroll_step || temp_scroll_step)
15111 amount_to_scroll = scroll_max;
15112 else
15114 aggressive = BVAR (current_buffer, scroll_up_aggressively);
15115 height = WINDOW_BOX_TEXT_HEIGHT (w);
15116 if (NUMBERP (aggressive))
15118 double float_amount = XFLOATINT (aggressive) * height;
15119 int aggressive_scroll = float_amount;
15120 if (aggressive_scroll == 0 && float_amount > 0)
15121 aggressive_scroll = 1;
15122 /* Don't let point enter the scroll margin near top of
15123 the window. This could happen if the value of
15124 scroll_up_aggressively is too large and there are
15125 non-zero margins, because scroll_up_aggressively
15126 means put point that fraction of window height
15127 _from_the_bottom_margin_. */
15128 if (aggressive_scroll + 2*this_scroll_margin > height)
15129 aggressive_scroll = height - 2*this_scroll_margin;
15130 amount_to_scroll = dy + aggressive_scroll;
15134 if (amount_to_scroll <= 0)
15135 return SCROLLING_FAILED;
15137 start_display (&it, w, startp);
15138 if (arg_scroll_conservatively <= scroll_limit)
15139 move_it_vertically (&it, amount_to_scroll);
15140 else
15142 /* Extra precision for users who set scroll-conservatively
15143 to a large number: make sure the amount we scroll
15144 the window start is never less than amount_to_scroll,
15145 which was computed as distance from window bottom to
15146 point. This matters when lines at window top and lines
15147 below window bottom have different height. */
15148 struct it it1;
15149 void *it1data = NULL;
15150 /* We use a temporary it1 because line_bottom_y can modify
15151 its argument, if it moves one line down; see there. */
15152 int start_y;
15154 SAVE_IT (it1, it, it1data);
15155 start_y = line_bottom_y (&it1);
15156 do {
15157 RESTORE_IT (&it, &it, it1data);
15158 move_it_by_lines (&it, 1);
15159 SAVE_IT (it1, it, it1data);
15160 } while (line_bottom_y (&it1) - start_y < amount_to_scroll);
15163 /* If STARTP is unchanged, move it down another screen line. */
15164 if (CHARPOS (it.current.pos) == CHARPOS (startp))
15165 move_it_by_lines (&it, 1);
15166 startp = it.current.pos;
15168 else
15170 struct text_pos scroll_margin_pos = startp;
15171 int y_offset = 0;
15173 /* See if point is inside the scroll margin at the top of the
15174 window. */
15175 if (this_scroll_margin)
15177 int y_start;
15179 start_display (&it, w, startp);
15180 y_start = it.current_y;
15181 move_it_vertically (&it, this_scroll_margin);
15182 scroll_margin_pos = it.current.pos;
15183 /* If we didn't move enough before hitting ZV, request
15184 additional amount of scroll, to move point out of the
15185 scroll margin. */
15186 if (IT_CHARPOS (it) == ZV
15187 && it.current_y - y_start < this_scroll_margin)
15188 y_offset = this_scroll_margin - (it.current_y - y_start);
15191 if (PT < CHARPOS (scroll_margin_pos))
15193 /* Point is in the scroll margin at the top of the window or
15194 above what is displayed in the window. */
15195 int y0, y_to_move;
15197 /* Compute the vertical distance from PT to the scroll
15198 margin position. Move as far as scroll_max allows, or
15199 one screenful, or 10 screen lines, whichever is largest.
15200 Give up if distance is greater than scroll_max or if we
15201 didn't reach the scroll margin position. */
15202 SET_TEXT_POS (pos, PT, PT_BYTE);
15203 start_display (&it, w, pos);
15204 y0 = it.current_y;
15205 y_to_move = max (it.last_visible_y,
15206 max (scroll_max, 10 * frame_line_height));
15207 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
15208 y_to_move, -1,
15209 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
15210 dy = it.current_y - y0;
15211 if (dy > scroll_max
15212 || IT_CHARPOS (it) < CHARPOS (scroll_margin_pos))
15213 return SCROLLING_FAILED;
15215 /* Additional scroll for when ZV was too close to point. */
15216 dy += y_offset;
15218 /* Compute new window start. */
15219 start_display (&it, w, startp);
15221 if (arg_scroll_conservatively)
15222 amount_to_scroll = max (dy, frame_line_height *
15223 max (scroll_step, temp_scroll_step));
15224 else if (scroll_step || temp_scroll_step)
15225 amount_to_scroll = scroll_max;
15226 else
15228 aggressive = BVAR (current_buffer, scroll_down_aggressively);
15229 height = WINDOW_BOX_TEXT_HEIGHT (w);
15230 if (NUMBERP (aggressive))
15232 double float_amount = XFLOATINT (aggressive) * height;
15233 int aggressive_scroll = float_amount;
15234 if (aggressive_scroll == 0 && float_amount > 0)
15235 aggressive_scroll = 1;
15236 /* Don't let point enter the scroll margin near
15237 bottom of the window, if the value of
15238 scroll_down_aggressively happens to be too
15239 large. */
15240 if (aggressive_scroll + 2*this_scroll_margin > height)
15241 aggressive_scroll = height - 2*this_scroll_margin;
15242 amount_to_scroll = dy + aggressive_scroll;
15246 if (amount_to_scroll <= 0)
15247 return SCROLLING_FAILED;
15249 move_it_vertically_backward (&it, amount_to_scroll);
15250 startp = it.current.pos;
15254 /* Run window scroll functions. */
15255 startp = run_window_scroll_functions (window, startp);
15257 /* Display the window. Give up if new fonts are loaded, or if point
15258 doesn't appear. */
15259 if (!try_window (window, startp, 0))
15260 rc = SCROLLING_NEED_LARGER_MATRICES;
15261 else if (w->cursor.vpos < 0)
15263 clear_glyph_matrix (w->desired_matrix);
15264 rc = SCROLLING_FAILED;
15266 else
15268 /* Maybe forget recorded base line for line number display. */
15269 if (!just_this_one_p
15270 || current_buffer->clip_changed
15271 || BEG_UNCHANGED < CHARPOS (startp))
15272 w->base_line_number = 0;
15274 /* If cursor ends up on a partially visible line,
15275 treat that as being off the bottom of the screen. */
15276 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0)
15277 /* It's possible that the cursor is on the first line of the
15278 buffer, which is partially obscured due to a vscroll
15279 (Bug#7537). In that case, avoid looping forever. */
15280 && extra_scroll_margin_lines < w->desired_matrix->nrows - 1)
15282 clear_glyph_matrix (w->desired_matrix);
15283 ++extra_scroll_margin_lines;
15284 goto too_near_end;
15286 rc = SCROLLING_SUCCESS;
15289 return rc;
15293 /* Compute a suitable window start for window W if display of W starts
15294 on a continuation line. Value is non-zero if a new window start
15295 was computed.
15297 The new window start will be computed, based on W's width, starting
15298 from the start of the continued line. It is the start of the
15299 screen line with the minimum distance from the old start W->start. */
15301 static int
15302 compute_window_start_on_continuation_line (struct window *w)
15304 struct text_pos pos, start_pos;
15305 int window_start_changed_p = 0;
15307 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
15309 /* If window start is on a continuation line... Window start may be
15310 < BEGV in case there's invisible text at the start of the
15311 buffer (M-x rmail, for example). */
15312 if (CHARPOS (start_pos) > BEGV
15313 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
15315 struct it it;
15316 struct glyph_row *row;
15318 /* Handle the case that the window start is out of range. */
15319 if (CHARPOS (start_pos) < BEGV)
15320 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
15321 else if (CHARPOS (start_pos) > ZV)
15322 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
15324 /* Find the start of the continued line. This should be fast
15325 because find_newline is fast (newline cache). */
15326 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
15327 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
15328 row, DEFAULT_FACE_ID);
15329 reseat_at_previous_visible_line_start (&it);
15331 /* If the line start is "too far" away from the window start,
15332 say it takes too much time to compute a new window start. */
15333 if (CHARPOS (start_pos) - IT_CHARPOS (it)
15334 /* PXW: Do we need upper bounds here? */
15335 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
15337 int min_distance, distance;
15339 /* Move forward by display lines to find the new window
15340 start. If window width was enlarged, the new start can
15341 be expected to be > the old start. If window width was
15342 decreased, the new window start will be < the old start.
15343 So, we're looking for the display line start with the
15344 minimum distance from the old window start. */
15345 pos = it.current.pos;
15346 min_distance = INFINITY;
15347 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
15348 distance < min_distance)
15350 min_distance = distance;
15351 pos = it.current.pos;
15352 if (it.line_wrap == WORD_WRAP)
15354 /* Under WORD_WRAP, move_it_by_lines is likely to
15355 overshoot and stop not at the first, but the
15356 second character from the left margin. So in
15357 that case, we need a more tight control on the X
15358 coordinate of the iterator than move_it_by_lines
15359 promises in its contract. The method is to first
15360 go to the last (rightmost) visible character of a
15361 line, then move to the leftmost character on the
15362 next line in a separate call. */
15363 move_it_to (&it, ZV, it.last_visible_x, it.current_y, -1,
15364 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
15365 move_it_to (&it, ZV, 0,
15366 it.current_y + it.max_ascent + it.max_descent, -1,
15367 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
15369 else
15370 move_it_by_lines (&it, 1);
15373 /* Set the window start there. */
15374 SET_MARKER_FROM_TEXT_POS (w->start, pos);
15375 window_start_changed_p = 1;
15379 return window_start_changed_p;
15383 /* Try cursor movement in case text has not changed in window WINDOW,
15384 with window start STARTP. Value is
15386 CURSOR_MOVEMENT_SUCCESS if successful
15388 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
15390 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
15391 display. *SCROLL_STEP is set to 1, under certain circumstances, if
15392 we want to scroll as if scroll-step were set to 1. See the code.
15394 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
15395 which case we have to abort this redisplay, and adjust matrices
15396 first. */
15398 enum
15400 CURSOR_MOVEMENT_SUCCESS,
15401 CURSOR_MOVEMENT_CANNOT_BE_USED,
15402 CURSOR_MOVEMENT_MUST_SCROLL,
15403 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
15406 static int
15407 try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_step)
15409 struct window *w = XWINDOW (window);
15410 struct frame *f = XFRAME (w->frame);
15411 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
15413 #ifdef GLYPH_DEBUG
15414 if (inhibit_try_cursor_movement)
15415 return rc;
15416 #endif
15418 /* Previously, there was a check for Lisp integer in the
15419 if-statement below. Now, this field is converted to
15420 ptrdiff_t, thus zero means invalid position in a buffer. */
15421 eassert (w->last_point > 0);
15422 /* Likewise there was a check whether window_end_vpos is nil or larger
15423 than the window. Now window_end_vpos is int and so never nil, but
15424 let's leave eassert to check whether it fits in the window. */
15425 eassert (w->window_end_vpos < w->current_matrix->nrows);
15427 /* Handle case where text has not changed, only point, and it has
15428 not moved off the frame. */
15429 if (/* Point may be in this window. */
15430 PT >= CHARPOS (startp)
15431 /* Selective display hasn't changed. */
15432 && !current_buffer->clip_changed
15433 /* Function force-mode-line-update is used to force a thorough
15434 redisplay. It sets either windows_or_buffers_changed or
15435 update_mode_lines. So don't take a shortcut here for these
15436 cases. */
15437 && !update_mode_lines
15438 && !windows_or_buffers_changed
15439 && !f->cursor_type_changed
15440 && NILP (Vshow_trailing_whitespace)
15441 /* This code is not used for mini-buffer for the sake of the case
15442 of redisplaying to replace an echo area message; since in
15443 that case the mini-buffer contents per se are usually
15444 unchanged. This code is of no real use in the mini-buffer
15445 since the handling of this_line_start_pos, etc., in redisplay
15446 handles the same cases. */
15447 && !EQ (window, minibuf_window)
15448 && (FRAME_WINDOW_P (f)
15449 || !overlay_arrow_in_current_buffer_p ()))
15451 int this_scroll_margin, top_scroll_margin;
15452 struct glyph_row *row = NULL;
15453 int frame_line_height = default_line_pixel_height (w);
15454 int window_total_lines
15455 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
15457 #ifdef GLYPH_DEBUG
15458 debug_method_add (w, "cursor movement");
15459 #endif
15461 /* Scroll if point within this distance from the top or bottom
15462 of the window. This is a pixel value. */
15463 if (scroll_margin > 0)
15465 this_scroll_margin = min (scroll_margin, window_total_lines / 4);
15466 this_scroll_margin *= frame_line_height;
15468 else
15469 this_scroll_margin = 0;
15471 top_scroll_margin = this_scroll_margin;
15472 if (WINDOW_WANTS_HEADER_LINE_P (w))
15473 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
15475 /* Start with the row the cursor was displayed during the last
15476 not paused redisplay. Give up if that row is not valid. */
15477 if (w->last_cursor_vpos < 0
15478 || w->last_cursor_vpos >= w->current_matrix->nrows)
15479 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15480 else
15482 row = MATRIX_ROW (w->current_matrix, w->last_cursor_vpos);
15483 if (row->mode_line_p)
15484 ++row;
15485 if (!row->enabled_p)
15486 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15489 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
15491 int scroll_p = 0, must_scroll = 0;
15492 int last_y = window_text_bottom_y (w) - this_scroll_margin;
15494 if (PT > w->last_point)
15496 /* Point has moved forward. */
15497 while (MATRIX_ROW_END_CHARPOS (row) < PT
15498 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
15500 eassert (row->enabled_p);
15501 ++row;
15504 /* If the end position of a row equals the start
15505 position of the next row, and PT is at that position,
15506 we would rather display cursor in the next line. */
15507 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15508 && MATRIX_ROW_END_CHARPOS (row) == PT
15509 && row < MATRIX_MODE_LINE_ROW (w->current_matrix)
15510 && MATRIX_ROW_START_CHARPOS (row+1) == PT
15511 && !cursor_row_p (row))
15512 ++row;
15514 /* If within the scroll margin, scroll. Note that
15515 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
15516 the next line would be drawn, and that
15517 this_scroll_margin can be zero. */
15518 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
15519 || PT > MATRIX_ROW_END_CHARPOS (row)
15520 /* Line is completely visible last line in window
15521 and PT is to be set in the next line. */
15522 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
15523 && PT == MATRIX_ROW_END_CHARPOS (row)
15524 && !row->ends_at_zv_p
15525 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
15526 scroll_p = 1;
15528 else if (PT < w->last_point)
15530 /* Cursor has to be moved backward. Note that PT >=
15531 CHARPOS (startp) because of the outer if-statement. */
15532 while (!row->mode_line_p
15533 && (MATRIX_ROW_START_CHARPOS (row) > PT
15534 || (MATRIX_ROW_START_CHARPOS (row) == PT
15535 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
15536 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
15537 row > w->current_matrix->rows
15538 && (row-1)->ends_in_newline_from_string_p))))
15539 && (row->y > top_scroll_margin
15540 || CHARPOS (startp) == BEGV))
15542 eassert (row->enabled_p);
15543 --row;
15546 /* Consider the following case: Window starts at BEGV,
15547 there is invisible, intangible text at BEGV, so that
15548 display starts at some point START > BEGV. It can
15549 happen that we are called with PT somewhere between
15550 BEGV and START. Try to handle that case. */
15551 if (row < w->current_matrix->rows
15552 || row->mode_line_p)
15554 row = w->current_matrix->rows;
15555 if (row->mode_line_p)
15556 ++row;
15559 /* Due to newlines in overlay strings, we may have to
15560 skip forward over overlay strings. */
15561 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15562 && MATRIX_ROW_END_CHARPOS (row) == PT
15563 && !cursor_row_p (row))
15564 ++row;
15566 /* If within the scroll margin, scroll. */
15567 if (row->y < top_scroll_margin
15568 && CHARPOS (startp) != BEGV)
15569 scroll_p = 1;
15571 else
15573 /* Cursor did not move. So don't scroll even if cursor line
15574 is partially visible, as it was so before. */
15575 rc = CURSOR_MOVEMENT_SUCCESS;
15578 if (PT < MATRIX_ROW_START_CHARPOS (row)
15579 || PT > MATRIX_ROW_END_CHARPOS (row))
15581 /* if PT is not in the glyph row, give up. */
15582 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15583 must_scroll = 1;
15585 else if (rc != CURSOR_MOVEMENT_SUCCESS
15586 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
15588 struct glyph_row *row1;
15590 /* If rows are bidi-reordered and point moved, back up
15591 until we find a row that does not belong to a
15592 continuation line. This is because we must consider
15593 all rows of a continued line as candidates for the
15594 new cursor positioning, since row start and end
15595 positions change non-linearly with vertical position
15596 in such rows. */
15597 /* FIXME: Revisit this when glyph ``spilling'' in
15598 continuation lines' rows is implemented for
15599 bidi-reordered rows. */
15600 for (row1 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
15601 MATRIX_ROW_CONTINUATION_LINE_P (row);
15602 --row)
15604 /* If we hit the beginning of the displayed portion
15605 without finding the first row of a continued
15606 line, give up. */
15607 if (row <= row1)
15609 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15610 break;
15612 eassert (row->enabled_p);
15615 if (must_scroll)
15617 else if (rc != CURSOR_MOVEMENT_SUCCESS
15618 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
15619 /* Make sure this isn't a header line by any chance, since
15620 then MATRIX_ROW_PARTIALLY_VISIBLE_P might yield non-zero. */
15621 && !row->mode_line_p
15622 && make_cursor_line_fully_visible_p)
15624 if (PT == MATRIX_ROW_END_CHARPOS (row)
15625 && !row->ends_at_zv_p
15626 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
15627 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15628 else if (row->height > window_box_height (w))
15630 /* If we end up in a partially visible line, let's
15631 make it fully visible, except when it's taller
15632 than the window, in which case we can't do much
15633 about it. */
15634 *scroll_step = 1;
15635 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15637 else
15639 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
15640 if (!cursor_row_fully_visible_p (w, 0, 1))
15641 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15642 else
15643 rc = CURSOR_MOVEMENT_SUCCESS;
15646 else if (scroll_p)
15647 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15648 else if (rc != CURSOR_MOVEMENT_SUCCESS
15649 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
15651 /* With bidi-reordered rows, there could be more than
15652 one candidate row whose start and end positions
15653 occlude point. We need to let set_cursor_from_row
15654 find the best candidate. */
15655 /* FIXME: Revisit this when glyph ``spilling'' in
15656 continuation lines' rows is implemented for
15657 bidi-reordered rows. */
15658 int rv = 0;
15662 int at_zv_p = 0, exact_match_p = 0;
15664 if (MATRIX_ROW_START_CHARPOS (row) <= PT
15665 && PT <= MATRIX_ROW_END_CHARPOS (row)
15666 && cursor_row_p (row))
15667 rv |= set_cursor_from_row (w, row, w->current_matrix,
15668 0, 0, 0, 0);
15669 /* As soon as we've found the exact match for point,
15670 or the first suitable row whose ends_at_zv_p flag
15671 is set, we are done. */
15672 if (rv)
15674 at_zv_p = MATRIX_ROW (w->current_matrix,
15675 w->cursor.vpos)->ends_at_zv_p;
15676 if (!at_zv_p
15677 && w->cursor.hpos >= 0
15678 && w->cursor.hpos < MATRIX_ROW_USED (w->current_matrix,
15679 w->cursor.vpos))
15681 struct glyph_row *candidate =
15682 MATRIX_ROW (w->current_matrix, w->cursor.vpos);
15683 struct glyph *g =
15684 candidate->glyphs[TEXT_AREA] + w->cursor.hpos;
15685 ptrdiff_t endpos = MATRIX_ROW_END_CHARPOS (candidate);
15687 exact_match_p =
15688 (BUFFERP (g->object) && g->charpos == PT)
15689 || (INTEGERP (g->object)
15690 && (g->charpos == PT
15691 || (g->charpos == 0 && endpos - 1 == PT)));
15693 if (at_zv_p || exact_match_p)
15695 rc = CURSOR_MOVEMENT_SUCCESS;
15696 break;
15699 if (MATRIX_ROW_BOTTOM_Y (row) == last_y)
15700 break;
15701 ++row;
15703 while (((MATRIX_ROW_CONTINUATION_LINE_P (row)
15704 || row->continued_p)
15705 && MATRIX_ROW_BOTTOM_Y (row) <= last_y)
15706 || (MATRIX_ROW_START_CHARPOS (row) == PT
15707 && MATRIX_ROW_BOTTOM_Y (row) < last_y));
15708 /* If we didn't find any candidate rows, or exited the
15709 loop before all the candidates were examined, signal
15710 to the caller that this method failed. */
15711 if (rc != CURSOR_MOVEMENT_SUCCESS
15712 && !(rv
15713 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
15714 && !row->continued_p))
15715 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15716 else if (rv)
15717 rc = CURSOR_MOVEMENT_SUCCESS;
15719 else
15723 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
15725 rc = CURSOR_MOVEMENT_SUCCESS;
15726 break;
15728 ++row;
15730 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15731 && MATRIX_ROW_START_CHARPOS (row) == PT
15732 && cursor_row_p (row));
15737 return rc;
15741 void
15742 set_vertical_scroll_bar (struct window *w)
15744 ptrdiff_t start, end, whole;
15746 /* Calculate the start and end positions for the current window.
15747 At some point, it would be nice to choose between scrollbars
15748 which reflect the whole buffer size, with special markers
15749 indicating narrowing, and scrollbars which reflect only the
15750 visible region.
15752 Note that mini-buffers sometimes aren't displaying any text. */
15753 if (!MINI_WINDOW_P (w)
15754 || (w == XWINDOW (minibuf_window)
15755 && NILP (echo_area_buffer[0])))
15757 struct buffer *buf = XBUFFER (w->contents);
15758 whole = BUF_ZV (buf) - BUF_BEGV (buf);
15759 start = marker_position (w->start) - BUF_BEGV (buf);
15760 /* I don't think this is guaranteed to be right. For the
15761 moment, we'll pretend it is. */
15762 end = BUF_Z (buf) - w->window_end_pos - BUF_BEGV (buf);
15764 if (end < start)
15765 end = start;
15766 if (whole < (end - start))
15767 whole = end - start;
15769 else
15770 start = end = whole = 0;
15772 /* Indicate what this scroll bar ought to be displaying now. */
15773 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
15774 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
15775 (w, end - start, whole, start);
15779 void
15780 set_horizontal_scroll_bar (struct window *w)
15782 int start, end, whole, box_width;
15784 if (!MINI_WINDOW_P (w)
15785 || (w == XWINDOW (minibuf_window)
15786 && NILP (echo_area_buffer[0])))
15788 struct buffer *b = XBUFFER (w->contents);
15789 struct buffer *old_buffer = NULL;
15790 struct it it;
15791 struct text_pos startp;
15793 if (b != current_buffer)
15795 old_buffer = current_buffer;
15796 set_buffer_internal (b);
15799 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15800 start_display (&it, w, startp);
15801 it.last_visible_x = INT_MAX;
15802 whole = move_it_to (&it, -1, INT_MAX, window_box_height (w), -1,
15803 MOVE_TO_X | MOVE_TO_Y);
15804 /* whole = move_it_to (&it, w->window_end_pos, INT_MAX,
15805 window_box_height (w), -1,
15806 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); */
15808 start = w->hscroll * FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w));
15809 box_width = window_box_width (w, TEXT_AREA);
15810 end = start + box_width;
15812 /* The following is needed to ensure that if after maximizing a
15813 window we get hscroll > 0, we can still drag the thumb to the
15814 left. */
15815 whole = max (whole, w->hscroll + box_width);
15816 whole = max (whole, end - start);
15818 if (old_buffer)
15819 set_buffer_internal (old_buffer);
15821 else
15822 start = end = whole = 0;
15824 w->hscroll_whole = whole;
15826 /* Indicate what this scroll bar ought to be displaying now. */
15827 if (FRAME_TERMINAL (XFRAME (w->frame))->set_horizontal_scroll_bar_hook)
15828 (*FRAME_TERMINAL (XFRAME (w->frame))->set_horizontal_scroll_bar_hook)
15829 (w, end - start, whole, start);
15833 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
15834 selected_window is redisplayed.
15836 We can return without actually redisplaying the window if fonts has been
15837 changed on window's frame. In that case, redisplay_internal will retry.
15839 As one of the important parts of redisplaying a window, we need to
15840 decide whether the previous window-start position (stored in the
15841 window's w->start marker position) is still valid, and if it isn't,
15842 recompute it. Some details about that:
15844 . The previous window-start could be in a continuation line, in
15845 which case we need to recompute it when the window width
15846 changes. See compute_window_start_on_continuation_line and its
15847 call below.
15849 . The text that changed since last redisplay could include the
15850 previous window-start position. In that case, we try to salvage
15851 what we can from the current glyph matrix by calling
15852 try_scrolling, which see.
15854 . Some Emacs command could force us to use a specific window-start
15855 position by setting the window's force_start flag, or gently
15856 propose doing that by setting the window's optional_new_start
15857 flag. In these cases, we try using the specified start point if
15858 that succeeds (i.e. the window desired matrix is successfully
15859 recomputed, and point location is within the window). In case
15860 of optional_new_start, we first check if the specified start
15861 position is feasible, i.e. if it will allow point to be
15862 displayed in the window. If using the specified start point
15863 fails, e.g., if new fonts are needed to be loaded, we abort the
15864 redisplay cycle and leave it up to the next cycle to figure out
15865 things.
15867 . Note that the window's force_start flag is sometimes set by
15868 redisplay itself, when it decides that the previous window start
15869 point is fine and should be kept. Search for "goto force_start"
15870 below to see the details. Like the values of window-start
15871 specified outside of redisplay, these internally-deduced values
15872 are tested for feasibility, and ignored if found to be
15873 unfeasible.
15875 . Note that the function try_window, used to completely redisplay
15876 a window, accepts the window's start point as its argument.
15877 This is used several times in the redisplay code to control
15878 where the window start will be, according to user options such
15879 as scroll-conservatively, and also to ensure the screen line
15880 showing point will be fully (as opposed to partially) visible on
15881 display. */
15883 static void
15884 redisplay_window (Lisp_Object window, bool just_this_one_p)
15886 struct window *w = XWINDOW (window);
15887 struct frame *f = XFRAME (w->frame);
15888 struct buffer *buffer = XBUFFER (w->contents);
15889 struct buffer *old = current_buffer;
15890 struct text_pos lpoint, opoint, startp;
15891 int update_mode_line;
15892 int tem;
15893 struct it it;
15894 /* Record it now because it's overwritten. */
15895 bool current_matrix_up_to_date_p = false;
15896 bool used_current_matrix_p = false;
15897 /* This is less strict than current_matrix_up_to_date_p.
15898 It indicates that the buffer contents and narrowing are unchanged. */
15899 bool buffer_unchanged_p = false;
15900 int temp_scroll_step = 0;
15901 ptrdiff_t count = SPECPDL_INDEX ();
15902 int rc;
15903 int centering_position = -1;
15904 int last_line_misfit = 0;
15905 ptrdiff_t beg_unchanged, end_unchanged;
15906 int frame_line_height;
15908 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15909 opoint = lpoint;
15911 #ifdef GLYPH_DEBUG
15912 *w->desired_matrix->method = 0;
15913 #endif
15915 if (!just_this_one_p
15916 && REDISPLAY_SOME_P ()
15917 && !w->redisplay
15918 && !f->redisplay
15919 && !buffer->text->redisplay
15920 && BUF_PT (buffer) == w->last_point)
15921 return;
15923 /* Make sure that both W's markers are valid. */
15924 eassert (XMARKER (w->start)->buffer == buffer);
15925 eassert (XMARKER (w->pointm)->buffer == buffer);
15927 /* We come here again if we need to run window-text-change-functions
15928 below. */
15929 restart:
15930 reconsider_clip_changes (w);
15931 frame_line_height = default_line_pixel_height (w);
15933 /* Has the mode line to be updated? */
15934 update_mode_line = (w->update_mode_line
15935 || update_mode_lines
15936 || buffer->clip_changed
15937 || buffer->prevent_redisplay_optimizations_p);
15939 if (!just_this_one_p)
15940 /* If `just_this_one_p' is set, we apparently set must_be_updated_p more
15941 cleverly elsewhere. */
15942 w->must_be_updated_p = true;
15944 if (MINI_WINDOW_P (w))
15946 if (w == XWINDOW (echo_area_window)
15947 && !NILP (echo_area_buffer[0]))
15949 if (update_mode_line)
15950 /* We may have to update a tty frame's menu bar or a
15951 tool-bar. Example `M-x C-h C-h C-g'. */
15952 goto finish_menu_bars;
15953 else
15954 /* We've already displayed the echo area glyphs in this window. */
15955 goto finish_scroll_bars;
15957 else if ((w != XWINDOW (minibuf_window)
15958 || minibuf_level == 0)
15959 /* When buffer is nonempty, redisplay window normally. */
15960 && BUF_Z (XBUFFER (w->contents)) == BUF_BEG (XBUFFER (w->contents))
15961 /* Quail displays non-mini buffers in minibuffer window.
15962 In that case, redisplay the window normally. */
15963 && !NILP (Fmemq (w->contents, Vminibuffer_list)))
15965 /* W is a mini-buffer window, but it's not active, so clear
15966 it. */
15967 int yb = window_text_bottom_y (w);
15968 struct glyph_row *row;
15969 int y;
15971 for (y = 0, row = w->desired_matrix->rows;
15972 y < yb;
15973 y += row->height, ++row)
15974 blank_row (w, row, y);
15975 goto finish_scroll_bars;
15978 clear_glyph_matrix (w->desired_matrix);
15981 /* Otherwise set up data on this window; select its buffer and point
15982 value. */
15983 /* Really select the buffer, for the sake of buffer-local
15984 variables. */
15985 set_buffer_internal_1 (XBUFFER (w->contents));
15987 current_matrix_up_to_date_p
15988 = (w->window_end_valid
15989 && !current_buffer->clip_changed
15990 && !current_buffer->prevent_redisplay_optimizations_p
15991 && !window_outdated (w));
15993 /* Run the window-text-change-functions
15994 if it is possible that the text on the screen has changed
15995 (either due to modification of the text, or any other reason). */
15996 if (!current_matrix_up_to_date_p
15997 && !NILP (Vwindow_text_change_functions))
15999 safe_run_hooks (Qwindow_text_change_functions);
16000 goto restart;
16003 beg_unchanged = BEG_UNCHANGED;
16004 end_unchanged = END_UNCHANGED;
16006 SET_TEXT_POS (opoint, PT, PT_BYTE);
16008 specbind (Qinhibit_point_motion_hooks, Qt);
16010 buffer_unchanged_p
16011 = (w->window_end_valid
16012 && !current_buffer->clip_changed
16013 && !window_outdated (w));
16015 /* When windows_or_buffers_changed is non-zero, we can't rely
16016 on the window end being valid, so set it to zero there. */
16017 if (windows_or_buffers_changed)
16019 /* If window starts on a continuation line, maybe adjust the
16020 window start in case the window's width changed. */
16021 if (XMARKER (w->start)->buffer == current_buffer)
16022 compute_window_start_on_continuation_line (w);
16024 w->window_end_valid = false;
16025 /* If so, we also can't rely on current matrix
16026 and should not fool try_cursor_movement below. */
16027 current_matrix_up_to_date_p = false;
16030 /* Some sanity checks. */
16031 CHECK_WINDOW_END (w);
16032 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
16033 emacs_abort ();
16034 if (BYTEPOS (opoint) < CHARPOS (opoint))
16035 emacs_abort ();
16037 if (mode_line_update_needed (w))
16038 update_mode_line = 1;
16040 /* Point refers normally to the selected window. For any other
16041 window, set up appropriate value. */
16042 if (!EQ (window, selected_window))
16044 ptrdiff_t new_pt = marker_position (w->pointm);
16045 ptrdiff_t new_pt_byte = marker_byte_position (w->pointm);
16047 if (new_pt < BEGV)
16049 new_pt = BEGV;
16050 new_pt_byte = BEGV_BYTE;
16051 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
16053 else if (new_pt > (ZV - 1))
16055 new_pt = ZV;
16056 new_pt_byte = ZV_BYTE;
16057 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
16060 /* We don't use SET_PT so that the point-motion hooks don't run. */
16061 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
16064 /* If any of the character widths specified in the display table
16065 have changed, invalidate the width run cache. It's true that
16066 this may be a bit late to catch such changes, but the rest of
16067 redisplay goes (non-fatally) haywire when the display table is
16068 changed, so why should we worry about doing any better? */
16069 if (current_buffer->width_run_cache
16070 || (current_buffer->base_buffer
16071 && current_buffer->base_buffer->width_run_cache))
16073 struct Lisp_Char_Table *disptab = buffer_display_table ();
16075 if (! disptab_matches_widthtab
16076 (disptab, XVECTOR (BVAR (current_buffer, width_table))))
16078 struct buffer *buf = current_buffer;
16080 if (buf->base_buffer)
16081 buf = buf->base_buffer;
16082 invalidate_region_cache (buf, buf->width_run_cache, BEG, Z);
16083 recompute_width_table (current_buffer, disptab);
16087 /* If window-start is screwed up, choose a new one. */
16088 if (XMARKER (w->start)->buffer != current_buffer)
16089 goto recenter;
16091 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16093 /* If someone specified a new starting point but did not insist,
16094 check whether it can be used. */
16095 if (w->optional_new_start
16096 && CHARPOS (startp) >= BEGV
16097 && CHARPOS (startp) <= ZV)
16099 w->optional_new_start = 0;
16100 start_display (&it, w, startp);
16101 move_it_to (&it, PT, 0, it.last_visible_y, -1,
16102 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
16103 if (IT_CHARPOS (it) == PT)
16104 w->force_start = 1;
16105 /* IT may overshoot PT if text at PT is invisible. */
16106 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
16107 w->force_start = 1;
16110 force_start:
16112 /* Handle case where place to start displaying has been specified,
16113 unless the specified location is outside the accessible range. */
16114 if (w->force_start || window_frozen_p (w))
16116 /* We set this later on if we have to adjust point. */
16117 int new_vpos = -1;
16119 w->force_start = 0;
16120 w->vscroll = 0;
16121 w->window_end_valid = 0;
16123 /* Forget any recorded base line for line number display. */
16124 if (!buffer_unchanged_p)
16125 w->base_line_number = 0;
16127 /* Redisplay the mode line. Select the buffer properly for that.
16128 Also, run the hook window-scroll-functions
16129 because we have scrolled. */
16130 /* Note, we do this after clearing force_start because
16131 if there's an error, it is better to forget about force_start
16132 than to get into an infinite loop calling the hook functions
16133 and having them get more errors. */
16134 if (!update_mode_line
16135 || ! NILP (Vwindow_scroll_functions))
16137 update_mode_line = 1;
16138 w->update_mode_line = 1;
16139 startp = run_window_scroll_functions (window, startp);
16142 if (CHARPOS (startp) < BEGV)
16143 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
16144 else if (CHARPOS (startp) > ZV)
16145 SET_TEXT_POS (startp, ZV, ZV_BYTE);
16147 /* Redisplay, then check if cursor has been set during the
16148 redisplay. Give up if new fonts were loaded. */
16149 /* We used to issue a CHECK_MARGINS argument to try_window here,
16150 but this causes scrolling to fail when point begins inside
16151 the scroll margin (bug#148) -- cyd */
16152 if (!try_window (window, startp, 0))
16154 w->force_start = 1;
16155 clear_glyph_matrix (w->desired_matrix);
16156 goto need_larger_matrices;
16159 if (w->cursor.vpos < 0 && !window_frozen_p (w))
16161 /* If point does not appear, try to move point so it does
16162 appear. The desired matrix has been built above, so we
16163 can use it here. */
16164 new_vpos = window_box_height (w) / 2;
16167 if (!cursor_row_fully_visible_p (w, 0, 0))
16169 /* Point does appear, but on a line partly visible at end of window.
16170 Move it back to a fully-visible line. */
16171 new_vpos = window_box_height (w);
16172 /* But if window_box_height suggests a Y coordinate that is
16173 not less than we already have, that line will clearly not
16174 be fully visible, so give up and scroll the display.
16175 This can happen when the default face uses a font whose
16176 dimensions are different from the frame's default
16177 font. */
16178 if (new_vpos >= w->cursor.y)
16180 w->cursor.vpos = -1;
16181 clear_glyph_matrix (w->desired_matrix);
16182 goto try_to_scroll;
16185 else if (w->cursor.vpos >= 0)
16187 /* Some people insist on not letting point enter the scroll
16188 margin, even though this part handles windows that didn't
16189 scroll at all. */
16190 int window_total_lines
16191 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
16192 int margin = min (scroll_margin, window_total_lines / 4);
16193 int pixel_margin = margin * frame_line_height;
16194 bool header_line = WINDOW_WANTS_HEADER_LINE_P (w);
16196 /* Note: We add an extra FRAME_LINE_HEIGHT, because the loop
16197 below, which finds the row to move point to, advances by
16198 the Y coordinate of the _next_ row, see the definition of
16199 MATRIX_ROW_BOTTOM_Y. */
16200 if (w->cursor.vpos < margin + header_line)
16202 w->cursor.vpos = -1;
16203 clear_glyph_matrix (w->desired_matrix);
16204 goto try_to_scroll;
16206 else
16208 int window_height = window_box_height (w);
16210 if (header_line)
16211 window_height += CURRENT_HEADER_LINE_HEIGHT (w);
16212 if (w->cursor.y >= window_height - pixel_margin)
16214 w->cursor.vpos = -1;
16215 clear_glyph_matrix (w->desired_matrix);
16216 goto try_to_scroll;
16221 /* If we need to move point for either of the above reasons,
16222 now actually do it. */
16223 if (new_vpos >= 0)
16225 struct glyph_row *row;
16227 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
16228 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
16229 ++row;
16231 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
16232 MATRIX_ROW_START_BYTEPOS (row));
16234 if (w != XWINDOW (selected_window))
16235 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
16236 else if (current_buffer == old)
16237 SET_TEXT_POS (lpoint, PT, PT_BYTE);
16239 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
16241 /* If we are highlighting the region, then we just changed
16242 the region, so redisplay to show it. */
16243 /* FIXME: We need to (re)run pre-redisplay-function! */
16244 /* if (markpos_of_region () >= 0)
16246 clear_glyph_matrix (w->desired_matrix);
16247 if (!try_window (window, startp, 0))
16248 goto need_larger_matrices;
16253 #ifdef GLYPH_DEBUG
16254 debug_method_add (w, "forced window start");
16255 #endif
16256 goto done;
16259 /* Handle case where text has not changed, only point, and it has
16260 not moved off the frame, and we are not retrying after hscroll.
16261 (current_matrix_up_to_date_p is nonzero when retrying.) */
16262 if (current_matrix_up_to_date_p
16263 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
16264 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
16266 switch (rc)
16268 case CURSOR_MOVEMENT_SUCCESS:
16269 used_current_matrix_p = 1;
16270 goto done;
16272 case CURSOR_MOVEMENT_MUST_SCROLL:
16273 goto try_to_scroll;
16275 default:
16276 emacs_abort ();
16279 /* If current starting point was originally the beginning of a line
16280 but no longer is, find a new starting point. */
16281 else if (w->start_at_line_beg
16282 && !(CHARPOS (startp) <= BEGV
16283 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
16285 #ifdef GLYPH_DEBUG
16286 debug_method_add (w, "recenter 1");
16287 #endif
16288 goto recenter;
16291 /* Try scrolling with try_window_id. Value is > 0 if update has
16292 been done, it is -1 if we know that the same window start will
16293 not work. It is 0 if unsuccessful for some other reason. */
16294 else if ((tem = try_window_id (w)) != 0)
16296 #ifdef GLYPH_DEBUG
16297 debug_method_add (w, "try_window_id %d", tem);
16298 #endif
16300 if (f->fonts_changed)
16301 goto need_larger_matrices;
16302 if (tem > 0)
16303 goto done;
16305 /* Otherwise try_window_id has returned -1 which means that we
16306 don't want the alternative below this comment to execute. */
16308 else if (CHARPOS (startp) >= BEGV
16309 && CHARPOS (startp) <= ZV
16310 && PT >= CHARPOS (startp)
16311 && (CHARPOS (startp) < ZV
16312 /* Avoid starting at end of buffer. */
16313 || CHARPOS (startp) == BEGV
16314 || !window_outdated (w)))
16316 int d1, d2, d3, d4, d5, d6;
16318 /* If first window line is a continuation line, and window start
16319 is inside the modified region, but the first change is before
16320 current window start, we must select a new window start.
16322 However, if this is the result of a down-mouse event (e.g. by
16323 extending the mouse-drag-overlay), we don't want to select a
16324 new window start, since that would change the position under
16325 the mouse, resulting in an unwanted mouse-movement rather
16326 than a simple mouse-click. */
16327 if (!w->start_at_line_beg
16328 && NILP (do_mouse_tracking)
16329 && CHARPOS (startp) > BEGV
16330 && CHARPOS (startp) > BEG + beg_unchanged
16331 && CHARPOS (startp) <= Z - end_unchanged
16332 /* Even if w->start_at_line_beg is nil, a new window may
16333 start at a line_beg, since that's how set_buffer_window
16334 sets it. So, we need to check the return value of
16335 compute_window_start_on_continuation_line. (See also
16336 bug#197). */
16337 && XMARKER (w->start)->buffer == current_buffer
16338 && compute_window_start_on_continuation_line (w)
16339 /* It doesn't make sense to force the window start like we
16340 do at label force_start if it is already known that point
16341 will not be visible in the resulting window, because
16342 doing so will move point from its correct position
16343 instead of scrolling the window to bring point into view.
16344 See bug#9324. */
16345 && pos_visible_p (w, PT, &d1, &d2, &d3, &d4, &d5, &d6))
16347 w->force_start = 1;
16348 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16349 goto force_start;
16352 #ifdef GLYPH_DEBUG
16353 debug_method_add (w, "same window start");
16354 #endif
16356 /* Try to redisplay starting at same place as before.
16357 If point has not moved off frame, accept the results. */
16358 if (!current_matrix_up_to_date_p
16359 /* Don't use try_window_reusing_current_matrix in this case
16360 because a window scroll function can have changed the
16361 buffer. */
16362 || !NILP (Vwindow_scroll_functions)
16363 || MINI_WINDOW_P (w)
16364 || !(used_current_matrix_p
16365 = try_window_reusing_current_matrix (w)))
16367 IF_DEBUG (debug_method_add (w, "1"));
16368 if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
16369 /* -1 means we need to scroll.
16370 0 means we need new matrices, but fonts_changed
16371 is set in that case, so we will detect it below. */
16372 goto try_to_scroll;
16375 if (f->fonts_changed)
16376 goto need_larger_matrices;
16378 if (w->cursor.vpos >= 0)
16380 if (!just_this_one_p
16381 || current_buffer->clip_changed
16382 || BEG_UNCHANGED < CHARPOS (startp))
16383 /* Forget any recorded base line for line number display. */
16384 w->base_line_number = 0;
16386 if (!cursor_row_fully_visible_p (w, 1, 0))
16388 clear_glyph_matrix (w->desired_matrix);
16389 last_line_misfit = 1;
16391 /* Drop through and scroll. */
16392 else
16393 goto done;
16395 else
16396 clear_glyph_matrix (w->desired_matrix);
16399 try_to_scroll:
16401 /* Redisplay the mode line. Select the buffer properly for that. */
16402 if (!update_mode_line)
16404 update_mode_line = 1;
16405 w->update_mode_line = 1;
16408 /* Try to scroll by specified few lines. */
16409 if ((scroll_conservatively
16410 || emacs_scroll_step
16411 || temp_scroll_step
16412 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively))
16413 || NUMBERP (BVAR (current_buffer, scroll_down_aggressively)))
16414 && CHARPOS (startp) >= BEGV
16415 && CHARPOS (startp) <= ZV)
16417 /* The function returns -1 if new fonts were loaded, 1 if
16418 successful, 0 if not successful. */
16419 int ss = try_scrolling (window, just_this_one_p,
16420 scroll_conservatively,
16421 emacs_scroll_step,
16422 temp_scroll_step, last_line_misfit);
16423 switch (ss)
16425 case SCROLLING_SUCCESS:
16426 goto done;
16428 case SCROLLING_NEED_LARGER_MATRICES:
16429 goto need_larger_matrices;
16431 case SCROLLING_FAILED:
16432 break;
16434 default:
16435 emacs_abort ();
16439 /* Finally, just choose a place to start which positions point
16440 according to user preferences. */
16442 recenter:
16444 #ifdef GLYPH_DEBUG
16445 debug_method_add (w, "recenter");
16446 #endif
16448 /* Forget any previously recorded base line for line number display. */
16449 if (!buffer_unchanged_p)
16450 w->base_line_number = 0;
16452 /* Determine the window start relative to point. */
16453 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
16454 it.current_y = it.last_visible_y;
16455 if (centering_position < 0)
16457 int window_total_lines
16458 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
16459 int margin =
16460 scroll_margin > 0
16461 ? min (scroll_margin, window_total_lines / 4)
16462 : 0;
16463 ptrdiff_t margin_pos = CHARPOS (startp);
16464 Lisp_Object aggressive;
16465 int scrolling_up;
16467 /* If there is a scroll margin at the top of the window, find
16468 its character position. */
16469 if (margin
16470 /* Cannot call start_display if startp is not in the
16471 accessible region of the buffer. This can happen when we
16472 have just switched to a different buffer and/or changed
16473 its restriction. In that case, startp is initialized to
16474 the character position 1 (BEGV) because we did not yet
16475 have chance to display the buffer even once. */
16476 && BEGV <= CHARPOS (startp) && CHARPOS (startp) <= ZV)
16478 struct it it1;
16479 void *it1data = NULL;
16481 SAVE_IT (it1, it, it1data);
16482 start_display (&it1, w, startp);
16483 move_it_vertically (&it1, margin * frame_line_height);
16484 margin_pos = IT_CHARPOS (it1);
16485 RESTORE_IT (&it, &it, it1data);
16487 scrolling_up = PT > margin_pos;
16488 aggressive =
16489 scrolling_up
16490 ? BVAR (current_buffer, scroll_up_aggressively)
16491 : BVAR (current_buffer, scroll_down_aggressively);
16493 if (!MINI_WINDOW_P (w)
16494 && (scroll_conservatively > SCROLL_LIMIT || NUMBERP (aggressive)))
16496 int pt_offset = 0;
16498 /* Setting scroll-conservatively overrides
16499 scroll-*-aggressively. */
16500 if (!scroll_conservatively && NUMBERP (aggressive))
16502 double float_amount = XFLOATINT (aggressive);
16504 pt_offset = float_amount * WINDOW_BOX_TEXT_HEIGHT (w);
16505 if (pt_offset == 0 && float_amount > 0)
16506 pt_offset = 1;
16507 if (pt_offset && margin > 0)
16508 margin -= 1;
16510 /* Compute how much to move the window start backward from
16511 point so that point will be displayed where the user
16512 wants it. */
16513 if (scrolling_up)
16515 centering_position = it.last_visible_y;
16516 if (pt_offset)
16517 centering_position -= pt_offset;
16518 centering_position -=
16519 frame_line_height * (1 + margin + (last_line_misfit != 0))
16520 + WINDOW_HEADER_LINE_HEIGHT (w);
16521 /* Don't let point enter the scroll margin near top of
16522 the window. */
16523 if (centering_position < margin * frame_line_height)
16524 centering_position = margin * frame_line_height;
16526 else
16527 centering_position = margin * frame_line_height + pt_offset;
16529 else
16530 /* Set the window start half the height of the window backward
16531 from point. */
16532 centering_position = window_box_height (w) / 2;
16534 move_it_vertically_backward (&it, centering_position);
16536 eassert (IT_CHARPOS (it) >= BEGV);
16538 /* The function move_it_vertically_backward may move over more
16539 than the specified y-distance. If it->w is small, e.g. a
16540 mini-buffer window, we may end up in front of the window's
16541 display area. Start displaying at the start of the line
16542 containing PT in this case. */
16543 if (it.current_y <= 0)
16545 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
16546 move_it_vertically_backward (&it, 0);
16547 it.current_y = 0;
16550 it.current_x = it.hpos = 0;
16552 /* Set the window start position here explicitly, to avoid an
16553 infinite loop in case the functions in window-scroll-functions
16554 get errors. */
16555 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
16557 /* Run scroll hooks. */
16558 startp = run_window_scroll_functions (window, it.current.pos);
16560 /* Redisplay the window. */
16561 if (!current_matrix_up_to_date_p
16562 || windows_or_buffers_changed
16563 || f->cursor_type_changed
16564 /* Don't use try_window_reusing_current_matrix in this case
16565 because it can have changed the buffer. */
16566 || !NILP (Vwindow_scroll_functions)
16567 || !just_this_one_p
16568 || MINI_WINDOW_P (w)
16569 || !(used_current_matrix_p
16570 = try_window_reusing_current_matrix (w)))
16571 try_window (window, startp, 0);
16573 /* If new fonts have been loaded (due to fontsets), give up. We
16574 have to start a new redisplay since we need to re-adjust glyph
16575 matrices. */
16576 if (f->fonts_changed)
16577 goto need_larger_matrices;
16579 /* If cursor did not appear assume that the middle of the window is
16580 in the first line of the window. Do it again with the next line.
16581 (Imagine a window of height 100, displaying two lines of height
16582 60. Moving back 50 from it->last_visible_y will end in the first
16583 line.) */
16584 if (w->cursor.vpos < 0)
16586 if (w->window_end_valid && PT >= Z - w->window_end_pos)
16588 clear_glyph_matrix (w->desired_matrix);
16589 move_it_by_lines (&it, 1);
16590 try_window (window, it.current.pos, 0);
16592 else if (PT < IT_CHARPOS (it))
16594 clear_glyph_matrix (w->desired_matrix);
16595 move_it_by_lines (&it, -1);
16596 try_window (window, it.current.pos, 0);
16598 else
16600 /* Not much we can do about it. */
16604 /* Consider the following case: Window starts at BEGV, there is
16605 invisible, intangible text at BEGV, so that display starts at
16606 some point START > BEGV. It can happen that we are called with
16607 PT somewhere between BEGV and START. Try to handle that case,
16608 and similar ones. */
16609 if (w->cursor.vpos < 0)
16611 /* First, try locating the proper glyph row for PT. */
16612 struct glyph_row *row =
16613 row_containing_pos (w, PT, w->current_matrix->rows, NULL, 0);
16615 /* Sometimes point is at the beginning of invisible text that is
16616 before the 1st character displayed in the row. In that case,
16617 row_containing_pos fails to find the row, because no glyphs
16618 with appropriate buffer positions are present in the row.
16619 Therefore, we next try to find the row which shows the 1st
16620 position after the invisible text. */
16621 if (!row)
16623 Lisp_Object val =
16624 get_char_property_and_overlay (make_number (PT), Qinvisible,
16625 Qnil, NULL);
16627 if (TEXT_PROP_MEANS_INVISIBLE (val))
16629 ptrdiff_t alt_pos;
16630 Lisp_Object invis_end =
16631 Fnext_single_char_property_change (make_number (PT), Qinvisible,
16632 Qnil, Qnil);
16634 if (NATNUMP (invis_end))
16635 alt_pos = XFASTINT (invis_end);
16636 else
16637 alt_pos = ZV;
16638 row = row_containing_pos (w, alt_pos, w->current_matrix->rows,
16639 NULL, 0);
16642 /* Finally, fall back on the first row of the window after the
16643 header line (if any). This is slightly better than not
16644 displaying the cursor at all. */
16645 if (!row)
16647 row = w->current_matrix->rows;
16648 if (row->mode_line_p)
16649 ++row;
16651 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
16654 if (!cursor_row_fully_visible_p (w, 0, 0))
16656 /* If vscroll is enabled, disable it and try again. */
16657 if (w->vscroll)
16659 w->vscroll = 0;
16660 clear_glyph_matrix (w->desired_matrix);
16661 goto recenter;
16664 /* Users who set scroll-conservatively to a large number want
16665 point just above/below the scroll margin. If we ended up
16666 with point's row partially visible, move the window start to
16667 make that row fully visible and out of the margin. */
16668 if (scroll_conservatively > SCROLL_LIMIT)
16670 int window_total_lines
16671 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) * frame_line_height;
16672 int margin =
16673 scroll_margin > 0
16674 ? min (scroll_margin, window_total_lines / 4)
16675 : 0;
16676 int move_down = w->cursor.vpos >= window_total_lines / 2;
16678 move_it_by_lines (&it, move_down ? margin + 1 : -(margin + 1));
16679 clear_glyph_matrix (w->desired_matrix);
16680 if (1 == try_window (window, it.current.pos,
16681 TRY_WINDOW_CHECK_MARGINS))
16682 goto done;
16685 /* If centering point failed to make the whole line visible,
16686 put point at the top instead. That has to make the whole line
16687 visible, if it can be done. */
16688 if (centering_position == 0)
16689 goto done;
16691 clear_glyph_matrix (w->desired_matrix);
16692 centering_position = 0;
16693 goto recenter;
16696 done:
16698 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16699 w->start_at_line_beg = (CHARPOS (startp) == BEGV
16700 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n');
16702 /* Display the mode line, if we must. */
16703 if ((update_mode_line
16704 /* If window not full width, must redo its mode line
16705 if (a) the window to its side is being redone and
16706 (b) we do a frame-based redisplay. This is a consequence
16707 of how inverted lines are drawn in frame-based redisplay. */
16708 || (!just_this_one_p
16709 && !FRAME_WINDOW_P (f)
16710 && !WINDOW_FULL_WIDTH_P (w))
16711 /* Line number to display. */
16712 || w->base_line_pos > 0
16713 /* Column number is displayed and different from the one displayed. */
16714 || (w->column_number_displayed != -1
16715 && (w->column_number_displayed != current_column ())))
16716 /* This means that the window has a mode line. */
16717 && (WINDOW_WANTS_MODELINE_P (w)
16718 || WINDOW_WANTS_HEADER_LINE_P (w)))
16721 display_mode_lines (w);
16723 /* If mode line height has changed, arrange for a thorough
16724 immediate redisplay using the correct mode line height. */
16725 if (WINDOW_WANTS_MODELINE_P (w)
16726 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
16728 f->fonts_changed = 1;
16729 w->mode_line_height = -1;
16730 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
16731 = DESIRED_MODE_LINE_HEIGHT (w);
16734 /* If header line height has changed, arrange for a thorough
16735 immediate redisplay using the correct header line height. */
16736 if (WINDOW_WANTS_HEADER_LINE_P (w)
16737 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
16739 f->fonts_changed = 1;
16740 w->header_line_height = -1;
16741 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
16742 = DESIRED_HEADER_LINE_HEIGHT (w);
16745 if (f->fonts_changed)
16746 goto need_larger_matrices;
16749 if (!line_number_displayed && w->base_line_pos != -1)
16751 w->base_line_pos = 0;
16752 w->base_line_number = 0;
16755 finish_menu_bars:
16757 /* When we reach a frame's selected window, redo the frame's menu bar. */
16758 if (update_mode_line
16759 && EQ (FRAME_SELECTED_WINDOW (f), window))
16761 int redisplay_menu_p = 0;
16763 if (FRAME_WINDOW_P (f))
16765 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
16766 || defined (HAVE_NS) || defined (USE_GTK)
16767 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
16768 #else
16769 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
16770 #endif
16772 else
16773 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
16775 if (redisplay_menu_p)
16776 display_menu_bar (w);
16778 #ifdef HAVE_WINDOW_SYSTEM
16779 if (FRAME_WINDOW_P (f))
16781 #if defined (USE_GTK) || defined (HAVE_NS)
16782 if (FRAME_EXTERNAL_TOOL_BAR (f))
16783 redisplay_tool_bar (f);
16784 #else
16785 if (WINDOWP (f->tool_bar_window)
16786 && (FRAME_TOOL_BAR_LINES (f) > 0
16787 || !NILP (Vauto_resize_tool_bars))
16788 && redisplay_tool_bar (f))
16789 ignore_mouse_drag_p = 1;
16790 #endif
16792 #endif
16795 #ifdef HAVE_WINDOW_SYSTEM
16796 if (FRAME_WINDOW_P (f)
16797 && update_window_fringes (w, (just_this_one_p
16798 || (!used_current_matrix_p && !overlay_arrow_seen)
16799 || w->pseudo_window_p)))
16801 update_begin (f);
16802 block_input ();
16803 if (draw_window_fringes (w, 1))
16805 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
16806 x_draw_right_divider (w);
16807 else
16808 x_draw_vertical_border (w);
16810 unblock_input ();
16811 update_end (f);
16814 if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
16815 x_draw_bottom_divider (w);
16816 #endif /* HAVE_WINDOW_SYSTEM */
16818 /* We go to this label, with fonts_changed set, if it is
16819 necessary to try again using larger glyph matrices.
16820 We have to redeem the scroll bar even in this case,
16821 because the loop in redisplay_internal expects that. */
16822 need_larger_matrices:
16824 finish_scroll_bars:
16826 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w) || WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w))
16828 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
16829 /* Set the thumb's position and size. */
16830 set_vertical_scroll_bar (w);
16832 if (WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w))
16833 /* Set the thumb's position and size. */
16834 set_horizontal_scroll_bar (w);
16836 /* Note that we actually used the scroll bar attached to this
16837 window, so it shouldn't be deleted at the end of redisplay. */
16838 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
16839 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
16842 /* Restore current_buffer and value of point in it. The window
16843 update may have changed the buffer, so first make sure `opoint'
16844 is still valid (Bug#6177). */
16845 if (CHARPOS (opoint) < BEGV)
16846 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
16847 else if (CHARPOS (opoint) > ZV)
16848 TEMP_SET_PT_BOTH (Z, Z_BYTE);
16849 else
16850 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
16852 set_buffer_internal_1 (old);
16853 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
16854 shorter. This can be caused by log truncation in *Messages*. */
16855 if (CHARPOS (lpoint) <= ZV)
16856 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
16858 unbind_to (count, Qnil);
16862 /* Build the complete desired matrix of WINDOW with a window start
16863 buffer position POS.
16865 Value is 1 if successful. It is zero if fonts were loaded during
16866 redisplay which makes re-adjusting glyph matrices necessary, and -1
16867 if point would appear in the scroll margins.
16868 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
16869 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
16870 set in FLAGS.) */
16873 try_window (Lisp_Object window, struct text_pos pos, int flags)
16875 struct window *w = XWINDOW (window);
16876 struct it it;
16877 struct glyph_row *last_text_row = NULL;
16878 struct frame *f = XFRAME (w->frame);
16879 int frame_line_height = default_line_pixel_height (w);
16881 /* Make POS the new window start. */
16882 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
16884 /* Mark cursor position as unknown. No overlay arrow seen. */
16885 w->cursor.vpos = -1;
16886 overlay_arrow_seen = 0;
16888 /* Initialize iterator and info to start at POS. */
16889 start_display (&it, w, pos);
16891 /* Display all lines of W. */
16892 while (it.current_y < it.last_visible_y)
16894 if (display_line (&it))
16895 last_text_row = it.glyph_row - 1;
16896 if (f->fonts_changed && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
16897 return 0;
16900 /* Don't let the cursor end in the scroll margins. */
16901 if ((flags & TRY_WINDOW_CHECK_MARGINS)
16902 && !MINI_WINDOW_P (w))
16904 int this_scroll_margin;
16905 int window_total_lines
16906 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
16908 if (scroll_margin > 0)
16910 this_scroll_margin = min (scroll_margin, window_total_lines / 4);
16911 this_scroll_margin *= frame_line_height;
16913 else
16914 this_scroll_margin = 0;
16916 if ((w->cursor.y >= 0 /* not vscrolled */
16917 && w->cursor.y < this_scroll_margin
16918 && CHARPOS (pos) > BEGV
16919 && IT_CHARPOS (it) < ZV)
16920 /* rms: considering make_cursor_line_fully_visible_p here
16921 seems to give wrong results. We don't want to recenter
16922 when the last line is partly visible, we want to allow
16923 that case to be handled in the usual way. */
16924 || w->cursor.y > it.last_visible_y - this_scroll_margin - 1)
16926 w->cursor.vpos = -1;
16927 clear_glyph_matrix (w->desired_matrix);
16928 return -1;
16932 /* If bottom moved off end of frame, change mode line percentage. */
16933 if (w->window_end_pos <= 0 && Z != IT_CHARPOS (it))
16934 w->update_mode_line = 1;
16936 /* Set window_end_pos to the offset of the last character displayed
16937 on the window from the end of current_buffer. Set
16938 window_end_vpos to its row number. */
16939 if (last_text_row)
16941 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
16942 adjust_window_ends (w, last_text_row, 0);
16943 eassert
16944 (MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->desired_matrix,
16945 w->window_end_vpos)));
16947 else
16949 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
16950 w->window_end_pos = Z - ZV;
16951 w->window_end_vpos = 0;
16954 /* But that is not valid info until redisplay finishes. */
16955 w->window_end_valid = 0;
16956 return 1;
16961 /************************************************************************
16962 Window redisplay reusing current matrix when buffer has not changed
16963 ************************************************************************/
16965 /* Try redisplay of window W showing an unchanged buffer with a
16966 different window start than the last time it was displayed by
16967 reusing its current matrix. Value is non-zero if successful.
16968 W->start is the new window start. */
16970 static int
16971 try_window_reusing_current_matrix (struct window *w)
16973 struct frame *f = XFRAME (w->frame);
16974 struct glyph_row *bottom_row;
16975 struct it it;
16976 struct run run;
16977 struct text_pos start, new_start;
16978 int nrows_scrolled, i;
16979 struct glyph_row *last_text_row;
16980 struct glyph_row *last_reused_text_row;
16981 struct glyph_row *start_row;
16982 int start_vpos, min_y, max_y;
16984 #ifdef GLYPH_DEBUG
16985 if (inhibit_try_window_reusing)
16986 return 0;
16987 #endif
16989 if (/* This function doesn't handle terminal frames. */
16990 !FRAME_WINDOW_P (f)
16991 /* Don't try to reuse the display if windows have been split
16992 or such. */
16993 || windows_or_buffers_changed
16994 || f->cursor_type_changed)
16995 return 0;
16997 /* Can't do this if showing trailing whitespace. */
16998 if (!NILP (Vshow_trailing_whitespace))
16999 return 0;
17001 /* If top-line visibility has changed, give up. */
17002 if (WINDOW_WANTS_HEADER_LINE_P (w)
17003 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
17004 return 0;
17006 /* Give up if old or new display is scrolled vertically. We could
17007 make this function handle this, but right now it doesn't. */
17008 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
17009 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
17010 return 0;
17012 /* The variable new_start now holds the new window start. The old
17013 start `start' can be determined from the current matrix. */
17014 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
17015 start = start_row->minpos;
17016 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
17018 /* Clear the desired matrix for the display below. */
17019 clear_glyph_matrix (w->desired_matrix);
17021 if (CHARPOS (new_start) <= CHARPOS (start))
17023 /* Don't use this method if the display starts with an ellipsis
17024 displayed for invisible text. It's not easy to handle that case
17025 below, and it's certainly not worth the effort since this is
17026 not a frequent case. */
17027 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
17028 return 0;
17030 IF_DEBUG (debug_method_add (w, "twu1"));
17032 /* Display up to a row that can be reused. The variable
17033 last_text_row is set to the last row displayed that displays
17034 text. Note that it.vpos == 0 if or if not there is a
17035 header-line; it's not the same as the MATRIX_ROW_VPOS! */
17036 start_display (&it, w, new_start);
17037 w->cursor.vpos = -1;
17038 last_text_row = last_reused_text_row = NULL;
17040 while (it.current_y < it.last_visible_y && !f->fonts_changed)
17042 /* If we have reached into the characters in the START row,
17043 that means the line boundaries have changed. So we
17044 can't start copying with the row START. Maybe it will
17045 work to start copying with the following row. */
17046 while (IT_CHARPOS (it) > CHARPOS (start))
17048 /* Advance to the next row as the "start". */
17049 start_row++;
17050 start = start_row->minpos;
17051 /* If there are no more rows to try, or just one, give up. */
17052 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
17053 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
17054 || CHARPOS (start) == ZV)
17056 clear_glyph_matrix (w->desired_matrix);
17057 return 0;
17060 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
17062 /* If we have reached alignment, we can copy the rest of the
17063 rows. */
17064 if (IT_CHARPOS (it) == CHARPOS (start)
17065 /* Don't accept "alignment" inside a display vector,
17066 since start_row could have started in the middle of
17067 that same display vector (thus their character
17068 positions match), and we have no way of telling if
17069 that is the case. */
17070 && it.current.dpvec_index < 0)
17071 break;
17073 if (display_line (&it))
17074 last_text_row = it.glyph_row - 1;
17078 /* A value of current_y < last_visible_y means that we stopped
17079 at the previous window start, which in turn means that we
17080 have at least one reusable row. */
17081 if (it.current_y < it.last_visible_y)
17083 struct glyph_row *row;
17085 /* IT.vpos always starts from 0; it counts text lines. */
17086 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
17088 /* Find PT if not already found in the lines displayed. */
17089 if (w->cursor.vpos < 0)
17091 int dy = it.current_y - start_row->y;
17093 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
17094 row = row_containing_pos (w, PT, row, NULL, dy);
17095 if (row)
17096 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
17097 dy, nrows_scrolled);
17098 else
17100 clear_glyph_matrix (w->desired_matrix);
17101 return 0;
17105 /* Scroll the display. Do it before the current matrix is
17106 changed. The problem here is that update has not yet
17107 run, i.e. part of the current matrix is not up to date.
17108 scroll_run_hook will clear the cursor, and use the
17109 current matrix to get the height of the row the cursor is
17110 in. */
17111 run.current_y = start_row->y;
17112 run.desired_y = it.current_y;
17113 run.height = it.last_visible_y - it.current_y;
17115 if (run.height > 0 && run.current_y != run.desired_y)
17117 update_begin (f);
17118 FRAME_RIF (f)->update_window_begin_hook (w);
17119 FRAME_RIF (f)->clear_window_mouse_face (w);
17120 FRAME_RIF (f)->scroll_run_hook (w, &run);
17121 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
17122 update_end (f);
17125 /* Shift current matrix down by nrows_scrolled lines. */
17126 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
17127 rotate_matrix (w->current_matrix,
17128 start_vpos,
17129 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
17130 nrows_scrolled);
17132 /* Disable lines that must be updated. */
17133 for (i = 0; i < nrows_scrolled; ++i)
17134 (start_row + i)->enabled_p = false;
17136 /* Re-compute Y positions. */
17137 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
17138 max_y = it.last_visible_y;
17139 for (row = start_row + nrows_scrolled;
17140 row < bottom_row;
17141 ++row)
17143 row->y = it.current_y;
17144 row->visible_height = row->height;
17146 if (row->y < min_y)
17147 row->visible_height -= min_y - row->y;
17148 if (row->y + row->height > max_y)
17149 row->visible_height -= row->y + row->height - max_y;
17150 if (row->fringe_bitmap_periodic_p)
17151 row->redraw_fringe_bitmaps_p = 1;
17153 it.current_y += row->height;
17155 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
17156 last_reused_text_row = row;
17157 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
17158 break;
17161 /* Disable lines in the current matrix which are now
17162 below the window. */
17163 for (++row; row < bottom_row; ++row)
17164 row->enabled_p = row->mode_line_p = 0;
17167 /* Update window_end_pos etc.; last_reused_text_row is the last
17168 reused row from the current matrix containing text, if any.
17169 The value of last_text_row is the last displayed line
17170 containing text. */
17171 if (last_reused_text_row)
17172 adjust_window_ends (w, last_reused_text_row, 1);
17173 else if (last_text_row)
17174 adjust_window_ends (w, last_text_row, 0);
17175 else
17177 /* This window must be completely empty. */
17178 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
17179 w->window_end_pos = Z - ZV;
17180 w->window_end_vpos = 0;
17182 w->window_end_valid = 0;
17184 /* Update hint: don't try scrolling again in update_window. */
17185 w->desired_matrix->no_scrolling_p = 1;
17187 #ifdef GLYPH_DEBUG
17188 debug_method_add (w, "try_window_reusing_current_matrix 1");
17189 #endif
17190 return 1;
17192 else if (CHARPOS (new_start) > CHARPOS (start))
17194 struct glyph_row *pt_row, *row;
17195 struct glyph_row *first_reusable_row;
17196 struct glyph_row *first_row_to_display;
17197 int dy;
17198 int yb = window_text_bottom_y (w);
17200 /* Find the row starting at new_start, if there is one. Don't
17201 reuse a partially visible line at the end. */
17202 first_reusable_row = start_row;
17203 while (first_reusable_row->enabled_p
17204 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
17205 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
17206 < CHARPOS (new_start)))
17207 ++first_reusable_row;
17209 /* Give up if there is no row to reuse. */
17210 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
17211 || !first_reusable_row->enabled_p
17212 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
17213 != CHARPOS (new_start)))
17214 return 0;
17216 /* We can reuse fully visible rows beginning with
17217 first_reusable_row to the end of the window. Set
17218 first_row_to_display to the first row that cannot be reused.
17219 Set pt_row to the row containing point, if there is any. */
17220 pt_row = NULL;
17221 for (first_row_to_display = first_reusable_row;
17222 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
17223 ++first_row_to_display)
17225 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
17226 && (PT < MATRIX_ROW_END_CHARPOS (first_row_to_display)
17227 || (PT == MATRIX_ROW_END_CHARPOS (first_row_to_display)
17228 && first_row_to_display->ends_at_zv_p
17229 && pt_row == NULL)))
17230 pt_row = first_row_to_display;
17233 /* Start displaying at the start of first_row_to_display. */
17234 eassert (first_row_to_display->y < yb);
17235 init_to_row_start (&it, w, first_row_to_display);
17237 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
17238 - start_vpos);
17239 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
17240 - nrows_scrolled);
17241 it.current_y = (first_row_to_display->y - first_reusable_row->y
17242 + WINDOW_HEADER_LINE_HEIGHT (w));
17244 /* Display lines beginning with first_row_to_display in the
17245 desired matrix. Set last_text_row to the last row displayed
17246 that displays text. */
17247 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
17248 if (pt_row == NULL)
17249 w->cursor.vpos = -1;
17250 last_text_row = NULL;
17251 while (it.current_y < it.last_visible_y && !f->fonts_changed)
17252 if (display_line (&it))
17253 last_text_row = it.glyph_row - 1;
17255 /* If point is in a reused row, adjust y and vpos of the cursor
17256 position. */
17257 if (pt_row)
17259 w->cursor.vpos -= nrows_scrolled;
17260 w->cursor.y -= first_reusable_row->y - start_row->y;
17263 /* Give up if point isn't in a row displayed or reused. (This
17264 also handles the case where w->cursor.vpos < nrows_scrolled
17265 after the calls to display_line, which can happen with scroll
17266 margins. See bug#1295.) */
17267 if (w->cursor.vpos < 0)
17269 clear_glyph_matrix (w->desired_matrix);
17270 return 0;
17273 /* Scroll the display. */
17274 run.current_y = first_reusable_row->y;
17275 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
17276 run.height = it.last_visible_y - run.current_y;
17277 dy = run.current_y - run.desired_y;
17279 if (run.height)
17281 update_begin (f);
17282 FRAME_RIF (f)->update_window_begin_hook (w);
17283 FRAME_RIF (f)->clear_window_mouse_face (w);
17284 FRAME_RIF (f)->scroll_run_hook (w, &run);
17285 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
17286 update_end (f);
17289 /* Adjust Y positions of reused rows. */
17290 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
17291 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
17292 max_y = it.last_visible_y;
17293 for (row = first_reusable_row; row < first_row_to_display; ++row)
17295 row->y -= dy;
17296 row->visible_height = row->height;
17297 if (row->y < min_y)
17298 row->visible_height -= min_y - row->y;
17299 if (row->y + row->height > max_y)
17300 row->visible_height -= row->y + row->height - max_y;
17301 if (row->fringe_bitmap_periodic_p)
17302 row->redraw_fringe_bitmaps_p = 1;
17305 /* Scroll the current matrix. */
17306 eassert (nrows_scrolled > 0);
17307 rotate_matrix (w->current_matrix,
17308 start_vpos,
17309 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
17310 -nrows_scrolled);
17312 /* Disable rows not reused. */
17313 for (row -= nrows_scrolled; row < bottom_row; ++row)
17314 row->enabled_p = false;
17316 /* Point may have moved to a different line, so we cannot assume that
17317 the previous cursor position is valid; locate the correct row. */
17318 if (pt_row)
17320 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
17321 row < bottom_row
17322 && PT >= MATRIX_ROW_END_CHARPOS (row)
17323 && !row->ends_at_zv_p;
17324 row++)
17326 w->cursor.vpos++;
17327 w->cursor.y = row->y;
17329 if (row < bottom_row)
17331 /* Can't simply scan the row for point with
17332 bidi-reordered glyph rows. Let set_cursor_from_row
17333 figure out where to put the cursor, and if it fails,
17334 give up. */
17335 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
17337 if (!set_cursor_from_row (w, row, w->current_matrix,
17338 0, 0, 0, 0))
17340 clear_glyph_matrix (w->desired_matrix);
17341 return 0;
17344 else
17346 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
17347 struct glyph *end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
17349 for (; glyph < end
17350 && (!BUFFERP (glyph->object)
17351 || glyph->charpos < PT);
17352 glyph++)
17354 w->cursor.hpos++;
17355 w->cursor.x += glyph->pixel_width;
17361 /* Adjust window end. A null value of last_text_row means that
17362 the window end is in reused rows which in turn means that
17363 only its vpos can have changed. */
17364 if (last_text_row)
17365 adjust_window_ends (w, last_text_row, 0);
17366 else
17367 w->window_end_vpos -= nrows_scrolled;
17369 w->window_end_valid = 0;
17370 w->desired_matrix->no_scrolling_p = 1;
17372 #ifdef GLYPH_DEBUG
17373 debug_method_add (w, "try_window_reusing_current_matrix 2");
17374 #endif
17375 return 1;
17378 return 0;
17383 /************************************************************************
17384 Window redisplay reusing current matrix when buffer has changed
17385 ************************************************************************/
17387 static struct glyph_row *find_last_unchanged_at_beg_row (struct window *);
17388 static struct glyph_row *find_first_unchanged_at_end_row (struct window *,
17389 ptrdiff_t *, ptrdiff_t *);
17390 static struct glyph_row *
17391 find_last_row_displaying_text (struct glyph_matrix *, struct it *,
17392 struct glyph_row *);
17395 /* Return the last row in MATRIX displaying text. If row START is
17396 non-null, start searching with that row. IT gives the dimensions
17397 of the display. Value is null if matrix is empty; otherwise it is
17398 a pointer to the row found. */
17400 static struct glyph_row *
17401 find_last_row_displaying_text (struct glyph_matrix *matrix, struct it *it,
17402 struct glyph_row *start)
17404 struct glyph_row *row, *row_found;
17406 /* Set row_found to the last row in IT->w's current matrix
17407 displaying text. The loop looks funny but think of partially
17408 visible lines. */
17409 row_found = NULL;
17410 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
17411 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
17413 eassert (row->enabled_p);
17414 row_found = row;
17415 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
17416 break;
17417 ++row;
17420 return row_found;
17424 /* Return the last row in the current matrix of W that is not affected
17425 by changes at the start of current_buffer that occurred since W's
17426 current matrix was built. Value is null if no such row exists.
17428 BEG_UNCHANGED us the number of characters unchanged at the start of
17429 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
17430 first changed character in current_buffer. Characters at positions <
17431 BEG + BEG_UNCHANGED are at the same buffer positions as they were
17432 when the current matrix was built. */
17434 static struct glyph_row *
17435 find_last_unchanged_at_beg_row (struct window *w)
17437 ptrdiff_t first_changed_pos = BEG + BEG_UNCHANGED;
17438 struct glyph_row *row;
17439 struct glyph_row *row_found = NULL;
17440 int yb = window_text_bottom_y (w);
17442 /* Find the last row displaying unchanged text. */
17443 for (row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
17444 MATRIX_ROW_DISPLAYS_TEXT_P (row)
17445 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos;
17446 ++row)
17448 if (/* If row ends before first_changed_pos, it is unchanged,
17449 except in some case. */
17450 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
17451 /* When row ends in ZV and we write at ZV it is not
17452 unchanged. */
17453 && !row->ends_at_zv_p
17454 /* When first_changed_pos is the end of a continued line,
17455 row is not unchanged because it may be no longer
17456 continued. */
17457 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
17458 && (row->continued_p
17459 || row->exact_window_width_line_p))
17460 /* If ROW->end is beyond ZV, then ROW->end is outdated and
17461 needs to be recomputed, so don't consider this row as
17462 unchanged. This happens when the last line was
17463 bidi-reordered and was killed immediately before this
17464 redisplay cycle. In that case, ROW->end stores the
17465 buffer position of the first visual-order character of
17466 the killed text, which is now beyond ZV. */
17467 && CHARPOS (row->end.pos) <= ZV)
17468 row_found = row;
17470 /* Stop if last visible row. */
17471 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
17472 break;
17475 return row_found;
17479 /* Find the first glyph row in the current matrix of W that is not
17480 affected by changes at the end of current_buffer since the
17481 time W's current matrix was built.
17483 Return in *DELTA the number of chars by which buffer positions in
17484 unchanged text at the end of current_buffer must be adjusted.
17486 Return in *DELTA_BYTES the corresponding number of bytes.
17488 Value is null if no such row exists, i.e. all rows are affected by
17489 changes. */
17491 static struct glyph_row *
17492 find_first_unchanged_at_end_row (struct window *w,
17493 ptrdiff_t *delta, ptrdiff_t *delta_bytes)
17495 struct glyph_row *row;
17496 struct glyph_row *row_found = NULL;
17498 *delta = *delta_bytes = 0;
17500 /* Display must not have been paused, otherwise the current matrix
17501 is not up to date. */
17502 eassert (w->window_end_valid);
17504 /* A value of window_end_pos >= END_UNCHANGED means that the window
17505 end is in the range of changed text. If so, there is no
17506 unchanged row at the end of W's current matrix. */
17507 if (w->window_end_pos >= END_UNCHANGED)
17508 return NULL;
17510 /* Set row to the last row in W's current matrix displaying text. */
17511 row = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
17513 /* If matrix is entirely empty, no unchanged row exists. */
17514 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
17516 /* The value of row is the last glyph row in the matrix having a
17517 meaningful buffer position in it. The end position of row
17518 corresponds to window_end_pos. This allows us to translate
17519 buffer positions in the current matrix to current buffer
17520 positions for characters not in changed text. */
17521 ptrdiff_t Z_old =
17522 MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos;
17523 ptrdiff_t Z_BYTE_old =
17524 MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
17525 ptrdiff_t last_unchanged_pos, last_unchanged_pos_old;
17526 struct glyph_row *first_text_row
17527 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
17529 *delta = Z - Z_old;
17530 *delta_bytes = Z_BYTE - Z_BYTE_old;
17532 /* Set last_unchanged_pos to the buffer position of the last
17533 character in the buffer that has not been changed. Z is the
17534 index + 1 of the last character in current_buffer, i.e. by
17535 subtracting END_UNCHANGED we get the index of the last
17536 unchanged character, and we have to add BEG to get its buffer
17537 position. */
17538 last_unchanged_pos = Z - END_UNCHANGED + BEG;
17539 last_unchanged_pos_old = last_unchanged_pos - *delta;
17541 /* Search backward from ROW for a row displaying a line that
17542 starts at a minimum position >= last_unchanged_pos_old. */
17543 for (; row > first_text_row; --row)
17545 /* This used to abort, but it can happen.
17546 It is ok to just stop the search instead here. KFS. */
17547 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
17548 break;
17550 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
17551 row_found = row;
17555 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
17557 return row_found;
17561 /* Make sure that glyph rows in the current matrix of window W
17562 reference the same glyph memory as corresponding rows in the
17563 frame's frame matrix. This function is called after scrolling W's
17564 current matrix on a terminal frame in try_window_id and
17565 try_window_reusing_current_matrix. */
17567 static void
17568 sync_frame_with_window_matrix_rows (struct window *w)
17570 struct frame *f = XFRAME (w->frame);
17571 struct glyph_row *window_row, *window_row_end, *frame_row;
17573 /* Preconditions: W must be a leaf window and full-width. Its frame
17574 must have a frame matrix. */
17575 eassert (BUFFERP (w->contents));
17576 eassert (WINDOW_FULL_WIDTH_P (w));
17577 eassert (!FRAME_WINDOW_P (f));
17579 /* If W is a full-width window, glyph pointers in W's current matrix
17580 have, by definition, to be the same as glyph pointers in the
17581 corresponding frame matrix. Note that frame matrices have no
17582 marginal areas (see build_frame_matrix). */
17583 window_row = w->current_matrix->rows;
17584 window_row_end = window_row + w->current_matrix->nrows;
17585 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
17586 while (window_row < window_row_end)
17588 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
17589 struct glyph *end = window_row->glyphs[LAST_AREA];
17591 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
17592 frame_row->glyphs[TEXT_AREA] = start;
17593 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
17594 frame_row->glyphs[LAST_AREA] = end;
17596 /* Disable frame rows whose corresponding window rows have
17597 been disabled in try_window_id. */
17598 if (!window_row->enabled_p)
17599 frame_row->enabled_p = false;
17601 ++window_row, ++frame_row;
17606 /* Find the glyph row in window W containing CHARPOS. Consider all
17607 rows between START and END (not inclusive). END null means search
17608 all rows to the end of the display area of W. Value is the row
17609 containing CHARPOS or null. */
17611 struct glyph_row *
17612 row_containing_pos (struct window *w, ptrdiff_t charpos,
17613 struct glyph_row *start, struct glyph_row *end, int dy)
17615 struct glyph_row *row = start;
17616 struct glyph_row *best_row = NULL;
17617 ptrdiff_t mindif = BUF_ZV (XBUFFER (w->contents)) + 1;
17618 int last_y;
17620 /* If we happen to start on a header-line, skip that. */
17621 if (row->mode_line_p)
17622 ++row;
17624 if ((end && row >= end) || !row->enabled_p)
17625 return NULL;
17627 last_y = window_text_bottom_y (w) - dy;
17629 while (1)
17631 /* Give up if we have gone too far. */
17632 if (end && row >= end)
17633 return NULL;
17634 /* This formerly returned if they were equal.
17635 I think that both quantities are of a "last plus one" type;
17636 if so, when they are equal, the row is within the screen. -- rms. */
17637 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
17638 return NULL;
17640 /* If it is in this row, return this row. */
17641 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
17642 || (MATRIX_ROW_END_CHARPOS (row) == charpos
17643 /* The end position of a row equals the start
17644 position of the next row. If CHARPOS is there, we
17645 would rather consider it displayed in the next
17646 line, except when this line ends in ZV. */
17647 && !row_for_charpos_p (row, charpos)))
17648 && charpos >= MATRIX_ROW_START_CHARPOS (row))
17650 struct glyph *g;
17652 if (NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
17653 || (!best_row && !row->continued_p))
17654 return row;
17655 /* In bidi-reordered rows, there could be several rows whose
17656 edges surround CHARPOS, all of these rows belonging to
17657 the same continued line. We need to find the row which
17658 fits CHARPOS the best. */
17659 for (g = row->glyphs[TEXT_AREA];
17660 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
17661 g++)
17663 if (!STRINGP (g->object))
17665 if (g->charpos > 0 && eabs (g->charpos - charpos) < mindif)
17667 mindif = eabs (g->charpos - charpos);
17668 best_row = row;
17669 /* Exact match always wins. */
17670 if (mindif == 0)
17671 return best_row;
17676 else if (best_row && !row->continued_p)
17677 return best_row;
17678 ++row;
17683 /* Try to redisplay window W by reusing its existing display. W's
17684 current matrix must be up to date when this function is called,
17685 i.e. window_end_valid must be nonzero.
17687 Value is
17689 >= 1 if successful, i.e. display has been updated
17690 specifically:
17691 1 means the changes were in front of a newline that precedes
17692 the window start, and the whole current matrix was reused
17693 2 means the changes were after the last position displayed
17694 in the window, and the whole current matrix was reused
17695 3 means portions of the current matrix were reused, while
17696 some of the screen lines were redrawn
17697 -1 if redisplay with same window start is known not to succeed
17698 0 if otherwise unsuccessful
17700 The following steps are performed:
17702 1. Find the last row in the current matrix of W that is not
17703 affected by changes at the start of current_buffer. If no such row
17704 is found, give up.
17706 2. Find the first row in W's current matrix that is not affected by
17707 changes at the end of current_buffer. Maybe there is no such row.
17709 3. Display lines beginning with the row + 1 found in step 1 to the
17710 row found in step 2 or, if step 2 didn't find a row, to the end of
17711 the window.
17713 4. If cursor is not known to appear on the window, give up.
17715 5. If display stopped at the row found in step 2, scroll the
17716 display and current matrix as needed.
17718 6. Maybe display some lines at the end of W, if we must. This can
17719 happen under various circumstances, like a partially visible line
17720 becoming fully visible, or because newly displayed lines are displayed
17721 in smaller font sizes.
17723 7. Update W's window end information. */
17725 static int
17726 try_window_id (struct window *w)
17728 struct frame *f = XFRAME (w->frame);
17729 struct glyph_matrix *current_matrix = w->current_matrix;
17730 struct glyph_matrix *desired_matrix = w->desired_matrix;
17731 struct glyph_row *last_unchanged_at_beg_row;
17732 struct glyph_row *first_unchanged_at_end_row;
17733 struct glyph_row *row;
17734 struct glyph_row *bottom_row;
17735 int bottom_vpos;
17736 struct it it;
17737 ptrdiff_t delta = 0, delta_bytes = 0, stop_pos;
17738 int dvpos, dy;
17739 struct text_pos start_pos;
17740 struct run run;
17741 int first_unchanged_at_end_vpos = 0;
17742 struct glyph_row *last_text_row, *last_text_row_at_end;
17743 struct text_pos start;
17744 ptrdiff_t first_changed_charpos, last_changed_charpos;
17746 #ifdef GLYPH_DEBUG
17747 if (inhibit_try_window_id)
17748 return 0;
17749 #endif
17751 /* This is handy for debugging. */
17752 #if 0
17753 #define GIVE_UP(X) \
17754 do { \
17755 fprintf (stderr, "try_window_id give up %d\n", (X)); \
17756 return 0; \
17757 } while (0)
17758 #else
17759 #define GIVE_UP(X) return 0
17760 #endif
17762 SET_TEXT_POS_FROM_MARKER (start, w->start);
17764 /* Don't use this for mini-windows because these can show
17765 messages and mini-buffers, and we don't handle that here. */
17766 if (MINI_WINDOW_P (w))
17767 GIVE_UP (1);
17769 /* This flag is used to prevent redisplay optimizations. */
17770 if (windows_or_buffers_changed || f->cursor_type_changed)
17771 GIVE_UP (2);
17773 /* This function's optimizations cannot be used if overlays have
17774 changed in the buffer displayed by the window, so give up if they
17775 have. */
17776 if (w->last_overlay_modified != OVERLAY_MODIFF)
17777 GIVE_UP (21);
17779 /* Verify that narrowing has not changed.
17780 Also verify that we were not told to prevent redisplay optimizations.
17781 It would be nice to further
17782 reduce the number of cases where this prevents try_window_id. */
17783 if (current_buffer->clip_changed
17784 || current_buffer->prevent_redisplay_optimizations_p)
17785 GIVE_UP (3);
17787 /* Window must either use window-based redisplay or be full width. */
17788 if (!FRAME_WINDOW_P (f)
17789 && (!FRAME_LINE_INS_DEL_OK (f)
17790 || !WINDOW_FULL_WIDTH_P (w)))
17791 GIVE_UP (4);
17793 /* Give up if point is known NOT to appear in W. */
17794 if (PT < CHARPOS (start))
17795 GIVE_UP (5);
17797 /* Another way to prevent redisplay optimizations. */
17798 if (w->last_modified == 0)
17799 GIVE_UP (6);
17801 /* Verify that window is not hscrolled. */
17802 if (w->hscroll != 0)
17803 GIVE_UP (7);
17805 /* Verify that display wasn't paused. */
17806 if (!w->window_end_valid)
17807 GIVE_UP (8);
17809 /* Likewise if highlighting trailing whitespace. */
17810 if (!NILP (Vshow_trailing_whitespace))
17811 GIVE_UP (11);
17813 /* Can't use this if overlay arrow position and/or string have
17814 changed. */
17815 if (overlay_arrows_changed_p ())
17816 GIVE_UP (12);
17818 /* When word-wrap is on, adding a space to the first word of a
17819 wrapped line can change the wrap position, altering the line
17820 above it. It might be worthwhile to handle this more
17821 intelligently, but for now just redisplay from scratch. */
17822 if (!NILP (BVAR (XBUFFER (w->contents), word_wrap)))
17823 GIVE_UP (21);
17825 /* Under bidi reordering, adding or deleting a character in the
17826 beginning of a paragraph, before the first strong directional
17827 character, can change the base direction of the paragraph (unless
17828 the buffer specifies a fixed paragraph direction), which will
17829 require to redisplay the whole paragraph. It might be worthwhile
17830 to find the paragraph limits and widen the range of redisplayed
17831 lines to that, but for now just give up this optimization and
17832 redisplay from scratch. */
17833 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
17834 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
17835 GIVE_UP (22);
17837 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
17838 only if buffer has really changed. The reason is that the gap is
17839 initially at Z for freshly visited files. The code below would
17840 set end_unchanged to 0 in that case. */
17841 if (MODIFF > SAVE_MODIFF
17842 /* This seems to happen sometimes after saving a buffer. */
17843 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
17845 if (GPT - BEG < BEG_UNCHANGED)
17846 BEG_UNCHANGED = GPT - BEG;
17847 if (Z - GPT < END_UNCHANGED)
17848 END_UNCHANGED = Z - GPT;
17851 /* The position of the first and last character that has been changed. */
17852 first_changed_charpos = BEG + BEG_UNCHANGED;
17853 last_changed_charpos = Z - END_UNCHANGED;
17855 /* If window starts after a line end, and the last change is in
17856 front of that newline, then changes don't affect the display.
17857 This case happens with stealth-fontification. Note that although
17858 the display is unchanged, glyph positions in the matrix have to
17859 be adjusted, of course. */
17860 row = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
17861 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
17862 && ((last_changed_charpos < CHARPOS (start)
17863 && CHARPOS (start) == BEGV)
17864 || (last_changed_charpos < CHARPOS (start) - 1
17865 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
17867 ptrdiff_t Z_old, Z_delta, Z_BYTE_old, Z_delta_bytes;
17868 struct glyph_row *r0;
17870 /* Compute how many chars/bytes have been added to or removed
17871 from the buffer. */
17872 Z_old = MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos;
17873 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
17874 Z_delta = Z - Z_old;
17875 Z_delta_bytes = Z_BYTE - Z_BYTE_old;
17877 /* Give up if PT is not in the window. Note that it already has
17878 been checked at the start of try_window_id that PT is not in
17879 front of the window start. */
17880 if (PT >= MATRIX_ROW_END_CHARPOS (row) + Z_delta)
17881 GIVE_UP (13);
17883 /* If window start is unchanged, we can reuse the whole matrix
17884 as is, after adjusting glyph positions. No need to compute
17885 the window end again, since its offset from Z hasn't changed. */
17886 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
17887 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + Z_delta
17888 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + Z_delta_bytes
17889 /* PT must not be in a partially visible line. */
17890 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + Z_delta
17891 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
17893 /* Adjust positions in the glyph matrix. */
17894 if (Z_delta || Z_delta_bytes)
17896 struct glyph_row *r1
17897 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
17898 increment_matrix_positions (w->current_matrix,
17899 MATRIX_ROW_VPOS (r0, current_matrix),
17900 MATRIX_ROW_VPOS (r1, current_matrix),
17901 Z_delta, Z_delta_bytes);
17904 /* Set the cursor. */
17905 row = row_containing_pos (w, PT, r0, NULL, 0);
17906 if (row)
17907 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
17908 return 1;
17912 /* Handle the case that changes are all below what is displayed in
17913 the window, and that PT is in the window. This shortcut cannot
17914 be taken if ZV is visible in the window, and text has been added
17915 there that is visible in the window. */
17916 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
17917 /* ZV is not visible in the window, or there are no
17918 changes at ZV, actually. */
17919 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
17920 || first_changed_charpos == last_changed_charpos))
17922 struct glyph_row *r0;
17924 /* Give up if PT is not in the window. Note that it already has
17925 been checked at the start of try_window_id that PT is not in
17926 front of the window start. */
17927 if (PT >= MATRIX_ROW_END_CHARPOS (row))
17928 GIVE_UP (14);
17930 /* If window start is unchanged, we can reuse the whole matrix
17931 as is, without changing glyph positions since no text has
17932 been added/removed in front of the window end. */
17933 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
17934 if (TEXT_POS_EQUAL_P (start, r0->minpos)
17935 /* PT must not be in a partially visible line. */
17936 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
17937 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
17939 /* We have to compute the window end anew since text
17940 could have been added/removed after it. */
17941 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
17942 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17944 /* Set the cursor. */
17945 row = row_containing_pos (w, PT, r0, NULL, 0);
17946 if (row)
17947 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
17948 return 2;
17952 /* Give up if window start is in the changed area.
17954 The condition used to read
17956 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
17958 but why that was tested escapes me at the moment. */
17959 if (CHARPOS (start) >= first_changed_charpos
17960 && CHARPOS (start) <= last_changed_charpos)
17961 GIVE_UP (15);
17963 /* Check that window start agrees with the start of the first glyph
17964 row in its current matrix. Check this after we know the window
17965 start is not in changed text, otherwise positions would not be
17966 comparable. */
17967 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
17968 if (!TEXT_POS_EQUAL_P (start, row->minpos))
17969 GIVE_UP (16);
17971 /* Give up if the window ends in strings. Overlay strings
17972 at the end are difficult to handle, so don't try. */
17973 row = MATRIX_ROW (current_matrix, w->window_end_vpos);
17974 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
17975 GIVE_UP (20);
17977 /* Compute the position at which we have to start displaying new
17978 lines. Some of the lines at the top of the window might be
17979 reusable because they are not displaying changed text. Find the
17980 last row in W's current matrix not affected by changes at the
17981 start of current_buffer. Value is null if changes start in the
17982 first line of window. */
17983 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
17984 if (last_unchanged_at_beg_row)
17986 /* Avoid starting to display in the middle of a character, a TAB
17987 for instance. This is easier than to set up the iterator
17988 exactly, and it's not a frequent case, so the additional
17989 effort wouldn't really pay off. */
17990 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
17991 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
17992 && last_unchanged_at_beg_row > w->current_matrix->rows)
17993 --last_unchanged_at_beg_row;
17995 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
17996 GIVE_UP (17);
17998 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
17999 GIVE_UP (18);
18000 start_pos = it.current.pos;
18002 /* Start displaying new lines in the desired matrix at the same
18003 vpos we would use in the current matrix, i.e. below
18004 last_unchanged_at_beg_row. */
18005 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
18006 current_matrix);
18007 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
18008 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
18010 eassert (it.hpos == 0 && it.current_x == 0);
18012 else
18014 /* There are no reusable lines at the start of the window.
18015 Start displaying in the first text line. */
18016 start_display (&it, w, start);
18017 it.vpos = it.first_vpos;
18018 start_pos = it.current.pos;
18021 /* Find the first row that is not affected by changes at the end of
18022 the buffer. Value will be null if there is no unchanged row, in
18023 which case we must redisplay to the end of the window. delta
18024 will be set to the value by which buffer positions beginning with
18025 first_unchanged_at_end_row have to be adjusted due to text
18026 changes. */
18027 first_unchanged_at_end_row
18028 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
18029 IF_DEBUG (debug_delta = delta);
18030 IF_DEBUG (debug_delta_bytes = delta_bytes);
18032 /* Set stop_pos to the buffer position up to which we will have to
18033 display new lines. If first_unchanged_at_end_row != NULL, this
18034 is the buffer position of the start of the line displayed in that
18035 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
18036 that we don't stop at a buffer position. */
18037 stop_pos = 0;
18038 if (first_unchanged_at_end_row)
18040 eassert (last_unchanged_at_beg_row == NULL
18041 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
18043 /* If this is a continuation line, move forward to the next one
18044 that isn't. Changes in lines above affect this line.
18045 Caution: this may move first_unchanged_at_end_row to a row
18046 not displaying text. */
18047 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
18048 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
18049 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
18050 < it.last_visible_y))
18051 ++first_unchanged_at_end_row;
18053 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
18054 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
18055 >= it.last_visible_y))
18056 first_unchanged_at_end_row = NULL;
18057 else
18059 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
18060 + delta);
18061 first_unchanged_at_end_vpos
18062 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
18063 eassert (stop_pos >= Z - END_UNCHANGED);
18066 else if (last_unchanged_at_beg_row == NULL)
18067 GIVE_UP (19);
18070 #ifdef GLYPH_DEBUG
18072 /* Either there is no unchanged row at the end, or the one we have
18073 now displays text. This is a necessary condition for the window
18074 end pos calculation at the end of this function. */
18075 eassert (first_unchanged_at_end_row == NULL
18076 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
18078 debug_last_unchanged_at_beg_vpos
18079 = (last_unchanged_at_beg_row
18080 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
18081 : -1);
18082 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
18084 #endif /* GLYPH_DEBUG */
18087 /* Display new lines. Set last_text_row to the last new line
18088 displayed which has text on it, i.e. might end up as being the
18089 line where the window_end_vpos is. */
18090 w->cursor.vpos = -1;
18091 last_text_row = NULL;
18092 overlay_arrow_seen = 0;
18093 while (it.current_y < it.last_visible_y
18094 && !f->fonts_changed
18095 && (first_unchanged_at_end_row == NULL
18096 || IT_CHARPOS (it) < stop_pos))
18098 if (display_line (&it))
18099 last_text_row = it.glyph_row - 1;
18102 if (f->fonts_changed)
18103 return -1;
18106 /* Compute differences in buffer positions, y-positions etc. for
18107 lines reused at the bottom of the window. Compute what we can
18108 scroll. */
18109 if (first_unchanged_at_end_row
18110 /* No lines reused because we displayed everything up to the
18111 bottom of the window. */
18112 && it.current_y < it.last_visible_y)
18114 dvpos = (it.vpos
18115 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
18116 current_matrix));
18117 dy = it.current_y - first_unchanged_at_end_row->y;
18118 run.current_y = first_unchanged_at_end_row->y;
18119 run.desired_y = run.current_y + dy;
18120 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
18122 else
18124 delta = delta_bytes = dvpos = dy
18125 = run.current_y = run.desired_y = run.height = 0;
18126 first_unchanged_at_end_row = NULL;
18128 IF_DEBUG ((debug_dvpos = dvpos, debug_dy = dy));
18131 /* Find the cursor if not already found. We have to decide whether
18132 PT will appear on this window (it sometimes doesn't, but this is
18133 not a very frequent case.) This decision has to be made before
18134 the current matrix is altered. A value of cursor.vpos < 0 means
18135 that PT is either in one of the lines beginning at
18136 first_unchanged_at_end_row or below the window. Don't care for
18137 lines that might be displayed later at the window end; as
18138 mentioned, this is not a frequent case. */
18139 if (w->cursor.vpos < 0)
18141 /* Cursor in unchanged rows at the top? */
18142 if (PT < CHARPOS (start_pos)
18143 && last_unchanged_at_beg_row)
18145 row = row_containing_pos (w, PT,
18146 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
18147 last_unchanged_at_beg_row + 1, 0);
18148 if (row)
18149 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
18152 /* Start from first_unchanged_at_end_row looking for PT. */
18153 else if (first_unchanged_at_end_row)
18155 row = row_containing_pos (w, PT - delta,
18156 first_unchanged_at_end_row, NULL, 0);
18157 if (row)
18158 set_cursor_from_row (w, row, w->current_matrix, delta,
18159 delta_bytes, dy, dvpos);
18162 /* Give up if cursor was not found. */
18163 if (w->cursor.vpos < 0)
18165 clear_glyph_matrix (w->desired_matrix);
18166 return -1;
18170 /* Don't let the cursor end in the scroll margins. */
18172 int this_scroll_margin, cursor_height;
18173 int frame_line_height = default_line_pixel_height (w);
18174 int window_total_lines
18175 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (it.f) / frame_line_height;
18177 this_scroll_margin =
18178 max (0, min (scroll_margin, window_total_lines / 4));
18179 this_scroll_margin *= frame_line_height;
18180 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
18182 if ((w->cursor.y < this_scroll_margin
18183 && CHARPOS (start) > BEGV)
18184 /* Old redisplay didn't take scroll margin into account at the bottom,
18185 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
18186 || (w->cursor.y + (make_cursor_line_fully_visible_p
18187 ? cursor_height + this_scroll_margin
18188 : 1)) > it.last_visible_y)
18190 w->cursor.vpos = -1;
18191 clear_glyph_matrix (w->desired_matrix);
18192 return -1;
18196 /* Scroll the display. Do it before changing the current matrix so
18197 that xterm.c doesn't get confused about where the cursor glyph is
18198 found. */
18199 if (dy && run.height)
18201 update_begin (f);
18203 if (FRAME_WINDOW_P (f))
18205 FRAME_RIF (f)->update_window_begin_hook (w);
18206 FRAME_RIF (f)->clear_window_mouse_face (w);
18207 FRAME_RIF (f)->scroll_run_hook (w, &run);
18208 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
18210 else
18212 /* Terminal frame. In this case, dvpos gives the number of
18213 lines to scroll by; dvpos < 0 means scroll up. */
18214 int from_vpos
18215 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
18216 int from = WINDOW_TOP_EDGE_LINE (w) + from_vpos;
18217 int end = (WINDOW_TOP_EDGE_LINE (w)
18218 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
18219 + window_internal_height (w));
18221 #if defined (HAVE_GPM) || defined (MSDOS)
18222 x_clear_window_mouse_face (w);
18223 #endif
18224 /* Perform the operation on the screen. */
18225 if (dvpos > 0)
18227 /* Scroll last_unchanged_at_beg_row to the end of the
18228 window down dvpos lines. */
18229 set_terminal_window (f, end);
18231 /* On dumb terminals delete dvpos lines at the end
18232 before inserting dvpos empty lines. */
18233 if (!FRAME_SCROLL_REGION_OK (f))
18234 ins_del_lines (f, end - dvpos, -dvpos);
18236 /* Insert dvpos empty lines in front of
18237 last_unchanged_at_beg_row. */
18238 ins_del_lines (f, from, dvpos);
18240 else if (dvpos < 0)
18242 /* Scroll up last_unchanged_at_beg_vpos to the end of
18243 the window to last_unchanged_at_beg_vpos - |dvpos|. */
18244 set_terminal_window (f, end);
18246 /* Delete dvpos lines in front of
18247 last_unchanged_at_beg_vpos. ins_del_lines will set
18248 the cursor to the given vpos and emit |dvpos| delete
18249 line sequences. */
18250 ins_del_lines (f, from + dvpos, dvpos);
18252 /* On a dumb terminal insert dvpos empty lines at the
18253 end. */
18254 if (!FRAME_SCROLL_REGION_OK (f))
18255 ins_del_lines (f, end + dvpos, -dvpos);
18258 set_terminal_window (f, 0);
18261 update_end (f);
18264 /* Shift reused rows of the current matrix to the right position.
18265 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
18266 text. */
18267 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
18268 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
18269 if (dvpos < 0)
18271 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
18272 bottom_vpos, dvpos);
18273 clear_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
18274 bottom_vpos);
18276 else if (dvpos > 0)
18278 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
18279 bottom_vpos, dvpos);
18280 clear_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
18281 first_unchanged_at_end_vpos + dvpos);
18284 /* For frame-based redisplay, make sure that current frame and window
18285 matrix are in sync with respect to glyph memory. */
18286 if (!FRAME_WINDOW_P (f))
18287 sync_frame_with_window_matrix_rows (w);
18289 /* Adjust buffer positions in reused rows. */
18290 if (delta || delta_bytes)
18291 increment_matrix_positions (current_matrix,
18292 first_unchanged_at_end_vpos + dvpos,
18293 bottom_vpos, delta, delta_bytes);
18295 /* Adjust Y positions. */
18296 if (dy)
18297 shift_glyph_matrix (w, current_matrix,
18298 first_unchanged_at_end_vpos + dvpos,
18299 bottom_vpos, dy);
18301 if (first_unchanged_at_end_row)
18303 first_unchanged_at_end_row += dvpos;
18304 if (first_unchanged_at_end_row->y >= it.last_visible_y
18305 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
18306 first_unchanged_at_end_row = NULL;
18309 /* If scrolling up, there may be some lines to display at the end of
18310 the window. */
18311 last_text_row_at_end = NULL;
18312 if (dy < 0)
18314 /* Scrolling up can leave for example a partially visible line
18315 at the end of the window to be redisplayed. */
18316 /* Set last_row to the glyph row in the current matrix where the
18317 window end line is found. It has been moved up or down in
18318 the matrix by dvpos. */
18319 int last_vpos = w->window_end_vpos + dvpos;
18320 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
18322 /* If last_row is the window end line, it should display text. */
18323 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_row));
18325 /* If window end line was partially visible before, begin
18326 displaying at that line. Otherwise begin displaying with the
18327 line following it. */
18328 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
18330 init_to_row_start (&it, w, last_row);
18331 it.vpos = last_vpos;
18332 it.current_y = last_row->y;
18334 else
18336 init_to_row_end (&it, w, last_row);
18337 it.vpos = 1 + last_vpos;
18338 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
18339 ++last_row;
18342 /* We may start in a continuation line. If so, we have to
18343 get the right continuation_lines_width and current_x. */
18344 it.continuation_lines_width = last_row->continuation_lines_width;
18345 it.hpos = it.current_x = 0;
18347 /* Display the rest of the lines at the window end. */
18348 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
18349 while (it.current_y < it.last_visible_y && !f->fonts_changed)
18351 /* Is it always sure that the display agrees with lines in
18352 the current matrix? I don't think so, so we mark rows
18353 displayed invalid in the current matrix by setting their
18354 enabled_p flag to zero. */
18355 SET_MATRIX_ROW_ENABLED_P (w->current_matrix, it.vpos, false);
18356 if (display_line (&it))
18357 last_text_row_at_end = it.glyph_row - 1;
18361 /* Update window_end_pos and window_end_vpos. */
18362 if (first_unchanged_at_end_row && !last_text_row_at_end)
18364 /* Window end line if one of the preserved rows from the current
18365 matrix. Set row to the last row displaying text in current
18366 matrix starting at first_unchanged_at_end_row, after
18367 scrolling. */
18368 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
18369 row = find_last_row_displaying_text (w->current_matrix, &it,
18370 first_unchanged_at_end_row);
18371 eassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
18372 adjust_window_ends (w, row, 1);
18373 eassert (w->window_end_bytepos >= 0);
18374 IF_DEBUG (debug_method_add (w, "A"));
18376 else if (last_text_row_at_end)
18378 adjust_window_ends (w, last_text_row_at_end, 0);
18379 eassert (w->window_end_bytepos >= 0);
18380 IF_DEBUG (debug_method_add (w, "B"));
18382 else if (last_text_row)
18384 /* We have displayed either to the end of the window or at the
18385 end of the window, i.e. the last row with text is to be found
18386 in the desired matrix. */
18387 adjust_window_ends (w, last_text_row, 0);
18388 eassert (w->window_end_bytepos >= 0);
18390 else if (first_unchanged_at_end_row == NULL
18391 && last_text_row == NULL
18392 && last_text_row_at_end == NULL)
18394 /* Displayed to end of window, but no line containing text was
18395 displayed. Lines were deleted at the end of the window. */
18396 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
18397 int vpos = w->window_end_vpos;
18398 struct glyph_row *current_row = current_matrix->rows + vpos;
18399 struct glyph_row *desired_row = desired_matrix->rows + vpos;
18401 for (row = NULL;
18402 row == NULL && vpos >= first_vpos;
18403 --vpos, --current_row, --desired_row)
18405 if (desired_row->enabled_p)
18407 if (MATRIX_ROW_DISPLAYS_TEXT_P (desired_row))
18408 row = desired_row;
18410 else if (MATRIX_ROW_DISPLAYS_TEXT_P (current_row))
18411 row = current_row;
18414 eassert (row != NULL);
18415 w->window_end_vpos = vpos + 1;
18416 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
18417 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
18418 eassert (w->window_end_bytepos >= 0);
18419 IF_DEBUG (debug_method_add (w, "C"));
18421 else
18422 emacs_abort ();
18424 IF_DEBUG ((debug_end_pos = w->window_end_pos,
18425 debug_end_vpos = w->window_end_vpos));
18427 /* Record that display has not been completed. */
18428 w->window_end_valid = 0;
18429 w->desired_matrix->no_scrolling_p = 1;
18430 return 3;
18432 #undef GIVE_UP
18437 /***********************************************************************
18438 More debugging support
18439 ***********************************************************************/
18441 #ifdef GLYPH_DEBUG
18443 void dump_glyph_row (struct glyph_row *, int, int) EXTERNALLY_VISIBLE;
18444 void dump_glyph_matrix (struct glyph_matrix *, int) EXTERNALLY_VISIBLE;
18445 void dump_glyph (struct glyph_row *, struct glyph *, int) EXTERNALLY_VISIBLE;
18448 /* Dump the contents of glyph matrix MATRIX on stderr.
18450 GLYPHS 0 means don't show glyph contents.
18451 GLYPHS 1 means show glyphs in short form
18452 GLYPHS > 1 means show glyphs in long form. */
18454 void
18455 dump_glyph_matrix (struct glyph_matrix *matrix, int glyphs)
18457 int i;
18458 for (i = 0; i < matrix->nrows; ++i)
18459 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
18463 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
18464 the glyph row and area where the glyph comes from. */
18466 void
18467 dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
18469 if (glyph->type == CHAR_GLYPH
18470 || glyph->type == GLYPHLESS_GLYPH)
18472 fprintf (stderr,
18473 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
18474 glyph - row->glyphs[TEXT_AREA],
18475 (glyph->type == CHAR_GLYPH
18476 ? 'C'
18477 : 'G'),
18478 glyph->charpos,
18479 (BUFFERP (glyph->object)
18480 ? 'B'
18481 : (STRINGP (glyph->object)
18482 ? 'S'
18483 : (INTEGERP (glyph->object)
18484 ? '0'
18485 : '-'))),
18486 glyph->pixel_width,
18487 glyph->u.ch,
18488 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
18489 ? glyph->u.ch
18490 : '.'),
18491 glyph->face_id,
18492 glyph->left_box_line_p,
18493 glyph->right_box_line_p);
18495 else if (glyph->type == STRETCH_GLYPH)
18497 fprintf (stderr,
18498 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
18499 glyph - row->glyphs[TEXT_AREA],
18500 'S',
18501 glyph->charpos,
18502 (BUFFERP (glyph->object)
18503 ? 'B'
18504 : (STRINGP (glyph->object)
18505 ? 'S'
18506 : (INTEGERP (glyph->object)
18507 ? '0'
18508 : '-'))),
18509 glyph->pixel_width,
18511 ' ',
18512 glyph->face_id,
18513 glyph->left_box_line_p,
18514 glyph->right_box_line_p);
18516 else if (glyph->type == IMAGE_GLYPH)
18518 fprintf (stderr,
18519 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
18520 glyph - row->glyphs[TEXT_AREA],
18521 'I',
18522 glyph->charpos,
18523 (BUFFERP (glyph->object)
18524 ? 'B'
18525 : (STRINGP (glyph->object)
18526 ? 'S'
18527 : (INTEGERP (glyph->object)
18528 ? '0'
18529 : '-'))),
18530 glyph->pixel_width,
18531 glyph->u.img_id,
18532 '.',
18533 glyph->face_id,
18534 glyph->left_box_line_p,
18535 glyph->right_box_line_p);
18537 else if (glyph->type == COMPOSITE_GLYPH)
18539 fprintf (stderr,
18540 " %5"pD"d %c %9"pI"d %c %3d 0x%06x",
18541 glyph - row->glyphs[TEXT_AREA],
18542 '+',
18543 glyph->charpos,
18544 (BUFFERP (glyph->object)
18545 ? 'B'
18546 : (STRINGP (glyph->object)
18547 ? 'S'
18548 : (INTEGERP (glyph->object)
18549 ? '0'
18550 : '-'))),
18551 glyph->pixel_width,
18552 glyph->u.cmp.id);
18553 if (glyph->u.cmp.automatic)
18554 fprintf (stderr,
18555 "[%d-%d]",
18556 glyph->slice.cmp.from, glyph->slice.cmp.to);
18557 fprintf (stderr, " . %4d %1.1d%1.1d\n",
18558 glyph->face_id,
18559 glyph->left_box_line_p,
18560 glyph->right_box_line_p);
18565 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
18566 GLYPHS 0 means don't show glyph contents.
18567 GLYPHS 1 means show glyphs in short form
18568 GLYPHS > 1 means show glyphs in long form. */
18570 void
18571 dump_glyph_row (struct glyph_row *row, int vpos, int glyphs)
18573 if (glyphs != 1)
18575 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
18576 fprintf (stderr, "==============================================================================\n");
18578 fprintf (stderr, "%3d %9"pI"d %9"pI"d %4d %1.1d%1.1d%1.1d%1.1d\
18579 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
18580 vpos,
18581 MATRIX_ROW_START_CHARPOS (row),
18582 MATRIX_ROW_END_CHARPOS (row),
18583 row->used[TEXT_AREA],
18584 row->contains_overlapping_glyphs_p,
18585 row->enabled_p,
18586 row->truncated_on_left_p,
18587 row->truncated_on_right_p,
18588 row->continued_p,
18589 MATRIX_ROW_CONTINUATION_LINE_P (row),
18590 MATRIX_ROW_DISPLAYS_TEXT_P (row),
18591 row->ends_at_zv_p,
18592 row->fill_line_p,
18593 row->ends_in_middle_of_char_p,
18594 row->starts_in_middle_of_char_p,
18595 row->mouse_face_p,
18596 row->x,
18597 row->y,
18598 row->pixel_width,
18599 row->height,
18600 row->visible_height,
18601 row->ascent,
18602 row->phys_ascent);
18603 /* The next 3 lines should align to "Start" in the header. */
18604 fprintf (stderr, " %9"pD"d %9"pD"d\t%5d\n", row->start.overlay_string_index,
18605 row->end.overlay_string_index,
18606 row->continuation_lines_width);
18607 fprintf (stderr, " %9"pI"d %9"pI"d\n",
18608 CHARPOS (row->start.string_pos),
18609 CHARPOS (row->end.string_pos));
18610 fprintf (stderr, " %9d %9d\n", row->start.dpvec_index,
18611 row->end.dpvec_index);
18614 if (glyphs > 1)
18616 int area;
18618 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18620 struct glyph *glyph = row->glyphs[area];
18621 struct glyph *glyph_end = glyph + row->used[area];
18623 /* Glyph for a line end in text. */
18624 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
18625 ++glyph_end;
18627 if (glyph < glyph_end)
18628 fprintf (stderr, " Glyph# Type Pos O W Code C Face LR\n");
18630 for (; glyph < glyph_end; ++glyph)
18631 dump_glyph (row, glyph, area);
18634 else if (glyphs == 1)
18636 int area;
18638 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18640 char *s = alloca (row->used[area] + 4);
18641 int i;
18643 for (i = 0; i < row->used[area]; ++i)
18645 struct glyph *glyph = row->glyphs[area] + i;
18646 if (i == row->used[area] - 1
18647 && area == TEXT_AREA
18648 && INTEGERP (glyph->object)
18649 && glyph->type == CHAR_GLYPH
18650 && glyph->u.ch == ' ')
18652 strcpy (&s[i], "[\\n]");
18653 i += 4;
18655 else if (glyph->type == CHAR_GLYPH
18656 && glyph->u.ch < 0x80
18657 && glyph->u.ch >= ' ')
18658 s[i] = glyph->u.ch;
18659 else
18660 s[i] = '.';
18663 s[i] = '\0';
18664 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
18670 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
18671 Sdump_glyph_matrix, 0, 1, "p",
18672 doc: /* Dump the current matrix of the selected window to stderr.
18673 Shows contents of glyph row structures. With non-nil
18674 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
18675 glyphs in short form, otherwise show glyphs in long form. */)
18676 (Lisp_Object glyphs)
18678 struct window *w = XWINDOW (selected_window);
18679 struct buffer *buffer = XBUFFER (w->contents);
18681 fprintf (stderr, "PT = %"pI"d, BEGV = %"pI"d. ZV = %"pI"d\n",
18682 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
18683 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
18684 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
18685 fprintf (stderr, "=============================================\n");
18686 dump_glyph_matrix (w->current_matrix,
18687 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 0);
18688 return Qnil;
18692 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
18693 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
18694 (void)
18696 struct frame *f = XFRAME (selected_frame);
18697 dump_glyph_matrix (f->current_matrix, 1);
18698 return Qnil;
18702 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
18703 doc: /* Dump glyph row ROW to stderr.
18704 GLYPH 0 means don't dump glyphs.
18705 GLYPH 1 means dump glyphs in short form.
18706 GLYPH > 1 or omitted means dump glyphs in long form. */)
18707 (Lisp_Object row, Lisp_Object glyphs)
18709 struct glyph_matrix *matrix;
18710 EMACS_INT vpos;
18712 CHECK_NUMBER (row);
18713 matrix = XWINDOW (selected_window)->current_matrix;
18714 vpos = XINT (row);
18715 if (vpos >= 0 && vpos < matrix->nrows)
18716 dump_glyph_row (MATRIX_ROW (matrix, vpos),
18717 vpos,
18718 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
18719 return Qnil;
18723 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
18724 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
18725 GLYPH 0 means don't dump glyphs.
18726 GLYPH 1 means dump glyphs in short form.
18727 GLYPH > 1 or omitted means dump glyphs in long form.
18729 If there's no tool-bar, or if the tool-bar is not drawn by Emacs,
18730 do nothing. */)
18731 (Lisp_Object row, Lisp_Object glyphs)
18733 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
18734 struct frame *sf = SELECTED_FRAME ();
18735 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
18736 EMACS_INT vpos;
18738 CHECK_NUMBER (row);
18739 vpos = XINT (row);
18740 if (vpos >= 0 && vpos < m->nrows)
18741 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
18742 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
18743 #endif
18744 return Qnil;
18748 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
18749 doc: /* Toggle tracing of redisplay.
18750 With ARG, turn tracing on if and only if ARG is positive. */)
18751 (Lisp_Object arg)
18753 if (NILP (arg))
18754 trace_redisplay_p = !trace_redisplay_p;
18755 else
18757 arg = Fprefix_numeric_value (arg);
18758 trace_redisplay_p = XINT (arg) > 0;
18761 return Qnil;
18765 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
18766 doc: /* Like `format', but print result to stderr.
18767 usage: (trace-to-stderr STRING &rest OBJECTS) */)
18768 (ptrdiff_t nargs, Lisp_Object *args)
18770 Lisp_Object s = Fformat (nargs, args);
18771 fprintf (stderr, "%s", SDATA (s));
18772 return Qnil;
18775 #endif /* GLYPH_DEBUG */
18779 /***********************************************************************
18780 Building Desired Matrix Rows
18781 ***********************************************************************/
18783 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
18784 Used for non-window-redisplay windows, and for windows w/o left fringe. */
18786 static struct glyph_row *
18787 get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
18789 struct frame *f = XFRAME (WINDOW_FRAME (w));
18790 struct buffer *buffer = XBUFFER (w->contents);
18791 struct buffer *old = current_buffer;
18792 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
18793 int arrow_len = SCHARS (overlay_arrow_string);
18794 const unsigned char *arrow_end = arrow_string + arrow_len;
18795 const unsigned char *p;
18796 struct it it;
18797 bool multibyte_p;
18798 int n_glyphs_before;
18800 set_buffer_temp (buffer);
18801 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
18802 it.glyph_row->used[TEXT_AREA] = 0;
18803 SET_TEXT_POS (it.position, 0, 0);
18805 multibyte_p = !NILP (BVAR (buffer, enable_multibyte_characters));
18806 p = arrow_string;
18807 while (p < arrow_end)
18809 Lisp_Object face, ilisp;
18811 /* Get the next character. */
18812 if (multibyte_p)
18813 it.c = it.char_to_display = string_char_and_length (p, &it.len);
18814 else
18816 it.c = it.char_to_display = *p, it.len = 1;
18817 if (! ASCII_CHAR_P (it.c))
18818 it.char_to_display = BYTE8_TO_CHAR (it.c);
18820 p += it.len;
18822 /* Get its face. */
18823 ilisp = make_number (p - arrow_string);
18824 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
18825 it.face_id = compute_char_face (f, it.char_to_display, face);
18827 /* Compute its width, get its glyphs. */
18828 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
18829 SET_TEXT_POS (it.position, -1, -1);
18830 PRODUCE_GLYPHS (&it);
18832 /* If this character doesn't fit any more in the line, we have
18833 to remove some glyphs. */
18834 if (it.current_x > it.last_visible_x)
18836 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
18837 break;
18841 set_buffer_temp (old);
18842 return it.glyph_row;
18846 /* Insert truncation glyphs at the start of IT->glyph_row. Which
18847 glyphs to insert is determined by produce_special_glyphs. */
18849 static void
18850 insert_left_trunc_glyphs (struct it *it)
18852 struct it truncate_it;
18853 struct glyph *from, *end, *to, *toend;
18855 eassert (!FRAME_WINDOW_P (it->f)
18856 || (!it->glyph_row->reversed_p
18857 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)
18858 || (it->glyph_row->reversed_p
18859 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0));
18861 /* Get the truncation glyphs. */
18862 truncate_it = *it;
18863 truncate_it.current_x = 0;
18864 truncate_it.face_id = DEFAULT_FACE_ID;
18865 truncate_it.glyph_row = &scratch_glyph_row;
18866 truncate_it.area = TEXT_AREA;
18867 truncate_it.glyph_row->used[TEXT_AREA] = 0;
18868 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
18869 truncate_it.object = make_number (0);
18870 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
18872 /* Overwrite glyphs from IT with truncation glyphs. */
18873 if (!it->glyph_row->reversed_p)
18875 short tused = truncate_it.glyph_row->used[TEXT_AREA];
18877 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
18878 end = from + tused;
18879 to = it->glyph_row->glyphs[TEXT_AREA];
18880 toend = to + it->glyph_row->used[TEXT_AREA];
18881 if (FRAME_WINDOW_P (it->f))
18883 /* On GUI frames, when variable-size fonts are displayed,
18884 the truncation glyphs may need more pixels than the row's
18885 glyphs they overwrite. We overwrite more glyphs to free
18886 enough screen real estate, and enlarge the stretch glyph
18887 on the right (see display_line), if there is one, to
18888 preserve the screen position of the truncation glyphs on
18889 the right. */
18890 int w = 0;
18891 struct glyph *g = to;
18892 short used;
18894 /* The first glyph could be partially visible, in which case
18895 it->glyph_row->x will be negative. But we want the left
18896 truncation glyphs to be aligned at the left margin of the
18897 window, so we override the x coordinate at which the row
18898 will begin. */
18899 it->glyph_row->x = 0;
18900 while (g < toend && w < it->truncation_pixel_width)
18902 w += g->pixel_width;
18903 ++g;
18905 if (g - to - tused > 0)
18907 memmove (to + tused, g, (toend - g) * sizeof(*g));
18908 it->glyph_row->used[TEXT_AREA] -= g - to - tused;
18910 used = it->glyph_row->used[TEXT_AREA];
18911 if (it->glyph_row->truncated_on_right_p
18912 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
18913 && it->glyph_row->glyphs[TEXT_AREA][used - 2].type
18914 == STRETCH_GLYPH)
18916 int extra = w - it->truncation_pixel_width;
18918 it->glyph_row->glyphs[TEXT_AREA][used - 2].pixel_width += extra;
18922 while (from < end)
18923 *to++ = *from++;
18925 /* There may be padding glyphs left over. Overwrite them too. */
18926 if (!FRAME_WINDOW_P (it->f))
18928 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
18930 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
18931 while (from < end)
18932 *to++ = *from++;
18936 if (to > toend)
18937 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
18939 else
18941 short tused = truncate_it.glyph_row->used[TEXT_AREA];
18943 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
18944 that back to front. */
18945 end = truncate_it.glyph_row->glyphs[TEXT_AREA];
18946 from = end + truncate_it.glyph_row->used[TEXT_AREA] - 1;
18947 toend = it->glyph_row->glyphs[TEXT_AREA];
18948 to = toend + it->glyph_row->used[TEXT_AREA] - 1;
18949 if (FRAME_WINDOW_P (it->f))
18951 int w = 0;
18952 struct glyph *g = to;
18954 while (g >= toend && w < it->truncation_pixel_width)
18956 w += g->pixel_width;
18957 --g;
18959 if (to - g - tused > 0)
18960 to = g + tused;
18961 if (it->glyph_row->truncated_on_right_p
18962 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0
18963 && it->glyph_row->glyphs[TEXT_AREA][1].type == STRETCH_GLYPH)
18965 int extra = w - it->truncation_pixel_width;
18967 it->glyph_row->glyphs[TEXT_AREA][1].pixel_width += extra;
18971 while (from >= end && to >= toend)
18972 *to-- = *from--;
18973 if (!FRAME_WINDOW_P (it->f))
18975 while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
18977 from =
18978 truncate_it.glyph_row->glyphs[TEXT_AREA]
18979 + truncate_it.glyph_row->used[TEXT_AREA] - 1;
18980 while (from >= end && to >= toend)
18981 *to-- = *from--;
18984 if (from >= end)
18986 /* Need to free some room before prepending additional
18987 glyphs. */
18988 int move_by = from - end + 1;
18989 struct glyph *g0 = it->glyph_row->glyphs[TEXT_AREA];
18990 struct glyph *g = g0 + it->glyph_row->used[TEXT_AREA] - 1;
18992 for ( ; g >= g0; g--)
18993 g[move_by] = *g;
18994 while (from >= end)
18995 *to-- = *from--;
18996 it->glyph_row->used[TEXT_AREA] += move_by;
19001 /* Compute the hash code for ROW. */
19002 unsigned
19003 row_hash (struct glyph_row *row)
19005 int area, k;
19006 unsigned hashval = 0;
19008 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
19009 for (k = 0; k < row->used[area]; ++k)
19010 hashval = ((((hashval << 4) + (hashval >> 24)) & 0x0fffffff)
19011 + row->glyphs[area][k].u.val
19012 + row->glyphs[area][k].face_id
19013 + row->glyphs[area][k].padding_p
19014 + (row->glyphs[area][k].type << 2));
19016 return hashval;
19019 /* Compute the pixel height and width of IT->glyph_row.
19021 Most of the time, ascent and height of a display line will be equal
19022 to the max_ascent and max_height values of the display iterator
19023 structure. This is not the case if
19025 1. We hit ZV without displaying anything. In this case, max_ascent
19026 and max_height will be zero.
19028 2. We have some glyphs that don't contribute to the line height.
19029 (The glyph row flag contributes_to_line_height_p is for future
19030 pixmap extensions).
19032 The first case is easily covered by using default values because in
19033 these cases, the line height does not really matter, except that it
19034 must not be zero. */
19036 static void
19037 compute_line_metrics (struct it *it)
19039 struct glyph_row *row = it->glyph_row;
19041 if (FRAME_WINDOW_P (it->f))
19043 int i, min_y, max_y;
19045 /* The line may consist of one space only, that was added to
19046 place the cursor on it. If so, the row's height hasn't been
19047 computed yet. */
19048 if (row->height == 0)
19050 if (it->max_ascent + it->max_descent == 0)
19051 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
19052 row->ascent = it->max_ascent;
19053 row->height = it->max_ascent + it->max_descent;
19054 row->phys_ascent = it->max_phys_ascent;
19055 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
19056 row->extra_line_spacing = it->max_extra_line_spacing;
19059 /* Compute the width of this line. */
19060 row->pixel_width = row->x;
19061 for (i = 0; i < row->used[TEXT_AREA]; ++i)
19062 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
19064 eassert (row->pixel_width >= 0);
19065 eassert (row->ascent >= 0 && row->height > 0);
19067 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
19068 || MATRIX_ROW_OVERLAPS_PRED_P (row));
19070 /* If first line's physical ascent is larger than its logical
19071 ascent, use the physical ascent, and make the row taller.
19072 This makes accented characters fully visible. */
19073 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
19074 && row->phys_ascent > row->ascent)
19076 row->height += row->phys_ascent - row->ascent;
19077 row->ascent = row->phys_ascent;
19080 /* Compute how much of the line is visible. */
19081 row->visible_height = row->height;
19083 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
19084 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
19086 if (row->y < min_y)
19087 row->visible_height -= min_y - row->y;
19088 if (row->y + row->height > max_y)
19089 row->visible_height -= row->y + row->height - max_y;
19091 else
19093 row->pixel_width = row->used[TEXT_AREA];
19094 if (row->continued_p)
19095 row->pixel_width -= it->continuation_pixel_width;
19096 else if (row->truncated_on_right_p)
19097 row->pixel_width -= it->truncation_pixel_width;
19098 row->ascent = row->phys_ascent = 0;
19099 row->height = row->phys_height = row->visible_height = 1;
19100 row->extra_line_spacing = 0;
19103 /* Compute a hash code for this row. */
19104 row->hash = row_hash (row);
19106 it->max_ascent = it->max_descent = 0;
19107 it->max_phys_ascent = it->max_phys_descent = 0;
19111 /* Append one space to the glyph row of iterator IT if doing a
19112 window-based redisplay. The space has the same face as
19113 IT->face_id. Value is non-zero if a space was added.
19115 This function is called to make sure that there is always one glyph
19116 at the end of a glyph row that the cursor can be set on under
19117 window-systems. (If there weren't such a glyph we would not know
19118 how wide and tall a box cursor should be displayed).
19120 At the same time this space let's a nicely handle clearing to the
19121 end of the line if the row ends in italic text. */
19123 static int
19124 append_space_for_newline (struct it *it, int default_face_p)
19126 if (FRAME_WINDOW_P (it->f))
19128 int n = it->glyph_row->used[TEXT_AREA];
19130 if (it->glyph_row->glyphs[TEXT_AREA] + n
19131 < it->glyph_row->glyphs[1 + TEXT_AREA])
19133 /* Save some values that must not be changed.
19134 Must save IT->c and IT->len because otherwise
19135 ITERATOR_AT_END_P wouldn't work anymore after
19136 append_space_for_newline has been called. */
19137 enum display_element_type saved_what = it->what;
19138 int saved_c = it->c, saved_len = it->len;
19139 int saved_char_to_display = it->char_to_display;
19140 int saved_x = it->current_x;
19141 int saved_face_id = it->face_id;
19142 int saved_box_end = it->end_of_box_run_p;
19143 struct text_pos saved_pos;
19144 Lisp_Object saved_object;
19145 struct face *face;
19147 saved_object = it->object;
19148 saved_pos = it->position;
19150 it->what = IT_CHARACTER;
19151 memset (&it->position, 0, sizeof it->position);
19152 it->object = make_number (0);
19153 it->c = it->char_to_display = ' ';
19154 it->len = 1;
19156 /* If the default face was remapped, be sure to use the
19157 remapped face for the appended newline. */
19158 if (default_face_p)
19159 it->face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
19160 else if (it->face_before_selective_p)
19161 it->face_id = it->saved_face_id;
19162 face = FACE_FROM_ID (it->f, it->face_id);
19163 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
19164 /* In R2L rows, we will prepend a stretch glyph that will
19165 have the end_of_box_run_p flag set for it, so there's no
19166 need for the appended newline glyph to have that flag
19167 set. */
19168 if (it->glyph_row->reversed_p
19169 /* But if the appended newline glyph goes all the way to
19170 the end of the row, there will be no stretch glyph,
19171 so leave the box flag set. */
19172 && saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x)
19173 it->end_of_box_run_p = 0;
19175 PRODUCE_GLYPHS (it);
19177 it->override_ascent = -1;
19178 it->constrain_row_ascent_descent_p = 0;
19179 it->current_x = saved_x;
19180 it->object = saved_object;
19181 it->position = saved_pos;
19182 it->what = saved_what;
19183 it->face_id = saved_face_id;
19184 it->len = saved_len;
19185 it->c = saved_c;
19186 it->char_to_display = saved_char_to_display;
19187 it->end_of_box_run_p = saved_box_end;
19188 return 1;
19192 return 0;
19196 /* Extend the face of the last glyph in the text area of IT->glyph_row
19197 to the end of the display line. Called from display_line. If the
19198 glyph row is empty, add a space glyph to it so that we know the
19199 face to draw. Set the glyph row flag fill_line_p. If the glyph
19200 row is R2L, prepend a stretch glyph to cover the empty space to the
19201 left of the leftmost glyph. */
19203 static void
19204 extend_face_to_end_of_line (struct it *it)
19206 struct face *face, *default_face;
19207 struct frame *f = it->f;
19209 /* If line is already filled, do nothing. Non window-system frames
19210 get a grace of one more ``pixel'' because their characters are
19211 1-``pixel'' wide, so they hit the equality too early. This grace
19212 is needed only for R2L rows that are not continued, to produce
19213 one extra blank where we could display the cursor. */
19214 if ((it->current_x >= it->last_visible_x
19215 + (!FRAME_WINDOW_P (f)
19216 && it->glyph_row->reversed_p
19217 && !it->glyph_row->continued_p))
19218 /* If the window has display margins, we will need to extend
19219 their face even if the text area is filled. */
19220 && !(WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
19221 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0))
19222 return;
19224 /* The default face, possibly remapped. */
19225 default_face = FACE_FROM_ID (f, lookup_basic_face (f, DEFAULT_FACE_ID));
19227 /* Face extension extends the background and box of IT->face_id
19228 to the end of the line. If the background equals the background
19229 of the frame, we don't have to do anything. */
19230 if (it->face_before_selective_p)
19231 face = FACE_FROM_ID (f, it->saved_face_id);
19232 else
19233 face = FACE_FROM_ID (f, it->face_id);
19235 if (FRAME_WINDOW_P (f)
19236 && MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row)
19237 && face->box == FACE_NO_BOX
19238 && face->background == FRAME_BACKGROUND_PIXEL (f)
19239 #ifdef HAVE_WINDOW_SYSTEM
19240 && !face->stipple
19241 #endif
19242 && !it->glyph_row->reversed_p)
19243 return;
19245 /* Set the glyph row flag indicating that the face of the last glyph
19246 in the text area has to be drawn to the end of the text area. */
19247 it->glyph_row->fill_line_p = 1;
19249 /* If current character of IT is not ASCII, make sure we have the
19250 ASCII face. This will be automatically undone the next time
19251 get_next_display_element returns a multibyte character. Note
19252 that the character will always be single byte in unibyte
19253 text. */
19254 if (!ASCII_CHAR_P (it->c))
19256 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
19259 if (FRAME_WINDOW_P (f))
19261 /* If the row is empty, add a space with the current face of IT,
19262 so that we know which face to draw. */
19263 if (it->glyph_row->used[TEXT_AREA] == 0)
19265 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
19266 it->glyph_row->glyphs[TEXT_AREA][0].face_id = face->id;
19267 it->glyph_row->used[TEXT_AREA] = 1;
19269 /* Mode line and the header line don't have margins, and
19270 likewise the frame's tool-bar window, if there is any. */
19271 if (!(it->glyph_row->mode_line_p
19272 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
19273 || (WINDOWP (f->tool_bar_window)
19274 && it->w == XWINDOW (f->tool_bar_window))
19275 #endif
19278 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
19279 && it->glyph_row->used[LEFT_MARGIN_AREA] == 0)
19281 it->glyph_row->glyphs[LEFT_MARGIN_AREA][0] = space_glyph;
19282 it->glyph_row->glyphs[LEFT_MARGIN_AREA][0].face_id =
19283 default_face->id;
19284 it->glyph_row->used[LEFT_MARGIN_AREA] = 1;
19286 if (WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0
19287 && it->glyph_row->used[RIGHT_MARGIN_AREA] == 0)
19289 it->glyph_row->glyphs[RIGHT_MARGIN_AREA][0] = space_glyph;
19290 it->glyph_row->glyphs[RIGHT_MARGIN_AREA][0].face_id =
19291 default_face->id;
19292 it->glyph_row->used[RIGHT_MARGIN_AREA] = 1;
19295 #ifdef HAVE_WINDOW_SYSTEM
19296 if (it->glyph_row->reversed_p)
19298 /* Prepend a stretch glyph to the row, such that the
19299 rightmost glyph will be drawn flushed all the way to the
19300 right margin of the window. The stretch glyph that will
19301 occupy the empty space, if any, to the left of the
19302 glyphs. */
19303 struct font *font = face->font ? face->font : FRAME_FONT (f);
19304 struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA];
19305 struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA];
19306 struct glyph *g;
19307 int row_width, stretch_ascent, stretch_width;
19308 struct text_pos saved_pos;
19309 int saved_face_id, saved_avoid_cursor, saved_box_start;
19311 for (row_width = 0, g = row_start; g < row_end; g++)
19312 row_width += g->pixel_width;
19313 stretch_width = window_box_width (it->w, TEXT_AREA) - row_width;
19314 if (stretch_width > 0)
19316 stretch_ascent =
19317 (((it->ascent + it->descent)
19318 * FONT_BASE (font)) / FONT_HEIGHT (font));
19319 saved_pos = it->position;
19320 memset (&it->position, 0, sizeof it->position);
19321 saved_avoid_cursor = it->avoid_cursor_p;
19322 it->avoid_cursor_p = 1;
19323 saved_face_id = it->face_id;
19324 saved_box_start = it->start_of_box_run_p;
19325 /* The last row's stretch glyph should get the default
19326 face, to avoid painting the rest of the window with
19327 the region face, if the region ends at ZV. */
19328 if (it->glyph_row->ends_at_zv_p)
19329 it->face_id = default_face->id;
19330 else
19331 it->face_id = face->id;
19332 it->start_of_box_run_p = 0;
19333 append_stretch_glyph (it, make_number (0), stretch_width,
19334 it->ascent + it->descent, stretch_ascent);
19335 it->position = saved_pos;
19336 it->avoid_cursor_p = saved_avoid_cursor;
19337 it->face_id = saved_face_id;
19338 it->start_of_box_run_p = saved_box_start;
19340 /* If stretch_width comes out negative, it means that the
19341 last glyph is only partially visible. In R2L rows, we
19342 want the leftmost glyph to be partially visible, so we
19343 need to give the row the corresponding left offset. */
19344 if (stretch_width < 0)
19345 it->glyph_row->x = stretch_width;
19347 #endif /* HAVE_WINDOW_SYSTEM */
19349 else
19351 /* Save some values that must not be changed. */
19352 int saved_x = it->current_x;
19353 struct text_pos saved_pos;
19354 Lisp_Object saved_object;
19355 enum display_element_type saved_what = it->what;
19356 int saved_face_id = it->face_id;
19358 saved_object = it->object;
19359 saved_pos = it->position;
19361 it->what = IT_CHARACTER;
19362 memset (&it->position, 0, sizeof it->position);
19363 it->object = make_number (0);
19364 it->c = it->char_to_display = ' ';
19365 it->len = 1;
19367 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
19368 && (it->glyph_row->used[LEFT_MARGIN_AREA]
19369 < WINDOW_LEFT_MARGIN_WIDTH (it->w))
19370 && !it->glyph_row->mode_line_p
19371 && default_face->background != FRAME_BACKGROUND_PIXEL (f))
19373 struct glyph *g = it->glyph_row->glyphs[LEFT_MARGIN_AREA];
19374 struct glyph *e = g + it->glyph_row->used[LEFT_MARGIN_AREA];
19376 for (it->current_x = 0; g < e; g++)
19377 it->current_x += g->pixel_width;
19379 it->area = LEFT_MARGIN_AREA;
19380 it->face_id = default_face->id;
19381 while (it->glyph_row->used[LEFT_MARGIN_AREA]
19382 < WINDOW_LEFT_MARGIN_WIDTH (it->w))
19384 PRODUCE_GLYPHS (it);
19385 /* term.c:produce_glyphs advances it->current_x only for
19386 TEXT_AREA. */
19387 it->current_x += it->pixel_width;
19390 it->current_x = saved_x;
19391 it->area = TEXT_AREA;
19394 /* The last row's blank glyphs should get the default face, to
19395 avoid painting the rest of the window with the region face,
19396 if the region ends at ZV. */
19397 if (it->glyph_row->ends_at_zv_p)
19398 it->face_id = default_face->id;
19399 else
19400 it->face_id = face->id;
19401 PRODUCE_GLYPHS (it);
19403 while (it->current_x <= it->last_visible_x)
19404 PRODUCE_GLYPHS (it);
19406 if (WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0
19407 && (it->glyph_row->used[RIGHT_MARGIN_AREA]
19408 < WINDOW_RIGHT_MARGIN_WIDTH (it->w))
19409 && !it->glyph_row->mode_line_p
19410 && default_face->background != FRAME_BACKGROUND_PIXEL (f))
19412 struct glyph *g = it->glyph_row->glyphs[RIGHT_MARGIN_AREA];
19413 struct glyph *e = g + it->glyph_row->used[RIGHT_MARGIN_AREA];
19415 for ( ; g < e; g++)
19416 it->current_x += g->pixel_width;
19418 it->area = RIGHT_MARGIN_AREA;
19419 it->face_id = default_face->id;
19420 while (it->glyph_row->used[RIGHT_MARGIN_AREA]
19421 < WINDOW_RIGHT_MARGIN_WIDTH (it->w))
19423 PRODUCE_GLYPHS (it);
19424 it->current_x += it->pixel_width;
19427 it->area = TEXT_AREA;
19430 /* Don't count these blanks really. It would let us insert a left
19431 truncation glyph below and make us set the cursor on them, maybe. */
19432 it->current_x = saved_x;
19433 it->object = saved_object;
19434 it->position = saved_pos;
19435 it->what = saved_what;
19436 it->face_id = saved_face_id;
19441 /* Value is non-zero if text starting at CHARPOS in current_buffer is
19442 trailing whitespace. */
19444 static int
19445 trailing_whitespace_p (ptrdiff_t charpos)
19447 ptrdiff_t bytepos = CHAR_TO_BYTE (charpos);
19448 int c = 0;
19450 while (bytepos < ZV_BYTE
19451 && (c = FETCH_CHAR (bytepos),
19452 c == ' ' || c == '\t'))
19453 ++bytepos;
19455 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
19457 if (bytepos != PT_BYTE)
19458 return 1;
19460 return 0;
19464 /* Highlight trailing whitespace, if any, in ROW. */
19466 static void
19467 highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
19469 int used = row->used[TEXT_AREA];
19471 if (used)
19473 struct glyph *start = row->glyphs[TEXT_AREA];
19474 struct glyph *glyph = start + used - 1;
19476 if (row->reversed_p)
19478 /* Right-to-left rows need to be processed in the opposite
19479 direction, so swap the edge pointers. */
19480 glyph = start;
19481 start = row->glyphs[TEXT_AREA] + used - 1;
19484 /* Skip over glyphs inserted to display the cursor at the
19485 end of a line, for extending the face of the last glyph
19486 to the end of the line on terminals, and for truncation
19487 and continuation glyphs. */
19488 if (!row->reversed_p)
19490 while (glyph >= start
19491 && glyph->type == CHAR_GLYPH
19492 && INTEGERP (glyph->object))
19493 --glyph;
19495 else
19497 while (glyph <= start
19498 && glyph->type == CHAR_GLYPH
19499 && INTEGERP (glyph->object))
19500 ++glyph;
19503 /* If last glyph is a space or stretch, and it's trailing
19504 whitespace, set the face of all trailing whitespace glyphs in
19505 IT->glyph_row to `trailing-whitespace'. */
19506 if ((row->reversed_p ? glyph <= start : glyph >= start)
19507 && BUFFERP (glyph->object)
19508 && (glyph->type == STRETCH_GLYPH
19509 || (glyph->type == CHAR_GLYPH
19510 && glyph->u.ch == ' '))
19511 && trailing_whitespace_p (glyph->charpos))
19513 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
19514 if (face_id < 0)
19515 return;
19517 if (!row->reversed_p)
19519 while (glyph >= start
19520 && BUFFERP (glyph->object)
19521 && (glyph->type == STRETCH_GLYPH
19522 || (glyph->type == CHAR_GLYPH
19523 && glyph->u.ch == ' ')))
19524 (glyph--)->face_id = face_id;
19526 else
19528 while (glyph <= start
19529 && BUFFERP (glyph->object)
19530 && (glyph->type == STRETCH_GLYPH
19531 || (glyph->type == CHAR_GLYPH
19532 && glyph->u.ch == ' ')))
19533 (glyph++)->face_id = face_id;
19540 /* Value is non-zero if glyph row ROW should be
19541 considered to hold the buffer position CHARPOS. */
19543 static int
19544 row_for_charpos_p (struct glyph_row *row, ptrdiff_t charpos)
19546 int result = 1;
19548 if (charpos == CHARPOS (row->end.pos)
19549 || charpos == MATRIX_ROW_END_CHARPOS (row))
19551 /* Suppose the row ends on a string.
19552 Unless the row is continued, that means it ends on a newline
19553 in the string. If it's anything other than a display string
19554 (e.g., a before-string from an overlay), we don't want the
19555 cursor there. (This heuristic seems to give the optimal
19556 behavior for the various types of multi-line strings.)
19557 One exception: if the string has `cursor' property on one of
19558 its characters, we _do_ want the cursor there. */
19559 if (CHARPOS (row->end.string_pos) >= 0)
19561 if (row->continued_p)
19562 result = 1;
19563 else
19565 /* Check for `display' property. */
19566 struct glyph *beg = row->glyphs[TEXT_AREA];
19567 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
19568 struct glyph *glyph;
19570 result = 0;
19571 for (glyph = end; glyph >= beg; --glyph)
19572 if (STRINGP (glyph->object))
19574 Lisp_Object prop
19575 = Fget_char_property (make_number (charpos),
19576 Qdisplay, Qnil);
19577 result =
19578 (!NILP (prop)
19579 && display_prop_string_p (prop, glyph->object));
19580 /* If there's a `cursor' property on one of the
19581 string's characters, this row is a cursor row,
19582 even though this is not a display string. */
19583 if (!result)
19585 Lisp_Object s = glyph->object;
19587 for ( ; glyph >= beg && EQ (glyph->object, s); --glyph)
19589 ptrdiff_t gpos = glyph->charpos;
19591 if (!NILP (Fget_char_property (make_number (gpos),
19592 Qcursor, s)))
19594 result = 1;
19595 break;
19599 break;
19603 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
19605 /* If the row ends in middle of a real character,
19606 and the line is continued, we want the cursor here.
19607 That's because CHARPOS (ROW->end.pos) would equal
19608 PT if PT is before the character. */
19609 if (!row->ends_in_ellipsis_p)
19610 result = row->continued_p;
19611 else
19612 /* If the row ends in an ellipsis, then
19613 CHARPOS (ROW->end.pos) will equal point after the
19614 invisible text. We want that position to be displayed
19615 after the ellipsis. */
19616 result = 0;
19618 /* If the row ends at ZV, display the cursor at the end of that
19619 row instead of at the start of the row below. */
19620 else if (row->ends_at_zv_p)
19621 result = 1;
19622 else
19623 result = 0;
19626 return result;
19629 /* Value is non-zero if glyph row ROW should be
19630 used to hold the cursor. */
19632 static int
19633 cursor_row_p (struct glyph_row *row)
19635 return row_for_charpos_p (row, PT);
19640 /* Push the property PROP so that it will be rendered at the current
19641 position in IT. Return 1 if PROP was successfully pushed, 0
19642 otherwise. Called from handle_line_prefix to handle the
19643 `line-prefix' and `wrap-prefix' properties. */
19645 static int
19646 push_prefix_prop (struct it *it, Lisp_Object prop)
19648 struct text_pos pos =
19649 STRINGP (it->string) ? it->current.string_pos : it->current.pos;
19651 eassert (it->method == GET_FROM_BUFFER
19652 || it->method == GET_FROM_DISPLAY_VECTOR
19653 || it->method == GET_FROM_STRING);
19655 /* We need to save the current buffer/string position, so it will be
19656 restored by pop_it, because iterate_out_of_display_property
19657 depends on that being set correctly, but some situations leave
19658 it->position not yet set when this function is called. */
19659 push_it (it, &pos);
19661 if (STRINGP (prop))
19663 if (SCHARS (prop) == 0)
19665 pop_it (it);
19666 return 0;
19669 it->string = prop;
19670 it->string_from_prefix_prop_p = 1;
19671 it->multibyte_p = STRING_MULTIBYTE (it->string);
19672 it->current.overlay_string_index = -1;
19673 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
19674 it->end_charpos = it->string_nchars = SCHARS (it->string);
19675 it->method = GET_FROM_STRING;
19676 it->stop_charpos = 0;
19677 it->prev_stop = 0;
19678 it->base_level_stop = 0;
19680 /* Force paragraph direction to be that of the parent
19681 buffer/string. */
19682 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
19683 it->paragraph_embedding = it->bidi_it.paragraph_dir;
19684 else
19685 it->paragraph_embedding = L2R;
19687 /* Set up the bidi iterator for this display string. */
19688 if (it->bidi_p)
19690 it->bidi_it.string.lstring = it->string;
19691 it->bidi_it.string.s = NULL;
19692 it->bidi_it.string.schars = it->end_charpos;
19693 it->bidi_it.string.bufpos = IT_CHARPOS (*it);
19694 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
19695 it->bidi_it.string.unibyte = !it->multibyte_p;
19696 it->bidi_it.w = it->w;
19697 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
19700 else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
19702 it->method = GET_FROM_STRETCH;
19703 it->object = prop;
19705 #ifdef HAVE_WINDOW_SYSTEM
19706 else if (IMAGEP (prop))
19708 it->what = IT_IMAGE;
19709 it->image_id = lookup_image (it->f, prop);
19710 it->method = GET_FROM_IMAGE;
19712 #endif /* HAVE_WINDOW_SYSTEM */
19713 else
19715 pop_it (it); /* bogus display property, give up */
19716 return 0;
19719 return 1;
19722 /* Return the character-property PROP at the current position in IT. */
19724 static Lisp_Object
19725 get_it_property (struct it *it, Lisp_Object prop)
19727 Lisp_Object position, object = it->object;
19729 if (STRINGP (object))
19730 position = make_number (IT_STRING_CHARPOS (*it));
19731 else if (BUFFERP (object))
19733 position = make_number (IT_CHARPOS (*it));
19734 object = it->window;
19736 else
19737 return Qnil;
19739 return Fget_char_property (position, prop, object);
19742 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
19744 static void
19745 handle_line_prefix (struct it *it)
19747 Lisp_Object prefix;
19749 if (it->continuation_lines_width > 0)
19751 prefix = get_it_property (it, Qwrap_prefix);
19752 if (NILP (prefix))
19753 prefix = Vwrap_prefix;
19755 else
19757 prefix = get_it_property (it, Qline_prefix);
19758 if (NILP (prefix))
19759 prefix = Vline_prefix;
19761 if (! NILP (prefix) && push_prefix_prop (it, prefix))
19763 /* If the prefix is wider than the window, and we try to wrap
19764 it, it would acquire its own wrap prefix, and so on till the
19765 iterator stack overflows. So, don't wrap the prefix. */
19766 it->line_wrap = TRUNCATE;
19767 it->avoid_cursor_p = 1;
19773 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
19774 only for R2L lines from display_line and display_string, when they
19775 decide that too many glyphs were produced by PRODUCE_GLYPHS, and
19776 the line/string needs to be continued on the next glyph row. */
19777 static void
19778 unproduce_glyphs (struct it *it, int n)
19780 struct glyph *glyph, *end;
19782 eassert (it->glyph_row);
19783 eassert (it->glyph_row->reversed_p);
19784 eassert (it->area == TEXT_AREA);
19785 eassert (n <= it->glyph_row->used[TEXT_AREA]);
19787 if (n > it->glyph_row->used[TEXT_AREA])
19788 n = it->glyph_row->used[TEXT_AREA];
19789 glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
19790 end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
19791 for ( ; glyph < end; glyph++)
19792 glyph[-n] = *glyph;
19795 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
19796 and ROW->maxpos. */
19797 static void
19798 find_row_edges (struct it *it, struct glyph_row *row,
19799 ptrdiff_t min_pos, ptrdiff_t min_bpos,
19800 ptrdiff_t max_pos, ptrdiff_t max_bpos)
19802 /* FIXME: Revisit this when glyph ``spilling'' in continuation
19803 lines' rows is implemented for bidi-reordered rows. */
19805 /* ROW->minpos is the value of min_pos, the minimal buffer position
19806 we have in ROW, or ROW->start.pos if that is smaller. */
19807 if (min_pos <= ZV && min_pos < row->start.pos.charpos)
19808 SET_TEXT_POS (row->minpos, min_pos, min_bpos);
19809 else
19810 /* We didn't find buffer positions smaller than ROW->start, or
19811 didn't find _any_ valid buffer positions in any of the glyphs,
19812 so we must trust the iterator's computed positions. */
19813 row->minpos = row->start.pos;
19814 if (max_pos <= 0)
19816 max_pos = CHARPOS (it->current.pos);
19817 max_bpos = BYTEPOS (it->current.pos);
19820 /* Here are the various use-cases for ending the row, and the
19821 corresponding values for ROW->maxpos:
19823 Line ends in a newline from buffer eol_pos + 1
19824 Line is continued from buffer max_pos + 1
19825 Line is truncated on right it->current.pos
19826 Line ends in a newline from string max_pos + 1(*)
19827 (*) + 1 only when line ends in a forward scan
19828 Line is continued from string max_pos
19829 Line is continued from display vector max_pos
19830 Line is entirely from a string min_pos == max_pos
19831 Line is entirely from a display vector min_pos == max_pos
19832 Line that ends at ZV ZV
19834 If you discover other use-cases, please add them here as
19835 appropriate. */
19836 if (row->ends_at_zv_p)
19837 row->maxpos = it->current.pos;
19838 else if (row->used[TEXT_AREA])
19840 int seen_this_string = 0;
19841 struct glyph_row *r1 = row - 1;
19843 /* Did we see the same display string on the previous row? */
19844 if (STRINGP (it->object)
19845 /* this is not the first row */
19846 && row > it->w->desired_matrix->rows
19847 /* previous row is not the header line */
19848 && !r1->mode_line_p
19849 /* previous row also ends in a newline from a string */
19850 && r1->ends_in_newline_from_string_p)
19852 struct glyph *start, *end;
19854 /* Search for the last glyph of the previous row that came
19855 from buffer or string. Depending on whether the row is
19856 L2R or R2L, we need to process it front to back or the
19857 other way round. */
19858 if (!r1->reversed_p)
19860 start = r1->glyphs[TEXT_AREA];
19861 end = start + r1->used[TEXT_AREA];
19862 /* Glyphs inserted by redisplay have an integer (zero)
19863 as their object. */
19864 while (end > start
19865 && INTEGERP ((end - 1)->object)
19866 && (end - 1)->charpos <= 0)
19867 --end;
19868 if (end > start)
19870 if (EQ ((end - 1)->object, it->object))
19871 seen_this_string = 1;
19873 else
19874 /* If all the glyphs of the previous row were inserted
19875 by redisplay, it means the previous row was
19876 produced from a single newline, which is only
19877 possible if that newline came from the same string
19878 as the one which produced this ROW. */
19879 seen_this_string = 1;
19881 else
19883 end = r1->glyphs[TEXT_AREA] - 1;
19884 start = end + r1->used[TEXT_AREA];
19885 while (end < start
19886 && INTEGERP ((end + 1)->object)
19887 && (end + 1)->charpos <= 0)
19888 ++end;
19889 if (end < start)
19891 if (EQ ((end + 1)->object, it->object))
19892 seen_this_string = 1;
19894 else
19895 seen_this_string = 1;
19898 /* Take note of each display string that covers a newline only
19899 once, the first time we see it. This is for when a display
19900 string includes more than one newline in it. */
19901 if (row->ends_in_newline_from_string_p && !seen_this_string)
19903 /* If we were scanning the buffer forward when we displayed
19904 the string, we want to account for at least one buffer
19905 position that belongs to this row (position covered by
19906 the display string), so that cursor positioning will
19907 consider this row as a candidate when point is at the end
19908 of the visual line represented by this row. This is not
19909 required when scanning back, because max_pos will already
19910 have a much larger value. */
19911 if (CHARPOS (row->end.pos) > max_pos)
19912 INC_BOTH (max_pos, max_bpos);
19913 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19915 else if (CHARPOS (it->eol_pos) > 0)
19916 SET_TEXT_POS (row->maxpos,
19917 CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
19918 else if (row->continued_p)
19920 /* If max_pos is different from IT's current position, it
19921 means IT->method does not belong to the display element
19922 at max_pos. However, it also means that the display
19923 element at max_pos was displayed in its entirety on this
19924 line, which is equivalent to saying that the next line
19925 starts at the next buffer position. */
19926 if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
19927 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19928 else
19930 INC_BOTH (max_pos, max_bpos);
19931 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19934 else if (row->truncated_on_right_p)
19935 /* display_line already called reseat_at_next_visible_line_start,
19936 which puts the iterator at the beginning of the next line, in
19937 the logical order. */
19938 row->maxpos = it->current.pos;
19939 else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
19940 /* A line that is entirely from a string/image/stretch... */
19941 row->maxpos = row->minpos;
19942 else
19943 emacs_abort ();
19945 else
19946 row->maxpos = it->current.pos;
19949 /* Construct the glyph row IT->glyph_row in the desired matrix of
19950 IT->w from text at the current position of IT. See dispextern.h
19951 for an overview of struct it. Value is non-zero if
19952 IT->glyph_row displays text, as opposed to a line displaying ZV
19953 only. */
19955 static int
19956 display_line (struct it *it)
19958 struct glyph_row *row = it->glyph_row;
19959 Lisp_Object overlay_arrow_string;
19960 struct it wrap_it;
19961 void *wrap_data = NULL;
19962 int may_wrap = 0, wrap_x IF_LINT (= 0);
19963 int wrap_row_used = -1;
19964 int wrap_row_ascent IF_LINT (= 0), wrap_row_height IF_LINT (= 0);
19965 int wrap_row_phys_ascent IF_LINT (= 0), wrap_row_phys_height IF_LINT (= 0);
19966 int wrap_row_extra_line_spacing IF_LINT (= 0);
19967 ptrdiff_t wrap_row_min_pos IF_LINT (= 0), wrap_row_min_bpos IF_LINT (= 0);
19968 ptrdiff_t wrap_row_max_pos IF_LINT (= 0), wrap_row_max_bpos IF_LINT (= 0);
19969 int cvpos;
19970 ptrdiff_t min_pos = ZV + 1, max_pos = 0;
19971 ptrdiff_t min_bpos IF_LINT (= 0), max_bpos IF_LINT (= 0);
19972 bool pending_handle_line_prefix = false;
19974 /* We always start displaying at hpos zero even if hscrolled. */
19975 eassert (it->hpos == 0 && it->current_x == 0);
19977 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
19978 >= it->w->desired_matrix->nrows)
19980 it->w->nrows_scale_factor++;
19981 it->f->fonts_changed = 1;
19982 return 0;
19985 /* Clear the result glyph row and enable it. */
19986 prepare_desired_row (it->w, row, false);
19988 row->y = it->current_y;
19989 row->start = it->start;
19990 row->continuation_lines_width = it->continuation_lines_width;
19991 row->displays_text_p = 1;
19992 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
19993 it->starts_in_middle_of_char_p = 0;
19995 /* Arrange the overlays nicely for our purposes. Usually, we call
19996 display_line on only one line at a time, in which case this
19997 can't really hurt too much, or we call it on lines which appear
19998 one after another in the buffer, in which case all calls to
19999 recenter_overlay_lists but the first will be pretty cheap. */
20000 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
20002 /* Move over display elements that are not visible because we are
20003 hscrolled. This may stop at an x-position < IT->first_visible_x
20004 if the first glyph is partially visible or if we hit a line end. */
20005 if (it->current_x < it->first_visible_x)
20007 enum move_it_result move_result;
20009 this_line_min_pos = row->start.pos;
20010 move_result = move_it_in_display_line_to (it, ZV, it->first_visible_x,
20011 MOVE_TO_POS | MOVE_TO_X);
20012 /* If we are under a large hscroll, move_it_in_display_line_to
20013 could hit the end of the line without reaching
20014 it->first_visible_x. Pretend that we did reach it. This is
20015 especially important on a TTY, where we will call
20016 extend_face_to_end_of_line, which needs to know how many
20017 blank glyphs to produce. */
20018 if (it->current_x < it->first_visible_x
20019 && (move_result == MOVE_NEWLINE_OR_CR
20020 || move_result == MOVE_POS_MATCH_OR_ZV))
20021 it->current_x = it->first_visible_x;
20023 /* Record the smallest positions seen while we moved over
20024 display elements that are not visible. This is needed by
20025 redisplay_internal for optimizing the case where the cursor
20026 stays inside the same line. The rest of this function only
20027 considers positions that are actually displayed, so
20028 RECORD_MAX_MIN_POS will not otherwise record positions that
20029 are hscrolled to the left of the left edge of the window. */
20030 min_pos = CHARPOS (this_line_min_pos);
20031 min_bpos = BYTEPOS (this_line_min_pos);
20033 else if (it->area == TEXT_AREA)
20035 /* We only do this when not calling move_it_in_display_line_to
20036 above, because that function calls itself handle_line_prefix. */
20037 handle_line_prefix (it);
20039 else
20041 /* Line-prefix and wrap-prefix are always displayed in the text
20042 area. But if this is the first call to display_line after
20043 init_iterator, the iterator might have been set up to write
20044 into a marginal area, e.g. if the line begins with some
20045 display property that writes to the margins. So we need to
20046 wait with the call to handle_line_prefix until whatever
20047 writes to the margin has done its job. */
20048 pending_handle_line_prefix = true;
20051 /* Get the initial row height. This is either the height of the
20052 text hscrolled, if there is any, or zero. */
20053 row->ascent = it->max_ascent;
20054 row->height = it->max_ascent + it->max_descent;
20055 row->phys_ascent = it->max_phys_ascent;
20056 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
20057 row->extra_line_spacing = it->max_extra_line_spacing;
20059 /* Utility macro to record max and min buffer positions seen until now. */
20060 #define RECORD_MAX_MIN_POS(IT) \
20061 do \
20063 int composition_p = !STRINGP ((IT)->string) \
20064 && ((IT)->what == IT_COMPOSITION); \
20065 ptrdiff_t current_pos = \
20066 composition_p ? (IT)->cmp_it.charpos \
20067 : IT_CHARPOS (*(IT)); \
20068 ptrdiff_t current_bpos = \
20069 composition_p ? CHAR_TO_BYTE (current_pos) \
20070 : IT_BYTEPOS (*(IT)); \
20071 if (current_pos < min_pos) \
20073 min_pos = current_pos; \
20074 min_bpos = current_bpos; \
20076 if (IT_CHARPOS (*it) > max_pos) \
20078 max_pos = IT_CHARPOS (*it); \
20079 max_bpos = IT_BYTEPOS (*it); \
20082 while (0)
20084 /* Loop generating characters. The loop is left with IT on the next
20085 character to display. */
20086 while (1)
20088 int n_glyphs_before, hpos_before, x_before;
20089 int x, nglyphs;
20090 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
20092 /* Retrieve the next thing to display. Value is zero if end of
20093 buffer reached. */
20094 if (!get_next_display_element (it))
20096 /* Maybe add a space at the end of this line that is used to
20097 display the cursor there under X. Set the charpos of the
20098 first glyph of blank lines not corresponding to any text
20099 to -1. */
20100 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
20101 row->exact_window_width_line_p = 1;
20102 else if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
20103 || row->used[TEXT_AREA] == 0)
20105 row->glyphs[TEXT_AREA]->charpos = -1;
20106 row->displays_text_p = 0;
20108 if (!NILP (BVAR (XBUFFER (it->w->contents), indicate_empty_lines))
20109 && (!MINI_WINDOW_P (it->w)
20110 || (minibuf_level && EQ (it->window, minibuf_window))))
20111 row->indicate_empty_line_p = 1;
20114 it->continuation_lines_width = 0;
20115 row->ends_at_zv_p = 1;
20116 /* A row that displays right-to-left text must always have
20117 its last face extended all the way to the end of line,
20118 even if this row ends in ZV, because we still write to
20119 the screen left to right. We also need to extend the
20120 last face if the default face is remapped to some
20121 different face, otherwise the functions that clear
20122 portions of the screen will clear with the default face's
20123 background color. */
20124 if (row->reversed_p
20125 || lookup_basic_face (it->f, DEFAULT_FACE_ID) != DEFAULT_FACE_ID)
20126 extend_face_to_end_of_line (it);
20127 break;
20130 /* Now, get the metrics of what we want to display. This also
20131 generates glyphs in `row' (which is IT->glyph_row). */
20132 n_glyphs_before = row->used[TEXT_AREA];
20133 x = it->current_x;
20135 /* Remember the line height so far in case the next element doesn't
20136 fit on the line. */
20137 if (it->line_wrap != TRUNCATE)
20139 ascent = it->max_ascent;
20140 descent = it->max_descent;
20141 phys_ascent = it->max_phys_ascent;
20142 phys_descent = it->max_phys_descent;
20144 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
20146 if (IT_DISPLAYING_WHITESPACE (it))
20147 may_wrap = 1;
20148 else if (may_wrap)
20150 SAVE_IT (wrap_it, *it, wrap_data);
20151 wrap_x = x;
20152 wrap_row_used = row->used[TEXT_AREA];
20153 wrap_row_ascent = row->ascent;
20154 wrap_row_height = row->height;
20155 wrap_row_phys_ascent = row->phys_ascent;
20156 wrap_row_phys_height = row->phys_height;
20157 wrap_row_extra_line_spacing = row->extra_line_spacing;
20158 wrap_row_min_pos = min_pos;
20159 wrap_row_min_bpos = min_bpos;
20160 wrap_row_max_pos = max_pos;
20161 wrap_row_max_bpos = max_bpos;
20162 may_wrap = 0;
20167 PRODUCE_GLYPHS (it);
20169 /* If this display element was in marginal areas, continue with
20170 the next one. */
20171 if (it->area != TEXT_AREA)
20173 row->ascent = max (row->ascent, it->max_ascent);
20174 row->height = max (row->height, it->max_ascent + it->max_descent);
20175 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
20176 row->phys_height = max (row->phys_height,
20177 it->max_phys_ascent + it->max_phys_descent);
20178 row->extra_line_spacing = max (row->extra_line_spacing,
20179 it->max_extra_line_spacing);
20180 set_iterator_to_next (it, 1);
20181 /* If we didn't handle the line/wrap prefix above, and the
20182 call to set_iterator_to_next just switched to TEXT_AREA,
20183 process the prefix now. */
20184 if (it->area == TEXT_AREA && pending_handle_line_prefix)
20186 pending_handle_line_prefix = false;
20187 handle_line_prefix (it);
20189 continue;
20192 /* Does the display element fit on the line? If we truncate
20193 lines, we should draw past the right edge of the window. If
20194 we don't truncate, we want to stop so that we can display the
20195 continuation glyph before the right margin. If lines are
20196 continued, there are two possible strategies for characters
20197 resulting in more than 1 glyph (e.g. tabs): Display as many
20198 glyphs as possible in this line and leave the rest for the
20199 continuation line, or display the whole element in the next
20200 line. Original redisplay did the former, so we do it also. */
20201 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
20202 hpos_before = it->hpos;
20203 x_before = x;
20205 if (/* Not a newline. */
20206 nglyphs > 0
20207 /* Glyphs produced fit entirely in the line. */
20208 && it->current_x < it->last_visible_x)
20210 it->hpos += nglyphs;
20211 row->ascent = max (row->ascent, it->max_ascent);
20212 row->height = max (row->height, it->max_ascent + it->max_descent);
20213 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
20214 row->phys_height = max (row->phys_height,
20215 it->max_phys_ascent + it->max_phys_descent);
20216 row->extra_line_spacing = max (row->extra_line_spacing,
20217 it->max_extra_line_spacing);
20218 if (it->current_x - it->pixel_width < it->first_visible_x
20219 /* In R2L rows, we arrange in extend_face_to_end_of_line
20220 to add a right offset to the line, by a suitable
20221 change to the stretch glyph that is the leftmost
20222 glyph of the line. */
20223 && !row->reversed_p)
20224 row->x = x - it->first_visible_x;
20225 /* Record the maximum and minimum buffer positions seen so
20226 far in glyphs that will be displayed by this row. */
20227 if (it->bidi_p)
20228 RECORD_MAX_MIN_POS (it);
20230 else
20232 int i, new_x;
20233 struct glyph *glyph;
20235 for (i = 0; i < nglyphs; ++i, x = new_x)
20237 /* Identify the glyphs added by the last call to
20238 PRODUCE_GLYPHS. In R2L rows, they are prepended to
20239 the previous glyphs. */
20240 if (!row->reversed_p)
20241 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
20242 else
20243 glyph = row->glyphs[TEXT_AREA] + nglyphs - 1 - i;
20244 new_x = x + glyph->pixel_width;
20246 if (/* Lines are continued. */
20247 it->line_wrap != TRUNCATE
20248 && (/* Glyph doesn't fit on the line. */
20249 new_x > it->last_visible_x
20250 /* Or it fits exactly on a window system frame. */
20251 || (new_x == it->last_visible_x
20252 && FRAME_WINDOW_P (it->f)
20253 && (row->reversed_p
20254 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
20255 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
20257 /* End of a continued line. */
20259 if (it->hpos == 0
20260 || (new_x == it->last_visible_x
20261 && FRAME_WINDOW_P (it->f)
20262 && (row->reversed_p
20263 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
20264 : WINDOW_RIGHT_FRINGE_WIDTH (it->w))))
20266 /* Current glyph is the only one on the line or
20267 fits exactly on the line. We must continue
20268 the line because we can't draw the cursor
20269 after the glyph. */
20270 row->continued_p = 1;
20271 it->current_x = new_x;
20272 it->continuation_lines_width += new_x;
20273 ++it->hpos;
20274 if (i == nglyphs - 1)
20276 /* If line-wrap is on, check if a previous
20277 wrap point was found. */
20278 if (wrap_row_used > 0
20279 /* Even if there is a previous wrap
20280 point, continue the line here as
20281 usual, if (i) the previous character
20282 was a space or tab AND (ii) the
20283 current character is not. */
20284 && (!may_wrap
20285 || IT_DISPLAYING_WHITESPACE (it)))
20286 goto back_to_wrap;
20288 /* Record the maximum and minimum buffer
20289 positions seen so far in glyphs that will be
20290 displayed by this row. */
20291 if (it->bidi_p)
20292 RECORD_MAX_MIN_POS (it);
20293 set_iterator_to_next (it, 1);
20294 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
20296 if (!get_next_display_element (it))
20298 row->exact_window_width_line_p = 1;
20299 it->continuation_lines_width = 0;
20300 row->continued_p = 0;
20301 row->ends_at_zv_p = 1;
20303 else if (ITERATOR_AT_END_OF_LINE_P (it))
20305 row->continued_p = 0;
20306 row->exact_window_width_line_p = 1;
20310 else if (it->bidi_p)
20311 RECORD_MAX_MIN_POS (it);
20312 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
20313 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)
20314 extend_face_to_end_of_line (it);
20316 else if (CHAR_GLYPH_PADDING_P (*glyph)
20317 && !FRAME_WINDOW_P (it->f))
20319 /* A padding glyph that doesn't fit on this line.
20320 This means the whole character doesn't fit
20321 on the line. */
20322 if (row->reversed_p)
20323 unproduce_glyphs (it, row->used[TEXT_AREA]
20324 - n_glyphs_before);
20325 row->used[TEXT_AREA] = n_glyphs_before;
20327 /* Fill the rest of the row with continuation
20328 glyphs like in 20.x. */
20329 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
20330 < row->glyphs[1 + TEXT_AREA])
20331 produce_special_glyphs (it, IT_CONTINUATION);
20333 row->continued_p = 1;
20334 it->current_x = x_before;
20335 it->continuation_lines_width += x_before;
20337 /* Restore the height to what it was before the
20338 element not fitting on the line. */
20339 it->max_ascent = ascent;
20340 it->max_descent = descent;
20341 it->max_phys_ascent = phys_ascent;
20342 it->max_phys_descent = phys_descent;
20343 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
20344 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)
20345 extend_face_to_end_of_line (it);
20347 else if (wrap_row_used > 0)
20349 back_to_wrap:
20350 if (row->reversed_p)
20351 unproduce_glyphs (it,
20352 row->used[TEXT_AREA] - wrap_row_used);
20353 RESTORE_IT (it, &wrap_it, wrap_data);
20354 it->continuation_lines_width += wrap_x;
20355 row->used[TEXT_AREA] = wrap_row_used;
20356 row->ascent = wrap_row_ascent;
20357 row->height = wrap_row_height;
20358 row->phys_ascent = wrap_row_phys_ascent;
20359 row->phys_height = wrap_row_phys_height;
20360 row->extra_line_spacing = wrap_row_extra_line_spacing;
20361 min_pos = wrap_row_min_pos;
20362 min_bpos = wrap_row_min_bpos;
20363 max_pos = wrap_row_max_pos;
20364 max_bpos = wrap_row_max_bpos;
20365 row->continued_p = 1;
20366 row->ends_at_zv_p = 0;
20367 row->exact_window_width_line_p = 0;
20368 it->continuation_lines_width += x;
20370 /* Make sure that a non-default face is extended
20371 up to the right margin of the window. */
20372 extend_face_to_end_of_line (it);
20374 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
20376 /* A TAB that extends past the right edge of the
20377 window. This produces a single glyph on
20378 window system frames. We leave the glyph in
20379 this row and let it fill the row, but don't
20380 consume the TAB. */
20381 if ((row->reversed_p
20382 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
20383 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
20384 produce_special_glyphs (it, IT_CONTINUATION);
20385 it->continuation_lines_width += it->last_visible_x;
20386 row->ends_in_middle_of_char_p = 1;
20387 row->continued_p = 1;
20388 glyph->pixel_width = it->last_visible_x - x;
20389 it->starts_in_middle_of_char_p = 1;
20390 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
20391 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)
20392 extend_face_to_end_of_line (it);
20394 else
20396 /* Something other than a TAB that draws past
20397 the right edge of the window. Restore
20398 positions to values before the element. */
20399 if (row->reversed_p)
20400 unproduce_glyphs (it, row->used[TEXT_AREA]
20401 - (n_glyphs_before + i));
20402 row->used[TEXT_AREA] = n_glyphs_before + i;
20404 /* Display continuation glyphs. */
20405 it->current_x = x_before;
20406 it->continuation_lines_width += x;
20407 if (!FRAME_WINDOW_P (it->f)
20408 || (row->reversed_p
20409 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
20410 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
20411 produce_special_glyphs (it, IT_CONTINUATION);
20412 row->continued_p = 1;
20414 extend_face_to_end_of_line (it);
20416 if (nglyphs > 1 && i > 0)
20418 row->ends_in_middle_of_char_p = 1;
20419 it->starts_in_middle_of_char_p = 1;
20422 /* Restore the height to what it was before the
20423 element not fitting on the line. */
20424 it->max_ascent = ascent;
20425 it->max_descent = descent;
20426 it->max_phys_ascent = phys_ascent;
20427 it->max_phys_descent = phys_descent;
20430 break;
20432 else if (new_x > it->first_visible_x)
20434 /* Increment number of glyphs actually displayed. */
20435 ++it->hpos;
20437 /* Record the maximum and minimum buffer positions
20438 seen so far in glyphs that will be displayed by
20439 this row. */
20440 if (it->bidi_p)
20441 RECORD_MAX_MIN_POS (it);
20443 if (x < it->first_visible_x && !row->reversed_p)
20444 /* Glyph is partially visible, i.e. row starts at
20445 negative X position. Don't do that in R2L
20446 rows, where we arrange to add a right offset to
20447 the line in extend_face_to_end_of_line, by a
20448 suitable change to the stretch glyph that is
20449 the leftmost glyph of the line. */
20450 row->x = x - it->first_visible_x;
20451 /* When the last glyph of an R2L row only fits
20452 partially on the line, we need to set row->x to a
20453 negative offset, so that the leftmost glyph is
20454 the one that is partially visible. */
20455 if (row->reversed_p && new_x > it->last_visible_x)
20456 row->x = it->last_visible_x - new_x;
20458 else
20460 /* Glyph is completely off the left margin of the
20461 window. This should not happen because of the
20462 move_it_in_display_line at the start of this
20463 function, unless the text display area of the
20464 window is empty. */
20465 eassert (it->first_visible_x <= it->last_visible_x);
20468 /* Even if this display element produced no glyphs at all,
20469 we want to record its position. */
20470 if (it->bidi_p && nglyphs == 0)
20471 RECORD_MAX_MIN_POS (it);
20473 row->ascent = max (row->ascent, it->max_ascent);
20474 row->height = max (row->height, it->max_ascent + it->max_descent);
20475 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
20476 row->phys_height = max (row->phys_height,
20477 it->max_phys_ascent + it->max_phys_descent);
20478 row->extra_line_spacing = max (row->extra_line_spacing,
20479 it->max_extra_line_spacing);
20481 /* End of this display line if row is continued. */
20482 if (row->continued_p || row->ends_at_zv_p)
20483 break;
20486 at_end_of_line:
20487 /* Is this a line end? If yes, we're also done, after making
20488 sure that a non-default face is extended up to the right
20489 margin of the window. */
20490 if (ITERATOR_AT_END_OF_LINE_P (it))
20492 int used_before = row->used[TEXT_AREA];
20494 row->ends_in_newline_from_string_p = STRINGP (it->object);
20496 /* Add a space at the end of the line that is used to
20497 display the cursor there. */
20498 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
20499 append_space_for_newline (it, 0);
20501 /* Extend the face to the end of the line. */
20502 extend_face_to_end_of_line (it);
20504 /* Make sure we have the position. */
20505 if (used_before == 0)
20506 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
20508 /* Record the position of the newline, for use in
20509 find_row_edges. */
20510 it->eol_pos = it->current.pos;
20512 /* Consume the line end. This skips over invisible lines. */
20513 set_iterator_to_next (it, 1);
20514 it->continuation_lines_width = 0;
20515 break;
20518 /* Proceed with next display element. Note that this skips
20519 over lines invisible because of selective display. */
20520 set_iterator_to_next (it, 1);
20522 /* If we truncate lines, we are done when the last displayed
20523 glyphs reach past the right margin of the window. */
20524 if (it->line_wrap == TRUNCATE
20525 && ((FRAME_WINDOW_P (it->f)
20526 /* Images are preprocessed in produce_image_glyph such
20527 that they are cropped at the right edge of the
20528 window, so an image glyph will always end exactly at
20529 last_visible_x, even if there's no right fringe. */
20530 && (WINDOW_RIGHT_FRINGE_WIDTH (it->w) || it->what == IT_IMAGE))
20531 ? (it->current_x >= it->last_visible_x)
20532 : (it->current_x > it->last_visible_x)))
20534 /* Maybe add truncation glyphs. */
20535 if (!FRAME_WINDOW_P (it->f)
20536 || (row->reversed_p
20537 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
20538 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
20540 int i, n;
20542 if (!row->reversed_p)
20544 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
20545 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
20546 break;
20548 else
20550 for (i = 0; i < row->used[TEXT_AREA]; i++)
20551 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
20552 break;
20553 /* Remove any padding glyphs at the front of ROW, to
20554 make room for the truncation glyphs we will be
20555 adding below. The loop below always inserts at
20556 least one truncation glyph, so also remove the
20557 last glyph added to ROW. */
20558 unproduce_glyphs (it, i + 1);
20559 /* Adjust i for the loop below. */
20560 i = row->used[TEXT_AREA] - (i + 1);
20563 /* produce_special_glyphs overwrites the last glyph, so
20564 we don't want that if we want to keep that last
20565 glyph, which means it's an image. */
20566 if (it->current_x > it->last_visible_x)
20568 it->current_x = x_before;
20569 if (!FRAME_WINDOW_P (it->f))
20571 for (n = row->used[TEXT_AREA]; i < n; ++i)
20573 row->used[TEXT_AREA] = i;
20574 produce_special_glyphs (it, IT_TRUNCATION);
20577 else
20579 row->used[TEXT_AREA] = i;
20580 produce_special_glyphs (it, IT_TRUNCATION);
20582 it->hpos = hpos_before;
20585 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
20587 /* Don't truncate if we can overflow newline into fringe. */
20588 if (!get_next_display_element (it))
20590 it->continuation_lines_width = 0;
20591 row->ends_at_zv_p = 1;
20592 row->exact_window_width_line_p = 1;
20593 break;
20595 if (ITERATOR_AT_END_OF_LINE_P (it))
20597 row->exact_window_width_line_p = 1;
20598 goto at_end_of_line;
20600 it->current_x = x_before;
20601 it->hpos = hpos_before;
20604 row->truncated_on_right_p = 1;
20605 it->continuation_lines_width = 0;
20606 reseat_at_next_visible_line_start (it, 0);
20607 if (IT_BYTEPOS (*it) <= BEG_BYTE)
20608 row->ends_at_zv_p = true;
20609 else
20610 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
20611 break;
20615 if (wrap_data)
20616 bidi_unshelve_cache (wrap_data, 1);
20618 /* If line is not empty and hscrolled, maybe insert truncation glyphs
20619 at the left window margin. */
20620 if (it->first_visible_x
20621 && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
20623 if (!FRAME_WINDOW_P (it->f)
20624 || (((row->reversed_p
20625 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
20626 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
20627 /* Don't let insert_left_trunc_glyphs overwrite the
20628 first glyph of the row if it is an image. */
20629 && row->glyphs[TEXT_AREA]->type != IMAGE_GLYPH))
20630 insert_left_trunc_glyphs (it);
20631 row->truncated_on_left_p = 1;
20634 /* Remember the position at which this line ends.
20636 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
20637 cannot be before the call to find_row_edges below, since that is
20638 where these positions are determined. */
20639 row->end = it->current;
20640 if (!it->bidi_p)
20642 row->minpos = row->start.pos;
20643 row->maxpos = row->end.pos;
20645 else
20647 /* ROW->minpos and ROW->maxpos must be the smallest and
20648 `1 + the largest' buffer positions in ROW. But if ROW was
20649 bidi-reordered, these two positions can be anywhere in the
20650 row, so we must determine them now. */
20651 find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
20654 /* If the start of this line is the overlay arrow-position, then
20655 mark this glyph row as the one containing the overlay arrow.
20656 This is clearly a mess with variable size fonts. It would be
20657 better to let it be displayed like cursors under X. */
20658 if ((MATRIX_ROW_DISPLAYS_TEXT_P (row) || !overlay_arrow_seen)
20659 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
20660 !NILP (overlay_arrow_string)))
20662 /* Overlay arrow in window redisplay is a fringe bitmap. */
20663 if (STRINGP (overlay_arrow_string))
20665 struct glyph_row *arrow_row
20666 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
20667 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
20668 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
20669 struct glyph *p = row->glyphs[TEXT_AREA];
20670 struct glyph *p2, *end;
20672 /* Copy the arrow glyphs. */
20673 while (glyph < arrow_end)
20674 *p++ = *glyph++;
20676 /* Throw away padding glyphs. */
20677 p2 = p;
20678 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
20679 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
20680 ++p2;
20681 if (p2 > p)
20683 while (p2 < end)
20684 *p++ = *p2++;
20685 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
20688 else
20690 eassert (INTEGERP (overlay_arrow_string));
20691 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
20693 overlay_arrow_seen = 1;
20696 /* Highlight trailing whitespace. */
20697 if (!NILP (Vshow_trailing_whitespace))
20698 highlight_trailing_whitespace (it->f, it->glyph_row);
20700 /* Compute pixel dimensions of this line. */
20701 compute_line_metrics (it);
20703 /* Implementation note: No changes in the glyphs of ROW or in their
20704 faces can be done past this point, because compute_line_metrics
20705 computes ROW's hash value and stores it within the glyph_row
20706 structure. */
20708 /* Record whether this row ends inside an ellipsis. */
20709 row->ends_in_ellipsis_p
20710 = (it->method == GET_FROM_DISPLAY_VECTOR
20711 && it->ellipsis_p);
20713 /* Save fringe bitmaps in this row. */
20714 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
20715 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
20716 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
20717 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
20719 it->left_user_fringe_bitmap = 0;
20720 it->left_user_fringe_face_id = 0;
20721 it->right_user_fringe_bitmap = 0;
20722 it->right_user_fringe_face_id = 0;
20724 /* Maybe set the cursor. */
20725 cvpos = it->w->cursor.vpos;
20726 if ((cvpos < 0
20727 /* In bidi-reordered rows, keep checking for proper cursor
20728 position even if one has been found already, because buffer
20729 positions in such rows change non-linearly with ROW->VPOS,
20730 when a line is continued. One exception: when we are at ZV,
20731 display cursor on the first suitable glyph row, since all
20732 the empty rows after that also have their position set to ZV. */
20733 /* FIXME: Revisit this when glyph ``spilling'' in continuation
20734 lines' rows is implemented for bidi-reordered rows. */
20735 || (it->bidi_p
20736 && !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
20737 && PT >= MATRIX_ROW_START_CHARPOS (row)
20738 && PT <= MATRIX_ROW_END_CHARPOS (row)
20739 && cursor_row_p (row))
20740 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
20742 /* Prepare for the next line. This line starts horizontally at (X
20743 HPOS) = (0 0). Vertical positions are incremented. As a
20744 convenience for the caller, IT->glyph_row is set to the next
20745 row to be used. */
20746 it->current_x = it->hpos = 0;
20747 it->current_y += row->height;
20748 SET_TEXT_POS (it->eol_pos, 0, 0);
20749 ++it->vpos;
20750 ++it->glyph_row;
20751 /* The next row should by default use the same value of the
20752 reversed_p flag as this one. set_iterator_to_next decides when
20753 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
20754 the flag accordingly. */
20755 if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
20756 it->glyph_row->reversed_p = row->reversed_p;
20757 it->start = row->end;
20758 return MATRIX_ROW_DISPLAYS_TEXT_P (row);
20760 #undef RECORD_MAX_MIN_POS
20763 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,
20764 Scurrent_bidi_paragraph_direction, 0, 1, 0,
20765 doc: /* Return paragraph direction at point in BUFFER.
20766 Value is either `left-to-right' or `right-to-left'.
20767 If BUFFER is omitted or nil, it defaults to the current buffer.
20769 Paragraph direction determines how the text in the paragraph is displayed.
20770 In left-to-right paragraphs, text begins at the left margin of the window
20771 and the reading direction is generally left to right. In right-to-left
20772 paragraphs, text begins at the right margin and is read from right to left.
20774 See also `bidi-paragraph-direction'. */)
20775 (Lisp_Object buffer)
20777 struct buffer *buf = current_buffer;
20778 struct buffer *old = buf;
20780 if (! NILP (buffer))
20782 CHECK_BUFFER (buffer);
20783 buf = XBUFFER (buffer);
20786 if (NILP (BVAR (buf, bidi_display_reordering))
20787 || NILP (BVAR (buf, enable_multibyte_characters))
20788 /* When we are loading loadup.el, the character property tables
20789 needed for bidi iteration are not yet available. */
20790 || !NILP (Vpurify_flag))
20791 return Qleft_to_right;
20792 else if (!NILP (BVAR (buf, bidi_paragraph_direction)))
20793 return BVAR (buf, bidi_paragraph_direction);
20794 else
20796 /* Determine the direction from buffer text. We could try to
20797 use current_matrix if it is up to date, but this seems fast
20798 enough as it is. */
20799 struct bidi_it itb;
20800 ptrdiff_t pos = BUF_PT (buf);
20801 ptrdiff_t bytepos = BUF_PT_BYTE (buf);
20802 int c;
20803 void *itb_data = bidi_shelve_cache ();
20805 set_buffer_temp (buf);
20806 /* bidi_paragraph_init finds the base direction of the paragraph
20807 by searching forward from paragraph start. We need the base
20808 direction of the current or _previous_ paragraph, so we need
20809 to make sure we are within that paragraph. To that end, find
20810 the previous non-empty line. */
20811 if (pos >= ZV && pos > BEGV)
20812 DEC_BOTH (pos, bytepos);
20813 if (fast_looking_at (build_string ("[\f\t ]*\n"),
20814 pos, bytepos, ZV, ZV_BYTE, Qnil) > 0)
20816 while ((c = FETCH_BYTE (bytepos)) == '\n'
20817 || c == ' ' || c == '\t' || c == '\f')
20819 if (bytepos <= BEGV_BYTE)
20820 break;
20821 bytepos--;
20822 pos--;
20824 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos)))
20825 bytepos--;
20827 bidi_init_it (pos, bytepos, FRAME_WINDOW_P (SELECTED_FRAME ()), &itb);
20828 itb.paragraph_dir = NEUTRAL_DIR;
20829 itb.string.s = NULL;
20830 itb.string.lstring = Qnil;
20831 itb.string.bufpos = 0;
20832 itb.string.from_disp_str = 0;
20833 itb.string.unibyte = 0;
20834 /* We have no window to use here for ignoring window-specific
20835 overlays. Using NULL for window pointer will cause
20836 compute_display_string_pos to use the current buffer. */
20837 itb.w = NULL;
20838 bidi_paragraph_init (NEUTRAL_DIR, &itb, 1);
20839 bidi_unshelve_cache (itb_data, 0);
20840 set_buffer_temp (old);
20841 switch (itb.paragraph_dir)
20843 case L2R:
20844 return Qleft_to_right;
20845 break;
20846 case R2L:
20847 return Qright_to_left;
20848 break;
20849 default:
20850 emacs_abort ();
20855 DEFUN ("move-point-visually", Fmove_point_visually,
20856 Smove_point_visually, 1, 1, 0,
20857 doc: /* Move point in the visual order in the specified DIRECTION.
20858 DIRECTION can be 1, meaning move to the right, or -1, which moves to the
20859 left.
20861 Value is the new character position of point. */)
20862 (Lisp_Object direction)
20864 struct window *w = XWINDOW (selected_window);
20865 struct buffer *b = XBUFFER (w->contents);
20866 struct glyph_row *row;
20867 int dir;
20868 Lisp_Object paragraph_dir;
20870 #define ROW_GLYPH_NEWLINE_P(ROW,GLYPH) \
20871 (!(ROW)->continued_p \
20872 && INTEGERP ((GLYPH)->object) \
20873 && (GLYPH)->type == CHAR_GLYPH \
20874 && (GLYPH)->u.ch == ' ' \
20875 && (GLYPH)->charpos >= 0 \
20876 && !(GLYPH)->avoid_cursor_p)
20878 CHECK_NUMBER (direction);
20879 dir = XINT (direction);
20880 if (dir > 0)
20881 dir = 1;
20882 else
20883 dir = -1;
20885 /* If current matrix is up-to-date, we can use the information
20886 recorded in the glyphs, at least as long as the goal is on the
20887 screen. */
20888 if (w->window_end_valid
20889 && !windows_or_buffers_changed
20890 && b
20891 && !b->clip_changed
20892 && !b->prevent_redisplay_optimizations_p
20893 && !window_outdated (w)
20894 /* We rely below on the cursor coordinates to be up to date, but
20895 we cannot trust them if some command moved point since the
20896 last complete redisplay. */
20897 && w->last_point == BUF_PT (b)
20898 && w->cursor.vpos >= 0
20899 && w->cursor.vpos < w->current_matrix->nrows
20900 && (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos))->enabled_p)
20902 struct glyph *g = row->glyphs[TEXT_AREA];
20903 struct glyph *e = dir > 0 ? g + row->used[TEXT_AREA] : g - 1;
20904 struct glyph *gpt = g + w->cursor.hpos;
20906 for (g = gpt + dir; (dir > 0 ? g < e : g > e); g += dir)
20908 if (BUFFERP (g->object) && g->charpos != PT)
20910 SET_PT (g->charpos);
20911 w->cursor.vpos = -1;
20912 return make_number (PT);
20914 else if (!INTEGERP (g->object) && !EQ (g->object, gpt->object))
20916 ptrdiff_t new_pos;
20918 if (BUFFERP (gpt->object))
20920 new_pos = PT;
20921 if ((gpt->resolved_level - row->reversed_p) % 2 == 0)
20922 new_pos += (row->reversed_p ? -dir : dir);
20923 else
20924 new_pos -= (row->reversed_p ? -dir : dir);;
20926 else if (BUFFERP (g->object))
20927 new_pos = g->charpos;
20928 else
20929 break;
20930 SET_PT (new_pos);
20931 w->cursor.vpos = -1;
20932 return make_number (PT);
20934 else if (ROW_GLYPH_NEWLINE_P (row, g))
20936 /* Glyphs inserted at the end of a non-empty line for
20937 positioning the cursor have zero charpos, so we must
20938 deduce the value of point by other means. */
20939 if (g->charpos > 0)
20940 SET_PT (g->charpos);
20941 else if (row->ends_at_zv_p && PT != ZV)
20942 SET_PT (ZV);
20943 else if (PT != MATRIX_ROW_END_CHARPOS (row) - 1)
20944 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
20945 else
20946 break;
20947 w->cursor.vpos = -1;
20948 return make_number (PT);
20951 if (g == e || INTEGERP (g->object))
20953 if (row->truncated_on_left_p || row->truncated_on_right_p)
20954 goto simulate_display;
20955 if (!row->reversed_p)
20956 row += dir;
20957 else
20958 row -= dir;
20959 if (row < MATRIX_FIRST_TEXT_ROW (w->current_matrix)
20960 || row > MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
20961 goto simulate_display;
20963 if (dir > 0)
20965 if (row->reversed_p && !row->continued_p)
20967 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
20968 w->cursor.vpos = -1;
20969 return make_number (PT);
20971 g = row->glyphs[TEXT_AREA];
20972 e = g + row->used[TEXT_AREA];
20973 for ( ; g < e; g++)
20975 if (BUFFERP (g->object)
20976 /* Empty lines have only one glyph, which stands
20977 for the newline, and whose charpos is the
20978 buffer position of the newline. */
20979 || ROW_GLYPH_NEWLINE_P (row, g)
20980 /* When the buffer ends in a newline, the line at
20981 EOB also has one glyph, but its charpos is -1. */
20982 || (row->ends_at_zv_p
20983 && !row->reversed_p
20984 && INTEGERP (g->object)
20985 && g->type == CHAR_GLYPH
20986 && g->u.ch == ' '))
20988 if (g->charpos > 0)
20989 SET_PT (g->charpos);
20990 else if (!row->reversed_p
20991 && row->ends_at_zv_p
20992 && PT != ZV)
20993 SET_PT (ZV);
20994 else
20995 continue;
20996 w->cursor.vpos = -1;
20997 return make_number (PT);
21001 else
21003 if (!row->reversed_p && !row->continued_p)
21005 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
21006 w->cursor.vpos = -1;
21007 return make_number (PT);
21009 e = row->glyphs[TEXT_AREA];
21010 g = e + row->used[TEXT_AREA] - 1;
21011 for ( ; g >= e; g--)
21013 if (BUFFERP (g->object)
21014 || (ROW_GLYPH_NEWLINE_P (row, g)
21015 && g->charpos > 0)
21016 /* Empty R2L lines on GUI frames have the buffer
21017 position of the newline stored in the stretch
21018 glyph. */
21019 || g->type == STRETCH_GLYPH
21020 || (row->ends_at_zv_p
21021 && row->reversed_p
21022 && INTEGERP (g->object)
21023 && g->type == CHAR_GLYPH
21024 && g->u.ch == ' '))
21026 if (g->charpos > 0)
21027 SET_PT (g->charpos);
21028 else if (row->reversed_p
21029 && row->ends_at_zv_p
21030 && PT != ZV)
21031 SET_PT (ZV);
21032 else
21033 continue;
21034 w->cursor.vpos = -1;
21035 return make_number (PT);
21042 simulate_display:
21044 /* If we wind up here, we failed to move by using the glyphs, so we
21045 need to simulate display instead. */
21047 if (b)
21048 paragraph_dir = Fcurrent_bidi_paragraph_direction (w->contents);
21049 else
21050 paragraph_dir = Qleft_to_right;
21051 if (EQ (paragraph_dir, Qright_to_left))
21052 dir = -dir;
21053 if (PT <= BEGV && dir < 0)
21054 xsignal0 (Qbeginning_of_buffer);
21055 else if (PT >= ZV && dir > 0)
21056 xsignal0 (Qend_of_buffer);
21057 else
21059 struct text_pos pt;
21060 struct it it;
21061 int pt_x, target_x, pixel_width, pt_vpos;
21062 bool at_eol_p;
21063 bool overshoot_expected = false;
21064 bool target_is_eol_p = false;
21066 /* Setup the arena. */
21067 SET_TEXT_POS (pt, PT, PT_BYTE);
21068 start_display (&it, w, pt);
21070 if (it.cmp_it.id < 0
21071 && it.method == GET_FROM_STRING
21072 && it.area == TEXT_AREA
21073 && it.string_from_display_prop_p
21074 && (it.sp > 0 && it.stack[it.sp - 1].method == GET_FROM_BUFFER))
21075 overshoot_expected = true;
21077 /* Find the X coordinate of point. We start from the beginning
21078 of this or previous line to make sure we are before point in
21079 the logical order (since the move_it_* functions can only
21080 move forward). */
21081 reseat:
21082 reseat_at_previous_visible_line_start (&it);
21083 it.current_x = it.hpos = it.current_y = it.vpos = 0;
21084 if (IT_CHARPOS (it) != PT)
21086 move_it_to (&it, overshoot_expected ? PT - 1 : PT,
21087 -1, -1, -1, MOVE_TO_POS);
21088 /* If we missed point because the character there is
21089 displayed out of a display vector that has more than one
21090 glyph, retry expecting overshoot. */
21091 if (it.method == GET_FROM_DISPLAY_VECTOR
21092 && it.current.dpvec_index > 0
21093 && !overshoot_expected)
21095 overshoot_expected = true;
21096 goto reseat;
21098 else if (IT_CHARPOS (it) != PT && !overshoot_expected)
21099 move_it_in_display_line (&it, PT, -1, MOVE_TO_POS);
21101 pt_x = it.current_x;
21102 pt_vpos = it.vpos;
21103 if (dir > 0 || overshoot_expected)
21105 struct glyph_row *row = it.glyph_row;
21107 /* When point is at beginning of line, we don't have
21108 information about the glyph there loaded into struct
21109 it. Calling get_next_display_element fixes that. */
21110 if (pt_x == 0)
21111 get_next_display_element (&it);
21112 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
21113 it.glyph_row = NULL;
21114 PRODUCE_GLYPHS (&it); /* compute it.pixel_width */
21115 it.glyph_row = row;
21116 /* PRODUCE_GLYPHS advances it.current_x, so we must restore
21117 it, lest it will become out of sync with it's buffer
21118 position. */
21119 it.current_x = pt_x;
21121 else
21122 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
21123 pixel_width = it.pixel_width;
21124 if (overshoot_expected && at_eol_p)
21125 pixel_width = 0;
21126 else if (pixel_width <= 0)
21127 pixel_width = 1;
21129 /* If there's a display string (or something similar) at point,
21130 we are actually at the glyph to the left of point, so we need
21131 to correct the X coordinate. */
21132 if (overshoot_expected)
21134 if (it.bidi_p)
21135 pt_x += pixel_width * it.bidi_it.scan_dir;
21136 else
21137 pt_x += pixel_width;
21140 /* Compute target X coordinate, either to the left or to the
21141 right of point. On TTY frames, all characters have the same
21142 pixel width of 1, so we can use that. On GUI frames we don't
21143 have an easy way of getting at the pixel width of the
21144 character to the left of point, so we use a different method
21145 of getting to that place. */
21146 if (dir > 0)
21147 target_x = pt_x + pixel_width;
21148 else
21149 target_x = pt_x - (!FRAME_WINDOW_P (it.f)) * pixel_width;
21151 /* Target X coordinate could be one line above or below the line
21152 of point, in which case we need to adjust the target X
21153 coordinate. Also, if moving to the left, we need to begin at
21154 the left edge of the point's screen line. */
21155 if (dir < 0)
21157 if (pt_x > 0)
21159 start_display (&it, w, pt);
21160 reseat_at_previous_visible_line_start (&it);
21161 it.current_x = it.current_y = it.hpos = 0;
21162 if (pt_vpos != 0)
21163 move_it_by_lines (&it, pt_vpos);
21165 else
21167 move_it_by_lines (&it, -1);
21168 target_x = it.last_visible_x - !FRAME_WINDOW_P (it.f);
21169 target_is_eol_p = true;
21170 /* Under word-wrap, we don't know the x coordinate of
21171 the last character displayed on the previous line,
21172 which immediately precedes the wrap point. To find
21173 out its x coordinate, we try moving to the right
21174 margin of the window, which will stop at the wrap
21175 point, and then reset target_x to point at the
21176 character that precedes the wrap point. This is not
21177 needed on GUI frames, because (see below) there we
21178 move from the left margin one grapheme cluster at a
21179 time, and stop when we hit the wrap point. */
21180 if (!FRAME_WINDOW_P (it.f) && it.line_wrap == WORD_WRAP)
21182 void *it_data = NULL;
21183 struct it it2;
21185 SAVE_IT (it2, it, it_data);
21186 move_it_in_display_line_to (&it, ZV, target_x,
21187 MOVE_TO_POS | MOVE_TO_X);
21188 /* If we arrived at target_x, that _is_ the last
21189 character on the previous line. */
21190 if (it.current_x != target_x)
21191 target_x = it.current_x - 1;
21192 RESTORE_IT (&it, &it2, it_data);
21196 else
21198 if (at_eol_p
21199 || (target_x >= it.last_visible_x
21200 && it.line_wrap != TRUNCATE))
21202 if (pt_x > 0)
21203 move_it_by_lines (&it, 0);
21204 move_it_by_lines (&it, 1);
21205 target_x = 0;
21209 /* Move to the target X coordinate. */
21210 #ifdef HAVE_WINDOW_SYSTEM
21211 /* On GUI frames, as we don't know the X coordinate of the
21212 character to the left of point, moving point to the left
21213 requires walking, one grapheme cluster at a time, until we
21214 find ourself at a place immediately to the left of the
21215 character at point. */
21216 if (FRAME_WINDOW_P (it.f) && dir < 0)
21218 struct text_pos new_pos;
21219 enum move_it_result rc = MOVE_X_REACHED;
21221 if (it.current_x == 0)
21222 get_next_display_element (&it);
21223 if (it.what == IT_COMPOSITION)
21225 new_pos.charpos = it.cmp_it.charpos;
21226 new_pos.bytepos = -1;
21228 else
21229 new_pos = it.current.pos;
21231 while (it.current_x + it.pixel_width <= target_x
21232 && (rc == MOVE_X_REACHED
21233 /* Under word-wrap, move_it_in_display_line_to
21234 stops at correct coordinates, but sometimes
21235 returns MOVE_POS_MATCH_OR_ZV. */
21236 || (it.line_wrap == WORD_WRAP
21237 && rc == MOVE_POS_MATCH_OR_ZV)))
21239 int new_x = it.current_x + it.pixel_width;
21241 /* For composed characters, we want the position of the
21242 first character in the grapheme cluster (usually, the
21243 composition's base character), whereas it.current
21244 might give us the position of the _last_ one, e.g. if
21245 the composition is rendered in reverse due to bidi
21246 reordering. */
21247 if (it.what == IT_COMPOSITION)
21249 new_pos.charpos = it.cmp_it.charpos;
21250 new_pos.bytepos = -1;
21252 else
21253 new_pos = it.current.pos;
21254 if (new_x == it.current_x)
21255 new_x++;
21256 rc = move_it_in_display_line_to (&it, ZV, new_x,
21257 MOVE_TO_POS | MOVE_TO_X);
21258 if (ITERATOR_AT_END_OF_LINE_P (&it) && !target_is_eol_p)
21259 break;
21261 /* The previous position we saw in the loop is the one we
21262 want. */
21263 if (new_pos.bytepos == -1)
21264 new_pos.bytepos = CHAR_TO_BYTE (new_pos.charpos);
21265 it.current.pos = new_pos;
21267 else
21268 #endif
21269 if (it.current_x != target_x)
21270 move_it_in_display_line_to (&it, ZV, target_x, MOVE_TO_POS | MOVE_TO_X);
21272 /* When lines are truncated, the above loop will stop at the
21273 window edge. But we want to get to the end of line, even if
21274 it is beyond the window edge; automatic hscroll will then
21275 scroll the window to show point as appropriate. */
21276 if (target_is_eol_p && it.line_wrap == TRUNCATE
21277 && get_next_display_element (&it))
21279 struct text_pos new_pos = it.current.pos;
21281 while (!ITERATOR_AT_END_OF_LINE_P (&it))
21283 set_iterator_to_next (&it, 0);
21284 if (it.method == GET_FROM_BUFFER)
21285 new_pos = it.current.pos;
21286 if (!get_next_display_element (&it))
21287 break;
21290 it.current.pos = new_pos;
21293 /* If we ended up in a display string that covers point, move to
21294 buffer position to the right in the visual order. */
21295 if (dir > 0)
21297 while (IT_CHARPOS (it) == PT)
21299 set_iterator_to_next (&it, 0);
21300 if (!get_next_display_element (&it))
21301 break;
21305 /* Move point to that position. */
21306 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
21309 return make_number (PT);
21311 #undef ROW_GLYPH_NEWLINE_P
21315 /***********************************************************************
21316 Menu Bar
21317 ***********************************************************************/
21319 /* Redisplay the menu bar in the frame for window W.
21321 The menu bar of X frames that don't have X toolkit support is
21322 displayed in a special window W->frame->menu_bar_window.
21324 The menu bar of terminal frames is treated specially as far as
21325 glyph matrices are concerned. Menu bar lines are not part of
21326 windows, so the update is done directly on the frame matrix rows
21327 for the menu bar. */
21329 static void
21330 display_menu_bar (struct window *w)
21332 struct frame *f = XFRAME (WINDOW_FRAME (w));
21333 struct it it;
21334 Lisp_Object items;
21335 int i;
21337 /* Don't do all this for graphical frames. */
21338 #ifdef HAVE_NTGUI
21339 if (FRAME_W32_P (f))
21340 return;
21341 #endif
21342 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
21343 if (FRAME_X_P (f))
21344 return;
21345 #endif
21347 #ifdef HAVE_NS
21348 if (FRAME_NS_P (f))
21349 return;
21350 #endif /* HAVE_NS */
21352 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
21353 eassert (!FRAME_WINDOW_P (f));
21354 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
21355 it.first_visible_x = 0;
21356 it.last_visible_x = FRAME_PIXEL_WIDTH (f);
21357 #elif defined (HAVE_X_WINDOWS) /* X without toolkit. */
21358 if (FRAME_WINDOW_P (f))
21360 /* Menu bar lines are displayed in the desired matrix of the
21361 dummy window menu_bar_window. */
21362 struct window *menu_w;
21363 menu_w = XWINDOW (f->menu_bar_window);
21364 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
21365 MENU_FACE_ID);
21366 it.first_visible_x = 0;
21367 it.last_visible_x = FRAME_PIXEL_WIDTH (f);
21369 else
21370 #endif /* not USE_X_TOOLKIT and not USE_GTK */
21372 /* This is a TTY frame, i.e. character hpos/vpos are used as
21373 pixel x/y. */
21374 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
21375 MENU_FACE_ID);
21376 it.first_visible_x = 0;
21377 it.last_visible_x = FRAME_COLS (f);
21380 /* FIXME: This should be controlled by a user option. See the
21381 comments in redisplay_tool_bar and display_mode_line about
21382 this. */
21383 it.paragraph_embedding = L2R;
21385 /* Clear all rows of the menu bar. */
21386 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
21388 struct glyph_row *row = it.glyph_row + i;
21389 clear_glyph_row (row);
21390 row->enabled_p = true;
21391 row->full_width_p = 1;
21394 /* Display all items of the menu bar. */
21395 items = FRAME_MENU_BAR_ITEMS (it.f);
21396 for (i = 0; i < ASIZE (items); i += 4)
21398 Lisp_Object string;
21400 /* Stop at nil string. */
21401 string = AREF (items, i + 1);
21402 if (NILP (string))
21403 break;
21405 /* Remember where item was displayed. */
21406 ASET (items, i + 3, make_number (it.hpos));
21408 /* Display the item, pad with one space. */
21409 if (it.current_x < it.last_visible_x)
21410 display_string (NULL, string, Qnil, 0, 0, &it,
21411 SCHARS (string) + 1, 0, 0, -1);
21414 /* Fill out the line with spaces. */
21415 if (it.current_x < it.last_visible_x)
21416 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
21418 /* Compute the total height of the lines. */
21419 compute_line_metrics (&it);
21422 /* Deep copy of a glyph row, including the glyphs. */
21423 static void
21424 deep_copy_glyph_row (struct glyph_row *to, struct glyph_row *from)
21426 struct glyph *pointers[1 + LAST_AREA];
21427 int to_used = to->used[TEXT_AREA];
21429 /* Save glyph pointers of TO. */
21430 memcpy (pointers, to->glyphs, sizeof to->glyphs);
21432 /* Do a structure assignment. */
21433 *to = *from;
21435 /* Restore original glyph pointers of TO. */
21436 memcpy (to->glyphs, pointers, sizeof to->glyphs);
21438 /* Copy the glyphs. */
21439 memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA],
21440 min (from->used[TEXT_AREA], to_used) * sizeof (struct glyph));
21442 /* If we filled only part of the TO row, fill the rest with
21443 space_glyph (which will display as empty space). */
21444 if (to_used > from->used[TEXT_AREA])
21445 fill_up_frame_row_with_spaces (to, to_used);
21448 /* Display one menu item on a TTY, by overwriting the glyphs in the
21449 frame F's desired glyph matrix with glyphs produced from the menu
21450 item text. Called from term.c to display TTY drop-down menus one
21451 item at a time.
21453 ITEM_TEXT is the menu item text as a C string.
21455 FACE_ID is the face ID to be used for this menu item. FACE_ID
21456 could specify one of 3 faces: a face for an enabled item, a face
21457 for a disabled item, or a face for a selected item.
21459 X and Y are coordinates of the first glyph in the frame's desired
21460 matrix to be overwritten by the menu item. Since this is a TTY, Y
21461 is the zero-based number of the glyph row and X is the zero-based
21462 glyph number in the row, starting from left, where to start
21463 displaying the item.
21465 SUBMENU non-zero means this menu item drops down a submenu, which
21466 should be indicated by displaying a proper visual cue after the
21467 item text. */
21469 void
21470 display_tty_menu_item (const char *item_text, int width, int face_id,
21471 int x, int y, int submenu)
21473 struct it it;
21474 struct frame *f = SELECTED_FRAME ();
21475 struct window *w = XWINDOW (f->selected_window);
21476 int saved_used, saved_truncated, saved_width, saved_reversed;
21477 struct glyph_row *row;
21478 size_t item_len = strlen (item_text);
21480 eassert (FRAME_TERMCAP_P (f));
21482 /* Don't write beyond the matrix's last row. This can happen for
21483 TTY screens that are not high enough to show the entire menu.
21484 (This is actually a bit of defensive programming, as
21485 tty_menu_display already limits the number of menu items to one
21486 less than the number of screen lines.) */
21487 if (y >= f->desired_matrix->nrows)
21488 return;
21490 init_iterator (&it, w, -1, -1, f->desired_matrix->rows + y, MENU_FACE_ID);
21491 it.first_visible_x = 0;
21492 it.last_visible_x = FRAME_COLS (f) - 1;
21493 row = it.glyph_row;
21494 /* Start with the row contents from the current matrix. */
21495 deep_copy_glyph_row (row, f->current_matrix->rows + y);
21496 saved_width = row->full_width_p;
21497 row->full_width_p = 1;
21498 saved_reversed = row->reversed_p;
21499 row->reversed_p = 0;
21500 row->enabled_p = true;
21502 /* Arrange for the menu item glyphs to start at (X,Y) and have the
21503 desired face. */
21504 eassert (x < f->desired_matrix->matrix_w);
21505 it.current_x = it.hpos = x;
21506 it.current_y = it.vpos = y;
21507 saved_used = row->used[TEXT_AREA];
21508 saved_truncated = row->truncated_on_right_p;
21509 row->used[TEXT_AREA] = x;
21510 it.face_id = face_id;
21511 it.line_wrap = TRUNCATE;
21513 /* FIXME: This should be controlled by a user option. See the
21514 comments in redisplay_tool_bar and display_mode_line about this.
21515 Also, if paragraph_embedding could ever be R2L, changes will be
21516 needed to avoid shifting to the right the row characters in
21517 term.c:append_glyph. */
21518 it.paragraph_embedding = L2R;
21520 /* Pad with a space on the left. */
21521 display_string (" ", Qnil, Qnil, 0, 0, &it, 1, 0, FRAME_COLS (f) - 1, -1);
21522 width--;
21523 /* Display the menu item, pad with spaces to WIDTH. */
21524 if (submenu)
21526 display_string (item_text, Qnil, Qnil, 0, 0, &it,
21527 item_len, 0, FRAME_COLS (f) - 1, -1);
21528 width -= item_len;
21529 /* Indicate with " >" that there's a submenu. */
21530 display_string (" >", Qnil, Qnil, 0, 0, &it, width, 0,
21531 FRAME_COLS (f) - 1, -1);
21533 else
21534 display_string (item_text, Qnil, Qnil, 0, 0, &it,
21535 width, 0, FRAME_COLS (f) - 1, -1);
21537 row->used[TEXT_AREA] = max (saved_used, row->used[TEXT_AREA]);
21538 row->truncated_on_right_p = saved_truncated;
21539 row->hash = row_hash (row);
21540 row->full_width_p = saved_width;
21541 row->reversed_p = saved_reversed;
21544 /***********************************************************************
21545 Mode Line
21546 ***********************************************************************/
21548 /* Redisplay mode lines in the window tree whose root is WINDOW. If
21549 FORCE is non-zero, redisplay mode lines unconditionally.
21550 Otherwise, redisplay only mode lines that are garbaged. Value is
21551 the number of windows whose mode lines were redisplayed. */
21553 static int
21554 redisplay_mode_lines (Lisp_Object window, bool force)
21556 int nwindows = 0;
21558 while (!NILP (window))
21560 struct window *w = XWINDOW (window);
21562 if (WINDOWP (w->contents))
21563 nwindows += redisplay_mode_lines (w->contents, force);
21564 else if (force
21565 || FRAME_GARBAGED_P (XFRAME (w->frame))
21566 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
21568 struct text_pos lpoint;
21569 struct buffer *old = current_buffer;
21571 /* Set the window's buffer for the mode line display. */
21572 SET_TEXT_POS (lpoint, PT, PT_BYTE);
21573 set_buffer_internal_1 (XBUFFER (w->contents));
21575 /* Point refers normally to the selected window. For any
21576 other window, set up appropriate value. */
21577 if (!EQ (window, selected_window))
21579 struct text_pos pt;
21581 CLIP_TEXT_POS_FROM_MARKER (pt, w->pointm);
21582 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
21585 /* Display mode lines. */
21586 clear_glyph_matrix (w->desired_matrix);
21587 if (display_mode_lines (w))
21588 ++nwindows;
21590 /* Restore old settings. */
21591 set_buffer_internal_1 (old);
21592 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
21595 window = w->next;
21598 return nwindows;
21602 /* Display the mode and/or header line of window W. Value is the
21603 sum number of mode lines and header lines displayed. */
21605 static int
21606 display_mode_lines (struct window *w)
21608 Lisp_Object old_selected_window = selected_window;
21609 Lisp_Object old_selected_frame = selected_frame;
21610 Lisp_Object new_frame = w->frame;
21611 Lisp_Object old_frame_selected_window = XFRAME (new_frame)->selected_window;
21612 int n = 0;
21614 selected_frame = new_frame;
21615 /* FIXME: If we were to allow the mode-line's computation changing the buffer
21616 or window's point, then we'd need select_window_1 here as well. */
21617 XSETWINDOW (selected_window, w);
21618 XFRAME (new_frame)->selected_window = selected_window;
21620 /* These will be set while the mode line specs are processed. */
21621 line_number_displayed = 0;
21622 w->column_number_displayed = -1;
21624 if (WINDOW_WANTS_MODELINE_P (w))
21626 struct window *sel_w = XWINDOW (old_selected_window);
21628 /* Select mode line face based on the real selected window. */
21629 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
21630 BVAR (current_buffer, mode_line_format));
21631 ++n;
21634 if (WINDOW_WANTS_HEADER_LINE_P (w))
21636 display_mode_line (w, HEADER_LINE_FACE_ID,
21637 BVAR (current_buffer, header_line_format));
21638 ++n;
21641 XFRAME (new_frame)->selected_window = old_frame_selected_window;
21642 selected_frame = old_selected_frame;
21643 selected_window = old_selected_window;
21644 if (n > 0)
21645 w->must_be_updated_p = true;
21646 return n;
21650 /* Display mode or header line of window W. FACE_ID specifies which
21651 line to display; it is either MODE_LINE_FACE_ID or
21652 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
21653 display. Value is the pixel height of the mode/header line
21654 displayed. */
21656 static int
21657 display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
21659 struct it it;
21660 struct face *face;
21661 ptrdiff_t count = SPECPDL_INDEX ();
21663 init_iterator (&it, w, -1, -1, NULL, face_id);
21664 /* Don't extend on a previously drawn mode-line.
21665 This may happen if called from pos_visible_p. */
21666 it.glyph_row->enabled_p = false;
21667 prepare_desired_row (w, it.glyph_row, true);
21669 it.glyph_row->mode_line_p = 1;
21671 /* FIXME: This should be controlled by a user option. But
21672 supporting such an option is not trivial, since the mode line is
21673 made up of many separate strings. */
21674 it.paragraph_embedding = L2R;
21676 record_unwind_protect (unwind_format_mode_line,
21677 format_mode_line_unwind_data (NULL, NULL, Qnil, 0));
21679 mode_line_target = MODE_LINE_DISPLAY;
21681 /* Temporarily make frame's keyboard the current kboard so that
21682 kboard-local variables in the mode_line_format will get the right
21683 values. */
21684 push_kboard (FRAME_KBOARD (it.f));
21685 record_unwind_save_match_data ();
21686 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
21687 pop_kboard ();
21689 unbind_to (count, Qnil);
21691 /* Fill up with spaces. */
21692 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
21694 compute_line_metrics (&it);
21695 it.glyph_row->full_width_p = 1;
21696 it.glyph_row->continued_p = 0;
21697 it.glyph_row->truncated_on_left_p = 0;
21698 it.glyph_row->truncated_on_right_p = 0;
21700 /* Make a 3D mode-line have a shadow at its right end. */
21701 face = FACE_FROM_ID (it.f, face_id);
21702 extend_face_to_end_of_line (&it);
21703 if (face->box != FACE_NO_BOX)
21705 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
21706 + it.glyph_row->used[TEXT_AREA] - 1);
21707 last->right_box_line_p = 1;
21710 return it.glyph_row->height;
21713 /* Move element ELT in LIST to the front of LIST.
21714 Return the updated list. */
21716 static Lisp_Object
21717 move_elt_to_front (Lisp_Object elt, Lisp_Object list)
21719 register Lisp_Object tail, prev;
21720 register Lisp_Object tem;
21722 tail = list;
21723 prev = Qnil;
21724 while (CONSP (tail))
21726 tem = XCAR (tail);
21728 if (EQ (elt, tem))
21730 /* Splice out the link TAIL. */
21731 if (NILP (prev))
21732 list = XCDR (tail);
21733 else
21734 Fsetcdr (prev, XCDR (tail));
21736 /* Now make it the first. */
21737 Fsetcdr (tail, list);
21738 return tail;
21740 else
21741 prev = tail;
21742 tail = XCDR (tail);
21743 QUIT;
21746 /* Not found--return unchanged LIST. */
21747 return list;
21750 /* Contribute ELT to the mode line for window IT->w. How it
21751 translates into text depends on its data type.
21753 IT describes the display environment in which we display, as usual.
21755 DEPTH is the depth in recursion. It is used to prevent
21756 infinite recursion here.
21758 FIELD_WIDTH is the number of characters the display of ELT should
21759 occupy in the mode line, and PRECISION is the maximum number of
21760 characters to display from ELT's representation. See
21761 display_string for details.
21763 Returns the hpos of the end of the text generated by ELT.
21765 PROPS is a property list to add to any string we encounter.
21767 If RISKY is nonzero, remove (disregard) any properties in any string
21768 we encounter, and ignore :eval and :propertize.
21770 The global variable `mode_line_target' determines whether the
21771 output is passed to `store_mode_line_noprop',
21772 `store_mode_line_string', or `display_string'. */
21774 static int
21775 display_mode_element (struct it *it, int depth, int field_width, int precision,
21776 Lisp_Object elt, Lisp_Object props, int risky)
21778 int n = 0, field, prec;
21779 int literal = 0;
21781 tail_recurse:
21782 if (depth > 100)
21783 elt = build_string ("*too-deep*");
21785 depth++;
21787 switch (XTYPE (elt))
21789 case Lisp_String:
21791 /* A string: output it and check for %-constructs within it. */
21792 unsigned char c;
21793 ptrdiff_t offset = 0;
21795 if (SCHARS (elt) > 0
21796 && (!NILP (props) || risky))
21798 Lisp_Object oprops, aelt;
21799 oprops = Ftext_properties_at (make_number (0), elt);
21801 /* If the starting string's properties are not what
21802 we want, translate the string. Also, if the string
21803 is risky, do that anyway. */
21805 if (NILP (Fequal (props, oprops)) || risky)
21807 /* If the starting string has properties,
21808 merge the specified ones onto the existing ones. */
21809 if (! NILP (oprops) && !risky)
21811 Lisp_Object tem;
21813 oprops = Fcopy_sequence (oprops);
21814 tem = props;
21815 while (CONSP (tem))
21817 oprops = Fplist_put (oprops, XCAR (tem),
21818 XCAR (XCDR (tem)));
21819 tem = XCDR (XCDR (tem));
21821 props = oprops;
21824 aelt = Fassoc (elt, mode_line_proptrans_alist);
21825 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
21827 /* AELT is what we want. Move it to the front
21828 without consing. */
21829 elt = XCAR (aelt);
21830 mode_line_proptrans_alist
21831 = move_elt_to_front (aelt, mode_line_proptrans_alist);
21833 else
21835 Lisp_Object tem;
21837 /* If AELT has the wrong props, it is useless.
21838 so get rid of it. */
21839 if (! NILP (aelt))
21840 mode_line_proptrans_alist
21841 = Fdelq (aelt, mode_line_proptrans_alist);
21843 elt = Fcopy_sequence (elt);
21844 Fset_text_properties (make_number (0), Flength (elt),
21845 props, elt);
21846 /* Add this item to mode_line_proptrans_alist. */
21847 mode_line_proptrans_alist
21848 = Fcons (Fcons (elt, props),
21849 mode_line_proptrans_alist);
21850 /* Truncate mode_line_proptrans_alist
21851 to at most 50 elements. */
21852 tem = Fnthcdr (make_number (50),
21853 mode_line_proptrans_alist);
21854 if (! NILP (tem))
21855 XSETCDR (tem, Qnil);
21860 offset = 0;
21862 if (literal)
21864 prec = precision - n;
21865 switch (mode_line_target)
21867 case MODE_LINE_NOPROP:
21868 case MODE_LINE_TITLE:
21869 n += store_mode_line_noprop (SSDATA (elt), -1, prec);
21870 break;
21871 case MODE_LINE_STRING:
21872 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
21873 break;
21874 case MODE_LINE_DISPLAY:
21875 n += display_string (NULL, elt, Qnil, 0, 0, it,
21876 0, prec, 0, STRING_MULTIBYTE (elt));
21877 break;
21880 break;
21883 /* Handle the non-literal case. */
21885 while ((precision <= 0 || n < precision)
21886 && SREF (elt, offset) != 0
21887 && (mode_line_target != MODE_LINE_DISPLAY
21888 || it->current_x < it->last_visible_x))
21890 ptrdiff_t last_offset = offset;
21892 /* Advance to end of string or next format specifier. */
21893 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
21896 if (offset - 1 != last_offset)
21898 ptrdiff_t nchars, nbytes;
21900 /* Output to end of string or up to '%'. Field width
21901 is length of string. Don't output more than
21902 PRECISION allows us. */
21903 offset--;
21905 prec = c_string_width (SDATA (elt) + last_offset,
21906 offset - last_offset, precision - n,
21907 &nchars, &nbytes);
21909 switch (mode_line_target)
21911 case MODE_LINE_NOPROP:
21912 case MODE_LINE_TITLE:
21913 n += store_mode_line_noprop (SSDATA (elt) + last_offset, 0, prec);
21914 break;
21915 case MODE_LINE_STRING:
21917 ptrdiff_t bytepos = last_offset;
21918 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
21919 ptrdiff_t endpos = (precision <= 0
21920 ? string_byte_to_char (elt, offset)
21921 : charpos + nchars);
21923 n += store_mode_line_string (NULL,
21924 Fsubstring (elt, make_number (charpos),
21925 make_number (endpos)),
21926 0, 0, 0, Qnil);
21928 break;
21929 case MODE_LINE_DISPLAY:
21931 ptrdiff_t bytepos = last_offset;
21932 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
21934 if (precision <= 0)
21935 nchars = string_byte_to_char (elt, offset) - charpos;
21936 n += display_string (NULL, elt, Qnil, 0, charpos,
21937 it, 0, nchars, 0,
21938 STRING_MULTIBYTE (elt));
21940 break;
21943 else /* c == '%' */
21945 ptrdiff_t percent_position = offset;
21947 /* Get the specified minimum width. Zero means
21948 don't pad. */
21949 field = 0;
21950 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
21951 field = field * 10 + c - '0';
21953 /* Don't pad beyond the total padding allowed. */
21954 if (field_width - n > 0 && field > field_width - n)
21955 field = field_width - n;
21957 /* Note that either PRECISION <= 0 or N < PRECISION. */
21958 prec = precision - n;
21960 if (c == 'M')
21961 n += display_mode_element (it, depth, field, prec,
21962 Vglobal_mode_string, props,
21963 risky);
21964 else if (c != 0)
21966 bool multibyte;
21967 ptrdiff_t bytepos, charpos;
21968 const char *spec;
21969 Lisp_Object string;
21971 bytepos = percent_position;
21972 charpos = (STRING_MULTIBYTE (elt)
21973 ? string_byte_to_char (elt, bytepos)
21974 : bytepos);
21975 spec = decode_mode_spec (it->w, c, field, &string);
21976 multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
21978 switch (mode_line_target)
21980 case MODE_LINE_NOPROP:
21981 case MODE_LINE_TITLE:
21982 n += store_mode_line_noprop (spec, field, prec);
21983 break;
21984 case MODE_LINE_STRING:
21986 Lisp_Object tem = build_string (spec);
21987 props = Ftext_properties_at (make_number (charpos), elt);
21988 /* Should only keep face property in props */
21989 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
21991 break;
21992 case MODE_LINE_DISPLAY:
21994 int nglyphs_before, nwritten;
21996 nglyphs_before = it->glyph_row->used[TEXT_AREA];
21997 nwritten = display_string (spec, string, elt,
21998 charpos, 0, it,
21999 field, prec, 0,
22000 multibyte);
22002 /* Assign to the glyphs written above the
22003 string where the `%x' came from, position
22004 of the `%'. */
22005 if (nwritten > 0)
22007 struct glyph *glyph
22008 = (it->glyph_row->glyphs[TEXT_AREA]
22009 + nglyphs_before);
22010 int i;
22012 for (i = 0; i < nwritten; ++i)
22014 glyph[i].object = elt;
22015 glyph[i].charpos = charpos;
22018 n += nwritten;
22021 break;
22024 else /* c == 0 */
22025 break;
22029 break;
22031 case Lisp_Symbol:
22032 /* A symbol: process the value of the symbol recursively
22033 as if it appeared here directly. Avoid error if symbol void.
22034 Special case: if value of symbol is a string, output the string
22035 literally. */
22037 register Lisp_Object tem;
22039 /* If the variable is not marked as risky to set
22040 then its contents are risky to use. */
22041 if (NILP (Fget (elt, Qrisky_local_variable)))
22042 risky = 1;
22044 tem = Fboundp (elt);
22045 if (!NILP (tem))
22047 tem = Fsymbol_value (elt);
22048 /* If value is a string, output that string literally:
22049 don't check for % within it. */
22050 if (STRINGP (tem))
22051 literal = 1;
22053 if (!EQ (tem, elt))
22055 /* Give up right away for nil or t. */
22056 elt = tem;
22057 goto tail_recurse;
22061 break;
22063 case Lisp_Cons:
22065 register Lisp_Object car, tem;
22067 /* A cons cell: five distinct cases.
22068 If first element is :eval or :propertize, do something special.
22069 If first element is a string or a cons, process all the elements
22070 and effectively concatenate them.
22071 If first element is a negative number, truncate displaying cdr to
22072 at most that many characters. If positive, pad (with spaces)
22073 to at least that many characters.
22074 If first element is a symbol, process the cadr or caddr recursively
22075 according to whether the symbol's value is non-nil or nil. */
22076 car = XCAR (elt);
22077 if (EQ (car, QCeval))
22079 /* An element of the form (:eval FORM) means evaluate FORM
22080 and use the result as mode line elements. */
22082 if (risky)
22083 break;
22085 if (CONSP (XCDR (elt)))
22087 Lisp_Object spec;
22088 spec = safe__eval (true, XCAR (XCDR (elt)));
22089 n += display_mode_element (it, depth, field_width - n,
22090 precision - n, spec, props,
22091 risky);
22094 else if (EQ (car, QCpropertize))
22096 /* An element of the form (:propertize ELT PROPS...)
22097 means display ELT but applying properties PROPS. */
22099 if (risky)
22100 break;
22102 if (CONSP (XCDR (elt)))
22103 n += display_mode_element (it, depth, field_width - n,
22104 precision - n, XCAR (XCDR (elt)),
22105 XCDR (XCDR (elt)), risky);
22107 else if (SYMBOLP (car))
22109 tem = Fboundp (car);
22110 elt = XCDR (elt);
22111 if (!CONSP (elt))
22112 goto invalid;
22113 /* elt is now the cdr, and we know it is a cons cell.
22114 Use its car if CAR has a non-nil value. */
22115 if (!NILP (tem))
22117 tem = Fsymbol_value (car);
22118 if (!NILP (tem))
22120 elt = XCAR (elt);
22121 goto tail_recurse;
22124 /* Symbol's value is nil (or symbol is unbound)
22125 Get the cddr of the original list
22126 and if possible find the caddr and use that. */
22127 elt = XCDR (elt);
22128 if (NILP (elt))
22129 break;
22130 else if (!CONSP (elt))
22131 goto invalid;
22132 elt = XCAR (elt);
22133 goto tail_recurse;
22135 else if (INTEGERP (car))
22137 register int lim = XINT (car);
22138 elt = XCDR (elt);
22139 if (lim < 0)
22141 /* Negative int means reduce maximum width. */
22142 if (precision <= 0)
22143 precision = -lim;
22144 else
22145 precision = min (precision, -lim);
22147 else if (lim > 0)
22149 /* Padding specified. Don't let it be more than
22150 current maximum. */
22151 if (precision > 0)
22152 lim = min (precision, lim);
22154 /* If that's more padding than already wanted, queue it.
22155 But don't reduce padding already specified even if
22156 that is beyond the current truncation point. */
22157 field_width = max (lim, field_width);
22159 goto tail_recurse;
22161 else if (STRINGP (car) || CONSP (car))
22163 Lisp_Object halftail = elt;
22164 int len = 0;
22166 while (CONSP (elt)
22167 && (precision <= 0 || n < precision))
22169 n += display_mode_element (it, depth,
22170 /* Do padding only after the last
22171 element in the list. */
22172 (! CONSP (XCDR (elt))
22173 ? field_width - n
22174 : 0),
22175 precision - n, XCAR (elt),
22176 props, risky);
22177 elt = XCDR (elt);
22178 len++;
22179 if ((len & 1) == 0)
22180 halftail = XCDR (halftail);
22181 /* Check for cycle. */
22182 if (EQ (halftail, elt))
22183 break;
22187 break;
22189 default:
22190 invalid:
22191 elt = build_string ("*invalid*");
22192 goto tail_recurse;
22195 /* Pad to FIELD_WIDTH. */
22196 if (field_width > 0 && n < field_width)
22198 switch (mode_line_target)
22200 case MODE_LINE_NOPROP:
22201 case MODE_LINE_TITLE:
22202 n += store_mode_line_noprop ("", field_width - n, 0);
22203 break;
22204 case MODE_LINE_STRING:
22205 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
22206 break;
22207 case MODE_LINE_DISPLAY:
22208 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
22209 0, 0, 0);
22210 break;
22214 return n;
22217 /* Store a mode-line string element in mode_line_string_list.
22219 If STRING is non-null, display that C string. Otherwise, the Lisp
22220 string LISP_STRING is displayed.
22222 FIELD_WIDTH is the minimum number of output glyphs to produce.
22223 If STRING has fewer characters than FIELD_WIDTH, pad to the right
22224 with spaces. FIELD_WIDTH <= 0 means don't pad.
22226 PRECISION is the maximum number of characters to output from
22227 STRING. PRECISION <= 0 means don't truncate the string.
22229 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
22230 properties to the string.
22232 PROPS are the properties to add to the string.
22233 The mode_line_string_face face property is always added to the string.
22236 static int
22237 store_mode_line_string (const char *string, Lisp_Object lisp_string, int copy_string,
22238 int field_width, int precision, Lisp_Object props)
22240 ptrdiff_t len;
22241 int n = 0;
22243 if (string != NULL)
22245 len = strlen (string);
22246 if (precision > 0 && len > precision)
22247 len = precision;
22248 lisp_string = make_string (string, len);
22249 if (NILP (props))
22250 props = mode_line_string_face_prop;
22251 else if (!NILP (mode_line_string_face))
22253 Lisp_Object face = Fplist_get (props, Qface);
22254 props = Fcopy_sequence (props);
22255 if (NILP (face))
22256 face = mode_line_string_face;
22257 else
22258 face = list2 (face, mode_line_string_face);
22259 props = Fplist_put (props, Qface, face);
22261 Fadd_text_properties (make_number (0), make_number (len),
22262 props, lisp_string);
22264 else
22266 len = XFASTINT (Flength (lisp_string));
22267 if (precision > 0 && len > precision)
22269 len = precision;
22270 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
22271 precision = -1;
22273 if (!NILP (mode_line_string_face))
22275 Lisp_Object face;
22276 if (NILP (props))
22277 props = Ftext_properties_at (make_number (0), lisp_string);
22278 face = Fplist_get (props, Qface);
22279 if (NILP (face))
22280 face = mode_line_string_face;
22281 else
22282 face = list2 (face, mode_line_string_face);
22283 props = list2 (Qface, face);
22284 if (copy_string)
22285 lisp_string = Fcopy_sequence (lisp_string);
22287 if (!NILP (props))
22288 Fadd_text_properties (make_number (0), make_number (len),
22289 props, lisp_string);
22292 if (len > 0)
22294 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
22295 n += len;
22298 if (field_width > len)
22300 field_width -= len;
22301 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
22302 if (!NILP (props))
22303 Fadd_text_properties (make_number (0), make_number (field_width),
22304 props, lisp_string);
22305 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
22306 n += field_width;
22309 return n;
22313 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
22314 1, 4, 0,
22315 doc: /* Format a string out of a mode line format specification.
22316 First arg FORMAT specifies the mode line format (see `mode-line-format'
22317 for details) to use.
22319 By default, the format is evaluated for the currently selected window.
22321 Optional second arg FACE specifies the face property to put on all
22322 characters for which no face is specified. The value nil means the
22323 default face. The value t means whatever face the window's mode line
22324 currently uses (either `mode-line' or `mode-line-inactive',
22325 depending on whether the window is the selected window or not).
22326 An integer value means the value string has no text
22327 properties.
22329 Optional third and fourth args WINDOW and BUFFER specify the window
22330 and buffer to use as the context for the formatting (defaults
22331 are the selected window and the WINDOW's buffer). */)
22332 (Lisp_Object format, Lisp_Object face,
22333 Lisp_Object window, Lisp_Object buffer)
22335 struct it it;
22336 int len;
22337 struct window *w;
22338 struct buffer *old_buffer = NULL;
22339 int face_id;
22340 int no_props = INTEGERP (face);
22341 ptrdiff_t count = SPECPDL_INDEX ();
22342 Lisp_Object str;
22343 int string_start = 0;
22345 w = decode_any_window (window);
22346 XSETWINDOW (window, w);
22348 if (NILP (buffer))
22349 buffer = w->contents;
22350 CHECK_BUFFER (buffer);
22352 /* Make formatting the modeline a non-op when noninteractive, otherwise
22353 there will be problems later caused by a partially initialized frame. */
22354 if (NILP (format) || noninteractive)
22355 return empty_unibyte_string;
22357 if (no_props)
22358 face = Qnil;
22360 face_id = (NILP (face) || EQ (face, Qdefault)) ? DEFAULT_FACE_ID
22361 : EQ (face, Qt) ? (EQ (window, selected_window)
22362 ? MODE_LINE_FACE_ID : MODE_LINE_INACTIVE_FACE_ID)
22363 : EQ (face, Qmode_line) ? MODE_LINE_FACE_ID
22364 : EQ (face, Qmode_line_inactive) ? MODE_LINE_INACTIVE_FACE_ID
22365 : EQ (face, Qheader_line) ? HEADER_LINE_FACE_ID
22366 : EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID
22367 : DEFAULT_FACE_ID;
22369 old_buffer = current_buffer;
22371 /* Save things including mode_line_proptrans_alist,
22372 and set that to nil so that we don't alter the outer value. */
22373 record_unwind_protect (unwind_format_mode_line,
22374 format_mode_line_unwind_data
22375 (XFRAME (WINDOW_FRAME (w)),
22376 old_buffer, selected_window, 1));
22377 mode_line_proptrans_alist = Qnil;
22379 Fselect_window (window, Qt);
22380 set_buffer_internal_1 (XBUFFER (buffer));
22382 init_iterator (&it, w, -1, -1, NULL, face_id);
22384 if (no_props)
22386 mode_line_target = MODE_LINE_NOPROP;
22387 mode_line_string_face_prop = Qnil;
22388 mode_line_string_list = Qnil;
22389 string_start = MODE_LINE_NOPROP_LEN (0);
22391 else
22393 mode_line_target = MODE_LINE_STRING;
22394 mode_line_string_list = Qnil;
22395 mode_line_string_face = face;
22396 mode_line_string_face_prop
22397 = NILP (face) ? Qnil : list2 (Qface, face);
22400 push_kboard (FRAME_KBOARD (it.f));
22401 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
22402 pop_kboard ();
22404 if (no_props)
22406 len = MODE_LINE_NOPROP_LEN (string_start);
22407 str = make_string (mode_line_noprop_buf + string_start, len);
22409 else
22411 mode_line_string_list = Fnreverse (mode_line_string_list);
22412 str = Fmapconcat (intern ("identity"), mode_line_string_list,
22413 empty_unibyte_string);
22416 unbind_to (count, Qnil);
22417 return str;
22420 /* Write a null-terminated, right justified decimal representation of
22421 the positive integer D to BUF using a minimal field width WIDTH. */
22423 static void
22424 pint2str (register char *buf, register int width, register ptrdiff_t d)
22426 register char *p = buf;
22428 if (d <= 0)
22429 *p++ = '0';
22430 else
22432 while (d > 0)
22434 *p++ = d % 10 + '0';
22435 d /= 10;
22439 for (width -= (int) (p - buf); width > 0; --width)
22440 *p++ = ' ';
22441 *p-- = '\0';
22442 while (p > buf)
22444 d = *buf;
22445 *buf++ = *p;
22446 *p-- = d;
22450 /* Write a null-terminated, right justified decimal and "human
22451 readable" representation of the nonnegative integer D to BUF using
22452 a minimal field width WIDTH. D should be smaller than 999.5e24. */
22454 static const char power_letter[] =
22456 0, /* no letter */
22457 'k', /* kilo */
22458 'M', /* mega */
22459 'G', /* giga */
22460 'T', /* tera */
22461 'P', /* peta */
22462 'E', /* exa */
22463 'Z', /* zetta */
22464 'Y' /* yotta */
22467 static void
22468 pint2hrstr (char *buf, int width, ptrdiff_t d)
22470 /* We aim to represent the nonnegative integer D as
22471 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
22472 ptrdiff_t quotient = d;
22473 int remainder = 0;
22474 /* -1 means: do not use TENTHS. */
22475 int tenths = -1;
22476 int exponent = 0;
22478 /* Length of QUOTIENT.TENTHS as a string. */
22479 int length;
22481 char * psuffix;
22482 char * p;
22484 if (quotient >= 1000)
22486 /* Scale to the appropriate EXPONENT. */
22489 remainder = quotient % 1000;
22490 quotient /= 1000;
22491 exponent++;
22493 while (quotient >= 1000);
22495 /* Round to nearest and decide whether to use TENTHS or not. */
22496 if (quotient <= 9)
22498 tenths = remainder / 100;
22499 if (remainder % 100 >= 50)
22501 if (tenths < 9)
22502 tenths++;
22503 else
22505 quotient++;
22506 if (quotient == 10)
22507 tenths = -1;
22508 else
22509 tenths = 0;
22513 else
22514 if (remainder >= 500)
22516 if (quotient < 999)
22517 quotient++;
22518 else
22520 quotient = 1;
22521 exponent++;
22522 tenths = 0;
22527 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
22528 if (tenths == -1 && quotient <= 99)
22529 if (quotient <= 9)
22530 length = 1;
22531 else
22532 length = 2;
22533 else
22534 length = 3;
22535 p = psuffix = buf + max (width, length);
22537 /* Print EXPONENT. */
22538 *psuffix++ = power_letter[exponent];
22539 *psuffix = '\0';
22541 /* Print TENTHS. */
22542 if (tenths >= 0)
22544 *--p = '0' + tenths;
22545 *--p = '.';
22548 /* Print QUOTIENT. */
22551 int digit = quotient % 10;
22552 *--p = '0' + digit;
22554 while ((quotient /= 10) != 0);
22556 /* Print leading spaces. */
22557 while (buf < p)
22558 *--p = ' ';
22561 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
22562 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
22563 type of CODING_SYSTEM. Return updated pointer into BUF. */
22565 static unsigned char invalid_eol_type[] = "(*invalid*)";
22567 static char *
22568 decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_flag)
22570 Lisp_Object val;
22571 bool multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
22572 const unsigned char *eol_str;
22573 int eol_str_len;
22574 /* The EOL conversion we are using. */
22575 Lisp_Object eoltype;
22577 val = CODING_SYSTEM_SPEC (coding_system);
22578 eoltype = Qnil;
22580 if (!VECTORP (val)) /* Not yet decided. */
22582 *buf++ = multibyte ? '-' : ' ';
22583 if (eol_flag)
22584 eoltype = eol_mnemonic_undecided;
22585 /* Don't mention EOL conversion if it isn't decided. */
22587 else
22589 Lisp_Object attrs;
22590 Lisp_Object eolvalue;
22592 attrs = AREF (val, 0);
22593 eolvalue = AREF (val, 2);
22595 *buf++ = multibyte
22596 ? XFASTINT (CODING_ATTR_MNEMONIC (attrs))
22597 : ' ';
22599 if (eol_flag)
22601 /* The EOL conversion that is normal on this system. */
22603 if (NILP (eolvalue)) /* Not yet decided. */
22604 eoltype = eol_mnemonic_undecided;
22605 else if (VECTORP (eolvalue)) /* Not yet decided. */
22606 eoltype = eol_mnemonic_undecided;
22607 else /* eolvalue is Qunix, Qdos, or Qmac. */
22608 eoltype = (EQ (eolvalue, Qunix)
22609 ? eol_mnemonic_unix
22610 : (EQ (eolvalue, Qdos) == 1
22611 ? eol_mnemonic_dos : eol_mnemonic_mac));
22615 if (eol_flag)
22617 /* Mention the EOL conversion if it is not the usual one. */
22618 if (STRINGP (eoltype))
22620 eol_str = SDATA (eoltype);
22621 eol_str_len = SBYTES (eoltype);
22623 else if (CHARACTERP (eoltype))
22625 unsigned char *tmp = alloca (MAX_MULTIBYTE_LENGTH);
22626 int c = XFASTINT (eoltype);
22627 eol_str_len = CHAR_STRING (c, tmp);
22628 eol_str = tmp;
22630 else
22632 eol_str = invalid_eol_type;
22633 eol_str_len = sizeof (invalid_eol_type) - 1;
22635 memcpy (buf, eol_str, eol_str_len);
22636 buf += eol_str_len;
22639 return buf;
22642 /* Return a string for the output of a mode line %-spec for window W,
22643 generated by character C. FIELD_WIDTH > 0 means pad the string
22644 returned with spaces to that value. Return a Lisp string in
22645 *STRING if the resulting string is taken from that Lisp string.
22647 Note we operate on the current buffer for most purposes. */
22649 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
22651 static const char *
22652 decode_mode_spec (struct window *w, register int c, int field_width,
22653 Lisp_Object *string)
22655 Lisp_Object obj;
22656 struct frame *f = XFRAME (WINDOW_FRAME (w));
22657 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
22658 /* We are going to use f->decode_mode_spec_buffer as the buffer to
22659 produce strings from numerical values, so limit preposterously
22660 large values of FIELD_WIDTH to avoid overrunning the buffer's
22661 end. The size of the buffer is enough for FRAME_MESSAGE_BUF_SIZE
22662 bytes plus the terminating null. */
22663 int width = min (field_width, FRAME_MESSAGE_BUF_SIZE (f));
22664 struct buffer *b = current_buffer;
22666 obj = Qnil;
22667 *string = Qnil;
22669 switch (c)
22671 case '*':
22672 if (!NILP (BVAR (b, read_only)))
22673 return "%";
22674 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
22675 return "*";
22676 return "-";
22678 case '+':
22679 /* This differs from %* only for a modified read-only buffer. */
22680 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
22681 return "*";
22682 if (!NILP (BVAR (b, read_only)))
22683 return "%";
22684 return "-";
22686 case '&':
22687 /* This differs from %* in ignoring read-only-ness. */
22688 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
22689 return "*";
22690 return "-";
22692 case '%':
22693 return "%";
22695 case '[':
22697 int i;
22698 char *p;
22700 if (command_loop_level > 5)
22701 return "[[[... ";
22702 p = decode_mode_spec_buf;
22703 for (i = 0; i < command_loop_level; i++)
22704 *p++ = '[';
22705 *p = 0;
22706 return decode_mode_spec_buf;
22709 case ']':
22711 int i;
22712 char *p;
22714 if (command_loop_level > 5)
22715 return " ...]]]";
22716 p = decode_mode_spec_buf;
22717 for (i = 0; i < command_loop_level; i++)
22718 *p++ = ']';
22719 *p = 0;
22720 return decode_mode_spec_buf;
22723 case '-':
22725 register int i;
22727 /* Let lots_of_dashes be a string of infinite length. */
22728 if (mode_line_target == MODE_LINE_NOPROP
22729 || mode_line_target == MODE_LINE_STRING)
22730 return "--";
22731 if (field_width <= 0
22732 || field_width > sizeof (lots_of_dashes))
22734 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
22735 decode_mode_spec_buf[i] = '-';
22736 decode_mode_spec_buf[i] = '\0';
22737 return decode_mode_spec_buf;
22739 else
22740 return lots_of_dashes;
22743 case 'b':
22744 obj = BVAR (b, name);
22745 break;
22747 case 'c':
22748 /* %c and %l are ignored in `frame-title-format'.
22749 (In redisplay_internal, the frame title is drawn _before_ the
22750 windows are updated, so the stuff which depends on actual
22751 window contents (such as %l) may fail to render properly, or
22752 even crash emacs.) */
22753 if (mode_line_target == MODE_LINE_TITLE)
22754 return "";
22755 else
22757 ptrdiff_t col = current_column ();
22758 w->column_number_displayed = col;
22759 pint2str (decode_mode_spec_buf, width, col);
22760 return decode_mode_spec_buf;
22763 case 'e':
22764 #ifndef SYSTEM_MALLOC
22766 if (NILP (Vmemory_full))
22767 return "";
22768 else
22769 return "!MEM FULL! ";
22771 #else
22772 return "";
22773 #endif
22775 case 'F':
22776 /* %F displays the frame name. */
22777 if (!NILP (f->title))
22778 return SSDATA (f->title);
22779 if (f->explicit_name || ! FRAME_WINDOW_P (f))
22780 return SSDATA (f->name);
22781 return "Emacs";
22783 case 'f':
22784 obj = BVAR (b, filename);
22785 break;
22787 case 'i':
22789 ptrdiff_t size = ZV - BEGV;
22790 pint2str (decode_mode_spec_buf, width, size);
22791 return decode_mode_spec_buf;
22794 case 'I':
22796 ptrdiff_t size = ZV - BEGV;
22797 pint2hrstr (decode_mode_spec_buf, width, size);
22798 return decode_mode_spec_buf;
22801 case 'l':
22803 ptrdiff_t startpos, startpos_byte, line, linepos, linepos_byte;
22804 ptrdiff_t topline, nlines, height;
22805 ptrdiff_t junk;
22807 /* %c and %l are ignored in `frame-title-format'. */
22808 if (mode_line_target == MODE_LINE_TITLE)
22809 return "";
22811 startpos = marker_position (w->start);
22812 startpos_byte = marker_byte_position (w->start);
22813 height = WINDOW_TOTAL_LINES (w);
22815 /* If we decided that this buffer isn't suitable for line numbers,
22816 don't forget that too fast. */
22817 if (w->base_line_pos == -1)
22818 goto no_value;
22820 /* If the buffer is very big, don't waste time. */
22821 if (INTEGERP (Vline_number_display_limit)
22822 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
22824 w->base_line_pos = 0;
22825 w->base_line_number = 0;
22826 goto no_value;
22829 if (w->base_line_number > 0
22830 && w->base_line_pos > 0
22831 && w->base_line_pos <= startpos)
22833 line = w->base_line_number;
22834 linepos = w->base_line_pos;
22835 linepos_byte = buf_charpos_to_bytepos (b, linepos);
22837 else
22839 line = 1;
22840 linepos = BUF_BEGV (b);
22841 linepos_byte = BUF_BEGV_BYTE (b);
22844 /* Count lines from base line to window start position. */
22845 nlines = display_count_lines (linepos_byte,
22846 startpos_byte,
22847 startpos, &junk);
22849 topline = nlines + line;
22851 /* Determine a new base line, if the old one is too close
22852 or too far away, or if we did not have one.
22853 "Too close" means it's plausible a scroll-down would
22854 go back past it. */
22855 if (startpos == BUF_BEGV (b))
22857 w->base_line_number = topline;
22858 w->base_line_pos = BUF_BEGV (b);
22860 else if (nlines < height + 25 || nlines > height * 3 + 50
22861 || linepos == BUF_BEGV (b))
22863 ptrdiff_t limit = BUF_BEGV (b);
22864 ptrdiff_t limit_byte = BUF_BEGV_BYTE (b);
22865 ptrdiff_t position;
22866 ptrdiff_t distance =
22867 (height * 2 + 30) * line_number_display_limit_width;
22869 if (startpos - distance > limit)
22871 limit = startpos - distance;
22872 limit_byte = CHAR_TO_BYTE (limit);
22875 nlines = display_count_lines (startpos_byte,
22876 limit_byte,
22877 - (height * 2 + 30),
22878 &position);
22879 /* If we couldn't find the lines we wanted within
22880 line_number_display_limit_width chars per line,
22881 give up on line numbers for this window. */
22882 if (position == limit_byte && limit == startpos - distance)
22884 w->base_line_pos = -1;
22885 w->base_line_number = 0;
22886 goto no_value;
22889 w->base_line_number = topline - nlines;
22890 w->base_line_pos = BYTE_TO_CHAR (position);
22893 /* Now count lines from the start pos to point. */
22894 nlines = display_count_lines (startpos_byte,
22895 PT_BYTE, PT, &junk);
22897 /* Record that we did display the line number. */
22898 line_number_displayed = 1;
22900 /* Make the string to show. */
22901 pint2str (decode_mode_spec_buf, width, topline + nlines);
22902 return decode_mode_spec_buf;
22903 no_value:
22905 char *p = decode_mode_spec_buf;
22906 int pad = width - 2;
22907 while (pad-- > 0)
22908 *p++ = ' ';
22909 *p++ = '?';
22910 *p++ = '?';
22911 *p = '\0';
22912 return decode_mode_spec_buf;
22915 break;
22917 case 'm':
22918 obj = BVAR (b, mode_name);
22919 break;
22921 case 'n':
22922 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
22923 return " Narrow";
22924 break;
22926 case 'p':
22928 ptrdiff_t pos = marker_position (w->start);
22929 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
22931 if (w->window_end_pos <= BUF_Z (b) - BUF_ZV (b))
22933 if (pos <= BUF_BEGV (b))
22934 return "All";
22935 else
22936 return "Bottom";
22938 else if (pos <= BUF_BEGV (b))
22939 return "Top";
22940 else
22942 if (total > 1000000)
22943 /* Do it differently for a large value, to avoid overflow. */
22944 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
22945 else
22946 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
22947 /* We can't normally display a 3-digit number,
22948 so get us a 2-digit number that is close. */
22949 if (total == 100)
22950 total = 99;
22951 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
22952 return decode_mode_spec_buf;
22956 /* Display percentage of size above the bottom of the screen. */
22957 case 'P':
22959 ptrdiff_t toppos = marker_position (w->start);
22960 ptrdiff_t botpos = BUF_Z (b) - w->window_end_pos;
22961 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
22963 if (botpos >= BUF_ZV (b))
22965 if (toppos <= BUF_BEGV (b))
22966 return "All";
22967 else
22968 return "Bottom";
22970 else
22972 if (total > 1000000)
22973 /* Do it differently for a large value, to avoid overflow. */
22974 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
22975 else
22976 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
22977 /* We can't normally display a 3-digit number,
22978 so get us a 2-digit number that is close. */
22979 if (total == 100)
22980 total = 99;
22981 if (toppos <= BUF_BEGV (b))
22982 sprintf (decode_mode_spec_buf, "Top%2"pD"d%%", total);
22983 else
22984 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
22985 return decode_mode_spec_buf;
22989 case 's':
22990 /* status of process */
22991 obj = Fget_buffer_process (Fcurrent_buffer ());
22992 if (NILP (obj))
22993 return "no process";
22994 #ifndef MSDOS
22995 obj = Fsymbol_name (Fprocess_status (obj));
22996 #endif
22997 break;
22999 case '@':
23001 ptrdiff_t count = inhibit_garbage_collection ();
23002 Lisp_Object curdir = BVAR (current_buffer, directory);
23003 Lisp_Object val = Qnil;
23005 if (STRINGP (curdir))
23006 val = call1 (intern ("file-remote-p"), curdir);
23008 unbind_to (count, Qnil);
23010 if (NILP (val))
23011 return "-";
23012 else
23013 return "@";
23016 case 'z':
23017 /* coding-system (not including end-of-line format) */
23018 case 'Z':
23019 /* coding-system (including end-of-line type) */
23021 int eol_flag = (c == 'Z');
23022 char *p = decode_mode_spec_buf;
23024 if (! FRAME_WINDOW_P (f))
23026 /* No need to mention EOL here--the terminal never needs
23027 to do EOL conversion. */
23028 p = decode_mode_spec_coding (CODING_ID_NAME
23029 (FRAME_KEYBOARD_CODING (f)->id),
23030 p, 0);
23031 p = decode_mode_spec_coding (CODING_ID_NAME
23032 (FRAME_TERMINAL_CODING (f)->id),
23033 p, 0);
23035 p = decode_mode_spec_coding (BVAR (b, buffer_file_coding_system),
23036 p, eol_flag);
23038 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
23039 #ifdef subprocesses
23040 obj = Fget_buffer_process (Fcurrent_buffer ());
23041 if (PROCESSP (obj))
23043 p = decode_mode_spec_coding
23044 (XPROCESS (obj)->decode_coding_system, p, eol_flag);
23045 p = decode_mode_spec_coding
23046 (XPROCESS (obj)->encode_coding_system, p, eol_flag);
23048 #endif /* subprocesses */
23049 #endif /* 0 */
23050 *p = 0;
23051 return decode_mode_spec_buf;
23055 if (STRINGP (obj))
23057 *string = obj;
23058 return SSDATA (obj);
23060 else
23061 return "";
23065 /* Count up to COUNT lines starting from START_BYTE. COUNT negative
23066 means count lines back from START_BYTE. But don't go beyond
23067 LIMIT_BYTE. Return the number of lines thus found (always
23068 nonnegative).
23070 Set *BYTE_POS_PTR to the byte position where we stopped. This is
23071 either the position COUNT lines after/before START_BYTE, if we
23072 found COUNT lines, or LIMIT_BYTE if we hit the limit before finding
23073 COUNT lines. */
23075 static ptrdiff_t
23076 display_count_lines (ptrdiff_t start_byte,
23077 ptrdiff_t limit_byte, ptrdiff_t count,
23078 ptrdiff_t *byte_pos_ptr)
23080 register unsigned char *cursor;
23081 unsigned char *base;
23083 register ptrdiff_t ceiling;
23084 register unsigned char *ceiling_addr;
23085 ptrdiff_t orig_count = count;
23087 /* If we are not in selective display mode,
23088 check only for newlines. */
23089 int selective_display = (!NILP (BVAR (current_buffer, selective_display))
23090 && !INTEGERP (BVAR (current_buffer, selective_display)));
23092 if (count > 0)
23094 while (start_byte < limit_byte)
23096 ceiling = BUFFER_CEILING_OF (start_byte);
23097 ceiling = min (limit_byte - 1, ceiling);
23098 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
23099 base = (cursor = BYTE_POS_ADDR (start_byte));
23103 if (selective_display)
23105 while (*cursor != '\n' && *cursor != 015
23106 && ++cursor != ceiling_addr)
23107 continue;
23108 if (cursor == ceiling_addr)
23109 break;
23111 else
23113 cursor = memchr (cursor, '\n', ceiling_addr - cursor);
23114 if (! cursor)
23115 break;
23118 cursor++;
23120 if (--count == 0)
23122 start_byte += cursor - base;
23123 *byte_pos_ptr = start_byte;
23124 return orig_count;
23127 while (cursor < ceiling_addr);
23129 start_byte += ceiling_addr - base;
23132 else
23134 while (start_byte > limit_byte)
23136 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
23137 ceiling = max (limit_byte, ceiling);
23138 ceiling_addr = BYTE_POS_ADDR (ceiling);
23139 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
23140 while (1)
23142 if (selective_display)
23144 while (--cursor >= ceiling_addr
23145 && *cursor != '\n' && *cursor != 015)
23146 continue;
23147 if (cursor < ceiling_addr)
23148 break;
23150 else
23152 cursor = memrchr (ceiling_addr, '\n', cursor - ceiling_addr);
23153 if (! cursor)
23154 break;
23157 if (++count == 0)
23159 start_byte += cursor - base + 1;
23160 *byte_pos_ptr = start_byte;
23161 /* When scanning backwards, we should
23162 not count the newline posterior to which we stop. */
23163 return - orig_count - 1;
23166 start_byte += ceiling_addr - base;
23170 *byte_pos_ptr = limit_byte;
23172 if (count < 0)
23173 return - orig_count + count;
23174 return orig_count - count;
23180 /***********************************************************************
23181 Displaying strings
23182 ***********************************************************************/
23184 /* Display a NUL-terminated string, starting with index START.
23186 If STRING is non-null, display that C string. Otherwise, the Lisp
23187 string LISP_STRING is displayed. There's a case that STRING is
23188 non-null and LISP_STRING is not nil. It means STRING is a string
23189 data of LISP_STRING. In that case, we display LISP_STRING while
23190 ignoring its text properties.
23192 If FACE_STRING is not nil, FACE_STRING_POS is a position in
23193 FACE_STRING. Display STRING or LISP_STRING with the face at
23194 FACE_STRING_POS in FACE_STRING:
23196 Display the string in the environment given by IT, but use the
23197 standard display table, temporarily.
23199 FIELD_WIDTH is the minimum number of output glyphs to produce.
23200 If STRING has fewer characters than FIELD_WIDTH, pad to the right
23201 with spaces. If STRING has more characters, more than FIELD_WIDTH
23202 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
23204 PRECISION is the maximum number of characters to output from
23205 STRING. PRECISION < 0 means don't truncate the string.
23207 This is roughly equivalent to printf format specifiers:
23209 FIELD_WIDTH PRECISION PRINTF
23210 ----------------------------------------
23211 -1 -1 %s
23212 -1 10 %.10s
23213 10 -1 %10s
23214 20 10 %20.10s
23216 MULTIBYTE zero means do not display multibyte chars, > 0 means do
23217 display them, and < 0 means obey the current buffer's value of
23218 enable_multibyte_characters.
23220 Value is the number of columns displayed. */
23222 static int
23223 display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_string,
23224 ptrdiff_t face_string_pos, ptrdiff_t start, struct it *it,
23225 int field_width, int precision, int max_x, int multibyte)
23227 int hpos_at_start = it->hpos;
23228 int saved_face_id = it->face_id;
23229 struct glyph_row *row = it->glyph_row;
23230 ptrdiff_t it_charpos;
23232 /* Initialize the iterator IT for iteration over STRING beginning
23233 with index START. */
23234 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
23235 precision, field_width, multibyte);
23236 if (string && STRINGP (lisp_string))
23237 /* LISP_STRING is the one returned by decode_mode_spec. We should
23238 ignore its text properties. */
23239 it->stop_charpos = it->end_charpos;
23241 /* If displaying STRING, set up the face of the iterator from
23242 FACE_STRING, if that's given. */
23243 if (STRINGP (face_string))
23245 ptrdiff_t endptr;
23246 struct face *face;
23248 it->face_id
23249 = face_at_string_position (it->w, face_string, face_string_pos,
23250 0, &endptr, it->base_face_id, 0);
23251 face = FACE_FROM_ID (it->f, it->face_id);
23252 it->face_box_p = face->box != FACE_NO_BOX;
23255 /* Set max_x to the maximum allowed X position. Don't let it go
23256 beyond the right edge of the window. */
23257 if (max_x <= 0)
23258 max_x = it->last_visible_x;
23259 else
23260 max_x = min (max_x, it->last_visible_x);
23262 /* Skip over display elements that are not visible. because IT->w is
23263 hscrolled. */
23264 if (it->current_x < it->first_visible_x)
23265 move_it_in_display_line_to (it, 100000, it->first_visible_x,
23266 MOVE_TO_POS | MOVE_TO_X);
23268 row->ascent = it->max_ascent;
23269 row->height = it->max_ascent + it->max_descent;
23270 row->phys_ascent = it->max_phys_ascent;
23271 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
23272 row->extra_line_spacing = it->max_extra_line_spacing;
23274 if (STRINGP (it->string))
23275 it_charpos = IT_STRING_CHARPOS (*it);
23276 else
23277 it_charpos = IT_CHARPOS (*it);
23279 /* This condition is for the case that we are called with current_x
23280 past last_visible_x. */
23281 while (it->current_x < max_x)
23283 int x_before, x, n_glyphs_before, i, nglyphs;
23285 /* Get the next display element. */
23286 if (!get_next_display_element (it))
23287 break;
23289 /* Produce glyphs. */
23290 x_before = it->current_x;
23291 n_glyphs_before = row->used[TEXT_AREA];
23292 PRODUCE_GLYPHS (it);
23294 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
23295 i = 0;
23296 x = x_before;
23297 while (i < nglyphs)
23299 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
23301 if (it->line_wrap != TRUNCATE
23302 && x + glyph->pixel_width > max_x)
23304 /* End of continued line or max_x reached. */
23305 if (CHAR_GLYPH_PADDING_P (*glyph))
23307 /* A wide character is unbreakable. */
23308 if (row->reversed_p)
23309 unproduce_glyphs (it, row->used[TEXT_AREA]
23310 - n_glyphs_before);
23311 row->used[TEXT_AREA] = n_glyphs_before;
23312 it->current_x = x_before;
23314 else
23316 if (row->reversed_p)
23317 unproduce_glyphs (it, row->used[TEXT_AREA]
23318 - (n_glyphs_before + i));
23319 row->used[TEXT_AREA] = n_glyphs_before + i;
23320 it->current_x = x;
23322 break;
23324 else if (x + glyph->pixel_width >= it->first_visible_x)
23326 /* Glyph is at least partially visible. */
23327 ++it->hpos;
23328 if (x < it->first_visible_x)
23329 row->x = x - it->first_visible_x;
23331 else
23333 /* Glyph is off the left margin of the display area.
23334 Should not happen. */
23335 emacs_abort ();
23338 row->ascent = max (row->ascent, it->max_ascent);
23339 row->height = max (row->height, it->max_ascent + it->max_descent);
23340 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
23341 row->phys_height = max (row->phys_height,
23342 it->max_phys_ascent + it->max_phys_descent);
23343 row->extra_line_spacing = max (row->extra_line_spacing,
23344 it->max_extra_line_spacing);
23345 x += glyph->pixel_width;
23346 ++i;
23349 /* Stop if max_x reached. */
23350 if (i < nglyphs)
23351 break;
23353 /* Stop at line ends. */
23354 if (ITERATOR_AT_END_OF_LINE_P (it))
23356 it->continuation_lines_width = 0;
23357 break;
23360 set_iterator_to_next (it, 1);
23361 if (STRINGP (it->string))
23362 it_charpos = IT_STRING_CHARPOS (*it);
23363 else
23364 it_charpos = IT_CHARPOS (*it);
23366 /* Stop if truncating at the right edge. */
23367 if (it->line_wrap == TRUNCATE
23368 && it->current_x >= it->last_visible_x)
23370 /* Add truncation mark, but don't do it if the line is
23371 truncated at a padding space. */
23372 if (it_charpos < it->string_nchars)
23374 if (!FRAME_WINDOW_P (it->f))
23376 int ii, n;
23378 if (it->current_x > it->last_visible_x)
23380 if (!row->reversed_p)
23382 for (ii = row->used[TEXT_AREA] - 1; ii > 0; --ii)
23383 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
23384 break;
23386 else
23388 for (ii = 0; ii < row->used[TEXT_AREA]; ii++)
23389 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
23390 break;
23391 unproduce_glyphs (it, ii + 1);
23392 ii = row->used[TEXT_AREA] - (ii + 1);
23394 for (n = row->used[TEXT_AREA]; ii < n; ++ii)
23396 row->used[TEXT_AREA] = ii;
23397 produce_special_glyphs (it, IT_TRUNCATION);
23400 produce_special_glyphs (it, IT_TRUNCATION);
23402 row->truncated_on_right_p = 1;
23404 break;
23408 /* Maybe insert a truncation at the left. */
23409 if (it->first_visible_x
23410 && it_charpos > 0)
23412 if (!FRAME_WINDOW_P (it->f)
23413 || (row->reversed_p
23414 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
23415 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
23416 insert_left_trunc_glyphs (it);
23417 row->truncated_on_left_p = 1;
23420 it->face_id = saved_face_id;
23422 /* Value is number of columns displayed. */
23423 return it->hpos - hpos_at_start;
23428 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
23429 appears as an element of LIST or as the car of an element of LIST.
23430 If PROPVAL is a list, compare each element against LIST in that
23431 way, and return 1/2 if any element of PROPVAL is found in LIST.
23432 Otherwise return 0. This function cannot quit.
23433 The return value is 2 if the text is invisible but with an ellipsis
23434 and 1 if it's invisible and without an ellipsis. */
23437 invisible_p (register Lisp_Object propval, Lisp_Object list)
23439 register Lisp_Object tail, proptail;
23441 for (tail = list; CONSP (tail); tail = XCDR (tail))
23443 register Lisp_Object tem;
23444 tem = XCAR (tail);
23445 if (EQ (propval, tem))
23446 return 1;
23447 if (CONSP (tem) && EQ (propval, XCAR (tem)))
23448 return NILP (XCDR (tem)) ? 1 : 2;
23451 if (CONSP (propval))
23453 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
23455 Lisp_Object propelt;
23456 propelt = XCAR (proptail);
23457 for (tail = list; CONSP (tail); tail = XCDR (tail))
23459 register Lisp_Object tem;
23460 tem = XCAR (tail);
23461 if (EQ (propelt, tem))
23462 return 1;
23463 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
23464 return NILP (XCDR (tem)) ? 1 : 2;
23469 return 0;
23472 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
23473 doc: /* Non-nil if the property makes the text invisible.
23474 POS-OR-PROP can be a marker or number, in which case it is taken to be
23475 a position in the current buffer and the value of the `invisible' property
23476 is checked; or it can be some other value, which is then presumed to be the
23477 value of the `invisible' property of the text of interest.
23478 The non-nil value returned can be t for truly invisible text or something
23479 else if the text is replaced by an ellipsis. */)
23480 (Lisp_Object pos_or_prop)
23482 Lisp_Object prop
23483 = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
23484 ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
23485 : pos_or_prop);
23486 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
23487 return (invis == 0 ? Qnil
23488 : invis == 1 ? Qt
23489 : make_number (invis));
23492 /* Calculate a width or height in pixels from a specification using
23493 the following elements:
23495 SPEC ::=
23496 NUM - a (fractional) multiple of the default font width/height
23497 (NUM) - specifies exactly NUM pixels
23498 UNIT - a fixed number of pixels, see below.
23499 ELEMENT - size of a display element in pixels, see below.
23500 (NUM . SPEC) - equals NUM * SPEC
23501 (+ SPEC SPEC ...) - add pixel values
23502 (- SPEC SPEC ...) - subtract pixel values
23503 (- SPEC) - negate pixel value
23505 NUM ::=
23506 INT or FLOAT - a number constant
23507 SYMBOL - use symbol's (buffer local) variable binding.
23509 UNIT ::=
23510 in - pixels per inch *)
23511 mm - pixels per 1/1000 meter *)
23512 cm - pixels per 1/100 meter *)
23513 width - width of current font in pixels.
23514 height - height of current font in pixels.
23516 *) using the ratio(s) defined in display-pixels-per-inch.
23518 ELEMENT ::=
23520 left-fringe - left fringe width in pixels
23521 right-fringe - right fringe width in pixels
23523 left-margin - left margin width in pixels
23524 right-margin - right margin width in pixels
23526 scroll-bar - scroll-bar area width in pixels
23528 Examples:
23530 Pixels corresponding to 5 inches:
23531 (5 . in)
23533 Total width of non-text areas on left side of window (if scroll-bar is on left):
23534 '(space :width (+ left-fringe left-margin scroll-bar))
23536 Align to first text column (in header line):
23537 '(space :align-to 0)
23539 Align to middle of text area minus half the width of variable `my-image'
23540 containing a loaded image:
23541 '(space :align-to (0.5 . (- text my-image)))
23543 Width of left margin minus width of 1 character in the default font:
23544 '(space :width (- left-margin 1))
23546 Width of left margin minus width of 2 characters in the current font:
23547 '(space :width (- left-margin (2 . width)))
23549 Center 1 character over left-margin (in header line):
23550 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
23552 Different ways to express width of left fringe plus left margin minus one pixel:
23553 '(space :width (- (+ left-fringe left-margin) (1)))
23554 '(space :width (+ left-fringe left-margin (- (1))))
23555 '(space :width (+ left-fringe left-margin (-1)))
23559 static int
23560 calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
23561 struct font *font, int width_p, int *align_to)
23563 double pixels;
23565 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
23566 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
23568 if (NILP (prop))
23569 return OK_PIXELS (0);
23571 eassert (FRAME_LIVE_P (it->f));
23573 if (SYMBOLP (prop))
23575 if (SCHARS (SYMBOL_NAME (prop)) == 2)
23577 char *unit = SSDATA (SYMBOL_NAME (prop));
23579 if (unit[0] == 'i' && unit[1] == 'n')
23580 pixels = 1.0;
23581 else if (unit[0] == 'm' && unit[1] == 'm')
23582 pixels = 25.4;
23583 else if (unit[0] == 'c' && unit[1] == 'm')
23584 pixels = 2.54;
23585 else
23586 pixels = 0;
23587 if (pixels > 0)
23589 double ppi = (width_p ? FRAME_RES_X (it->f)
23590 : FRAME_RES_Y (it->f));
23592 if (ppi > 0)
23593 return OK_PIXELS (ppi / pixels);
23594 return 0;
23598 #ifdef HAVE_WINDOW_SYSTEM
23599 if (EQ (prop, Qheight))
23600 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
23601 if (EQ (prop, Qwidth))
23602 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
23603 #else
23604 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
23605 return OK_PIXELS (1);
23606 #endif
23608 if (EQ (prop, Qtext))
23609 return OK_PIXELS (width_p
23610 ? window_box_width (it->w, TEXT_AREA)
23611 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
23613 if (align_to && *align_to < 0)
23615 *res = 0;
23616 if (EQ (prop, Qleft))
23617 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
23618 if (EQ (prop, Qright))
23619 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
23620 if (EQ (prop, Qcenter))
23621 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
23622 + window_box_width (it->w, TEXT_AREA) / 2);
23623 if (EQ (prop, Qleft_fringe))
23624 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
23625 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
23626 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
23627 if (EQ (prop, Qright_fringe))
23628 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
23629 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
23630 : window_box_right_offset (it->w, TEXT_AREA));
23631 if (EQ (prop, Qleft_margin))
23632 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
23633 if (EQ (prop, Qright_margin))
23634 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
23635 if (EQ (prop, Qscroll_bar))
23636 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
23638 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
23639 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
23640 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
23641 : 0)));
23643 else
23645 if (EQ (prop, Qleft_fringe))
23646 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
23647 if (EQ (prop, Qright_fringe))
23648 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
23649 if (EQ (prop, Qleft_margin))
23650 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
23651 if (EQ (prop, Qright_margin))
23652 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
23653 if (EQ (prop, Qscroll_bar))
23654 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
23657 prop = buffer_local_value (prop, it->w->contents);
23658 if (EQ (prop, Qunbound))
23659 prop = Qnil;
23662 if (INTEGERP (prop) || FLOATP (prop))
23664 int base_unit = (width_p
23665 ? FRAME_COLUMN_WIDTH (it->f)
23666 : FRAME_LINE_HEIGHT (it->f));
23667 return OK_PIXELS (XFLOATINT (prop) * base_unit);
23670 if (CONSP (prop))
23672 Lisp_Object car = XCAR (prop);
23673 Lisp_Object cdr = XCDR (prop);
23675 if (SYMBOLP (car))
23677 #ifdef HAVE_WINDOW_SYSTEM
23678 if (FRAME_WINDOW_P (it->f)
23679 && valid_image_p (prop))
23681 ptrdiff_t id = lookup_image (it->f, prop);
23682 struct image *img = IMAGE_FROM_ID (it->f, id);
23684 return OK_PIXELS (width_p ? img->width : img->height);
23686 #endif
23687 if (EQ (car, Qplus) || EQ (car, Qminus))
23689 int first = 1;
23690 double px;
23692 pixels = 0;
23693 while (CONSP (cdr))
23695 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
23696 font, width_p, align_to))
23697 return 0;
23698 if (first)
23699 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
23700 else
23701 pixels += px;
23702 cdr = XCDR (cdr);
23704 if (EQ (car, Qminus))
23705 pixels = -pixels;
23706 return OK_PIXELS (pixels);
23709 car = buffer_local_value (car, it->w->contents);
23710 if (EQ (car, Qunbound))
23711 car = Qnil;
23714 if (INTEGERP (car) || FLOATP (car))
23716 double fact;
23717 pixels = XFLOATINT (car);
23718 if (NILP (cdr))
23719 return OK_PIXELS (pixels);
23720 if (calc_pixel_width_or_height (&fact, it, cdr,
23721 font, width_p, align_to))
23722 return OK_PIXELS (pixels * fact);
23723 return 0;
23726 return 0;
23729 return 0;
23733 /***********************************************************************
23734 Glyph Display
23735 ***********************************************************************/
23737 #ifdef HAVE_WINDOW_SYSTEM
23739 #ifdef GLYPH_DEBUG
23741 void
23742 dump_glyph_string (struct glyph_string *s)
23744 fprintf (stderr, "glyph string\n");
23745 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
23746 s->x, s->y, s->width, s->height);
23747 fprintf (stderr, " ybase = %d\n", s->ybase);
23748 fprintf (stderr, " hl = %d\n", s->hl);
23749 fprintf (stderr, " left overhang = %d, right = %d\n",
23750 s->left_overhang, s->right_overhang);
23751 fprintf (stderr, " nchars = %d\n", s->nchars);
23752 fprintf (stderr, " extends to end of line = %d\n",
23753 s->extends_to_end_of_line_p);
23754 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
23755 fprintf (stderr, " bg width = %d\n", s->background_width);
23758 #endif /* GLYPH_DEBUG */
23760 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
23761 of XChar2b structures for S; it can't be allocated in
23762 init_glyph_string because it must be allocated via `alloca'. W
23763 is the window on which S is drawn. ROW and AREA are the glyph row
23764 and area within the row from which S is constructed. START is the
23765 index of the first glyph structure covered by S. HL is a
23766 face-override for drawing S. */
23768 #ifdef HAVE_NTGUI
23769 #define OPTIONAL_HDC(hdc) HDC hdc,
23770 #define DECLARE_HDC(hdc) HDC hdc;
23771 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
23772 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
23773 #endif
23775 #ifndef OPTIONAL_HDC
23776 #define OPTIONAL_HDC(hdc)
23777 #define DECLARE_HDC(hdc)
23778 #define ALLOCATE_HDC(hdc, f)
23779 #define RELEASE_HDC(hdc, f)
23780 #endif
23782 static void
23783 init_glyph_string (struct glyph_string *s,
23784 OPTIONAL_HDC (hdc)
23785 XChar2b *char2b, struct window *w, struct glyph_row *row,
23786 enum glyph_row_area area, int start, enum draw_glyphs_face hl)
23788 memset (s, 0, sizeof *s);
23789 s->w = w;
23790 s->f = XFRAME (w->frame);
23791 #ifdef HAVE_NTGUI
23792 s->hdc = hdc;
23793 #endif
23794 s->display = FRAME_X_DISPLAY (s->f);
23795 s->window = FRAME_X_WINDOW (s->f);
23796 s->char2b = char2b;
23797 s->hl = hl;
23798 s->row = row;
23799 s->area = area;
23800 s->first_glyph = row->glyphs[area] + start;
23801 s->height = row->height;
23802 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
23803 s->ybase = s->y + row->ascent;
23807 /* Append the list of glyph strings with head H and tail T to the list
23808 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
23810 static void
23811 append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
23812 struct glyph_string *h, struct glyph_string *t)
23814 if (h)
23816 if (*head)
23817 (*tail)->next = h;
23818 else
23819 *head = h;
23820 h->prev = *tail;
23821 *tail = t;
23826 /* Prepend the list of glyph strings with head H and tail T to the
23827 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
23828 result. */
23830 static void
23831 prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
23832 struct glyph_string *h, struct glyph_string *t)
23834 if (h)
23836 if (*head)
23837 (*head)->prev = t;
23838 else
23839 *tail = t;
23840 t->next = *head;
23841 *head = h;
23846 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
23847 Set *HEAD and *TAIL to the resulting list. */
23849 static void
23850 append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
23851 struct glyph_string *s)
23853 s->next = s->prev = NULL;
23854 append_glyph_string_lists (head, tail, s, s);
23858 /* Get face and two-byte form of character C in face FACE_ID on frame F.
23859 The encoding of C is returned in *CHAR2B. DISPLAY_P non-zero means
23860 make sure that X resources for the face returned are allocated.
23861 Value is a pointer to a realized face that is ready for display if
23862 DISPLAY_P is non-zero. */
23864 static struct face *
23865 get_char_face_and_encoding (struct frame *f, int c, int face_id,
23866 XChar2b *char2b, int display_p)
23868 struct face *face = FACE_FROM_ID (f, face_id);
23869 unsigned code = 0;
23871 if (face->font)
23873 code = face->font->driver->encode_char (face->font, c);
23875 if (code == FONT_INVALID_CODE)
23876 code = 0;
23878 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
23880 /* Make sure X resources of the face are allocated. */
23881 #ifdef HAVE_X_WINDOWS
23882 if (display_p)
23883 #endif
23885 eassert (face != NULL);
23886 prepare_face_for_display (f, face);
23889 return face;
23893 /* Get face and two-byte form of character glyph GLYPH on frame F.
23894 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
23895 a pointer to a realized face that is ready for display. */
23897 static struct face *
23898 get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
23899 XChar2b *char2b, int *two_byte_p)
23901 struct face *face;
23902 unsigned code = 0;
23904 eassert (glyph->type == CHAR_GLYPH);
23905 face = FACE_FROM_ID (f, glyph->face_id);
23907 /* Make sure X resources of the face are allocated. */
23908 eassert (face != NULL);
23909 prepare_face_for_display (f, face);
23911 if (two_byte_p)
23912 *two_byte_p = 0;
23914 if (face->font)
23916 if (CHAR_BYTE8_P (glyph->u.ch))
23917 code = CHAR_TO_BYTE8 (glyph->u.ch);
23918 else
23919 code = face->font->driver->encode_char (face->font, glyph->u.ch);
23921 if (code == FONT_INVALID_CODE)
23922 code = 0;
23925 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
23926 return face;
23930 /* Get glyph code of character C in FONT in the two-byte form CHAR2B.
23931 Return 1 if FONT has a glyph for C, otherwise return 0. */
23933 static int
23934 get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
23936 unsigned code;
23938 if (CHAR_BYTE8_P (c))
23939 code = CHAR_TO_BYTE8 (c);
23940 else
23941 code = font->driver->encode_char (font, c);
23943 if (code == FONT_INVALID_CODE)
23944 return 0;
23945 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
23946 return 1;
23950 /* Fill glyph string S with composition components specified by S->cmp.
23952 BASE_FACE is the base face of the composition.
23953 S->cmp_from is the index of the first component for S.
23955 OVERLAPS non-zero means S should draw the foreground only, and use
23956 its physical height for clipping. See also draw_glyphs.
23958 Value is the index of a component not in S. */
23960 static int
23961 fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
23962 int overlaps)
23964 int i;
23965 /* For all glyphs of this composition, starting at the offset
23966 S->cmp_from, until we reach the end of the definition or encounter a
23967 glyph that requires the different face, add it to S. */
23968 struct face *face;
23970 eassert (s);
23972 s->for_overlaps = overlaps;
23973 s->face = NULL;
23974 s->font = NULL;
23975 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
23977 int c = COMPOSITION_GLYPH (s->cmp, i);
23979 /* TAB in a composition means display glyphs with padding space
23980 on the left or right. */
23981 if (c != '\t')
23983 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
23984 -1, Qnil);
23986 face = get_char_face_and_encoding (s->f, c, face_id,
23987 s->char2b + i, 1);
23988 if (face)
23990 if (! s->face)
23992 s->face = face;
23993 s->font = s->face->font;
23995 else if (s->face != face)
23996 break;
23999 ++s->nchars;
24001 s->cmp_to = i;
24003 if (s->face == NULL)
24005 s->face = base_face->ascii_face;
24006 s->font = s->face->font;
24009 /* All glyph strings for the same composition has the same width,
24010 i.e. the width set for the first component of the composition. */
24011 s->width = s->first_glyph->pixel_width;
24013 /* If the specified font could not be loaded, use the frame's
24014 default font, but record the fact that we couldn't load it in
24015 the glyph string so that we can draw rectangles for the
24016 characters of the glyph string. */
24017 if (s->font == NULL)
24019 s->font_not_found_p = 1;
24020 s->font = FRAME_FONT (s->f);
24023 /* Adjust base line for subscript/superscript text. */
24024 s->ybase += s->first_glyph->voffset;
24026 /* This glyph string must always be drawn with 16-bit functions. */
24027 s->two_byte_p = 1;
24029 return s->cmp_to;
24032 static int
24033 fill_gstring_glyph_string (struct glyph_string *s, int face_id,
24034 int start, int end, int overlaps)
24036 struct glyph *glyph, *last;
24037 Lisp_Object lgstring;
24038 int i;
24040 s->for_overlaps = overlaps;
24041 glyph = s->row->glyphs[s->area] + start;
24042 last = s->row->glyphs[s->area] + end;
24043 s->cmp_id = glyph->u.cmp.id;
24044 s->cmp_from = glyph->slice.cmp.from;
24045 s->cmp_to = glyph->slice.cmp.to + 1;
24046 s->face = FACE_FROM_ID (s->f, face_id);
24047 lgstring = composition_gstring_from_id (s->cmp_id);
24048 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
24049 glyph++;
24050 while (glyph < last
24051 && glyph->u.cmp.automatic
24052 && glyph->u.cmp.id == s->cmp_id
24053 && s->cmp_to == glyph->slice.cmp.from)
24054 s->cmp_to = (glyph++)->slice.cmp.to + 1;
24056 for (i = s->cmp_from; i < s->cmp_to; i++)
24058 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
24059 unsigned code = LGLYPH_CODE (lglyph);
24061 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
24063 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
24064 return glyph - s->row->glyphs[s->area];
24068 /* Fill glyph string S from a sequence glyphs for glyphless characters.
24069 See the comment of fill_glyph_string for arguments.
24070 Value is the index of the first glyph not in S. */
24073 static int
24074 fill_glyphless_glyph_string (struct glyph_string *s, int face_id,
24075 int start, int end, int overlaps)
24077 struct glyph *glyph, *last;
24078 int voffset;
24080 eassert (s->first_glyph->type == GLYPHLESS_GLYPH);
24081 s->for_overlaps = overlaps;
24082 glyph = s->row->glyphs[s->area] + start;
24083 last = s->row->glyphs[s->area] + end;
24084 voffset = glyph->voffset;
24085 s->face = FACE_FROM_ID (s->f, face_id);
24086 s->font = s->face->font ? s->face->font : FRAME_FONT (s->f);
24087 s->nchars = 1;
24088 s->width = glyph->pixel_width;
24089 glyph++;
24090 while (glyph < last
24091 && glyph->type == GLYPHLESS_GLYPH
24092 && glyph->voffset == voffset
24093 && glyph->face_id == face_id)
24095 s->nchars++;
24096 s->width += glyph->pixel_width;
24097 glyph++;
24099 s->ybase += voffset;
24100 return glyph - s->row->glyphs[s->area];
24104 /* Fill glyph string S from a sequence of character glyphs.
24106 FACE_ID is the face id of the string. START is the index of the
24107 first glyph to consider, END is the index of the last + 1.
24108 OVERLAPS non-zero means S should draw the foreground only, and use
24109 its physical height for clipping. See also draw_glyphs.
24111 Value is the index of the first glyph not in S. */
24113 static int
24114 fill_glyph_string (struct glyph_string *s, int face_id,
24115 int start, int end, int overlaps)
24117 struct glyph *glyph, *last;
24118 int voffset;
24119 int glyph_not_available_p;
24121 eassert (s->f == XFRAME (s->w->frame));
24122 eassert (s->nchars == 0);
24123 eassert (start >= 0 && end > start);
24125 s->for_overlaps = overlaps;
24126 glyph = s->row->glyphs[s->area] + start;
24127 last = s->row->glyphs[s->area] + end;
24128 voffset = glyph->voffset;
24129 s->padding_p = glyph->padding_p;
24130 glyph_not_available_p = glyph->glyph_not_available_p;
24132 while (glyph < last
24133 && glyph->type == CHAR_GLYPH
24134 && glyph->voffset == voffset
24135 /* Same face id implies same font, nowadays. */
24136 && glyph->face_id == face_id
24137 && glyph->glyph_not_available_p == glyph_not_available_p)
24139 int two_byte_p;
24141 s->face = get_glyph_face_and_encoding (s->f, glyph,
24142 s->char2b + s->nchars,
24143 &two_byte_p);
24144 s->two_byte_p = two_byte_p;
24145 ++s->nchars;
24146 eassert (s->nchars <= end - start);
24147 s->width += glyph->pixel_width;
24148 if (glyph++->padding_p != s->padding_p)
24149 break;
24152 s->font = s->face->font;
24154 /* If the specified font could not be loaded, use the frame's font,
24155 but record the fact that we couldn't load it in
24156 S->font_not_found_p so that we can draw rectangles for the
24157 characters of the glyph string. */
24158 if (s->font == NULL || glyph_not_available_p)
24160 s->font_not_found_p = 1;
24161 s->font = FRAME_FONT (s->f);
24164 /* Adjust base line for subscript/superscript text. */
24165 s->ybase += voffset;
24167 eassert (s->face && s->face->gc);
24168 return glyph - s->row->glyphs[s->area];
24172 /* Fill glyph string S from image glyph S->first_glyph. */
24174 static void
24175 fill_image_glyph_string (struct glyph_string *s)
24177 eassert (s->first_glyph->type == IMAGE_GLYPH);
24178 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
24179 eassert (s->img);
24180 s->slice = s->first_glyph->slice.img;
24181 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
24182 s->font = s->face->font;
24183 s->width = s->first_glyph->pixel_width;
24185 /* Adjust base line for subscript/superscript text. */
24186 s->ybase += s->first_glyph->voffset;
24190 /* Fill glyph string S from a sequence of stretch glyphs.
24192 START is the index of the first glyph to consider,
24193 END is the index of the last + 1.
24195 Value is the index of the first glyph not in S. */
24197 static int
24198 fill_stretch_glyph_string (struct glyph_string *s, int start, int end)
24200 struct glyph *glyph, *last;
24201 int voffset, face_id;
24203 eassert (s->first_glyph->type == STRETCH_GLYPH);
24205 glyph = s->row->glyphs[s->area] + start;
24206 last = s->row->glyphs[s->area] + end;
24207 face_id = glyph->face_id;
24208 s->face = FACE_FROM_ID (s->f, face_id);
24209 s->font = s->face->font;
24210 s->width = glyph->pixel_width;
24211 s->nchars = 1;
24212 voffset = glyph->voffset;
24214 for (++glyph;
24215 (glyph < last
24216 && glyph->type == STRETCH_GLYPH
24217 && glyph->voffset == voffset
24218 && glyph->face_id == face_id);
24219 ++glyph)
24220 s->width += glyph->pixel_width;
24222 /* Adjust base line for subscript/superscript text. */
24223 s->ybase += voffset;
24225 /* The case that face->gc == 0 is handled when drawing the glyph
24226 string by calling prepare_face_for_display. */
24227 eassert (s->face);
24228 return glyph - s->row->glyphs[s->area];
24231 static struct font_metrics *
24232 get_per_char_metric (struct font *font, XChar2b *char2b)
24234 static struct font_metrics metrics;
24235 unsigned code;
24237 if (! font)
24238 return NULL;
24239 code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
24240 if (code == FONT_INVALID_CODE)
24241 return NULL;
24242 font->driver->text_extents (font, &code, 1, &metrics);
24243 return &metrics;
24246 /* EXPORT for RIF:
24247 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
24248 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
24249 assumed to be zero. */
24251 void
24252 x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *right)
24254 *left = *right = 0;
24256 if (glyph->type == CHAR_GLYPH)
24258 struct face *face;
24259 XChar2b char2b;
24260 struct font_metrics *pcm;
24262 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
24263 if (face->font && (pcm = get_per_char_metric (face->font, &char2b)))
24265 if (pcm->rbearing > pcm->width)
24266 *right = pcm->rbearing - pcm->width;
24267 if (pcm->lbearing < 0)
24268 *left = -pcm->lbearing;
24271 else if (glyph->type == COMPOSITE_GLYPH)
24273 if (! glyph->u.cmp.automatic)
24275 struct composition *cmp = composition_table[glyph->u.cmp.id];
24277 if (cmp->rbearing > cmp->pixel_width)
24278 *right = cmp->rbearing - cmp->pixel_width;
24279 if (cmp->lbearing < 0)
24280 *left = - cmp->lbearing;
24282 else
24284 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
24285 struct font_metrics metrics;
24287 composition_gstring_width (gstring, glyph->slice.cmp.from,
24288 glyph->slice.cmp.to + 1, &metrics);
24289 if (metrics.rbearing > metrics.width)
24290 *right = metrics.rbearing - metrics.width;
24291 if (metrics.lbearing < 0)
24292 *left = - metrics.lbearing;
24298 /* Return the index of the first glyph preceding glyph string S that
24299 is overwritten by S because of S's left overhang. Value is -1
24300 if no glyphs are overwritten. */
24302 static int
24303 left_overwritten (struct glyph_string *s)
24305 int k;
24307 if (s->left_overhang)
24309 int x = 0, i;
24310 struct glyph *glyphs = s->row->glyphs[s->area];
24311 int first = s->first_glyph - glyphs;
24313 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
24314 x -= glyphs[i].pixel_width;
24316 k = i + 1;
24318 else
24319 k = -1;
24321 return k;
24325 /* Return the index of the first glyph preceding glyph string S that
24326 is overwriting S because of its right overhang. Value is -1 if no
24327 glyph in front of S overwrites S. */
24329 static int
24330 left_overwriting (struct glyph_string *s)
24332 int i, k, x;
24333 struct glyph *glyphs = s->row->glyphs[s->area];
24334 int first = s->first_glyph - glyphs;
24336 k = -1;
24337 x = 0;
24338 for (i = first - 1; i >= 0; --i)
24340 int left, right;
24341 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
24342 if (x + right > 0)
24343 k = i;
24344 x -= glyphs[i].pixel_width;
24347 return k;
24351 /* Return the index of the last glyph following glyph string S that is
24352 overwritten by S because of S's right overhang. Value is -1 if
24353 no such glyph is found. */
24355 static int
24356 right_overwritten (struct glyph_string *s)
24358 int k = -1;
24360 if (s->right_overhang)
24362 int x = 0, i;
24363 struct glyph *glyphs = s->row->glyphs[s->area];
24364 int first = (s->first_glyph - glyphs
24365 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
24366 int end = s->row->used[s->area];
24368 for (i = first; i < end && s->right_overhang > x; ++i)
24369 x += glyphs[i].pixel_width;
24371 k = i;
24374 return k;
24378 /* Return the index of the last glyph following glyph string S that
24379 overwrites S because of its left overhang. Value is negative
24380 if no such glyph is found. */
24382 static int
24383 right_overwriting (struct glyph_string *s)
24385 int i, k, x;
24386 int end = s->row->used[s->area];
24387 struct glyph *glyphs = s->row->glyphs[s->area];
24388 int first = (s->first_glyph - glyphs
24389 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
24391 k = -1;
24392 x = 0;
24393 for (i = first; i < end; ++i)
24395 int left, right;
24396 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
24397 if (x - left < 0)
24398 k = i;
24399 x += glyphs[i].pixel_width;
24402 return k;
24406 /* Set background width of glyph string S. START is the index of the
24407 first glyph following S. LAST_X is the right-most x-position + 1
24408 in the drawing area. */
24410 static void
24411 set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
24413 /* If the face of this glyph string has to be drawn to the end of
24414 the drawing area, set S->extends_to_end_of_line_p. */
24416 if (start == s->row->used[s->area]
24417 && ((s->row->fill_line_p
24418 && (s->hl == DRAW_NORMAL_TEXT
24419 || s->hl == DRAW_IMAGE_RAISED
24420 || s->hl == DRAW_IMAGE_SUNKEN))
24421 || s->hl == DRAW_MOUSE_FACE))
24422 s->extends_to_end_of_line_p = 1;
24424 /* If S extends its face to the end of the line, set its
24425 background_width to the distance to the right edge of the drawing
24426 area. */
24427 if (s->extends_to_end_of_line_p)
24428 s->background_width = last_x - s->x + 1;
24429 else
24430 s->background_width = s->width;
24434 /* Compute overhangs and x-positions for glyph string S and its
24435 predecessors, or successors. X is the starting x-position for S.
24436 BACKWARD_P non-zero means process predecessors. */
24438 static void
24439 compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
24441 if (backward_p)
24443 while (s)
24445 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
24446 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
24447 x -= s->width;
24448 s->x = x;
24449 s = s->prev;
24452 else
24454 while (s)
24456 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
24457 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
24458 s->x = x;
24459 x += s->width;
24460 s = s->next;
24467 /* The following macros are only called from draw_glyphs below.
24468 They reference the following parameters of that function directly:
24469 `w', `row', `area', and `overlap_p'
24470 as well as the following local variables:
24471 `s', `f', and `hdc' (in W32) */
24473 #ifdef HAVE_NTGUI
24474 /* On W32, silently add local `hdc' variable to argument list of
24475 init_glyph_string. */
24476 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
24477 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
24478 #else
24479 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
24480 init_glyph_string (s, char2b, w, row, area, start, hl)
24481 #endif
24483 /* Add a glyph string for a stretch glyph to the list of strings
24484 between HEAD and TAIL. START is the index of the stretch glyph in
24485 row area AREA of glyph row ROW. END is the index of the last glyph
24486 in that glyph row area. X is the current output position assigned
24487 to the new glyph string constructed. HL overrides that face of the
24488 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
24489 is the right-most x-position of the drawing area. */
24491 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
24492 and below -- keep them on one line. */
24493 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
24494 do \
24496 s = alloca (sizeof *s); \
24497 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
24498 START = fill_stretch_glyph_string (s, START, END); \
24499 append_glyph_string (&HEAD, &TAIL, s); \
24500 s->x = (X); \
24502 while (0)
24505 /* Add a glyph string for an image glyph to the list of strings
24506 between HEAD and TAIL. START is the index of the image glyph in
24507 row area AREA of glyph row ROW. END is the index of the last glyph
24508 in that glyph row area. X is the current output position assigned
24509 to the new glyph string constructed. HL overrides that face of the
24510 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
24511 is the right-most x-position of the drawing area. */
24513 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
24514 do \
24516 s = alloca (sizeof *s); \
24517 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
24518 fill_image_glyph_string (s); \
24519 append_glyph_string (&HEAD, &TAIL, s); \
24520 ++START; \
24521 s->x = (X); \
24523 while (0)
24526 /* Add a glyph string for a sequence of character glyphs to the list
24527 of strings between HEAD and TAIL. START is the index of the first
24528 glyph in row area AREA of glyph row ROW that is part of the new
24529 glyph string. END is the index of the last glyph in that glyph row
24530 area. X is the current output position assigned to the new glyph
24531 string constructed. HL overrides that face of the glyph; e.g. it
24532 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
24533 right-most x-position of the drawing area. */
24535 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
24536 do \
24538 int face_id; \
24539 XChar2b *char2b; \
24541 face_id = (row)->glyphs[area][START].face_id; \
24543 s = alloca (sizeof *s); \
24544 char2b = alloca ((END - START) * sizeof *char2b); \
24545 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
24546 append_glyph_string (&HEAD, &TAIL, s); \
24547 s->x = (X); \
24548 START = fill_glyph_string (s, face_id, START, END, overlaps); \
24550 while (0)
24553 /* Add a glyph string for a composite sequence to the list of strings
24554 between HEAD and TAIL. START is the index of the first glyph in
24555 row area AREA of glyph row ROW that is part of the new glyph
24556 string. END is the index of the last glyph in that glyph row area.
24557 X is the current output position assigned to the new glyph string
24558 constructed. HL overrides that face of the glyph; e.g. it is
24559 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
24560 x-position of the drawing area. */
24562 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
24563 do { \
24564 int face_id = (row)->glyphs[area][START].face_id; \
24565 struct face *base_face = FACE_FROM_ID (f, face_id); \
24566 ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \
24567 struct composition *cmp = composition_table[cmp_id]; \
24568 XChar2b *char2b; \
24569 struct glyph_string *first_s = NULL; \
24570 int n; \
24572 char2b = alloca (cmp->glyph_len * sizeof *char2b); \
24574 /* Make glyph_strings for each glyph sequence that is drawable by \
24575 the same face, and append them to HEAD/TAIL. */ \
24576 for (n = 0; n < cmp->glyph_len;) \
24578 s = alloca (sizeof *s); \
24579 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
24580 append_glyph_string (&(HEAD), &(TAIL), s); \
24581 s->cmp = cmp; \
24582 s->cmp_from = n; \
24583 s->x = (X); \
24584 if (n == 0) \
24585 first_s = s; \
24586 n = fill_composite_glyph_string (s, base_face, overlaps); \
24589 ++START; \
24590 s = first_s; \
24591 } while (0)
24594 /* Add a glyph string for a glyph-string sequence to the list of strings
24595 between HEAD and TAIL. */
24597 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
24598 do { \
24599 int face_id; \
24600 XChar2b *char2b; \
24601 Lisp_Object gstring; \
24603 face_id = (row)->glyphs[area][START].face_id; \
24604 gstring = (composition_gstring_from_id \
24605 ((row)->glyphs[area][START].u.cmp.id)); \
24606 s = alloca (sizeof *s); \
24607 char2b = alloca (LGSTRING_GLYPH_LEN (gstring) * sizeof *char2b); \
24608 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
24609 append_glyph_string (&(HEAD), &(TAIL), s); \
24610 s->x = (X); \
24611 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
24612 } while (0)
24615 /* Add a glyph string for a sequence of glyphless character's glyphs
24616 to the list of strings between HEAD and TAIL. The meanings of
24617 arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */
24619 #define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
24620 do \
24622 int face_id; \
24624 face_id = (row)->glyphs[area][START].face_id; \
24626 s = alloca (sizeof *s); \
24627 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
24628 append_glyph_string (&HEAD, &TAIL, s); \
24629 s->x = (X); \
24630 START = fill_glyphless_glyph_string (s, face_id, START, END, \
24631 overlaps); \
24633 while (0)
24636 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
24637 of AREA of glyph row ROW on window W between indices START and END.
24638 HL overrides the face for drawing glyph strings, e.g. it is
24639 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
24640 x-positions of the drawing area.
24642 This is an ugly monster macro construct because we must use alloca
24643 to allocate glyph strings (because draw_glyphs can be called
24644 asynchronously). */
24646 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
24647 do \
24649 HEAD = TAIL = NULL; \
24650 while (START < END) \
24652 struct glyph *first_glyph = (row)->glyphs[area] + START; \
24653 switch (first_glyph->type) \
24655 case CHAR_GLYPH: \
24656 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
24657 HL, X, LAST_X); \
24658 break; \
24660 case COMPOSITE_GLYPH: \
24661 if (first_glyph->u.cmp.automatic) \
24662 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
24663 HL, X, LAST_X); \
24664 else \
24665 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
24666 HL, X, LAST_X); \
24667 break; \
24669 case STRETCH_GLYPH: \
24670 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
24671 HL, X, LAST_X); \
24672 break; \
24674 case IMAGE_GLYPH: \
24675 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
24676 HL, X, LAST_X); \
24677 break; \
24679 case GLYPHLESS_GLYPH: \
24680 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
24681 HL, X, LAST_X); \
24682 break; \
24684 default: \
24685 emacs_abort (); \
24688 if (s) \
24690 set_glyph_string_background_width (s, START, LAST_X); \
24691 (X) += s->width; \
24694 } while (0)
24697 /* Draw glyphs between START and END in AREA of ROW on window W,
24698 starting at x-position X. X is relative to AREA in W. HL is a
24699 face-override with the following meaning:
24701 DRAW_NORMAL_TEXT draw normally
24702 DRAW_CURSOR draw in cursor face
24703 DRAW_MOUSE_FACE draw in mouse face.
24704 DRAW_INVERSE_VIDEO draw in mode line face
24705 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
24706 DRAW_IMAGE_RAISED draw an image with a raised relief around it
24708 If OVERLAPS is non-zero, draw only the foreground of characters and
24709 clip to the physical height of ROW. Non-zero value also defines
24710 the overlapping part to be drawn:
24712 OVERLAPS_PRED overlap with preceding rows
24713 OVERLAPS_SUCC overlap with succeeding rows
24714 OVERLAPS_BOTH overlap with both preceding/succeeding rows
24715 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
24717 Value is the x-position reached, relative to AREA of W. */
24719 static int
24720 draw_glyphs (struct window *w, int x, struct glyph_row *row,
24721 enum glyph_row_area area, ptrdiff_t start, ptrdiff_t end,
24722 enum draw_glyphs_face hl, int overlaps)
24724 struct glyph_string *head, *tail;
24725 struct glyph_string *s;
24726 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
24727 int i, j, x_reached, last_x, area_left = 0;
24728 struct frame *f = XFRAME (WINDOW_FRAME (w));
24729 DECLARE_HDC (hdc);
24731 ALLOCATE_HDC (hdc, f);
24733 /* Let's rather be paranoid than getting a SEGV. */
24734 end = min (end, row->used[area]);
24735 start = clip_to_bounds (0, start, end);
24737 /* Translate X to frame coordinates. Set last_x to the right
24738 end of the drawing area. */
24739 if (row->full_width_p)
24741 /* X is relative to the left edge of W, without scroll bars
24742 or fringes. */
24743 area_left = WINDOW_LEFT_EDGE_X (w);
24744 last_x = (WINDOW_LEFT_EDGE_X (w) + WINDOW_PIXEL_WIDTH (w)
24745 - (row->mode_line_p ? WINDOW_RIGHT_DIVIDER_WIDTH (w) : 0));
24747 else
24749 area_left = window_box_left (w, area);
24750 last_x = area_left + window_box_width (w, area);
24752 x += area_left;
24754 /* Build a doubly-linked list of glyph_string structures between
24755 head and tail from what we have to draw. Note that the macro
24756 BUILD_GLYPH_STRINGS will modify its start parameter. That's
24757 the reason we use a separate variable `i'. */
24758 i = start;
24759 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
24760 if (tail)
24761 x_reached = tail->x + tail->background_width;
24762 else
24763 x_reached = x;
24765 /* If there are any glyphs with lbearing < 0 or rbearing > width in
24766 the row, redraw some glyphs in front or following the glyph
24767 strings built above. */
24768 if (head && !overlaps && row->contains_overlapping_glyphs_p)
24770 struct glyph_string *h, *t;
24771 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
24772 int mouse_beg_col IF_LINT (= 0), mouse_end_col IF_LINT (= 0);
24773 int check_mouse_face = 0;
24774 int dummy_x = 0;
24776 /* If mouse highlighting is on, we may need to draw adjacent
24777 glyphs using mouse-face highlighting. */
24778 if (area == TEXT_AREA && row->mouse_face_p
24779 && hlinfo->mouse_face_beg_row >= 0
24780 && hlinfo->mouse_face_end_row >= 0)
24782 ptrdiff_t row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
24784 if (row_vpos >= hlinfo->mouse_face_beg_row
24785 && row_vpos <= hlinfo->mouse_face_end_row)
24787 check_mouse_face = 1;
24788 mouse_beg_col = (row_vpos == hlinfo->mouse_face_beg_row)
24789 ? hlinfo->mouse_face_beg_col : 0;
24790 mouse_end_col = (row_vpos == hlinfo->mouse_face_end_row)
24791 ? hlinfo->mouse_face_end_col
24792 : row->used[TEXT_AREA];
24796 /* Compute overhangs for all glyph strings. */
24797 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
24798 for (s = head; s; s = s->next)
24799 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
24801 /* Prepend glyph strings for glyphs in front of the first glyph
24802 string that are overwritten because of the first glyph
24803 string's left overhang. The background of all strings
24804 prepended must be drawn because the first glyph string
24805 draws over it. */
24806 i = left_overwritten (head);
24807 if (i >= 0)
24809 enum draw_glyphs_face overlap_hl;
24811 /* If this row contains mouse highlighting, attempt to draw
24812 the overlapped glyphs with the correct highlight. This
24813 code fails if the overlap encompasses more than one glyph
24814 and mouse-highlight spans only some of these glyphs.
24815 However, making it work perfectly involves a lot more
24816 code, and I don't know if the pathological case occurs in
24817 practice, so we'll stick to this for now. --- cyd */
24818 if (check_mouse_face
24819 && mouse_beg_col < start && mouse_end_col > i)
24820 overlap_hl = DRAW_MOUSE_FACE;
24821 else
24822 overlap_hl = DRAW_NORMAL_TEXT;
24824 if (hl != overlap_hl)
24825 clip_head = head;
24826 j = i;
24827 BUILD_GLYPH_STRINGS (j, start, h, t,
24828 overlap_hl, dummy_x, last_x);
24829 start = i;
24830 compute_overhangs_and_x (t, head->x, 1);
24831 prepend_glyph_string_lists (&head, &tail, h, t);
24832 if (clip_head == NULL)
24833 clip_head = head;
24836 /* Prepend glyph strings for glyphs in front of the first glyph
24837 string that overwrite that glyph string because of their
24838 right overhang. For these strings, only the foreground must
24839 be drawn, because it draws over the glyph string at `head'.
24840 The background must not be drawn because this would overwrite
24841 right overhangs of preceding glyphs for which no glyph
24842 strings exist. */
24843 i = left_overwriting (head);
24844 if (i >= 0)
24846 enum draw_glyphs_face overlap_hl;
24848 if (check_mouse_face
24849 && mouse_beg_col < start && mouse_end_col > i)
24850 overlap_hl = DRAW_MOUSE_FACE;
24851 else
24852 overlap_hl = DRAW_NORMAL_TEXT;
24854 if (hl == overlap_hl || clip_head == NULL)
24855 clip_head = head;
24856 BUILD_GLYPH_STRINGS (i, start, h, t,
24857 overlap_hl, dummy_x, last_x);
24858 for (s = h; s; s = s->next)
24859 s->background_filled_p = 1;
24860 compute_overhangs_and_x (t, head->x, 1);
24861 prepend_glyph_string_lists (&head, &tail, h, t);
24864 /* Append glyphs strings for glyphs following the last glyph
24865 string tail that are overwritten by tail. The background of
24866 these strings has to be drawn because tail's foreground draws
24867 over it. */
24868 i = right_overwritten (tail);
24869 if (i >= 0)
24871 enum draw_glyphs_face overlap_hl;
24873 if (check_mouse_face
24874 && mouse_beg_col < i && mouse_end_col > end)
24875 overlap_hl = DRAW_MOUSE_FACE;
24876 else
24877 overlap_hl = DRAW_NORMAL_TEXT;
24879 if (hl != overlap_hl)
24880 clip_tail = tail;
24881 BUILD_GLYPH_STRINGS (end, i, h, t,
24882 overlap_hl, x, last_x);
24883 /* Because BUILD_GLYPH_STRINGS updates the first argument,
24884 we don't have `end = i;' here. */
24885 compute_overhangs_and_x (h, tail->x + tail->width, 0);
24886 append_glyph_string_lists (&head, &tail, h, t);
24887 if (clip_tail == NULL)
24888 clip_tail = tail;
24891 /* Append glyph strings for glyphs following the last glyph
24892 string tail that overwrite tail. The foreground of such
24893 glyphs has to be drawn because it writes into the background
24894 of tail. The background must not be drawn because it could
24895 paint over the foreground of following glyphs. */
24896 i = right_overwriting (tail);
24897 if (i >= 0)
24899 enum draw_glyphs_face overlap_hl;
24900 if (check_mouse_face
24901 && mouse_beg_col < i && mouse_end_col > end)
24902 overlap_hl = DRAW_MOUSE_FACE;
24903 else
24904 overlap_hl = DRAW_NORMAL_TEXT;
24906 if (hl == overlap_hl || clip_tail == NULL)
24907 clip_tail = tail;
24908 i++; /* We must include the Ith glyph. */
24909 BUILD_GLYPH_STRINGS (end, i, h, t,
24910 overlap_hl, x, last_x);
24911 for (s = h; s; s = s->next)
24912 s->background_filled_p = 1;
24913 compute_overhangs_and_x (h, tail->x + tail->width, 0);
24914 append_glyph_string_lists (&head, &tail, h, t);
24916 if (clip_head || clip_tail)
24917 for (s = head; s; s = s->next)
24919 s->clip_head = clip_head;
24920 s->clip_tail = clip_tail;
24924 /* Draw all strings. */
24925 for (s = head; s; s = s->next)
24926 FRAME_RIF (f)->draw_glyph_string (s);
24928 #ifndef HAVE_NS
24929 /* When focus a sole frame and move horizontally, this sets on_p to 0
24930 causing a failure to erase prev cursor position. */
24931 if (area == TEXT_AREA
24932 && !row->full_width_p
24933 /* When drawing overlapping rows, only the glyph strings'
24934 foreground is drawn, which doesn't erase a cursor
24935 completely. */
24936 && !overlaps)
24938 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
24939 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
24940 : (tail ? tail->x + tail->background_width : x));
24941 x0 -= area_left;
24942 x1 -= area_left;
24944 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
24945 row->y, MATRIX_ROW_BOTTOM_Y (row));
24947 #endif
24949 /* Value is the x-position up to which drawn, relative to AREA of W.
24950 This doesn't include parts drawn because of overhangs. */
24951 if (row->full_width_p)
24952 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
24953 else
24954 x_reached -= area_left;
24956 RELEASE_HDC (hdc, f);
24958 return x_reached;
24961 /* Expand row matrix if too narrow. Don't expand if area
24962 is not present. */
24964 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
24966 if (!it->f->fonts_changed \
24967 && (it->glyph_row->glyphs[area] \
24968 < it->glyph_row->glyphs[area + 1])) \
24970 it->w->ncols_scale_factor++; \
24971 it->f->fonts_changed = 1; \
24975 /* Store one glyph for IT->char_to_display in IT->glyph_row.
24976 Called from x_produce_glyphs when IT->glyph_row is non-null. */
24978 static void
24979 append_glyph (struct it *it)
24981 struct glyph *glyph;
24982 enum glyph_row_area area = it->area;
24984 eassert (it->glyph_row);
24985 eassert (it->char_to_display != '\n' && it->char_to_display != '\t');
24987 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24988 if (glyph < it->glyph_row->glyphs[area + 1])
24990 /* If the glyph row is reversed, we need to prepend the glyph
24991 rather than append it. */
24992 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24994 struct glyph *g;
24996 /* Make room for the additional glyph. */
24997 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
24998 g[1] = *g;
24999 glyph = it->glyph_row->glyphs[area];
25001 glyph->charpos = CHARPOS (it->position);
25002 glyph->object = it->object;
25003 if (it->pixel_width > 0)
25005 glyph->pixel_width = it->pixel_width;
25006 glyph->padding_p = 0;
25008 else
25010 /* Assure at least 1-pixel width. Otherwise, cursor can't
25011 be displayed correctly. */
25012 glyph->pixel_width = 1;
25013 glyph->padding_p = 1;
25015 glyph->ascent = it->ascent;
25016 glyph->descent = it->descent;
25017 glyph->voffset = it->voffset;
25018 glyph->type = CHAR_GLYPH;
25019 glyph->avoid_cursor_p = it->avoid_cursor_p;
25020 glyph->multibyte_p = it->multibyte_p;
25021 if (it->glyph_row->reversed_p && area == TEXT_AREA)
25023 /* In R2L rows, the left and the right box edges need to be
25024 drawn in reverse direction. */
25025 glyph->right_box_line_p = it->start_of_box_run_p;
25026 glyph->left_box_line_p = it->end_of_box_run_p;
25028 else
25030 glyph->left_box_line_p = it->start_of_box_run_p;
25031 glyph->right_box_line_p = it->end_of_box_run_p;
25033 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
25034 || it->phys_descent > it->descent);
25035 glyph->glyph_not_available_p = it->glyph_not_available_p;
25036 glyph->face_id = it->face_id;
25037 glyph->u.ch = it->char_to_display;
25038 glyph->slice.img = null_glyph_slice;
25039 glyph->font_type = FONT_TYPE_UNKNOWN;
25040 if (it->bidi_p)
25042 glyph->resolved_level = it->bidi_it.resolved_level;
25043 if ((it->bidi_it.type & 7) != it->bidi_it.type)
25044 emacs_abort ();
25045 glyph->bidi_type = it->bidi_it.type;
25047 else
25049 glyph->resolved_level = 0;
25050 glyph->bidi_type = UNKNOWN_BT;
25052 ++it->glyph_row->used[area];
25054 else
25055 IT_EXPAND_MATRIX_WIDTH (it, area);
25058 /* Store one glyph for the composition IT->cmp_it.id in
25059 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
25060 non-null. */
25062 static void
25063 append_composite_glyph (struct it *it)
25065 struct glyph *glyph;
25066 enum glyph_row_area area = it->area;
25068 eassert (it->glyph_row);
25070 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
25071 if (glyph < it->glyph_row->glyphs[area + 1])
25073 /* If the glyph row is reversed, we need to prepend the glyph
25074 rather than append it. */
25075 if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
25077 struct glyph *g;
25079 /* Make room for the new glyph. */
25080 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
25081 g[1] = *g;
25082 glyph = it->glyph_row->glyphs[it->area];
25084 glyph->charpos = it->cmp_it.charpos;
25085 glyph->object = it->object;
25086 glyph->pixel_width = it->pixel_width;
25087 glyph->ascent = it->ascent;
25088 glyph->descent = it->descent;
25089 glyph->voffset = it->voffset;
25090 glyph->type = COMPOSITE_GLYPH;
25091 if (it->cmp_it.ch < 0)
25093 glyph->u.cmp.automatic = 0;
25094 glyph->u.cmp.id = it->cmp_it.id;
25095 glyph->slice.cmp.from = glyph->slice.cmp.to = 0;
25097 else
25099 glyph->u.cmp.automatic = 1;
25100 glyph->u.cmp.id = it->cmp_it.id;
25101 glyph->slice.cmp.from = it->cmp_it.from;
25102 glyph->slice.cmp.to = it->cmp_it.to - 1;
25104 glyph->avoid_cursor_p = it->avoid_cursor_p;
25105 glyph->multibyte_p = it->multibyte_p;
25106 if (it->glyph_row->reversed_p && area == TEXT_AREA)
25108 /* In R2L rows, the left and the right box edges need to be
25109 drawn in reverse direction. */
25110 glyph->right_box_line_p = it->start_of_box_run_p;
25111 glyph->left_box_line_p = it->end_of_box_run_p;
25113 else
25115 glyph->left_box_line_p = it->start_of_box_run_p;
25116 glyph->right_box_line_p = it->end_of_box_run_p;
25118 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
25119 || it->phys_descent > it->descent);
25120 glyph->padding_p = 0;
25121 glyph->glyph_not_available_p = 0;
25122 glyph->face_id = it->face_id;
25123 glyph->font_type = FONT_TYPE_UNKNOWN;
25124 if (it->bidi_p)
25126 glyph->resolved_level = it->bidi_it.resolved_level;
25127 if ((it->bidi_it.type & 7) != it->bidi_it.type)
25128 emacs_abort ();
25129 glyph->bidi_type = it->bidi_it.type;
25131 ++it->glyph_row->used[area];
25133 else
25134 IT_EXPAND_MATRIX_WIDTH (it, area);
25138 /* Change IT->ascent and IT->height according to the setting of
25139 IT->voffset. */
25141 static void
25142 take_vertical_position_into_account (struct it *it)
25144 if (it->voffset)
25146 if (it->voffset < 0)
25147 /* Increase the ascent so that we can display the text higher
25148 in the line. */
25149 it->ascent -= it->voffset;
25150 else
25151 /* Increase the descent so that we can display the text lower
25152 in the line. */
25153 it->descent += it->voffset;
25158 /* Produce glyphs/get display metrics for the image IT is loaded with.
25159 See the description of struct display_iterator in dispextern.h for
25160 an overview of struct display_iterator. */
25162 static void
25163 produce_image_glyph (struct it *it)
25165 struct image *img;
25166 struct face *face;
25167 int glyph_ascent, crop;
25168 struct glyph_slice slice;
25170 eassert (it->what == IT_IMAGE);
25172 face = FACE_FROM_ID (it->f, it->face_id);
25173 eassert (face);
25174 /* Make sure X resources of the face is loaded. */
25175 prepare_face_for_display (it->f, face);
25177 if (it->image_id < 0)
25179 /* Fringe bitmap. */
25180 it->ascent = it->phys_ascent = 0;
25181 it->descent = it->phys_descent = 0;
25182 it->pixel_width = 0;
25183 it->nglyphs = 0;
25184 return;
25187 img = IMAGE_FROM_ID (it->f, it->image_id);
25188 eassert (img);
25189 /* Make sure X resources of the image is loaded. */
25190 prepare_image_for_display (it->f, img);
25192 slice.x = slice.y = 0;
25193 slice.width = img->width;
25194 slice.height = img->height;
25196 if (INTEGERP (it->slice.x))
25197 slice.x = XINT (it->slice.x);
25198 else if (FLOATP (it->slice.x))
25199 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
25201 if (INTEGERP (it->slice.y))
25202 slice.y = XINT (it->slice.y);
25203 else if (FLOATP (it->slice.y))
25204 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
25206 if (INTEGERP (it->slice.width))
25207 slice.width = XINT (it->slice.width);
25208 else if (FLOATP (it->slice.width))
25209 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
25211 if (INTEGERP (it->slice.height))
25212 slice.height = XINT (it->slice.height);
25213 else if (FLOATP (it->slice.height))
25214 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
25216 if (slice.x >= img->width)
25217 slice.x = img->width;
25218 if (slice.y >= img->height)
25219 slice.y = img->height;
25220 if (slice.x + slice.width >= img->width)
25221 slice.width = img->width - slice.x;
25222 if (slice.y + slice.height > img->height)
25223 slice.height = img->height - slice.y;
25225 if (slice.width == 0 || slice.height == 0)
25226 return;
25228 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
25230 it->descent = slice.height - glyph_ascent;
25231 if (slice.y == 0)
25232 it->descent += img->vmargin;
25233 if (slice.y + slice.height == img->height)
25234 it->descent += img->vmargin;
25235 it->phys_descent = it->descent;
25237 it->pixel_width = slice.width;
25238 if (slice.x == 0)
25239 it->pixel_width += img->hmargin;
25240 if (slice.x + slice.width == img->width)
25241 it->pixel_width += img->hmargin;
25243 /* It's quite possible for images to have an ascent greater than
25244 their height, so don't get confused in that case. */
25245 if (it->descent < 0)
25246 it->descent = 0;
25248 it->nglyphs = 1;
25250 if (face->box != FACE_NO_BOX)
25252 if (face->box_line_width > 0)
25254 if (slice.y == 0)
25255 it->ascent += face->box_line_width;
25256 if (slice.y + slice.height == img->height)
25257 it->descent += face->box_line_width;
25260 if (it->start_of_box_run_p && slice.x == 0)
25261 it->pixel_width += eabs (face->box_line_width);
25262 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
25263 it->pixel_width += eabs (face->box_line_width);
25266 take_vertical_position_into_account (it);
25268 /* Automatically crop wide image glyphs at right edge so we can
25269 draw the cursor on same display row. */
25270 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
25271 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
25273 it->pixel_width -= crop;
25274 slice.width -= crop;
25277 if (it->glyph_row)
25279 struct glyph *glyph;
25280 enum glyph_row_area area = it->area;
25282 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
25283 if (glyph < it->glyph_row->glyphs[area + 1])
25285 glyph->charpos = CHARPOS (it->position);
25286 glyph->object = it->object;
25287 glyph->pixel_width = it->pixel_width;
25288 glyph->ascent = glyph_ascent;
25289 glyph->descent = it->descent;
25290 glyph->voffset = it->voffset;
25291 glyph->type = IMAGE_GLYPH;
25292 glyph->avoid_cursor_p = it->avoid_cursor_p;
25293 glyph->multibyte_p = it->multibyte_p;
25294 if (it->glyph_row->reversed_p && area == TEXT_AREA)
25296 /* In R2L rows, the left and the right box edges need to be
25297 drawn in reverse direction. */
25298 glyph->right_box_line_p = it->start_of_box_run_p;
25299 glyph->left_box_line_p = it->end_of_box_run_p;
25301 else
25303 glyph->left_box_line_p = it->start_of_box_run_p;
25304 glyph->right_box_line_p = it->end_of_box_run_p;
25306 glyph->overlaps_vertically_p = 0;
25307 glyph->padding_p = 0;
25308 glyph->glyph_not_available_p = 0;
25309 glyph->face_id = it->face_id;
25310 glyph->u.img_id = img->id;
25311 glyph->slice.img = slice;
25312 glyph->font_type = FONT_TYPE_UNKNOWN;
25313 if (it->bidi_p)
25315 glyph->resolved_level = it->bidi_it.resolved_level;
25316 if ((it->bidi_it.type & 7) != it->bidi_it.type)
25317 emacs_abort ();
25318 glyph->bidi_type = it->bidi_it.type;
25320 ++it->glyph_row->used[area];
25322 else
25323 IT_EXPAND_MATRIX_WIDTH (it, area);
25328 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
25329 of the glyph, WIDTH and HEIGHT are the width and height of the
25330 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
25332 static void
25333 append_stretch_glyph (struct it *it, Lisp_Object object,
25334 int width, int height, int ascent)
25336 struct glyph *glyph;
25337 enum glyph_row_area area = it->area;
25339 eassert (ascent >= 0 && ascent <= height);
25341 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
25342 if (glyph < it->glyph_row->glyphs[area + 1])
25344 /* If the glyph row is reversed, we need to prepend the glyph
25345 rather than append it. */
25346 if (it->glyph_row->reversed_p && area == TEXT_AREA)
25348 struct glyph *g;
25350 /* Make room for the additional glyph. */
25351 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
25352 g[1] = *g;
25353 glyph = it->glyph_row->glyphs[area];
25355 /* Decrease the width of the first glyph of the row that
25356 begins before first_visible_x (e.g., due to hscroll).
25357 This is so the overall width of the row becomes smaller
25358 by the scroll amount, and the stretch glyph appended by
25359 extend_face_to_end_of_line will be wider, to shift the
25360 row glyphs to the right. (In L2R rows, the corresponding
25361 left-shift effect is accomplished by setting row->x to a
25362 negative value, which won't work with R2L rows.)
25364 This must leave us with a positive value of WIDTH, since
25365 otherwise the call to move_it_in_display_line_to at the
25366 beginning of display_line would have got past the entire
25367 first glyph, and then it->current_x would have been
25368 greater or equal to it->first_visible_x. */
25369 if (it->current_x < it->first_visible_x)
25370 width -= it->first_visible_x - it->current_x;
25371 eassert (width > 0);
25373 glyph->charpos = CHARPOS (it->position);
25374 glyph->object = object;
25375 glyph->pixel_width = width;
25376 glyph->ascent = ascent;
25377 glyph->descent = height - ascent;
25378 glyph->voffset = it->voffset;
25379 glyph->type = STRETCH_GLYPH;
25380 glyph->avoid_cursor_p = it->avoid_cursor_p;
25381 glyph->multibyte_p = it->multibyte_p;
25382 if (it->glyph_row->reversed_p && area == TEXT_AREA)
25384 /* In R2L rows, the left and the right box edges need to be
25385 drawn in reverse direction. */
25386 glyph->right_box_line_p = it->start_of_box_run_p;
25387 glyph->left_box_line_p = it->end_of_box_run_p;
25389 else
25391 glyph->left_box_line_p = it->start_of_box_run_p;
25392 glyph->right_box_line_p = it->end_of_box_run_p;
25394 glyph->overlaps_vertically_p = 0;
25395 glyph->padding_p = 0;
25396 glyph->glyph_not_available_p = 0;
25397 glyph->face_id = it->face_id;
25398 glyph->u.stretch.ascent = ascent;
25399 glyph->u.stretch.height = height;
25400 glyph->slice.img = null_glyph_slice;
25401 glyph->font_type = FONT_TYPE_UNKNOWN;
25402 if (it->bidi_p)
25404 glyph->resolved_level = it->bidi_it.resolved_level;
25405 if ((it->bidi_it.type & 7) != it->bidi_it.type)
25406 emacs_abort ();
25407 glyph->bidi_type = it->bidi_it.type;
25409 else
25411 glyph->resolved_level = 0;
25412 glyph->bidi_type = UNKNOWN_BT;
25414 ++it->glyph_row->used[area];
25416 else
25417 IT_EXPAND_MATRIX_WIDTH (it, area);
25420 #endif /* HAVE_WINDOW_SYSTEM */
25422 /* Produce a stretch glyph for iterator IT. IT->object is the value
25423 of the glyph property displayed. The value must be a list
25424 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
25425 being recognized:
25427 1. `:width WIDTH' specifies that the space should be WIDTH *
25428 canonical char width wide. WIDTH may be an integer or floating
25429 point number.
25431 2. `:relative-width FACTOR' specifies that the width of the stretch
25432 should be computed from the width of the first character having the
25433 `glyph' property, and should be FACTOR times that width.
25435 3. `:align-to HPOS' specifies that the space should be wide enough
25436 to reach HPOS, a value in canonical character units.
25438 Exactly one of the above pairs must be present.
25440 4. `:height HEIGHT' specifies that the height of the stretch produced
25441 should be HEIGHT, measured in canonical character units.
25443 5. `:relative-height FACTOR' specifies that the height of the
25444 stretch should be FACTOR times the height of the characters having
25445 the glyph property.
25447 Either none or exactly one of 4 or 5 must be present.
25449 6. `:ascent ASCENT' specifies that ASCENT percent of the height
25450 of the stretch should be used for the ascent of the stretch.
25451 ASCENT must be in the range 0 <= ASCENT <= 100. */
25453 void
25454 produce_stretch_glyph (struct it *it)
25456 /* (space :width WIDTH :height HEIGHT ...) */
25457 Lisp_Object prop, plist;
25458 int width = 0, height = 0, align_to = -1;
25459 int zero_width_ok_p = 0;
25460 double tem;
25461 struct font *font = NULL;
25463 #ifdef HAVE_WINDOW_SYSTEM
25464 int ascent = 0;
25465 int zero_height_ok_p = 0;
25467 if (FRAME_WINDOW_P (it->f))
25469 struct face *face = FACE_FROM_ID (it->f, it->face_id);
25470 font = face->font ? face->font : FRAME_FONT (it->f);
25471 prepare_face_for_display (it->f, face);
25473 #endif
25475 /* List should start with `space'. */
25476 eassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
25477 plist = XCDR (it->object);
25479 /* Compute the width of the stretch. */
25480 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
25481 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
25483 /* Absolute width `:width WIDTH' specified and valid. */
25484 zero_width_ok_p = 1;
25485 width = (int)tem;
25487 #ifdef HAVE_WINDOW_SYSTEM
25488 else if (FRAME_WINDOW_P (it->f)
25489 && (prop = Fplist_get (plist, QCrelative_width), NUMVAL (prop) > 0))
25491 /* Relative width `:relative-width FACTOR' specified and valid.
25492 Compute the width of the characters having the `glyph'
25493 property. */
25494 struct it it2;
25495 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
25497 it2 = *it;
25498 if (it->multibyte_p)
25499 it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
25500 else
25502 it2.c = it2.char_to_display = *p, it2.len = 1;
25503 if (! ASCII_CHAR_P (it2.c))
25504 it2.char_to_display = BYTE8_TO_CHAR (it2.c);
25507 it2.glyph_row = NULL;
25508 it2.what = IT_CHARACTER;
25509 x_produce_glyphs (&it2);
25510 width = NUMVAL (prop) * it2.pixel_width;
25512 #endif /* HAVE_WINDOW_SYSTEM */
25513 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
25514 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
25516 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
25517 align_to = (align_to < 0
25519 : align_to - window_box_left_offset (it->w, TEXT_AREA));
25520 else if (align_to < 0)
25521 align_to = window_box_left_offset (it->w, TEXT_AREA);
25522 width = max (0, (int)tem + align_to - it->current_x);
25523 zero_width_ok_p = 1;
25525 else
25526 /* Nothing specified -> width defaults to canonical char width. */
25527 width = FRAME_COLUMN_WIDTH (it->f);
25529 if (width <= 0 && (width < 0 || !zero_width_ok_p))
25530 width = 1;
25532 #ifdef HAVE_WINDOW_SYSTEM
25533 /* Compute height. */
25534 if (FRAME_WINDOW_P (it->f))
25536 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
25537 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
25539 height = (int)tem;
25540 zero_height_ok_p = 1;
25542 else if (prop = Fplist_get (plist, QCrelative_height),
25543 NUMVAL (prop) > 0)
25544 height = FONT_HEIGHT (font) * NUMVAL (prop);
25545 else
25546 height = FONT_HEIGHT (font);
25548 if (height <= 0 && (height < 0 || !zero_height_ok_p))
25549 height = 1;
25551 /* Compute percentage of height used for ascent. If
25552 `:ascent ASCENT' is present and valid, use that. Otherwise,
25553 derive the ascent from the font in use. */
25554 if (prop = Fplist_get (plist, QCascent),
25555 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
25556 ascent = height * NUMVAL (prop) / 100.0;
25557 else if (!NILP (prop)
25558 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
25559 ascent = min (max (0, (int)tem), height);
25560 else
25561 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
25563 else
25564 #endif /* HAVE_WINDOW_SYSTEM */
25565 height = 1;
25567 if (width > 0 && it->line_wrap != TRUNCATE
25568 && it->current_x + width > it->last_visible_x)
25570 width = it->last_visible_x - it->current_x;
25571 #ifdef HAVE_WINDOW_SYSTEM
25572 /* Subtract one more pixel from the stretch width, but only on
25573 GUI frames, since on a TTY each glyph is one "pixel" wide. */
25574 width -= FRAME_WINDOW_P (it->f);
25575 #endif
25578 if (width > 0 && height > 0 && it->glyph_row)
25580 Lisp_Object o_object = it->object;
25581 Lisp_Object object = it->stack[it->sp - 1].string;
25582 int n = width;
25584 if (!STRINGP (object))
25585 object = it->w->contents;
25586 #ifdef HAVE_WINDOW_SYSTEM
25587 if (FRAME_WINDOW_P (it->f))
25588 append_stretch_glyph (it, object, width, height, ascent);
25589 else
25590 #endif
25592 it->object = object;
25593 it->char_to_display = ' ';
25594 it->pixel_width = it->len = 1;
25595 while (n--)
25596 tty_append_glyph (it);
25597 it->object = o_object;
25601 it->pixel_width = width;
25602 #ifdef HAVE_WINDOW_SYSTEM
25603 if (FRAME_WINDOW_P (it->f))
25605 it->ascent = it->phys_ascent = ascent;
25606 it->descent = it->phys_descent = height - it->ascent;
25607 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
25608 take_vertical_position_into_account (it);
25610 else
25611 #endif
25612 it->nglyphs = width;
25615 /* Get information about special display element WHAT in an
25616 environment described by IT. WHAT is one of IT_TRUNCATION or
25617 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
25618 non-null glyph_row member. This function ensures that fields like
25619 face_id, c, len of IT are left untouched. */
25621 static void
25622 produce_special_glyphs (struct it *it, enum display_element_type what)
25624 struct it temp_it;
25625 Lisp_Object gc;
25626 GLYPH glyph;
25628 temp_it = *it;
25629 temp_it.object = make_number (0);
25630 memset (&temp_it.current, 0, sizeof temp_it.current);
25632 if (what == IT_CONTINUATION)
25634 /* Continuation glyph. For R2L lines, we mirror it by hand. */
25635 if (it->bidi_it.paragraph_dir == R2L)
25636 SET_GLYPH_FROM_CHAR (glyph, '/');
25637 else
25638 SET_GLYPH_FROM_CHAR (glyph, '\\');
25639 if (it->dp
25640 && (gc = DISP_CONTINUE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
25642 /* FIXME: Should we mirror GC for R2L lines? */
25643 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
25644 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
25647 else if (what == IT_TRUNCATION)
25649 /* Truncation glyph. */
25650 SET_GLYPH_FROM_CHAR (glyph, '$');
25651 if (it->dp
25652 && (gc = DISP_TRUNC_GLYPH (it->dp), GLYPH_CODE_P (gc)))
25654 /* FIXME: Should we mirror GC for R2L lines? */
25655 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
25656 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
25659 else
25660 emacs_abort ();
25662 #ifdef HAVE_WINDOW_SYSTEM
25663 /* On a GUI frame, when the right fringe (left fringe for R2L rows)
25664 is turned off, we precede the truncation/continuation glyphs by a
25665 stretch glyph whose width is computed such that these special
25666 glyphs are aligned at the window margin, even when very different
25667 fonts are used in different glyph rows. */
25668 if (FRAME_WINDOW_P (temp_it.f)
25669 /* init_iterator calls this with it->glyph_row == NULL, and it
25670 wants only the pixel width of the truncation/continuation
25671 glyphs. */
25672 && temp_it.glyph_row
25673 /* insert_left_trunc_glyphs calls us at the beginning of the
25674 row, and it has its own calculation of the stretch glyph
25675 width. */
25676 && temp_it.glyph_row->used[TEXT_AREA] > 0
25677 && (temp_it.glyph_row->reversed_p
25678 ? WINDOW_LEFT_FRINGE_WIDTH (temp_it.w)
25679 : WINDOW_RIGHT_FRINGE_WIDTH (temp_it.w)) == 0)
25681 int stretch_width = temp_it.last_visible_x - temp_it.current_x;
25683 if (stretch_width > 0)
25685 struct face *face = FACE_FROM_ID (temp_it.f, temp_it.face_id);
25686 struct font *font =
25687 face->font ? face->font : FRAME_FONT (temp_it.f);
25688 int stretch_ascent =
25689 (((temp_it.ascent + temp_it.descent)
25690 * FONT_BASE (font)) / FONT_HEIGHT (font));
25692 append_stretch_glyph (&temp_it, make_number (0), stretch_width,
25693 temp_it.ascent + temp_it.descent,
25694 stretch_ascent);
25697 #endif
25699 temp_it.dp = NULL;
25700 temp_it.what = IT_CHARACTER;
25701 temp_it.len = 1;
25702 temp_it.c = temp_it.char_to_display = GLYPH_CHAR (glyph);
25703 temp_it.face_id = GLYPH_FACE (glyph);
25704 temp_it.len = CHAR_BYTES (temp_it.c);
25706 PRODUCE_GLYPHS (&temp_it);
25707 it->pixel_width = temp_it.pixel_width;
25708 it->nglyphs = temp_it.pixel_width;
25711 #ifdef HAVE_WINDOW_SYSTEM
25713 /* Calculate line-height and line-spacing properties.
25714 An integer value specifies explicit pixel value.
25715 A float value specifies relative value to current face height.
25716 A cons (float . face-name) specifies relative value to
25717 height of specified face font.
25719 Returns height in pixels, or nil. */
25722 static Lisp_Object
25723 calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
25724 int boff, int override)
25726 Lisp_Object face_name = Qnil;
25727 int ascent, descent, height;
25729 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
25730 return val;
25732 if (CONSP (val))
25734 face_name = XCAR (val);
25735 val = XCDR (val);
25736 if (!NUMBERP (val))
25737 val = make_number (1);
25738 if (NILP (face_name))
25740 height = it->ascent + it->descent;
25741 goto scale;
25745 if (NILP (face_name))
25747 font = FRAME_FONT (it->f);
25748 boff = FRAME_BASELINE_OFFSET (it->f);
25750 else if (EQ (face_name, Qt))
25752 override = 0;
25754 else
25756 int face_id;
25757 struct face *face;
25759 face_id = lookup_named_face (it->f, face_name, 0);
25760 if (face_id < 0)
25761 return make_number (-1);
25763 face = FACE_FROM_ID (it->f, face_id);
25764 font = face->font;
25765 if (font == NULL)
25766 return make_number (-1);
25767 boff = font->baseline_offset;
25768 if (font->vertical_centering)
25769 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
25772 ascent = FONT_BASE (font) + boff;
25773 descent = FONT_DESCENT (font) - boff;
25775 if (override)
25777 it->override_ascent = ascent;
25778 it->override_descent = descent;
25779 it->override_boff = boff;
25782 height = ascent + descent;
25784 scale:
25785 if (FLOATP (val))
25786 height = (int)(XFLOAT_DATA (val) * height);
25787 else if (INTEGERP (val))
25788 height *= XINT (val);
25790 return make_number (height);
25794 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
25795 is a face ID to be used for the glyph. FOR_NO_FONT is nonzero if
25796 and only if this is for a character for which no font was found.
25798 If the display method (it->glyphless_method) is
25799 GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
25800 length of the acronym or the hexadecimal string, UPPER_XOFF and
25801 UPPER_YOFF are pixel offsets for the upper part of the string,
25802 LOWER_XOFF and LOWER_YOFF are for the lower part.
25804 For the other display methods, LEN through LOWER_YOFF are zero. */
25806 static void
25807 append_glyphless_glyph (struct it *it, int face_id, int for_no_font, int len,
25808 short upper_xoff, short upper_yoff,
25809 short lower_xoff, short lower_yoff)
25811 struct glyph *glyph;
25812 enum glyph_row_area area = it->area;
25814 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
25815 if (glyph < it->glyph_row->glyphs[area + 1])
25817 /* If the glyph row is reversed, we need to prepend the glyph
25818 rather than append it. */
25819 if (it->glyph_row->reversed_p && area == TEXT_AREA)
25821 struct glyph *g;
25823 /* Make room for the additional glyph. */
25824 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
25825 g[1] = *g;
25826 glyph = it->glyph_row->glyphs[area];
25828 glyph->charpos = CHARPOS (it->position);
25829 glyph->object = it->object;
25830 glyph->pixel_width = it->pixel_width;
25831 glyph->ascent = it->ascent;
25832 glyph->descent = it->descent;
25833 glyph->voffset = it->voffset;
25834 glyph->type = GLYPHLESS_GLYPH;
25835 glyph->u.glyphless.method = it->glyphless_method;
25836 glyph->u.glyphless.for_no_font = for_no_font;
25837 glyph->u.glyphless.len = len;
25838 glyph->u.glyphless.ch = it->c;
25839 glyph->slice.glyphless.upper_xoff = upper_xoff;
25840 glyph->slice.glyphless.upper_yoff = upper_yoff;
25841 glyph->slice.glyphless.lower_xoff = lower_xoff;
25842 glyph->slice.glyphless.lower_yoff = lower_yoff;
25843 glyph->avoid_cursor_p = it->avoid_cursor_p;
25844 glyph->multibyte_p = it->multibyte_p;
25845 if (it->glyph_row->reversed_p && area == TEXT_AREA)
25847 /* In R2L rows, the left and the right box edges need to be
25848 drawn in reverse direction. */
25849 glyph->right_box_line_p = it->start_of_box_run_p;
25850 glyph->left_box_line_p = it->end_of_box_run_p;
25852 else
25854 glyph->left_box_line_p = it->start_of_box_run_p;
25855 glyph->right_box_line_p = it->end_of_box_run_p;
25857 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
25858 || it->phys_descent > it->descent);
25859 glyph->padding_p = 0;
25860 glyph->glyph_not_available_p = 0;
25861 glyph->face_id = face_id;
25862 glyph->font_type = FONT_TYPE_UNKNOWN;
25863 if (it->bidi_p)
25865 glyph->resolved_level = it->bidi_it.resolved_level;
25866 if ((it->bidi_it.type & 7) != it->bidi_it.type)
25867 emacs_abort ();
25868 glyph->bidi_type = it->bidi_it.type;
25870 ++it->glyph_row->used[area];
25872 else
25873 IT_EXPAND_MATRIX_WIDTH (it, area);
25877 /* Produce a glyph for a glyphless character for iterator IT.
25878 IT->glyphless_method specifies which method to use for displaying
25879 the character. See the description of enum
25880 glyphless_display_method in dispextern.h for the detail.
25882 FOR_NO_FONT is nonzero if and only if this is for a character for
25883 which no font was found. ACRONYM, if non-nil, is an acronym string
25884 for the character. */
25886 static void
25887 produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
25889 int face_id;
25890 struct face *face;
25891 struct font *font;
25892 int base_width, base_height, width, height;
25893 short upper_xoff, upper_yoff, lower_xoff, lower_yoff;
25894 int len;
25896 /* Get the metrics of the base font. We always refer to the current
25897 ASCII face. */
25898 face = FACE_FROM_ID (it->f, it->face_id)->ascii_face;
25899 font = face->font ? face->font : FRAME_FONT (it->f);
25900 it->ascent = FONT_BASE (font) + font->baseline_offset;
25901 it->descent = FONT_DESCENT (font) - font->baseline_offset;
25902 base_height = it->ascent + it->descent;
25903 base_width = font->average_width;
25905 face_id = merge_glyphless_glyph_face (it);
25907 if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
25909 it->pixel_width = THIN_SPACE_WIDTH;
25910 len = 0;
25911 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
25913 else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX)
25915 width = CHAR_WIDTH (it->c);
25916 if (width == 0)
25917 width = 1;
25918 else if (width > 4)
25919 width = 4;
25920 it->pixel_width = base_width * width;
25921 len = 0;
25922 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
25924 else
25926 char buf[7];
25927 const char *str;
25928 unsigned int code[6];
25929 int upper_len;
25930 int ascent, descent;
25931 struct font_metrics metrics_upper, metrics_lower;
25933 face = FACE_FROM_ID (it->f, face_id);
25934 font = face->font ? face->font : FRAME_FONT (it->f);
25935 prepare_face_for_display (it->f, face);
25937 if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM)
25939 if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
25940 acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
25941 if (CONSP (acronym))
25942 acronym = XCAR (acronym);
25943 str = STRINGP (acronym) ? SSDATA (acronym) : "";
25945 else
25947 eassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
25948 sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c);
25949 str = buf;
25951 for (len = 0; str[len] && ASCII_CHAR_P (str[len]) && len < 6; len++)
25952 code[len] = font->driver->encode_char (font, str[len]);
25953 upper_len = (len + 1) / 2;
25954 font->driver->text_extents (font, code, upper_len,
25955 &metrics_upper);
25956 font->driver->text_extents (font, code + upper_len, len - upper_len,
25957 &metrics_lower);
25961 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
25962 width = max (metrics_upper.width, metrics_lower.width) + 4;
25963 upper_xoff = upper_yoff = 2; /* the typical case */
25964 if (base_width >= width)
25966 /* Align the upper to the left, the lower to the right. */
25967 it->pixel_width = base_width;
25968 lower_xoff = base_width - 2 - metrics_lower.width;
25970 else
25972 /* Center the shorter one. */
25973 it->pixel_width = width;
25974 if (metrics_upper.width >= metrics_lower.width)
25975 lower_xoff = (width - metrics_lower.width) / 2;
25976 else
25978 /* FIXME: This code doesn't look right. It formerly was
25979 missing the "lower_xoff = 0;", which couldn't have
25980 been right since it left lower_xoff uninitialized. */
25981 lower_xoff = 0;
25982 upper_xoff = (width - metrics_upper.width) / 2;
25986 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
25987 top, bottom, and between upper and lower strings. */
25988 height = (metrics_upper.ascent + metrics_upper.descent
25989 + metrics_lower.ascent + metrics_lower.descent) + 5;
25990 /* Center vertically.
25991 H:base_height, D:base_descent
25992 h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent
25994 ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up
25995 descent = D - H/2 + h/2;
25996 lower_yoff = descent - 2 - ld;
25997 upper_yoff = lower_yoff - la - 1 - ud; */
25998 ascent = - (it->descent - (base_height + height + 1) / 2);
25999 descent = it->descent - (base_height - height) / 2;
26000 lower_yoff = descent - 2 - metrics_lower.descent;
26001 upper_yoff = (lower_yoff - metrics_lower.ascent - 1
26002 - metrics_upper.descent);
26003 /* Don't make the height shorter than the base height. */
26004 if (height > base_height)
26006 it->ascent = ascent;
26007 it->descent = descent;
26011 it->phys_ascent = it->ascent;
26012 it->phys_descent = it->descent;
26013 if (it->glyph_row)
26014 append_glyphless_glyph (it, face_id, for_no_font, len,
26015 upper_xoff, upper_yoff,
26016 lower_xoff, lower_yoff);
26017 it->nglyphs = 1;
26018 take_vertical_position_into_account (it);
26022 /* RIF:
26023 Produce glyphs/get display metrics for the display element IT is
26024 loaded with. See the description of struct it in dispextern.h
26025 for an overview of struct it. */
26027 void
26028 x_produce_glyphs (struct it *it)
26030 int extra_line_spacing = it->extra_line_spacing;
26032 it->glyph_not_available_p = 0;
26034 if (it->what == IT_CHARACTER)
26036 XChar2b char2b;
26037 struct face *face = FACE_FROM_ID (it->f, it->face_id);
26038 struct font *font = face->font;
26039 struct font_metrics *pcm = NULL;
26040 int boff; /* Baseline offset. */
26042 if (font == NULL)
26044 /* When no suitable font is found, display this character by
26045 the method specified in the first extra slot of
26046 Vglyphless_char_display. */
26047 Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
26049 eassert (it->what == IT_GLYPHLESS);
26050 produce_glyphless_glyph (it, 1, STRINGP (acronym) ? acronym : Qnil);
26051 goto done;
26054 boff = font->baseline_offset;
26055 if (font->vertical_centering)
26056 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
26058 if (it->char_to_display != '\n' && it->char_to_display != '\t')
26060 int stretched_p;
26062 it->nglyphs = 1;
26064 if (it->override_ascent >= 0)
26066 it->ascent = it->override_ascent;
26067 it->descent = it->override_descent;
26068 boff = it->override_boff;
26070 else
26072 it->ascent = FONT_BASE (font) + boff;
26073 it->descent = FONT_DESCENT (font) - boff;
26076 if (get_char_glyph_code (it->char_to_display, font, &char2b))
26078 pcm = get_per_char_metric (font, &char2b);
26079 if (pcm->width == 0
26080 && pcm->rbearing == 0 && pcm->lbearing == 0)
26081 pcm = NULL;
26084 if (pcm)
26086 it->phys_ascent = pcm->ascent + boff;
26087 it->phys_descent = pcm->descent - boff;
26088 it->pixel_width = pcm->width;
26090 else
26092 it->glyph_not_available_p = 1;
26093 it->phys_ascent = it->ascent;
26094 it->phys_descent = it->descent;
26095 it->pixel_width = font->space_width;
26098 if (it->constrain_row_ascent_descent_p)
26100 if (it->descent > it->max_descent)
26102 it->ascent += it->descent - it->max_descent;
26103 it->descent = it->max_descent;
26105 if (it->ascent > it->max_ascent)
26107 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
26108 it->ascent = it->max_ascent;
26110 it->phys_ascent = min (it->phys_ascent, it->ascent);
26111 it->phys_descent = min (it->phys_descent, it->descent);
26112 extra_line_spacing = 0;
26115 /* If this is a space inside a region of text with
26116 `space-width' property, change its width. */
26117 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
26118 if (stretched_p)
26119 it->pixel_width *= XFLOATINT (it->space_width);
26121 /* If face has a box, add the box thickness to the character
26122 height. If character has a box line to the left and/or
26123 right, add the box line width to the character's width. */
26124 if (face->box != FACE_NO_BOX)
26126 int thick = face->box_line_width;
26128 if (thick > 0)
26130 it->ascent += thick;
26131 it->descent += thick;
26133 else
26134 thick = -thick;
26136 if (it->start_of_box_run_p)
26137 it->pixel_width += thick;
26138 if (it->end_of_box_run_p)
26139 it->pixel_width += thick;
26142 /* If face has an overline, add the height of the overline
26143 (1 pixel) and a 1 pixel margin to the character height. */
26144 if (face->overline_p)
26145 it->ascent += overline_margin;
26147 if (it->constrain_row_ascent_descent_p)
26149 if (it->ascent > it->max_ascent)
26150 it->ascent = it->max_ascent;
26151 if (it->descent > it->max_descent)
26152 it->descent = it->max_descent;
26155 take_vertical_position_into_account (it);
26157 /* If we have to actually produce glyphs, do it. */
26158 if (it->glyph_row)
26160 if (stretched_p)
26162 /* Translate a space with a `space-width' property
26163 into a stretch glyph. */
26164 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
26165 / FONT_HEIGHT (font));
26166 append_stretch_glyph (it, it->object, it->pixel_width,
26167 it->ascent + it->descent, ascent);
26169 else
26170 append_glyph (it);
26172 /* If characters with lbearing or rbearing are displayed
26173 in this line, record that fact in a flag of the
26174 glyph row. This is used to optimize X output code. */
26175 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
26176 it->glyph_row->contains_overlapping_glyphs_p = 1;
26178 if (! stretched_p && it->pixel_width == 0)
26179 /* We assure that all visible glyphs have at least 1-pixel
26180 width. */
26181 it->pixel_width = 1;
26183 else if (it->char_to_display == '\n')
26185 /* A newline has no width, but we need the height of the
26186 line. But if previous part of the line sets a height,
26187 don't increase that height. */
26189 Lisp_Object height;
26190 Lisp_Object total_height = Qnil;
26192 it->override_ascent = -1;
26193 it->pixel_width = 0;
26194 it->nglyphs = 0;
26196 height = get_it_property (it, Qline_height);
26197 /* Split (line-height total-height) list. */
26198 if (CONSP (height)
26199 && CONSP (XCDR (height))
26200 && NILP (XCDR (XCDR (height))))
26202 total_height = XCAR (XCDR (height));
26203 height = XCAR (height);
26205 height = calc_line_height_property (it, height, font, boff, 1);
26207 if (it->override_ascent >= 0)
26209 it->ascent = it->override_ascent;
26210 it->descent = it->override_descent;
26211 boff = it->override_boff;
26213 else
26215 it->ascent = FONT_BASE (font) + boff;
26216 it->descent = FONT_DESCENT (font) - boff;
26219 if (EQ (height, Qt))
26221 if (it->descent > it->max_descent)
26223 it->ascent += it->descent - it->max_descent;
26224 it->descent = it->max_descent;
26226 if (it->ascent > it->max_ascent)
26228 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
26229 it->ascent = it->max_ascent;
26231 it->phys_ascent = min (it->phys_ascent, it->ascent);
26232 it->phys_descent = min (it->phys_descent, it->descent);
26233 it->constrain_row_ascent_descent_p = 1;
26234 extra_line_spacing = 0;
26236 else
26238 Lisp_Object spacing;
26240 it->phys_ascent = it->ascent;
26241 it->phys_descent = it->descent;
26243 if ((it->max_ascent > 0 || it->max_descent > 0)
26244 && face->box != FACE_NO_BOX
26245 && face->box_line_width > 0)
26247 it->ascent += face->box_line_width;
26248 it->descent += face->box_line_width;
26250 if (!NILP (height)
26251 && XINT (height) > it->ascent + it->descent)
26252 it->ascent = XINT (height) - it->descent;
26254 if (!NILP (total_height))
26255 spacing = calc_line_height_property (it, total_height, font, boff, 0);
26256 else
26258 spacing = get_it_property (it, Qline_spacing);
26259 spacing = calc_line_height_property (it, spacing, font, boff, 0);
26261 if (INTEGERP (spacing))
26263 extra_line_spacing = XINT (spacing);
26264 if (!NILP (total_height))
26265 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
26269 else /* i.e. (it->char_to_display == '\t') */
26271 if (font->space_width > 0)
26273 int tab_width = it->tab_width * font->space_width;
26274 int x = it->current_x + it->continuation_lines_width;
26275 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
26277 /* If the distance from the current position to the next tab
26278 stop is less than a space character width, use the
26279 tab stop after that. */
26280 if (next_tab_x - x < font->space_width)
26281 next_tab_x += tab_width;
26283 it->pixel_width = next_tab_x - x;
26284 it->nglyphs = 1;
26285 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
26286 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
26288 if (it->glyph_row)
26290 append_stretch_glyph (it, it->object, it->pixel_width,
26291 it->ascent + it->descent, it->ascent);
26294 else
26296 it->pixel_width = 0;
26297 it->nglyphs = 1;
26301 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
26303 /* A static composition.
26305 Note: A composition is represented as one glyph in the
26306 glyph matrix. There are no padding glyphs.
26308 Important note: pixel_width, ascent, and descent are the
26309 values of what is drawn by draw_glyphs (i.e. the values of
26310 the overall glyphs composed). */
26311 struct face *face = FACE_FROM_ID (it->f, it->face_id);
26312 int boff; /* baseline offset */
26313 struct composition *cmp = composition_table[it->cmp_it.id];
26314 int glyph_len = cmp->glyph_len;
26315 struct font *font = face->font;
26317 it->nglyphs = 1;
26319 /* If we have not yet calculated pixel size data of glyphs of
26320 the composition for the current face font, calculate them
26321 now. Theoretically, we have to check all fonts for the
26322 glyphs, but that requires much time and memory space. So,
26323 here we check only the font of the first glyph. This may
26324 lead to incorrect display, but it's very rare, and C-l
26325 (recenter-top-bottom) can correct the display anyway. */
26326 if (! cmp->font || cmp->font != font)
26328 /* Ascent and descent of the font of the first character
26329 of this composition (adjusted by baseline offset).
26330 Ascent and descent of overall glyphs should not be less
26331 than these, respectively. */
26332 int font_ascent, font_descent, font_height;
26333 /* Bounding box of the overall glyphs. */
26334 int leftmost, rightmost, lowest, highest;
26335 int lbearing, rbearing;
26336 int i, width, ascent, descent;
26337 int left_padded = 0, right_padded = 0;
26338 int c IF_LINT (= 0); /* cmp->glyph_len can't be zero; see Bug#8512 */
26339 XChar2b char2b;
26340 struct font_metrics *pcm;
26341 int font_not_found_p;
26342 ptrdiff_t pos;
26344 for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
26345 if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
26346 break;
26347 if (glyph_len < cmp->glyph_len)
26348 right_padded = 1;
26349 for (i = 0; i < glyph_len; i++)
26351 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
26352 break;
26353 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
26355 if (i > 0)
26356 left_padded = 1;
26358 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
26359 : IT_CHARPOS (*it));
26360 /* If no suitable font is found, use the default font. */
26361 font_not_found_p = font == NULL;
26362 if (font_not_found_p)
26364 face = face->ascii_face;
26365 font = face->font;
26367 boff = font->baseline_offset;
26368 if (font->vertical_centering)
26369 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
26370 font_ascent = FONT_BASE (font) + boff;
26371 font_descent = FONT_DESCENT (font) - boff;
26372 font_height = FONT_HEIGHT (font);
26374 cmp->font = font;
26376 pcm = NULL;
26377 if (! font_not_found_p)
26379 get_char_face_and_encoding (it->f, c, it->face_id,
26380 &char2b, 0);
26381 pcm = get_per_char_metric (font, &char2b);
26384 /* Initialize the bounding box. */
26385 if (pcm)
26387 width = cmp->glyph_len > 0 ? pcm->width : 0;
26388 ascent = pcm->ascent;
26389 descent = pcm->descent;
26390 lbearing = pcm->lbearing;
26391 rbearing = pcm->rbearing;
26393 else
26395 width = cmp->glyph_len > 0 ? font->space_width : 0;
26396 ascent = FONT_BASE (font);
26397 descent = FONT_DESCENT (font);
26398 lbearing = 0;
26399 rbearing = width;
26402 rightmost = width;
26403 leftmost = 0;
26404 lowest = - descent + boff;
26405 highest = ascent + boff;
26407 if (! font_not_found_p
26408 && font->default_ascent
26409 && CHAR_TABLE_P (Vuse_default_ascent)
26410 && !NILP (Faref (Vuse_default_ascent,
26411 make_number (it->char_to_display))))
26412 highest = font->default_ascent + boff;
26414 /* Draw the first glyph at the normal position. It may be
26415 shifted to right later if some other glyphs are drawn
26416 at the left. */
26417 cmp->offsets[i * 2] = 0;
26418 cmp->offsets[i * 2 + 1] = boff;
26419 cmp->lbearing = lbearing;
26420 cmp->rbearing = rbearing;
26422 /* Set cmp->offsets for the remaining glyphs. */
26423 for (i++; i < glyph_len; i++)
26425 int left, right, btm, top;
26426 int ch = COMPOSITION_GLYPH (cmp, i);
26427 int face_id;
26428 struct face *this_face;
26430 if (ch == '\t')
26431 ch = ' ';
26432 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
26433 this_face = FACE_FROM_ID (it->f, face_id);
26434 font = this_face->font;
26436 if (font == NULL)
26437 pcm = NULL;
26438 else
26440 get_char_face_and_encoding (it->f, ch, face_id,
26441 &char2b, 0);
26442 pcm = get_per_char_metric (font, &char2b);
26444 if (! pcm)
26445 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
26446 else
26448 width = pcm->width;
26449 ascent = pcm->ascent;
26450 descent = pcm->descent;
26451 lbearing = pcm->lbearing;
26452 rbearing = pcm->rbearing;
26453 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
26455 /* Relative composition with or without
26456 alternate chars. */
26457 left = (leftmost + rightmost - width) / 2;
26458 btm = - descent + boff;
26459 if (font->relative_compose
26460 && (! CHAR_TABLE_P (Vignore_relative_composition)
26461 || NILP (Faref (Vignore_relative_composition,
26462 make_number (ch)))))
26465 if (- descent >= font->relative_compose)
26466 /* One extra pixel between two glyphs. */
26467 btm = highest + 1;
26468 else if (ascent <= 0)
26469 /* One extra pixel between two glyphs. */
26470 btm = lowest - 1 - ascent - descent;
26473 else
26475 /* A composition rule is specified by an integer
26476 value that encodes global and new reference
26477 points (GREF and NREF). GREF and NREF are
26478 specified by numbers as below:
26480 0---1---2 -- ascent
26484 9--10--11 -- center
26486 ---3---4---5--- baseline
26488 6---7---8 -- descent
26490 int rule = COMPOSITION_RULE (cmp, i);
26491 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
26493 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
26494 grefx = gref % 3, nrefx = nref % 3;
26495 grefy = gref / 3, nrefy = nref / 3;
26496 if (xoff)
26497 xoff = font_height * (xoff - 128) / 256;
26498 if (yoff)
26499 yoff = font_height * (yoff - 128) / 256;
26501 left = (leftmost
26502 + grefx * (rightmost - leftmost) / 2
26503 - nrefx * width / 2
26504 + xoff);
26506 btm = ((grefy == 0 ? highest
26507 : grefy == 1 ? 0
26508 : grefy == 2 ? lowest
26509 : (highest + lowest) / 2)
26510 - (nrefy == 0 ? ascent + descent
26511 : nrefy == 1 ? descent - boff
26512 : nrefy == 2 ? 0
26513 : (ascent + descent) / 2)
26514 + yoff);
26517 cmp->offsets[i * 2] = left;
26518 cmp->offsets[i * 2 + 1] = btm + descent;
26520 /* Update the bounding box of the overall glyphs. */
26521 if (width > 0)
26523 right = left + width;
26524 if (left < leftmost)
26525 leftmost = left;
26526 if (right > rightmost)
26527 rightmost = right;
26529 top = btm + descent + ascent;
26530 if (top > highest)
26531 highest = top;
26532 if (btm < lowest)
26533 lowest = btm;
26535 if (cmp->lbearing > left + lbearing)
26536 cmp->lbearing = left + lbearing;
26537 if (cmp->rbearing < left + rbearing)
26538 cmp->rbearing = left + rbearing;
26542 /* If there are glyphs whose x-offsets are negative,
26543 shift all glyphs to the right and make all x-offsets
26544 non-negative. */
26545 if (leftmost < 0)
26547 for (i = 0; i < cmp->glyph_len; i++)
26548 cmp->offsets[i * 2] -= leftmost;
26549 rightmost -= leftmost;
26550 cmp->lbearing -= leftmost;
26551 cmp->rbearing -= leftmost;
26554 if (left_padded && cmp->lbearing < 0)
26556 for (i = 0; i < cmp->glyph_len; i++)
26557 cmp->offsets[i * 2] -= cmp->lbearing;
26558 rightmost -= cmp->lbearing;
26559 cmp->rbearing -= cmp->lbearing;
26560 cmp->lbearing = 0;
26562 if (right_padded && rightmost < cmp->rbearing)
26564 rightmost = cmp->rbearing;
26567 cmp->pixel_width = rightmost;
26568 cmp->ascent = highest;
26569 cmp->descent = - lowest;
26570 if (cmp->ascent < font_ascent)
26571 cmp->ascent = font_ascent;
26572 if (cmp->descent < font_descent)
26573 cmp->descent = font_descent;
26576 if (it->glyph_row
26577 && (cmp->lbearing < 0
26578 || cmp->rbearing > cmp->pixel_width))
26579 it->glyph_row->contains_overlapping_glyphs_p = 1;
26581 it->pixel_width = cmp->pixel_width;
26582 it->ascent = it->phys_ascent = cmp->ascent;
26583 it->descent = it->phys_descent = cmp->descent;
26584 if (face->box != FACE_NO_BOX)
26586 int thick = face->box_line_width;
26588 if (thick > 0)
26590 it->ascent += thick;
26591 it->descent += thick;
26593 else
26594 thick = - thick;
26596 if (it->start_of_box_run_p)
26597 it->pixel_width += thick;
26598 if (it->end_of_box_run_p)
26599 it->pixel_width += thick;
26602 /* If face has an overline, add the height of the overline
26603 (1 pixel) and a 1 pixel margin to the character height. */
26604 if (face->overline_p)
26605 it->ascent += overline_margin;
26607 take_vertical_position_into_account (it);
26608 if (it->ascent < 0)
26609 it->ascent = 0;
26610 if (it->descent < 0)
26611 it->descent = 0;
26613 if (it->glyph_row && cmp->glyph_len > 0)
26614 append_composite_glyph (it);
26616 else if (it->what == IT_COMPOSITION)
26618 /* A dynamic (automatic) composition. */
26619 struct face *face = FACE_FROM_ID (it->f, it->face_id);
26620 Lisp_Object gstring;
26621 struct font_metrics metrics;
26623 it->nglyphs = 1;
26625 gstring = composition_gstring_from_id (it->cmp_it.id);
26626 it->pixel_width
26627 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
26628 &metrics);
26629 if (it->glyph_row
26630 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
26631 it->glyph_row->contains_overlapping_glyphs_p = 1;
26632 it->ascent = it->phys_ascent = metrics.ascent;
26633 it->descent = it->phys_descent = metrics.descent;
26634 if (face->box != FACE_NO_BOX)
26636 int thick = face->box_line_width;
26638 if (thick > 0)
26640 it->ascent += thick;
26641 it->descent += thick;
26643 else
26644 thick = - thick;
26646 if (it->start_of_box_run_p)
26647 it->pixel_width += thick;
26648 if (it->end_of_box_run_p)
26649 it->pixel_width += thick;
26651 /* If face has an overline, add the height of the overline
26652 (1 pixel) and a 1 pixel margin to the character height. */
26653 if (face->overline_p)
26654 it->ascent += overline_margin;
26655 take_vertical_position_into_account (it);
26656 if (it->ascent < 0)
26657 it->ascent = 0;
26658 if (it->descent < 0)
26659 it->descent = 0;
26661 if (it->glyph_row)
26662 append_composite_glyph (it);
26664 else if (it->what == IT_GLYPHLESS)
26665 produce_glyphless_glyph (it, 0, Qnil);
26666 else if (it->what == IT_IMAGE)
26667 produce_image_glyph (it);
26668 else if (it->what == IT_STRETCH)
26669 produce_stretch_glyph (it);
26671 done:
26672 /* Accumulate dimensions. Note: can't assume that it->descent > 0
26673 because this isn't true for images with `:ascent 100'. */
26674 eassert (it->ascent >= 0 && it->descent >= 0);
26675 if (it->area == TEXT_AREA)
26676 it->current_x += it->pixel_width;
26678 if (extra_line_spacing > 0)
26680 it->descent += extra_line_spacing;
26681 if (extra_line_spacing > it->max_extra_line_spacing)
26682 it->max_extra_line_spacing = extra_line_spacing;
26685 it->max_ascent = max (it->max_ascent, it->ascent);
26686 it->max_descent = max (it->max_descent, it->descent);
26687 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
26688 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
26691 /* EXPORT for RIF:
26692 Output LEN glyphs starting at START at the nominal cursor position.
26693 Advance the nominal cursor over the text. UPDATED_ROW is the glyph row
26694 being updated, and UPDATED_AREA is the area of that row being updated. */
26696 void
26697 x_write_glyphs (struct window *w, struct glyph_row *updated_row,
26698 struct glyph *start, enum glyph_row_area updated_area, int len)
26700 int x, hpos, chpos = w->phys_cursor.hpos;
26702 eassert (updated_row);
26703 /* When the window is hscrolled, cursor hpos can legitimately be out
26704 of bounds, but we draw the cursor at the corresponding window
26705 margin in that case. */
26706 if (!updated_row->reversed_p && chpos < 0)
26707 chpos = 0;
26708 if (updated_row->reversed_p && chpos >= updated_row->used[TEXT_AREA])
26709 chpos = updated_row->used[TEXT_AREA] - 1;
26711 block_input ();
26713 /* Write glyphs. */
26715 hpos = start - updated_row->glyphs[updated_area];
26716 x = draw_glyphs (w, w->output_cursor.x,
26717 updated_row, updated_area,
26718 hpos, hpos + len,
26719 DRAW_NORMAL_TEXT, 0);
26721 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
26722 if (updated_area == TEXT_AREA
26723 && w->phys_cursor_on_p
26724 && w->phys_cursor.vpos == w->output_cursor.vpos
26725 && chpos >= hpos
26726 && chpos < hpos + len)
26727 w->phys_cursor_on_p = 0;
26729 unblock_input ();
26731 /* Advance the output cursor. */
26732 w->output_cursor.hpos += len;
26733 w->output_cursor.x = x;
26737 /* EXPORT for RIF:
26738 Insert LEN glyphs from START at the nominal cursor position. */
26740 void
26741 x_insert_glyphs (struct window *w, struct glyph_row *updated_row,
26742 struct glyph *start, enum glyph_row_area updated_area, int len)
26744 struct frame *f;
26745 int line_height, shift_by_width, shifted_region_width;
26746 struct glyph_row *row;
26747 struct glyph *glyph;
26748 int frame_x, frame_y;
26749 ptrdiff_t hpos;
26751 eassert (updated_row);
26752 block_input ();
26753 f = XFRAME (WINDOW_FRAME (w));
26755 /* Get the height of the line we are in. */
26756 row = updated_row;
26757 line_height = row->height;
26759 /* Get the width of the glyphs to insert. */
26760 shift_by_width = 0;
26761 for (glyph = start; glyph < start + len; ++glyph)
26762 shift_by_width += glyph->pixel_width;
26764 /* Get the width of the region to shift right. */
26765 shifted_region_width = (window_box_width (w, updated_area)
26766 - w->output_cursor.x
26767 - shift_by_width);
26769 /* Shift right. */
26770 frame_x = window_box_left (w, updated_area) + w->output_cursor.x;
26771 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, w->output_cursor.y);
26773 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
26774 line_height, shift_by_width);
26776 /* Write the glyphs. */
26777 hpos = start - row->glyphs[updated_area];
26778 draw_glyphs (w, w->output_cursor.x, row, updated_area,
26779 hpos, hpos + len,
26780 DRAW_NORMAL_TEXT, 0);
26782 /* Advance the output cursor. */
26783 w->output_cursor.hpos += len;
26784 w->output_cursor.x += shift_by_width;
26785 unblock_input ();
26789 /* EXPORT for RIF:
26790 Erase the current text line from the nominal cursor position
26791 (inclusive) to pixel column TO_X (exclusive). The idea is that
26792 everything from TO_X onward is already erased.
26794 TO_X is a pixel position relative to UPDATED_AREA of currently
26795 updated window W. TO_X == -1 means clear to the end of this area. */
26797 void
26798 x_clear_end_of_line (struct window *w, struct glyph_row *updated_row,
26799 enum glyph_row_area updated_area, int to_x)
26801 struct frame *f;
26802 int max_x, min_y, max_y;
26803 int from_x, from_y, to_y;
26805 eassert (updated_row);
26806 f = XFRAME (w->frame);
26808 if (updated_row->full_width_p)
26809 max_x = (WINDOW_PIXEL_WIDTH (w)
26810 - (updated_row->mode_line_p ? WINDOW_RIGHT_DIVIDER_WIDTH (w) : 0));
26811 else
26812 max_x = window_box_width (w, updated_area);
26813 max_y = window_text_bottom_y (w);
26815 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
26816 of window. For TO_X > 0, truncate to end of drawing area. */
26817 if (to_x == 0)
26818 return;
26819 else if (to_x < 0)
26820 to_x = max_x;
26821 else
26822 to_x = min (to_x, max_x);
26824 to_y = min (max_y, w->output_cursor.y + updated_row->height);
26826 /* Notice if the cursor will be cleared by this operation. */
26827 if (!updated_row->full_width_p)
26828 notice_overwritten_cursor (w, updated_area,
26829 w->output_cursor.x, -1,
26830 updated_row->y,
26831 MATRIX_ROW_BOTTOM_Y (updated_row));
26833 from_x = w->output_cursor.x;
26835 /* Translate to frame coordinates. */
26836 if (updated_row->full_width_p)
26838 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
26839 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
26841 else
26843 int area_left = window_box_left (w, updated_area);
26844 from_x += area_left;
26845 to_x += area_left;
26848 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
26849 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, w->output_cursor.y));
26850 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
26852 /* Prevent inadvertently clearing to end of the X window. */
26853 if (to_x > from_x && to_y > from_y)
26855 block_input ();
26856 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
26857 to_x - from_x, to_y - from_y);
26858 unblock_input ();
26862 #endif /* HAVE_WINDOW_SYSTEM */
26866 /***********************************************************************
26867 Cursor types
26868 ***********************************************************************/
26870 /* Value is the internal representation of the specified cursor type
26871 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
26872 of the bar cursor. */
26874 static enum text_cursor_kinds
26875 get_specified_cursor_type (Lisp_Object arg, int *width)
26877 enum text_cursor_kinds type;
26879 if (NILP (arg))
26880 return NO_CURSOR;
26882 if (EQ (arg, Qbox))
26883 return FILLED_BOX_CURSOR;
26885 if (EQ (arg, Qhollow))
26886 return HOLLOW_BOX_CURSOR;
26888 if (EQ (arg, Qbar))
26890 *width = 2;
26891 return BAR_CURSOR;
26894 if (CONSP (arg)
26895 && EQ (XCAR (arg), Qbar)
26896 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
26898 *width = XINT (XCDR (arg));
26899 return BAR_CURSOR;
26902 if (EQ (arg, Qhbar))
26904 *width = 2;
26905 return HBAR_CURSOR;
26908 if (CONSP (arg)
26909 && EQ (XCAR (arg), Qhbar)
26910 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
26912 *width = XINT (XCDR (arg));
26913 return HBAR_CURSOR;
26916 /* Treat anything unknown as "hollow box cursor".
26917 It was bad to signal an error; people have trouble fixing
26918 .Xdefaults with Emacs, when it has something bad in it. */
26919 type = HOLLOW_BOX_CURSOR;
26921 return type;
26924 /* Set the default cursor types for specified frame. */
26925 void
26926 set_frame_cursor_types (struct frame *f, Lisp_Object arg)
26928 int width = 1;
26929 Lisp_Object tem;
26931 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
26932 FRAME_CURSOR_WIDTH (f) = width;
26934 /* By default, set up the blink-off state depending on the on-state. */
26936 tem = Fassoc (arg, Vblink_cursor_alist);
26937 if (!NILP (tem))
26939 FRAME_BLINK_OFF_CURSOR (f)
26940 = get_specified_cursor_type (XCDR (tem), &width);
26941 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
26943 else
26944 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
26946 /* Make sure the cursor gets redrawn. */
26947 f->cursor_type_changed = 1;
26951 #ifdef HAVE_WINDOW_SYSTEM
26953 /* Return the cursor we want to be displayed in window W. Return
26954 width of bar/hbar cursor through WIDTH arg. Return with
26955 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
26956 (i.e. if the `system caret' should track this cursor).
26958 In a mini-buffer window, we want the cursor only to appear if we
26959 are reading input from this window. For the selected window, we
26960 want the cursor type given by the frame parameter or buffer local
26961 setting of cursor-type. If explicitly marked off, draw no cursor.
26962 In all other cases, we want a hollow box cursor. */
26964 static enum text_cursor_kinds
26965 get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
26966 int *active_cursor)
26968 struct frame *f = XFRAME (w->frame);
26969 struct buffer *b = XBUFFER (w->contents);
26970 int cursor_type = DEFAULT_CURSOR;
26971 Lisp_Object alt_cursor;
26972 int non_selected = 0;
26974 *active_cursor = 1;
26976 /* Echo area */
26977 if (cursor_in_echo_area
26978 && FRAME_HAS_MINIBUF_P (f)
26979 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
26981 if (w == XWINDOW (echo_area_window))
26983 if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
26985 *width = FRAME_CURSOR_WIDTH (f);
26986 return FRAME_DESIRED_CURSOR (f);
26988 else
26989 return get_specified_cursor_type (BVAR (b, cursor_type), width);
26992 *active_cursor = 0;
26993 non_selected = 1;
26996 /* Detect a nonselected window or nonselected frame. */
26997 else if (w != XWINDOW (f->selected_window)
26998 || f != FRAME_DISPLAY_INFO (f)->x_highlight_frame)
27000 *active_cursor = 0;
27002 if (MINI_WINDOW_P (w) && minibuf_level == 0)
27003 return NO_CURSOR;
27005 non_selected = 1;
27008 /* Never display a cursor in a window in which cursor-type is nil. */
27009 if (NILP (BVAR (b, cursor_type)))
27010 return NO_CURSOR;
27012 /* Get the normal cursor type for this window. */
27013 if (EQ (BVAR (b, cursor_type), Qt))
27015 cursor_type = FRAME_DESIRED_CURSOR (f);
27016 *width = FRAME_CURSOR_WIDTH (f);
27018 else
27019 cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
27021 /* Use cursor-in-non-selected-windows instead
27022 for non-selected window or frame. */
27023 if (non_selected)
27025 alt_cursor = BVAR (b, cursor_in_non_selected_windows);
27026 if (!EQ (Qt, alt_cursor))
27027 return get_specified_cursor_type (alt_cursor, width);
27028 /* t means modify the normal cursor type. */
27029 if (cursor_type == FILLED_BOX_CURSOR)
27030 cursor_type = HOLLOW_BOX_CURSOR;
27031 else if (cursor_type == BAR_CURSOR && *width > 1)
27032 --*width;
27033 return cursor_type;
27036 /* Use normal cursor if not blinked off. */
27037 if (!w->cursor_off_p)
27039 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
27041 if (cursor_type == FILLED_BOX_CURSOR)
27043 /* Using a block cursor on large images can be very annoying.
27044 So use a hollow cursor for "large" images.
27045 If image is not transparent (no mask), also use hollow cursor. */
27046 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
27047 if (img != NULL && IMAGEP (img->spec))
27049 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
27050 where N = size of default frame font size.
27051 This should cover most of the "tiny" icons people may use. */
27052 if (!img->mask
27053 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
27054 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
27055 cursor_type = HOLLOW_BOX_CURSOR;
27058 else if (cursor_type != NO_CURSOR)
27060 /* Display current only supports BOX and HOLLOW cursors for images.
27061 So for now, unconditionally use a HOLLOW cursor when cursor is
27062 not a solid box cursor. */
27063 cursor_type = HOLLOW_BOX_CURSOR;
27066 return cursor_type;
27069 /* Cursor is blinked off, so determine how to "toggle" it. */
27071 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
27072 if ((alt_cursor = Fassoc (BVAR (b, cursor_type), Vblink_cursor_alist), !NILP (alt_cursor)))
27073 return get_specified_cursor_type (XCDR (alt_cursor), width);
27075 /* Then see if frame has specified a specific blink off cursor type. */
27076 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
27078 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
27079 return FRAME_BLINK_OFF_CURSOR (f);
27082 #if 0
27083 /* Some people liked having a permanently visible blinking cursor,
27084 while others had very strong opinions against it. So it was
27085 decided to remove it. KFS 2003-09-03 */
27087 /* Finally perform built-in cursor blinking:
27088 filled box <-> hollow box
27089 wide [h]bar <-> narrow [h]bar
27090 narrow [h]bar <-> no cursor
27091 other type <-> no cursor */
27093 if (cursor_type == FILLED_BOX_CURSOR)
27094 return HOLLOW_BOX_CURSOR;
27096 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
27098 *width = 1;
27099 return cursor_type;
27101 #endif
27103 return NO_CURSOR;
27107 /* Notice when the text cursor of window W has been completely
27108 overwritten by a drawing operation that outputs glyphs in AREA
27109 starting at X0 and ending at X1 in the line starting at Y0 and
27110 ending at Y1. X coordinates are area-relative. X1 < 0 means all
27111 the rest of the line after X0 has been written. Y coordinates
27112 are window-relative. */
27114 static void
27115 notice_overwritten_cursor (struct window *w, enum glyph_row_area area,
27116 int x0, int x1, int y0, int y1)
27118 int cx0, cx1, cy0, cy1;
27119 struct glyph_row *row;
27121 if (!w->phys_cursor_on_p)
27122 return;
27123 if (area != TEXT_AREA)
27124 return;
27126 if (w->phys_cursor.vpos < 0
27127 || w->phys_cursor.vpos >= w->current_matrix->nrows
27128 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
27129 !(row->enabled_p && MATRIX_ROW_DISPLAYS_TEXT_P (row))))
27130 return;
27132 if (row->cursor_in_fringe_p)
27134 row->cursor_in_fringe_p = 0;
27135 draw_fringe_bitmap (w, row, row->reversed_p);
27136 w->phys_cursor_on_p = 0;
27137 return;
27140 cx0 = w->phys_cursor.x;
27141 cx1 = cx0 + w->phys_cursor_width;
27142 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
27143 return;
27145 /* The cursor image will be completely removed from the
27146 screen if the output area intersects the cursor area in
27147 y-direction. When we draw in [y0 y1[, and some part of
27148 the cursor is at y < y0, that part must have been drawn
27149 before. When scrolling, the cursor is erased before
27150 actually scrolling, so we don't come here. When not
27151 scrolling, the rows above the old cursor row must have
27152 changed, and in this case these rows must have written
27153 over the cursor image.
27155 Likewise if part of the cursor is below y1, with the
27156 exception of the cursor being in the first blank row at
27157 the buffer and window end because update_text_area
27158 doesn't draw that row. (Except when it does, but
27159 that's handled in update_text_area.) */
27161 cy0 = w->phys_cursor.y;
27162 cy1 = cy0 + w->phys_cursor_height;
27163 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
27164 return;
27166 w->phys_cursor_on_p = 0;
27169 #endif /* HAVE_WINDOW_SYSTEM */
27172 /************************************************************************
27173 Mouse Face
27174 ************************************************************************/
27176 #ifdef HAVE_WINDOW_SYSTEM
27178 /* EXPORT for RIF:
27179 Fix the display of area AREA of overlapping row ROW in window W
27180 with respect to the overlapping part OVERLAPS. */
27182 void
27183 x_fix_overlapping_area (struct window *w, struct glyph_row *row,
27184 enum glyph_row_area area, int overlaps)
27186 int i, x;
27188 block_input ();
27190 x = 0;
27191 for (i = 0; i < row->used[area];)
27193 if (row->glyphs[area][i].overlaps_vertically_p)
27195 int start = i, start_x = x;
27199 x += row->glyphs[area][i].pixel_width;
27200 ++i;
27202 while (i < row->used[area]
27203 && row->glyphs[area][i].overlaps_vertically_p);
27205 draw_glyphs (w, start_x, row, area,
27206 start, i,
27207 DRAW_NORMAL_TEXT, overlaps);
27209 else
27211 x += row->glyphs[area][i].pixel_width;
27212 ++i;
27216 unblock_input ();
27220 /* EXPORT:
27221 Draw the cursor glyph of window W in glyph row ROW. See the
27222 comment of draw_glyphs for the meaning of HL. */
27224 void
27225 draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
27226 enum draw_glyphs_face hl)
27228 /* If cursor hpos is out of bounds, don't draw garbage. This can
27229 happen in mini-buffer windows when switching between echo area
27230 glyphs and mini-buffer. */
27231 if ((row->reversed_p
27232 ? (w->phys_cursor.hpos >= 0)
27233 : (w->phys_cursor.hpos < row->used[TEXT_AREA])))
27235 int on_p = w->phys_cursor_on_p;
27236 int x1;
27237 int hpos = w->phys_cursor.hpos;
27239 /* When the window is hscrolled, cursor hpos can legitimately be
27240 out of bounds, but we draw the cursor at the corresponding
27241 window margin in that case. */
27242 if (!row->reversed_p && hpos < 0)
27243 hpos = 0;
27244 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
27245 hpos = row->used[TEXT_AREA] - 1;
27247 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA, hpos, hpos + 1,
27248 hl, 0);
27249 w->phys_cursor_on_p = on_p;
27251 if (hl == DRAW_CURSOR)
27252 w->phys_cursor_width = x1 - w->phys_cursor.x;
27253 /* When we erase the cursor, and ROW is overlapped by other
27254 rows, make sure that these overlapping parts of other rows
27255 are redrawn. */
27256 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
27258 w->phys_cursor_width = x1 - w->phys_cursor.x;
27260 if (row > w->current_matrix->rows
27261 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
27262 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
27263 OVERLAPS_ERASED_CURSOR);
27265 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
27266 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
27267 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
27268 OVERLAPS_ERASED_CURSOR);
27274 /* Erase the image of a cursor of window W from the screen. */
27276 void
27277 erase_phys_cursor (struct window *w)
27279 struct frame *f = XFRAME (w->frame);
27280 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
27281 int hpos = w->phys_cursor.hpos;
27282 int vpos = w->phys_cursor.vpos;
27283 int mouse_face_here_p = 0;
27284 struct glyph_matrix *active_glyphs = w->current_matrix;
27285 struct glyph_row *cursor_row;
27286 struct glyph *cursor_glyph;
27287 enum draw_glyphs_face hl;
27289 /* No cursor displayed or row invalidated => nothing to do on the
27290 screen. */
27291 if (w->phys_cursor_type == NO_CURSOR)
27292 goto mark_cursor_off;
27294 /* VPOS >= active_glyphs->nrows means that window has been resized.
27295 Don't bother to erase the cursor. */
27296 if (vpos >= active_glyphs->nrows)
27297 goto mark_cursor_off;
27299 /* If row containing cursor is marked invalid, there is nothing we
27300 can do. */
27301 cursor_row = MATRIX_ROW (active_glyphs, vpos);
27302 if (!cursor_row->enabled_p)
27303 goto mark_cursor_off;
27305 /* If line spacing is > 0, old cursor may only be partially visible in
27306 window after split-window. So adjust visible height. */
27307 cursor_row->visible_height = min (cursor_row->visible_height,
27308 window_text_bottom_y (w) - cursor_row->y);
27310 /* If row is completely invisible, don't attempt to delete a cursor which
27311 isn't there. This can happen if cursor is at top of a window, and
27312 we switch to a buffer with a header line in that window. */
27313 if (cursor_row->visible_height <= 0)
27314 goto mark_cursor_off;
27316 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
27317 if (cursor_row->cursor_in_fringe_p)
27319 cursor_row->cursor_in_fringe_p = 0;
27320 draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
27321 goto mark_cursor_off;
27324 /* This can happen when the new row is shorter than the old one.
27325 In this case, either draw_glyphs or clear_end_of_line
27326 should have cleared the cursor. Note that we wouldn't be
27327 able to erase the cursor in this case because we don't have a
27328 cursor glyph at hand. */
27329 if ((cursor_row->reversed_p
27330 ? (w->phys_cursor.hpos < 0)
27331 : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
27332 goto mark_cursor_off;
27334 /* When the window is hscrolled, cursor hpos can legitimately be out
27335 of bounds, but we draw the cursor at the corresponding window
27336 margin in that case. */
27337 if (!cursor_row->reversed_p && hpos < 0)
27338 hpos = 0;
27339 if (cursor_row->reversed_p && hpos >= cursor_row->used[TEXT_AREA])
27340 hpos = cursor_row->used[TEXT_AREA] - 1;
27342 /* If the cursor is in the mouse face area, redisplay that when
27343 we clear the cursor. */
27344 if (! NILP (hlinfo->mouse_face_window)
27345 && coords_in_mouse_face_p (w, hpos, vpos)
27346 /* Don't redraw the cursor's spot in mouse face if it is at the
27347 end of a line (on a newline). The cursor appears there, but
27348 mouse highlighting does not. */
27349 && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
27350 mouse_face_here_p = 1;
27352 /* Maybe clear the display under the cursor. */
27353 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
27355 int x, y, left_x;
27356 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
27357 int width;
27359 cursor_glyph = get_phys_cursor_glyph (w);
27360 if (cursor_glyph == NULL)
27361 goto mark_cursor_off;
27363 width = cursor_glyph->pixel_width;
27364 left_x = window_box_left_offset (w, TEXT_AREA);
27365 x = w->phys_cursor.x;
27366 if (x < left_x)
27367 width -= left_x - x;
27368 width = min (width, window_box_width (w, TEXT_AREA) - x);
27369 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
27370 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
27372 if (width > 0)
27373 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
27376 /* Erase the cursor by redrawing the character underneath it. */
27377 if (mouse_face_here_p)
27378 hl = DRAW_MOUSE_FACE;
27379 else
27380 hl = DRAW_NORMAL_TEXT;
27381 draw_phys_cursor_glyph (w, cursor_row, hl);
27383 mark_cursor_off:
27384 w->phys_cursor_on_p = 0;
27385 w->phys_cursor_type = NO_CURSOR;
27389 /* EXPORT:
27390 Display or clear cursor of window W. If ON is zero, clear the
27391 cursor. If it is non-zero, display the cursor. If ON is nonzero,
27392 where to put the cursor is specified by HPOS, VPOS, X and Y. */
27394 void
27395 display_and_set_cursor (struct window *w, bool on,
27396 int hpos, int vpos, int x, int y)
27398 struct frame *f = XFRAME (w->frame);
27399 int new_cursor_type;
27400 int new_cursor_width;
27401 int active_cursor;
27402 struct glyph_row *glyph_row;
27403 struct glyph *glyph;
27405 /* This is pointless on invisible frames, and dangerous on garbaged
27406 windows and frames; in the latter case, the frame or window may
27407 be in the midst of changing its size, and x and y may be off the
27408 window. */
27409 if (! FRAME_VISIBLE_P (f)
27410 || FRAME_GARBAGED_P (f)
27411 || vpos >= w->current_matrix->nrows
27412 || hpos >= w->current_matrix->matrix_w)
27413 return;
27415 /* If cursor is off and we want it off, return quickly. */
27416 if (!on && !w->phys_cursor_on_p)
27417 return;
27419 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
27420 /* If cursor row is not enabled, we don't really know where to
27421 display the cursor. */
27422 if (!glyph_row->enabled_p)
27424 w->phys_cursor_on_p = 0;
27425 return;
27428 glyph = NULL;
27429 if (!glyph_row->exact_window_width_line_p
27430 || (0 <= hpos && hpos < glyph_row->used[TEXT_AREA]))
27431 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
27433 eassert (input_blocked_p ());
27435 /* Set new_cursor_type to the cursor we want to be displayed. */
27436 new_cursor_type = get_window_cursor_type (w, glyph,
27437 &new_cursor_width, &active_cursor);
27439 /* If cursor is currently being shown and we don't want it to be or
27440 it is in the wrong place, or the cursor type is not what we want,
27441 erase it. */
27442 if (w->phys_cursor_on_p
27443 && (!on
27444 || w->phys_cursor.x != x
27445 || w->phys_cursor.y != y
27446 || new_cursor_type != w->phys_cursor_type
27447 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
27448 && new_cursor_width != w->phys_cursor_width)))
27449 erase_phys_cursor (w);
27451 /* Don't check phys_cursor_on_p here because that flag is only set
27452 to zero in some cases where we know that the cursor has been
27453 completely erased, to avoid the extra work of erasing the cursor
27454 twice. In other words, phys_cursor_on_p can be 1 and the cursor
27455 still not be visible, or it has only been partly erased. */
27456 if (on)
27458 w->phys_cursor_ascent = glyph_row->ascent;
27459 w->phys_cursor_height = glyph_row->height;
27461 /* Set phys_cursor_.* before x_draw_.* is called because some
27462 of them may need the information. */
27463 w->phys_cursor.x = x;
27464 w->phys_cursor.y = glyph_row->y;
27465 w->phys_cursor.hpos = hpos;
27466 w->phys_cursor.vpos = vpos;
27469 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
27470 new_cursor_type, new_cursor_width,
27471 on, active_cursor);
27475 /* Switch the display of W's cursor on or off, according to the value
27476 of ON. */
27478 static void
27479 update_window_cursor (struct window *w, bool on)
27481 /* Don't update cursor in windows whose frame is in the process
27482 of being deleted. */
27483 if (w->current_matrix)
27485 int hpos = w->phys_cursor.hpos;
27486 int vpos = w->phys_cursor.vpos;
27487 struct glyph_row *row;
27489 if (vpos >= w->current_matrix->nrows
27490 || hpos >= w->current_matrix->matrix_w)
27491 return;
27493 row = MATRIX_ROW (w->current_matrix, vpos);
27495 /* When the window is hscrolled, cursor hpos can legitimately be
27496 out of bounds, but we draw the cursor at the corresponding
27497 window margin in that case. */
27498 if (!row->reversed_p && hpos < 0)
27499 hpos = 0;
27500 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
27501 hpos = row->used[TEXT_AREA] - 1;
27503 block_input ();
27504 display_and_set_cursor (w, on, hpos, vpos,
27505 w->phys_cursor.x, w->phys_cursor.y);
27506 unblock_input ();
27511 /* Call update_window_cursor with parameter ON_P on all leaf windows
27512 in the window tree rooted at W. */
27514 static void
27515 update_cursor_in_window_tree (struct window *w, bool on_p)
27517 while (w)
27519 if (WINDOWP (w->contents))
27520 update_cursor_in_window_tree (XWINDOW (w->contents), on_p);
27521 else
27522 update_window_cursor (w, on_p);
27524 w = NILP (w->next) ? 0 : XWINDOW (w->next);
27529 /* EXPORT:
27530 Display the cursor on window W, or clear it, according to ON_P.
27531 Don't change the cursor's position. */
27533 void
27534 x_update_cursor (struct frame *f, bool on_p)
27536 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
27540 /* EXPORT:
27541 Clear the cursor of window W to background color, and mark the
27542 cursor as not shown. This is used when the text where the cursor
27543 is about to be rewritten. */
27545 void
27546 x_clear_cursor (struct window *w)
27548 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
27549 update_window_cursor (w, 0);
27552 #endif /* HAVE_WINDOW_SYSTEM */
27554 /* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
27555 and MSDOS. */
27556 static void
27557 draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
27558 int start_hpos, int end_hpos,
27559 enum draw_glyphs_face draw)
27561 #ifdef HAVE_WINDOW_SYSTEM
27562 if (FRAME_WINDOW_P (XFRAME (w->frame)))
27564 draw_glyphs (w, start_x, row, TEXT_AREA, start_hpos, end_hpos, draw, 0);
27565 return;
27567 #endif
27568 #if defined (HAVE_GPM) || defined (MSDOS) || defined (WINDOWSNT)
27569 tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
27570 #endif
27573 /* Display the active region described by mouse_face_* according to DRAW. */
27575 static void
27576 show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
27578 struct window *w = XWINDOW (hlinfo->mouse_face_window);
27579 struct frame *f = XFRAME (WINDOW_FRAME (w));
27581 if (/* If window is in the process of being destroyed, don't bother
27582 to do anything. */
27583 w->current_matrix != NULL
27584 /* Don't update mouse highlight if hidden. */
27585 && (draw != DRAW_MOUSE_FACE || !hlinfo->mouse_face_hidden)
27586 /* Recognize when we are called to operate on rows that don't exist
27587 anymore. This can happen when a window is split. */
27588 && hlinfo->mouse_face_end_row < w->current_matrix->nrows)
27590 int phys_cursor_on_p = w->phys_cursor_on_p;
27591 struct glyph_row *row, *first, *last;
27593 first = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
27594 last = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
27596 for (row = first; row <= last && row->enabled_p; ++row)
27598 int start_hpos, end_hpos, start_x;
27600 /* For all but the first row, the highlight starts at column 0. */
27601 if (row == first)
27603 /* R2L rows have BEG and END in reversed order, but the
27604 screen drawing geometry is always left to right. So
27605 we need to mirror the beginning and end of the
27606 highlighted area in R2L rows. */
27607 if (!row->reversed_p)
27609 start_hpos = hlinfo->mouse_face_beg_col;
27610 start_x = hlinfo->mouse_face_beg_x;
27612 else if (row == last)
27614 start_hpos = hlinfo->mouse_face_end_col;
27615 start_x = hlinfo->mouse_face_end_x;
27617 else
27619 start_hpos = 0;
27620 start_x = 0;
27623 else if (row->reversed_p && row == last)
27625 start_hpos = hlinfo->mouse_face_end_col;
27626 start_x = hlinfo->mouse_face_end_x;
27628 else
27630 start_hpos = 0;
27631 start_x = 0;
27634 if (row == last)
27636 if (!row->reversed_p)
27637 end_hpos = hlinfo->mouse_face_end_col;
27638 else if (row == first)
27639 end_hpos = hlinfo->mouse_face_beg_col;
27640 else
27642 end_hpos = row->used[TEXT_AREA];
27643 if (draw == DRAW_NORMAL_TEXT)
27644 row->fill_line_p = 1; /* Clear to end of line */
27647 else if (row->reversed_p && row == first)
27648 end_hpos = hlinfo->mouse_face_beg_col;
27649 else
27651 end_hpos = row->used[TEXT_AREA];
27652 if (draw == DRAW_NORMAL_TEXT)
27653 row->fill_line_p = 1; /* Clear to end of line */
27656 if (end_hpos > start_hpos)
27658 draw_row_with_mouse_face (w, start_x, row,
27659 start_hpos, end_hpos, draw);
27661 row->mouse_face_p
27662 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
27666 #ifdef HAVE_WINDOW_SYSTEM
27667 /* When we've written over the cursor, arrange for it to
27668 be displayed again. */
27669 if (FRAME_WINDOW_P (f)
27670 && phys_cursor_on_p && !w->phys_cursor_on_p)
27672 int hpos = w->phys_cursor.hpos;
27674 /* When the window is hscrolled, cursor hpos can legitimately be
27675 out of bounds, but we draw the cursor at the corresponding
27676 window margin in that case. */
27677 if (!row->reversed_p && hpos < 0)
27678 hpos = 0;
27679 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
27680 hpos = row->used[TEXT_AREA] - 1;
27682 block_input ();
27683 display_and_set_cursor (w, 1, hpos, w->phys_cursor.vpos,
27684 w->phys_cursor.x, w->phys_cursor.y);
27685 unblock_input ();
27687 #endif /* HAVE_WINDOW_SYSTEM */
27690 #ifdef HAVE_WINDOW_SYSTEM
27691 /* Change the mouse cursor. */
27692 if (FRAME_WINDOW_P (f))
27694 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
27695 if (draw == DRAW_NORMAL_TEXT
27696 && !EQ (hlinfo->mouse_face_window, f->tool_bar_window))
27697 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
27698 else
27699 #endif
27700 if (draw == DRAW_MOUSE_FACE)
27701 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
27702 else
27703 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
27705 #endif /* HAVE_WINDOW_SYSTEM */
27708 /* EXPORT:
27709 Clear out the mouse-highlighted active region.
27710 Redraw it un-highlighted first. Value is non-zero if mouse
27711 face was actually drawn unhighlighted. */
27714 clear_mouse_face (Mouse_HLInfo *hlinfo)
27716 int cleared = 0;
27718 if (!hlinfo->mouse_face_hidden && !NILP (hlinfo->mouse_face_window))
27720 show_mouse_face (hlinfo, DRAW_NORMAL_TEXT);
27721 cleared = 1;
27724 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
27725 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
27726 hlinfo->mouse_face_window = Qnil;
27727 hlinfo->mouse_face_overlay = Qnil;
27728 return cleared;
27731 /* Return true if the coordinates HPOS and VPOS on windows W are
27732 within the mouse face on that window. */
27733 static bool
27734 coords_in_mouse_face_p (struct window *w, int hpos, int vpos)
27736 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
27738 /* Quickly resolve the easy cases. */
27739 if (!(WINDOWP (hlinfo->mouse_face_window)
27740 && XWINDOW (hlinfo->mouse_face_window) == w))
27741 return false;
27742 if (vpos < hlinfo->mouse_face_beg_row
27743 || vpos > hlinfo->mouse_face_end_row)
27744 return false;
27745 if (vpos > hlinfo->mouse_face_beg_row
27746 && vpos < hlinfo->mouse_face_end_row)
27747 return true;
27749 if (!MATRIX_ROW (w->current_matrix, vpos)->reversed_p)
27751 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
27753 if (hlinfo->mouse_face_beg_col <= hpos && hpos < hlinfo->mouse_face_end_col)
27754 return true;
27756 else if ((vpos == hlinfo->mouse_face_beg_row
27757 && hpos >= hlinfo->mouse_face_beg_col)
27758 || (vpos == hlinfo->mouse_face_end_row
27759 && hpos < hlinfo->mouse_face_end_col))
27760 return true;
27762 else
27764 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
27766 if (hlinfo->mouse_face_end_col < hpos && hpos <= hlinfo->mouse_face_beg_col)
27767 return true;
27769 else if ((vpos == hlinfo->mouse_face_beg_row
27770 && hpos <= hlinfo->mouse_face_beg_col)
27771 || (vpos == hlinfo->mouse_face_end_row
27772 && hpos > hlinfo->mouse_face_end_col))
27773 return true;
27775 return false;
27779 /* EXPORT:
27780 True if physical cursor of window W is within mouse face. */
27782 bool
27783 cursor_in_mouse_face_p (struct window *w)
27785 int hpos = w->phys_cursor.hpos;
27786 int vpos = w->phys_cursor.vpos;
27787 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
27789 /* When the window is hscrolled, cursor hpos can legitimately be out
27790 of bounds, but we draw the cursor at the corresponding window
27791 margin in that case. */
27792 if (!row->reversed_p && hpos < 0)
27793 hpos = 0;
27794 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
27795 hpos = row->used[TEXT_AREA] - 1;
27797 return coords_in_mouse_face_p (w, hpos, vpos);
27802 /* Find the glyph rows START_ROW and END_ROW of window W that display
27803 characters between buffer positions START_CHARPOS and END_CHARPOS
27804 (excluding END_CHARPOS). DISP_STRING is a display string that
27805 covers these buffer positions. This is similar to
27806 row_containing_pos, but is more accurate when bidi reordering makes
27807 buffer positions change non-linearly with glyph rows. */
27808 static void
27809 rows_from_pos_range (struct window *w,
27810 ptrdiff_t start_charpos, ptrdiff_t end_charpos,
27811 Lisp_Object disp_string,
27812 struct glyph_row **start, struct glyph_row **end)
27814 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
27815 int last_y = window_text_bottom_y (w);
27816 struct glyph_row *row;
27818 *start = NULL;
27819 *end = NULL;
27821 while (!first->enabled_p
27822 && first < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
27823 first++;
27825 /* Find the START row. */
27826 for (row = first;
27827 row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y;
27828 row++)
27830 /* A row can potentially be the START row if the range of the
27831 characters it displays intersects the range
27832 [START_CHARPOS..END_CHARPOS). */
27833 if (! ((start_charpos < MATRIX_ROW_START_CHARPOS (row)
27834 && end_charpos < MATRIX_ROW_START_CHARPOS (row))
27835 /* See the commentary in row_containing_pos, for the
27836 explanation of the complicated way to check whether
27837 some position is beyond the end of the characters
27838 displayed by a row. */
27839 || ((start_charpos > MATRIX_ROW_END_CHARPOS (row)
27840 || (start_charpos == MATRIX_ROW_END_CHARPOS (row)
27841 && !row->ends_at_zv_p
27842 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
27843 && (end_charpos > MATRIX_ROW_END_CHARPOS (row)
27844 || (end_charpos == MATRIX_ROW_END_CHARPOS (row)
27845 && !row->ends_at_zv_p
27846 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))))))
27848 /* Found a candidate row. Now make sure at least one of the
27849 glyphs it displays has a charpos from the range
27850 [START_CHARPOS..END_CHARPOS).
27852 This is not obvious because bidi reordering could make
27853 buffer positions of a row be 1,2,3,102,101,100, and if we
27854 want to highlight characters in [50..60), we don't want
27855 this row, even though [50..60) does intersect [1..103),
27856 the range of character positions given by the row's start
27857 and end positions. */
27858 struct glyph *g = row->glyphs[TEXT_AREA];
27859 struct glyph *e = g + row->used[TEXT_AREA];
27861 while (g < e)
27863 if (((BUFFERP (g->object) || INTEGERP (g->object))
27864 && start_charpos <= g->charpos && g->charpos < end_charpos)
27865 /* A glyph that comes from DISP_STRING is by
27866 definition to be highlighted. */
27867 || EQ (g->object, disp_string))
27868 *start = row;
27869 g++;
27871 if (*start)
27872 break;
27876 /* Find the END row. */
27877 if (!*start
27878 /* If the last row is partially visible, start looking for END
27879 from that row, instead of starting from FIRST. */
27880 && !(row->enabled_p
27881 && row->y < last_y && MATRIX_ROW_BOTTOM_Y (row) > last_y))
27882 row = first;
27883 for ( ; row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y; row++)
27885 struct glyph_row *next = row + 1;
27886 ptrdiff_t next_start = MATRIX_ROW_START_CHARPOS (next);
27888 if (!next->enabled_p
27889 || next >= MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)
27890 /* The first row >= START whose range of displayed characters
27891 does NOT intersect the range [START_CHARPOS..END_CHARPOS]
27892 is the row END + 1. */
27893 || (start_charpos < next_start
27894 && end_charpos < next_start)
27895 || ((start_charpos > MATRIX_ROW_END_CHARPOS (next)
27896 || (start_charpos == MATRIX_ROW_END_CHARPOS (next)
27897 && !next->ends_at_zv_p
27898 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))
27899 && (end_charpos > MATRIX_ROW_END_CHARPOS (next)
27900 || (end_charpos == MATRIX_ROW_END_CHARPOS (next)
27901 && !next->ends_at_zv_p
27902 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))))
27904 *end = row;
27905 break;
27907 else
27909 /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
27910 but none of the characters it displays are in the range, it is
27911 also END + 1. */
27912 struct glyph *g = next->glyphs[TEXT_AREA];
27913 struct glyph *s = g;
27914 struct glyph *e = g + next->used[TEXT_AREA];
27916 while (g < e)
27918 if (((BUFFERP (g->object) || INTEGERP (g->object))
27919 && ((start_charpos <= g->charpos && g->charpos < end_charpos)
27920 /* If the buffer position of the first glyph in
27921 the row is equal to END_CHARPOS, it means
27922 the last character to be highlighted is the
27923 newline of ROW, and we must consider NEXT as
27924 END, not END+1. */
27925 || (((!next->reversed_p && g == s)
27926 || (next->reversed_p && g == e - 1))
27927 && (g->charpos == end_charpos
27928 /* Special case for when NEXT is an
27929 empty line at ZV. */
27930 || (g->charpos == -1
27931 && !row->ends_at_zv_p
27932 && next_start == end_charpos)))))
27933 /* A glyph that comes from DISP_STRING is by
27934 definition to be highlighted. */
27935 || EQ (g->object, disp_string))
27936 break;
27937 g++;
27939 if (g == e)
27941 *end = row;
27942 break;
27944 /* The first row that ends at ZV must be the last to be
27945 highlighted. */
27946 else if (next->ends_at_zv_p)
27948 *end = next;
27949 break;
27955 /* This function sets the mouse_face_* elements of HLINFO, assuming
27956 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
27957 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
27958 for the overlay or run of text properties specifying the mouse
27959 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
27960 before-string and after-string that must also be highlighted.
27961 DISP_STRING, if non-nil, is a display string that may cover some
27962 or all of the highlighted text. */
27964 static void
27965 mouse_face_from_buffer_pos (Lisp_Object window,
27966 Mouse_HLInfo *hlinfo,
27967 ptrdiff_t mouse_charpos,
27968 ptrdiff_t start_charpos,
27969 ptrdiff_t end_charpos,
27970 Lisp_Object before_string,
27971 Lisp_Object after_string,
27972 Lisp_Object disp_string)
27974 struct window *w = XWINDOW (window);
27975 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
27976 struct glyph_row *r1, *r2;
27977 struct glyph *glyph, *end;
27978 ptrdiff_t ignore, pos;
27979 int x;
27981 eassert (NILP (disp_string) || STRINGP (disp_string));
27982 eassert (NILP (before_string) || STRINGP (before_string));
27983 eassert (NILP (after_string) || STRINGP (after_string));
27985 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
27986 rows_from_pos_range (w, start_charpos, end_charpos, disp_string, &r1, &r2);
27987 if (r1 == NULL)
27988 r1 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
27989 /* If the before-string or display-string contains newlines,
27990 rows_from_pos_range skips to its last row. Move back. */
27991 if (!NILP (before_string) || !NILP (disp_string))
27993 struct glyph_row *prev;
27994 while ((prev = r1 - 1, prev >= first)
27995 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
27996 && prev->used[TEXT_AREA] > 0)
27998 struct glyph *beg = prev->glyphs[TEXT_AREA];
27999 glyph = beg + prev->used[TEXT_AREA];
28000 while (--glyph >= beg && INTEGERP (glyph->object));
28001 if (glyph < beg
28002 || !(EQ (glyph->object, before_string)
28003 || EQ (glyph->object, disp_string)))
28004 break;
28005 r1 = prev;
28008 if (r2 == NULL)
28010 r2 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
28011 hlinfo->mouse_face_past_end = 1;
28013 else if (!NILP (after_string))
28015 /* If the after-string has newlines, advance to its last row. */
28016 struct glyph_row *next;
28017 struct glyph_row *last
28018 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
28020 for (next = r2 + 1;
28021 next <= last
28022 && next->used[TEXT_AREA] > 0
28023 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
28024 ++next)
28025 r2 = next;
28027 /* The rest of the display engine assumes that mouse_face_beg_row is
28028 either above mouse_face_end_row or identical to it. But with
28029 bidi-reordered continued lines, the row for START_CHARPOS could
28030 be below the row for END_CHARPOS. If so, swap the rows and store
28031 them in correct order. */
28032 if (r1->y > r2->y)
28034 struct glyph_row *tem = r2;
28036 r2 = r1;
28037 r1 = tem;
28040 hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
28041 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
28043 /* For a bidi-reordered row, the positions of BEFORE_STRING,
28044 AFTER_STRING, DISP_STRING, START_CHARPOS, and END_CHARPOS
28045 could be anywhere in the row and in any order. The strategy
28046 below is to find the leftmost and the rightmost glyph that
28047 belongs to either of these 3 strings, or whose position is
28048 between START_CHARPOS and END_CHARPOS, and highlight all the
28049 glyphs between those two. This may cover more than just the text
28050 between START_CHARPOS and END_CHARPOS if the range of characters
28051 strides the bidi level boundary, e.g. if the beginning is in R2L
28052 text while the end is in L2R text or vice versa. */
28053 if (!r1->reversed_p)
28055 /* This row is in a left to right paragraph. Scan it left to
28056 right. */
28057 glyph = r1->glyphs[TEXT_AREA];
28058 end = glyph + r1->used[TEXT_AREA];
28059 x = r1->x;
28061 /* Skip truncation glyphs at the start of the glyph row. */
28062 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
28063 for (; glyph < end
28064 && INTEGERP (glyph->object)
28065 && glyph->charpos < 0;
28066 ++glyph)
28067 x += glyph->pixel_width;
28069 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
28070 or DISP_STRING, and the first glyph from buffer whose
28071 position is between START_CHARPOS and END_CHARPOS. */
28072 for (; glyph < end
28073 && !INTEGERP (glyph->object)
28074 && !EQ (glyph->object, disp_string)
28075 && !(BUFFERP (glyph->object)
28076 && (glyph->charpos >= start_charpos
28077 && glyph->charpos < end_charpos));
28078 ++glyph)
28080 /* BEFORE_STRING or AFTER_STRING are only relevant if they
28081 are present at buffer positions between START_CHARPOS and
28082 END_CHARPOS, or if they come from an overlay. */
28083 if (EQ (glyph->object, before_string))
28085 pos = string_buffer_position (before_string,
28086 start_charpos);
28087 /* If pos == 0, it means before_string came from an
28088 overlay, not from a buffer position. */
28089 if (!pos || (pos >= start_charpos && pos < end_charpos))
28090 break;
28092 else if (EQ (glyph->object, after_string))
28094 pos = string_buffer_position (after_string, end_charpos);
28095 if (!pos || (pos >= start_charpos && pos < end_charpos))
28096 break;
28098 x += glyph->pixel_width;
28100 hlinfo->mouse_face_beg_x = x;
28101 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
28103 else
28105 /* This row is in a right to left paragraph. Scan it right to
28106 left. */
28107 struct glyph *g;
28109 end = r1->glyphs[TEXT_AREA] - 1;
28110 glyph = end + r1->used[TEXT_AREA];
28112 /* Skip truncation glyphs at the start of the glyph row. */
28113 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
28114 for (; glyph > end
28115 && INTEGERP (glyph->object)
28116 && glyph->charpos < 0;
28117 --glyph)
28120 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
28121 or DISP_STRING, and the first glyph from buffer whose
28122 position is between START_CHARPOS and END_CHARPOS. */
28123 for (; glyph > end
28124 && !INTEGERP (glyph->object)
28125 && !EQ (glyph->object, disp_string)
28126 && !(BUFFERP (glyph->object)
28127 && (glyph->charpos >= start_charpos
28128 && glyph->charpos < end_charpos));
28129 --glyph)
28131 /* BEFORE_STRING or AFTER_STRING are only relevant if they
28132 are present at buffer positions between START_CHARPOS and
28133 END_CHARPOS, or if they come from an overlay. */
28134 if (EQ (glyph->object, before_string))
28136 pos = string_buffer_position (before_string, start_charpos);
28137 /* If pos == 0, it means before_string came from an
28138 overlay, not from a buffer position. */
28139 if (!pos || (pos >= start_charpos && pos < end_charpos))
28140 break;
28142 else if (EQ (glyph->object, after_string))
28144 pos = string_buffer_position (after_string, end_charpos);
28145 if (!pos || (pos >= start_charpos && pos < end_charpos))
28146 break;
28150 glyph++; /* first glyph to the right of the highlighted area */
28151 for (g = r1->glyphs[TEXT_AREA], x = r1->x; g < glyph; g++)
28152 x += g->pixel_width;
28153 hlinfo->mouse_face_beg_x = x;
28154 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
28157 /* If the highlight ends in a different row, compute GLYPH and END
28158 for the end row. Otherwise, reuse the values computed above for
28159 the row where the highlight begins. */
28160 if (r2 != r1)
28162 if (!r2->reversed_p)
28164 glyph = r2->glyphs[TEXT_AREA];
28165 end = glyph + r2->used[TEXT_AREA];
28166 x = r2->x;
28168 else
28170 end = r2->glyphs[TEXT_AREA] - 1;
28171 glyph = end + r2->used[TEXT_AREA];
28175 if (!r2->reversed_p)
28177 /* Skip truncation and continuation glyphs near the end of the
28178 row, and also blanks and stretch glyphs inserted by
28179 extend_face_to_end_of_line. */
28180 while (end > glyph
28181 && INTEGERP ((end - 1)->object))
28182 --end;
28183 /* Scan the rest of the glyph row from the end, looking for the
28184 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
28185 DISP_STRING, or whose position is between START_CHARPOS
28186 and END_CHARPOS */
28187 for (--end;
28188 end > glyph
28189 && !INTEGERP (end->object)
28190 && !EQ (end->object, disp_string)
28191 && !(BUFFERP (end->object)
28192 && (end->charpos >= start_charpos
28193 && end->charpos < end_charpos));
28194 --end)
28196 /* BEFORE_STRING or AFTER_STRING are only relevant if they
28197 are present at buffer positions between START_CHARPOS and
28198 END_CHARPOS, or if they come from an overlay. */
28199 if (EQ (end->object, before_string))
28201 pos = string_buffer_position (before_string, start_charpos);
28202 if (!pos || (pos >= start_charpos && pos < end_charpos))
28203 break;
28205 else if (EQ (end->object, after_string))
28207 pos = string_buffer_position (after_string, end_charpos);
28208 if (!pos || (pos >= start_charpos && pos < end_charpos))
28209 break;
28212 /* Find the X coordinate of the last glyph to be highlighted. */
28213 for (; glyph <= end; ++glyph)
28214 x += glyph->pixel_width;
28216 hlinfo->mouse_face_end_x = x;
28217 hlinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
28219 else
28221 /* Skip truncation and continuation glyphs near the end of the
28222 row, and also blanks and stretch glyphs inserted by
28223 extend_face_to_end_of_line. */
28224 x = r2->x;
28225 end++;
28226 while (end < glyph
28227 && INTEGERP (end->object))
28229 x += end->pixel_width;
28230 ++end;
28232 /* Scan the rest of the glyph row from the end, looking for the
28233 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
28234 DISP_STRING, or whose position is between START_CHARPOS
28235 and END_CHARPOS */
28236 for ( ;
28237 end < glyph
28238 && !INTEGERP (end->object)
28239 && !EQ (end->object, disp_string)
28240 && !(BUFFERP (end->object)
28241 && (end->charpos >= start_charpos
28242 && end->charpos < end_charpos));
28243 ++end)
28245 /* BEFORE_STRING or AFTER_STRING are only relevant if they
28246 are present at buffer positions between START_CHARPOS and
28247 END_CHARPOS, or if they come from an overlay. */
28248 if (EQ (end->object, before_string))
28250 pos = string_buffer_position (before_string, start_charpos);
28251 if (!pos || (pos >= start_charpos && pos < end_charpos))
28252 break;
28254 else if (EQ (end->object, after_string))
28256 pos = string_buffer_position (after_string, end_charpos);
28257 if (!pos || (pos >= start_charpos && pos < end_charpos))
28258 break;
28260 x += end->pixel_width;
28262 /* If we exited the above loop because we arrived at the last
28263 glyph of the row, and its buffer position is still not in
28264 range, it means the last character in range is the preceding
28265 newline. Bump the end column and x values to get past the
28266 last glyph. */
28267 if (end == glyph
28268 && BUFFERP (end->object)
28269 && (end->charpos < start_charpos
28270 || end->charpos >= end_charpos))
28272 x += end->pixel_width;
28273 ++end;
28275 hlinfo->mouse_face_end_x = x;
28276 hlinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
28279 hlinfo->mouse_face_window = window;
28280 hlinfo->mouse_face_face_id
28281 = face_at_buffer_position (w, mouse_charpos, &ignore,
28282 mouse_charpos + 1,
28283 !hlinfo->mouse_face_hidden, -1);
28284 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
28287 /* The following function is not used anymore (replaced with
28288 mouse_face_from_string_pos), but I leave it here for the time
28289 being, in case someone would. */
28291 #if 0 /* not used */
28293 /* Find the position of the glyph for position POS in OBJECT in
28294 window W's current matrix, and return in *X, *Y the pixel
28295 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
28297 RIGHT_P non-zero means return the position of the right edge of the
28298 glyph, RIGHT_P zero means return the left edge position.
28300 If no glyph for POS exists in the matrix, return the position of
28301 the glyph with the next smaller position that is in the matrix, if
28302 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
28303 exists in the matrix, return the position of the glyph with the
28304 next larger position in OBJECT.
28306 Value is non-zero if a glyph was found. */
28308 static int
28309 fast_find_string_pos (struct window *w, ptrdiff_t pos, Lisp_Object object,
28310 int *hpos, int *vpos, int *x, int *y, int right_p)
28312 int yb = window_text_bottom_y (w);
28313 struct glyph_row *r;
28314 struct glyph *best_glyph = NULL;
28315 struct glyph_row *best_row = NULL;
28316 int best_x = 0;
28318 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
28319 r->enabled_p && r->y < yb;
28320 ++r)
28322 struct glyph *g = r->glyphs[TEXT_AREA];
28323 struct glyph *e = g + r->used[TEXT_AREA];
28324 int gx;
28326 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
28327 if (EQ (g->object, object))
28329 if (g->charpos == pos)
28331 best_glyph = g;
28332 best_x = gx;
28333 best_row = r;
28334 goto found;
28336 else if (best_glyph == NULL
28337 || ((eabs (g->charpos - pos)
28338 < eabs (best_glyph->charpos - pos))
28339 && (right_p
28340 ? g->charpos < pos
28341 : g->charpos > pos)))
28343 best_glyph = g;
28344 best_x = gx;
28345 best_row = r;
28350 found:
28352 if (best_glyph)
28354 *x = best_x;
28355 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
28357 if (right_p)
28359 *x += best_glyph->pixel_width;
28360 ++*hpos;
28363 *y = best_row->y;
28364 *vpos = MATRIX_ROW_VPOS (best_row, w->current_matrix);
28367 return best_glyph != NULL;
28369 #endif /* not used */
28371 /* Find the positions of the first and the last glyphs in window W's
28372 current matrix that occlude positions [STARTPOS..ENDPOS) in OBJECT
28373 (assumed to be a string), and return in HLINFO's mouse_face_*
28374 members the pixel and column/row coordinates of those glyphs. */
28376 static void
28377 mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
28378 Lisp_Object object,
28379 ptrdiff_t startpos, ptrdiff_t endpos)
28381 int yb = window_text_bottom_y (w);
28382 struct glyph_row *r;
28383 struct glyph *g, *e;
28384 int gx;
28385 int found = 0;
28387 /* Find the glyph row with at least one position in the range
28388 [STARTPOS..ENDPOS), and the first glyph in that row whose
28389 position belongs to that range. */
28390 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
28391 r->enabled_p && r->y < yb;
28392 ++r)
28394 if (!r->reversed_p)
28396 g = r->glyphs[TEXT_AREA];
28397 e = g + r->used[TEXT_AREA];
28398 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
28399 if (EQ (g->object, object)
28400 && startpos <= g->charpos && g->charpos < endpos)
28402 hlinfo->mouse_face_beg_row
28403 = MATRIX_ROW_VPOS (r, w->current_matrix);
28404 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
28405 hlinfo->mouse_face_beg_x = gx;
28406 found = 1;
28407 break;
28410 else
28412 struct glyph *g1;
28414 e = r->glyphs[TEXT_AREA];
28415 g = e + r->used[TEXT_AREA];
28416 for ( ; g > e; --g)
28417 if (EQ ((g-1)->object, object)
28418 && startpos <= (g-1)->charpos && (g-1)->charpos < endpos)
28420 hlinfo->mouse_face_beg_row
28421 = MATRIX_ROW_VPOS (r, w->current_matrix);
28422 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
28423 for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
28424 gx += g1->pixel_width;
28425 hlinfo->mouse_face_beg_x = gx;
28426 found = 1;
28427 break;
28430 if (found)
28431 break;
28434 if (!found)
28435 return;
28437 /* Starting with the next row, look for the first row which does NOT
28438 include any glyphs whose positions are in the range. */
28439 for (++r; r->enabled_p && r->y < yb; ++r)
28441 g = r->glyphs[TEXT_AREA];
28442 e = g + r->used[TEXT_AREA];
28443 found = 0;
28444 for ( ; g < e; ++g)
28445 if (EQ (g->object, object)
28446 && startpos <= g->charpos && g->charpos < endpos)
28448 found = 1;
28449 break;
28451 if (!found)
28452 break;
28455 /* The highlighted region ends on the previous row. */
28456 r--;
28458 /* Set the end row. */
28459 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r, w->current_matrix);
28461 /* Compute and set the end column and the end column's horizontal
28462 pixel coordinate. */
28463 if (!r->reversed_p)
28465 g = r->glyphs[TEXT_AREA];
28466 e = g + r->used[TEXT_AREA];
28467 for ( ; e > g; --e)
28468 if (EQ ((e-1)->object, object)
28469 && startpos <= (e-1)->charpos && (e-1)->charpos < endpos)
28470 break;
28471 hlinfo->mouse_face_end_col = e - g;
28473 for (gx = r->x; g < e; ++g)
28474 gx += g->pixel_width;
28475 hlinfo->mouse_face_end_x = gx;
28477 else
28479 e = r->glyphs[TEXT_AREA];
28480 g = e + r->used[TEXT_AREA];
28481 for (gx = r->x ; e < g; ++e)
28483 if (EQ (e->object, object)
28484 && startpos <= e->charpos && e->charpos < endpos)
28485 break;
28486 gx += e->pixel_width;
28488 hlinfo->mouse_face_end_col = e - r->glyphs[TEXT_AREA];
28489 hlinfo->mouse_face_end_x = gx;
28493 #ifdef HAVE_WINDOW_SYSTEM
28495 /* See if position X, Y is within a hot-spot of an image. */
28497 static int
28498 on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
28500 if (!CONSP (hot_spot))
28501 return 0;
28503 if (EQ (XCAR (hot_spot), Qrect))
28505 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
28506 Lisp_Object rect = XCDR (hot_spot);
28507 Lisp_Object tem;
28508 if (!CONSP (rect))
28509 return 0;
28510 if (!CONSP (XCAR (rect)))
28511 return 0;
28512 if (!CONSP (XCDR (rect)))
28513 return 0;
28514 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
28515 return 0;
28516 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
28517 return 0;
28518 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
28519 return 0;
28520 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
28521 return 0;
28522 return 1;
28524 else if (EQ (XCAR (hot_spot), Qcircle))
28526 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
28527 Lisp_Object circ = XCDR (hot_spot);
28528 Lisp_Object lr, lx0, ly0;
28529 if (CONSP (circ)
28530 && CONSP (XCAR (circ))
28531 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
28532 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
28533 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
28535 double r = XFLOATINT (lr);
28536 double dx = XINT (lx0) - x;
28537 double dy = XINT (ly0) - y;
28538 return (dx * dx + dy * dy <= r * r);
28541 else if (EQ (XCAR (hot_spot), Qpoly))
28543 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
28544 if (VECTORP (XCDR (hot_spot)))
28546 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
28547 Lisp_Object *poly = v->contents;
28548 ptrdiff_t n = v->header.size;
28549 ptrdiff_t i;
28550 int inside = 0;
28551 Lisp_Object lx, ly;
28552 int x0, y0;
28554 /* Need an even number of coordinates, and at least 3 edges. */
28555 if (n < 6 || n & 1)
28556 return 0;
28558 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
28559 If count is odd, we are inside polygon. Pixels on edges
28560 may or may not be included depending on actual geometry of the
28561 polygon. */
28562 if ((lx = poly[n-2], !INTEGERP (lx))
28563 || (ly = poly[n-1], !INTEGERP (lx)))
28564 return 0;
28565 x0 = XINT (lx), y0 = XINT (ly);
28566 for (i = 0; i < n; i += 2)
28568 int x1 = x0, y1 = y0;
28569 if ((lx = poly[i], !INTEGERP (lx))
28570 || (ly = poly[i+1], !INTEGERP (ly)))
28571 return 0;
28572 x0 = XINT (lx), y0 = XINT (ly);
28574 /* Does this segment cross the X line? */
28575 if (x0 >= x)
28577 if (x1 >= x)
28578 continue;
28580 else if (x1 < x)
28581 continue;
28582 if (y > y0 && y > y1)
28583 continue;
28584 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
28585 inside = !inside;
28587 return inside;
28590 return 0;
28593 Lisp_Object
28594 find_hot_spot (Lisp_Object map, int x, int y)
28596 while (CONSP (map))
28598 if (CONSP (XCAR (map))
28599 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
28600 return XCAR (map);
28601 map = XCDR (map);
28604 return Qnil;
28607 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
28608 3, 3, 0,
28609 doc: /* Lookup in image map MAP coordinates X and Y.
28610 An image map is an alist where each element has the format (AREA ID PLIST).
28611 An AREA is specified as either a rectangle, a circle, or a polygon:
28612 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
28613 pixel coordinates of the upper left and bottom right corners.
28614 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
28615 and the radius of the circle; r may be a float or integer.
28616 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
28617 vector describes one corner in the polygon.
28618 Returns the alist element for the first matching AREA in MAP. */)
28619 (Lisp_Object map, Lisp_Object x, Lisp_Object y)
28621 if (NILP (map))
28622 return Qnil;
28624 CHECK_NUMBER (x);
28625 CHECK_NUMBER (y);
28627 return find_hot_spot (map,
28628 clip_to_bounds (INT_MIN, XINT (x), INT_MAX),
28629 clip_to_bounds (INT_MIN, XINT (y), INT_MAX));
28633 /* Display frame CURSOR, optionally using shape defined by POINTER. */
28634 static void
28635 define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
28637 /* Do not change cursor shape while dragging mouse. */
28638 if (!NILP (do_mouse_tracking))
28639 return;
28641 if (!NILP (pointer))
28643 if (EQ (pointer, Qarrow))
28644 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
28645 else if (EQ (pointer, Qhand))
28646 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
28647 else if (EQ (pointer, Qtext))
28648 cursor = FRAME_X_OUTPUT (f)->text_cursor;
28649 else if (EQ (pointer, intern ("hdrag")))
28650 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
28651 else if (EQ (pointer, intern ("nhdrag")))
28652 cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
28653 #ifdef HAVE_X_WINDOWS
28654 else if (EQ (pointer, intern ("vdrag")))
28655 cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
28656 #endif
28657 else if (EQ (pointer, intern ("hourglass")))
28658 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
28659 else if (EQ (pointer, Qmodeline))
28660 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
28661 else
28662 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
28665 if (cursor != No_Cursor)
28666 FRAME_RIF (f)->define_frame_cursor (f, cursor);
28669 #endif /* HAVE_WINDOW_SYSTEM */
28671 /* Take proper action when mouse has moved to the mode or header line
28672 or marginal area AREA of window W, x-position X and y-position Y.
28673 X is relative to the start of the text display area of W, so the
28674 width of bitmap areas and scroll bars must be subtracted to get a
28675 position relative to the start of the mode line. */
28677 static void
28678 note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
28679 enum window_part area)
28681 struct window *w = XWINDOW (window);
28682 struct frame *f = XFRAME (w->frame);
28683 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
28684 #ifdef HAVE_WINDOW_SYSTEM
28685 Display_Info *dpyinfo;
28686 #endif
28687 Cursor cursor = No_Cursor;
28688 Lisp_Object pointer = Qnil;
28689 int dx, dy, width, height;
28690 ptrdiff_t charpos;
28691 Lisp_Object string, object = Qnil;
28692 Lisp_Object pos IF_LINT (= Qnil), help;
28694 Lisp_Object mouse_face;
28695 int original_x_pixel = x;
28696 struct glyph * glyph = NULL, * row_start_glyph = NULL;
28697 struct glyph_row *row IF_LINT (= 0);
28699 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
28701 int x0;
28702 struct glyph *end;
28704 /* Kludge alert: mode_line_string takes X/Y in pixels, but
28705 returns them in row/column units! */
28706 string = mode_line_string (w, area, &x, &y, &charpos,
28707 &object, &dx, &dy, &width, &height);
28709 row = (area == ON_MODE_LINE
28710 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
28711 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
28713 /* Find the glyph under the mouse pointer. */
28714 if (row->mode_line_p && row->enabled_p)
28716 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
28717 end = glyph + row->used[TEXT_AREA];
28719 for (x0 = original_x_pixel;
28720 glyph < end && x0 >= glyph->pixel_width;
28721 ++glyph)
28722 x0 -= glyph->pixel_width;
28724 if (glyph >= end)
28725 glyph = NULL;
28728 else
28730 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
28731 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
28732 returns them in row/column units! */
28733 string = marginal_area_string (w, area, &x, &y, &charpos,
28734 &object, &dx, &dy, &width, &height);
28737 help = Qnil;
28739 #ifdef HAVE_WINDOW_SYSTEM
28740 if (IMAGEP (object))
28742 Lisp_Object image_map, hotspot;
28743 if ((image_map = Fplist_get (XCDR (object), QCmap),
28744 !NILP (image_map))
28745 && (hotspot = find_hot_spot (image_map, dx, dy),
28746 CONSP (hotspot))
28747 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
28749 Lisp_Object plist;
28751 /* Could check XCAR (hotspot) to see if we enter/leave this hot-spot.
28752 If so, we could look for mouse-enter, mouse-leave
28753 properties in PLIST (and do something...). */
28754 hotspot = XCDR (hotspot);
28755 if (CONSP (hotspot)
28756 && (plist = XCAR (hotspot), CONSP (plist)))
28758 pointer = Fplist_get (plist, Qpointer);
28759 if (NILP (pointer))
28760 pointer = Qhand;
28761 help = Fplist_get (plist, Qhelp_echo);
28762 if (!NILP (help))
28764 help_echo_string = help;
28765 XSETWINDOW (help_echo_window, w);
28766 help_echo_object = w->contents;
28767 help_echo_pos = charpos;
28771 if (NILP (pointer))
28772 pointer = Fplist_get (XCDR (object), QCpointer);
28774 #endif /* HAVE_WINDOW_SYSTEM */
28776 if (STRINGP (string))
28777 pos = make_number (charpos);
28779 /* Set the help text and mouse pointer. If the mouse is on a part
28780 of the mode line without any text (e.g. past the right edge of
28781 the mode line text), use the default help text and pointer. */
28782 if (STRINGP (string) || area == ON_MODE_LINE)
28784 /* Arrange to display the help by setting the global variables
28785 help_echo_string, help_echo_object, and help_echo_pos. */
28786 if (NILP (help))
28788 if (STRINGP (string))
28789 help = Fget_text_property (pos, Qhelp_echo, string);
28791 if (!NILP (help))
28793 help_echo_string = help;
28794 XSETWINDOW (help_echo_window, w);
28795 help_echo_object = string;
28796 help_echo_pos = charpos;
28798 else if (area == ON_MODE_LINE)
28800 Lisp_Object default_help
28801 = buffer_local_value (Qmode_line_default_help_echo,
28802 w->contents);
28804 if (STRINGP (default_help))
28806 help_echo_string = default_help;
28807 XSETWINDOW (help_echo_window, w);
28808 help_echo_object = Qnil;
28809 help_echo_pos = -1;
28814 #ifdef HAVE_WINDOW_SYSTEM
28815 /* Change the mouse pointer according to what is under it. */
28816 if (FRAME_WINDOW_P (f))
28818 bool draggable = (! WINDOW_BOTTOMMOST_P (w)
28819 || minibuf_level
28820 || NILP (Vresize_mini_windows));
28822 dpyinfo = FRAME_DISPLAY_INFO (f);
28823 if (STRINGP (string))
28825 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
28827 if (NILP (pointer))
28828 pointer = Fget_text_property (pos, Qpointer, string);
28830 /* Change the mouse pointer according to what is under X/Y. */
28831 if (NILP (pointer)
28832 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
28834 Lisp_Object map;
28835 map = Fget_text_property (pos, Qlocal_map, string);
28836 if (!KEYMAPP (map))
28837 map = Fget_text_property (pos, Qkeymap, string);
28838 if (!KEYMAPP (map) && draggable)
28839 cursor = dpyinfo->vertical_scroll_bar_cursor;
28842 else if (draggable)
28843 /* Default mode-line pointer. */
28844 cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
28846 #endif
28849 /* Change the mouse face according to what is under X/Y. */
28850 if (STRINGP (string))
28852 mouse_face = Fget_text_property (pos, Qmouse_face, string);
28853 if (!NILP (Vmouse_highlight) && !NILP (mouse_face)
28854 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
28855 && glyph)
28857 Lisp_Object b, e;
28859 struct glyph * tmp_glyph;
28861 int gpos;
28862 int gseq_length;
28863 int total_pixel_width;
28864 ptrdiff_t begpos, endpos, ignore;
28866 int vpos, hpos;
28868 b = Fprevious_single_property_change (make_number (charpos + 1),
28869 Qmouse_face, string, Qnil);
28870 if (NILP (b))
28871 begpos = 0;
28872 else
28873 begpos = XINT (b);
28875 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
28876 if (NILP (e))
28877 endpos = SCHARS (string);
28878 else
28879 endpos = XINT (e);
28881 /* Calculate the glyph position GPOS of GLYPH in the
28882 displayed string, relative to the beginning of the
28883 highlighted part of the string.
28885 Note: GPOS is different from CHARPOS. CHARPOS is the
28886 position of GLYPH in the internal string object. A mode
28887 line string format has structures which are converted to
28888 a flattened string by the Emacs Lisp interpreter. The
28889 internal string is an element of those structures. The
28890 displayed string is the flattened string. */
28891 tmp_glyph = row_start_glyph;
28892 while (tmp_glyph < glyph
28893 && (!(EQ (tmp_glyph->object, glyph->object)
28894 && begpos <= tmp_glyph->charpos
28895 && tmp_glyph->charpos < endpos)))
28896 tmp_glyph++;
28897 gpos = glyph - tmp_glyph;
28899 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
28900 the highlighted part of the displayed string to which
28901 GLYPH belongs. Note: GSEQ_LENGTH is different from
28902 SCHARS (STRING), because the latter returns the length of
28903 the internal string. */
28904 for (tmp_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
28905 tmp_glyph > glyph
28906 && (!(EQ (tmp_glyph->object, glyph->object)
28907 && begpos <= tmp_glyph->charpos
28908 && tmp_glyph->charpos < endpos));
28909 tmp_glyph--)
28911 gseq_length = gpos + (tmp_glyph - glyph) + 1;
28913 /* Calculate the total pixel width of all the glyphs between
28914 the beginning of the highlighted area and GLYPH. */
28915 total_pixel_width = 0;
28916 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
28917 total_pixel_width += tmp_glyph->pixel_width;
28919 /* Pre calculation of re-rendering position. Note: X is in
28920 column units here, after the call to mode_line_string or
28921 marginal_area_string. */
28922 hpos = x - gpos;
28923 vpos = (area == ON_MODE_LINE
28924 ? (w->current_matrix)->nrows - 1
28925 : 0);
28927 /* If GLYPH's position is included in the region that is
28928 already drawn in mouse face, we have nothing to do. */
28929 if ( EQ (window, hlinfo->mouse_face_window)
28930 && (!row->reversed_p
28931 ? (hlinfo->mouse_face_beg_col <= hpos
28932 && hpos < hlinfo->mouse_face_end_col)
28933 /* In R2L rows we swap BEG and END, see below. */
28934 : (hlinfo->mouse_face_end_col <= hpos
28935 && hpos < hlinfo->mouse_face_beg_col))
28936 && hlinfo->mouse_face_beg_row == vpos )
28937 return;
28939 if (clear_mouse_face (hlinfo))
28940 cursor = No_Cursor;
28942 if (!row->reversed_p)
28944 hlinfo->mouse_face_beg_col = hpos;
28945 hlinfo->mouse_face_beg_x = original_x_pixel
28946 - (total_pixel_width + dx);
28947 hlinfo->mouse_face_end_col = hpos + gseq_length;
28948 hlinfo->mouse_face_end_x = 0;
28950 else
28952 /* In R2L rows, show_mouse_face expects BEG and END
28953 coordinates to be swapped. */
28954 hlinfo->mouse_face_end_col = hpos;
28955 hlinfo->mouse_face_end_x = original_x_pixel
28956 - (total_pixel_width + dx);
28957 hlinfo->mouse_face_beg_col = hpos + gseq_length;
28958 hlinfo->mouse_face_beg_x = 0;
28961 hlinfo->mouse_face_beg_row = vpos;
28962 hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row;
28963 hlinfo->mouse_face_past_end = 0;
28964 hlinfo->mouse_face_window = window;
28966 hlinfo->mouse_face_face_id = face_at_string_position (w, string,
28967 charpos,
28968 0, &ignore,
28969 glyph->face_id,
28971 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
28973 if (NILP (pointer))
28974 pointer = Qhand;
28976 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
28977 clear_mouse_face (hlinfo);
28979 #ifdef HAVE_WINDOW_SYSTEM
28980 if (FRAME_WINDOW_P (f))
28981 define_frame_cursor1 (f, cursor, pointer);
28982 #endif
28986 /* EXPORT:
28987 Take proper action when the mouse has moved to position X, Y on
28988 frame F with regards to highlighting portions of display that have
28989 mouse-face properties. Also de-highlight portions of display where
28990 the mouse was before, set the mouse pointer shape as appropriate
28991 for the mouse coordinates, and activate help echo (tooltips).
28992 X and Y can be negative or out of range. */
28994 void
28995 note_mouse_highlight (struct frame *f, int x, int y)
28997 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
28998 enum window_part part = ON_NOTHING;
28999 Lisp_Object window;
29000 struct window *w;
29001 Cursor cursor = No_Cursor;
29002 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
29003 struct buffer *b;
29005 /* When a menu is active, don't highlight because this looks odd. */
29006 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
29007 if (popup_activated ())
29008 return;
29009 #endif
29011 if (!f->glyphs_initialized_p
29012 || f->pointer_invisible)
29013 return;
29015 hlinfo->mouse_face_mouse_x = x;
29016 hlinfo->mouse_face_mouse_y = y;
29017 hlinfo->mouse_face_mouse_frame = f;
29019 if (hlinfo->mouse_face_defer)
29020 return;
29022 /* Which window is that in? */
29023 window = window_from_coordinates (f, x, y, &part, 1);
29025 /* If displaying active text in another window, clear that. */
29026 if (! EQ (window, hlinfo->mouse_face_window)
29027 /* Also clear if we move out of text area in same window. */
29028 || (!NILP (hlinfo->mouse_face_window)
29029 && !NILP (window)
29030 && part != ON_TEXT
29031 && part != ON_MODE_LINE
29032 && part != ON_HEADER_LINE))
29033 clear_mouse_face (hlinfo);
29035 /* Not on a window -> return. */
29036 if (!WINDOWP (window))
29037 return;
29039 /* Reset help_echo_string. It will get recomputed below. */
29040 help_echo_string = Qnil;
29042 /* Convert to window-relative pixel coordinates. */
29043 w = XWINDOW (window);
29044 frame_to_window_pixel_xy (w, &x, &y);
29046 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
29047 /* Handle tool-bar window differently since it doesn't display a
29048 buffer. */
29049 if (EQ (window, f->tool_bar_window))
29051 note_tool_bar_highlight (f, x, y);
29052 return;
29054 #endif
29056 /* Mouse is on the mode, header line or margin? */
29057 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
29058 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
29060 note_mode_line_or_margin_highlight (window, x, y, part);
29062 #ifdef HAVE_WINDOW_SYSTEM
29063 if (part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
29065 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
29066 /* Show non-text cursor (Bug#16647). */
29067 goto set_cursor;
29069 else
29070 #endif
29071 return;
29074 #ifdef HAVE_WINDOW_SYSTEM
29075 if (part == ON_VERTICAL_BORDER)
29077 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
29078 help_echo_string = build_string ("drag-mouse-1: resize");
29080 else if (part == ON_RIGHT_DIVIDER)
29082 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
29083 help_echo_string = build_string ("drag-mouse-1: resize");
29085 else if (part == ON_BOTTOM_DIVIDER)
29086 if (! WINDOW_BOTTOMMOST_P (w)
29087 || minibuf_level
29088 || NILP (Vresize_mini_windows))
29090 cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
29091 help_echo_string = build_string ("drag-mouse-1: resize");
29093 else
29094 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
29095 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
29096 || part == ON_VERTICAL_SCROLL_BAR
29097 || part == ON_HORIZONTAL_SCROLL_BAR)
29098 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
29099 else
29100 cursor = FRAME_X_OUTPUT (f)->text_cursor;
29101 #endif
29103 /* Are we in a window whose display is up to date?
29104 And verify the buffer's text has not changed. */
29105 b = XBUFFER (w->contents);
29106 if (part == ON_TEXT && w->window_end_valid && !window_outdated (w))
29108 int hpos, vpos, dx, dy, area = LAST_AREA;
29109 ptrdiff_t pos;
29110 struct glyph *glyph;
29111 Lisp_Object object;
29112 Lisp_Object mouse_face = Qnil, position;
29113 Lisp_Object *overlay_vec = NULL;
29114 ptrdiff_t i, noverlays;
29115 struct buffer *obuf;
29116 ptrdiff_t obegv, ozv;
29117 int same_region;
29119 /* Find the glyph under X/Y. */
29120 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
29122 #ifdef HAVE_WINDOW_SYSTEM
29123 /* Look for :pointer property on image. */
29124 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
29126 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
29127 if (img != NULL && IMAGEP (img->spec))
29129 Lisp_Object image_map, hotspot;
29130 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
29131 !NILP (image_map))
29132 && (hotspot = find_hot_spot (image_map,
29133 glyph->slice.img.x + dx,
29134 glyph->slice.img.y + dy),
29135 CONSP (hotspot))
29136 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
29138 Lisp_Object plist;
29140 /* Could check XCAR (hotspot) to see if we enter/leave
29141 this hot-spot.
29142 If so, we could look for mouse-enter, mouse-leave
29143 properties in PLIST (and do something...). */
29144 hotspot = XCDR (hotspot);
29145 if (CONSP (hotspot)
29146 && (plist = XCAR (hotspot), CONSP (plist)))
29148 pointer = Fplist_get (plist, Qpointer);
29149 if (NILP (pointer))
29150 pointer = Qhand;
29151 help_echo_string = Fplist_get (plist, Qhelp_echo);
29152 if (!NILP (help_echo_string))
29154 help_echo_window = window;
29155 help_echo_object = glyph->object;
29156 help_echo_pos = glyph->charpos;
29160 if (NILP (pointer))
29161 pointer = Fplist_get (XCDR (img->spec), QCpointer);
29164 #endif /* HAVE_WINDOW_SYSTEM */
29166 /* Clear mouse face if X/Y not over text. */
29167 if (glyph == NULL
29168 || area != TEXT_AREA
29169 || !MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->current_matrix, vpos))
29170 /* Glyph's OBJECT is an integer for glyphs inserted by the
29171 display engine for its internal purposes, like truncation
29172 and continuation glyphs and blanks beyond the end of
29173 line's text on text terminals. If we are over such a
29174 glyph, we are not over any text. */
29175 || INTEGERP (glyph->object)
29176 /* R2L rows have a stretch glyph at their front, which
29177 stands for no text, whereas L2R rows have no glyphs at
29178 all beyond the end of text. Treat such stretch glyphs
29179 like we do with NULL glyphs in L2R rows. */
29180 || (MATRIX_ROW (w->current_matrix, vpos)->reversed_p
29181 && glyph == MATRIX_ROW_GLYPH_START (w->current_matrix, vpos)
29182 && glyph->type == STRETCH_GLYPH
29183 && glyph->avoid_cursor_p))
29185 if (clear_mouse_face (hlinfo))
29186 cursor = No_Cursor;
29187 #ifdef HAVE_WINDOW_SYSTEM
29188 if (FRAME_WINDOW_P (f) && NILP (pointer))
29190 if (area != TEXT_AREA)
29191 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
29192 else
29193 pointer = Vvoid_text_area_pointer;
29195 #endif
29196 goto set_cursor;
29199 pos = glyph->charpos;
29200 object = glyph->object;
29201 if (!STRINGP (object) && !BUFFERP (object))
29202 goto set_cursor;
29204 /* If we get an out-of-range value, return now; avoid an error. */
29205 if (BUFFERP (object) && pos > BUF_Z (b))
29206 goto set_cursor;
29208 /* Make the window's buffer temporarily current for
29209 overlays_at and compute_char_face. */
29210 obuf = current_buffer;
29211 current_buffer = b;
29212 obegv = BEGV;
29213 ozv = ZV;
29214 BEGV = BEG;
29215 ZV = Z;
29217 /* Is this char mouse-active or does it have help-echo? */
29218 position = make_number (pos);
29220 if (BUFFERP (object))
29222 /* Put all the overlays we want in a vector in overlay_vec. */
29223 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
29224 /* Sort overlays into increasing priority order. */
29225 noverlays = sort_overlays (overlay_vec, noverlays, w);
29227 else
29228 noverlays = 0;
29230 if (NILP (Vmouse_highlight))
29232 clear_mouse_face (hlinfo);
29233 goto check_help_echo;
29236 same_region = coords_in_mouse_face_p (w, hpos, vpos);
29238 if (same_region)
29239 cursor = No_Cursor;
29241 /* Check mouse-face highlighting. */
29242 if (! same_region
29243 /* If there exists an overlay with mouse-face overlapping
29244 the one we are currently highlighting, we have to
29245 check if we enter the overlapping overlay, and then
29246 highlight only that. */
29247 || (OVERLAYP (hlinfo->mouse_face_overlay)
29248 && mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
29250 /* Find the highest priority overlay with a mouse-face. */
29251 Lisp_Object overlay = Qnil;
29252 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
29254 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
29255 if (!NILP (mouse_face))
29256 overlay = overlay_vec[i];
29259 /* If we're highlighting the same overlay as before, there's
29260 no need to do that again. */
29261 if (!NILP (overlay) && EQ (overlay, hlinfo->mouse_face_overlay))
29262 goto check_help_echo;
29263 hlinfo->mouse_face_overlay = overlay;
29265 /* Clear the display of the old active region, if any. */
29266 if (clear_mouse_face (hlinfo))
29267 cursor = No_Cursor;
29269 /* If no overlay applies, get a text property. */
29270 if (NILP (overlay))
29271 mouse_face = Fget_text_property (position, Qmouse_face, object);
29273 /* Next, compute the bounds of the mouse highlighting and
29274 display it. */
29275 if (!NILP (mouse_face) && STRINGP (object))
29277 /* The mouse-highlighting comes from a display string
29278 with a mouse-face. */
29279 Lisp_Object s, e;
29280 ptrdiff_t ignore;
29282 s = Fprevious_single_property_change
29283 (make_number (pos + 1), Qmouse_face, object, Qnil);
29284 e = Fnext_single_property_change
29285 (position, Qmouse_face, object, Qnil);
29286 if (NILP (s))
29287 s = make_number (0);
29288 if (NILP (e))
29289 e = make_number (SCHARS (object));
29290 mouse_face_from_string_pos (w, hlinfo, object,
29291 XINT (s), XINT (e));
29292 hlinfo->mouse_face_past_end = 0;
29293 hlinfo->mouse_face_window = window;
29294 hlinfo->mouse_face_face_id
29295 = face_at_string_position (w, object, pos, 0, &ignore,
29296 glyph->face_id, 1);
29297 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
29298 cursor = No_Cursor;
29300 else
29302 /* The mouse-highlighting, if any, comes from an overlay
29303 or text property in the buffer. */
29304 Lisp_Object buffer IF_LINT (= Qnil);
29305 Lisp_Object disp_string IF_LINT (= Qnil);
29307 if (STRINGP (object))
29309 /* If we are on a display string with no mouse-face,
29310 check if the text under it has one. */
29311 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
29312 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
29313 pos = string_buffer_position (object, start);
29314 if (pos > 0)
29316 mouse_face = get_char_property_and_overlay
29317 (make_number (pos), Qmouse_face, w->contents, &overlay);
29318 buffer = w->contents;
29319 disp_string = object;
29322 else
29324 buffer = object;
29325 disp_string = Qnil;
29328 if (!NILP (mouse_face))
29330 Lisp_Object before, after;
29331 Lisp_Object before_string, after_string;
29332 /* To correctly find the limits of mouse highlight
29333 in a bidi-reordered buffer, we must not use the
29334 optimization of limiting the search in
29335 previous-single-property-change and
29336 next-single-property-change, because
29337 rows_from_pos_range needs the real start and end
29338 positions to DTRT in this case. That's because
29339 the first row visible in a window does not
29340 necessarily display the character whose position
29341 is the smallest. */
29342 Lisp_Object lim1
29343 = NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
29344 ? Fmarker_position (w->start)
29345 : Qnil;
29346 Lisp_Object lim2
29347 = NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
29348 ? make_number (BUF_Z (XBUFFER (buffer))
29349 - w->window_end_pos)
29350 : Qnil;
29352 if (NILP (overlay))
29354 /* Handle the text property case. */
29355 before = Fprevious_single_property_change
29356 (make_number (pos + 1), Qmouse_face, buffer, lim1);
29357 after = Fnext_single_property_change
29358 (make_number (pos), Qmouse_face, buffer, lim2);
29359 before_string = after_string = Qnil;
29361 else
29363 /* Handle the overlay case. */
29364 before = Foverlay_start (overlay);
29365 after = Foverlay_end (overlay);
29366 before_string = Foverlay_get (overlay, Qbefore_string);
29367 after_string = Foverlay_get (overlay, Qafter_string);
29369 if (!STRINGP (before_string)) before_string = Qnil;
29370 if (!STRINGP (after_string)) after_string = Qnil;
29373 mouse_face_from_buffer_pos (window, hlinfo, pos,
29374 NILP (before)
29376 : XFASTINT (before),
29377 NILP (after)
29378 ? BUF_Z (XBUFFER (buffer))
29379 : XFASTINT (after),
29380 before_string, after_string,
29381 disp_string);
29382 cursor = No_Cursor;
29387 check_help_echo:
29389 /* Look for a `help-echo' property. */
29390 if (NILP (help_echo_string)) {
29391 Lisp_Object help, overlay;
29393 /* Check overlays first. */
29394 help = overlay = Qnil;
29395 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
29397 overlay = overlay_vec[i];
29398 help = Foverlay_get (overlay, Qhelp_echo);
29401 if (!NILP (help))
29403 help_echo_string = help;
29404 help_echo_window = window;
29405 help_echo_object = overlay;
29406 help_echo_pos = pos;
29408 else
29410 Lisp_Object obj = glyph->object;
29411 ptrdiff_t charpos = glyph->charpos;
29413 /* Try text properties. */
29414 if (STRINGP (obj)
29415 && charpos >= 0
29416 && charpos < SCHARS (obj))
29418 help = Fget_text_property (make_number (charpos),
29419 Qhelp_echo, obj);
29420 if (NILP (help))
29422 /* If the string itself doesn't specify a help-echo,
29423 see if the buffer text ``under'' it does. */
29424 struct glyph_row *r
29425 = MATRIX_ROW (w->current_matrix, vpos);
29426 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
29427 ptrdiff_t p = string_buffer_position (obj, start);
29428 if (p > 0)
29430 help = Fget_char_property (make_number (p),
29431 Qhelp_echo, w->contents);
29432 if (!NILP (help))
29434 charpos = p;
29435 obj = w->contents;
29440 else if (BUFFERP (obj)
29441 && charpos >= BEGV
29442 && charpos < ZV)
29443 help = Fget_text_property (make_number (charpos), Qhelp_echo,
29444 obj);
29446 if (!NILP (help))
29448 help_echo_string = help;
29449 help_echo_window = window;
29450 help_echo_object = obj;
29451 help_echo_pos = charpos;
29456 #ifdef HAVE_WINDOW_SYSTEM
29457 /* Look for a `pointer' property. */
29458 if (FRAME_WINDOW_P (f) && NILP (pointer))
29460 /* Check overlays first. */
29461 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
29462 pointer = Foverlay_get (overlay_vec[i], Qpointer);
29464 if (NILP (pointer))
29466 Lisp_Object obj = glyph->object;
29467 ptrdiff_t charpos = glyph->charpos;
29469 /* Try text properties. */
29470 if (STRINGP (obj)
29471 && charpos >= 0
29472 && charpos < SCHARS (obj))
29474 pointer = Fget_text_property (make_number (charpos),
29475 Qpointer, obj);
29476 if (NILP (pointer))
29478 /* If the string itself doesn't specify a pointer,
29479 see if the buffer text ``under'' it does. */
29480 struct glyph_row *r
29481 = MATRIX_ROW (w->current_matrix, vpos);
29482 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
29483 ptrdiff_t p = string_buffer_position (obj, start);
29484 if (p > 0)
29485 pointer = Fget_char_property (make_number (p),
29486 Qpointer, w->contents);
29489 else if (BUFFERP (obj)
29490 && charpos >= BEGV
29491 && charpos < ZV)
29492 pointer = Fget_text_property (make_number (charpos),
29493 Qpointer, obj);
29496 #endif /* HAVE_WINDOW_SYSTEM */
29498 BEGV = obegv;
29499 ZV = ozv;
29500 current_buffer = obuf;
29503 set_cursor:
29505 #ifdef HAVE_WINDOW_SYSTEM
29506 if (FRAME_WINDOW_P (f))
29507 define_frame_cursor1 (f, cursor, pointer);
29508 #else
29509 /* This is here to prevent a compiler error, about "label at end of
29510 compound statement". */
29511 return;
29512 #endif
29516 /* EXPORT for RIF:
29517 Clear any mouse-face on window W. This function is part of the
29518 redisplay interface, and is called from try_window_id and similar
29519 functions to ensure the mouse-highlight is off. */
29521 void
29522 x_clear_window_mouse_face (struct window *w)
29524 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
29525 Lisp_Object window;
29527 block_input ();
29528 XSETWINDOW (window, w);
29529 if (EQ (window, hlinfo->mouse_face_window))
29530 clear_mouse_face (hlinfo);
29531 unblock_input ();
29535 /* EXPORT:
29536 Just discard the mouse face information for frame F, if any.
29537 This is used when the size of F is changed. */
29539 void
29540 cancel_mouse_face (struct frame *f)
29542 Lisp_Object window;
29543 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
29545 window = hlinfo->mouse_face_window;
29546 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
29547 reset_mouse_highlight (hlinfo);
29552 /***********************************************************************
29553 Exposure Events
29554 ***********************************************************************/
29556 #ifdef HAVE_WINDOW_SYSTEM
29558 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
29559 which intersects rectangle R. R is in window-relative coordinates. */
29561 static void
29562 expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
29563 enum glyph_row_area area)
29565 struct glyph *first = row->glyphs[area];
29566 struct glyph *end = row->glyphs[area] + row->used[area];
29567 struct glyph *last;
29568 int first_x, start_x, x;
29570 if (area == TEXT_AREA && row->fill_line_p)
29571 /* If row extends face to end of line write the whole line. */
29572 draw_glyphs (w, 0, row, area,
29573 0, row->used[area],
29574 DRAW_NORMAL_TEXT, 0);
29575 else
29577 /* Set START_X to the window-relative start position for drawing glyphs of
29578 AREA. The first glyph of the text area can be partially visible.
29579 The first glyphs of other areas cannot. */
29580 start_x = window_box_left_offset (w, area);
29581 x = start_x;
29582 if (area == TEXT_AREA)
29583 x += row->x;
29585 /* Find the first glyph that must be redrawn. */
29586 while (first < end
29587 && x + first->pixel_width < r->x)
29589 x += first->pixel_width;
29590 ++first;
29593 /* Find the last one. */
29594 last = first;
29595 first_x = x;
29596 while (last < end
29597 && x < r->x + r->width)
29599 x += last->pixel_width;
29600 ++last;
29603 /* Repaint. */
29604 if (last > first)
29605 draw_glyphs (w, first_x - start_x, row, area,
29606 first - row->glyphs[area], last - row->glyphs[area],
29607 DRAW_NORMAL_TEXT, 0);
29612 /* Redraw the parts of the glyph row ROW on window W intersecting
29613 rectangle R. R is in window-relative coordinates. Value is
29614 non-zero if mouse-face was overwritten. */
29616 static int
29617 expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
29619 eassert (row->enabled_p);
29621 if (row->mode_line_p || w->pseudo_window_p)
29622 draw_glyphs (w, 0, row, TEXT_AREA,
29623 0, row->used[TEXT_AREA],
29624 DRAW_NORMAL_TEXT, 0);
29625 else
29627 if (row->used[LEFT_MARGIN_AREA])
29628 expose_area (w, row, r, LEFT_MARGIN_AREA);
29629 if (row->used[TEXT_AREA])
29630 expose_area (w, row, r, TEXT_AREA);
29631 if (row->used[RIGHT_MARGIN_AREA])
29632 expose_area (w, row, r, RIGHT_MARGIN_AREA);
29633 draw_row_fringe_bitmaps (w, row);
29636 return row->mouse_face_p;
29640 /* Redraw those parts of glyphs rows during expose event handling that
29641 overlap other rows. Redrawing of an exposed line writes over parts
29642 of lines overlapping that exposed line; this function fixes that.
29644 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
29645 row in W's current matrix that is exposed and overlaps other rows.
29646 LAST_OVERLAPPING_ROW is the last such row. */
29648 static void
29649 expose_overlaps (struct window *w,
29650 struct glyph_row *first_overlapping_row,
29651 struct glyph_row *last_overlapping_row,
29652 XRectangle *r)
29654 struct glyph_row *row;
29656 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
29657 if (row->overlapping_p)
29659 eassert (row->enabled_p && !row->mode_line_p);
29661 row->clip = r;
29662 if (row->used[LEFT_MARGIN_AREA])
29663 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
29665 if (row->used[TEXT_AREA])
29666 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
29668 if (row->used[RIGHT_MARGIN_AREA])
29669 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
29670 row->clip = NULL;
29675 /* Return non-zero if W's cursor intersects rectangle R. */
29677 static int
29678 phys_cursor_in_rect_p (struct window *w, XRectangle *r)
29680 XRectangle cr, result;
29681 struct glyph *cursor_glyph;
29682 struct glyph_row *row;
29684 if (w->phys_cursor.vpos >= 0
29685 && w->phys_cursor.vpos < w->current_matrix->nrows
29686 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
29687 row->enabled_p)
29688 && row->cursor_in_fringe_p)
29690 /* Cursor is in the fringe. */
29691 cr.x = window_box_right_offset (w,
29692 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
29693 ? RIGHT_MARGIN_AREA
29694 : TEXT_AREA));
29695 cr.y = row->y;
29696 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
29697 cr.height = row->height;
29698 return x_intersect_rectangles (&cr, r, &result);
29701 cursor_glyph = get_phys_cursor_glyph (w);
29702 if (cursor_glyph)
29704 /* r is relative to W's box, but w->phys_cursor.x is relative
29705 to left edge of W's TEXT area. Adjust it. */
29706 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
29707 cr.y = w->phys_cursor.y;
29708 cr.width = cursor_glyph->pixel_width;
29709 cr.height = w->phys_cursor_height;
29710 /* ++KFS: W32 version used W32-specific IntersectRect here, but
29711 I assume the effect is the same -- and this is portable. */
29712 return x_intersect_rectangles (&cr, r, &result);
29714 /* If we don't understand the format, pretend we're not in the hot-spot. */
29715 return 0;
29719 /* EXPORT:
29720 Draw a vertical window border to the right of window W if W doesn't
29721 have vertical scroll bars. */
29723 void
29724 x_draw_vertical_border (struct window *w)
29726 struct frame *f = XFRAME (WINDOW_FRAME (w));
29728 /* We could do better, if we knew what type of scroll-bar the adjacent
29729 windows (on either side) have... But we don't :-(
29730 However, I think this works ok. ++KFS 2003-04-25 */
29732 /* Redraw borders between horizontally adjacent windows. Don't
29733 do it for frames with vertical scroll bars because either the
29734 right scroll bar of a window, or the left scroll bar of its
29735 neighbor will suffice as a border. */
29736 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f) || FRAME_RIGHT_DIVIDER_WIDTH (f))
29737 return;
29739 /* Note: It is necessary to redraw both the left and the right
29740 borders, for when only this single window W is being
29741 redisplayed. */
29742 if (!WINDOW_RIGHTMOST_P (w)
29743 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
29745 int x0, x1, y0, y1;
29747 window_box_edges (w, &x0, &y0, &x1, &y1);
29748 y1 -= 1;
29750 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
29751 x1 -= 1;
29753 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
29756 if (!WINDOW_LEFTMOST_P (w)
29757 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
29759 int x0, x1, y0, y1;
29761 window_box_edges (w, &x0, &y0, &x1, &y1);
29762 y1 -= 1;
29764 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
29765 x0 -= 1;
29767 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
29772 /* Draw window dividers for window W. */
29774 void
29775 x_draw_right_divider (struct window *w)
29777 struct frame *f = WINDOW_XFRAME (w);
29779 if (w->mini || w->pseudo_window_p)
29780 return;
29781 else if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
29783 int x0 = WINDOW_RIGHT_EDGE_X (w) - WINDOW_RIGHT_DIVIDER_WIDTH (w);
29784 int x1 = WINDOW_RIGHT_EDGE_X (w);
29785 int y0 = WINDOW_TOP_EDGE_Y (w);
29786 /* The bottom divider prevails. */
29787 int y1 = WINDOW_BOTTOM_EDGE_Y (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
29789 FRAME_RIF (f)->draw_window_divider (w, x0, x1, y0, y1);
29793 static void
29794 x_draw_bottom_divider (struct window *w)
29796 struct frame *f = XFRAME (WINDOW_FRAME (w));
29798 if (w->mini || w->pseudo_window_p)
29799 return;
29800 else if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
29802 int x0 = WINDOW_LEFT_EDGE_X (w);
29803 int x1 = WINDOW_RIGHT_EDGE_X (w);
29804 int y0 = WINDOW_BOTTOM_EDGE_Y (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
29805 int y1 = WINDOW_BOTTOM_EDGE_Y (w);
29807 FRAME_RIF (f)->draw_window_divider (w, x0, x1, y0, y1);
29811 /* Redraw the part of window W intersection rectangle FR. Pixel
29812 coordinates in FR are frame-relative. Call this function with
29813 input blocked. Value is non-zero if the exposure overwrites
29814 mouse-face. */
29816 static int
29817 expose_window (struct window *w, XRectangle *fr)
29819 struct frame *f = XFRAME (w->frame);
29820 XRectangle wr, r;
29821 int mouse_face_overwritten_p = 0;
29823 /* If window is not yet fully initialized, do nothing. This can
29824 happen when toolkit scroll bars are used and a window is split.
29825 Reconfiguring the scroll bar will generate an expose for a newly
29826 created window. */
29827 if (w->current_matrix == NULL)
29828 return 0;
29830 /* When we're currently updating the window, display and current
29831 matrix usually don't agree. Arrange for a thorough display
29832 later. */
29833 if (w->must_be_updated_p)
29835 SET_FRAME_GARBAGED (f);
29836 return 0;
29839 /* Frame-relative pixel rectangle of W. */
29840 wr.x = WINDOW_LEFT_EDGE_X (w);
29841 wr.y = WINDOW_TOP_EDGE_Y (w);
29842 wr.width = WINDOW_PIXEL_WIDTH (w);
29843 wr.height = WINDOW_PIXEL_HEIGHT (w);
29845 if (x_intersect_rectangles (fr, &wr, &r))
29847 int yb = window_text_bottom_y (w);
29848 struct glyph_row *row;
29849 int cursor_cleared_p, phys_cursor_on_p;
29850 struct glyph_row *first_overlapping_row, *last_overlapping_row;
29852 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
29853 r.x, r.y, r.width, r.height));
29855 /* Convert to window coordinates. */
29856 r.x -= WINDOW_LEFT_EDGE_X (w);
29857 r.y -= WINDOW_TOP_EDGE_Y (w);
29859 /* Turn off the cursor. */
29860 if (!w->pseudo_window_p
29861 && phys_cursor_in_rect_p (w, &r))
29863 x_clear_cursor (w);
29864 cursor_cleared_p = 1;
29866 else
29867 cursor_cleared_p = 0;
29869 /* If the row containing the cursor extends face to end of line,
29870 then expose_area might overwrite the cursor outside the
29871 rectangle and thus notice_overwritten_cursor might clear
29872 w->phys_cursor_on_p. We remember the original value and
29873 check later if it is changed. */
29874 phys_cursor_on_p = w->phys_cursor_on_p;
29876 /* Update lines intersecting rectangle R. */
29877 first_overlapping_row = last_overlapping_row = NULL;
29878 for (row = w->current_matrix->rows;
29879 row->enabled_p;
29880 ++row)
29882 int y0 = row->y;
29883 int y1 = MATRIX_ROW_BOTTOM_Y (row);
29885 if ((y0 >= r.y && y0 < r.y + r.height)
29886 || (y1 > r.y && y1 < r.y + r.height)
29887 || (r.y >= y0 && r.y < y1)
29888 || (r.y + r.height > y0 && r.y + r.height < y1))
29890 /* A header line may be overlapping, but there is no need
29891 to fix overlapping areas for them. KFS 2005-02-12 */
29892 if (row->overlapping_p && !row->mode_line_p)
29894 if (first_overlapping_row == NULL)
29895 first_overlapping_row = row;
29896 last_overlapping_row = row;
29899 row->clip = fr;
29900 if (expose_line (w, row, &r))
29901 mouse_face_overwritten_p = 1;
29902 row->clip = NULL;
29904 else if (row->overlapping_p)
29906 /* We must redraw a row overlapping the exposed area. */
29907 if (y0 < r.y
29908 ? y0 + row->phys_height > r.y
29909 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
29911 if (first_overlapping_row == NULL)
29912 first_overlapping_row = row;
29913 last_overlapping_row = row;
29917 if (y1 >= yb)
29918 break;
29921 /* Display the mode line if there is one. */
29922 if (WINDOW_WANTS_MODELINE_P (w)
29923 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
29924 row->enabled_p)
29925 && row->y < r.y + r.height)
29927 if (expose_line (w, row, &r))
29928 mouse_face_overwritten_p = 1;
29931 if (!w->pseudo_window_p)
29933 /* Fix the display of overlapping rows. */
29934 if (first_overlapping_row)
29935 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
29936 fr);
29938 /* Draw border between windows. */
29939 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
29940 x_draw_right_divider (w);
29941 else
29942 x_draw_vertical_border (w);
29944 if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
29945 x_draw_bottom_divider (w);
29947 /* Turn the cursor on again. */
29948 if (cursor_cleared_p
29949 || (phys_cursor_on_p && !w->phys_cursor_on_p))
29950 update_window_cursor (w, 1);
29954 return mouse_face_overwritten_p;
29959 /* Redraw (parts) of all windows in the window tree rooted at W that
29960 intersect R. R contains frame pixel coordinates. Value is
29961 non-zero if the exposure overwrites mouse-face. */
29963 static int
29964 expose_window_tree (struct window *w, XRectangle *r)
29966 struct frame *f = XFRAME (w->frame);
29967 int mouse_face_overwritten_p = 0;
29969 while (w && !FRAME_GARBAGED_P (f))
29971 if (WINDOWP (w->contents))
29972 mouse_face_overwritten_p
29973 |= expose_window_tree (XWINDOW (w->contents), r);
29974 else
29975 mouse_face_overwritten_p |= expose_window (w, r);
29977 w = NILP (w->next) ? NULL : XWINDOW (w->next);
29980 return mouse_face_overwritten_p;
29984 /* EXPORT:
29985 Redisplay an exposed area of frame F. X and Y are the upper-left
29986 corner of the exposed rectangle. W and H are width and height of
29987 the exposed area. All are pixel values. W or H zero means redraw
29988 the entire frame. */
29990 void
29991 expose_frame (struct frame *f, int x, int y, int w, int h)
29993 XRectangle r;
29994 int mouse_face_overwritten_p = 0;
29996 TRACE ((stderr, "expose_frame "));
29998 /* No need to redraw if frame will be redrawn soon. */
29999 if (FRAME_GARBAGED_P (f))
30001 TRACE ((stderr, " garbaged\n"));
30002 return;
30005 /* If basic faces haven't been realized yet, there is no point in
30006 trying to redraw anything. This can happen when we get an expose
30007 event while Emacs is starting, e.g. by moving another window. */
30008 if (FRAME_FACE_CACHE (f) == NULL
30009 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
30011 TRACE ((stderr, " no faces\n"));
30012 return;
30015 if (w == 0 || h == 0)
30017 r.x = r.y = 0;
30018 r.width = FRAME_TEXT_WIDTH (f);
30019 r.height = FRAME_TEXT_HEIGHT (f);
30020 /** r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f); **/
30021 /** r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f); **/
30023 else
30025 r.x = x;
30026 r.y = y;
30027 r.width = w;
30028 r.height = h;
30031 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
30032 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
30034 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
30035 if (WINDOWP (f->tool_bar_window))
30036 mouse_face_overwritten_p
30037 |= expose_window (XWINDOW (f->tool_bar_window), &r);
30038 #endif
30040 #ifdef HAVE_X_WINDOWS
30041 #ifndef MSDOS
30042 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
30043 if (WINDOWP (f->menu_bar_window))
30044 mouse_face_overwritten_p
30045 |= expose_window (XWINDOW (f->menu_bar_window), &r);
30046 #endif /* not USE_X_TOOLKIT and not USE_GTK */
30047 #endif
30048 #endif
30050 /* Some window managers support a focus-follows-mouse style with
30051 delayed raising of frames. Imagine a partially obscured frame,
30052 and moving the mouse into partially obscured mouse-face on that
30053 frame. The visible part of the mouse-face will be highlighted,
30054 then the WM raises the obscured frame. With at least one WM, KDE
30055 2.1, Emacs is not getting any event for the raising of the frame
30056 (even tried with SubstructureRedirectMask), only Expose events.
30057 These expose events will draw text normally, i.e. not
30058 highlighted. Which means we must redo the highlight here.
30059 Subsume it under ``we love X''. --gerd 2001-08-15 */
30060 /* Included in Windows version because Windows most likely does not
30061 do the right thing if any third party tool offers
30062 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
30063 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
30065 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
30066 if (f == hlinfo->mouse_face_mouse_frame)
30068 int mouse_x = hlinfo->mouse_face_mouse_x;
30069 int mouse_y = hlinfo->mouse_face_mouse_y;
30070 clear_mouse_face (hlinfo);
30071 note_mouse_highlight (f, mouse_x, mouse_y);
30077 /* EXPORT:
30078 Determine the intersection of two rectangles R1 and R2. Return
30079 the intersection in *RESULT. Value is non-zero if RESULT is not
30080 empty. */
30083 x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
30085 XRectangle *left, *right;
30086 XRectangle *upper, *lower;
30087 int intersection_p = 0;
30089 /* Rearrange so that R1 is the left-most rectangle. */
30090 if (r1->x < r2->x)
30091 left = r1, right = r2;
30092 else
30093 left = r2, right = r1;
30095 /* X0 of the intersection is right.x0, if this is inside R1,
30096 otherwise there is no intersection. */
30097 if (right->x <= left->x + left->width)
30099 result->x = right->x;
30101 /* The right end of the intersection is the minimum of
30102 the right ends of left and right. */
30103 result->width = (min (left->x + left->width, right->x + right->width)
30104 - result->x);
30106 /* Same game for Y. */
30107 if (r1->y < r2->y)
30108 upper = r1, lower = r2;
30109 else
30110 upper = r2, lower = r1;
30112 /* The upper end of the intersection is lower.y0, if this is inside
30113 of upper. Otherwise, there is no intersection. */
30114 if (lower->y <= upper->y + upper->height)
30116 result->y = lower->y;
30118 /* The lower end of the intersection is the minimum of the lower
30119 ends of upper and lower. */
30120 result->height = (min (lower->y + lower->height,
30121 upper->y + upper->height)
30122 - result->y);
30123 intersection_p = 1;
30127 return intersection_p;
30130 #endif /* HAVE_WINDOW_SYSTEM */
30133 /***********************************************************************
30134 Initialization
30135 ***********************************************************************/
30137 void
30138 syms_of_xdisp (void)
30140 Vwith_echo_area_save_vector = Qnil;
30141 staticpro (&Vwith_echo_area_save_vector);
30143 Vmessage_stack = Qnil;
30144 staticpro (&Vmessage_stack);
30146 DEFSYM (Qinhibit_redisplay, "inhibit-redisplay");
30147 DEFSYM (Qredisplay_internal, "redisplay_internal (C function)");
30149 message_dolog_marker1 = Fmake_marker ();
30150 staticpro (&message_dolog_marker1);
30151 message_dolog_marker2 = Fmake_marker ();
30152 staticpro (&message_dolog_marker2);
30153 message_dolog_marker3 = Fmake_marker ();
30154 staticpro (&message_dolog_marker3);
30156 #ifdef GLYPH_DEBUG
30157 defsubr (&Sdump_frame_glyph_matrix);
30158 defsubr (&Sdump_glyph_matrix);
30159 defsubr (&Sdump_glyph_row);
30160 defsubr (&Sdump_tool_bar_row);
30161 defsubr (&Strace_redisplay);
30162 defsubr (&Strace_to_stderr);
30163 #endif
30164 #ifdef HAVE_WINDOW_SYSTEM
30165 defsubr (&Stool_bar_height);
30166 defsubr (&Slookup_image_map);
30167 #endif
30168 defsubr (&Sline_pixel_height);
30169 defsubr (&Sformat_mode_line);
30170 defsubr (&Sinvisible_p);
30171 defsubr (&Scurrent_bidi_paragraph_direction);
30172 defsubr (&Swindow_text_pixel_size);
30173 defsubr (&Smove_point_visually);
30175 DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook");
30176 DEFSYM (Qoverriding_terminal_local_map, "overriding-terminal-local-map");
30177 DEFSYM (Qoverriding_local_map, "overriding-local-map");
30178 DEFSYM (Qwindow_scroll_functions, "window-scroll-functions");
30179 DEFSYM (Qwindow_text_change_functions, "window-text-change-functions");
30180 DEFSYM (Qredisplay_end_trigger_functions, "redisplay-end-trigger-functions");
30181 DEFSYM (Qinhibit_point_motion_hooks, "inhibit-point-motion-hooks");
30182 DEFSYM (Qeval, "eval");
30183 DEFSYM (QCdata, ":data");
30184 DEFSYM (Qdisplay, "display");
30185 DEFSYM (Qspace_width, "space-width");
30186 DEFSYM (Qraise, "raise");
30187 DEFSYM (Qslice, "slice");
30188 DEFSYM (Qspace, "space");
30189 DEFSYM (Qmargin, "margin");
30190 DEFSYM (Qpointer, "pointer");
30191 DEFSYM (Qleft_margin, "left-margin");
30192 DEFSYM (Qright_margin, "right-margin");
30193 DEFSYM (Qcenter, "center");
30194 DEFSYM (Qline_height, "line-height");
30195 DEFSYM (QCalign_to, ":align-to");
30196 DEFSYM (QCrelative_width, ":relative-width");
30197 DEFSYM (QCrelative_height, ":relative-height");
30198 DEFSYM (QCeval, ":eval");
30199 DEFSYM (QCpropertize, ":propertize");
30200 DEFSYM (QCfile, ":file");
30201 DEFSYM (Qfontified, "fontified");
30202 DEFSYM (Qfontification_functions, "fontification-functions");
30203 DEFSYM (Qtrailing_whitespace, "trailing-whitespace");
30204 DEFSYM (Qescape_glyph, "escape-glyph");
30205 DEFSYM (Qnobreak_space, "nobreak-space");
30206 DEFSYM (Qimage, "image");
30207 DEFSYM (Qtext, "text");
30208 DEFSYM (Qboth, "both");
30209 DEFSYM (Qboth_horiz, "both-horiz");
30210 DEFSYM (Qtext_image_horiz, "text-image-horiz");
30211 DEFSYM (QCmap, ":map");
30212 DEFSYM (QCpointer, ":pointer");
30213 DEFSYM (Qrect, "rect");
30214 DEFSYM (Qcircle, "circle");
30215 DEFSYM (Qpoly, "poly");
30216 DEFSYM (Qmessage_truncate_lines, "message-truncate-lines");
30217 DEFSYM (Qgrow_only, "grow-only");
30218 DEFSYM (Qinhibit_menubar_update, "inhibit-menubar-update");
30219 DEFSYM (Qinhibit_eval_during_redisplay, "inhibit-eval-during-redisplay");
30220 DEFSYM (Qposition, "position");
30221 DEFSYM (Qbuffer_position, "buffer-position");
30222 DEFSYM (Qobject, "object");
30223 DEFSYM (Qbar, "bar");
30224 DEFSYM (Qhbar, "hbar");
30225 DEFSYM (Qbox, "box");
30226 DEFSYM (Qhollow, "hollow");
30227 DEFSYM (Qhand, "hand");
30228 DEFSYM (Qarrow, "arrow");
30229 DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces");
30231 list_of_error = list1 (list2 (intern_c_string ("error"),
30232 intern_c_string ("void-variable")));
30233 staticpro (&list_of_error);
30235 DEFSYM (Qlast_arrow_position, "last-arrow-position");
30236 DEFSYM (Qlast_arrow_string, "last-arrow-string");
30237 DEFSYM (Qoverlay_arrow_string, "overlay-arrow-string");
30238 DEFSYM (Qoverlay_arrow_bitmap, "overlay-arrow-bitmap");
30240 echo_buffer[0] = echo_buffer[1] = Qnil;
30241 staticpro (&echo_buffer[0]);
30242 staticpro (&echo_buffer[1]);
30244 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
30245 staticpro (&echo_area_buffer[0]);
30246 staticpro (&echo_area_buffer[1]);
30248 Vmessages_buffer_name = build_pure_c_string ("*Messages*");
30249 staticpro (&Vmessages_buffer_name);
30251 mode_line_proptrans_alist = Qnil;
30252 staticpro (&mode_line_proptrans_alist);
30253 mode_line_string_list = Qnil;
30254 staticpro (&mode_line_string_list);
30255 mode_line_string_face = Qnil;
30256 staticpro (&mode_line_string_face);
30257 mode_line_string_face_prop = Qnil;
30258 staticpro (&mode_line_string_face_prop);
30259 Vmode_line_unwind_vector = Qnil;
30260 staticpro (&Vmode_line_unwind_vector);
30262 DEFSYM (Qmode_line_default_help_echo, "mode-line-default-help-echo");
30264 help_echo_string = Qnil;
30265 staticpro (&help_echo_string);
30266 help_echo_object = Qnil;
30267 staticpro (&help_echo_object);
30268 help_echo_window = Qnil;
30269 staticpro (&help_echo_window);
30270 previous_help_echo_string = Qnil;
30271 staticpro (&previous_help_echo_string);
30272 help_echo_pos = -1;
30274 DEFSYM (Qright_to_left, "right-to-left");
30275 DEFSYM (Qleft_to_right, "left-to-right");
30277 #ifdef HAVE_WINDOW_SYSTEM
30278 DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p,
30279 doc: /* Non-nil means draw block cursor as wide as the glyph under it.
30280 For example, if a block cursor is over a tab, it will be drawn as
30281 wide as that tab on the display. */);
30282 x_stretch_cursor_p = 0;
30283 #endif
30285 DEFVAR_LISP ("show-trailing-whitespace", Vshow_trailing_whitespace,
30286 doc: /* Non-nil means highlight trailing whitespace.
30287 The face used for trailing whitespace is `trailing-whitespace'. */);
30288 Vshow_trailing_whitespace = Qnil;
30290 DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display,
30291 doc: /* Control highlighting of non-ASCII space and hyphen chars.
30292 If the value is t, Emacs highlights non-ASCII chars which have the
30293 same appearance as an ASCII space or hyphen, using the `nobreak-space'
30294 or `escape-glyph' face respectively.
30296 U+00A0 (no-break space), U+00AD (soft hyphen), U+2010 (hyphen), and
30297 U+2011 (non-breaking hyphen) are affected.
30299 Any other non-nil value means to display these characters as a escape
30300 glyph followed by an ordinary space or hyphen.
30302 A value of nil means no special handling of these characters. */);
30303 Vnobreak_char_display = Qt;
30305 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer,
30306 doc: /* The pointer shape to show in void text areas.
30307 A value of nil means to show the text pointer. Other options are
30308 `arrow', `text', `hand', `vdrag', `hdrag', `nhdrag', `modeline', and
30309 `hourglass'. */);
30310 Vvoid_text_area_pointer = Qarrow;
30312 DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay,
30313 doc: /* Non-nil means don't actually do any redisplay.
30314 This is used for internal purposes. */);
30315 Vinhibit_redisplay = Qnil;
30317 DEFVAR_LISP ("global-mode-string", Vglobal_mode_string,
30318 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
30319 Vglobal_mode_string = Qnil;
30321 DEFVAR_LISP ("overlay-arrow-position", Voverlay_arrow_position,
30322 doc: /* Marker for where to display an arrow on top of the buffer text.
30323 This must be the beginning of a line in order to work.
30324 See also `overlay-arrow-string'. */);
30325 Voverlay_arrow_position = Qnil;
30327 DEFVAR_LISP ("overlay-arrow-string", Voverlay_arrow_string,
30328 doc: /* String to display as an arrow in non-window frames.
30329 See also `overlay-arrow-position'. */);
30330 Voverlay_arrow_string = build_pure_c_string ("=>");
30332 DEFVAR_LISP ("overlay-arrow-variable-list", Voverlay_arrow_variable_list,
30333 doc: /* List of variables (symbols) which hold markers for overlay arrows.
30334 The symbols on this list are examined during redisplay to determine
30335 where to display overlay arrows. */);
30336 Voverlay_arrow_variable_list
30337 = list1 (intern_c_string ("overlay-arrow-position"));
30339 DEFVAR_INT ("scroll-step", emacs_scroll_step,
30340 doc: /* The number of lines to try scrolling a window by when point moves out.
30341 If that fails to bring point back on frame, point is centered instead.
30342 If this is zero, point is always centered after it moves off frame.
30343 If you want scrolling to always be a line at a time, you should set
30344 `scroll-conservatively' to a large value rather than set this to 1. */);
30346 DEFVAR_INT ("scroll-conservatively", scroll_conservatively,
30347 doc: /* Scroll up to this many lines, to bring point back on screen.
30348 If point moves off-screen, redisplay will scroll by up to
30349 `scroll-conservatively' lines in order to bring point just barely
30350 onto the screen again. If that cannot be done, then redisplay
30351 recenters point as usual.
30353 If the value is greater than 100, redisplay will never recenter point,
30354 but will always scroll just enough text to bring point into view, even
30355 if you move far away.
30357 A value of zero means always recenter point if it moves off screen. */);
30358 scroll_conservatively = 0;
30360 DEFVAR_INT ("scroll-margin", scroll_margin,
30361 doc: /* Number of lines of margin at the top and bottom of a window.
30362 Recenter the window whenever point gets within this many lines
30363 of the top or bottom of the window. */);
30364 scroll_margin = 0;
30366 DEFVAR_LISP ("display-pixels-per-inch", Vdisplay_pixels_per_inch,
30367 doc: /* Pixels per inch value for non-window system displays.
30368 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
30369 Vdisplay_pixels_per_inch = make_float (72.0);
30371 #ifdef GLYPH_DEBUG
30372 DEFVAR_INT ("debug-end-pos", debug_end_pos, doc: /* Don't ask. */);
30373 #endif
30375 DEFVAR_LISP ("truncate-partial-width-windows",
30376 Vtruncate_partial_width_windows,
30377 doc: /* Non-nil means truncate lines in windows narrower than the frame.
30378 For an integer value, truncate lines in each window narrower than the
30379 full frame width, provided the window width is less than that integer;
30380 otherwise, respect the value of `truncate-lines'.
30382 For any other non-nil value, truncate lines in all windows that do
30383 not span the full frame width.
30385 A value of nil means to respect the value of `truncate-lines'.
30387 If `word-wrap' is enabled, you might want to reduce this. */);
30388 Vtruncate_partial_width_windows = make_number (50);
30390 DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit,
30391 doc: /* Maximum buffer size for which line number should be displayed.
30392 If the buffer is bigger than this, the line number does not appear
30393 in the mode line. A value of nil means no limit. */);
30394 Vline_number_display_limit = Qnil;
30396 DEFVAR_INT ("line-number-display-limit-width",
30397 line_number_display_limit_width,
30398 doc: /* Maximum line width (in characters) for line number display.
30399 If the average length of the lines near point is bigger than this, then the
30400 line number may be omitted from the mode line. */);
30401 line_number_display_limit_width = 200;
30403 DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows,
30404 doc: /* Non-nil means highlight region even in nonselected windows. */);
30405 highlight_nonselected_windows = 0;
30407 DEFVAR_BOOL ("multiple-frames", multiple_frames,
30408 doc: /* Non-nil if more than one frame is visible on this display.
30409 Minibuffer-only frames don't count, but iconified frames do.
30410 This variable is not guaranteed to be accurate except while processing
30411 `frame-title-format' and `icon-title-format'. */);
30413 DEFVAR_LISP ("frame-title-format", Vframe_title_format,
30414 doc: /* Template for displaying the title bar of visible frames.
30415 \(Assuming the window manager supports this feature.)
30417 This variable has the same structure as `mode-line-format', except that
30418 the %c and %l constructs are ignored. It is used only on frames for
30419 which no explicit name has been set \(see `modify-frame-parameters'). */);
30421 DEFVAR_LISP ("icon-title-format", Vicon_title_format,
30422 doc: /* Template for displaying the title bar of an iconified frame.
30423 \(Assuming the window manager supports this feature.)
30424 This variable has the same structure as `mode-line-format' (which see),
30425 and is used only on frames for which no explicit name has been set
30426 \(see `modify-frame-parameters'). */);
30427 Vicon_title_format
30428 = Vframe_title_format
30429 = listn (CONSTYPE_PURE, 3,
30430 intern_c_string ("multiple-frames"),
30431 build_pure_c_string ("%b"),
30432 listn (CONSTYPE_PURE, 4,
30433 empty_unibyte_string,
30434 intern_c_string ("invocation-name"),
30435 build_pure_c_string ("@"),
30436 intern_c_string ("system-name")));
30438 DEFVAR_LISP ("message-log-max", Vmessage_log_max,
30439 doc: /* Maximum number of lines to keep in the message log buffer.
30440 If nil, disable message logging. If t, log messages but don't truncate
30441 the buffer when it becomes large. */);
30442 Vmessage_log_max = make_number (1000);
30444 DEFVAR_LISP ("window-size-change-functions", Vwindow_size_change_functions,
30445 doc: /* Functions called before redisplay, if window sizes have changed.
30446 The value should be a list of functions that take one argument.
30447 Just before redisplay, for each frame, if any of its windows have changed
30448 size since the last redisplay, or have been split or deleted,
30449 all the functions in the list are called, with the frame as argument. */);
30450 Vwindow_size_change_functions = Qnil;
30452 DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions,
30453 doc: /* List of functions to call before redisplaying a window with scrolling.
30454 Each function is called with two arguments, the window and its new
30455 display-start position. Note that these functions are also called by
30456 `set-window-buffer'. Also note that the value of `window-end' is not
30457 valid when these functions are called.
30459 Warning: Do not use this feature to alter the way the window
30460 is scrolled. It is not designed for that, and such use probably won't
30461 work. */);
30462 Vwindow_scroll_functions = Qnil;
30464 DEFVAR_LISP ("window-text-change-functions",
30465 Vwindow_text_change_functions,
30466 doc: /* Functions to call in redisplay when text in the window might change. */);
30467 Vwindow_text_change_functions = Qnil;
30469 DEFVAR_LISP ("redisplay-end-trigger-functions", Vredisplay_end_trigger_functions,
30470 doc: /* Functions called when redisplay of a window reaches the end trigger.
30471 Each function is called with two arguments, the window and the end trigger value.
30472 See `set-window-redisplay-end-trigger'. */);
30473 Vredisplay_end_trigger_functions = Qnil;
30475 DEFVAR_LISP ("mouse-autoselect-window", Vmouse_autoselect_window,
30476 doc: /* Non-nil means autoselect window with mouse pointer.
30477 If nil, do not autoselect windows.
30478 A positive number means delay autoselection by that many seconds: a
30479 window is autoselected only after the mouse has remained in that
30480 window for the duration of the delay.
30481 A negative number has a similar effect, but causes windows to be
30482 autoselected only after the mouse has stopped moving. \(Because of
30483 the way Emacs compares mouse events, you will occasionally wait twice
30484 that time before the window gets selected.\)
30485 Any other value means to autoselect window instantaneously when the
30486 mouse pointer enters it.
30488 Autoselection selects the minibuffer only if it is active, and never
30489 unselects the minibuffer if it is active.
30491 When customizing this variable make sure that the actual value of
30492 `focus-follows-mouse' matches the behavior of your window manager. */);
30493 Vmouse_autoselect_window = Qnil;
30495 DEFVAR_LISP ("auto-resize-tool-bars", Vauto_resize_tool_bars,
30496 doc: /* Non-nil means automatically resize tool-bars.
30497 This dynamically changes the tool-bar's height to the minimum height
30498 that is needed to make all tool-bar items visible.
30499 If value is `grow-only', the tool-bar's height is only increased
30500 automatically; to decrease the tool-bar height, use \\[recenter]. */);
30501 Vauto_resize_tool_bars = Qt;
30503 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p,
30504 doc: /* Non-nil means raise tool-bar buttons when the mouse moves over them. */);
30505 auto_raise_tool_bar_buttons_p = 1;
30507 DEFVAR_BOOL ("make-cursor-line-fully-visible", make_cursor_line_fully_visible_p,
30508 doc: /* Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
30509 make_cursor_line_fully_visible_p = 1;
30511 DEFVAR_LISP ("tool-bar-border", Vtool_bar_border,
30512 doc: /* Border below tool-bar in pixels.
30513 If an integer, use it as the height of the border.
30514 If it is one of `internal-border-width' or `border-width', use the
30515 value of the corresponding frame parameter.
30516 Otherwise, no border is added below the tool-bar. */);
30517 Vtool_bar_border = Qinternal_border_width;
30519 DEFVAR_LISP ("tool-bar-button-margin", Vtool_bar_button_margin,
30520 doc: /* Margin around tool-bar buttons in pixels.
30521 If an integer, use that for both horizontal and vertical margins.
30522 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
30523 HORZ specifying the horizontal margin, and VERT specifying the
30524 vertical margin. */);
30525 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
30527 DEFVAR_INT ("tool-bar-button-relief", tool_bar_button_relief,
30528 doc: /* Relief thickness of tool-bar buttons. */);
30529 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
30531 DEFVAR_LISP ("tool-bar-style", Vtool_bar_style,
30532 doc: /* Tool bar style to use.
30533 It can be one of
30534 image - show images only
30535 text - show text only
30536 both - show both, text below image
30537 both-horiz - show text to the right of the image
30538 text-image-horiz - show text to the left of the image
30539 any other - use system default or image if no system default.
30541 This variable only affects the GTK+ toolkit version of Emacs. */);
30542 Vtool_bar_style = Qnil;
30544 DEFVAR_INT ("tool-bar-max-label-size", tool_bar_max_label_size,
30545 doc: /* Maximum number of characters a label can have to be shown.
30546 The tool bar style must also show labels for this to have any effect, see
30547 `tool-bar-style'. */);
30548 tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
30550 DEFVAR_LISP ("fontification-functions", Vfontification_functions,
30551 doc: /* List of functions to call to fontify regions of text.
30552 Each function is called with one argument POS. Functions must
30553 fontify a region starting at POS in the current buffer, and give
30554 fontified regions the property `fontified'. */);
30555 Vfontification_functions = Qnil;
30556 Fmake_variable_buffer_local (Qfontification_functions);
30558 DEFVAR_BOOL ("unibyte-display-via-language-environment",
30559 unibyte_display_via_language_environment,
30560 doc: /* Non-nil means display unibyte text according to language environment.
30561 Specifically, this means that raw bytes in the range 160-255 decimal
30562 are displayed by converting them to the equivalent multibyte characters
30563 according to the current language environment. As a result, they are
30564 displayed according to the current fontset.
30566 Note that this variable affects only how these bytes are displayed,
30567 but does not change the fact they are interpreted as raw bytes. */);
30568 unibyte_display_via_language_environment = 0;
30570 DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height,
30571 doc: /* Maximum height for resizing mini-windows (the minibuffer and the echo area).
30572 If a float, it specifies a fraction of the mini-window frame's height.
30573 If an integer, it specifies a number of lines. */);
30574 Vmax_mini_window_height = make_float (0.25);
30576 DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows,
30577 doc: /* How to resize mini-windows (the minibuffer and the echo area).
30578 A value of nil means don't automatically resize mini-windows.
30579 A value of t means resize them to fit the text displayed in them.
30580 A value of `grow-only', the default, means let mini-windows grow only;
30581 they return to their normal size when the minibuffer is closed, or the
30582 echo area becomes empty. */);
30583 Vresize_mini_windows = Qgrow_only;
30585 DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist,
30586 doc: /* Alist specifying how to blink the cursor off.
30587 Each element has the form (ON-STATE . OFF-STATE). Whenever the
30588 `cursor-type' frame-parameter or variable equals ON-STATE,
30589 comparing using `equal', Emacs uses OFF-STATE to specify
30590 how to blink it off. ON-STATE and OFF-STATE are values for
30591 the `cursor-type' frame parameter.
30593 If a frame's ON-STATE has no entry in this list,
30594 the frame's other specifications determine how to blink the cursor off. */);
30595 Vblink_cursor_alist = Qnil;
30597 DEFVAR_BOOL ("auto-hscroll-mode", automatic_hscrolling_p,
30598 doc: /* Allow or disallow automatic horizontal scrolling of windows.
30599 If non-nil, windows are automatically scrolled horizontally to make
30600 point visible. */);
30601 automatic_hscrolling_p = 1;
30602 DEFSYM (Qauto_hscroll_mode, "auto-hscroll-mode");
30604 DEFVAR_INT ("hscroll-margin", hscroll_margin,
30605 doc: /* How many columns away from the window edge point is allowed to get
30606 before automatic hscrolling will horizontally scroll the window. */);
30607 hscroll_margin = 5;
30609 DEFVAR_LISP ("hscroll-step", Vhscroll_step,
30610 doc: /* How many columns to scroll the window when point gets too close to the edge.
30611 When point is less than `hscroll-margin' columns from the window
30612 edge, automatic hscrolling will scroll the window by the amount of columns
30613 determined by this variable. If its value is a positive integer, scroll that
30614 many columns. If it's a positive floating-point number, it specifies the
30615 fraction of the window's width to scroll. If it's nil or zero, point will be
30616 centered horizontally after the scroll. Any other value, including negative
30617 numbers, are treated as if the value were zero.
30619 Automatic hscrolling always moves point outside the scroll margin, so if
30620 point was more than scroll step columns inside the margin, the window will
30621 scroll more than the value given by the scroll step.
30623 Note that the lower bound for automatic hscrolling specified by `scroll-left'
30624 and `scroll-right' overrides this variable's effect. */);
30625 Vhscroll_step = make_number (0);
30627 DEFVAR_BOOL ("message-truncate-lines", message_truncate_lines,
30628 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
30629 Bind this around calls to `message' to let it take effect. */);
30630 message_truncate_lines = 0;
30632 DEFVAR_LISP ("menu-bar-update-hook", Vmenu_bar_update_hook,
30633 doc: /* Normal hook run to update the menu bar definitions.
30634 Redisplay runs this hook before it redisplays the menu bar.
30635 This is used to update menus such as Buffers, whose contents depend on
30636 various data. */);
30637 Vmenu_bar_update_hook = Qnil;
30639 DEFVAR_LISP ("menu-updating-frame", Vmenu_updating_frame,
30640 doc: /* Frame for which we are updating a menu.
30641 The enable predicate for a menu binding should check this variable. */);
30642 Vmenu_updating_frame = Qnil;
30644 DEFVAR_BOOL ("inhibit-menubar-update", inhibit_menubar_update,
30645 doc: /* Non-nil means don't update menu bars. Internal use only. */);
30646 inhibit_menubar_update = 0;
30648 DEFVAR_LISP ("wrap-prefix", Vwrap_prefix,
30649 doc: /* Prefix prepended to all continuation lines at display time.
30650 The value may be a string, an image, or a stretch-glyph; it is
30651 interpreted in the same way as the value of a `display' text property.
30653 This variable is overridden by any `wrap-prefix' text or overlay
30654 property.
30656 To add a prefix to non-continuation lines, use `line-prefix'. */);
30657 Vwrap_prefix = Qnil;
30658 DEFSYM (Qwrap_prefix, "wrap-prefix");
30659 Fmake_variable_buffer_local (Qwrap_prefix);
30661 DEFVAR_LISP ("line-prefix", Vline_prefix,
30662 doc: /* Prefix prepended to all non-continuation lines at display time.
30663 The value may be a string, an image, or a stretch-glyph; it is
30664 interpreted in the same way as the value of a `display' text property.
30666 This variable is overridden by any `line-prefix' text or overlay
30667 property.
30669 To add a prefix to continuation lines, use `wrap-prefix'. */);
30670 Vline_prefix = Qnil;
30671 DEFSYM (Qline_prefix, "line-prefix");
30672 Fmake_variable_buffer_local (Qline_prefix);
30674 DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay,
30675 doc: /* Non-nil means don't eval Lisp during redisplay. */);
30676 inhibit_eval_during_redisplay = 0;
30678 DEFVAR_BOOL ("inhibit-free-realized-faces", inhibit_free_realized_faces,
30679 doc: /* Non-nil means don't free realized faces. Internal use only. */);
30680 inhibit_free_realized_faces = 0;
30682 #ifdef GLYPH_DEBUG
30683 DEFVAR_BOOL ("inhibit-try-window-id", inhibit_try_window_id,
30684 doc: /* Inhibit try_window_id display optimization. */);
30685 inhibit_try_window_id = 0;
30687 DEFVAR_BOOL ("inhibit-try-window-reusing", inhibit_try_window_reusing,
30688 doc: /* Inhibit try_window_reusing display optimization. */);
30689 inhibit_try_window_reusing = 0;
30691 DEFVAR_BOOL ("inhibit-try-cursor-movement", inhibit_try_cursor_movement,
30692 doc: /* Inhibit try_cursor_movement display optimization. */);
30693 inhibit_try_cursor_movement = 0;
30694 #endif /* GLYPH_DEBUG */
30696 DEFVAR_INT ("overline-margin", overline_margin,
30697 doc: /* Space between overline and text, in pixels.
30698 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
30699 margin to the character height. */);
30700 overline_margin = 2;
30702 DEFVAR_INT ("underline-minimum-offset",
30703 underline_minimum_offset,
30704 doc: /* Minimum distance between baseline and underline.
30705 This can improve legibility of underlined text at small font sizes,
30706 particularly when using variable `x-use-underline-position-properties'
30707 with fonts that specify an UNDERLINE_POSITION relatively close to the
30708 baseline. The default value is 1. */);
30709 underline_minimum_offset = 1;
30711 DEFVAR_BOOL ("display-hourglass", display_hourglass_p,
30712 doc: /* Non-nil means show an hourglass pointer, when Emacs is busy.
30713 This feature only works when on a window system that can change
30714 cursor shapes. */);
30715 display_hourglass_p = 1;
30717 DEFVAR_LISP ("hourglass-delay", Vhourglass_delay,
30718 doc: /* Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
30719 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
30721 #ifdef HAVE_WINDOW_SYSTEM
30722 hourglass_atimer = NULL;
30723 hourglass_shown_p = 0;
30724 #endif /* HAVE_WINDOW_SYSTEM */
30726 DEFSYM (Qglyphless_char, "glyphless-char");
30727 DEFSYM (Qhex_code, "hex-code");
30728 DEFSYM (Qempty_box, "empty-box");
30729 DEFSYM (Qthin_space, "thin-space");
30730 DEFSYM (Qzero_width, "zero-width");
30732 DEFVAR_LISP ("pre-redisplay-function", Vpre_redisplay_function,
30733 doc: /* Function run just before redisplay.
30734 It is called with one argument, which is the set of windows that are to
30735 be redisplayed. This set can be nil (meaning, only the selected window),
30736 or t (meaning all windows). */);
30737 Vpre_redisplay_function = intern ("ignore");
30739 DEFSYM (Qglyphless_char_display, "glyphless-char-display");
30740 Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
30742 DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display,
30743 doc: /* Char-table defining glyphless characters.
30744 Each element, if non-nil, should be one of the following:
30745 an ASCII acronym string: display this string in a box
30746 `hex-code': display the hexadecimal code of a character in a box
30747 `empty-box': display as an empty box
30748 `thin-space': display as 1-pixel width space
30749 `zero-width': don't display
30750 An element may also be a cons cell (GRAPHICAL . TEXT), which specifies the
30751 display method for graphical terminals and text terminals respectively.
30752 GRAPHICAL and TEXT should each have one of the values listed above.
30754 The char-table has one extra slot to control the display of a character for
30755 which no font is found. This slot only takes effect on graphical terminals.
30756 Its value should be an ASCII acronym string, `hex-code', `empty-box', or
30757 `thin-space'. The default is `empty-box'.
30759 If a character has a non-nil entry in an active display table, the
30760 display table takes effect; in this case, Emacs does not consult
30761 `glyphless-char-display' at all. */);
30762 Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
30763 Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
30764 Qempty_box);
30766 DEFVAR_LISP ("debug-on-message", Vdebug_on_message,
30767 doc: /* If non-nil, debug if a message matching this regexp is displayed. */);
30768 Vdebug_on_message = Qnil;
30770 DEFVAR_LISP ("redisplay--all-windows-cause", Vredisplay__all_windows_cause,
30771 doc: /* */);
30772 Vredisplay__all_windows_cause
30773 = Fmake_vector (make_number (100), make_number (0));
30775 DEFVAR_LISP ("redisplay--mode-lines-cause", Vredisplay__mode_lines_cause,
30776 doc: /* */);
30777 Vredisplay__mode_lines_cause
30778 = Fmake_vector (make_number (100), make_number (0));
30782 /* Initialize this module when Emacs starts. */
30784 void
30785 init_xdisp (void)
30787 CHARPOS (this_line_start_pos) = 0;
30789 if (!noninteractive)
30791 struct window *m = XWINDOW (minibuf_window);
30792 Lisp_Object frame = m->frame;
30793 struct frame *f = XFRAME (frame);
30794 Lisp_Object root = FRAME_ROOT_WINDOW (f);
30795 struct window *r = XWINDOW (root);
30796 int i;
30798 echo_area_window = minibuf_window;
30800 r->top_line = FRAME_TOP_MARGIN (f);
30801 r->pixel_top = r->top_line * FRAME_LINE_HEIGHT (f);
30802 r->total_cols = FRAME_COLS (f);
30803 r->pixel_width = r->total_cols * FRAME_COLUMN_WIDTH (f);
30804 r->total_lines = FRAME_TOTAL_LINES (f) - 1 - FRAME_TOP_MARGIN (f);
30805 r->pixel_height = r->total_lines * FRAME_LINE_HEIGHT (f);
30807 m->top_line = FRAME_TOTAL_LINES (f) - 1;
30808 m->pixel_top = m->top_line * FRAME_LINE_HEIGHT (f);
30809 m->total_cols = FRAME_COLS (f);
30810 m->pixel_width = m->total_cols * FRAME_COLUMN_WIDTH (f);
30811 m->total_lines = 1;
30812 m->pixel_height = m->total_lines * FRAME_LINE_HEIGHT (f);
30814 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
30815 scratch_glyph_row.glyphs[TEXT_AREA + 1]
30816 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
30818 /* The default ellipsis glyphs `...'. */
30819 for (i = 0; i < 3; ++i)
30820 default_invis_vector[i] = make_number ('.');
30824 /* Allocate the buffer for frame titles.
30825 Also used for `format-mode-line'. */
30826 int size = 100;
30827 mode_line_noprop_buf = xmalloc (size);
30828 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
30829 mode_line_noprop_ptr = mode_line_noprop_buf;
30830 mode_line_target = MODE_LINE_DISPLAY;
30833 help_echo_showing_p = 0;
30836 #ifdef HAVE_WINDOW_SYSTEM
30838 /* Platform-independent portion of hourglass implementation. */
30840 /* Timer function of hourglass_atimer. */
30842 static void
30843 show_hourglass (struct atimer *timer)
30845 /* The timer implementation will cancel this timer automatically
30846 after this function has run. Set hourglass_atimer to null
30847 so that we know the timer doesn't have to be canceled. */
30848 hourglass_atimer = NULL;
30850 if (!hourglass_shown_p)
30852 Lisp_Object tail, frame;
30854 block_input ();
30856 FOR_EACH_FRAME (tail, frame)
30858 struct frame *f = XFRAME (frame);
30860 if (FRAME_LIVE_P (f) && FRAME_WINDOW_P (f)
30861 && FRAME_RIF (f)->show_hourglass)
30862 FRAME_RIF (f)->show_hourglass (f);
30865 hourglass_shown_p = 1;
30866 unblock_input ();
30870 /* Cancel a currently active hourglass timer, and start a new one. */
30872 void
30873 start_hourglass (void)
30875 struct timespec delay;
30877 cancel_hourglass ();
30879 if (INTEGERP (Vhourglass_delay)
30880 && XINT (Vhourglass_delay) > 0)
30881 delay = make_timespec (min (XINT (Vhourglass_delay),
30882 TYPE_MAXIMUM (time_t)),
30884 else if (FLOATP (Vhourglass_delay)
30885 && XFLOAT_DATA (Vhourglass_delay) > 0)
30886 delay = dtotimespec (XFLOAT_DATA (Vhourglass_delay));
30887 else
30888 delay = make_timespec (DEFAULT_HOURGLASS_DELAY, 0);
30890 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
30891 show_hourglass, NULL);
30894 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
30895 shown. */
30897 void
30898 cancel_hourglass (void)
30900 if (hourglass_atimer)
30902 cancel_atimer (hourglass_atimer);
30903 hourglass_atimer = NULL;
30906 if (hourglass_shown_p)
30908 Lisp_Object tail, frame;
30910 block_input ();
30912 FOR_EACH_FRAME (tail, frame)
30914 struct frame *f = XFRAME (frame);
30916 if (FRAME_LIVE_P (f) && FRAME_WINDOW_P (f)
30917 && FRAME_RIF (f)->hide_hourglass)
30918 FRAME_RIF (f)->hide_hourglass (f);
30919 #ifdef HAVE_NTGUI
30920 /* No cursors on non GUI frames - restore to stock arrow cursor. */
30921 else if (!FRAME_W32_P (f))
30922 w32_arrow_cursor ();
30923 #endif
30926 hourglass_shown_p = 0;
30927 unblock_input ();
30931 #endif /* HAVE_WINDOW_SYSTEM */