Merge from trunk and resolve conflicts.
[emacs.git] / src / xdisp.c
blob7c3aaa2042e6a4b8ce01e0887a499ce1e4dcfa49
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. */
1147 static int
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 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1459 int bottom_y;
1460 struct it save_it;
1461 void *save_it_data = NULL;
1463 /* Calling line_bottom_y may change it.method, it.position, etc. */
1464 SAVE_IT (save_it, it, save_it_data);
1465 last_height = 0;
1466 bottom_y = line_bottom_y (&it);
1467 if (top_y < window_top_y)
1468 visible_p = bottom_y > window_top_y;
1469 else if (top_y < it.last_visible_y)
1470 visible_p = 1;
1471 if (bottom_y >= it.last_visible_y
1472 && it.bidi_p && it.bidi_it.scan_dir == -1
1473 && IT_CHARPOS (it) < charpos)
1475 /* When the last line of the window is scanned backwards
1476 under bidi iteration, we could be duped into thinking
1477 that we have passed CHARPOS, when in fact move_it_to
1478 simply stopped short of CHARPOS because it reached
1479 last_visible_y. To see if that's what happened, we call
1480 move_it_to again with a slightly larger vertical limit,
1481 and see if it actually moved vertically; if it did, we
1482 didn't really reach CHARPOS, which is beyond window end. */
1483 /* Why 10? because we don't know how many canonical lines
1484 will the height of the next line(s) be. So we guess. */
1485 int ten_more_lines = 10 * default_line_pixel_height (w);
1487 move_it_to (&it, charpos, -1, bottom_y + ten_more_lines, -1,
1488 MOVE_TO_POS | MOVE_TO_Y);
1489 if (it.current_y > top_y)
1490 visible_p = 0;
1493 RESTORE_IT (&it, &save_it, save_it_data);
1494 if (visible_p)
1496 if (it.method == GET_FROM_DISPLAY_VECTOR)
1498 /* We stopped on the last glyph of a display vector.
1499 Try and recompute. Hack alert! */
1500 if (charpos < 2 || top.charpos >= charpos)
1501 top_x = it.glyph_row->x;
1502 else
1504 struct it it2, it2_prev;
1505 /* The idea is to get to the previous buffer
1506 position, consume the character there, and use
1507 the pixel coordinates we get after that. But if
1508 the previous buffer position is also displayed
1509 from a display vector, we need to consume all of
1510 the glyphs from that display vector. */
1511 start_display (&it2, w, top);
1512 move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS);
1513 /* If we didn't get to CHARPOS - 1, there's some
1514 replacing display property at that position, and
1515 we stopped after it. That is exactly the place
1516 whose coordinates we want. */
1517 if (IT_CHARPOS (it2) != charpos - 1)
1518 it2_prev = it2;
1519 else
1521 /* Iterate until we get out of the display
1522 vector that displays the character at
1523 CHARPOS - 1. */
1524 do {
1525 get_next_display_element (&it2);
1526 PRODUCE_GLYPHS (&it2);
1527 it2_prev = it2;
1528 set_iterator_to_next (&it2, 1);
1529 } while (it2.method == GET_FROM_DISPLAY_VECTOR
1530 && IT_CHARPOS (it2) < charpos);
1532 if (ITERATOR_AT_END_OF_LINE_P (&it2_prev)
1533 || it2_prev.current_x > it2_prev.last_visible_x)
1534 top_x = it.glyph_row->x;
1535 else
1537 top_x = it2_prev.current_x;
1538 top_y = it2_prev.current_y;
1542 else if (IT_CHARPOS (it) != charpos)
1544 Lisp_Object cpos = make_number (charpos);
1545 Lisp_Object spec = Fget_char_property (cpos, Qdisplay, Qnil);
1546 Lisp_Object string = string_from_display_spec (spec);
1547 struct text_pos tpos;
1548 int replacing_spec_p;
1549 bool newline_in_string
1550 = (STRINGP (string)
1551 && memchr (SDATA (string), '\n', SBYTES (string)));
1553 SET_TEXT_POS (tpos, charpos, CHAR_TO_BYTE (charpos));
1554 replacing_spec_p
1555 = (!NILP (spec)
1556 && handle_display_spec (NULL, spec, Qnil, Qnil, &tpos,
1557 charpos, FRAME_WINDOW_P (it.f)));
1558 /* The tricky code below is needed because there's a
1559 discrepancy between move_it_to and how we set cursor
1560 when PT is at the beginning of a portion of text
1561 covered by a display property or an overlay with a
1562 display property, or the display line ends in a
1563 newline from a display string. move_it_to will stop
1564 _after_ such display strings, whereas
1565 set_cursor_from_row conspires with cursor_row_p to
1566 place the cursor on the first glyph produced from the
1567 display string. */
1569 /* We have overshoot PT because it is covered by a
1570 display property that replaces the text it covers.
1571 If the string includes embedded newlines, we are also
1572 in the wrong display line. Backtrack to the correct
1573 line, where the display property begins. */
1574 if (replacing_spec_p)
1576 Lisp_Object startpos, endpos;
1577 EMACS_INT start, end;
1578 struct it it3;
1579 int it3_moved;
1581 /* Find the first and the last buffer positions
1582 covered by the display string. */
1583 endpos =
1584 Fnext_single_char_property_change (cpos, Qdisplay,
1585 Qnil, Qnil);
1586 startpos =
1587 Fprevious_single_char_property_change (endpos, Qdisplay,
1588 Qnil, Qnil);
1589 start = XFASTINT (startpos);
1590 end = XFASTINT (endpos);
1591 /* Move to the last buffer position before the
1592 display property. */
1593 start_display (&it3, w, top);
1594 if (start > CHARPOS (top))
1595 move_it_to (&it3, start - 1, -1, -1, -1, MOVE_TO_POS);
1596 /* Move forward one more line if the position before
1597 the display string is a newline or if it is the
1598 rightmost character on a line that is
1599 continued or word-wrapped. */
1600 if (it3.method == GET_FROM_BUFFER
1601 && (it3.c == '\n'
1602 || FETCH_BYTE (IT_BYTEPOS (it3)) == '\n'))
1603 move_it_by_lines (&it3, 1);
1604 else if (move_it_in_display_line_to (&it3, -1,
1605 it3.current_x
1606 + it3.pixel_width,
1607 MOVE_TO_X)
1608 == MOVE_LINE_CONTINUED)
1610 move_it_by_lines (&it3, 1);
1611 /* When we are under word-wrap, the #$@%!
1612 move_it_by_lines moves 2 lines, so we need to
1613 fix that up. */
1614 if (it3.line_wrap == WORD_WRAP)
1615 move_it_by_lines (&it3, -1);
1618 /* Record the vertical coordinate of the display
1619 line where we wound up. */
1620 top_y = it3.current_y;
1621 if (it3.bidi_p)
1623 /* When characters are reordered for display,
1624 the character displayed to the left of the
1625 display string could be _after_ the display
1626 property in the logical order. Use the
1627 smallest vertical position of these two. */
1628 start_display (&it3, w, top);
1629 move_it_to (&it3, end + 1, -1, -1, -1, MOVE_TO_POS);
1630 if (it3.current_y < top_y)
1631 top_y = it3.current_y;
1633 /* Move from the top of the window to the beginning
1634 of the display line where the display string
1635 begins. */
1636 start_display (&it3, w, top);
1637 move_it_to (&it3, -1, 0, top_y, -1, MOVE_TO_X | MOVE_TO_Y);
1638 /* If it3_moved stays zero after the 'while' loop
1639 below, that means we already were at a newline
1640 before the loop (e.g., the display string begins
1641 with a newline), so we don't need to (and cannot)
1642 inspect the glyphs of it3.glyph_row, because
1643 PRODUCE_GLYPHS will not produce anything for a
1644 newline, and thus it3.glyph_row stays at its
1645 stale content it got at top of the window. */
1646 it3_moved = 0;
1647 /* Finally, advance the iterator until we hit the
1648 first display element whose character position is
1649 CHARPOS, or until the first newline from the
1650 display string, which signals the end of the
1651 display line. */
1652 while (get_next_display_element (&it3))
1654 PRODUCE_GLYPHS (&it3);
1655 if (IT_CHARPOS (it3) == charpos
1656 || ITERATOR_AT_END_OF_LINE_P (&it3))
1657 break;
1658 it3_moved = 1;
1659 set_iterator_to_next (&it3, 0);
1661 top_x = it3.current_x - it3.pixel_width;
1662 /* Normally, we would exit the above loop because we
1663 found the display element whose character
1664 position is CHARPOS. For the contingency that we
1665 didn't, and stopped at the first newline from the
1666 display string, move back over the glyphs
1667 produced from the string, until we find the
1668 rightmost glyph not from the string. */
1669 if (it3_moved
1670 && newline_in_string
1671 && IT_CHARPOS (it3) != charpos && EQ (it3.object, string))
1673 struct glyph *g = it3.glyph_row->glyphs[TEXT_AREA]
1674 + it3.glyph_row->used[TEXT_AREA];
1676 while (EQ ((g - 1)->object, string))
1678 --g;
1679 top_x -= g->pixel_width;
1681 eassert (g < it3.glyph_row->glyphs[TEXT_AREA]
1682 + it3.glyph_row->used[TEXT_AREA]);
1687 *x = top_x;
1688 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1689 *rtop = max (0, window_top_y - top_y);
1690 *rbot = max (0, bottom_y - it.last_visible_y);
1691 *rowh = max (0, (min (bottom_y, it.last_visible_y)
1692 - max (top_y, window_top_y)));
1693 *vpos = it.vpos;
1696 else
1698 /* Either we were asked to provide info about WINDOW_END, or
1699 CHARPOS is in the partially visible glyph row at end of
1700 window. */
1701 struct it it2;
1702 void *it2data = NULL;
1704 SAVE_IT (it2, it, it2data);
1705 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1706 move_it_by_lines (&it, 1);
1707 if (charpos < IT_CHARPOS (it)
1708 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1710 visible_p = true;
1711 RESTORE_IT (&it2, &it2, it2data);
1712 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1713 *x = it2.current_x;
1714 *y = it2.current_y + it2.max_ascent - it2.ascent;
1715 *rtop = max (0, -it2.current_y);
1716 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1717 - it.last_visible_y));
1718 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
1719 it.last_visible_y)
1720 - max (it2.current_y,
1721 WINDOW_HEADER_LINE_HEIGHT (w))));
1722 *vpos = it2.vpos;
1724 else
1725 bidi_unshelve_cache (it2data, 1);
1727 bidi_unshelve_cache (itdata, 0);
1729 if (old_buffer)
1730 set_buffer_internal_1 (old_buffer);
1732 if (visible_p && w->hscroll > 0)
1733 *x -=
1734 window_hscroll_limited (w, WINDOW_XFRAME (w))
1735 * WINDOW_FRAME_COLUMN_WIDTH (w);
1737 #if 0
1738 /* Debugging code. */
1739 if (visible_p)
1740 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1741 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
1742 else
1743 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
1744 #endif
1746 return visible_p;
1750 /* Return the next character from STR. Return in *LEN the length of
1751 the character. This is like STRING_CHAR_AND_LENGTH but never
1752 returns an invalid character. If we find one, we return a `?', but
1753 with the length of the invalid character. */
1755 static int
1756 string_char_and_length (const unsigned char *str, int *len)
1758 int c;
1760 c = STRING_CHAR_AND_LENGTH (str, *len);
1761 if (!CHAR_VALID_P (c))
1762 /* We may not change the length here because other places in Emacs
1763 don't use this function, i.e. they silently accept invalid
1764 characters. */
1765 c = '?';
1767 return c;
1772 /* Given a position POS containing a valid character and byte position
1773 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1775 static struct text_pos
1776 string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, ptrdiff_t nchars)
1778 eassert (STRINGP (string) && nchars >= 0);
1780 if (STRING_MULTIBYTE (string))
1782 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1783 int len;
1785 while (nchars--)
1787 string_char_and_length (p, &len);
1788 p += len;
1789 CHARPOS (pos) += 1;
1790 BYTEPOS (pos) += len;
1793 else
1794 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1796 return pos;
1800 /* Value is the text position, i.e. character and byte position,
1801 for character position CHARPOS in STRING. */
1803 static struct text_pos
1804 string_pos (ptrdiff_t charpos, Lisp_Object string)
1806 struct text_pos pos;
1807 eassert (STRINGP (string));
1808 eassert (charpos >= 0);
1809 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1810 return pos;
1814 /* Value is a text position, i.e. character and byte position, for
1815 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1816 means recognize multibyte characters. */
1818 static struct text_pos
1819 c_string_pos (ptrdiff_t charpos, const char *s, bool multibyte_p)
1821 struct text_pos pos;
1823 eassert (s != NULL);
1824 eassert (charpos >= 0);
1826 if (multibyte_p)
1828 int len;
1830 SET_TEXT_POS (pos, 0, 0);
1831 while (charpos--)
1833 string_char_and_length ((const unsigned char *) s, &len);
1834 s += len;
1835 CHARPOS (pos) += 1;
1836 BYTEPOS (pos) += len;
1839 else
1840 SET_TEXT_POS (pos, charpos, charpos);
1842 return pos;
1846 /* Value is the number of characters in C string S. MULTIBYTE_P
1847 non-zero means recognize multibyte characters. */
1849 static ptrdiff_t
1850 number_of_chars (const char *s, bool multibyte_p)
1852 ptrdiff_t nchars;
1854 if (multibyte_p)
1856 ptrdiff_t rest = strlen (s);
1857 int len;
1858 const unsigned char *p = (const unsigned char *) s;
1860 for (nchars = 0; rest > 0; ++nchars)
1862 string_char_and_length (p, &len);
1863 rest -= len, p += len;
1866 else
1867 nchars = strlen (s);
1869 return nchars;
1873 /* Compute byte position NEWPOS->bytepos corresponding to
1874 NEWPOS->charpos. POS is a known position in string STRING.
1875 NEWPOS->charpos must be >= POS.charpos. */
1877 static void
1878 compute_string_pos (struct text_pos *newpos, struct text_pos pos, Lisp_Object string)
1880 eassert (STRINGP (string));
1881 eassert (CHARPOS (*newpos) >= CHARPOS (pos));
1883 if (STRING_MULTIBYTE (string))
1884 *newpos = string_pos_nchars_ahead (pos, string,
1885 CHARPOS (*newpos) - CHARPOS (pos));
1886 else
1887 BYTEPOS (*newpos) = CHARPOS (*newpos);
1890 /* EXPORT:
1891 Return an estimation of the pixel height of mode or header lines on
1892 frame F. FACE_ID specifies what line's height to estimate. */
1895 estimate_mode_line_height (struct frame *f, enum face_id face_id)
1897 #ifdef HAVE_WINDOW_SYSTEM
1898 if (FRAME_WINDOW_P (f))
1900 int height = FONT_HEIGHT (FRAME_FONT (f));
1902 /* This function is called so early when Emacs starts that the face
1903 cache and mode line face are not yet initialized. */
1904 if (FRAME_FACE_CACHE (f))
1906 struct face *face = FACE_FROM_ID (f, face_id);
1907 if (face)
1909 if (face->font)
1910 height = FONT_HEIGHT (face->font);
1911 if (face->box_line_width > 0)
1912 height += 2 * face->box_line_width;
1916 return height;
1918 #endif
1920 return 1;
1923 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1924 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1925 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1926 not force the value into range. */
1928 void
1929 pixel_to_glyph_coords (struct frame *f, register int pix_x, register int pix_y,
1930 int *x, int *y, NativeRectangle *bounds, int noclip)
1933 #ifdef HAVE_WINDOW_SYSTEM
1934 if (FRAME_WINDOW_P (f))
1936 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1937 even for negative values. */
1938 if (pix_x < 0)
1939 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1940 if (pix_y < 0)
1941 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1943 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1944 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1946 if (bounds)
1947 STORE_NATIVE_RECT (*bounds,
1948 FRAME_COL_TO_PIXEL_X (f, pix_x),
1949 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1950 FRAME_COLUMN_WIDTH (f) - 1,
1951 FRAME_LINE_HEIGHT (f) - 1);
1953 /* PXW: Should we clip pixels before converting to columns/lines? */
1954 if (!noclip)
1956 if (pix_x < 0)
1957 pix_x = 0;
1958 else if (pix_x > FRAME_TOTAL_COLS (f))
1959 pix_x = FRAME_TOTAL_COLS (f);
1961 if (pix_y < 0)
1962 pix_y = 0;
1963 else if (pix_y > FRAME_TOTAL_LINES (f))
1964 pix_y = FRAME_TOTAL_LINES (f);
1967 #endif
1969 *x = pix_x;
1970 *y = pix_y;
1974 /* Find the glyph under window-relative coordinates X/Y in window W.
1975 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1976 strings. Return in *HPOS and *VPOS the row and column number of
1977 the glyph found. Return in *AREA the glyph area containing X.
1978 Value is a pointer to the glyph found or null if X/Y is not on
1979 text, or we can't tell because W's current matrix is not up to
1980 date. */
1982 static struct glyph *
1983 x_y_to_hpos_vpos (struct window *w, int x, int y, int *hpos, int *vpos,
1984 int *dx, int *dy, int *area)
1986 struct glyph *glyph, *end;
1987 struct glyph_row *row = NULL;
1988 int x0, i;
1990 /* Find row containing Y. Give up if some row is not enabled. */
1991 for (i = 0; i < w->current_matrix->nrows; ++i)
1993 row = MATRIX_ROW (w->current_matrix, i);
1994 if (!row->enabled_p)
1995 return NULL;
1996 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1997 break;
2000 *vpos = i;
2001 *hpos = 0;
2003 /* Give up if Y is not in the window. */
2004 if (i == w->current_matrix->nrows)
2005 return NULL;
2007 /* Get the glyph area containing X. */
2008 if (w->pseudo_window_p)
2010 *area = TEXT_AREA;
2011 x0 = 0;
2013 else
2015 if (x < window_box_left_offset (w, TEXT_AREA))
2017 *area = LEFT_MARGIN_AREA;
2018 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
2020 else if (x < window_box_right_offset (w, TEXT_AREA))
2022 *area = TEXT_AREA;
2023 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
2025 else
2027 *area = RIGHT_MARGIN_AREA;
2028 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
2032 /* Find glyph containing X. */
2033 glyph = row->glyphs[*area];
2034 end = glyph + row->used[*area];
2035 x -= x0;
2036 while (glyph < end && x >= glyph->pixel_width)
2038 x -= glyph->pixel_width;
2039 ++glyph;
2042 if (glyph == end)
2043 return NULL;
2045 if (dx)
2047 *dx = x;
2048 *dy = y - (row->y + row->ascent - glyph->ascent);
2051 *hpos = glyph - row->glyphs[*area];
2052 return glyph;
2055 /* Convert frame-relative x/y to coordinates relative to window W.
2056 Takes pseudo-windows into account. */
2058 static void
2059 frame_to_window_pixel_xy (struct window *w, int *x, int *y)
2061 if (w->pseudo_window_p)
2063 /* A pseudo-window is always full-width, and starts at the
2064 left edge of the frame, plus a frame border. */
2065 struct frame *f = XFRAME (w->frame);
2066 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
2067 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
2069 else
2071 *x -= WINDOW_LEFT_EDGE_X (w);
2072 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
2076 #ifdef HAVE_WINDOW_SYSTEM
2078 /* EXPORT:
2079 Return in RECTS[] at most N clipping rectangles for glyph string S.
2080 Return the number of stored rectangles. */
2083 get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int n)
2085 XRectangle r;
2087 if (n <= 0)
2088 return 0;
2090 if (s->row->full_width_p)
2092 /* Draw full-width. X coordinates are relative to S->w->left_col. */
2093 r.x = WINDOW_LEFT_EDGE_X (s->w);
2094 if (s->row->mode_line_p)
2095 r.width = WINDOW_PIXEL_WIDTH (s->w) - WINDOW_RIGHT_DIVIDER_WIDTH (s->w);
2096 else
2097 r.width = WINDOW_PIXEL_WIDTH (s->w);
2099 /* Unless displaying a mode or menu bar line, which are always
2100 fully visible, clip to the visible part of the row. */
2101 if (s->w->pseudo_window_p)
2102 r.height = s->row->visible_height;
2103 else
2104 r.height = s->height;
2106 else
2108 /* This is a text line that may be partially visible. */
2109 r.x = window_box_left (s->w, s->area);
2110 r.width = window_box_width (s->w, s->area);
2111 r.height = s->row->visible_height;
2114 if (s->clip_head)
2115 if (r.x < s->clip_head->x)
2117 if (r.width >= s->clip_head->x - r.x)
2118 r.width -= s->clip_head->x - r.x;
2119 else
2120 r.width = 0;
2121 r.x = s->clip_head->x;
2123 if (s->clip_tail)
2124 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
2126 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
2127 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
2128 else
2129 r.width = 0;
2132 /* If S draws overlapping rows, it's sufficient to use the top and
2133 bottom of the window for clipping because this glyph string
2134 intentionally draws over other lines. */
2135 if (s->for_overlaps)
2137 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2138 r.height = window_text_bottom_y (s->w) - r.y;
2140 /* Alas, the above simple strategy does not work for the
2141 environments with anti-aliased text: if the same text is
2142 drawn onto the same place multiple times, it gets thicker.
2143 If the overlap we are processing is for the erased cursor, we
2144 take the intersection with the rectangle of the cursor. */
2145 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
2147 XRectangle rc, r_save = r;
2149 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
2150 rc.y = s->w->phys_cursor.y;
2151 rc.width = s->w->phys_cursor_width;
2152 rc.height = s->w->phys_cursor_height;
2154 x_intersect_rectangles (&r_save, &rc, &r);
2157 else
2159 /* Don't use S->y for clipping because it doesn't take partially
2160 visible lines into account. For example, it can be negative for
2161 partially visible lines at the top of a window. */
2162 if (!s->row->full_width_p
2163 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
2164 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2165 else
2166 r.y = max (0, s->row->y);
2169 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
2171 /* If drawing the cursor, don't let glyph draw outside its
2172 advertised boundaries. Cleartype does this under some circumstances. */
2173 if (s->hl == DRAW_CURSOR)
2175 struct glyph *glyph = s->first_glyph;
2176 int height, max_y;
2178 if (s->x > r.x)
2180 if (r.width >= s->x - r.x)
2181 r.width -= s->x - r.x;
2182 else /* R2L hscrolled row with cursor outside text area */
2183 r.width = 0;
2184 r.x = s->x;
2186 r.width = min (r.width, glyph->pixel_width);
2188 /* If r.y is below window bottom, ensure that we still see a cursor. */
2189 height = min (glyph->ascent + glyph->descent,
2190 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
2191 max_y = window_text_bottom_y (s->w) - height;
2192 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
2193 if (s->ybase - glyph->ascent > max_y)
2195 r.y = max_y;
2196 r.height = height;
2198 else
2200 /* Don't draw cursor glyph taller than our actual glyph. */
2201 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
2202 if (height < r.height)
2204 max_y = r.y + r.height;
2205 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
2206 r.height = min (max_y - r.y, height);
2211 if (s->row->clip)
2213 XRectangle r_save = r;
2215 if (! x_intersect_rectangles (&r_save, s->row->clip, &r))
2216 r.width = 0;
2219 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
2220 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
2222 #ifdef CONVERT_FROM_XRECT
2223 CONVERT_FROM_XRECT (r, *rects);
2224 #else
2225 *rects = r;
2226 #endif
2227 return 1;
2229 else
2231 /* If we are processing overlapping and allowed to return
2232 multiple clipping rectangles, we exclude the row of the glyph
2233 string from the clipping rectangle. This is to avoid drawing
2234 the same text on the environment with anti-aliasing. */
2235 #ifdef CONVERT_FROM_XRECT
2236 XRectangle rs[2];
2237 #else
2238 XRectangle *rs = rects;
2239 #endif
2240 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
2242 if (s->for_overlaps & OVERLAPS_PRED)
2244 rs[i] = r;
2245 if (r.y + r.height > row_y)
2247 if (r.y < row_y)
2248 rs[i].height = row_y - r.y;
2249 else
2250 rs[i].height = 0;
2252 i++;
2254 if (s->for_overlaps & OVERLAPS_SUCC)
2256 rs[i] = r;
2257 if (r.y < row_y + s->row->visible_height)
2259 if (r.y + r.height > row_y + s->row->visible_height)
2261 rs[i].y = row_y + s->row->visible_height;
2262 rs[i].height = r.y + r.height - rs[i].y;
2264 else
2265 rs[i].height = 0;
2267 i++;
2270 n = i;
2271 #ifdef CONVERT_FROM_XRECT
2272 for (i = 0; i < n; i++)
2273 CONVERT_FROM_XRECT (rs[i], rects[i]);
2274 #endif
2275 return n;
2279 /* EXPORT:
2280 Return in *NR the clipping rectangle for glyph string S. */
2282 void
2283 get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr)
2285 get_glyph_string_clip_rects (s, nr, 1);
2289 /* EXPORT:
2290 Return the position and height of the phys cursor in window W.
2291 Set w->phys_cursor_width to width of phys cursor.
2294 void
2295 get_phys_cursor_geometry (struct window *w, struct glyph_row *row,
2296 struct glyph *glyph, int *xp, int *yp, int *heightp)
2298 struct frame *f = XFRAME (WINDOW_FRAME (w));
2299 int x, y, wd, h, h0, y0;
2301 /* Compute the width of the rectangle to draw. If on a stretch
2302 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2303 rectangle as wide as the glyph, but use a canonical character
2304 width instead. */
2305 wd = glyph->pixel_width - 1;
2306 #if defined (HAVE_NTGUI) || defined (HAVE_NS)
2307 wd++; /* Why? */
2308 #endif
2310 x = w->phys_cursor.x;
2311 if (x < 0)
2313 wd += x;
2314 x = 0;
2317 if (glyph->type == STRETCH_GLYPH
2318 && !x_stretch_cursor_p)
2319 wd = min (FRAME_COLUMN_WIDTH (f), wd);
2320 w->phys_cursor_width = wd;
2322 y = w->phys_cursor.y + row->ascent - glyph->ascent;
2324 /* If y is below window bottom, ensure that we still see a cursor. */
2325 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
2327 h = max (h0, glyph->ascent + glyph->descent);
2328 h0 = min (h0, glyph->ascent + glyph->descent);
2330 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
2331 if (y < y0)
2333 h = max (h - (y0 - y) + 1, h0);
2334 y = y0 - 1;
2336 else
2338 y0 = window_text_bottom_y (w) - h0;
2339 if (y > y0)
2341 h += y - y0;
2342 y = y0;
2346 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
2347 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
2348 *heightp = h;
2352 * Remember which glyph the mouse is over.
2355 void
2356 remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
2358 Lisp_Object window;
2359 struct window *w;
2360 struct glyph_row *r, *gr, *end_row;
2361 enum window_part part;
2362 enum glyph_row_area area;
2363 int x, y, width, height;
2365 /* Try to determine frame pixel position and size of the glyph under
2366 frame pixel coordinates X/Y on frame F. */
2368 if (window_resize_pixelwise)
2370 width = height = 1;
2371 goto virtual_glyph;
2373 else if (!f->glyphs_initialized_p
2374 || (window = window_from_coordinates (f, gx, gy, &part, 0),
2375 NILP (window)))
2377 width = FRAME_SMALLEST_CHAR_WIDTH (f);
2378 height = FRAME_SMALLEST_FONT_HEIGHT (f);
2379 goto virtual_glyph;
2382 w = XWINDOW (window);
2383 width = WINDOW_FRAME_COLUMN_WIDTH (w);
2384 height = WINDOW_FRAME_LINE_HEIGHT (w);
2386 x = window_relative_x_coord (w, part, gx);
2387 y = gy - WINDOW_TOP_EDGE_Y (w);
2389 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
2390 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
2392 if (w->pseudo_window_p)
2394 area = TEXT_AREA;
2395 part = ON_MODE_LINE; /* Don't adjust margin. */
2396 goto text_glyph;
2399 switch (part)
2401 case ON_LEFT_MARGIN:
2402 area = LEFT_MARGIN_AREA;
2403 goto text_glyph;
2405 case ON_RIGHT_MARGIN:
2406 area = RIGHT_MARGIN_AREA;
2407 goto text_glyph;
2409 case ON_HEADER_LINE:
2410 case ON_MODE_LINE:
2411 gr = (part == ON_HEADER_LINE
2412 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
2413 : MATRIX_MODE_LINE_ROW (w->current_matrix));
2414 gy = gr->y;
2415 area = TEXT_AREA;
2416 goto text_glyph_row_found;
2418 case ON_TEXT:
2419 area = TEXT_AREA;
2421 text_glyph:
2422 gr = 0; gy = 0;
2423 for (; r <= end_row && r->enabled_p; ++r)
2424 if (r->y + r->height > y)
2426 gr = r; gy = r->y;
2427 break;
2430 text_glyph_row_found:
2431 if (gr && gy <= y)
2433 struct glyph *g = gr->glyphs[area];
2434 struct glyph *end = g + gr->used[area];
2436 height = gr->height;
2437 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2438 if (gx + g->pixel_width > x)
2439 break;
2441 if (g < end)
2443 if (g->type == IMAGE_GLYPH)
2445 /* Don't remember when mouse is over image, as
2446 image may have hot-spots. */
2447 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2448 return;
2450 width = g->pixel_width;
2452 else
2454 /* Use nominal char spacing at end of line. */
2455 x -= gx;
2456 gx += (x / width) * width;
2459 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2461 gx += window_box_left_offset (w, area);
2462 /* Don't expand over the modeline to make sure the vertical
2463 drag cursor is shown early enough. */
2464 height = min (height,
2465 max (0, WINDOW_BOX_HEIGHT_NO_MODE_LINE (w) - gy));
2468 else
2470 /* Use nominal line height at end of window. */
2471 gx = (x / width) * width;
2472 y -= gy;
2473 gy += (y / height) * height;
2474 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2475 /* See comment above. */
2476 height = min (height,
2477 max (0, WINDOW_BOX_HEIGHT_NO_MODE_LINE (w) - gy));
2479 break;
2481 case ON_LEFT_FRINGE:
2482 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2483 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2484 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2485 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2486 goto row_glyph;
2488 case ON_RIGHT_FRINGE:
2489 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2490 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2491 : window_box_right_offset (w, TEXT_AREA));
2492 if (WINDOW_RIGHT_DIVIDER_WIDTH (w) == 0
2493 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w)
2494 && !WINDOW_RIGHTMOST_P (w))
2495 if (gx < WINDOW_PIXEL_WIDTH (w) - width)
2496 /* Make sure the vertical border can get her own glyph to the
2497 right of the one we build here. */
2498 width = WINDOW_RIGHT_FRINGE_WIDTH (w) - width;
2499 else
2500 width = WINDOW_PIXEL_WIDTH (w) - gx;
2501 else
2502 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2504 goto row_glyph;
2506 case ON_VERTICAL_BORDER:
2507 gx = WINDOW_PIXEL_WIDTH (w) - width;
2508 goto row_glyph;
2510 case ON_VERTICAL_SCROLL_BAR:
2511 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2513 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2514 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2515 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2516 : 0)));
2517 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2519 row_glyph:
2520 gr = 0, gy = 0;
2521 for (; r <= end_row && r->enabled_p; ++r)
2522 if (r->y + r->height > y)
2524 gr = r; gy = r->y;
2525 break;
2528 if (gr && gy <= y)
2529 height = gr->height;
2530 else
2532 /* Use nominal line height at end of window. */
2533 y -= gy;
2534 gy += (y / height) * height;
2536 break;
2538 case ON_RIGHT_DIVIDER:
2539 gx = WINDOW_PIXEL_WIDTH (w) - WINDOW_RIGHT_DIVIDER_WIDTH (w);
2540 width = WINDOW_RIGHT_DIVIDER_WIDTH (w);
2541 gy = 0;
2542 /* The bottom divider prevails. */
2543 height = WINDOW_PIXEL_HEIGHT (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
2544 goto add_edge;
2546 case ON_BOTTOM_DIVIDER:
2547 gx = 0;
2548 width = WINDOW_PIXEL_WIDTH (w);
2549 gy = WINDOW_PIXEL_HEIGHT (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
2550 height = WINDOW_BOTTOM_DIVIDER_WIDTH (w);
2551 goto add_edge;
2553 default:
2555 virtual_glyph:
2556 /* If there is no glyph under the mouse, then we divide the screen
2557 into a grid of the smallest glyph in the frame, and use that
2558 as our "glyph". */
2560 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2561 round down even for negative values. */
2562 if (gx < 0)
2563 gx -= width - 1;
2564 if (gy < 0)
2565 gy -= height - 1;
2567 gx = (gx / width) * width;
2568 gy = (gy / height) * height;
2570 goto store_rect;
2573 add_edge:
2574 gx += WINDOW_LEFT_EDGE_X (w);
2575 gy += WINDOW_TOP_EDGE_Y (w);
2577 store_rect:
2578 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2580 /* Visible feedback for debugging. */
2581 #if 0
2582 #if HAVE_X_WINDOWS
2583 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2584 f->output_data.x->normal_gc,
2585 gx, gy, width, height);
2586 #endif
2587 #endif
2591 #endif /* HAVE_WINDOW_SYSTEM */
2593 static void
2594 adjust_window_ends (struct window *w, struct glyph_row *row, bool current)
2596 eassert (w);
2597 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
2598 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
2599 w->window_end_vpos
2600 = MATRIX_ROW_VPOS (row, current ? w->current_matrix : w->desired_matrix);
2603 /***********************************************************************
2604 Lisp form evaluation
2605 ***********************************************************************/
2607 /* Error handler for safe_eval and safe_call. */
2609 static Lisp_Object
2610 safe_eval_handler (Lisp_Object arg, ptrdiff_t nargs, Lisp_Object *args)
2612 add_to_log ("Error during redisplay: %S signaled %S",
2613 Flist (nargs, args), arg);
2614 return Qnil;
2617 /* Call function FUNC with the rest of NARGS - 1 arguments
2618 following. Return the result, or nil if something went
2619 wrong. Prevent redisplay during the evaluation. */
2621 static Lisp_Object
2622 safe__call (bool inhibit_quit, ptrdiff_t nargs, Lisp_Object func, va_list ap)
2624 Lisp_Object val;
2626 if (inhibit_eval_during_redisplay)
2627 val = Qnil;
2628 else
2630 ptrdiff_t i;
2631 ptrdiff_t count = SPECPDL_INDEX ();
2632 Lisp_Object *args;
2633 USE_SAFE_ALLOCA;
2634 SAFE_ALLOCA_LISP (args, nargs);
2636 args[0] = func;
2637 for (i = 1; i < nargs; i++)
2638 args[i] = va_arg (ap, Lisp_Object);
2640 specbind (Qinhibit_redisplay, Qt);
2641 if (inhibit_quit)
2642 specbind (Qinhibit_quit, Qt);
2643 /* Use Qt to ensure debugger does not run,
2644 so there is no possibility of wanting to redisplay. */
2645 val = internal_condition_case_n (Ffuncall, nargs, args, Qt,
2646 safe_eval_handler);
2647 SAFE_FREE ();
2648 val = unbind_to (count, val);
2651 return val;
2654 Lisp_Object
2655 safe_call (ptrdiff_t nargs, Lisp_Object func, ...)
2657 Lisp_Object retval;
2658 va_list ap;
2660 va_start (ap, func);
2661 retval = safe__call (false, nargs, func, ap);
2662 va_end (ap);
2663 return retval;
2666 /* Call function FN with one argument ARG.
2667 Return the result, or nil if something went wrong. */
2669 Lisp_Object
2670 safe_call1 (Lisp_Object fn, Lisp_Object arg)
2672 return safe_call (2, fn, arg);
2675 static Lisp_Object
2676 safe__call1 (bool inhibit_quit, Lisp_Object fn, ...)
2678 Lisp_Object retval;
2679 va_list ap;
2681 va_start (ap, fn);
2682 retval = safe__call (inhibit_quit, 2, fn, ap);
2683 va_end (ap);
2684 return retval;
2687 static Lisp_Object Qeval;
2689 Lisp_Object
2690 safe_eval (Lisp_Object sexpr)
2692 return safe__call1 (false, Qeval, sexpr);
2695 static Lisp_Object
2696 safe__eval (bool inhibit_quit, Lisp_Object sexpr)
2698 return safe__call1 (inhibit_quit, Qeval, sexpr);
2701 /* Call function FN with two arguments ARG1 and ARG2.
2702 Return the result, or nil if something went wrong. */
2704 Lisp_Object
2705 safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
2707 return safe_call (3, fn, arg1, arg2);
2712 /***********************************************************************
2713 Debugging
2714 ***********************************************************************/
2716 #if 0
2718 /* Define CHECK_IT to perform sanity checks on iterators.
2719 This is for debugging. It is too slow to do unconditionally. */
2721 static void
2722 check_it (struct it *it)
2724 if (it->method == GET_FROM_STRING)
2726 eassert (STRINGP (it->string));
2727 eassert (IT_STRING_CHARPOS (*it) >= 0);
2729 else
2731 eassert (IT_STRING_CHARPOS (*it) < 0);
2732 if (it->method == GET_FROM_BUFFER)
2734 /* Check that character and byte positions agree. */
2735 eassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2739 if (it->dpvec)
2740 eassert (it->current.dpvec_index >= 0);
2741 else
2742 eassert (it->current.dpvec_index < 0);
2745 #define CHECK_IT(IT) check_it ((IT))
2747 #else /* not 0 */
2749 #define CHECK_IT(IT) (void) 0
2751 #endif /* not 0 */
2754 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2756 /* Check that the window end of window W is what we expect it
2757 to be---the last row in the current matrix displaying text. */
2759 static void
2760 check_window_end (struct window *w)
2762 if (!MINI_WINDOW_P (w) && w->window_end_valid)
2764 struct glyph_row *row;
2765 eassert ((row = MATRIX_ROW (w->current_matrix, w->window_end_vpos),
2766 !row->enabled_p
2767 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2768 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2772 #define CHECK_WINDOW_END(W) check_window_end ((W))
2774 #else
2776 #define CHECK_WINDOW_END(W) (void) 0
2778 #endif /* GLYPH_DEBUG and ENABLE_CHECKING */
2780 /***********************************************************************
2781 Iterator initialization
2782 ***********************************************************************/
2784 /* Initialize IT for displaying current_buffer in window W, starting
2785 at character position CHARPOS. CHARPOS < 0 means that no buffer
2786 position is specified which is useful when the iterator is assigned
2787 a position later. BYTEPOS is the byte position corresponding to
2788 CHARPOS.
2790 If ROW is not null, calls to produce_glyphs with IT as parameter
2791 will produce glyphs in that row.
2793 BASE_FACE_ID is the id of a base face to use. It must be one of
2794 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2795 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2796 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2798 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2799 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2800 will be initialized to use the corresponding mode line glyph row of
2801 the desired matrix of W. */
2803 void
2804 init_iterator (struct it *it, struct window *w,
2805 ptrdiff_t charpos, ptrdiff_t bytepos,
2806 struct glyph_row *row, enum face_id base_face_id)
2808 enum face_id remapped_base_face_id = base_face_id;
2810 /* Some precondition checks. */
2811 eassert (w != NULL && it != NULL);
2812 eassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2813 && charpos <= ZV));
2815 /* If face attributes have been changed since the last redisplay,
2816 free realized faces now because they depend on face definitions
2817 that might have changed. Don't free faces while there might be
2818 desired matrices pending which reference these faces. */
2819 if (face_change_count && !inhibit_free_realized_faces)
2821 face_change_count = 0;
2822 free_all_realized_faces (Qnil);
2825 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
2826 if (! NILP (Vface_remapping_alist))
2827 remapped_base_face_id
2828 = lookup_basic_face (XFRAME (w->frame), base_face_id);
2830 /* Use one of the mode line rows of W's desired matrix if
2831 appropriate. */
2832 if (row == NULL)
2834 if (base_face_id == MODE_LINE_FACE_ID
2835 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2836 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2837 else if (base_face_id == HEADER_LINE_FACE_ID)
2838 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2841 /* Clear IT. */
2842 memset (it, 0, sizeof *it);
2843 it->current.overlay_string_index = -1;
2844 it->current.dpvec_index = -1;
2845 it->base_face_id = remapped_base_face_id;
2846 it->string = Qnil;
2847 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2848 it->paragraph_embedding = L2R;
2849 it->bidi_it.string.lstring = Qnil;
2850 it->bidi_it.string.s = NULL;
2851 it->bidi_it.string.bufpos = 0;
2852 it->bidi_it.w = w;
2854 /* The window in which we iterate over current_buffer: */
2855 XSETWINDOW (it->window, w);
2856 it->w = w;
2857 it->f = XFRAME (w->frame);
2859 it->cmp_it.id = -1;
2861 /* Extra space between lines (on window systems only). */
2862 if (base_face_id == DEFAULT_FACE_ID
2863 && FRAME_WINDOW_P (it->f))
2865 if (NATNUMP (BVAR (current_buffer, extra_line_spacing)))
2866 it->extra_line_spacing = XFASTINT (BVAR (current_buffer, extra_line_spacing));
2867 else if (FLOATP (BVAR (current_buffer, extra_line_spacing)))
2868 it->extra_line_spacing = (XFLOAT_DATA (BVAR (current_buffer, extra_line_spacing))
2869 * FRAME_LINE_HEIGHT (it->f));
2870 else if (it->f->extra_line_spacing > 0)
2871 it->extra_line_spacing = it->f->extra_line_spacing;
2872 it->max_extra_line_spacing = 0;
2875 /* If realized faces have been removed, e.g. because of face
2876 attribute changes of named faces, recompute them. When running
2877 in batch mode, the face cache of the initial frame is null. If
2878 we happen to get called, make a dummy face cache. */
2879 if (FRAME_FACE_CACHE (it->f) == NULL)
2880 init_frame_faces (it->f);
2881 if (FRAME_FACE_CACHE (it->f)->used == 0)
2882 recompute_basic_faces (it->f);
2884 /* Current value of the `slice', `space-width', and 'height' properties. */
2885 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2886 it->space_width = Qnil;
2887 it->font_height = Qnil;
2888 it->override_ascent = -1;
2890 /* Are control characters displayed as `^C'? */
2891 it->ctl_arrow_p = !NILP (BVAR (current_buffer, ctl_arrow));
2893 /* -1 means everything between a CR and the following line end
2894 is invisible. >0 means lines indented more than this value are
2895 invisible. */
2896 it->selective = (INTEGERP (BVAR (current_buffer, selective_display))
2897 ? (clip_to_bounds
2898 (-1, XINT (BVAR (current_buffer, selective_display)),
2899 PTRDIFF_MAX))
2900 : (!NILP (BVAR (current_buffer, selective_display))
2901 ? -1 : 0));
2902 it->selective_display_ellipsis_p
2903 = !NILP (BVAR (current_buffer, selective_display_ellipses));
2905 /* Display table to use. */
2906 it->dp = window_display_table (w);
2908 /* Are multibyte characters enabled in current_buffer? */
2909 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
2911 /* Get the position at which the redisplay_end_trigger hook should
2912 be run, if it is to be run at all. */
2913 if (MARKERP (w->redisplay_end_trigger)
2914 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2915 it->redisplay_end_trigger_charpos
2916 = marker_position (w->redisplay_end_trigger);
2917 else if (INTEGERP (w->redisplay_end_trigger))
2918 it->redisplay_end_trigger_charpos
2919 = clip_to_bounds (PTRDIFF_MIN, XINT (w->redisplay_end_trigger),
2920 PTRDIFF_MAX);
2922 it->tab_width = SANE_TAB_WIDTH (current_buffer);
2924 /* Are lines in the display truncated? */
2925 if (base_face_id != DEFAULT_FACE_ID
2926 || it->w->hscroll
2927 || (! WINDOW_FULL_WIDTH_P (it->w)
2928 && ((!NILP (Vtruncate_partial_width_windows)
2929 && !INTEGERP (Vtruncate_partial_width_windows))
2930 || (INTEGERP (Vtruncate_partial_width_windows)
2931 /* PXW: Shall we do something about this? */
2932 && (WINDOW_TOTAL_COLS (it->w)
2933 < XINT (Vtruncate_partial_width_windows))))))
2934 it->line_wrap = TRUNCATE;
2935 else if (NILP (BVAR (current_buffer, truncate_lines)))
2936 it->line_wrap = NILP (BVAR (current_buffer, word_wrap))
2937 ? WINDOW_WRAP : WORD_WRAP;
2938 else
2939 it->line_wrap = TRUNCATE;
2941 /* Get dimensions of truncation and continuation glyphs. These are
2942 displayed as fringe bitmaps under X, but we need them for such
2943 frames when the fringes are turned off. But leave the dimensions
2944 zero for tooltip frames, as these glyphs look ugly there and also
2945 sabotage calculations of tooltip dimensions in x-show-tip. */
2946 #ifdef HAVE_WINDOW_SYSTEM
2947 if (!(FRAME_WINDOW_P (it->f)
2948 && FRAMEP (tip_frame)
2949 && it->f == XFRAME (tip_frame)))
2950 #endif
2952 if (it->line_wrap == TRUNCATE)
2954 /* We will need the truncation glyph. */
2955 eassert (it->glyph_row == NULL);
2956 produce_special_glyphs (it, IT_TRUNCATION);
2957 it->truncation_pixel_width = it->pixel_width;
2959 else
2961 /* We will need the continuation glyph. */
2962 eassert (it->glyph_row == NULL);
2963 produce_special_glyphs (it, IT_CONTINUATION);
2964 it->continuation_pixel_width = it->pixel_width;
2968 /* Reset these values to zero because the produce_special_glyphs
2969 above has changed them. */
2970 it->pixel_width = it->ascent = it->descent = 0;
2971 it->phys_ascent = it->phys_descent = 0;
2973 /* Set this after getting the dimensions of truncation and
2974 continuation glyphs, so that we don't produce glyphs when calling
2975 produce_special_glyphs, above. */
2976 it->glyph_row = row;
2977 it->area = TEXT_AREA;
2979 /* Get the dimensions of the display area. The display area
2980 consists of the visible window area plus a horizontally scrolled
2981 part to the left of the window. All x-values are relative to the
2982 start of this total display area. */
2983 if (base_face_id != DEFAULT_FACE_ID)
2985 /* Mode lines, menu bar in terminal frames. */
2986 it->first_visible_x = 0;
2987 it->last_visible_x = WINDOW_PIXEL_WIDTH (w);
2989 else
2991 it->first_visible_x
2992 = window_hscroll_limited (it->w, it->f) * FRAME_COLUMN_WIDTH (it->f);
2993 it->last_visible_x = (it->first_visible_x
2994 + window_box_width (w, TEXT_AREA));
2996 /* If we truncate lines, leave room for the truncation glyph(s) at
2997 the right margin. Otherwise, leave room for the continuation
2998 glyph(s). Done only if the window has no right fringe. */
2999 if (WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0)
3001 if (it->line_wrap == TRUNCATE)
3002 it->last_visible_x -= it->truncation_pixel_width;
3003 else
3004 it->last_visible_x -= it->continuation_pixel_width;
3007 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
3008 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
3011 /* Leave room for a border glyph. */
3012 if (!FRAME_WINDOW_P (it->f)
3013 && !WINDOW_RIGHTMOST_P (it->w))
3014 it->last_visible_x -= 1;
3016 it->last_visible_y = window_text_bottom_y (w);
3018 /* For mode lines and alike, arrange for the first glyph having a
3019 left box line if the face specifies a box. */
3020 if (base_face_id != DEFAULT_FACE_ID)
3022 struct face *face;
3024 it->face_id = remapped_base_face_id;
3026 /* If we have a boxed mode line, make the first character appear
3027 with a left box line. */
3028 face = FACE_FROM_ID (it->f, remapped_base_face_id);
3029 if (face && face->box != FACE_NO_BOX)
3030 it->start_of_box_run_p = true;
3033 /* If a buffer position was specified, set the iterator there,
3034 getting overlays and face properties from that position. */
3035 if (charpos >= BUF_BEG (current_buffer))
3037 it->stop_charpos = charpos;
3038 it->end_charpos = ZV;
3039 eassert (charpos == BYTE_TO_CHAR (bytepos));
3040 IT_CHARPOS (*it) = charpos;
3041 IT_BYTEPOS (*it) = bytepos;
3043 /* We will rely on `reseat' to set this up properly, via
3044 handle_face_prop. */
3045 it->face_id = it->base_face_id;
3047 it->start = it->current;
3048 /* Do we need to reorder bidirectional text? Not if this is a
3049 unibyte buffer: by definition, none of the single-byte
3050 characters are strong R2L, so no reordering is needed. And
3051 bidi.c doesn't support unibyte buffers anyway. Also, don't
3052 reorder while we are loading loadup.el, since the tables of
3053 character properties needed for reordering are not yet
3054 available. */
3055 it->bidi_p =
3056 NILP (Vpurify_flag)
3057 && !NILP (BVAR (current_buffer, bidi_display_reordering))
3058 && it->multibyte_p;
3060 /* If we are to reorder bidirectional text, init the bidi
3061 iterator. */
3062 if (it->bidi_p)
3064 /* Since we don't know at this point whether there will be
3065 any R2L lines in the window, we reserve space for
3066 truncation/continuation glyphs even if only the left
3067 fringe is absent. */
3068 if (base_face_id == DEFAULT_FACE_ID
3069 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0
3070 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) != 0)
3072 if (it->line_wrap == TRUNCATE)
3073 it->last_visible_x -= it->truncation_pixel_width;
3074 else
3075 it->last_visible_x -= it->continuation_pixel_width;
3077 /* Note the paragraph direction that this buffer wants to
3078 use. */
3079 if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
3080 Qleft_to_right))
3081 it->paragraph_embedding = L2R;
3082 else if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
3083 Qright_to_left))
3084 it->paragraph_embedding = R2L;
3085 else
3086 it->paragraph_embedding = NEUTRAL_DIR;
3087 bidi_unshelve_cache (NULL, 0);
3088 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
3089 &it->bidi_it);
3092 /* Compute faces etc. */
3093 reseat (it, it->current.pos, 1);
3096 CHECK_IT (it);
3100 /* Initialize IT for the display of window W with window start POS. */
3102 void
3103 start_display (struct it *it, struct window *w, struct text_pos pos)
3105 struct glyph_row *row;
3106 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
3108 row = w->desired_matrix->rows + first_vpos;
3109 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
3110 it->first_vpos = first_vpos;
3112 /* Don't reseat to previous visible line start if current start
3113 position is in a string or image. */
3114 if (it->method == GET_FROM_BUFFER && it->line_wrap != TRUNCATE)
3116 int start_at_line_beg_p;
3117 int first_y = it->current_y;
3119 /* If window start is not at a line start, skip forward to POS to
3120 get the correct continuation lines width. */
3121 start_at_line_beg_p = (CHARPOS (pos) == BEGV
3122 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
3123 if (!start_at_line_beg_p)
3125 int new_x;
3127 reseat_at_previous_visible_line_start (it);
3128 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
3130 new_x = it->current_x + it->pixel_width;
3132 /* If lines are continued, this line may end in the middle
3133 of a multi-glyph character (e.g. a control character
3134 displayed as \003, or in the middle of an overlay
3135 string). In this case move_it_to above will not have
3136 taken us to the start of the continuation line but to the
3137 end of the continued line. */
3138 if (it->current_x > 0
3139 && it->line_wrap != TRUNCATE /* Lines are continued. */
3140 && (/* And glyph doesn't fit on the line. */
3141 new_x > it->last_visible_x
3142 /* Or it fits exactly and we're on a window
3143 system frame. */
3144 || (new_x == it->last_visible_x
3145 && FRAME_WINDOW_P (it->f)
3146 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
3147 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
3148 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
3150 if ((it->current.dpvec_index >= 0
3151 || it->current.overlay_string_index >= 0)
3152 /* If we are on a newline from a display vector or
3153 overlay string, then we are already at the end of
3154 a screen line; no need to go to the next line in
3155 that case, as this line is not really continued.
3156 (If we do go to the next line, C-e will not DTRT.) */
3157 && it->c != '\n')
3159 set_iterator_to_next (it, 1);
3160 move_it_in_display_line_to (it, -1, -1, 0);
3163 it->continuation_lines_width += it->current_x;
3165 /* If the character at POS is displayed via a display
3166 vector, move_it_to above stops at the final glyph of
3167 IT->dpvec. To make the caller redisplay that character
3168 again (a.k.a. start at POS), we need to reset the
3169 dpvec_index to the beginning of IT->dpvec. */
3170 else if (it->current.dpvec_index >= 0)
3171 it->current.dpvec_index = 0;
3173 /* We're starting a new display line, not affected by the
3174 height of the continued line, so clear the appropriate
3175 fields in the iterator structure. */
3176 it->max_ascent = it->max_descent = 0;
3177 it->max_phys_ascent = it->max_phys_descent = 0;
3179 it->current_y = first_y;
3180 it->vpos = 0;
3181 it->current_x = it->hpos = 0;
3187 /* Return 1 if POS is a position in ellipses displayed for invisible
3188 text. W is the window we display, for text property lookup. */
3190 static int
3191 in_ellipses_for_invisible_text_p (struct display_pos *pos, struct window *w)
3193 Lisp_Object prop, window;
3194 int ellipses_p = 0;
3195 ptrdiff_t charpos = CHARPOS (pos->pos);
3197 /* If POS specifies a position in a display vector, this might
3198 be for an ellipsis displayed for invisible text. We won't
3199 get the iterator set up for delivering that ellipsis unless
3200 we make sure that it gets aware of the invisible text. */
3201 if (pos->dpvec_index >= 0
3202 && pos->overlay_string_index < 0
3203 && CHARPOS (pos->string_pos) < 0
3204 && charpos > BEGV
3205 && (XSETWINDOW (window, w),
3206 prop = Fget_char_property (make_number (charpos),
3207 Qinvisible, window),
3208 !TEXT_PROP_MEANS_INVISIBLE (prop)))
3210 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
3211 window);
3212 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
3215 return ellipses_p;
3219 /* Initialize IT for stepping through current_buffer in window W,
3220 starting at position POS that includes overlay string and display
3221 vector/ control character translation position information. Value
3222 is zero if there are overlay strings with newlines at POS. */
3224 static int
3225 init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos)
3227 ptrdiff_t charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
3228 int i, overlay_strings_with_newlines = 0;
3230 /* If POS specifies a position in a display vector, this might
3231 be for an ellipsis displayed for invisible text. We won't
3232 get the iterator set up for delivering that ellipsis unless
3233 we make sure that it gets aware of the invisible text. */
3234 if (in_ellipses_for_invisible_text_p (pos, w))
3236 --charpos;
3237 bytepos = 0;
3240 /* Keep in mind: the call to reseat in init_iterator skips invisible
3241 text, so we might end up at a position different from POS. This
3242 is only a problem when POS is a row start after a newline and an
3243 overlay starts there with an after-string, and the overlay has an
3244 invisible property. Since we don't skip invisible text in
3245 display_line and elsewhere immediately after consuming the
3246 newline before the row start, such a POS will not be in a string,
3247 but the call to init_iterator below will move us to the
3248 after-string. */
3249 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
3251 /* This only scans the current chunk -- it should scan all chunks.
3252 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
3253 to 16 in 22.1 to make this a lesser problem. */
3254 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
3256 const char *s = SSDATA (it->overlay_strings[i]);
3257 const char *e = s + SBYTES (it->overlay_strings[i]);
3259 while (s < e && *s != '\n')
3260 ++s;
3262 if (s < e)
3264 overlay_strings_with_newlines = 1;
3265 break;
3269 /* If position is within an overlay string, set up IT to the right
3270 overlay string. */
3271 if (pos->overlay_string_index >= 0)
3273 int relative_index;
3275 /* If the first overlay string happens to have a `display'
3276 property for an image, the iterator will be set up for that
3277 image, and we have to undo that setup first before we can
3278 correct the overlay string index. */
3279 if (it->method == GET_FROM_IMAGE)
3280 pop_it (it);
3282 /* We already have the first chunk of overlay strings in
3283 IT->overlay_strings. Load more until the one for
3284 pos->overlay_string_index is in IT->overlay_strings. */
3285 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
3287 ptrdiff_t n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
3288 it->current.overlay_string_index = 0;
3289 while (n--)
3291 load_overlay_strings (it, 0);
3292 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
3296 it->current.overlay_string_index = pos->overlay_string_index;
3297 relative_index = (it->current.overlay_string_index
3298 % OVERLAY_STRING_CHUNK_SIZE);
3299 it->string = it->overlay_strings[relative_index];
3300 eassert (STRINGP (it->string));
3301 it->current.string_pos = pos->string_pos;
3302 it->method = GET_FROM_STRING;
3303 it->end_charpos = SCHARS (it->string);
3304 /* Set up the bidi iterator for this overlay string. */
3305 if (it->bidi_p)
3307 it->bidi_it.string.lstring = it->string;
3308 it->bidi_it.string.s = NULL;
3309 it->bidi_it.string.schars = SCHARS (it->string);
3310 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
3311 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
3312 it->bidi_it.string.unibyte = !it->multibyte_p;
3313 it->bidi_it.w = it->w;
3314 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3315 FRAME_WINDOW_P (it->f), &it->bidi_it);
3317 /* Synchronize the state of the bidi iterator with
3318 pos->string_pos. For any string position other than
3319 zero, this will be done automagically when we resume
3320 iteration over the string and get_visually_first_element
3321 is called. But if string_pos is zero, and the string is
3322 to be reordered for display, we need to resync manually,
3323 since it could be that the iteration state recorded in
3324 pos ended at string_pos of 0 moving backwards in string. */
3325 if (CHARPOS (pos->string_pos) == 0)
3327 get_visually_first_element (it);
3328 if (IT_STRING_CHARPOS (*it) != 0)
3329 do {
3330 /* Paranoia. */
3331 eassert (it->bidi_it.charpos < it->bidi_it.string.schars);
3332 bidi_move_to_visually_next (&it->bidi_it);
3333 } while (it->bidi_it.charpos != 0);
3335 eassert (IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
3336 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos);
3340 if (CHARPOS (pos->string_pos) >= 0)
3342 /* Recorded position is not in an overlay string, but in another
3343 string. This can only be a string from a `display' property.
3344 IT should already be filled with that string. */
3345 it->current.string_pos = pos->string_pos;
3346 eassert (STRINGP (it->string));
3347 if (it->bidi_p)
3348 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3349 FRAME_WINDOW_P (it->f), &it->bidi_it);
3352 /* Restore position in display vector translations, control
3353 character translations or ellipses. */
3354 if (pos->dpvec_index >= 0)
3356 if (it->dpvec == NULL)
3357 get_next_display_element (it);
3358 eassert (it->dpvec && it->current.dpvec_index == 0);
3359 it->current.dpvec_index = pos->dpvec_index;
3362 CHECK_IT (it);
3363 return !overlay_strings_with_newlines;
3367 /* Initialize IT for stepping through current_buffer in window W
3368 starting at ROW->start. */
3370 static void
3371 init_to_row_start (struct it *it, struct window *w, struct glyph_row *row)
3373 init_from_display_pos (it, w, &row->start);
3374 it->start = row->start;
3375 it->continuation_lines_width = row->continuation_lines_width;
3376 CHECK_IT (it);
3380 /* Initialize IT for stepping through current_buffer in window W
3381 starting in the line following ROW, i.e. starting at ROW->end.
3382 Value is zero if there are overlay strings with newlines at ROW's
3383 end position. */
3385 static int
3386 init_to_row_end (struct it *it, struct window *w, struct glyph_row *row)
3388 int success = 0;
3390 if (init_from_display_pos (it, w, &row->end))
3392 if (row->continued_p)
3393 it->continuation_lines_width
3394 = row->continuation_lines_width + row->pixel_width;
3395 CHECK_IT (it);
3396 success = 1;
3399 return success;
3405 /***********************************************************************
3406 Text properties
3407 ***********************************************************************/
3409 /* Called when IT reaches IT->stop_charpos. Handle text property and
3410 overlay changes. Set IT->stop_charpos to the next position where
3411 to stop. */
3413 static void
3414 handle_stop (struct it *it)
3416 enum prop_handled handled;
3417 int handle_overlay_change_p;
3418 struct props *p;
3420 it->dpvec = NULL;
3421 it->current.dpvec_index = -1;
3422 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
3423 it->ignore_overlay_strings_at_pos_p = 0;
3424 it->ellipsis_p = 0;
3426 /* Use face of preceding text for ellipsis (if invisible) */
3427 if (it->selective_display_ellipsis_p)
3428 it->saved_face_id = it->face_id;
3430 /* Here's the description of the semantics of, and the logic behind,
3431 the various HANDLED_* statuses:
3433 HANDLED_NORMALLY means the handler did its job, and the loop
3434 should proceed to calling the next handler in order.
3436 HANDLED_RECOMPUTE_PROPS means the handler caused a significant
3437 change in the properties and overlays at current position, so the
3438 loop should be restarted, to re-invoke the handlers that were
3439 already called. This happens when fontification-functions were
3440 called by handle_fontified_prop, and actually fontified
3441 something. Another case where HANDLED_RECOMPUTE_PROPS is
3442 returned is when we discover overlay strings that need to be
3443 displayed right away. The loop below will continue for as long
3444 as the status is HANDLED_RECOMPUTE_PROPS.
3446 HANDLED_RETURN means return immediately to the caller, to
3447 continue iteration without calling any further handlers. This is
3448 used when we need to act on some property right away, for example
3449 when we need to display the ellipsis or a replacing display
3450 property, such as display string or image.
3452 HANDLED_OVERLAY_STRING_CONSUMED means an overlay string was just
3453 consumed, and the handler switched to the next overlay string.
3454 This signals the loop below to refrain from looking for more
3455 overlays before all the overlay strings of the current overlay
3456 are processed.
3458 Some of the handlers called by the loop push the iterator state
3459 onto the stack (see 'push_it'), and arrange for the iteration to
3460 continue with another object, such as an image, a display string,
3461 or an overlay string. In most such cases, it->stop_charpos is
3462 set to the first character of the string, so that when the
3463 iteration resumes, this function will immediately be called
3464 again, to examine the properties at the beginning of the string.
3466 When a display or overlay string is exhausted, the iterator state
3467 is popped (see 'pop_it'), and iteration continues with the
3468 previous object. Again, in many such cases this function is
3469 called again to find the next position where properties might
3470 change. */
3474 handled = HANDLED_NORMALLY;
3476 /* Call text property handlers. */
3477 for (p = it_props; p->handler; ++p)
3479 handled = p->handler (it);
3481 if (handled == HANDLED_RECOMPUTE_PROPS)
3482 break;
3483 else if (handled == HANDLED_RETURN)
3485 /* We still want to show before and after strings from
3486 overlays even if the actual buffer text is replaced. */
3487 if (!handle_overlay_change_p
3488 || it->sp > 1
3489 /* Don't call get_overlay_strings_1 if we already
3490 have overlay strings loaded, because doing so
3491 will load them again and push the iterator state
3492 onto the stack one more time, which is not
3493 expected by the rest of the code that processes
3494 overlay strings. */
3495 || (it->current.overlay_string_index < 0
3496 ? !get_overlay_strings_1 (it, 0, 0)
3497 : 0))
3499 if (it->ellipsis_p)
3500 setup_for_ellipsis (it, 0);
3501 /* When handling a display spec, we might load an
3502 empty string. In that case, discard it here. We
3503 used to discard it in handle_single_display_spec,
3504 but that causes get_overlay_strings_1, above, to
3505 ignore overlay strings that we must check. */
3506 if (STRINGP (it->string) && !SCHARS (it->string))
3507 pop_it (it);
3508 return;
3510 else if (STRINGP (it->string) && !SCHARS (it->string))
3511 pop_it (it);
3512 else
3514 it->ignore_overlay_strings_at_pos_p = true;
3515 it->string_from_display_prop_p = 0;
3516 it->from_disp_prop_p = 0;
3517 handle_overlay_change_p = 0;
3519 handled = HANDLED_RECOMPUTE_PROPS;
3520 break;
3522 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
3523 handle_overlay_change_p = 0;
3526 if (handled != HANDLED_RECOMPUTE_PROPS)
3528 /* Don't check for overlay strings below when set to deliver
3529 characters from a display vector. */
3530 if (it->method == GET_FROM_DISPLAY_VECTOR)
3531 handle_overlay_change_p = 0;
3533 /* Handle overlay changes.
3534 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
3535 if it finds overlays. */
3536 if (handle_overlay_change_p)
3537 handled = handle_overlay_change (it);
3540 if (it->ellipsis_p)
3542 setup_for_ellipsis (it, 0);
3543 break;
3546 while (handled == HANDLED_RECOMPUTE_PROPS);
3548 /* Determine where to stop next. */
3549 if (handled == HANDLED_NORMALLY)
3550 compute_stop_pos (it);
3554 /* Compute IT->stop_charpos from text property and overlay change
3555 information for IT's current position. */
3557 static void
3558 compute_stop_pos (struct it *it)
3560 register INTERVAL iv, next_iv;
3561 Lisp_Object object, limit, position;
3562 ptrdiff_t charpos, bytepos;
3564 if (STRINGP (it->string))
3566 /* Strings are usually short, so don't limit the search for
3567 properties. */
3568 it->stop_charpos = it->end_charpos;
3569 object = it->string;
3570 limit = Qnil;
3571 charpos = IT_STRING_CHARPOS (*it);
3572 bytepos = IT_STRING_BYTEPOS (*it);
3574 else
3576 ptrdiff_t pos;
3578 /* If end_charpos is out of range for some reason, such as a
3579 misbehaving display function, rationalize it (Bug#5984). */
3580 if (it->end_charpos > ZV)
3581 it->end_charpos = ZV;
3582 it->stop_charpos = it->end_charpos;
3584 /* If next overlay change is in front of the current stop pos
3585 (which is IT->end_charpos), stop there. Note: value of
3586 next_overlay_change is point-max if no overlay change
3587 follows. */
3588 charpos = IT_CHARPOS (*it);
3589 bytepos = IT_BYTEPOS (*it);
3590 pos = next_overlay_change (charpos);
3591 if (pos < it->stop_charpos)
3592 it->stop_charpos = pos;
3594 /* Set up variables for computing the stop position from text
3595 property changes. */
3596 XSETBUFFER (object, current_buffer);
3597 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3600 /* Get the interval containing IT's position. Value is a null
3601 interval if there isn't such an interval. */
3602 position = make_number (charpos);
3603 iv = validate_interval_range (object, &position, &position, 0);
3604 if (iv)
3606 Lisp_Object values_here[LAST_PROP_IDX];
3607 struct props *p;
3609 /* Get properties here. */
3610 for (p = it_props; p->handler; ++p)
3611 values_here[p->idx] = textget (iv->plist, *p->name);
3613 /* Look for an interval following iv that has different
3614 properties. */
3615 for (next_iv = next_interval (iv);
3616 (next_iv
3617 && (NILP (limit)
3618 || XFASTINT (limit) > next_iv->position));
3619 next_iv = next_interval (next_iv))
3621 for (p = it_props; p->handler; ++p)
3623 Lisp_Object new_value;
3625 new_value = textget (next_iv->plist, *p->name);
3626 if (!EQ (values_here[p->idx], new_value))
3627 break;
3630 if (p->handler)
3631 break;
3634 if (next_iv)
3636 if (INTEGERP (limit)
3637 && next_iv->position >= XFASTINT (limit))
3638 /* No text property change up to limit. */
3639 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3640 else
3641 /* Text properties change in next_iv. */
3642 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3646 if (it->cmp_it.id < 0)
3648 ptrdiff_t stoppos = it->end_charpos;
3650 if (it->bidi_p && it->bidi_it.scan_dir < 0)
3651 stoppos = -1;
3652 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
3653 stoppos, it->string);
3656 eassert (STRINGP (it->string)
3657 || (it->stop_charpos >= BEGV
3658 && it->stop_charpos >= IT_CHARPOS (*it)));
3662 /* Return the position of the next overlay change after POS in
3663 current_buffer. Value is point-max if no overlay change
3664 follows. This is like `next-overlay-change' but doesn't use
3665 xmalloc. */
3667 static ptrdiff_t
3668 next_overlay_change (ptrdiff_t pos)
3670 ptrdiff_t i, noverlays;
3671 ptrdiff_t endpos;
3672 Lisp_Object *overlays;
3673 USE_SAFE_ALLOCA;
3675 /* Get all overlays at the given position. */
3676 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
3678 /* If any of these overlays ends before endpos,
3679 use its ending point instead. */
3680 for (i = 0; i < noverlays; ++i)
3682 Lisp_Object oend;
3683 ptrdiff_t oendpos;
3685 oend = OVERLAY_END (overlays[i]);
3686 oendpos = OVERLAY_POSITION (oend);
3687 endpos = min (endpos, oendpos);
3690 SAFE_FREE ();
3691 return endpos;
3694 /* How many characters forward to search for a display property or
3695 display string. Searching too far forward makes the bidi display
3696 sluggish, especially in small windows. */
3697 #define MAX_DISP_SCAN 250
3699 /* Return the character position of a display string at or after
3700 position specified by POSITION. If no display string exists at or
3701 after POSITION, return ZV. A display string is either an overlay
3702 with `display' property whose value is a string, or a `display'
3703 text property whose value is a string. STRING is data about the
3704 string to iterate; if STRING->lstring is nil, we are iterating a
3705 buffer. FRAME_WINDOW_P is non-zero when we are displaying a window
3706 on a GUI frame. DISP_PROP is set to zero if we searched
3707 MAX_DISP_SCAN characters forward without finding any display
3708 strings, non-zero otherwise. It is set to 2 if the display string
3709 uses any kind of `(space ...)' spec that will produce a stretch of
3710 white space in the text area. */
3711 ptrdiff_t
3712 compute_display_string_pos (struct text_pos *position,
3713 struct bidi_string_data *string,
3714 struct window *w,
3715 int frame_window_p, int *disp_prop)
3717 /* OBJECT = nil means current buffer. */
3718 Lisp_Object object, object1;
3719 Lisp_Object pos, spec, limpos;
3720 int string_p = (string && (STRINGP (string->lstring) || string->s));
3721 ptrdiff_t eob = string_p ? string->schars : ZV;
3722 ptrdiff_t begb = string_p ? 0 : BEGV;
3723 ptrdiff_t bufpos, charpos = CHARPOS (*position);
3724 ptrdiff_t lim =
3725 (charpos < eob - MAX_DISP_SCAN) ? charpos + MAX_DISP_SCAN : eob;
3726 struct text_pos tpos;
3727 int rv = 0;
3729 if (string && STRINGP (string->lstring))
3730 object1 = object = string->lstring;
3731 else if (w && !string_p)
3733 XSETWINDOW (object, w);
3734 object1 = Qnil;
3736 else
3737 object1 = object = Qnil;
3739 *disp_prop = 1;
3741 if (charpos >= eob
3742 /* We don't support display properties whose values are strings
3743 that have display string properties. */
3744 || string->from_disp_str
3745 /* C strings cannot have display properties. */
3746 || (string->s && !STRINGP (object)))
3748 *disp_prop = 0;
3749 return eob;
3752 /* If the character at CHARPOS is where the display string begins,
3753 return CHARPOS. */
3754 pos = make_number (charpos);
3755 if (STRINGP (object))
3756 bufpos = string->bufpos;
3757 else
3758 bufpos = charpos;
3759 tpos = *position;
3760 if (!NILP (spec = Fget_char_property (pos, Qdisplay, object))
3761 && (charpos <= begb
3762 || !EQ (Fget_char_property (make_number (charpos - 1), Qdisplay,
3763 object),
3764 spec))
3765 && (rv = handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
3766 frame_window_p)))
3768 if (rv == 2)
3769 *disp_prop = 2;
3770 return charpos;
3773 /* Look forward for the first character with a `display' property
3774 that will replace the underlying text when displayed. */
3775 limpos = make_number (lim);
3776 do {
3777 pos = Fnext_single_char_property_change (pos, Qdisplay, object1, limpos);
3778 CHARPOS (tpos) = XFASTINT (pos);
3779 if (CHARPOS (tpos) >= lim)
3781 *disp_prop = 0;
3782 break;
3784 if (STRINGP (object))
3785 BYTEPOS (tpos) = string_char_to_byte (object, CHARPOS (tpos));
3786 else
3787 BYTEPOS (tpos) = CHAR_TO_BYTE (CHARPOS (tpos));
3788 spec = Fget_char_property (pos, Qdisplay, object);
3789 if (!STRINGP (object))
3790 bufpos = CHARPOS (tpos);
3791 } while (NILP (spec)
3792 || !(rv = handle_display_spec (NULL, spec, object, Qnil, &tpos,
3793 bufpos, frame_window_p)));
3794 if (rv == 2)
3795 *disp_prop = 2;
3797 return CHARPOS (tpos);
3800 /* Return the character position of the end of the display string that
3801 started at CHARPOS. If there's no display string at CHARPOS,
3802 return -1. A display string is either an overlay with `display'
3803 property whose value is a string or a `display' text property whose
3804 value is a string. */
3805 ptrdiff_t
3806 compute_display_string_end (ptrdiff_t charpos, struct bidi_string_data *string)
3808 /* OBJECT = nil means current buffer. */
3809 Lisp_Object object =
3810 (string && STRINGP (string->lstring)) ? string->lstring : Qnil;
3811 Lisp_Object pos = make_number (charpos);
3812 ptrdiff_t eob =
3813 (STRINGP (object) || (string && string->s)) ? string->schars : ZV;
3815 if (charpos >= eob || (string->s && !STRINGP (object)))
3816 return eob;
3818 /* It could happen that the display property or overlay was removed
3819 since we found it in compute_display_string_pos above. One way
3820 this can happen is if JIT font-lock was called (through
3821 handle_fontified_prop), and jit-lock-functions remove text
3822 properties or overlays from the portion of buffer that includes
3823 CHARPOS. Muse mode is known to do that, for example. In this
3824 case, we return -1 to the caller, to signal that no display
3825 string is actually present at CHARPOS. See bidi_fetch_char for
3826 how this is handled.
3828 An alternative would be to never look for display properties past
3829 it->stop_charpos. But neither compute_display_string_pos nor
3830 bidi_fetch_char that calls it know or care where the next
3831 stop_charpos is. */
3832 if (NILP (Fget_char_property (pos, Qdisplay, object)))
3833 return -1;
3835 /* Look forward for the first character where the `display' property
3836 changes. */
3837 pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil);
3839 return XFASTINT (pos);
3844 /***********************************************************************
3845 Fontification
3846 ***********************************************************************/
3848 /* Handle changes in the `fontified' property of the current buffer by
3849 calling hook functions from Qfontification_functions to fontify
3850 regions of text. */
3852 static enum prop_handled
3853 handle_fontified_prop (struct it *it)
3855 Lisp_Object prop, pos;
3856 enum prop_handled handled = HANDLED_NORMALLY;
3858 if (!NILP (Vmemory_full))
3859 return handled;
3861 /* Get the value of the `fontified' property at IT's current buffer
3862 position. (The `fontified' property doesn't have a special
3863 meaning in strings.) If the value is nil, call functions from
3864 Qfontification_functions. */
3865 if (!STRINGP (it->string)
3866 && it->s == NULL
3867 && !NILP (Vfontification_functions)
3868 && !NILP (Vrun_hooks)
3869 && (pos = make_number (IT_CHARPOS (*it)),
3870 prop = Fget_char_property (pos, Qfontified, Qnil),
3871 /* Ignore the special cased nil value always present at EOB since
3872 no amount of fontifying will be able to change it. */
3873 NILP (prop) && IT_CHARPOS (*it) < Z))
3875 ptrdiff_t count = SPECPDL_INDEX ();
3876 Lisp_Object val;
3877 struct buffer *obuf = current_buffer;
3878 ptrdiff_t begv = BEGV, zv = ZV;
3879 bool old_clip_changed = current_buffer->clip_changed;
3881 val = Vfontification_functions;
3882 specbind (Qfontification_functions, Qnil);
3884 eassert (it->end_charpos == ZV);
3886 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3887 safe_call1 (val, pos);
3888 else
3890 Lisp_Object fns, fn;
3891 struct gcpro gcpro1, gcpro2;
3893 fns = Qnil;
3894 GCPRO2 (val, fns);
3896 for (; CONSP (val); val = XCDR (val))
3898 fn = XCAR (val);
3900 if (EQ (fn, Qt))
3902 /* A value of t indicates this hook has a local
3903 binding; it means to run the global binding too.
3904 In a global value, t should not occur. If it
3905 does, we must ignore it to avoid an endless
3906 loop. */
3907 for (fns = Fdefault_value (Qfontification_functions);
3908 CONSP (fns);
3909 fns = XCDR (fns))
3911 fn = XCAR (fns);
3912 if (!EQ (fn, Qt))
3913 safe_call1 (fn, pos);
3916 else
3917 safe_call1 (fn, pos);
3920 UNGCPRO;
3923 unbind_to (count, Qnil);
3925 /* Fontification functions routinely call `save-restriction'.
3926 Normally, this tags clip_changed, which can confuse redisplay
3927 (see discussion in Bug#6671). Since we don't perform any
3928 special handling of fontification changes in the case where
3929 `save-restriction' isn't called, there's no point doing so in
3930 this case either. So, if the buffer's restrictions are
3931 actually left unchanged, reset clip_changed. */
3932 if (obuf == current_buffer)
3934 if (begv == BEGV && zv == ZV)
3935 current_buffer->clip_changed = old_clip_changed;
3937 /* There isn't much we can reasonably do to protect against
3938 misbehaving fontification, but here's a fig leaf. */
3939 else if (BUFFER_LIVE_P (obuf))
3940 set_buffer_internal_1 (obuf);
3942 /* The fontification code may have added/removed text.
3943 It could do even a lot worse, but let's at least protect against
3944 the most obvious case where only the text past `pos' gets changed',
3945 as is/was done in grep.el where some escapes sequences are turned
3946 into face properties (bug#7876). */
3947 it->end_charpos = ZV;
3949 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3950 something. This avoids an endless loop if they failed to
3951 fontify the text for which reason ever. */
3952 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3953 handled = HANDLED_RECOMPUTE_PROPS;
3956 return handled;
3961 /***********************************************************************
3962 Faces
3963 ***********************************************************************/
3965 /* Set up iterator IT from face properties at its current position.
3966 Called from handle_stop. */
3968 static enum prop_handled
3969 handle_face_prop (struct it *it)
3971 int new_face_id;
3972 ptrdiff_t next_stop;
3974 if (!STRINGP (it->string))
3976 new_face_id
3977 = face_at_buffer_position (it->w,
3978 IT_CHARPOS (*it),
3979 &next_stop,
3980 (IT_CHARPOS (*it)
3981 + TEXT_PROP_DISTANCE_LIMIT),
3982 0, it->base_face_id);
3984 /* Is this a start of a run of characters with box face?
3985 Caveat: this can be called for a freshly initialized
3986 iterator; face_id is -1 in this case. We know that the new
3987 face will not change until limit, i.e. if the new face has a
3988 box, all characters up to limit will have one. But, as
3989 usual, we don't know whether limit is really the end. */
3990 if (new_face_id != it->face_id)
3992 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3993 /* If it->face_id is -1, old_face below will be NULL, see
3994 the definition of FACE_FROM_ID. This will happen if this
3995 is the initial call that gets the face. */
3996 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3998 /* If the value of face_id of the iterator is -1, we have to
3999 look in front of IT's position and see whether there is a
4000 face there that's different from new_face_id. */
4001 if (!old_face && IT_CHARPOS (*it) > BEG)
4003 int prev_face_id = face_before_it_pos (it);
4005 old_face = FACE_FROM_ID (it->f, prev_face_id);
4008 /* If the new face has a box, but the old face does not,
4009 this is the start of a run of characters with box face,
4010 i.e. this character has a shadow on the left side. */
4011 it->start_of_box_run_p = (new_face->box != FACE_NO_BOX
4012 && (old_face == NULL || !old_face->box));
4013 it->face_box_p = new_face->box != FACE_NO_BOX;
4016 else
4018 int base_face_id;
4019 ptrdiff_t bufpos;
4020 int i;
4021 Lisp_Object from_overlay
4022 = (it->current.overlay_string_index >= 0
4023 ? it->string_overlays[it->current.overlay_string_index
4024 % OVERLAY_STRING_CHUNK_SIZE]
4025 : Qnil);
4027 /* See if we got to this string directly or indirectly from
4028 an overlay property. That includes the before-string or
4029 after-string of an overlay, strings in display properties
4030 provided by an overlay, their text properties, etc.
4032 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
4033 if (! NILP (from_overlay))
4034 for (i = it->sp - 1; i >= 0; i--)
4036 if (it->stack[i].current.overlay_string_index >= 0)
4037 from_overlay
4038 = it->string_overlays[it->stack[i].current.overlay_string_index
4039 % OVERLAY_STRING_CHUNK_SIZE];
4040 else if (! NILP (it->stack[i].from_overlay))
4041 from_overlay = it->stack[i].from_overlay;
4043 if (!NILP (from_overlay))
4044 break;
4047 if (! NILP (from_overlay))
4049 bufpos = IT_CHARPOS (*it);
4050 /* For a string from an overlay, the base face depends
4051 only on text properties and ignores overlays. */
4052 base_face_id
4053 = face_for_overlay_string (it->w,
4054 IT_CHARPOS (*it),
4055 &next_stop,
4056 (IT_CHARPOS (*it)
4057 + TEXT_PROP_DISTANCE_LIMIT),
4059 from_overlay);
4061 else
4063 bufpos = 0;
4065 /* For strings from a `display' property, use the face at
4066 IT's current buffer position as the base face to merge
4067 with, so that overlay strings appear in the same face as
4068 surrounding text, unless they specify their own faces.
4069 For strings from wrap-prefix and line-prefix properties,
4070 use the default face, possibly remapped via
4071 Vface_remapping_alist. */
4072 /* Note that the fact that we use the face at _buffer_
4073 position means that a 'display' property on an overlay
4074 string will not inherit the face of that overlay string,
4075 but will instead revert to the face of buffer text
4076 covered by the overlay. This is visible, e.g., when the
4077 overlay specifies a box face, but neither the buffer nor
4078 the display string do. This sounds like a design bug,
4079 but Emacs always did that since v21.1, so changing that
4080 might be a big deal. */
4081 base_face_id = it->string_from_prefix_prop_p
4082 ? (!NILP (Vface_remapping_alist)
4083 ? lookup_basic_face (it->f, DEFAULT_FACE_ID)
4084 : DEFAULT_FACE_ID)
4085 : underlying_face_id (it);
4088 new_face_id = face_at_string_position (it->w,
4089 it->string,
4090 IT_STRING_CHARPOS (*it),
4091 bufpos,
4092 &next_stop,
4093 base_face_id, 0);
4095 /* Is this a start of a run of characters with box? Caveat:
4096 this can be called for a freshly allocated iterator; face_id
4097 is -1 is this case. We know that the new face will not
4098 change until the next check pos, i.e. if the new face has a
4099 box, all characters up to that position will have a
4100 box. But, as usual, we don't know whether that position
4101 is really the end. */
4102 if (new_face_id != it->face_id)
4104 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
4105 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
4107 /* If new face has a box but old face hasn't, this is the
4108 start of a run of characters with box, i.e. it has a
4109 shadow on the left side. */
4110 it->start_of_box_run_p
4111 = new_face->box && (old_face == NULL || !old_face->box);
4112 it->face_box_p = new_face->box != FACE_NO_BOX;
4116 it->face_id = new_face_id;
4117 return HANDLED_NORMALLY;
4121 /* Return the ID of the face ``underlying'' IT's current position,
4122 which is in a string. If the iterator is associated with a
4123 buffer, return the face at IT's current buffer position.
4124 Otherwise, use the iterator's base_face_id. */
4126 static int
4127 underlying_face_id (struct it *it)
4129 int face_id = it->base_face_id, i;
4131 eassert (STRINGP (it->string));
4133 for (i = it->sp - 1; i >= 0; --i)
4134 if (NILP (it->stack[i].string))
4135 face_id = it->stack[i].face_id;
4137 return face_id;
4141 /* Compute the face one character before or after the current position
4142 of IT, in the visual order. BEFORE_P non-zero means get the face
4143 in front (to the left in L2R paragraphs, to the right in R2L
4144 paragraphs) of IT's screen position. Value is the ID of the face. */
4146 static int
4147 face_before_or_after_it_pos (struct it *it, int before_p)
4149 int face_id, limit;
4150 ptrdiff_t next_check_charpos;
4151 struct it it_copy;
4152 void *it_copy_data = NULL;
4154 eassert (it->s == NULL);
4156 if (STRINGP (it->string))
4158 ptrdiff_t bufpos, charpos;
4159 int base_face_id;
4161 /* No face change past the end of the string (for the case
4162 we are padding with spaces). No face change before the
4163 string start. */
4164 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
4165 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
4166 return it->face_id;
4168 if (!it->bidi_p)
4170 /* Set charpos to the position before or after IT's current
4171 position, in the logical order, which in the non-bidi
4172 case is the same as the visual order. */
4173 if (before_p)
4174 charpos = IT_STRING_CHARPOS (*it) - 1;
4175 else if (it->what == IT_COMPOSITION)
4176 /* For composition, we must check the character after the
4177 composition. */
4178 charpos = IT_STRING_CHARPOS (*it) + it->cmp_it.nchars;
4179 else
4180 charpos = IT_STRING_CHARPOS (*it) + 1;
4182 else
4184 if (before_p)
4186 /* With bidi iteration, the character before the current
4187 in the visual order cannot be found by simple
4188 iteration, because "reverse" reordering is not
4189 supported. Instead, we need to use the move_it_*
4190 family of functions. */
4191 /* Ignore face changes before the first visible
4192 character on this display line. */
4193 if (it->current_x <= it->first_visible_x)
4194 return it->face_id;
4195 SAVE_IT (it_copy, *it, it_copy_data);
4196 /* Implementation note: Since move_it_in_display_line
4197 works in the iterator geometry, and thinks the first
4198 character is always the leftmost, even in R2L lines,
4199 we don't need to distinguish between the R2L and L2R
4200 cases here. */
4201 move_it_in_display_line (&it_copy, SCHARS (it_copy.string),
4202 it_copy.current_x - 1, MOVE_TO_X);
4203 charpos = IT_STRING_CHARPOS (it_copy);
4204 RESTORE_IT (it, it, it_copy_data);
4206 else
4208 /* Set charpos to the string position of the character
4209 that comes after IT's current position in the visual
4210 order. */
4211 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
4213 it_copy = *it;
4214 while (n--)
4215 bidi_move_to_visually_next (&it_copy.bidi_it);
4217 charpos = it_copy.bidi_it.charpos;
4220 eassert (0 <= charpos && charpos <= SCHARS (it->string));
4222 if (it->current.overlay_string_index >= 0)
4223 bufpos = IT_CHARPOS (*it);
4224 else
4225 bufpos = 0;
4227 base_face_id = underlying_face_id (it);
4229 /* Get the face for ASCII, or unibyte. */
4230 face_id = face_at_string_position (it->w,
4231 it->string,
4232 charpos,
4233 bufpos,
4234 &next_check_charpos,
4235 base_face_id, 0);
4237 /* Correct the face for charsets different from ASCII. Do it
4238 for the multibyte case only. The face returned above is
4239 suitable for unibyte text if IT->string is unibyte. */
4240 if (STRING_MULTIBYTE (it->string))
4242 struct text_pos pos1 = string_pos (charpos, it->string);
4243 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos1);
4244 int c, len;
4245 struct face *face = FACE_FROM_ID (it->f, face_id);
4247 c = string_char_and_length (p, &len);
4248 face_id = FACE_FOR_CHAR (it->f, face, c, charpos, it->string);
4251 else
4253 struct text_pos pos;
4255 if ((IT_CHARPOS (*it) >= ZV && !before_p)
4256 || (IT_CHARPOS (*it) <= BEGV && before_p))
4257 return it->face_id;
4259 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
4260 pos = it->current.pos;
4262 if (!it->bidi_p)
4264 if (before_p)
4265 DEC_TEXT_POS (pos, it->multibyte_p);
4266 else
4268 if (it->what == IT_COMPOSITION)
4270 /* For composition, we must check the position after
4271 the composition. */
4272 pos.charpos += it->cmp_it.nchars;
4273 pos.bytepos += it->len;
4275 else
4276 INC_TEXT_POS (pos, it->multibyte_p);
4279 else
4281 if (before_p)
4283 /* With bidi iteration, the character before the current
4284 in the visual order cannot be found by simple
4285 iteration, because "reverse" reordering is not
4286 supported. Instead, we need to use the move_it_*
4287 family of functions. */
4288 /* Ignore face changes before the first visible
4289 character on this display line. */
4290 if (it->current_x <= it->first_visible_x)
4291 return it->face_id;
4292 SAVE_IT (it_copy, *it, it_copy_data);
4293 /* Implementation note: Since move_it_in_display_line
4294 works in the iterator geometry, and thinks the first
4295 character is always the leftmost, even in R2L lines,
4296 we don't need to distinguish between the R2L and L2R
4297 cases here. */
4298 move_it_in_display_line (&it_copy, ZV,
4299 it_copy.current_x - 1, MOVE_TO_X);
4300 pos = it_copy.current.pos;
4301 RESTORE_IT (it, it, it_copy_data);
4303 else
4305 /* Set charpos to the buffer position of the character
4306 that comes after IT's current position in the visual
4307 order. */
4308 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
4310 it_copy = *it;
4311 while (n--)
4312 bidi_move_to_visually_next (&it_copy.bidi_it);
4314 SET_TEXT_POS (pos,
4315 it_copy.bidi_it.charpos, it_copy.bidi_it.bytepos);
4318 eassert (BEGV <= CHARPOS (pos) && CHARPOS (pos) <= ZV);
4320 /* Determine face for CHARSET_ASCII, or unibyte. */
4321 face_id = face_at_buffer_position (it->w,
4322 CHARPOS (pos),
4323 &next_check_charpos,
4324 limit, 0, -1);
4326 /* Correct the face for charsets different from ASCII. Do it
4327 for the multibyte case only. The face returned above is
4328 suitable for unibyte text if current_buffer is unibyte. */
4329 if (it->multibyte_p)
4331 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
4332 struct face *face = FACE_FROM_ID (it->f, face_id);
4333 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
4337 return face_id;
4342 /***********************************************************************
4343 Invisible text
4344 ***********************************************************************/
4346 /* Set up iterator IT from invisible properties at its current
4347 position. Called from handle_stop. */
4349 static enum prop_handled
4350 handle_invisible_prop (struct it *it)
4352 enum prop_handled handled = HANDLED_NORMALLY;
4353 int invis_p;
4354 Lisp_Object prop;
4356 if (STRINGP (it->string))
4358 Lisp_Object end_charpos, limit, charpos;
4360 /* Get the value of the invisible text property at the
4361 current position. Value will be nil if there is no such
4362 property. */
4363 charpos = make_number (IT_STRING_CHARPOS (*it));
4364 prop = Fget_text_property (charpos, Qinvisible, it->string);
4365 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4367 if (invis_p && IT_STRING_CHARPOS (*it) < it->end_charpos)
4369 /* Record whether we have to display an ellipsis for the
4370 invisible text. */
4371 int display_ellipsis_p = (invis_p == 2);
4372 ptrdiff_t len, endpos;
4374 handled = HANDLED_RECOMPUTE_PROPS;
4376 /* Get the position at which the next visible text can be
4377 found in IT->string, if any. */
4378 endpos = len = SCHARS (it->string);
4379 XSETINT (limit, len);
4382 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
4383 it->string, limit);
4384 if (INTEGERP (end_charpos))
4386 endpos = XFASTINT (end_charpos);
4387 prop = Fget_text_property (end_charpos, Qinvisible, it->string);
4388 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4389 if (invis_p == 2)
4390 display_ellipsis_p = true;
4393 while (invis_p && endpos < len);
4395 if (display_ellipsis_p)
4396 it->ellipsis_p = true;
4398 if (endpos < len)
4400 /* Text at END_CHARPOS is visible. Move IT there. */
4401 struct text_pos old;
4402 ptrdiff_t oldpos;
4404 old = it->current.string_pos;
4405 oldpos = CHARPOS (old);
4406 if (it->bidi_p)
4408 if (it->bidi_it.first_elt
4409 && it->bidi_it.charpos < SCHARS (it->string))
4410 bidi_paragraph_init (it->paragraph_embedding,
4411 &it->bidi_it, 1);
4412 /* Bidi-iterate out of the invisible text. */
4415 bidi_move_to_visually_next (&it->bidi_it);
4417 while (oldpos <= it->bidi_it.charpos
4418 && it->bidi_it.charpos < endpos);
4420 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
4421 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
4422 if (IT_CHARPOS (*it) >= endpos)
4423 it->prev_stop = endpos;
4425 else
4427 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
4428 compute_string_pos (&it->current.string_pos, old, it->string);
4431 else
4433 /* The rest of the string is invisible. If this is an
4434 overlay string, proceed with the next overlay string
4435 or whatever comes and return a character from there. */
4436 if (it->current.overlay_string_index >= 0
4437 && !display_ellipsis_p)
4439 next_overlay_string (it);
4440 /* Don't check for overlay strings when we just
4441 finished processing them. */
4442 handled = HANDLED_OVERLAY_STRING_CONSUMED;
4444 else
4446 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
4447 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
4452 else
4454 ptrdiff_t newpos, next_stop, start_charpos, tem;
4455 Lisp_Object pos, overlay;
4457 /* First of all, is there invisible text at this position? */
4458 tem = start_charpos = IT_CHARPOS (*it);
4459 pos = make_number (tem);
4460 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
4461 &overlay);
4462 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4464 /* If we are on invisible text, skip over it. */
4465 if (invis_p && start_charpos < it->end_charpos)
4467 /* Record whether we have to display an ellipsis for the
4468 invisible text. */
4469 int display_ellipsis_p = invis_p == 2;
4471 handled = HANDLED_RECOMPUTE_PROPS;
4473 /* Loop skipping over invisible text. The loop is left at
4474 ZV or with IT on the first char being visible again. */
4477 /* Try to skip some invisible text. Return value is the
4478 position reached which can be equal to where we start
4479 if there is nothing invisible there. This skips both
4480 over invisible text properties and overlays with
4481 invisible property. */
4482 newpos = skip_invisible (tem, &next_stop, ZV, it->window);
4484 /* If we skipped nothing at all we weren't at invisible
4485 text in the first place. If everything to the end of
4486 the buffer was skipped, end the loop. */
4487 if (newpos == tem || newpos >= ZV)
4488 invis_p = 0;
4489 else
4491 /* We skipped some characters but not necessarily
4492 all there are. Check if we ended up on visible
4493 text. Fget_char_property returns the property of
4494 the char before the given position, i.e. if we
4495 get invis_p = 0, this means that the char at
4496 newpos is visible. */
4497 pos = make_number (newpos);
4498 prop = Fget_char_property (pos, Qinvisible, it->window);
4499 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4502 /* If we ended up on invisible text, proceed to
4503 skip starting with next_stop. */
4504 if (invis_p)
4505 tem = next_stop;
4507 /* If there are adjacent invisible texts, don't lose the
4508 second one's ellipsis. */
4509 if (invis_p == 2)
4510 display_ellipsis_p = true;
4512 while (invis_p);
4514 /* The position newpos is now either ZV or on visible text. */
4515 if (it->bidi_p)
4517 ptrdiff_t bpos = CHAR_TO_BYTE (newpos);
4518 int on_newline
4519 = bpos == ZV_BYTE || FETCH_BYTE (bpos) == '\n';
4520 int after_newline
4521 = newpos <= BEGV || FETCH_BYTE (bpos - 1) == '\n';
4523 /* If the invisible text ends on a newline or on a
4524 character after a newline, we can avoid the costly,
4525 character by character, bidi iteration to NEWPOS, and
4526 instead simply reseat the iterator there. That's
4527 because all bidi reordering information is tossed at
4528 the newline. This is a big win for modes that hide
4529 complete lines, like Outline, Org, etc. */
4530 if (on_newline || after_newline)
4532 struct text_pos tpos;
4533 bidi_dir_t pdir = it->bidi_it.paragraph_dir;
4535 SET_TEXT_POS (tpos, newpos, bpos);
4536 reseat_1 (it, tpos, 0);
4537 /* If we reseat on a newline/ZV, we need to prep the
4538 bidi iterator for advancing to the next character
4539 after the newline/EOB, keeping the current paragraph
4540 direction (so that PRODUCE_GLYPHS does TRT wrt
4541 prepending/appending glyphs to a glyph row). */
4542 if (on_newline)
4544 it->bidi_it.first_elt = 0;
4545 it->bidi_it.paragraph_dir = pdir;
4546 it->bidi_it.ch = (bpos == ZV_BYTE) ? -1 : '\n';
4547 it->bidi_it.nchars = 1;
4548 it->bidi_it.ch_len = 1;
4551 else /* Must use the slow method. */
4553 /* With bidi iteration, the region of invisible text
4554 could start and/or end in the middle of a
4555 non-base embedding level. Therefore, we need to
4556 skip invisible text using the bidi iterator,
4557 starting at IT's current position, until we find
4558 ourselves outside of the invisible text.
4559 Skipping invisible text _after_ bidi iteration
4560 avoids affecting the visual order of the
4561 displayed text when invisible properties are
4562 added or removed. */
4563 if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV)
4565 /* If we were `reseat'ed to a new paragraph,
4566 determine the paragraph base direction. We
4567 need to do it now because
4568 next_element_from_buffer may not have a
4569 chance to do it, if we are going to skip any
4570 text at the beginning, which resets the
4571 FIRST_ELT flag. */
4572 bidi_paragraph_init (it->paragraph_embedding,
4573 &it->bidi_it, 1);
4577 bidi_move_to_visually_next (&it->bidi_it);
4579 while (it->stop_charpos <= it->bidi_it.charpos
4580 && it->bidi_it.charpos < newpos);
4581 IT_CHARPOS (*it) = it->bidi_it.charpos;
4582 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
4583 /* If we overstepped NEWPOS, record its position in
4584 the iterator, so that we skip invisible text if
4585 later the bidi iteration lands us in the
4586 invisible region again. */
4587 if (IT_CHARPOS (*it) >= newpos)
4588 it->prev_stop = newpos;
4591 else
4593 IT_CHARPOS (*it) = newpos;
4594 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
4597 /* If there are before-strings at the start of invisible
4598 text, and the text is invisible because of a text
4599 property, arrange to show before-strings because 20.x did
4600 it that way. (If the text is invisible because of an
4601 overlay property instead of a text property, this is
4602 already handled in the overlay code.) */
4603 if (NILP (overlay)
4604 && get_overlay_strings (it, it->stop_charpos))
4606 handled = HANDLED_RECOMPUTE_PROPS;
4607 if (it->sp > 0)
4609 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
4610 /* The call to get_overlay_strings above recomputes
4611 it->stop_charpos, but it only considers changes
4612 in properties and overlays beyond iterator's
4613 current position. This causes us to miss changes
4614 that happen exactly where the invisible property
4615 ended. So we play it safe here and force the
4616 iterator to check for potential stop positions
4617 immediately after the invisible text. Note that
4618 if get_overlay_strings returns non-zero, it
4619 normally also pushed the iterator stack, so we
4620 need to update the stop position in the slot
4621 below the current one. */
4622 it->stack[it->sp - 1].stop_charpos
4623 = CHARPOS (it->stack[it->sp - 1].current.pos);
4626 else if (display_ellipsis_p)
4628 /* Make sure that the glyphs of the ellipsis will get
4629 correct `charpos' values. If we would not update
4630 it->position here, the glyphs would belong to the
4631 last visible character _before_ the invisible
4632 text, which confuses `set_cursor_from_row'.
4634 We use the last invisible position instead of the
4635 first because this way the cursor is always drawn on
4636 the first "." of the ellipsis, whenever PT is inside
4637 the invisible text. Otherwise the cursor would be
4638 placed _after_ the ellipsis when the point is after the
4639 first invisible character. */
4640 if (!STRINGP (it->object))
4642 it->position.charpos = newpos - 1;
4643 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
4645 it->ellipsis_p = true;
4646 /* Let the ellipsis display before
4647 considering any properties of the following char.
4648 Fixes jasonr@gnu.org 01 Oct 07 bug. */
4649 handled = HANDLED_RETURN;
4654 return handled;
4658 /* Make iterator IT return `...' next.
4659 Replaces LEN characters from buffer. */
4661 static void
4662 setup_for_ellipsis (struct it *it, int len)
4664 /* Use the display table definition for `...'. Invalid glyphs
4665 will be handled by the method returning elements from dpvec. */
4666 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
4668 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
4669 it->dpvec = v->contents;
4670 it->dpend = v->contents + v->header.size;
4672 else
4674 /* Default `...'. */
4675 it->dpvec = default_invis_vector;
4676 it->dpend = default_invis_vector + 3;
4679 it->dpvec_char_len = len;
4680 it->current.dpvec_index = 0;
4681 it->dpvec_face_id = -1;
4683 /* Remember the current face id in case glyphs specify faces.
4684 IT's face is restored in set_iterator_to_next.
4685 saved_face_id was set to preceding char's face in handle_stop. */
4686 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
4687 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
4689 it->method = GET_FROM_DISPLAY_VECTOR;
4690 it->ellipsis_p = true;
4695 /***********************************************************************
4696 'display' property
4697 ***********************************************************************/
4699 /* Set up iterator IT from `display' property at its current position.
4700 Called from handle_stop.
4701 We return HANDLED_RETURN if some part of the display property
4702 overrides the display of the buffer text itself.
4703 Otherwise we return HANDLED_NORMALLY. */
4705 static enum prop_handled
4706 handle_display_prop (struct it *it)
4708 Lisp_Object propval, object, overlay;
4709 struct text_pos *position;
4710 ptrdiff_t bufpos;
4711 /* Nonzero if some property replaces the display of the text itself. */
4712 int display_replaced_p = 0;
4714 if (STRINGP (it->string))
4716 object = it->string;
4717 position = &it->current.string_pos;
4718 bufpos = CHARPOS (it->current.pos);
4720 else
4722 XSETWINDOW (object, it->w);
4723 position = &it->current.pos;
4724 bufpos = CHARPOS (*position);
4727 /* Reset those iterator values set from display property values. */
4728 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
4729 it->space_width = Qnil;
4730 it->font_height = Qnil;
4731 it->voffset = 0;
4733 /* We don't support recursive `display' properties, i.e. string
4734 values that have a string `display' property, that have a string
4735 `display' property etc. */
4736 if (!it->string_from_display_prop_p)
4737 it->area = TEXT_AREA;
4739 propval = get_char_property_and_overlay (make_number (position->charpos),
4740 Qdisplay, object, &overlay);
4741 if (NILP (propval))
4742 return HANDLED_NORMALLY;
4743 /* Now OVERLAY is the overlay that gave us this property, or nil
4744 if it was a text property. */
4746 if (!STRINGP (it->string))
4747 object = it->w->contents;
4749 display_replaced_p = handle_display_spec (it, propval, object, overlay,
4750 position, bufpos,
4751 FRAME_WINDOW_P (it->f));
4753 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
4756 /* Subroutine of handle_display_prop. Returns non-zero if the display
4757 specification in SPEC is a replacing specification, i.e. it would
4758 replace the text covered by `display' property with something else,
4759 such as an image or a display string. If SPEC includes any kind or
4760 `(space ...) specification, the value is 2; this is used by
4761 compute_display_string_pos, which see.
4763 See handle_single_display_spec for documentation of arguments.
4764 frame_window_p is non-zero if the window being redisplayed is on a
4765 GUI frame; this argument is used only if IT is NULL, see below.
4767 IT can be NULL, if this is called by the bidi reordering code
4768 through compute_display_string_pos, which see. In that case, this
4769 function only examines SPEC, but does not otherwise "handle" it, in
4770 the sense that it doesn't set up members of IT from the display
4771 spec. */
4772 static int
4773 handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4774 Lisp_Object overlay, struct text_pos *position,
4775 ptrdiff_t bufpos, int frame_window_p)
4777 int replacing_p = 0;
4778 int rv;
4780 if (CONSP (spec)
4781 /* Simple specifications. */
4782 && !EQ (XCAR (spec), Qimage)
4783 && !EQ (XCAR (spec), Qspace)
4784 && !EQ (XCAR (spec), Qwhen)
4785 && !EQ (XCAR (spec), Qslice)
4786 && !EQ (XCAR (spec), Qspace_width)
4787 && !EQ (XCAR (spec), Qheight)
4788 && !EQ (XCAR (spec), Qraise)
4789 /* Marginal area specifications. */
4790 && !(CONSP (XCAR (spec)) && EQ (XCAR (XCAR (spec)), Qmargin))
4791 && !EQ (XCAR (spec), Qleft_fringe)
4792 && !EQ (XCAR (spec), Qright_fringe)
4793 && !NILP (XCAR (spec)))
4795 for (; CONSP (spec); spec = XCDR (spec))
4797 if ((rv = handle_single_display_spec (it, XCAR (spec), object,
4798 overlay, position, bufpos,
4799 replacing_p, frame_window_p)))
4801 replacing_p = rv;
4802 /* If some text in a string is replaced, `position' no
4803 longer points to the position of `object'. */
4804 if (!it || STRINGP (object))
4805 break;
4809 else if (VECTORP (spec))
4811 ptrdiff_t i;
4812 for (i = 0; i < ASIZE (spec); ++i)
4813 if ((rv = handle_single_display_spec (it, AREF (spec, i), object,
4814 overlay, position, bufpos,
4815 replacing_p, frame_window_p)))
4817 replacing_p = rv;
4818 /* If some text in a string is replaced, `position' no
4819 longer points to the position of `object'. */
4820 if (!it || STRINGP (object))
4821 break;
4824 else
4826 if ((rv = handle_single_display_spec (it, spec, object, overlay,
4827 position, bufpos, 0,
4828 frame_window_p)))
4829 replacing_p = rv;
4832 return replacing_p;
4835 /* Value is the position of the end of the `display' property starting
4836 at START_POS in OBJECT. */
4838 static struct text_pos
4839 display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
4841 Lisp_Object end;
4842 struct text_pos end_pos;
4844 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
4845 Qdisplay, object, Qnil);
4846 CHARPOS (end_pos) = XFASTINT (end);
4847 if (STRINGP (object))
4848 compute_string_pos (&end_pos, start_pos, it->string);
4849 else
4850 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
4852 return end_pos;
4856 /* Set up IT from a single `display' property specification SPEC. OBJECT
4857 is the object in which the `display' property was found. *POSITION
4858 is the position in OBJECT at which the `display' property was found.
4859 BUFPOS is the buffer position of OBJECT (different from POSITION if
4860 OBJECT is not a buffer). DISPLAY_REPLACED_P non-zero means that we
4861 previously saw a display specification which already replaced text
4862 display with something else, for example an image; we ignore such
4863 properties after the first one has been processed.
4865 OVERLAY is the overlay this `display' property came from,
4866 or nil if it was a text property.
4868 If SPEC is a `space' or `image' specification, and in some other
4869 cases too, set *POSITION to the position where the `display'
4870 property ends.
4872 If IT is NULL, only examine the property specification in SPEC, but
4873 don't set up IT. In that case, FRAME_WINDOW_P non-zero means SPEC
4874 is intended to be displayed in a window on a GUI frame.
4876 Value is non-zero if something was found which replaces the display
4877 of buffer or string text. */
4879 static int
4880 handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4881 Lisp_Object overlay, struct text_pos *position,
4882 ptrdiff_t bufpos, int display_replaced_p,
4883 int frame_window_p)
4885 Lisp_Object form;
4886 Lisp_Object location, value;
4887 struct text_pos start_pos = *position;
4888 int valid_p;
4890 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4891 If the result is non-nil, use VALUE instead of SPEC. */
4892 form = Qt;
4893 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
4895 spec = XCDR (spec);
4896 if (!CONSP (spec))
4897 return 0;
4898 form = XCAR (spec);
4899 spec = XCDR (spec);
4902 if (!NILP (form) && !EQ (form, Qt))
4904 ptrdiff_t count = SPECPDL_INDEX ();
4905 struct gcpro gcpro1;
4907 /* Bind `object' to the object having the `display' property, a
4908 buffer or string. Bind `position' to the position in the
4909 object where the property was found, and `buffer-position'
4910 to the current position in the buffer. */
4912 if (NILP (object))
4913 XSETBUFFER (object, current_buffer);
4914 specbind (Qobject, object);
4915 specbind (Qposition, make_number (CHARPOS (*position)));
4916 specbind (Qbuffer_position, make_number (bufpos));
4917 GCPRO1 (form);
4918 form = safe_eval (form);
4919 UNGCPRO;
4920 unbind_to (count, Qnil);
4923 if (NILP (form))
4924 return 0;
4926 /* Handle `(height HEIGHT)' specifications. */
4927 if (CONSP (spec)
4928 && EQ (XCAR (spec), Qheight)
4929 && CONSP (XCDR (spec)))
4931 if (it)
4933 if (!FRAME_WINDOW_P (it->f))
4934 return 0;
4936 it->font_height = XCAR (XCDR (spec));
4937 if (!NILP (it->font_height))
4939 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4940 int new_height = -1;
4942 if (CONSP (it->font_height)
4943 && (EQ (XCAR (it->font_height), Qplus)
4944 || EQ (XCAR (it->font_height), Qminus))
4945 && CONSP (XCDR (it->font_height))
4946 && RANGED_INTEGERP (0, XCAR (XCDR (it->font_height)), INT_MAX))
4948 /* `(+ N)' or `(- N)' where N is an integer. */
4949 int steps = XINT (XCAR (XCDR (it->font_height)));
4950 if (EQ (XCAR (it->font_height), Qplus))
4951 steps = - steps;
4952 it->face_id = smaller_face (it->f, it->face_id, steps);
4954 else if (FUNCTIONP (it->font_height))
4956 /* Call function with current height as argument.
4957 Value is the new height. */
4958 Lisp_Object height;
4959 height = safe_call1 (it->font_height,
4960 face->lface[LFACE_HEIGHT_INDEX]);
4961 if (NUMBERP (height))
4962 new_height = XFLOATINT (height);
4964 else if (NUMBERP (it->font_height))
4966 /* Value is a multiple of the canonical char height. */
4967 struct face *f;
4969 f = FACE_FROM_ID (it->f,
4970 lookup_basic_face (it->f, DEFAULT_FACE_ID));
4971 new_height = (XFLOATINT (it->font_height)
4972 * XINT (f->lface[LFACE_HEIGHT_INDEX]));
4974 else
4976 /* Evaluate IT->font_height with `height' bound to the
4977 current specified height to get the new height. */
4978 ptrdiff_t count = SPECPDL_INDEX ();
4980 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
4981 value = safe_eval (it->font_height);
4982 unbind_to (count, Qnil);
4984 if (NUMBERP (value))
4985 new_height = XFLOATINT (value);
4988 if (new_height > 0)
4989 it->face_id = face_with_height (it->f, it->face_id, new_height);
4993 return 0;
4996 /* Handle `(space-width WIDTH)'. */
4997 if (CONSP (spec)
4998 && EQ (XCAR (spec), Qspace_width)
4999 && CONSP (XCDR (spec)))
5001 if (it)
5003 if (!FRAME_WINDOW_P (it->f))
5004 return 0;
5006 value = XCAR (XCDR (spec));
5007 if (NUMBERP (value) && XFLOATINT (value) > 0)
5008 it->space_width = value;
5011 return 0;
5014 /* Handle `(slice X Y WIDTH HEIGHT)'. */
5015 if (CONSP (spec)
5016 && EQ (XCAR (spec), Qslice))
5018 Lisp_Object tem;
5020 if (it)
5022 if (!FRAME_WINDOW_P (it->f))
5023 return 0;
5025 if (tem = XCDR (spec), CONSP (tem))
5027 it->slice.x = XCAR (tem);
5028 if (tem = XCDR (tem), CONSP (tem))
5030 it->slice.y = XCAR (tem);
5031 if (tem = XCDR (tem), CONSP (tem))
5033 it->slice.width = XCAR (tem);
5034 if (tem = XCDR (tem), CONSP (tem))
5035 it->slice.height = XCAR (tem);
5041 return 0;
5044 /* Handle `(raise FACTOR)'. */
5045 if (CONSP (spec)
5046 && EQ (XCAR (spec), Qraise)
5047 && CONSP (XCDR (spec)))
5049 if (it)
5051 if (!FRAME_WINDOW_P (it->f))
5052 return 0;
5054 #ifdef HAVE_WINDOW_SYSTEM
5055 value = XCAR (XCDR (spec));
5056 if (NUMBERP (value))
5058 struct face *face = FACE_FROM_ID (it->f, it->face_id);
5059 it->voffset = - (XFLOATINT (value)
5060 * (FONT_HEIGHT (face->font)));
5062 #endif /* HAVE_WINDOW_SYSTEM */
5065 return 0;
5068 /* Don't handle the other kinds of display specifications
5069 inside a string that we got from a `display' property. */
5070 if (it && it->string_from_display_prop_p)
5071 return 0;
5073 /* Characters having this form of property are not displayed, so
5074 we have to find the end of the property. */
5075 if (it)
5077 start_pos = *position;
5078 *position = display_prop_end (it, object, start_pos);
5080 value = Qnil;
5082 /* Stop the scan at that end position--we assume that all
5083 text properties change there. */
5084 if (it)
5085 it->stop_charpos = position->charpos;
5087 /* Handle `(left-fringe BITMAP [FACE])'
5088 and `(right-fringe BITMAP [FACE])'. */
5089 if (CONSP (spec)
5090 && (EQ (XCAR (spec), Qleft_fringe)
5091 || EQ (XCAR (spec), Qright_fringe))
5092 && CONSP (XCDR (spec)))
5094 int fringe_bitmap;
5096 if (it)
5098 if (!FRAME_WINDOW_P (it->f))
5099 /* If we return here, POSITION has been advanced
5100 across the text with this property. */
5102 /* Synchronize the bidi iterator with POSITION. This is
5103 needed because we are not going to push the iterator
5104 on behalf of this display property, so there will be
5105 no pop_it call to do this synchronization for us. */
5106 if (it->bidi_p)
5108 it->position = *position;
5109 iterate_out_of_display_property (it);
5110 *position = it->position;
5112 return 1;
5115 else if (!frame_window_p)
5116 return 1;
5118 #ifdef HAVE_WINDOW_SYSTEM
5119 value = XCAR (XCDR (spec));
5120 if (!SYMBOLP (value)
5121 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
5122 /* If we return here, POSITION has been advanced
5123 across the text with this property. */
5125 if (it && it->bidi_p)
5127 it->position = *position;
5128 iterate_out_of_display_property (it);
5129 *position = it->position;
5131 return 1;
5134 if (it)
5136 int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
5138 if (CONSP (XCDR (XCDR (spec))))
5140 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
5141 int face_id2 = lookup_derived_face (it->f, face_name,
5142 FRINGE_FACE_ID, 0);
5143 if (face_id2 >= 0)
5144 face_id = face_id2;
5147 /* Save current settings of IT so that we can restore them
5148 when we are finished with the glyph property value. */
5149 push_it (it, position);
5151 it->area = TEXT_AREA;
5152 it->what = IT_IMAGE;
5153 it->image_id = -1; /* no image */
5154 it->position = start_pos;
5155 it->object = NILP (object) ? it->w->contents : object;
5156 it->method = GET_FROM_IMAGE;
5157 it->from_overlay = Qnil;
5158 it->face_id = face_id;
5159 it->from_disp_prop_p = true;
5161 /* Say that we haven't consumed the characters with
5162 `display' property yet. The call to pop_it in
5163 set_iterator_to_next will clean this up. */
5164 *position = start_pos;
5166 if (EQ (XCAR (spec), Qleft_fringe))
5168 it->left_user_fringe_bitmap = fringe_bitmap;
5169 it->left_user_fringe_face_id = face_id;
5171 else
5173 it->right_user_fringe_bitmap = fringe_bitmap;
5174 it->right_user_fringe_face_id = face_id;
5177 #endif /* HAVE_WINDOW_SYSTEM */
5178 return 1;
5181 /* Prepare to handle `((margin left-margin) ...)',
5182 `((margin right-margin) ...)' and `((margin nil) ...)'
5183 prefixes for display specifications. */
5184 location = Qunbound;
5185 if (CONSP (spec) && CONSP (XCAR (spec)))
5187 Lisp_Object tem;
5189 value = XCDR (spec);
5190 if (CONSP (value))
5191 value = XCAR (value);
5193 tem = XCAR (spec);
5194 if (EQ (XCAR (tem), Qmargin)
5195 && (tem = XCDR (tem),
5196 tem = CONSP (tem) ? XCAR (tem) : Qnil,
5197 (NILP (tem)
5198 || EQ (tem, Qleft_margin)
5199 || EQ (tem, Qright_margin))))
5200 location = tem;
5203 if (EQ (location, Qunbound))
5205 location = Qnil;
5206 value = spec;
5209 /* After this point, VALUE is the property after any
5210 margin prefix has been stripped. It must be a string,
5211 an image specification, or `(space ...)'.
5213 LOCATION specifies where to display: `left-margin',
5214 `right-margin' or nil. */
5216 valid_p = (STRINGP (value)
5217 #ifdef HAVE_WINDOW_SYSTEM
5218 || ((it ? FRAME_WINDOW_P (it->f) : frame_window_p)
5219 && valid_image_p (value))
5220 #endif /* not HAVE_WINDOW_SYSTEM */
5221 || (CONSP (value) && EQ (XCAR (value), Qspace)));
5223 if (valid_p && !display_replaced_p)
5225 int retval = 1;
5227 if (!it)
5229 /* Callers need to know whether the display spec is any kind
5230 of `(space ...)' spec that is about to affect text-area
5231 display. */
5232 if (CONSP (value) && EQ (XCAR (value), Qspace) && NILP (location))
5233 retval = 2;
5234 return retval;
5237 /* Save current settings of IT so that we can restore them
5238 when we are finished with the glyph property value. */
5239 push_it (it, position);
5240 it->from_overlay = overlay;
5241 it->from_disp_prop_p = true;
5243 if (NILP (location))
5244 it->area = TEXT_AREA;
5245 else if (EQ (location, Qleft_margin))
5246 it->area = LEFT_MARGIN_AREA;
5247 else
5248 it->area = RIGHT_MARGIN_AREA;
5250 if (STRINGP (value))
5252 it->string = value;
5253 it->multibyte_p = STRING_MULTIBYTE (it->string);
5254 it->current.overlay_string_index = -1;
5255 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5256 it->end_charpos = it->string_nchars = SCHARS (it->string);
5257 it->method = GET_FROM_STRING;
5258 it->stop_charpos = 0;
5259 it->prev_stop = 0;
5260 it->base_level_stop = 0;
5261 it->string_from_display_prop_p = true;
5262 /* Say that we haven't consumed the characters with
5263 `display' property yet. The call to pop_it in
5264 set_iterator_to_next will clean this up. */
5265 if (BUFFERP (object))
5266 *position = start_pos;
5268 /* Force paragraph direction to be that of the parent
5269 object. If the parent object's paragraph direction is
5270 not yet determined, default to L2R. */
5271 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
5272 it->paragraph_embedding = it->bidi_it.paragraph_dir;
5273 else
5274 it->paragraph_embedding = L2R;
5276 /* Set up the bidi iterator for this display string. */
5277 if (it->bidi_p)
5279 it->bidi_it.string.lstring = it->string;
5280 it->bidi_it.string.s = NULL;
5281 it->bidi_it.string.schars = it->end_charpos;
5282 it->bidi_it.string.bufpos = bufpos;
5283 it->bidi_it.string.from_disp_str = 1;
5284 it->bidi_it.string.unibyte = !it->multibyte_p;
5285 it->bidi_it.w = it->w;
5286 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5289 else if (CONSP (value) && EQ (XCAR (value), Qspace))
5291 it->method = GET_FROM_STRETCH;
5292 it->object = value;
5293 *position = it->position = start_pos;
5294 retval = 1 + (it->area == TEXT_AREA);
5296 #ifdef HAVE_WINDOW_SYSTEM
5297 else
5299 it->what = IT_IMAGE;
5300 it->image_id = lookup_image (it->f, value);
5301 it->position = start_pos;
5302 it->object = NILP (object) ? it->w->contents : object;
5303 it->method = GET_FROM_IMAGE;
5305 /* Say that we haven't consumed the characters with
5306 `display' property yet. The call to pop_it in
5307 set_iterator_to_next will clean this up. */
5308 *position = start_pos;
5310 #endif /* HAVE_WINDOW_SYSTEM */
5312 return retval;
5315 /* Invalid property or property not supported. Restore
5316 POSITION to what it was before. */
5317 *position = start_pos;
5318 return 0;
5321 /* Check if PROP is a display property value whose text should be
5322 treated as intangible. OVERLAY is the overlay from which PROP
5323 came, or nil if it came from a text property. CHARPOS and BYTEPOS
5324 specify the buffer position covered by PROP. */
5327 display_prop_intangible_p (Lisp_Object prop, Lisp_Object overlay,
5328 ptrdiff_t charpos, ptrdiff_t bytepos)
5330 int frame_window_p = FRAME_WINDOW_P (XFRAME (selected_frame));
5331 struct text_pos position;
5333 SET_TEXT_POS (position, charpos, bytepos);
5334 return handle_display_spec (NULL, prop, Qnil, overlay,
5335 &position, charpos, frame_window_p);
5339 /* Return 1 if PROP is a display sub-property value containing STRING.
5341 Implementation note: this and the following function are really
5342 special cases of handle_display_spec and
5343 handle_single_display_spec, and should ideally use the same code.
5344 Until they do, these two pairs must be consistent and must be
5345 modified in sync. */
5347 static int
5348 single_display_spec_string_p (Lisp_Object prop, Lisp_Object string)
5350 if (EQ (string, prop))
5351 return 1;
5353 /* Skip over `when FORM'. */
5354 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
5356 prop = XCDR (prop);
5357 if (!CONSP (prop))
5358 return 0;
5359 /* Actually, the condition following `when' should be eval'ed,
5360 like handle_single_display_spec does, and we should return
5361 zero if it evaluates to nil. However, this function is
5362 called only when the buffer was already displayed and some
5363 glyph in the glyph matrix was found to come from a display
5364 string. Therefore, the condition was already evaluated, and
5365 the result was non-nil, otherwise the display string wouldn't
5366 have been displayed and we would have never been called for
5367 this property. Thus, we can skip the evaluation and assume
5368 its result is non-nil. */
5369 prop = XCDR (prop);
5372 if (CONSP (prop))
5373 /* Skip over `margin LOCATION'. */
5374 if (EQ (XCAR (prop), Qmargin))
5376 prop = XCDR (prop);
5377 if (!CONSP (prop))
5378 return 0;
5380 prop = XCDR (prop);
5381 if (!CONSP (prop))
5382 return 0;
5385 return EQ (prop, string) || (CONSP (prop) && EQ (XCAR (prop), string));
5389 /* Return 1 if STRING appears in the `display' property PROP. */
5391 static int
5392 display_prop_string_p (Lisp_Object prop, Lisp_Object string)
5394 if (CONSP (prop)
5395 && !EQ (XCAR (prop), Qwhen)
5396 && !(CONSP (XCAR (prop)) && EQ (Qmargin, XCAR (XCAR (prop)))))
5398 /* A list of sub-properties. */
5399 while (CONSP (prop))
5401 if (single_display_spec_string_p (XCAR (prop), string))
5402 return 1;
5403 prop = XCDR (prop);
5406 else if (VECTORP (prop))
5408 /* A vector of sub-properties. */
5409 ptrdiff_t i;
5410 for (i = 0; i < ASIZE (prop); ++i)
5411 if (single_display_spec_string_p (AREF (prop, i), string))
5412 return 1;
5414 else
5415 return single_display_spec_string_p (prop, string);
5417 return 0;
5420 /* Look for STRING in overlays and text properties in the current
5421 buffer, between character positions FROM and TO (excluding TO).
5422 BACK_P non-zero means look back (in this case, TO is supposed to be
5423 less than FROM).
5424 Value is the first character position where STRING was found, or
5425 zero if it wasn't found before hitting TO.
5427 This function may only use code that doesn't eval because it is
5428 called asynchronously from note_mouse_highlight. */
5430 static ptrdiff_t
5431 string_buffer_position_lim (Lisp_Object string,
5432 ptrdiff_t from, ptrdiff_t to, int back_p)
5434 Lisp_Object limit, prop, pos;
5435 int found = 0;
5437 pos = make_number (max (from, BEGV));
5439 if (!back_p) /* looking forward */
5441 limit = make_number (min (to, ZV));
5442 while (!found && !EQ (pos, limit))
5444 prop = Fget_char_property (pos, Qdisplay, Qnil);
5445 if (!NILP (prop) && display_prop_string_p (prop, string))
5446 found = 1;
5447 else
5448 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil,
5449 limit);
5452 else /* looking back */
5454 limit = make_number (max (to, BEGV));
5455 while (!found && !EQ (pos, limit))
5457 prop = Fget_char_property (pos, Qdisplay, Qnil);
5458 if (!NILP (prop) && display_prop_string_p (prop, string))
5459 found = 1;
5460 else
5461 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
5462 limit);
5466 return found ? XINT (pos) : 0;
5469 /* Determine which buffer position in current buffer STRING comes from.
5470 AROUND_CHARPOS is an approximate position where it could come from.
5471 Value is the buffer position or 0 if it couldn't be determined.
5473 This function is necessary because we don't record buffer positions
5474 in glyphs generated from strings (to keep struct glyph small).
5475 This function may only use code that doesn't eval because it is
5476 called asynchronously from note_mouse_highlight. */
5478 static ptrdiff_t
5479 string_buffer_position (Lisp_Object string, ptrdiff_t around_charpos)
5481 const int MAX_DISTANCE = 1000;
5482 ptrdiff_t found = string_buffer_position_lim (string, around_charpos,
5483 around_charpos + MAX_DISTANCE,
5486 if (!found)
5487 found = string_buffer_position_lim (string, around_charpos,
5488 around_charpos - MAX_DISTANCE, 1);
5489 return found;
5494 /***********************************************************************
5495 `composition' property
5496 ***********************************************************************/
5498 /* Set up iterator IT from `composition' property at its current
5499 position. Called from handle_stop. */
5501 static enum prop_handled
5502 handle_composition_prop (struct it *it)
5504 Lisp_Object prop, string;
5505 ptrdiff_t pos, pos_byte, start, end;
5507 if (STRINGP (it->string))
5509 unsigned char *s;
5511 pos = IT_STRING_CHARPOS (*it);
5512 pos_byte = IT_STRING_BYTEPOS (*it);
5513 string = it->string;
5514 s = SDATA (string) + pos_byte;
5515 it->c = STRING_CHAR (s);
5517 else
5519 pos = IT_CHARPOS (*it);
5520 pos_byte = IT_BYTEPOS (*it);
5521 string = Qnil;
5522 it->c = FETCH_CHAR (pos_byte);
5525 /* If there's a valid composition and point is not inside of the
5526 composition (in the case that the composition is from the current
5527 buffer), draw a glyph composed from the composition components. */
5528 if (find_composition (pos, -1, &start, &end, &prop, string)
5529 && composition_valid_p (start, end, prop)
5530 && (STRINGP (it->string) || (PT <= start || PT >= end)))
5532 if (start < pos)
5533 /* As we can't handle this situation (perhaps font-lock added
5534 a new composition), we just return here hoping that next
5535 redisplay will detect this composition much earlier. */
5536 return HANDLED_NORMALLY;
5537 if (start != pos)
5539 if (STRINGP (it->string))
5540 pos_byte = string_char_to_byte (it->string, start);
5541 else
5542 pos_byte = CHAR_TO_BYTE (start);
5544 it->cmp_it.id = get_composition_id (start, pos_byte, end - start,
5545 prop, string);
5547 if (it->cmp_it.id >= 0)
5549 it->cmp_it.ch = -1;
5550 it->cmp_it.nchars = COMPOSITION_LENGTH (prop);
5551 it->cmp_it.nglyphs = -1;
5555 return HANDLED_NORMALLY;
5560 /***********************************************************************
5561 Overlay strings
5562 ***********************************************************************/
5564 /* The following structure is used to record overlay strings for
5565 later sorting in load_overlay_strings. */
5567 struct overlay_entry
5569 Lisp_Object overlay;
5570 Lisp_Object string;
5571 EMACS_INT priority;
5572 int after_string_p;
5576 /* Set up iterator IT from overlay strings at its current position.
5577 Called from handle_stop. */
5579 static enum prop_handled
5580 handle_overlay_change (struct it *it)
5582 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
5583 return HANDLED_RECOMPUTE_PROPS;
5584 else
5585 return HANDLED_NORMALLY;
5589 /* Set up the next overlay string for delivery by IT, if there is an
5590 overlay string to deliver. Called by set_iterator_to_next when the
5591 end of the current overlay string is reached. If there are more
5592 overlay strings to display, IT->string and
5593 IT->current.overlay_string_index are set appropriately here.
5594 Otherwise IT->string is set to nil. */
5596 static void
5597 next_overlay_string (struct it *it)
5599 ++it->current.overlay_string_index;
5600 if (it->current.overlay_string_index == it->n_overlay_strings)
5602 /* No more overlay strings. Restore IT's settings to what
5603 they were before overlay strings were processed, and
5604 continue to deliver from current_buffer. */
5606 it->ellipsis_p = (it->stack[it->sp - 1].display_ellipsis_p != 0);
5607 pop_it (it);
5608 eassert (it->sp > 0
5609 || (NILP (it->string)
5610 && it->method == GET_FROM_BUFFER
5611 && it->stop_charpos >= BEGV
5612 && it->stop_charpos <= it->end_charpos));
5613 it->current.overlay_string_index = -1;
5614 it->n_overlay_strings = 0;
5615 it->overlay_strings_charpos = -1;
5616 /* If there's an empty display string on the stack, pop the
5617 stack, to resync the bidi iterator with IT's position. Such
5618 empty strings are pushed onto the stack in
5619 get_overlay_strings_1. */
5620 if (it->sp > 0 && STRINGP (it->string) && !SCHARS (it->string))
5621 pop_it (it);
5623 /* If we're at the end of the buffer, record that we have
5624 processed the overlay strings there already, so that
5625 next_element_from_buffer doesn't try it again. */
5626 if (NILP (it->string) && IT_CHARPOS (*it) >= it->end_charpos)
5627 it->overlay_strings_at_end_processed_p = true;
5629 else
5631 /* There are more overlay strings to process. If
5632 IT->current.overlay_string_index has advanced to a position
5633 where we must load IT->overlay_strings with more strings, do
5634 it. We must load at the IT->overlay_strings_charpos where
5635 IT->n_overlay_strings was originally computed; when invisible
5636 text is present, this might not be IT_CHARPOS (Bug#7016). */
5637 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
5639 if (it->current.overlay_string_index && i == 0)
5640 load_overlay_strings (it, it->overlay_strings_charpos);
5642 /* Initialize IT to deliver display elements from the overlay
5643 string. */
5644 it->string = it->overlay_strings[i];
5645 it->multibyte_p = STRING_MULTIBYTE (it->string);
5646 SET_TEXT_POS (it->current.string_pos, 0, 0);
5647 it->method = GET_FROM_STRING;
5648 it->stop_charpos = 0;
5649 it->end_charpos = SCHARS (it->string);
5650 if (it->cmp_it.stop_pos >= 0)
5651 it->cmp_it.stop_pos = 0;
5652 it->prev_stop = 0;
5653 it->base_level_stop = 0;
5655 /* Set up the bidi iterator for this overlay string. */
5656 if (it->bidi_p)
5658 it->bidi_it.string.lstring = it->string;
5659 it->bidi_it.string.s = NULL;
5660 it->bidi_it.string.schars = SCHARS (it->string);
5661 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
5662 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5663 it->bidi_it.string.unibyte = !it->multibyte_p;
5664 it->bidi_it.w = it->w;
5665 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5669 CHECK_IT (it);
5673 /* Compare two overlay_entry structures E1 and E2. Used as a
5674 comparison function for qsort in load_overlay_strings. Overlay
5675 strings for the same position are sorted so that
5677 1. All after-strings come in front of before-strings, except
5678 when they come from the same overlay.
5680 2. Within after-strings, strings are sorted so that overlay strings
5681 from overlays with higher priorities come first.
5683 2. Within before-strings, strings are sorted so that overlay
5684 strings from overlays with higher priorities come last.
5686 Value is analogous to strcmp. */
5689 static int
5690 compare_overlay_entries (const void *e1, const void *e2)
5692 struct overlay_entry const *entry1 = e1;
5693 struct overlay_entry const *entry2 = e2;
5694 int result;
5696 if (entry1->after_string_p != entry2->after_string_p)
5698 /* Let after-strings appear in front of before-strings if
5699 they come from different overlays. */
5700 if (EQ (entry1->overlay, entry2->overlay))
5701 result = entry1->after_string_p ? 1 : -1;
5702 else
5703 result = entry1->after_string_p ? -1 : 1;
5705 else if (entry1->priority != entry2->priority)
5707 if (entry1->after_string_p)
5708 /* After-strings sorted in order of decreasing priority. */
5709 result = entry2->priority < entry1->priority ? -1 : 1;
5710 else
5711 /* Before-strings sorted in order of increasing priority. */
5712 result = entry1->priority < entry2->priority ? -1 : 1;
5714 else
5715 result = 0;
5717 return result;
5721 /* Load the vector IT->overlay_strings with overlay strings from IT's
5722 current buffer position, or from CHARPOS if that is > 0. Set
5723 IT->n_overlays to the total number of overlay strings found.
5725 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
5726 a time. On entry into load_overlay_strings,
5727 IT->current.overlay_string_index gives the number of overlay
5728 strings that have already been loaded by previous calls to this
5729 function.
5731 IT->add_overlay_start contains an additional overlay start
5732 position to consider for taking overlay strings from, if non-zero.
5733 This position comes into play when the overlay has an `invisible'
5734 property, and both before and after-strings. When we've skipped to
5735 the end of the overlay, because of its `invisible' property, we
5736 nevertheless want its before-string to appear.
5737 IT->add_overlay_start will contain the overlay start position
5738 in this case.
5740 Overlay strings are sorted so that after-string strings come in
5741 front of before-string strings. Within before and after-strings,
5742 strings are sorted by overlay priority. See also function
5743 compare_overlay_entries. */
5745 static void
5746 load_overlay_strings (struct it *it, ptrdiff_t charpos)
5748 Lisp_Object overlay, window, str, invisible;
5749 struct Lisp_Overlay *ov;
5750 ptrdiff_t start, end;
5751 ptrdiff_t n = 0, i, j;
5752 int invis_p;
5753 struct overlay_entry entriesbuf[20];
5754 ptrdiff_t size = ARRAYELTS (entriesbuf);
5755 struct overlay_entry *entries = entriesbuf;
5756 USE_SAFE_ALLOCA;
5758 if (charpos <= 0)
5759 charpos = IT_CHARPOS (*it);
5761 /* Append the overlay string STRING of overlay OVERLAY to vector
5762 `entries' which has size `size' and currently contains `n'
5763 elements. AFTER_P non-zero means STRING is an after-string of
5764 OVERLAY. */
5765 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
5766 do \
5768 Lisp_Object priority; \
5770 if (n == size) \
5772 struct overlay_entry *old = entries; \
5773 SAFE_NALLOCA (entries, 2, size); \
5774 memcpy (entries, old, size * sizeof *entries); \
5775 size *= 2; \
5778 entries[n].string = (STRING); \
5779 entries[n].overlay = (OVERLAY); \
5780 priority = Foverlay_get ((OVERLAY), Qpriority); \
5781 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
5782 entries[n].after_string_p = (AFTER_P); \
5783 ++n; \
5785 while (0)
5787 /* Process overlay before the overlay center. */
5788 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
5790 XSETMISC (overlay, ov);
5791 eassert (OVERLAYP (overlay));
5792 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5793 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5795 if (end < charpos)
5796 break;
5798 /* Skip this overlay if it doesn't start or end at IT's current
5799 position. */
5800 if (end != charpos && start != charpos)
5801 continue;
5803 /* Skip this overlay if it doesn't apply to IT->w. */
5804 window = Foverlay_get (overlay, Qwindow);
5805 if (WINDOWP (window) && XWINDOW (window) != it->w)
5806 continue;
5808 /* If the text ``under'' the overlay is invisible, both before-
5809 and after-strings from this overlay are visible; start and
5810 end position are indistinguishable. */
5811 invisible = Foverlay_get (overlay, Qinvisible);
5812 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5814 /* If overlay has a non-empty before-string, record it. */
5815 if ((start == charpos || (end == charpos && invis_p))
5816 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5817 && SCHARS (str))
5818 RECORD_OVERLAY_STRING (overlay, str, 0);
5820 /* If overlay has a non-empty after-string, record it. */
5821 if ((end == charpos || (start == charpos && invis_p))
5822 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5823 && SCHARS (str))
5824 RECORD_OVERLAY_STRING (overlay, str, 1);
5827 /* Process overlays after the overlay center. */
5828 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
5830 XSETMISC (overlay, ov);
5831 eassert (OVERLAYP (overlay));
5832 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5833 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5835 if (start > charpos)
5836 break;
5838 /* Skip this overlay if it doesn't start or end at IT's current
5839 position. */
5840 if (end != charpos && start != charpos)
5841 continue;
5843 /* Skip this overlay if it doesn't apply to IT->w. */
5844 window = Foverlay_get (overlay, Qwindow);
5845 if (WINDOWP (window) && XWINDOW (window) != it->w)
5846 continue;
5848 /* If the text ``under'' the overlay is invisible, it has a zero
5849 dimension, and both before- and after-strings apply. */
5850 invisible = Foverlay_get (overlay, Qinvisible);
5851 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5853 /* If overlay has a non-empty before-string, record it. */
5854 if ((start == charpos || (end == charpos && invis_p))
5855 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5856 && SCHARS (str))
5857 RECORD_OVERLAY_STRING (overlay, str, 0);
5859 /* If overlay has a non-empty after-string, record it. */
5860 if ((end == charpos || (start == charpos && invis_p))
5861 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5862 && SCHARS (str))
5863 RECORD_OVERLAY_STRING (overlay, str, 1);
5866 #undef RECORD_OVERLAY_STRING
5868 /* Sort entries. */
5869 if (n > 1)
5870 qsort (entries, n, sizeof *entries, compare_overlay_entries);
5872 /* Record number of overlay strings, and where we computed it. */
5873 it->n_overlay_strings = n;
5874 it->overlay_strings_charpos = charpos;
5876 /* IT->current.overlay_string_index is the number of overlay strings
5877 that have already been consumed by IT. Copy some of the
5878 remaining overlay strings to IT->overlay_strings. */
5879 i = 0;
5880 j = it->current.overlay_string_index;
5881 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
5883 it->overlay_strings[i] = entries[j].string;
5884 it->string_overlays[i++] = entries[j++].overlay;
5887 CHECK_IT (it);
5888 SAFE_FREE ();
5892 /* Get the first chunk of overlay strings at IT's current buffer
5893 position, or at CHARPOS if that is > 0. Value is non-zero if at
5894 least one overlay string was found. */
5896 static int
5897 get_overlay_strings_1 (struct it *it, ptrdiff_t charpos, int compute_stop_p)
5899 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
5900 process. This fills IT->overlay_strings with strings, and sets
5901 IT->n_overlay_strings to the total number of strings to process.
5902 IT->pos.overlay_string_index has to be set temporarily to zero
5903 because load_overlay_strings needs this; it must be set to -1
5904 when no overlay strings are found because a zero value would
5905 indicate a position in the first overlay string. */
5906 it->current.overlay_string_index = 0;
5907 load_overlay_strings (it, charpos);
5909 /* If we found overlay strings, set up IT to deliver display
5910 elements from the first one. Otherwise set up IT to deliver
5911 from current_buffer. */
5912 if (it->n_overlay_strings)
5914 /* Make sure we know settings in current_buffer, so that we can
5915 restore meaningful values when we're done with the overlay
5916 strings. */
5917 if (compute_stop_p)
5918 compute_stop_pos (it);
5919 eassert (it->face_id >= 0);
5921 /* Save IT's settings. They are restored after all overlay
5922 strings have been processed. */
5923 eassert (!compute_stop_p || it->sp == 0);
5925 /* When called from handle_stop, there might be an empty display
5926 string loaded. In that case, don't bother saving it. But
5927 don't use this optimization with the bidi iterator, since we
5928 need the corresponding pop_it call to resync the bidi
5929 iterator's position with IT's position, after we are done
5930 with the overlay strings. (The corresponding call to pop_it
5931 in case of an empty display string is in
5932 next_overlay_string.) */
5933 if (!(!it->bidi_p
5934 && STRINGP (it->string) && !SCHARS (it->string)))
5935 push_it (it, NULL);
5937 /* Set up IT to deliver display elements from the first overlay
5938 string. */
5939 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5940 it->string = it->overlay_strings[0];
5941 it->from_overlay = Qnil;
5942 it->stop_charpos = 0;
5943 eassert (STRINGP (it->string));
5944 it->end_charpos = SCHARS (it->string);
5945 it->prev_stop = 0;
5946 it->base_level_stop = 0;
5947 it->multibyte_p = STRING_MULTIBYTE (it->string);
5948 it->method = GET_FROM_STRING;
5949 it->from_disp_prop_p = 0;
5951 /* Force paragraph direction to be that of the parent
5952 buffer. */
5953 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
5954 it->paragraph_embedding = it->bidi_it.paragraph_dir;
5955 else
5956 it->paragraph_embedding = L2R;
5958 /* Set up the bidi iterator for this overlay string. */
5959 if (it->bidi_p)
5961 ptrdiff_t pos = (charpos > 0 ? charpos : IT_CHARPOS (*it));
5963 it->bidi_it.string.lstring = it->string;
5964 it->bidi_it.string.s = NULL;
5965 it->bidi_it.string.schars = SCHARS (it->string);
5966 it->bidi_it.string.bufpos = pos;
5967 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5968 it->bidi_it.string.unibyte = !it->multibyte_p;
5969 it->bidi_it.w = it->w;
5970 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5972 return 1;
5975 it->current.overlay_string_index = -1;
5976 return 0;
5979 static int
5980 get_overlay_strings (struct it *it, ptrdiff_t charpos)
5982 it->string = Qnil;
5983 it->method = GET_FROM_BUFFER;
5985 (void) get_overlay_strings_1 (it, charpos, 1);
5987 CHECK_IT (it);
5989 /* Value is non-zero if we found at least one overlay string. */
5990 return STRINGP (it->string);
5995 /***********************************************************************
5996 Saving and restoring state
5997 ***********************************************************************/
5999 /* Save current settings of IT on IT->stack. Called, for example,
6000 before setting up IT for an overlay string, to be able to restore
6001 IT's settings to what they were after the overlay string has been
6002 processed. If POSITION is non-NULL, it is the position to save on
6003 the stack instead of IT->position. */
6005 static void
6006 push_it (struct it *it, struct text_pos *position)
6008 struct iterator_stack_entry *p;
6010 eassert (it->sp < IT_STACK_SIZE);
6011 p = it->stack + it->sp;
6013 p->stop_charpos = it->stop_charpos;
6014 p->prev_stop = it->prev_stop;
6015 p->base_level_stop = it->base_level_stop;
6016 p->cmp_it = it->cmp_it;
6017 eassert (it->face_id >= 0);
6018 p->face_id = it->face_id;
6019 p->string = it->string;
6020 p->method = it->method;
6021 p->from_overlay = it->from_overlay;
6022 switch (p->method)
6024 case GET_FROM_IMAGE:
6025 p->u.image.object = it->object;
6026 p->u.image.image_id = it->image_id;
6027 p->u.image.slice = it->slice;
6028 break;
6029 case GET_FROM_STRETCH:
6030 p->u.stretch.object = it->object;
6031 break;
6033 p->position = position ? *position : it->position;
6034 p->current = it->current;
6035 p->end_charpos = it->end_charpos;
6036 p->string_nchars = it->string_nchars;
6037 p->area = it->area;
6038 p->multibyte_p = it->multibyte_p;
6039 p->avoid_cursor_p = it->avoid_cursor_p;
6040 p->space_width = it->space_width;
6041 p->font_height = it->font_height;
6042 p->voffset = it->voffset;
6043 p->string_from_display_prop_p = it->string_from_display_prop_p;
6044 p->string_from_prefix_prop_p = it->string_from_prefix_prop_p;
6045 p->display_ellipsis_p = 0;
6046 p->line_wrap = it->line_wrap;
6047 p->bidi_p = it->bidi_p;
6048 p->paragraph_embedding = it->paragraph_embedding;
6049 p->from_disp_prop_p = it->from_disp_prop_p;
6050 ++it->sp;
6052 /* Save the state of the bidi iterator as well. */
6053 if (it->bidi_p)
6054 bidi_push_it (&it->bidi_it);
6057 static void
6058 iterate_out_of_display_property (struct it *it)
6060 int buffer_p = !STRINGP (it->string);
6061 ptrdiff_t eob = (buffer_p ? ZV : it->end_charpos);
6062 ptrdiff_t bob = (buffer_p ? BEGV : 0);
6064 eassert (eob >= CHARPOS (it->position) && CHARPOS (it->position) >= bob);
6066 /* Maybe initialize paragraph direction. If we are at the beginning
6067 of a new paragraph, next_element_from_buffer may not have a
6068 chance to do that. */
6069 if (it->bidi_it.first_elt && it->bidi_it.charpos < eob)
6070 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
6071 /* prev_stop can be zero, so check against BEGV as well. */
6072 while (it->bidi_it.charpos >= bob
6073 && it->prev_stop <= it->bidi_it.charpos
6074 && it->bidi_it.charpos < CHARPOS (it->position)
6075 && it->bidi_it.charpos < eob)
6076 bidi_move_to_visually_next (&it->bidi_it);
6077 /* Record the stop_pos we just crossed, for when we cross it
6078 back, maybe. */
6079 if (it->bidi_it.charpos > CHARPOS (it->position))
6080 it->prev_stop = CHARPOS (it->position);
6081 /* If we ended up not where pop_it put us, resync IT's
6082 positional members with the bidi iterator. */
6083 if (it->bidi_it.charpos != CHARPOS (it->position))
6084 SET_TEXT_POS (it->position, it->bidi_it.charpos, it->bidi_it.bytepos);
6085 if (buffer_p)
6086 it->current.pos = it->position;
6087 else
6088 it->current.string_pos = it->position;
6091 /* Restore IT's settings from IT->stack. Called, for example, when no
6092 more overlay strings must be processed, and we return to delivering
6093 display elements from a buffer, or when the end of a string from a
6094 `display' property is reached and we return to delivering display
6095 elements from an overlay string, or from a buffer. */
6097 static void
6098 pop_it (struct it *it)
6100 struct iterator_stack_entry *p;
6101 int from_display_prop = it->from_disp_prop_p;
6103 eassert (it->sp > 0);
6104 --it->sp;
6105 p = it->stack + it->sp;
6106 it->stop_charpos = p->stop_charpos;
6107 it->prev_stop = p->prev_stop;
6108 it->base_level_stop = p->base_level_stop;
6109 it->cmp_it = p->cmp_it;
6110 it->face_id = p->face_id;
6111 it->current = p->current;
6112 it->position = p->position;
6113 it->string = p->string;
6114 it->from_overlay = p->from_overlay;
6115 if (NILP (it->string))
6116 SET_TEXT_POS (it->current.string_pos, -1, -1);
6117 it->method = p->method;
6118 switch (it->method)
6120 case GET_FROM_IMAGE:
6121 it->image_id = p->u.image.image_id;
6122 it->object = p->u.image.object;
6123 it->slice = p->u.image.slice;
6124 break;
6125 case GET_FROM_STRETCH:
6126 it->object = p->u.stretch.object;
6127 break;
6128 case GET_FROM_BUFFER:
6129 it->object = it->w->contents;
6130 break;
6131 case GET_FROM_STRING:
6133 struct face *face = FACE_FROM_ID (it->f, it->face_id);
6135 /* Restore the face_box_p flag, since it could have been
6136 overwritten by the face of the object that we just finished
6137 displaying. */
6138 if (face)
6139 it->face_box_p = face->box != FACE_NO_BOX;
6140 it->object = it->string;
6142 break;
6143 case GET_FROM_DISPLAY_VECTOR:
6144 if (it->s)
6145 it->method = GET_FROM_C_STRING;
6146 else if (STRINGP (it->string))
6147 it->method = GET_FROM_STRING;
6148 else
6150 it->method = GET_FROM_BUFFER;
6151 it->object = it->w->contents;
6154 it->end_charpos = p->end_charpos;
6155 it->string_nchars = p->string_nchars;
6156 it->area = p->area;
6157 it->multibyte_p = p->multibyte_p;
6158 it->avoid_cursor_p = p->avoid_cursor_p;
6159 it->space_width = p->space_width;
6160 it->font_height = p->font_height;
6161 it->voffset = p->voffset;
6162 it->string_from_display_prop_p = p->string_from_display_prop_p;
6163 it->string_from_prefix_prop_p = p->string_from_prefix_prop_p;
6164 it->line_wrap = p->line_wrap;
6165 it->bidi_p = p->bidi_p;
6166 it->paragraph_embedding = p->paragraph_embedding;
6167 it->from_disp_prop_p = p->from_disp_prop_p;
6168 if (it->bidi_p)
6170 bidi_pop_it (&it->bidi_it);
6171 /* Bidi-iterate until we get out of the portion of text, if any,
6172 covered by a `display' text property or by an overlay with
6173 `display' property. (We cannot just jump there, because the
6174 internal coherency of the bidi iterator state can not be
6175 preserved across such jumps.) We also must determine the
6176 paragraph base direction if the overlay we just processed is
6177 at the beginning of a new paragraph. */
6178 if (from_display_prop
6179 && (it->method == GET_FROM_BUFFER || it->method == GET_FROM_STRING))
6180 iterate_out_of_display_property (it);
6182 eassert ((BUFFERP (it->object)
6183 && IT_CHARPOS (*it) == it->bidi_it.charpos
6184 && IT_BYTEPOS (*it) == it->bidi_it.bytepos)
6185 || (STRINGP (it->object)
6186 && IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
6187 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos)
6188 || (CONSP (it->object) && it->method == GET_FROM_STRETCH));
6194 /***********************************************************************
6195 Moving over lines
6196 ***********************************************************************/
6198 /* Set IT's current position to the previous line start. */
6200 static void
6201 back_to_previous_line_start (struct it *it)
6203 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
6205 DEC_BOTH (cp, bp);
6206 IT_CHARPOS (*it) = find_newline_no_quit (cp, bp, -1, &IT_BYTEPOS (*it));
6210 /* Move IT to the next line start.
6212 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
6213 we skipped over part of the text (as opposed to moving the iterator
6214 continuously over the text). Otherwise, don't change the value
6215 of *SKIPPED_P.
6217 If BIDI_IT_PREV is non-NULL, store into it the state of the bidi
6218 iterator on the newline, if it was found.
6220 Newlines may come from buffer text, overlay strings, or strings
6221 displayed via the `display' property. That's the reason we can't
6222 simply use find_newline_no_quit.
6224 Note that this function may not skip over invisible text that is so
6225 because of text properties and immediately follows a newline. If
6226 it would, function reseat_at_next_visible_line_start, when called
6227 from set_iterator_to_next, would effectively make invisible
6228 characters following a newline part of the wrong glyph row, which
6229 leads to wrong cursor motion. */
6231 static int
6232 forward_to_next_line_start (struct it *it, int *skipped_p,
6233 struct bidi_it *bidi_it_prev)
6235 ptrdiff_t old_selective;
6236 int newline_found_p, n;
6237 const int MAX_NEWLINE_DISTANCE = 500;
6239 /* If already on a newline, just consume it to avoid unintended
6240 skipping over invisible text below. */
6241 if (it->what == IT_CHARACTER
6242 && it->c == '\n'
6243 && CHARPOS (it->position) == IT_CHARPOS (*it))
6245 if (it->bidi_p && bidi_it_prev)
6246 *bidi_it_prev = it->bidi_it;
6247 set_iterator_to_next (it, 0);
6248 it->c = 0;
6249 return 1;
6252 /* Don't handle selective display in the following. It's (a)
6253 unnecessary because it's done by the caller, and (b) leads to an
6254 infinite recursion because next_element_from_ellipsis indirectly
6255 calls this function. */
6256 old_selective = it->selective;
6257 it->selective = 0;
6259 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
6260 from buffer text. */
6261 for (n = newline_found_p = 0;
6262 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
6263 n += STRINGP (it->string) ? 0 : 1)
6265 if (!get_next_display_element (it))
6266 return 0;
6267 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
6268 if (newline_found_p && it->bidi_p && bidi_it_prev)
6269 *bidi_it_prev = it->bidi_it;
6270 set_iterator_to_next (it, 0);
6273 /* If we didn't find a newline near enough, see if we can use a
6274 short-cut. */
6275 if (!newline_found_p)
6277 ptrdiff_t bytepos, start = IT_CHARPOS (*it);
6278 ptrdiff_t limit = find_newline_no_quit (start, IT_BYTEPOS (*it),
6279 1, &bytepos);
6280 Lisp_Object pos;
6282 eassert (!STRINGP (it->string));
6284 /* If there isn't any `display' property in sight, and no
6285 overlays, we can just use the position of the newline in
6286 buffer text. */
6287 if (it->stop_charpos >= limit
6288 || ((pos = Fnext_single_property_change (make_number (start),
6289 Qdisplay, Qnil,
6290 make_number (limit)),
6291 NILP (pos))
6292 && next_overlay_change (start) == ZV))
6294 if (!it->bidi_p)
6296 IT_CHARPOS (*it) = limit;
6297 IT_BYTEPOS (*it) = bytepos;
6299 else
6301 struct bidi_it bprev;
6303 /* Help bidi.c avoid expensive searches for display
6304 properties and overlays, by telling it that there are
6305 none up to `limit'. */
6306 if (it->bidi_it.disp_pos < limit)
6308 it->bidi_it.disp_pos = limit;
6309 it->bidi_it.disp_prop = 0;
6311 do {
6312 bprev = it->bidi_it;
6313 bidi_move_to_visually_next (&it->bidi_it);
6314 } while (it->bidi_it.charpos != limit);
6315 IT_CHARPOS (*it) = limit;
6316 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6317 if (bidi_it_prev)
6318 *bidi_it_prev = bprev;
6320 *skipped_p = newline_found_p = true;
6322 else
6324 while (get_next_display_element (it)
6325 && !newline_found_p)
6327 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
6328 if (newline_found_p && it->bidi_p && bidi_it_prev)
6329 *bidi_it_prev = it->bidi_it;
6330 set_iterator_to_next (it, 0);
6335 it->selective = old_selective;
6336 return newline_found_p;
6340 /* Set IT's current position to the previous visible line start. Skip
6341 invisible text that is so either due to text properties or due to
6342 selective display. Caution: this does not change IT->current_x and
6343 IT->hpos. */
6345 static void
6346 back_to_previous_visible_line_start (struct it *it)
6348 while (IT_CHARPOS (*it) > BEGV)
6350 back_to_previous_line_start (it);
6352 if (IT_CHARPOS (*it) <= BEGV)
6353 break;
6355 /* If selective > 0, then lines indented more than its value are
6356 invisible. */
6357 if (it->selective > 0
6358 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6359 it->selective))
6360 continue;
6362 /* Check the newline before point for invisibility. */
6364 Lisp_Object prop;
6365 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
6366 Qinvisible, it->window);
6367 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6368 continue;
6371 if (IT_CHARPOS (*it) <= BEGV)
6372 break;
6375 struct it it2;
6376 void *it2data = NULL;
6377 ptrdiff_t pos;
6378 ptrdiff_t beg, end;
6379 Lisp_Object val, overlay;
6381 SAVE_IT (it2, *it, it2data);
6383 /* If newline is part of a composition, continue from start of composition */
6384 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
6385 && beg < IT_CHARPOS (*it))
6386 goto replaced;
6388 /* If newline is replaced by a display property, find start of overlay
6389 or interval and continue search from that point. */
6390 pos = --IT_CHARPOS (it2);
6391 --IT_BYTEPOS (it2);
6392 it2.sp = 0;
6393 bidi_unshelve_cache (NULL, 0);
6394 it2.string_from_display_prop_p = 0;
6395 it2.from_disp_prop_p = 0;
6396 if (handle_display_prop (&it2) == HANDLED_RETURN
6397 && !NILP (val = get_char_property_and_overlay
6398 (make_number (pos), Qdisplay, Qnil, &overlay))
6399 && (OVERLAYP (overlay)
6400 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
6401 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
6403 RESTORE_IT (it, it, it2data);
6404 goto replaced;
6407 /* Newline is not replaced by anything -- so we are done. */
6408 RESTORE_IT (it, it, it2data);
6409 break;
6411 replaced:
6412 if (beg < BEGV)
6413 beg = BEGV;
6414 IT_CHARPOS (*it) = beg;
6415 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
6419 it->continuation_lines_width = 0;
6421 eassert (IT_CHARPOS (*it) >= BEGV);
6422 eassert (IT_CHARPOS (*it) == BEGV
6423 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6424 CHECK_IT (it);
6428 /* Reseat iterator IT at the previous visible line start. Skip
6429 invisible text that is so either due to text properties or due to
6430 selective display. At the end, update IT's overlay information,
6431 face information etc. */
6433 void
6434 reseat_at_previous_visible_line_start (struct it *it)
6436 back_to_previous_visible_line_start (it);
6437 reseat (it, it->current.pos, 1);
6438 CHECK_IT (it);
6442 /* Reseat iterator IT on the next visible line start in the current
6443 buffer. ON_NEWLINE_P non-zero means position IT on the newline
6444 preceding the line start. Skip over invisible text that is so
6445 because of selective display. Compute faces, overlays etc at the
6446 new position. Note that this function does not skip over text that
6447 is invisible because of text properties. */
6449 static void
6450 reseat_at_next_visible_line_start (struct it *it, int on_newline_p)
6452 int newline_found_p, skipped_p = 0;
6453 struct bidi_it bidi_it_prev;
6455 newline_found_p = forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6457 /* Skip over lines that are invisible because they are indented
6458 more than the value of IT->selective. */
6459 if (it->selective > 0)
6460 while (IT_CHARPOS (*it) < ZV
6461 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6462 it->selective))
6464 eassert (IT_BYTEPOS (*it) == BEGV
6465 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6466 newline_found_p =
6467 forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6470 /* Position on the newline if that's what's requested. */
6471 if (on_newline_p && newline_found_p)
6473 if (STRINGP (it->string))
6475 if (IT_STRING_CHARPOS (*it) > 0)
6477 if (!it->bidi_p)
6479 --IT_STRING_CHARPOS (*it);
6480 --IT_STRING_BYTEPOS (*it);
6482 else
6484 /* We need to restore the bidi iterator to the state
6485 it had on the newline, and resync the IT's
6486 position with that. */
6487 it->bidi_it = bidi_it_prev;
6488 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
6489 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
6493 else if (IT_CHARPOS (*it) > BEGV)
6495 if (!it->bidi_p)
6497 --IT_CHARPOS (*it);
6498 --IT_BYTEPOS (*it);
6500 else
6502 /* We need to restore the bidi iterator to the state it
6503 had on the newline and resync IT with that. */
6504 it->bidi_it = bidi_it_prev;
6505 IT_CHARPOS (*it) = it->bidi_it.charpos;
6506 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6508 reseat (it, it->current.pos, 0);
6511 else if (skipped_p)
6512 reseat (it, it->current.pos, 0);
6514 CHECK_IT (it);
6519 /***********************************************************************
6520 Changing an iterator's position
6521 ***********************************************************************/
6523 /* Change IT's current position to POS in current_buffer. If FORCE_P
6524 is non-zero, always check for text properties at the new position.
6525 Otherwise, text properties are only looked up if POS >=
6526 IT->check_charpos of a property. */
6528 static void
6529 reseat (struct it *it, struct text_pos pos, int force_p)
6531 ptrdiff_t original_pos = IT_CHARPOS (*it);
6533 reseat_1 (it, pos, 0);
6535 /* Determine where to check text properties. Avoid doing it
6536 where possible because text property lookup is very expensive. */
6537 if (force_p
6538 || CHARPOS (pos) > it->stop_charpos
6539 || CHARPOS (pos) < original_pos)
6541 if (it->bidi_p)
6543 /* For bidi iteration, we need to prime prev_stop and
6544 base_level_stop with our best estimations. */
6545 /* Implementation note: Of course, POS is not necessarily a
6546 stop position, so assigning prev_pos to it is a lie; we
6547 should have called compute_stop_backwards. However, if
6548 the current buffer does not include any R2L characters,
6549 that call would be a waste of cycles, because the
6550 iterator will never move back, and thus never cross this
6551 "fake" stop position. So we delay that backward search
6552 until the time we really need it, in next_element_from_buffer. */
6553 if (CHARPOS (pos) != it->prev_stop)
6554 it->prev_stop = CHARPOS (pos);
6555 if (CHARPOS (pos) < it->base_level_stop)
6556 it->base_level_stop = 0; /* meaning it's unknown */
6557 handle_stop (it);
6559 else
6561 handle_stop (it);
6562 it->prev_stop = it->base_level_stop = 0;
6567 CHECK_IT (it);
6571 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
6572 IT->stop_pos to POS, also. */
6574 static void
6575 reseat_1 (struct it *it, struct text_pos pos, int set_stop_p)
6577 /* Don't call this function when scanning a C string. */
6578 eassert (it->s == NULL);
6580 /* POS must be a reasonable value. */
6581 eassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
6583 it->current.pos = it->position = pos;
6584 it->end_charpos = ZV;
6585 it->dpvec = NULL;
6586 it->current.dpvec_index = -1;
6587 it->current.overlay_string_index = -1;
6588 IT_STRING_CHARPOS (*it) = -1;
6589 IT_STRING_BYTEPOS (*it) = -1;
6590 it->string = Qnil;
6591 it->method = GET_FROM_BUFFER;
6592 it->object = it->w->contents;
6593 it->area = TEXT_AREA;
6594 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
6595 it->sp = 0;
6596 it->string_from_display_prop_p = 0;
6597 it->string_from_prefix_prop_p = 0;
6599 it->from_disp_prop_p = 0;
6600 it->face_before_selective_p = 0;
6601 if (it->bidi_p)
6603 bidi_init_it (IT_CHARPOS (*it), IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6604 &it->bidi_it);
6605 bidi_unshelve_cache (NULL, 0);
6606 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6607 it->bidi_it.string.s = NULL;
6608 it->bidi_it.string.lstring = Qnil;
6609 it->bidi_it.string.bufpos = 0;
6610 it->bidi_it.string.from_disp_str = 0;
6611 it->bidi_it.string.unibyte = 0;
6612 it->bidi_it.w = it->w;
6615 if (set_stop_p)
6617 it->stop_charpos = CHARPOS (pos);
6618 it->base_level_stop = CHARPOS (pos);
6620 /* This make the information stored in it->cmp_it invalidate. */
6621 it->cmp_it.id = -1;
6625 /* Set up IT for displaying a string, starting at CHARPOS in window W.
6626 If S is non-null, it is a C string to iterate over. Otherwise,
6627 STRING gives a Lisp string to iterate over.
6629 If PRECISION > 0, don't return more then PRECISION number of
6630 characters from the string.
6632 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
6633 characters have been returned. FIELD_WIDTH < 0 means an infinite
6634 field width.
6636 MULTIBYTE = 0 means disable processing of multibyte characters,
6637 MULTIBYTE > 0 means enable it,
6638 MULTIBYTE < 0 means use IT->multibyte_p.
6640 IT must be initialized via a prior call to init_iterator before
6641 calling this function. */
6643 static void
6644 reseat_to_string (struct it *it, const char *s, Lisp_Object string,
6645 ptrdiff_t charpos, ptrdiff_t precision, int field_width,
6646 int multibyte)
6648 /* No text property checks performed by default, but see below. */
6649 it->stop_charpos = -1;
6651 /* Set iterator position and end position. */
6652 memset (&it->current, 0, sizeof it->current);
6653 it->current.overlay_string_index = -1;
6654 it->current.dpvec_index = -1;
6655 eassert (charpos >= 0);
6657 /* If STRING is specified, use its multibyteness, otherwise use the
6658 setting of MULTIBYTE, if specified. */
6659 if (multibyte >= 0)
6660 it->multibyte_p = multibyte > 0;
6662 /* Bidirectional reordering of strings is controlled by the default
6663 value of bidi-display-reordering. Don't try to reorder while
6664 loading loadup.el, as the necessary character property tables are
6665 not yet available. */
6666 it->bidi_p =
6667 NILP (Vpurify_flag)
6668 && !NILP (BVAR (&buffer_defaults, bidi_display_reordering));
6670 if (s == NULL)
6672 eassert (STRINGP (string));
6673 it->string = string;
6674 it->s = NULL;
6675 it->end_charpos = it->string_nchars = SCHARS (string);
6676 it->method = GET_FROM_STRING;
6677 it->current.string_pos = string_pos (charpos, string);
6679 if (it->bidi_p)
6681 it->bidi_it.string.lstring = string;
6682 it->bidi_it.string.s = NULL;
6683 it->bidi_it.string.schars = it->end_charpos;
6684 it->bidi_it.string.bufpos = 0;
6685 it->bidi_it.string.from_disp_str = 0;
6686 it->bidi_it.string.unibyte = !it->multibyte_p;
6687 it->bidi_it.w = it->w;
6688 bidi_init_it (charpos, IT_STRING_BYTEPOS (*it),
6689 FRAME_WINDOW_P (it->f), &it->bidi_it);
6692 else
6694 it->s = (const unsigned char *) s;
6695 it->string = Qnil;
6697 /* Note that we use IT->current.pos, not it->current.string_pos,
6698 for displaying C strings. */
6699 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
6700 if (it->multibyte_p)
6702 it->current.pos = c_string_pos (charpos, s, 1);
6703 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
6705 else
6707 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
6708 it->end_charpos = it->string_nchars = strlen (s);
6711 if (it->bidi_p)
6713 it->bidi_it.string.lstring = Qnil;
6714 it->bidi_it.string.s = (const unsigned char *) s;
6715 it->bidi_it.string.schars = it->end_charpos;
6716 it->bidi_it.string.bufpos = 0;
6717 it->bidi_it.string.from_disp_str = 0;
6718 it->bidi_it.string.unibyte = !it->multibyte_p;
6719 it->bidi_it.w = it->w;
6720 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6721 &it->bidi_it);
6723 it->method = GET_FROM_C_STRING;
6726 /* PRECISION > 0 means don't return more than PRECISION characters
6727 from the string. */
6728 if (precision > 0 && it->end_charpos - charpos > precision)
6730 it->end_charpos = it->string_nchars = charpos + precision;
6731 if (it->bidi_p)
6732 it->bidi_it.string.schars = it->end_charpos;
6735 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
6736 characters have been returned. FIELD_WIDTH == 0 means don't pad,
6737 FIELD_WIDTH < 0 means infinite field width. This is useful for
6738 padding with `-' at the end of a mode line. */
6739 if (field_width < 0)
6740 field_width = INFINITY;
6741 /* Implementation note: We deliberately don't enlarge
6742 it->bidi_it.string.schars here to fit it->end_charpos, because
6743 the bidi iterator cannot produce characters out of thin air. */
6744 if (field_width > it->end_charpos - charpos)
6745 it->end_charpos = charpos + field_width;
6747 /* Use the standard display table for displaying strings. */
6748 if (DISP_TABLE_P (Vstandard_display_table))
6749 it->dp = XCHAR_TABLE (Vstandard_display_table);
6751 it->stop_charpos = charpos;
6752 it->prev_stop = charpos;
6753 it->base_level_stop = 0;
6754 if (it->bidi_p)
6756 it->bidi_it.first_elt = 1;
6757 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6758 it->bidi_it.disp_pos = -1;
6760 if (s == NULL && it->multibyte_p)
6762 ptrdiff_t endpos = SCHARS (it->string);
6763 if (endpos > it->end_charpos)
6764 endpos = it->end_charpos;
6765 composition_compute_stop_pos (&it->cmp_it, charpos, -1, endpos,
6766 it->string);
6768 CHECK_IT (it);
6773 /***********************************************************************
6774 Iteration
6775 ***********************************************************************/
6777 /* Map enum it_method value to corresponding next_element_from_* function. */
6779 static int (* get_next_element[NUM_IT_METHODS]) (struct it *it) =
6781 next_element_from_buffer,
6782 next_element_from_display_vector,
6783 next_element_from_string,
6784 next_element_from_c_string,
6785 next_element_from_image,
6786 next_element_from_stretch
6789 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
6792 /* Return 1 iff a character at CHARPOS (and BYTEPOS) is composed
6793 (possibly with the following characters). */
6795 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS) \
6796 ((IT)->cmp_it.id >= 0 \
6797 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
6798 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
6799 END_CHARPOS, (IT)->w, \
6800 FACE_FROM_ID ((IT)->f, (IT)->face_id), \
6801 (IT)->string)))
6804 /* Lookup the char-table Vglyphless_char_display for character C (-1
6805 if we want information for no-font case), and return the display
6806 method symbol. By side-effect, update it->what and
6807 it->glyphless_method. This function is called from
6808 get_next_display_element for each character element, and from
6809 x_produce_glyphs when no suitable font was found. */
6811 Lisp_Object
6812 lookup_glyphless_char_display (int c, struct it *it)
6814 Lisp_Object glyphless_method = Qnil;
6816 if (CHAR_TABLE_P (Vglyphless_char_display)
6817 && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display)) >= 1)
6819 if (c >= 0)
6821 glyphless_method = CHAR_TABLE_REF (Vglyphless_char_display, c);
6822 if (CONSP (glyphless_method))
6823 glyphless_method = FRAME_WINDOW_P (it->f)
6824 ? XCAR (glyphless_method)
6825 : XCDR (glyphless_method);
6827 else
6828 glyphless_method = XCHAR_TABLE (Vglyphless_char_display)->extras[0];
6831 retry:
6832 if (NILP (glyphless_method))
6834 if (c >= 0)
6835 /* The default is to display the character by a proper font. */
6836 return Qnil;
6837 /* The default for the no-font case is to display an empty box. */
6838 glyphless_method = Qempty_box;
6840 if (EQ (glyphless_method, Qzero_width))
6842 if (c >= 0)
6843 return glyphless_method;
6844 /* This method can't be used for the no-font case. */
6845 glyphless_method = Qempty_box;
6847 if (EQ (glyphless_method, Qthin_space))
6848 it->glyphless_method = GLYPHLESS_DISPLAY_THIN_SPACE;
6849 else if (EQ (glyphless_method, Qempty_box))
6850 it->glyphless_method = GLYPHLESS_DISPLAY_EMPTY_BOX;
6851 else if (EQ (glyphless_method, Qhex_code))
6852 it->glyphless_method = GLYPHLESS_DISPLAY_HEX_CODE;
6853 else if (STRINGP (glyphless_method))
6854 it->glyphless_method = GLYPHLESS_DISPLAY_ACRONYM;
6855 else
6857 /* Invalid value. We use the default method. */
6858 glyphless_method = Qnil;
6859 goto retry;
6861 it->what = IT_GLYPHLESS;
6862 return glyphless_method;
6865 /* Merge escape glyph face and cache the result. */
6867 static struct frame *last_escape_glyph_frame = NULL;
6868 static int last_escape_glyph_face_id = (1 << FACE_ID_BITS);
6869 static int last_escape_glyph_merged_face_id = 0;
6871 static int
6872 merge_escape_glyph_face (struct it *it)
6874 int face_id;
6876 if (it->f == last_escape_glyph_frame
6877 && it->face_id == last_escape_glyph_face_id)
6878 face_id = last_escape_glyph_merged_face_id;
6879 else
6881 /* Merge the `escape-glyph' face into the current face. */
6882 face_id = merge_faces (it->f, Qescape_glyph, 0, it->face_id);
6883 last_escape_glyph_frame = it->f;
6884 last_escape_glyph_face_id = it->face_id;
6885 last_escape_glyph_merged_face_id = face_id;
6887 return face_id;
6890 /* Likewise for glyphless glyph face. */
6892 static struct frame *last_glyphless_glyph_frame = NULL;
6893 static int last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
6894 static int last_glyphless_glyph_merged_face_id = 0;
6897 merge_glyphless_glyph_face (struct it *it)
6899 int face_id;
6901 if (it->f == last_glyphless_glyph_frame
6902 && it->face_id == last_glyphless_glyph_face_id)
6903 face_id = last_glyphless_glyph_merged_face_id;
6904 else
6906 /* Merge the `glyphless-char' face into the current face. */
6907 face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
6908 last_glyphless_glyph_frame = it->f;
6909 last_glyphless_glyph_face_id = it->face_id;
6910 last_glyphless_glyph_merged_face_id = face_id;
6912 return face_id;
6915 /* Load IT's display element fields with information about the next
6916 display element from the current position of IT. Value is zero if
6917 end of buffer (or C string) is reached. */
6919 static int
6920 get_next_display_element (struct it *it)
6922 /* Non-zero means that we found a display element. Zero means that
6923 we hit the end of what we iterate over. Performance note: the
6924 function pointer `method' used here turns out to be faster than
6925 using a sequence of if-statements. */
6926 int success_p;
6928 get_next:
6929 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
6931 if (it->what == IT_CHARACTER)
6933 /* UAX#9, L4: "A character is depicted by a mirrored glyph if
6934 and only if (a) the resolved directionality of that character
6935 is R..." */
6936 /* FIXME: Do we need an exception for characters from display
6937 tables? */
6938 if (it->bidi_p && it->bidi_it.type == STRONG_R
6939 && !inhibit_bidi_mirroring)
6940 it->c = bidi_mirror_char (it->c);
6941 /* Map via display table or translate control characters.
6942 IT->c, IT->len etc. have been set to the next character by
6943 the function call above. If we have a display table, and it
6944 contains an entry for IT->c, translate it. Don't do this if
6945 IT->c itself comes from a display table, otherwise we could
6946 end up in an infinite recursion. (An alternative could be to
6947 count the recursion depth of this function and signal an
6948 error when a certain maximum depth is reached.) Is it worth
6949 it? */
6950 if (success_p && it->dpvec == NULL)
6952 Lisp_Object dv;
6953 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
6954 int nonascii_space_p = 0;
6955 int nonascii_hyphen_p = 0;
6956 int c = it->c; /* This is the character to display. */
6958 if (! it->multibyte_p && ! ASCII_CHAR_P (c))
6960 eassert (SINGLE_BYTE_CHAR_P (c));
6961 if (unibyte_display_via_language_environment)
6963 c = DECODE_CHAR (unibyte, c);
6964 if (c < 0)
6965 c = BYTE8_TO_CHAR (it->c);
6967 else
6968 c = BYTE8_TO_CHAR (it->c);
6971 if (it->dp
6972 && (dv = DISP_CHAR_VECTOR (it->dp, c),
6973 VECTORP (dv)))
6975 struct Lisp_Vector *v = XVECTOR (dv);
6977 /* Return the first character from the display table
6978 entry, if not empty. If empty, don't display the
6979 current character. */
6980 if (v->header.size)
6982 it->dpvec_char_len = it->len;
6983 it->dpvec = v->contents;
6984 it->dpend = v->contents + v->header.size;
6985 it->current.dpvec_index = 0;
6986 it->dpvec_face_id = -1;
6987 it->saved_face_id = it->face_id;
6988 it->method = GET_FROM_DISPLAY_VECTOR;
6989 it->ellipsis_p = 0;
6991 else
6993 set_iterator_to_next (it, 0);
6995 goto get_next;
6998 if (! NILP (lookup_glyphless_char_display (c, it)))
7000 if (it->what == IT_GLYPHLESS)
7001 goto done;
7002 /* Don't display this character. */
7003 set_iterator_to_next (it, 0);
7004 goto get_next;
7007 /* If `nobreak-char-display' is non-nil, we display
7008 non-ASCII spaces and hyphens specially. */
7009 if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
7011 if (c == 0xA0)
7012 nonascii_space_p = true;
7013 else if (c == 0xAD || c == 0x2010 || c == 0x2011)
7014 nonascii_hyphen_p = true;
7017 /* Translate control characters into `\003' or `^C' form.
7018 Control characters coming from a display table entry are
7019 currently not translated because we use IT->dpvec to hold
7020 the translation. This could easily be changed but I
7021 don't believe that it is worth doing.
7023 The characters handled by `nobreak-char-display' must be
7024 translated too.
7026 Non-printable characters and raw-byte characters are also
7027 translated to octal form. */
7028 if (((c < ' ' || c == 127) /* ASCII control chars. */
7029 ? (it->area != TEXT_AREA
7030 /* In mode line, treat \n, \t like other crl chars. */
7031 || (c != '\t'
7032 && it->glyph_row
7033 && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
7034 || (c != '\n' && c != '\t'))
7035 : (nonascii_space_p
7036 || nonascii_hyphen_p
7037 || CHAR_BYTE8_P (c)
7038 || ! CHAR_PRINTABLE_P (c))))
7040 /* C is a control character, non-ASCII space/hyphen,
7041 raw-byte, or a non-printable character which must be
7042 displayed either as '\003' or as `^C' where the '\\'
7043 and '^' can be defined in the display table. Fill
7044 IT->ctl_chars with glyphs for what we have to
7045 display. Then, set IT->dpvec to these glyphs. */
7046 Lisp_Object gc;
7047 int ctl_len;
7048 int face_id;
7049 int lface_id = 0;
7050 int escape_glyph;
7052 /* Handle control characters with ^. */
7054 if (ASCII_CHAR_P (c) && it->ctl_arrow_p)
7056 int g;
7058 g = '^'; /* default glyph for Control */
7059 /* Set IT->ctl_chars[0] to the glyph for `^'. */
7060 if (it->dp
7061 && (gc = DISP_CTRL_GLYPH (it->dp), GLYPH_CODE_P (gc)))
7063 g = GLYPH_CODE_CHAR (gc);
7064 lface_id = GLYPH_CODE_FACE (gc);
7067 face_id = (lface_id
7068 ? merge_faces (it->f, Qt, lface_id, it->face_id)
7069 : merge_escape_glyph_face (it));
7071 XSETINT (it->ctl_chars[0], g);
7072 XSETINT (it->ctl_chars[1], c ^ 0100);
7073 ctl_len = 2;
7074 goto display_control;
7077 /* Handle non-ascii space in the mode where it only gets
7078 highlighting. */
7080 if (nonascii_space_p && EQ (Vnobreak_char_display, Qt))
7082 /* Merge `nobreak-space' into the current face. */
7083 face_id = merge_faces (it->f, Qnobreak_space, 0,
7084 it->face_id);
7085 XSETINT (it->ctl_chars[0], ' ');
7086 ctl_len = 1;
7087 goto display_control;
7090 /* Handle sequences that start with the "escape glyph". */
7092 /* the default escape glyph is \. */
7093 escape_glyph = '\\';
7095 if (it->dp
7096 && (gc = DISP_ESCAPE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
7098 escape_glyph = GLYPH_CODE_CHAR (gc);
7099 lface_id = GLYPH_CODE_FACE (gc);
7102 face_id = (lface_id
7103 ? merge_faces (it->f, Qt, lface_id, it->face_id)
7104 : merge_escape_glyph_face (it));
7106 /* Draw non-ASCII hyphen with just highlighting: */
7108 if (nonascii_hyphen_p && EQ (Vnobreak_char_display, Qt))
7110 XSETINT (it->ctl_chars[0], '-');
7111 ctl_len = 1;
7112 goto display_control;
7115 /* Draw non-ASCII space/hyphen with escape glyph: */
7117 if (nonascii_space_p || nonascii_hyphen_p)
7119 XSETINT (it->ctl_chars[0], escape_glyph);
7120 XSETINT (it->ctl_chars[1], nonascii_space_p ? ' ' : '-');
7121 ctl_len = 2;
7122 goto display_control;
7126 char str[10];
7127 int len, i;
7129 if (CHAR_BYTE8_P (c))
7130 /* Display \200 instead of \17777600. */
7131 c = CHAR_TO_BYTE8 (c);
7132 len = sprintf (str, "%03o", c);
7134 XSETINT (it->ctl_chars[0], escape_glyph);
7135 for (i = 0; i < len; i++)
7136 XSETINT (it->ctl_chars[i + 1], str[i]);
7137 ctl_len = len + 1;
7140 display_control:
7141 /* Set up IT->dpvec and return first character from it. */
7142 it->dpvec_char_len = it->len;
7143 it->dpvec = it->ctl_chars;
7144 it->dpend = it->dpvec + ctl_len;
7145 it->current.dpvec_index = 0;
7146 it->dpvec_face_id = face_id;
7147 it->saved_face_id = it->face_id;
7148 it->method = GET_FROM_DISPLAY_VECTOR;
7149 it->ellipsis_p = 0;
7150 goto get_next;
7152 it->char_to_display = c;
7154 else if (success_p)
7156 it->char_to_display = it->c;
7160 #ifdef HAVE_WINDOW_SYSTEM
7161 /* Adjust face id for a multibyte character. There are no multibyte
7162 character in unibyte text. */
7163 if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
7164 && it->multibyte_p
7165 && success_p
7166 && FRAME_WINDOW_P (it->f))
7168 struct face *face = FACE_FROM_ID (it->f, it->face_id);
7170 if (it->what == IT_COMPOSITION && it->cmp_it.ch >= 0)
7172 /* Automatic composition with glyph-string. */
7173 Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id);
7175 it->face_id = face_for_font (it->f, LGSTRING_FONT (gstring), face);
7177 else
7179 ptrdiff_t pos = (it->s ? -1
7180 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
7181 : IT_CHARPOS (*it));
7182 int c;
7184 if (it->what == IT_CHARACTER)
7185 c = it->char_to_display;
7186 else
7188 struct composition *cmp = composition_table[it->cmp_it.id];
7189 int i;
7191 c = ' ';
7192 for (i = 0; i < cmp->glyph_len; i++)
7193 /* TAB in a composition means display glyphs with
7194 padding space on the left or right. */
7195 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
7196 break;
7198 it->face_id = FACE_FOR_CHAR (it->f, face, c, pos, it->string);
7201 #endif /* HAVE_WINDOW_SYSTEM */
7203 done:
7204 /* Is this character the last one of a run of characters with
7205 box? If yes, set IT->end_of_box_run_p to 1. */
7206 if (it->face_box_p
7207 && it->s == NULL)
7209 if (it->method == GET_FROM_STRING && it->sp)
7211 int face_id = underlying_face_id (it);
7212 struct face *face = FACE_FROM_ID (it->f, face_id);
7214 if (face)
7216 if (face->box == FACE_NO_BOX)
7218 /* If the box comes from face properties in a
7219 display string, check faces in that string. */
7220 int string_face_id = face_after_it_pos (it);
7221 it->end_of_box_run_p
7222 = (FACE_FROM_ID (it->f, string_face_id)->box
7223 == FACE_NO_BOX);
7225 /* Otherwise, the box comes from the underlying face.
7226 If this is the last string character displayed, check
7227 the next buffer location. */
7228 else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1)
7229 /* n_overlay_strings is unreliable unless
7230 overlay_string_index is non-negative. */
7231 && ((it->current.overlay_string_index >= 0
7232 && (it->current.overlay_string_index
7233 == it->n_overlay_strings - 1))
7234 /* A string from display property. */
7235 || it->from_disp_prop_p))
7237 ptrdiff_t ignore;
7238 int next_face_id;
7239 struct text_pos pos = it->current.pos;
7241 /* For a string from a display property, the next
7242 buffer position is stored in the 'position'
7243 member of the iteration stack slot below the
7244 current one, see handle_single_display_spec. By
7245 contrast, it->current.pos was is not yet updated
7246 to point to that buffer position; that will
7247 happen in pop_it, after we finish displaying the
7248 current string. Note that we already checked
7249 above that it->sp is positive, so subtracting one
7250 from it is safe. */
7251 if (it->from_disp_prop_p)
7252 pos = (it->stack + it->sp - 1)->position;
7253 else
7254 INC_TEXT_POS (pos, it->multibyte_p);
7256 if (CHARPOS (pos) >= ZV)
7257 it->end_of_box_run_p = true;
7258 else
7260 next_face_id = face_at_buffer_position
7261 (it->w, CHARPOS (pos), &ignore,
7262 CHARPOS (pos) + TEXT_PROP_DISTANCE_LIMIT, 0, -1);
7263 it->end_of_box_run_p
7264 = (FACE_FROM_ID (it->f, next_face_id)->box
7265 == FACE_NO_BOX);
7270 /* next_element_from_display_vector sets this flag according to
7271 faces of the display vector glyphs, see there. */
7272 else if (it->method != GET_FROM_DISPLAY_VECTOR)
7274 int face_id = face_after_it_pos (it);
7275 it->end_of_box_run_p
7276 = (face_id != it->face_id
7277 && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX);
7280 /* If we reached the end of the object we've been iterating (e.g., a
7281 display string or an overlay string), and there's something on
7282 IT->stack, proceed with what's on the stack. It doesn't make
7283 sense to return zero if there's unprocessed stuff on the stack,
7284 because otherwise that stuff will never be displayed. */
7285 if (!success_p && it->sp > 0)
7287 set_iterator_to_next (it, 0);
7288 success_p = get_next_display_element (it);
7291 /* Value is 0 if end of buffer or string reached. */
7292 return success_p;
7296 /* Move IT to the next display element.
7298 RESEAT_P non-zero means if called on a newline in buffer text,
7299 skip to the next visible line start.
7301 Functions get_next_display_element and set_iterator_to_next are
7302 separate because I find this arrangement easier to handle than a
7303 get_next_display_element function that also increments IT's
7304 position. The way it is we can first look at an iterator's current
7305 display element, decide whether it fits on a line, and if it does,
7306 increment the iterator position. The other way around we probably
7307 would either need a flag indicating whether the iterator has to be
7308 incremented the next time, or we would have to implement a
7309 decrement position function which would not be easy to write. */
7311 void
7312 set_iterator_to_next (struct it *it, int reseat_p)
7314 /* Reset flags indicating start and end of a sequence of characters
7315 with box. Reset them at the start of this function because
7316 moving the iterator to a new position might set them. */
7317 it->start_of_box_run_p = it->end_of_box_run_p = 0;
7319 switch (it->method)
7321 case GET_FROM_BUFFER:
7322 /* The current display element of IT is a character from
7323 current_buffer. Advance in the buffer, and maybe skip over
7324 invisible lines that are so because of selective display. */
7325 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
7326 reseat_at_next_visible_line_start (it, 0);
7327 else if (it->cmp_it.id >= 0)
7329 /* We are currently getting glyphs from a composition. */
7330 int i;
7332 if (! it->bidi_p)
7334 IT_CHARPOS (*it) += it->cmp_it.nchars;
7335 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
7336 if (it->cmp_it.to < it->cmp_it.nglyphs)
7338 it->cmp_it.from = it->cmp_it.to;
7340 else
7342 it->cmp_it.id = -1;
7343 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7344 IT_BYTEPOS (*it),
7345 it->end_charpos, Qnil);
7348 else if (! it->cmp_it.reversed_p)
7350 /* Composition created while scanning forward. */
7351 /* Update IT's char/byte positions to point to the first
7352 character of the next grapheme cluster, or to the
7353 character visually after the current composition. */
7354 for (i = 0; i < it->cmp_it.nchars; i++)
7355 bidi_move_to_visually_next (&it->bidi_it);
7356 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7357 IT_CHARPOS (*it) = it->bidi_it.charpos;
7359 if (it->cmp_it.to < it->cmp_it.nglyphs)
7361 /* Proceed to the next grapheme cluster. */
7362 it->cmp_it.from = it->cmp_it.to;
7364 else
7366 /* No more grapheme clusters in this composition.
7367 Find the next stop position. */
7368 ptrdiff_t stop = it->end_charpos;
7369 if (it->bidi_it.scan_dir < 0)
7370 /* Now we are scanning backward and don't know
7371 where to stop. */
7372 stop = -1;
7373 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7374 IT_BYTEPOS (*it), stop, Qnil);
7377 else
7379 /* Composition created while scanning backward. */
7380 /* Update IT's char/byte positions to point to the last
7381 character of the previous grapheme cluster, or the
7382 character visually after the current composition. */
7383 for (i = 0; i < it->cmp_it.nchars; i++)
7384 bidi_move_to_visually_next (&it->bidi_it);
7385 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7386 IT_CHARPOS (*it) = it->bidi_it.charpos;
7387 if (it->cmp_it.from > 0)
7389 /* Proceed to the previous grapheme cluster. */
7390 it->cmp_it.to = it->cmp_it.from;
7392 else
7394 /* No more grapheme clusters in this composition.
7395 Find the next stop position. */
7396 ptrdiff_t stop = it->end_charpos;
7397 if (it->bidi_it.scan_dir < 0)
7398 /* Now we are scanning backward and don't know
7399 where to stop. */
7400 stop = -1;
7401 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7402 IT_BYTEPOS (*it), stop, Qnil);
7406 else
7408 eassert (it->len != 0);
7410 if (!it->bidi_p)
7412 IT_BYTEPOS (*it) += it->len;
7413 IT_CHARPOS (*it) += 1;
7415 else
7417 int prev_scan_dir = it->bidi_it.scan_dir;
7418 /* If this is a new paragraph, determine its base
7419 direction (a.k.a. its base embedding level). */
7420 if (it->bidi_it.new_paragraph)
7421 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
7422 bidi_move_to_visually_next (&it->bidi_it);
7423 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7424 IT_CHARPOS (*it) = it->bidi_it.charpos;
7425 if (prev_scan_dir != it->bidi_it.scan_dir)
7427 /* As the scan direction was changed, we must
7428 re-compute the stop position for composition. */
7429 ptrdiff_t stop = it->end_charpos;
7430 if (it->bidi_it.scan_dir < 0)
7431 stop = -1;
7432 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7433 IT_BYTEPOS (*it), stop, Qnil);
7436 eassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
7438 break;
7440 case GET_FROM_C_STRING:
7441 /* Current display element of IT is from a C string. */
7442 if (!it->bidi_p
7443 /* If the string position is beyond string's end, it means
7444 next_element_from_c_string is padding the string with
7445 blanks, in which case we bypass the bidi iterator,
7446 because it cannot deal with such virtual characters. */
7447 || IT_CHARPOS (*it) >= it->bidi_it.string.schars)
7449 IT_BYTEPOS (*it) += it->len;
7450 IT_CHARPOS (*it) += 1;
7452 else
7454 bidi_move_to_visually_next (&it->bidi_it);
7455 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7456 IT_CHARPOS (*it) = it->bidi_it.charpos;
7458 break;
7460 case GET_FROM_DISPLAY_VECTOR:
7461 /* Current display element of IT is from a display table entry.
7462 Advance in the display table definition. Reset it to null if
7463 end reached, and continue with characters from buffers/
7464 strings. */
7465 ++it->current.dpvec_index;
7467 /* Restore face of the iterator to what they were before the
7468 display vector entry (these entries may contain faces). */
7469 it->face_id = it->saved_face_id;
7471 if (it->dpvec + it->current.dpvec_index >= it->dpend)
7473 int recheck_faces = it->ellipsis_p;
7475 if (it->s)
7476 it->method = GET_FROM_C_STRING;
7477 else if (STRINGP (it->string))
7478 it->method = GET_FROM_STRING;
7479 else
7481 it->method = GET_FROM_BUFFER;
7482 it->object = it->w->contents;
7485 it->dpvec = NULL;
7486 it->current.dpvec_index = -1;
7488 /* Skip over characters which were displayed via IT->dpvec. */
7489 if (it->dpvec_char_len < 0)
7490 reseat_at_next_visible_line_start (it, 1);
7491 else if (it->dpvec_char_len > 0)
7493 if (it->method == GET_FROM_STRING
7494 && it->current.overlay_string_index >= 0
7495 && it->n_overlay_strings > 0)
7496 it->ignore_overlay_strings_at_pos_p = true;
7497 it->len = it->dpvec_char_len;
7498 set_iterator_to_next (it, reseat_p);
7501 /* Maybe recheck faces after display vector. */
7502 if (recheck_faces)
7503 it->stop_charpos = IT_CHARPOS (*it);
7505 break;
7507 case GET_FROM_STRING:
7508 /* Current display element is a character from a Lisp string. */
7509 eassert (it->s == NULL && STRINGP (it->string));
7510 /* Don't advance past string end. These conditions are true
7511 when set_iterator_to_next is called at the end of
7512 get_next_display_element, in which case the Lisp string is
7513 already exhausted, and all we want is pop the iterator
7514 stack. */
7515 if (it->current.overlay_string_index >= 0)
7517 /* This is an overlay string, so there's no padding with
7518 spaces, and the number of characters in the string is
7519 where the string ends. */
7520 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7521 goto consider_string_end;
7523 else
7525 /* Not an overlay string. There could be padding, so test
7526 against it->end_charpos. */
7527 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7528 goto consider_string_end;
7530 if (it->cmp_it.id >= 0)
7532 int i;
7534 if (! it->bidi_p)
7536 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
7537 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
7538 if (it->cmp_it.to < it->cmp_it.nglyphs)
7539 it->cmp_it.from = it->cmp_it.to;
7540 else
7542 it->cmp_it.id = -1;
7543 composition_compute_stop_pos (&it->cmp_it,
7544 IT_STRING_CHARPOS (*it),
7545 IT_STRING_BYTEPOS (*it),
7546 it->end_charpos, it->string);
7549 else if (! it->cmp_it.reversed_p)
7551 for (i = 0; i < it->cmp_it.nchars; i++)
7552 bidi_move_to_visually_next (&it->bidi_it);
7553 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7554 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7556 if (it->cmp_it.to < it->cmp_it.nglyphs)
7557 it->cmp_it.from = it->cmp_it.to;
7558 else
7560 ptrdiff_t stop = it->end_charpos;
7561 if (it->bidi_it.scan_dir < 0)
7562 stop = -1;
7563 composition_compute_stop_pos (&it->cmp_it,
7564 IT_STRING_CHARPOS (*it),
7565 IT_STRING_BYTEPOS (*it), stop,
7566 it->string);
7569 else
7571 for (i = 0; i < it->cmp_it.nchars; i++)
7572 bidi_move_to_visually_next (&it->bidi_it);
7573 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7574 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7575 if (it->cmp_it.from > 0)
7576 it->cmp_it.to = it->cmp_it.from;
7577 else
7579 ptrdiff_t stop = it->end_charpos;
7580 if (it->bidi_it.scan_dir < 0)
7581 stop = -1;
7582 composition_compute_stop_pos (&it->cmp_it,
7583 IT_STRING_CHARPOS (*it),
7584 IT_STRING_BYTEPOS (*it), stop,
7585 it->string);
7589 else
7591 if (!it->bidi_p
7592 /* If the string position is beyond string's end, it
7593 means next_element_from_string is padding the string
7594 with blanks, in which case we bypass the bidi
7595 iterator, because it cannot deal with such virtual
7596 characters. */
7597 || IT_STRING_CHARPOS (*it) >= it->bidi_it.string.schars)
7599 IT_STRING_BYTEPOS (*it) += it->len;
7600 IT_STRING_CHARPOS (*it) += 1;
7602 else
7604 int prev_scan_dir = it->bidi_it.scan_dir;
7606 bidi_move_to_visually_next (&it->bidi_it);
7607 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7608 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7609 if (prev_scan_dir != it->bidi_it.scan_dir)
7611 ptrdiff_t stop = it->end_charpos;
7613 if (it->bidi_it.scan_dir < 0)
7614 stop = -1;
7615 composition_compute_stop_pos (&it->cmp_it,
7616 IT_STRING_CHARPOS (*it),
7617 IT_STRING_BYTEPOS (*it), stop,
7618 it->string);
7623 consider_string_end:
7625 if (it->current.overlay_string_index >= 0)
7627 /* IT->string is an overlay string. Advance to the
7628 next, if there is one. */
7629 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7631 it->ellipsis_p = 0;
7632 next_overlay_string (it);
7633 if (it->ellipsis_p)
7634 setup_for_ellipsis (it, 0);
7637 else
7639 /* IT->string is not an overlay string. If we reached
7640 its end, and there is something on IT->stack, proceed
7641 with what is on the stack. This can be either another
7642 string, this time an overlay string, or a buffer. */
7643 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
7644 && it->sp > 0)
7646 pop_it (it);
7647 if (it->method == GET_FROM_STRING)
7648 goto consider_string_end;
7651 break;
7653 case GET_FROM_IMAGE:
7654 case GET_FROM_STRETCH:
7655 /* The position etc with which we have to proceed are on
7656 the stack. The position may be at the end of a string,
7657 if the `display' property takes up the whole string. */
7658 eassert (it->sp > 0);
7659 pop_it (it);
7660 if (it->method == GET_FROM_STRING)
7661 goto consider_string_end;
7662 break;
7664 default:
7665 /* There are no other methods defined, so this should be a bug. */
7666 emacs_abort ();
7669 eassert (it->method != GET_FROM_STRING
7670 || (STRINGP (it->string)
7671 && IT_STRING_CHARPOS (*it) >= 0));
7674 /* Load IT's display element fields with information about the next
7675 display element which comes from a display table entry or from the
7676 result of translating a control character to one of the forms `^C'
7677 or `\003'.
7679 IT->dpvec holds the glyphs to return as characters.
7680 IT->saved_face_id holds the face id before the display vector--it
7681 is restored into IT->face_id in set_iterator_to_next. */
7683 static int
7684 next_element_from_display_vector (struct it *it)
7686 Lisp_Object gc;
7687 int prev_face_id = it->face_id;
7688 int next_face_id;
7690 /* Precondition. */
7691 eassert (it->dpvec && it->current.dpvec_index >= 0);
7693 it->face_id = it->saved_face_id;
7695 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
7696 That seemed totally bogus - so I changed it... */
7697 gc = it->dpvec[it->current.dpvec_index];
7699 if (GLYPH_CODE_P (gc))
7701 struct face *this_face, *prev_face, *next_face;
7703 it->c = GLYPH_CODE_CHAR (gc);
7704 it->len = CHAR_BYTES (it->c);
7706 /* The entry may contain a face id to use. Such a face id is
7707 the id of a Lisp face, not a realized face. A face id of
7708 zero means no face is specified. */
7709 if (it->dpvec_face_id >= 0)
7710 it->face_id = it->dpvec_face_id;
7711 else
7713 int lface_id = GLYPH_CODE_FACE (gc);
7714 if (lface_id > 0)
7715 it->face_id = merge_faces (it->f, Qt, lface_id,
7716 it->saved_face_id);
7719 /* Glyphs in the display vector could have the box face, so we
7720 need to set the related flags in the iterator, as
7721 appropriate. */
7722 this_face = FACE_FROM_ID (it->f, it->face_id);
7723 prev_face = FACE_FROM_ID (it->f, prev_face_id);
7725 /* Is this character the first character of a box-face run? */
7726 it->start_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX
7727 && (!prev_face
7728 || prev_face->box == FACE_NO_BOX));
7730 /* For the last character of the box-face run, we need to look
7731 either at the next glyph from the display vector, or at the
7732 face we saw before the display vector. */
7733 next_face_id = it->saved_face_id;
7734 if (it->current.dpvec_index < it->dpend - it->dpvec - 1)
7736 if (it->dpvec_face_id >= 0)
7737 next_face_id = it->dpvec_face_id;
7738 else
7740 int lface_id =
7741 GLYPH_CODE_FACE (it->dpvec[it->current.dpvec_index + 1]);
7743 if (lface_id > 0)
7744 next_face_id = merge_faces (it->f, Qt, lface_id,
7745 it->saved_face_id);
7748 next_face = FACE_FROM_ID (it->f, next_face_id);
7749 it->end_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX
7750 && (!next_face
7751 || next_face->box == FACE_NO_BOX));
7752 it->face_box_p = this_face && this_face->box != FACE_NO_BOX;
7754 else
7755 /* Display table entry is invalid. Return a space. */
7756 it->c = ' ', it->len = 1;
7758 /* Don't change position and object of the iterator here. They are
7759 still the values of the character that had this display table
7760 entry or was translated, and that's what we want. */
7761 it->what = IT_CHARACTER;
7762 return 1;
7765 /* Get the first element of string/buffer in the visual order, after
7766 being reseated to a new position in a string or a buffer. */
7767 static void
7768 get_visually_first_element (struct it *it)
7770 int string_p = STRINGP (it->string) || it->s;
7771 ptrdiff_t eob = (string_p ? it->bidi_it.string.schars : ZV);
7772 ptrdiff_t bob = (string_p ? 0 : BEGV);
7774 if (STRINGP (it->string))
7776 it->bidi_it.charpos = IT_STRING_CHARPOS (*it);
7777 it->bidi_it.bytepos = IT_STRING_BYTEPOS (*it);
7779 else
7781 it->bidi_it.charpos = IT_CHARPOS (*it);
7782 it->bidi_it.bytepos = IT_BYTEPOS (*it);
7785 if (it->bidi_it.charpos == eob)
7787 /* Nothing to do, but reset the FIRST_ELT flag, like
7788 bidi_paragraph_init does, because we are not going to
7789 call it. */
7790 it->bidi_it.first_elt = 0;
7792 else if (it->bidi_it.charpos == bob
7793 || (!string_p
7794 && (FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n'
7795 || FETCH_CHAR (it->bidi_it.bytepos) == '\n')))
7797 /* If we are at the beginning of a line/string, we can produce
7798 the next element right away. */
7799 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
7800 bidi_move_to_visually_next (&it->bidi_it);
7802 else
7804 ptrdiff_t orig_bytepos = it->bidi_it.bytepos;
7806 /* We need to prime the bidi iterator starting at the line's or
7807 string's beginning, before we will be able to produce the
7808 next element. */
7809 if (string_p)
7810 it->bidi_it.charpos = it->bidi_it.bytepos = 0;
7811 else
7812 it->bidi_it.charpos = find_newline_no_quit (IT_CHARPOS (*it),
7813 IT_BYTEPOS (*it), -1,
7814 &it->bidi_it.bytepos);
7815 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
7818 /* Now return to buffer/string position where we were asked
7819 to get the next display element, and produce that. */
7820 bidi_move_to_visually_next (&it->bidi_it);
7822 while (it->bidi_it.bytepos != orig_bytepos
7823 && it->bidi_it.charpos < eob);
7826 /* Adjust IT's position information to where we ended up. */
7827 if (STRINGP (it->string))
7829 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7830 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7832 else
7834 IT_CHARPOS (*it) = it->bidi_it.charpos;
7835 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7838 if (STRINGP (it->string) || !it->s)
7840 ptrdiff_t stop, charpos, bytepos;
7842 if (STRINGP (it->string))
7844 eassert (!it->s);
7845 stop = SCHARS (it->string);
7846 if (stop > it->end_charpos)
7847 stop = it->end_charpos;
7848 charpos = IT_STRING_CHARPOS (*it);
7849 bytepos = IT_STRING_BYTEPOS (*it);
7851 else
7853 stop = it->end_charpos;
7854 charpos = IT_CHARPOS (*it);
7855 bytepos = IT_BYTEPOS (*it);
7857 if (it->bidi_it.scan_dir < 0)
7858 stop = -1;
7859 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos, stop,
7860 it->string);
7864 /* Load IT with the next display element from Lisp string IT->string.
7865 IT->current.string_pos is the current position within the string.
7866 If IT->current.overlay_string_index >= 0, the Lisp string is an
7867 overlay string. */
7869 static int
7870 next_element_from_string (struct it *it)
7872 struct text_pos position;
7874 eassert (STRINGP (it->string));
7875 eassert (!it->bidi_p || EQ (it->string, it->bidi_it.string.lstring));
7876 eassert (IT_STRING_CHARPOS (*it) >= 0);
7877 position = it->current.string_pos;
7879 /* With bidi reordering, the character to display might not be the
7880 character at IT_STRING_CHARPOS. BIDI_IT.FIRST_ELT non-zero means
7881 that we were reseat()ed to a new string, whose paragraph
7882 direction is not known. */
7883 if (it->bidi_p && it->bidi_it.first_elt)
7885 get_visually_first_element (it);
7886 SET_TEXT_POS (position, IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it));
7889 /* Time to check for invisible text? */
7890 if (IT_STRING_CHARPOS (*it) < it->end_charpos)
7892 if (IT_STRING_CHARPOS (*it) >= it->stop_charpos)
7894 if (!(!it->bidi_p
7895 || BIDI_AT_BASE_LEVEL (it->bidi_it)
7896 || IT_STRING_CHARPOS (*it) == it->stop_charpos))
7898 /* With bidi non-linear iteration, we could find
7899 ourselves far beyond the last computed stop_charpos,
7900 with several other stop positions in between that we
7901 missed. Scan them all now, in buffer's logical
7902 order, until we find and handle the last stop_charpos
7903 that precedes our current position. */
7904 handle_stop_backwards (it, it->stop_charpos);
7905 return GET_NEXT_DISPLAY_ELEMENT (it);
7907 else
7909 if (it->bidi_p)
7911 /* Take note of the stop position we just moved
7912 across, for when we will move back across it. */
7913 it->prev_stop = it->stop_charpos;
7914 /* If we are at base paragraph embedding level, take
7915 note of the last stop position seen at this
7916 level. */
7917 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
7918 it->base_level_stop = it->stop_charpos;
7920 handle_stop (it);
7922 /* Since a handler may have changed IT->method, we must
7923 recurse here. */
7924 return GET_NEXT_DISPLAY_ELEMENT (it);
7927 else if (it->bidi_p
7928 /* If we are before prev_stop, we may have overstepped
7929 on our way backwards a stop_pos, and if so, we need
7930 to handle that stop_pos. */
7931 && IT_STRING_CHARPOS (*it) < it->prev_stop
7932 /* We can sometimes back up for reasons that have nothing
7933 to do with bidi reordering. E.g., compositions. The
7934 code below is only needed when we are above the base
7935 embedding level, so test for that explicitly. */
7936 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
7938 /* If we lost track of base_level_stop, we have no better
7939 place for handle_stop_backwards to start from than string
7940 beginning. This happens, e.g., when we were reseated to
7941 the previous screenful of text by vertical-motion. */
7942 if (it->base_level_stop <= 0
7943 || IT_STRING_CHARPOS (*it) < it->base_level_stop)
7944 it->base_level_stop = 0;
7945 handle_stop_backwards (it, it->base_level_stop);
7946 return GET_NEXT_DISPLAY_ELEMENT (it);
7950 if (it->current.overlay_string_index >= 0)
7952 /* Get the next character from an overlay string. In overlay
7953 strings, there is no field width or padding with spaces to
7954 do. */
7955 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7957 it->what = IT_EOB;
7958 return 0;
7960 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
7961 IT_STRING_BYTEPOS (*it),
7962 it->bidi_it.scan_dir < 0
7963 ? -1
7964 : SCHARS (it->string))
7965 && next_element_from_composition (it))
7967 return 1;
7969 else if (STRING_MULTIBYTE (it->string))
7971 const unsigned char *s = (SDATA (it->string)
7972 + IT_STRING_BYTEPOS (*it));
7973 it->c = string_char_and_length (s, &it->len);
7975 else
7977 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
7978 it->len = 1;
7981 else
7983 /* Get the next character from a Lisp string that is not an
7984 overlay string. Such strings come from the mode line, for
7985 example. We may have to pad with spaces, or truncate the
7986 string. See also next_element_from_c_string. */
7987 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7989 it->what = IT_EOB;
7990 return 0;
7992 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
7994 /* Pad with spaces. */
7995 it->c = ' ', it->len = 1;
7996 CHARPOS (position) = BYTEPOS (position) = -1;
7998 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
7999 IT_STRING_BYTEPOS (*it),
8000 it->bidi_it.scan_dir < 0
8001 ? -1
8002 : it->string_nchars)
8003 && next_element_from_composition (it))
8005 return 1;
8007 else if (STRING_MULTIBYTE (it->string))
8009 const unsigned char *s = (SDATA (it->string)
8010 + IT_STRING_BYTEPOS (*it));
8011 it->c = string_char_and_length (s, &it->len);
8013 else
8015 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
8016 it->len = 1;
8020 /* Record what we have and where it came from. */
8021 it->what = IT_CHARACTER;
8022 it->object = it->string;
8023 it->position = position;
8024 return 1;
8028 /* Load IT with next display element from C string IT->s.
8029 IT->string_nchars is the maximum number of characters to return
8030 from the string. IT->end_charpos may be greater than
8031 IT->string_nchars when this function is called, in which case we
8032 may have to return padding spaces. Value is zero if end of string
8033 reached, including padding spaces. */
8035 static int
8036 next_element_from_c_string (struct it *it)
8038 bool success_p = true;
8040 eassert (it->s);
8041 eassert (!it->bidi_p || it->s == it->bidi_it.string.s);
8042 it->what = IT_CHARACTER;
8043 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
8044 it->object = Qnil;
8046 /* With bidi reordering, the character to display might not be the
8047 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
8048 we were reseated to a new string, whose paragraph direction is
8049 not known. */
8050 if (it->bidi_p && it->bidi_it.first_elt)
8051 get_visually_first_element (it);
8053 /* IT's position can be greater than IT->string_nchars in case a
8054 field width or precision has been specified when the iterator was
8055 initialized. */
8056 if (IT_CHARPOS (*it) >= it->end_charpos)
8058 /* End of the game. */
8059 it->what = IT_EOB;
8060 success_p = 0;
8062 else if (IT_CHARPOS (*it) >= it->string_nchars)
8064 /* Pad with spaces. */
8065 it->c = ' ', it->len = 1;
8066 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
8068 else if (it->multibyte_p)
8069 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), &it->len);
8070 else
8071 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
8073 return success_p;
8077 /* Set up IT to return characters from an ellipsis, if appropriate.
8078 The definition of the ellipsis glyphs may come from a display table
8079 entry. This function fills IT with the first glyph from the
8080 ellipsis if an ellipsis is to be displayed. */
8082 static int
8083 next_element_from_ellipsis (struct it *it)
8085 if (it->selective_display_ellipsis_p)
8086 setup_for_ellipsis (it, it->len);
8087 else
8089 /* The face at the current position may be different from the
8090 face we find after the invisible text. Remember what it
8091 was in IT->saved_face_id, and signal that it's there by
8092 setting face_before_selective_p. */
8093 it->saved_face_id = it->face_id;
8094 it->method = GET_FROM_BUFFER;
8095 it->object = it->w->contents;
8096 reseat_at_next_visible_line_start (it, 1);
8097 it->face_before_selective_p = true;
8100 return GET_NEXT_DISPLAY_ELEMENT (it);
8104 /* Deliver an image display element. The iterator IT is already
8105 filled with image information (done in handle_display_prop). Value
8106 is always 1. */
8109 static int
8110 next_element_from_image (struct it *it)
8112 it->what = IT_IMAGE;
8113 it->ignore_overlay_strings_at_pos_p = 0;
8114 return 1;
8118 /* Fill iterator IT with next display element from a stretch glyph
8119 property. IT->object is the value of the text property. Value is
8120 always 1. */
8122 static int
8123 next_element_from_stretch (struct it *it)
8125 it->what = IT_STRETCH;
8126 return 1;
8129 /* Scan backwards from IT's current position until we find a stop
8130 position, or until BEGV. This is called when we find ourself
8131 before both the last known prev_stop and base_level_stop while
8132 reordering bidirectional text. */
8134 static void
8135 compute_stop_pos_backwards (struct it *it)
8137 const int SCAN_BACK_LIMIT = 1000;
8138 struct text_pos pos;
8139 struct display_pos save_current = it->current;
8140 struct text_pos save_position = it->position;
8141 ptrdiff_t charpos = IT_CHARPOS (*it);
8142 ptrdiff_t where_we_are = charpos;
8143 ptrdiff_t save_stop_pos = it->stop_charpos;
8144 ptrdiff_t save_end_pos = it->end_charpos;
8146 eassert (NILP (it->string) && !it->s);
8147 eassert (it->bidi_p);
8148 it->bidi_p = 0;
8151 it->end_charpos = min (charpos + 1, ZV);
8152 charpos = max (charpos - SCAN_BACK_LIMIT, BEGV);
8153 SET_TEXT_POS (pos, charpos, CHAR_TO_BYTE (charpos));
8154 reseat_1 (it, pos, 0);
8155 compute_stop_pos (it);
8156 /* We must advance forward, right? */
8157 if (it->stop_charpos <= charpos)
8158 emacs_abort ();
8160 while (charpos > BEGV && it->stop_charpos >= it->end_charpos);
8162 if (it->stop_charpos <= where_we_are)
8163 it->prev_stop = it->stop_charpos;
8164 else
8165 it->prev_stop = BEGV;
8166 it->bidi_p = true;
8167 it->current = save_current;
8168 it->position = save_position;
8169 it->stop_charpos = save_stop_pos;
8170 it->end_charpos = save_end_pos;
8173 /* Scan forward from CHARPOS in the current buffer/string, until we
8174 find a stop position > current IT's position. Then handle the stop
8175 position before that. This is called when we bump into a stop
8176 position while reordering bidirectional text. CHARPOS should be
8177 the last previously processed stop_pos (or BEGV/0, if none were
8178 processed yet) whose position is less that IT's current
8179 position. */
8181 static void
8182 handle_stop_backwards (struct it *it, ptrdiff_t charpos)
8184 int bufp = !STRINGP (it->string);
8185 ptrdiff_t where_we_are = (bufp ? IT_CHARPOS (*it) : IT_STRING_CHARPOS (*it));
8186 struct display_pos save_current = it->current;
8187 struct text_pos save_position = it->position;
8188 struct text_pos pos1;
8189 ptrdiff_t next_stop;
8191 /* Scan in strict logical order. */
8192 eassert (it->bidi_p);
8193 it->bidi_p = 0;
8196 it->prev_stop = charpos;
8197 if (bufp)
8199 SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos));
8200 reseat_1 (it, pos1, 0);
8202 else
8203 it->current.string_pos = string_pos (charpos, it->string);
8204 compute_stop_pos (it);
8205 /* We must advance forward, right? */
8206 if (it->stop_charpos <= it->prev_stop)
8207 emacs_abort ();
8208 charpos = it->stop_charpos;
8210 while (charpos <= where_we_are);
8212 it->bidi_p = true;
8213 it->current = save_current;
8214 it->position = save_position;
8215 next_stop = it->stop_charpos;
8216 it->stop_charpos = it->prev_stop;
8217 handle_stop (it);
8218 it->stop_charpos = next_stop;
8221 /* Load IT with the next display element from current_buffer. Value
8222 is zero if end of buffer reached. IT->stop_charpos is the next
8223 position at which to stop and check for text properties or buffer
8224 end. */
8226 static int
8227 next_element_from_buffer (struct it *it)
8229 bool success_p = true;
8231 eassert (IT_CHARPOS (*it) >= BEGV);
8232 eassert (NILP (it->string) && !it->s);
8233 eassert (!it->bidi_p
8234 || (EQ (it->bidi_it.string.lstring, Qnil)
8235 && it->bidi_it.string.s == NULL));
8237 /* With bidi reordering, the character to display might not be the
8238 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
8239 we were reseat()ed to a new buffer position, which is potentially
8240 a different paragraph. */
8241 if (it->bidi_p && it->bidi_it.first_elt)
8243 get_visually_first_element (it);
8244 SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8247 if (IT_CHARPOS (*it) >= it->stop_charpos)
8249 if (IT_CHARPOS (*it) >= it->end_charpos)
8251 int overlay_strings_follow_p;
8253 /* End of the game, except when overlay strings follow that
8254 haven't been returned yet. */
8255 if (it->overlay_strings_at_end_processed_p)
8256 overlay_strings_follow_p = 0;
8257 else
8259 it->overlay_strings_at_end_processed_p = true;
8260 overlay_strings_follow_p = get_overlay_strings (it, 0);
8263 if (overlay_strings_follow_p)
8264 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
8265 else
8267 it->what = IT_EOB;
8268 it->position = it->current.pos;
8269 success_p = 0;
8272 else if (!(!it->bidi_p
8273 || BIDI_AT_BASE_LEVEL (it->bidi_it)
8274 || IT_CHARPOS (*it) == it->stop_charpos))
8276 /* With bidi non-linear iteration, we could find ourselves
8277 far beyond the last computed stop_charpos, with several
8278 other stop positions in between that we missed. Scan
8279 them all now, in buffer's logical order, until we find
8280 and handle the last stop_charpos that precedes our
8281 current position. */
8282 handle_stop_backwards (it, it->stop_charpos);
8283 return GET_NEXT_DISPLAY_ELEMENT (it);
8285 else
8287 if (it->bidi_p)
8289 /* Take note of the stop position we just moved across,
8290 for when we will move back across it. */
8291 it->prev_stop = it->stop_charpos;
8292 /* If we are at base paragraph embedding level, take
8293 note of the last stop position seen at this
8294 level. */
8295 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
8296 it->base_level_stop = it->stop_charpos;
8298 handle_stop (it);
8299 return GET_NEXT_DISPLAY_ELEMENT (it);
8302 else if (it->bidi_p
8303 /* If we are before prev_stop, we may have overstepped on
8304 our way backwards a stop_pos, and if so, we need to
8305 handle that stop_pos. */
8306 && IT_CHARPOS (*it) < it->prev_stop
8307 /* We can sometimes back up for reasons that have nothing
8308 to do with bidi reordering. E.g., compositions. The
8309 code below is only needed when we are above the base
8310 embedding level, so test for that explicitly. */
8311 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
8313 if (it->base_level_stop <= 0
8314 || IT_CHARPOS (*it) < it->base_level_stop)
8316 /* If we lost track of base_level_stop, we need to find
8317 prev_stop by looking backwards. This happens, e.g., when
8318 we were reseated to the previous screenful of text by
8319 vertical-motion. */
8320 it->base_level_stop = BEGV;
8321 compute_stop_pos_backwards (it);
8322 handle_stop_backwards (it, it->prev_stop);
8324 else
8325 handle_stop_backwards (it, it->base_level_stop);
8326 return GET_NEXT_DISPLAY_ELEMENT (it);
8328 else
8330 /* No face changes, overlays etc. in sight, so just return a
8331 character from current_buffer. */
8332 unsigned char *p;
8333 ptrdiff_t stop;
8335 /* Maybe run the redisplay end trigger hook. Performance note:
8336 This doesn't seem to cost measurable time. */
8337 if (it->redisplay_end_trigger_charpos
8338 && it->glyph_row
8339 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
8340 run_redisplay_end_trigger_hook (it);
8342 stop = it->bidi_it.scan_dir < 0 ? -1 : it->end_charpos;
8343 if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it),
8344 stop)
8345 && next_element_from_composition (it))
8347 return 1;
8350 /* Get the next character, maybe multibyte. */
8351 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
8352 if (it->multibyte_p && !ASCII_CHAR_P (*p))
8353 it->c = STRING_CHAR_AND_LENGTH (p, it->len);
8354 else
8355 it->c = *p, it->len = 1;
8357 /* Record what we have and where it came from. */
8358 it->what = IT_CHARACTER;
8359 it->object = it->w->contents;
8360 it->position = it->current.pos;
8362 /* Normally we return the character found above, except when we
8363 really want to return an ellipsis for selective display. */
8364 if (it->selective)
8366 if (it->c == '\n')
8368 /* A value of selective > 0 means hide lines indented more
8369 than that number of columns. */
8370 if (it->selective > 0
8371 && IT_CHARPOS (*it) + 1 < ZV
8372 && indented_beyond_p (IT_CHARPOS (*it) + 1,
8373 IT_BYTEPOS (*it) + 1,
8374 it->selective))
8376 success_p = next_element_from_ellipsis (it);
8377 it->dpvec_char_len = -1;
8380 else if (it->c == '\r' && it->selective == -1)
8382 /* A value of selective == -1 means that everything from the
8383 CR to the end of the line is invisible, with maybe an
8384 ellipsis displayed for it. */
8385 success_p = next_element_from_ellipsis (it);
8386 it->dpvec_char_len = -1;
8391 /* Value is zero if end of buffer reached. */
8392 eassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
8393 return success_p;
8397 /* Run the redisplay end trigger hook for IT. */
8399 static void
8400 run_redisplay_end_trigger_hook (struct it *it)
8402 Lisp_Object args[3];
8404 /* IT->glyph_row should be non-null, i.e. we should be actually
8405 displaying something, or otherwise we should not run the hook. */
8406 eassert (it->glyph_row);
8408 /* Set up hook arguments. */
8409 args[0] = Qredisplay_end_trigger_functions;
8410 args[1] = it->window;
8411 XSETINT (args[2], it->redisplay_end_trigger_charpos);
8412 it->redisplay_end_trigger_charpos = 0;
8414 /* Since we are *trying* to run these functions, don't try to run
8415 them again, even if they get an error. */
8416 wset_redisplay_end_trigger (it->w, Qnil);
8417 Frun_hook_with_args (3, args);
8419 /* Notice if it changed the face of the character we are on. */
8420 handle_face_prop (it);
8424 /* Deliver a composition display element. Unlike the other
8425 next_element_from_XXX, this function is not registered in the array
8426 get_next_element[]. It is called from next_element_from_buffer and
8427 next_element_from_string when necessary. */
8429 static int
8430 next_element_from_composition (struct it *it)
8432 it->what = IT_COMPOSITION;
8433 it->len = it->cmp_it.nbytes;
8434 if (STRINGP (it->string))
8436 if (it->c < 0)
8438 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
8439 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
8440 return 0;
8442 it->position = it->current.string_pos;
8443 it->object = it->string;
8444 it->c = composition_update_it (&it->cmp_it, IT_STRING_CHARPOS (*it),
8445 IT_STRING_BYTEPOS (*it), it->string);
8447 else
8449 if (it->c < 0)
8451 IT_CHARPOS (*it) += it->cmp_it.nchars;
8452 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
8453 if (it->bidi_p)
8455 if (it->bidi_it.new_paragraph)
8456 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
8457 /* Resync the bidi iterator with IT's new position.
8458 FIXME: this doesn't support bidirectional text. */
8459 while (it->bidi_it.charpos < IT_CHARPOS (*it))
8460 bidi_move_to_visually_next (&it->bidi_it);
8462 return 0;
8464 it->position = it->current.pos;
8465 it->object = it->w->contents;
8466 it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
8467 IT_BYTEPOS (*it), Qnil);
8469 return 1;
8474 /***********************************************************************
8475 Moving an iterator without producing glyphs
8476 ***********************************************************************/
8478 /* Check if iterator is at a position corresponding to a valid buffer
8479 position after some move_it_ call. */
8481 #define IT_POS_VALID_AFTER_MOVE_P(it) \
8482 ((it)->method == GET_FROM_STRING \
8483 ? IT_STRING_CHARPOS (*it) == 0 \
8484 : 1)
8487 /* Move iterator IT to a specified buffer or X position within one
8488 line on the display without producing glyphs.
8490 OP should be a bit mask including some or all of these bits:
8491 MOVE_TO_X: Stop upon reaching x-position TO_X.
8492 MOVE_TO_POS: Stop upon reaching buffer or string position TO_CHARPOS.
8493 Regardless of OP's value, stop upon reaching the end of the display line.
8495 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
8496 This means, in particular, that TO_X includes window's horizontal
8497 scroll amount.
8499 The return value has several possible values that
8500 say what condition caused the scan to stop:
8502 MOVE_POS_MATCH_OR_ZV
8503 - when TO_POS or ZV was reached.
8505 MOVE_X_REACHED
8506 -when TO_X was reached before TO_POS or ZV were reached.
8508 MOVE_LINE_CONTINUED
8509 - when we reached the end of the display area and the line must
8510 be continued.
8512 MOVE_LINE_TRUNCATED
8513 - when we reached the end of the display area and the line is
8514 truncated.
8516 MOVE_NEWLINE_OR_CR
8517 - when we stopped at a line end, i.e. a newline or a CR and selective
8518 display is on. */
8520 static enum move_it_result
8521 move_it_in_display_line_to (struct it *it,
8522 ptrdiff_t to_charpos, int to_x,
8523 enum move_operation_enum op)
8525 enum move_it_result result = MOVE_UNDEFINED;
8526 struct glyph_row *saved_glyph_row;
8527 struct it wrap_it, atpos_it, atx_it, ppos_it;
8528 void *wrap_data = NULL, *atpos_data = NULL, *atx_data = NULL;
8529 void *ppos_data = NULL;
8530 int may_wrap = 0;
8531 enum it_method prev_method = it->method;
8532 ptrdiff_t closest_pos IF_LINT (= 0), prev_pos = IT_CHARPOS (*it);
8533 int saw_smaller_pos = prev_pos < to_charpos;
8535 /* Don't produce glyphs in produce_glyphs. */
8536 saved_glyph_row = it->glyph_row;
8537 it->glyph_row = NULL;
8539 /* Use wrap_it to save a copy of IT wherever a word wrap could
8540 occur. Use atpos_it to save a copy of IT at the desired buffer
8541 position, if found, so that we can scan ahead and check if the
8542 word later overshoots the window edge. Use atx_it similarly, for
8543 pixel positions. */
8544 wrap_it.sp = -1;
8545 atpos_it.sp = -1;
8546 atx_it.sp = -1;
8548 /* Use ppos_it under bidi reordering to save a copy of IT for the
8549 initial position. We restore that position in IT when we have
8550 scanned the entire display line without finding a match for
8551 TO_CHARPOS and all the character positions are greater than
8552 TO_CHARPOS. We then restart the scan from the initial position,
8553 and stop at CLOSEST_POS, which is a position > TO_CHARPOS that is
8554 the closest to TO_CHARPOS. */
8555 if (it->bidi_p)
8557 if ((op & MOVE_TO_POS) && IT_CHARPOS (*it) >= to_charpos)
8559 SAVE_IT (ppos_it, *it, ppos_data);
8560 closest_pos = IT_CHARPOS (*it);
8562 else
8563 closest_pos = ZV;
8566 #define BUFFER_POS_REACHED_P() \
8567 ((op & MOVE_TO_POS) != 0 \
8568 && BUFFERP (it->object) \
8569 && (IT_CHARPOS (*it) == to_charpos \
8570 || ((!it->bidi_p \
8571 || BIDI_AT_BASE_LEVEL (it->bidi_it)) \
8572 && IT_CHARPOS (*it) > to_charpos) \
8573 || (it->what == IT_COMPOSITION \
8574 && ((IT_CHARPOS (*it) > to_charpos \
8575 && to_charpos >= it->cmp_it.charpos) \
8576 || (IT_CHARPOS (*it) < to_charpos \
8577 && to_charpos <= it->cmp_it.charpos)))) \
8578 && (it->method == GET_FROM_BUFFER \
8579 || (it->method == GET_FROM_DISPLAY_VECTOR \
8580 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
8582 /* If there's a line-/wrap-prefix, handle it. */
8583 if (it->hpos == 0 && it->method == GET_FROM_BUFFER
8584 && it->current_y < it->last_visible_y)
8585 handle_line_prefix (it);
8587 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8588 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8590 while (1)
8592 int x, i, ascent = 0, descent = 0;
8594 /* Utility macro to reset an iterator with x, ascent, and descent. */
8595 #define IT_RESET_X_ASCENT_DESCENT(IT) \
8596 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
8597 (IT)->max_descent = descent)
8599 /* Stop if we move beyond TO_CHARPOS (after an image or a
8600 display string or stretch glyph). */
8601 if ((op & MOVE_TO_POS) != 0
8602 && BUFFERP (it->object)
8603 && it->method == GET_FROM_BUFFER
8604 && (((!it->bidi_p
8605 /* When the iterator is at base embedding level, we
8606 are guaranteed that characters are delivered for
8607 display in strictly increasing order of their
8608 buffer positions. */
8609 || BIDI_AT_BASE_LEVEL (it->bidi_it))
8610 && IT_CHARPOS (*it) > to_charpos)
8611 || (it->bidi_p
8612 && (prev_method == GET_FROM_IMAGE
8613 || prev_method == GET_FROM_STRETCH
8614 || prev_method == GET_FROM_STRING)
8615 /* Passed TO_CHARPOS from left to right. */
8616 && ((prev_pos < to_charpos
8617 && IT_CHARPOS (*it) > to_charpos)
8618 /* Passed TO_CHARPOS from right to left. */
8619 || (prev_pos > to_charpos
8620 && IT_CHARPOS (*it) < to_charpos)))))
8622 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8624 result = MOVE_POS_MATCH_OR_ZV;
8625 break;
8627 else if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8628 /* If wrap_it is valid, the current position might be in a
8629 word that is wrapped. So, save the iterator in
8630 atpos_it and continue to see if wrapping happens. */
8631 SAVE_IT (atpos_it, *it, atpos_data);
8634 /* Stop when ZV reached.
8635 We used to stop here when TO_CHARPOS reached as well, but that is
8636 too soon if this glyph does not fit on this line. So we handle it
8637 explicitly below. */
8638 if (!get_next_display_element (it))
8640 result = MOVE_POS_MATCH_OR_ZV;
8641 break;
8644 if (it->line_wrap == TRUNCATE)
8646 if (BUFFER_POS_REACHED_P ())
8648 result = MOVE_POS_MATCH_OR_ZV;
8649 break;
8652 else
8654 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
8656 if (IT_DISPLAYING_WHITESPACE (it))
8657 may_wrap = 1;
8658 else if (may_wrap)
8660 /* We have reached a glyph that follows one or more
8661 whitespace characters. If the position is
8662 already found, we are done. */
8663 if (atpos_it.sp >= 0)
8665 RESTORE_IT (it, &atpos_it, atpos_data);
8666 result = MOVE_POS_MATCH_OR_ZV;
8667 goto done;
8669 if (atx_it.sp >= 0)
8671 RESTORE_IT (it, &atx_it, atx_data);
8672 result = MOVE_X_REACHED;
8673 goto done;
8675 /* Otherwise, we can wrap here. */
8676 SAVE_IT (wrap_it, *it, wrap_data);
8677 may_wrap = 0;
8682 /* Remember the line height for the current line, in case
8683 the next element doesn't fit on the line. */
8684 ascent = it->max_ascent;
8685 descent = it->max_descent;
8687 /* The call to produce_glyphs will get the metrics of the
8688 display element IT is loaded with. Record the x-position
8689 before this display element, in case it doesn't fit on the
8690 line. */
8691 x = it->current_x;
8693 PRODUCE_GLYPHS (it);
8695 if (it->area != TEXT_AREA)
8697 prev_method = it->method;
8698 if (it->method == GET_FROM_BUFFER)
8699 prev_pos = IT_CHARPOS (*it);
8700 set_iterator_to_next (it, 1);
8701 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8702 SET_TEXT_POS (this_line_min_pos,
8703 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8704 if (it->bidi_p
8705 && (op & MOVE_TO_POS)
8706 && IT_CHARPOS (*it) > to_charpos
8707 && IT_CHARPOS (*it) < closest_pos)
8708 closest_pos = IT_CHARPOS (*it);
8709 continue;
8712 /* The number of glyphs we get back in IT->nglyphs will normally
8713 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
8714 character on a terminal frame, or (iii) a line end. For the
8715 second case, IT->nglyphs - 1 padding glyphs will be present.
8716 (On X frames, there is only one glyph produced for a
8717 composite character.)
8719 The behavior implemented below means, for continuation lines,
8720 that as many spaces of a TAB as fit on the current line are
8721 displayed there. For terminal frames, as many glyphs of a
8722 multi-glyph character are displayed in the current line, too.
8723 This is what the old redisplay code did, and we keep it that
8724 way. Under X, the whole shape of a complex character must
8725 fit on the line or it will be completely displayed in the
8726 next line.
8728 Note that both for tabs and padding glyphs, all glyphs have
8729 the same width. */
8730 if (it->nglyphs)
8732 /* More than one glyph or glyph doesn't fit on line. All
8733 glyphs have the same width. */
8734 int single_glyph_width = it->pixel_width / it->nglyphs;
8735 int new_x;
8736 int x_before_this_char = x;
8737 int hpos_before_this_char = it->hpos;
8739 for (i = 0; i < it->nglyphs; ++i, x = new_x)
8741 new_x = x + single_glyph_width;
8743 /* We want to leave anything reaching TO_X to the caller. */
8744 if ((op & MOVE_TO_X) && new_x > to_x)
8746 if (BUFFER_POS_REACHED_P ())
8748 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8749 goto buffer_pos_reached;
8750 if (atpos_it.sp < 0)
8752 SAVE_IT (atpos_it, *it, atpos_data);
8753 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8756 else
8758 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8760 it->current_x = x;
8761 result = MOVE_X_REACHED;
8762 break;
8764 if (atx_it.sp < 0)
8766 SAVE_IT (atx_it, *it, atx_data);
8767 IT_RESET_X_ASCENT_DESCENT (&atx_it);
8772 if (/* Lines are continued. */
8773 it->line_wrap != TRUNCATE
8774 && (/* And glyph doesn't fit on the line. */
8775 new_x > it->last_visible_x
8776 /* Or it fits exactly and we're on a window
8777 system frame. */
8778 || (new_x == it->last_visible_x
8779 && FRAME_WINDOW_P (it->f)
8780 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
8781 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8782 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
8784 if (/* IT->hpos == 0 means the very first glyph
8785 doesn't fit on the line, e.g. a wide image. */
8786 it->hpos == 0
8787 || (new_x == it->last_visible_x
8788 && FRAME_WINDOW_P (it->f)
8789 /* When word-wrap is ON and we have a valid
8790 wrap point, we don't allow the last glyph
8791 to "just barely fit" on the line. */
8792 && (it->line_wrap != WORD_WRAP
8793 || wrap_it.sp < 0)))
8795 ++it->hpos;
8796 it->current_x = new_x;
8798 /* The character's last glyph just barely fits
8799 in this row. */
8800 if (i == it->nglyphs - 1)
8802 /* If this is the destination position,
8803 return a position *before* it in this row,
8804 now that we know it fits in this row. */
8805 if (BUFFER_POS_REACHED_P ())
8807 if (it->line_wrap != WORD_WRAP
8808 || wrap_it.sp < 0)
8810 it->hpos = hpos_before_this_char;
8811 it->current_x = x_before_this_char;
8812 result = MOVE_POS_MATCH_OR_ZV;
8813 break;
8815 if (it->line_wrap == WORD_WRAP
8816 && atpos_it.sp < 0)
8818 SAVE_IT (atpos_it, *it, atpos_data);
8819 atpos_it.current_x = x_before_this_char;
8820 atpos_it.hpos = hpos_before_this_char;
8824 prev_method = it->method;
8825 if (it->method == GET_FROM_BUFFER)
8826 prev_pos = IT_CHARPOS (*it);
8827 set_iterator_to_next (it, 1);
8828 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8829 SET_TEXT_POS (this_line_min_pos,
8830 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8831 /* On graphical terminals, newlines may
8832 "overflow" into the fringe if
8833 overflow-newline-into-fringe is non-nil.
8834 On text terminals, and on graphical
8835 terminals with no right margin, newlines
8836 may overflow into the last glyph on the
8837 display line.*/
8838 if (!FRAME_WINDOW_P (it->f)
8839 || ((it->bidi_p
8840 && it->bidi_it.paragraph_dir == R2L)
8841 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8842 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
8843 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8845 if (!get_next_display_element (it))
8847 result = MOVE_POS_MATCH_OR_ZV;
8848 break;
8850 if (BUFFER_POS_REACHED_P ())
8852 if (ITERATOR_AT_END_OF_LINE_P (it))
8853 result = MOVE_POS_MATCH_OR_ZV;
8854 else
8855 result = MOVE_LINE_CONTINUED;
8856 break;
8858 if (ITERATOR_AT_END_OF_LINE_P (it)
8859 && (it->line_wrap != WORD_WRAP
8860 || wrap_it.sp < 0))
8862 result = MOVE_NEWLINE_OR_CR;
8863 break;
8868 else
8869 IT_RESET_X_ASCENT_DESCENT (it);
8871 if (wrap_it.sp >= 0)
8873 RESTORE_IT (it, &wrap_it, wrap_data);
8874 atpos_it.sp = -1;
8875 atx_it.sp = -1;
8878 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
8879 IT_CHARPOS (*it)));
8880 result = MOVE_LINE_CONTINUED;
8881 break;
8884 if (BUFFER_POS_REACHED_P ())
8886 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8887 goto buffer_pos_reached;
8888 if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8890 SAVE_IT (atpos_it, *it, atpos_data);
8891 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8895 if (new_x > it->first_visible_x)
8897 /* Glyph is visible. Increment number of glyphs that
8898 would be displayed. */
8899 ++it->hpos;
8903 if (result != MOVE_UNDEFINED)
8904 break;
8906 else if (BUFFER_POS_REACHED_P ())
8908 buffer_pos_reached:
8909 IT_RESET_X_ASCENT_DESCENT (it);
8910 result = MOVE_POS_MATCH_OR_ZV;
8911 break;
8913 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
8915 /* Stop when TO_X specified and reached. This check is
8916 necessary here because of lines consisting of a line end,
8917 only. The line end will not produce any glyphs and we
8918 would never get MOVE_X_REACHED. */
8919 eassert (it->nglyphs == 0);
8920 result = MOVE_X_REACHED;
8921 break;
8924 /* Is this a line end? If yes, we're done. */
8925 if (ITERATOR_AT_END_OF_LINE_P (it))
8927 /* If we are past TO_CHARPOS, but never saw any character
8928 positions smaller than TO_CHARPOS, return
8929 MOVE_POS_MATCH_OR_ZV, like the unidirectional display
8930 did. */
8931 if (it->bidi_p && (op & MOVE_TO_POS) != 0)
8933 if (!saw_smaller_pos && IT_CHARPOS (*it) > to_charpos)
8935 if (closest_pos < ZV)
8937 RESTORE_IT (it, &ppos_it, ppos_data);
8938 /* Don't recurse if closest_pos is equal to
8939 to_charpos, since we have just tried that. */
8940 if (closest_pos != to_charpos)
8941 move_it_in_display_line_to (it, closest_pos, -1,
8942 MOVE_TO_POS);
8943 result = MOVE_POS_MATCH_OR_ZV;
8945 else
8946 goto buffer_pos_reached;
8948 else if (it->line_wrap == WORD_WRAP && atpos_it.sp >= 0
8949 && IT_CHARPOS (*it) > to_charpos)
8950 goto buffer_pos_reached;
8951 else
8952 result = MOVE_NEWLINE_OR_CR;
8954 else
8955 result = MOVE_NEWLINE_OR_CR;
8956 break;
8959 prev_method = it->method;
8960 if (it->method == GET_FROM_BUFFER)
8961 prev_pos = IT_CHARPOS (*it);
8962 /* The current display element has been consumed. Advance
8963 to the next. */
8964 set_iterator_to_next (it, 1);
8965 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8966 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8967 if (IT_CHARPOS (*it) < to_charpos)
8968 saw_smaller_pos = 1;
8969 if (it->bidi_p
8970 && (op & MOVE_TO_POS)
8971 && IT_CHARPOS (*it) >= to_charpos
8972 && IT_CHARPOS (*it) < closest_pos)
8973 closest_pos = IT_CHARPOS (*it);
8975 /* Stop if lines are truncated and IT's current x-position is
8976 past the right edge of the window now. */
8977 if (it->line_wrap == TRUNCATE
8978 && it->current_x >= it->last_visible_x)
8980 if (!FRAME_WINDOW_P (it->f)
8981 || ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
8982 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8983 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
8984 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8986 int at_eob_p = 0;
8988 if ((at_eob_p = !get_next_display_element (it))
8989 || BUFFER_POS_REACHED_P ()
8990 /* If we are past TO_CHARPOS, but never saw any
8991 character positions smaller than TO_CHARPOS,
8992 return MOVE_POS_MATCH_OR_ZV, like the
8993 unidirectional display did. */
8994 || (it->bidi_p && (op & MOVE_TO_POS) != 0
8995 && !saw_smaller_pos
8996 && IT_CHARPOS (*it) > to_charpos))
8998 if (it->bidi_p
8999 && !BUFFER_POS_REACHED_P ()
9000 && !at_eob_p && closest_pos < ZV)
9002 RESTORE_IT (it, &ppos_it, ppos_data);
9003 if (closest_pos != to_charpos)
9004 move_it_in_display_line_to (it, closest_pos, -1,
9005 MOVE_TO_POS);
9007 result = MOVE_POS_MATCH_OR_ZV;
9008 break;
9010 if (ITERATOR_AT_END_OF_LINE_P (it))
9012 result = MOVE_NEWLINE_OR_CR;
9013 break;
9016 else if (it->bidi_p && (op & MOVE_TO_POS) != 0
9017 && !saw_smaller_pos
9018 && IT_CHARPOS (*it) > to_charpos)
9020 if (closest_pos < ZV)
9022 RESTORE_IT (it, &ppos_it, ppos_data);
9023 if (closest_pos != to_charpos)
9024 move_it_in_display_line_to (it, closest_pos, -1,
9025 MOVE_TO_POS);
9027 result = MOVE_POS_MATCH_OR_ZV;
9028 break;
9030 result = MOVE_LINE_TRUNCATED;
9031 break;
9033 #undef IT_RESET_X_ASCENT_DESCENT
9036 #undef BUFFER_POS_REACHED_P
9038 /* If we scanned beyond to_pos and didn't find a point to wrap at,
9039 restore the saved iterator. */
9040 if (atpos_it.sp >= 0)
9041 RESTORE_IT (it, &atpos_it, atpos_data);
9042 else if (atx_it.sp >= 0)
9043 RESTORE_IT (it, &atx_it, atx_data);
9045 done:
9047 if (atpos_data)
9048 bidi_unshelve_cache (atpos_data, 1);
9049 if (atx_data)
9050 bidi_unshelve_cache (atx_data, 1);
9051 if (wrap_data)
9052 bidi_unshelve_cache (wrap_data, 1);
9053 if (ppos_data)
9054 bidi_unshelve_cache (ppos_data, 1);
9056 /* Restore the iterator settings altered at the beginning of this
9057 function. */
9058 it->glyph_row = saved_glyph_row;
9059 return result;
9062 /* For external use. */
9063 void
9064 move_it_in_display_line (struct it *it,
9065 ptrdiff_t to_charpos, int to_x,
9066 enum move_operation_enum op)
9068 if (it->line_wrap == WORD_WRAP
9069 && (op & MOVE_TO_X))
9071 struct it save_it;
9072 void *save_data = NULL;
9073 int skip;
9075 SAVE_IT (save_it, *it, save_data);
9076 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
9077 /* When word-wrap is on, TO_X may lie past the end
9078 of a wrapped line. Then it->current is the
9079 character on the next line, so backtrack to the
9080 space before the wrap point. */
9081 if (skip == MOVE_LINE_CONTINUED)
9083 int prev_x = max (it->current_x - 1, 0);
9084 RESTORE_IT (it, &save_it, save_data);
9085 move_it_in_display_line_to
9086 (it, -1, prev_x, MOVE_TO_X);
9088 else
9089 bidi_unshelve_cache (save_data, 1);
9091 else
9092 move_it_in_display_line_to (it, to_charpos, to_x, op);
9096 /* Move IT forward until it satisfies one or more of the criteria in
9097 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
9099 OP is a bit-mask that specifies where to stop, and in particular,
9100 which of those four position arguments makes a difference. See the
9101 description of enum move_operation_enum.
9103 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
9104 screen line, this function will set IT to the next position that is
9105 displayed to the right of TO_CHARPOS on the screen.
9107 Return the maximum pixel length of any line scanned but never more
9108 than it.last_visible_x. */
9111 move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos, int op)
9113 enum move_it_result skip, skip2 = MOVE_X_REACHED;
9114 int line_height, line_start_x = 0, reached = 0;
9115 int max_current_x = 0;
9116 void *backup_data = NULL;
9118 for (;;)
9120 if (op & MOVE_TO_VPOS)
9122 /* If no TO_CHARPOS and no TO_X specified, stop at the
9123 start of the line TO_VPOS. */
9124 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
9126 if (it->vpos == to_vpos)
9128 reached = 1;
9129 break;
9131 else
9132 skip = move_it_in_display_line_to (it, -1, -1, 0);
9134 else
9136 /* TO_VPOS >= 0 means stop at TO_X in the line at
9137 TO_VPOS, or at TO_POS, whichever comes first. */
9138 if (it->vpos == to_vpos)
9140 reached = 2;
9141 break;
9144 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
9146 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
9148 reached = 3;
9149 break;
9151 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
9153 /* We have reached TO_X but not in the line we want. */
9154 skip = move_it_in_display_line_to (it, to_charpos,
9155 -1, MOVE_TO_POS);
9156 if (skip == MOVE_POS_MATCH_OR_ZV)
9158 reached = 4;
9159 break;
9164 else if (op & MOVE_TO_Y)
9166 struct it it_backup;
9168 if (it->line_wrap == WORD_WRAP)
9169 SAVE_IT (it_backup, *it, backup_data);
9171 /* TO_Y specified means stop at TO_X in the line containing
9172 TO_Y---or at TO_CHARPOS if this is reached first. The
9173 problem is that we can't really tell whether the line
9174 contains TO_Y before we have completely scanned it, and
9175 this may skip past TO_X. What we do is to first scan to
9176 TO_X.
9178 If TO_X is not specified, use a TO_X of zero. The reason
9179 is to make the outcome of this function more predictable.
9180 If we didn't use TO_X == 0, we would stop at the end of
9181 the line which is probably not what a caller would expect
9182 to happen. */
9183 skip = move_it_in_display_line_to
9184 (it, to_charpos, ((op & MOVE_TO_X) ? to_x : 0),
9185 (MOVE_TO_X | (op & MOVE_TO_POS)));
9187 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
9188 if (skip == MOVE_POS_MATCH_OR_ZV)
9189 reached = 5;
9190 else if (skip == MOVE_X_REACHED)
9192 /* If TO_X was reached, we want to know whether TO_Y is
9193 in the line. We know this is the case if the already
9194 scanned glyphs make the line tall enough. Otherwise,
9195 we must check by scanning the rest of the line. */
9196 line_height = it->max_ascent + it->max_descent;
9197 if (to_y >= it->current_y
9198 && to_y < it->current_y + line_height)
9200 reached = 6;
9201 break;
9203 SAVE_IT (it_backup, *it, backup_data);
9204 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
9205 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
9206 op & MOVE_TO_POS);
9207 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
9208 line_height = it->max_ascent + it->max_descent;
9209 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
9211 if (to_y >= it->current_y
9212 && to_y < it->current_y + line_height)
9214 /* If TO_Y is in this line and TO_X was reached
9215 above, we scanned too far. We have to restore
9216 IT's settings to the ones before skipping. But
9217 keep the more accurate values of max_ascent and
9218 max_descent we've found while skipping the rest
9219 of the line, for the sake of callers, such as
9220 pos_visible_p, that need to know the line
9221 height. */
9222 int max_ascent = it->max_ascent;
9223 int max_descent = it->max_descent;
9225 RESTORE_IT (it, &it_backup, backup_data);
9226 it->max_ascent = max_ascent;
9227 it->max_descent = max_descent;
9228 reached = 6;
9230 else
9232 skip = skip2;
9233 if (skip == MOVE_POS_MATCH_OR_ZV)
9234 reached = 7;
9237 else
9239 /* Check whether TO_Y is in this line. */
9240 line_height = it->max_ascent + it->max_descent;
9241 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
9243 if (to_y >= it->current_y
9244 && to_y < it->current_y + line_height)
9246 if (to_y > it->current_y)
9247 max_current_x = max (it->current_x, max_current_x);
9249 /* When word-wrap is on, TO_X may lie past the end
9250 of a wrapped line. Then it->current is the
9251 character on the next line, so backtrack to the
9252 space before the wrap point. */
9253 if (skip == MOVE_LINE_CONTINUED
9254 && it->line_wrap == WORD_WRAP)
9256 int prev_x = max (it->current_x - 1, 0);
9257 RESTORE_IT (it, &it_backup, backup_data);
9258 skip = move_it_in_display_line_to
9259 (it, -1, prev_x, MOVE_TO_X);
9262 reached = 6;
9266 if (reached)
9268 max_current_x = max (it->current_x, max_current_x);
9269 break;
9272 else if (BUFFERP (it->object)
9273 && (it->method == GET_FROM_BUFFER
9274 || it->method == GET_FROM_STRETCH)
9275 && IT_CHARPOS (*it) >= to_charpos
9276 /* Under bidi iteration, a call to set_iterator_to_next
9277 can scan far beyond to_charpos if the initial
9278 portion of the next line needs to be reordered. In
9279 that case, give move_it_in_display_line_to another
9280 chance below. */
9281 && !(it->bidi_p
9282 && it->bidi_it.scan_dir == -1))
9283 skip = MOVE_POS_MATCH_OR_ZV;
9284 else
9285 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
9287 switch (skip)
9289 case MOVE_POS_MATCH_OR_ZV:
9290 max_current_x = max (it->current_x, max_current_x);
9291 reached = 8;
9292 goto out;
9294 case MOVE_NEWLINE_OR_CR:
9295 max_current_x = max (it->current_x, max_current_x);
9296 set_iterator_to_next (it, 1);
9297 it->continuation_lines_width = 0;
9298 break;
9300 case MOVE_LINE_TRUNCATED:
9301 max_current_x = it->last_visible_x;
9302 it->continuation_lines_width = 0;
9303 reseat_at_next_visible_line_start (it, 0);
9304 if ((op & MOVE_TO_POS) != 0
9305 && IT_CHARPOS (*it) > to_charpos)
9307 reached = 9;
9308 goto out;
9310 break;
9312 case MOVE_LINE_CONTINUED:
9313 max_current_x = it->last_visible_x;
9314 /* For continued lines ending in a tab, some of the glyphs
9315 associated with the tab are displayed on the current
9316 line. Since it->current_x does not include these glyphs,
9317 we use it->last_visible_x instead. */
9318 if (it->c == '\t')
9320 it->continuation_lines_width += it->last_visible_x;
9321 /* When moving by vpos, ensure that the iterator really
9322 advances to the next line (bug#847, bug#969). Fixme:
9323 do we need to do this in other circumstances? */
9324 if (it->current_x != it->last_visible_x
9325 && (op & MOVE_TO_VPOS)
9326 && !(op & (MOVE_TO_X | MOVE_TO_POS)))
9328 line_start_x = it->current_x + it->pixel_width
9329 - it->last_visible_x;
9330 if (FRAME_WINDOW_P (it->f))
9332 struct face *face = FACE_FROM_ID (it->f, it->face_id);
9333 struct font *face_font = face->font;
9335 /* When display_line produces a continued line
9336 that ends in a TAB, it skips a tab stop that
9337 is closer than the font's space character
9338 width (see x_produce_glyphs where it produces
9339 the stretch glyph which represents a TAB).
9340 We need to reproduce the same logic here. */
9341 eassert (face_font);
9342 if (face_font)
9344 if (line_start_x < face_font->space_width)
9345 line_start_x
9346 += it->tab_width * face_font->space_width;
9349 set_iterator_to_next (it, 0);
9352 else
9353 it->continuation_lines_width += it->current_x;
9354 break;
9356 default:
9357 emacs_abort ();
9360 /* Reset/increment for the next run. */
9361 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
9362 it->current_x = line_start_x;
9363 line_start_x = 0;
9364 it->hpos = 0;
9365 it->current_y += it->max_ascent + it->max_descent;
9366 ++it->vpos;
9367 last_height = it->max_ascent + it->max_descent;
9368 it->max_ascent = it->max_descent = 0;
9371 out:
9373 /* On text terminals, we may stop at the end of a line in the middle
9374 of a multi-character glyph. If the glyph itself is continued,
9375 i.e. it is actually displayed on the next line, don't treat this
9376 stopping point as valid; move to the next line instead (unless
9377 that brings us offscreen). */
9378 if (!FRAME_WINDOW_P (it->f)
9379 && op & MOVE_TO_POS
9380 && IT_CHARPOS (*it) == to_charpos
9381 && it->what == IT_CHARACTER
9382 && it->nglyphs > 1
9383 && it->line_wrap == WINDOW_WRAP
9384 && it->current_x == it->last_visible_x - 1
9385 && it->c != '\n'
9386 && it->c != '\t'
9387 && it->vpos < it->w->window_end_vpos)
9389 it->continuation_lines_width += it->current_x;
9390 it->current_x = it->hpos = it->max_ascent = it->max_descent = 0;
9391 it->current_y += it->max_ascent + it->max_descent;
9392 ++it->vpos;
9393 last_height = it->max_ascent + it->max_descent;
9396 if (backup_data)
9397 bidi_unshelve_cache (backup_data, 1);
9399 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
9401 return max_current_x;
9405 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
9407 If DY > 0, move IT backward at least that many pixels. DY = 0
9408 means move IT backward to the preceding line start or BEGV. This
9409 function may move over more than DY pixels if IT->current_y - DY
9410 ends up in the middle of a line; in this case IT->current_y will be
9411 set to the top of the line moved to. */
9413 void
9414 move_it_vertically_backward (struct it *it, int dy)
9416 int nlines, h;
9417 struct it it2, it3;
9418 void *it2data = NULL, *it3data = NULL;
9419 ptrdiff_t start_pos;
9420 int nchars_per_row
9421 = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
9422 ptrdiff_t pos_limit;
9424 move_further_back:
9425 eassert (dy >= 0);
9427 start_pos = IT_CHARPOS (*it);
9429 /* Estimate how many newlines we must move back. */
9430 nlines = max (1, dy / default_line_pixel_height (it->w));
9431 if (it->line_wrap == TRUNCATE || nchars_per_row == 0)
9432 pos_limit = BEGV;
9433 else
9434 pos_limit = max (start_pos - nlines * nchars_per_row, BEGV);
9436 /* Set the iterator's position that many lines back. But don't go
9437 back more than NLINES full screen lines -- this wins a day with
9438 buffers which have very long lines. */
9439 while (nlines-- && IT_CHARPOS (*it) > pos_limit)
9440 back_to_previous_visible_line_start (it);
9442 /* Reseat the iterator here. When moving backward, we don't want
9443 reseat to skip forward over invisible text, set up the iterator
9444 to deliver from overlay strings at the new position etc. So,
9445 use reseat_1 here. */
9446 reseat_1 (it, it->current.pos, 1);
9448 /* We are now surely at a line start. */
9449 it->current_x = it->hpos = 0; /* FIXME: this is incorrect when bidi
9450 reordering is in effect. */
9451 it->continuation_lines_width = 0;
9453 /* Move forward and see what y-distance we moved. First move to the
9454 start of the next line so that we get its height. We need this
9455 height to be able to tell whether we reached the specified
9456 y-distance. */
9457 SAVE_IT (it2, *it, it2data);
9458 it2.max_ascent = it2.max_descent = 0;
9461 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
9462 MOVE_TO_POS | MOVE_TO_VPOS);
9464 while (!(IT_POS_VALID_AFTER_MOVE_P (&it2)
9465 /* If we are in a display string which starts at START_POS,
9466 and that display string includes a newline, and we are
9467 right after that newline (i.e. at the beginning of a
9468 display line), exit the loop, because otherwise we will
9469 infloop, since move_it_to will see that it is already at
9470 START_POS and will not move. */
9471 || (it2.method == GET_FROM_STRING
9472 && IT_CHARPOS (it2) == start_pos
9473 && SREF (it2.string, IT_STRING_BYTEPOS (it2) - 1) == '\n')));
9474 eassert (IT_CHARPOS (*it) >= BEGV);
9475 SAVE_IT (it3, it2, it3data);
9477 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
9478 eassert (IT_CHARPOS (*it) >= BEGV);
9479 /* H is the actual vertical distance from the position in *IT
9480 and the starting position. */
9481 h = it2.current_y - it->current_y;
9482 /* NLINES is the distance in number of lines. */
9483 nlines = it2.vpos - it->vpos;
9485 /* Correct IT's y and vpos position
9486 so that they are relative to the starting point. */
9487 it->vpos -= nlines;
9488 it->current_y -= h;
9490 if (dy == 0)
9492 /* DY == 0 means move to the start of the screen line. The
9493 value of nlines is > 0 if continuation lines were involved,
9494 or if the original IT position was at start of a line. */
9495 RESTORE_IT (it, it, it2data);
9496 if (nlines > 0)
9497 move_it_by_lines (it, nlines);
9498 /* The above code moves us to some position NLINES down,
9499 usually to its first glyph (leftmost in an L2R line), but
9500 that's not necessarily the start of the line, under bidi
9501 reordering. We want to get to the character position
9502 that is immediately after the newline of the previous
9503 line. */
9504 if (it->bidi_p
9505 && !it->continuation_lines_width
9506 && !STRINGP (it->string)
9507 && IT_CHARPOS (*it) > BEGV
9508 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9510 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
9512 DEC_BOTH (cp, bp);
9513 cp = find_newline_no_quit (cp, bp, -1, NULL);
9514 move_it_to (it, cp, -1, -1, -1, MOVE_TO_POS);
9516 bidi_unshelve_cache (it3data, 1);
9518 else
9520 /* The y-position we try to reach, relative to *IT.
9521 Note that H has been subtracted in front of the if-statement. */
9522 int target_y = it->current_y + h - dy;
9523 int y0 = it3.current_y;
9524 int y1;
9525 int line_height;
9527 RESTORE_IT (&it3, &it3, it3data);
9528 y1 = line_bottom_y (&it3);
9529 line_height = y1 - y0;
9530 RESTORE_IT (it, it, it2data);
9531 /* If we did not reach target_y, try to move further backward if
9532 we can. If we moved too far backward, try to move forward. */
9533 if (target_y < it->current_y
9534 /* This is heuristic. In a window that's 3 lines high, with
9535 a line height of 13 pixels each, recentering with point
9536 on the bottom line will try to move -39/2 = 19 pixels
9537 backward. Try to avoid moving into the first line. */
9538 && (it->current_y - target_y
9539 > min (window_box_height (it->w), line_height * 2 / 3))
9540 && IT_CHARPOS (*it) > BEGV)
9542 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
9543 target_y - it->current_y));
9544 dy = it->current_y - target_y;
9545 goto move_further_back;
9547 else if (target_y >= it->current_y + line_height
9548 && IT_CHARPOS (*it) < ZV)
9550 /* Should move forward by at least one line, maybe more.
9552 Note: Calling move_it_by_lines can be expensive on
9553 terminal frames, where compute_motion is used (via
9554 vmotion) to do the job, when there are very long lines
9555 and truncate-lines is nil. That's the reason for
9556 treating terminal frames specially here. */
9558 if (!FRAME_WINDOW_P (it->f))
9559 move_it_vertically (it, target_y - (it->current_y + line_height));
9560 else
9564 move_it_by_lines (it, 1);
9566 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
9573 /* Move IT by a specified amount of pixel lines DY. DY negative means
9574 move backwards. DY = 0 means move to start of screen line. At the
9575 end, IT will be on the start of a screen line. */
9577 void
9578 move_it_vertically (struct it *it, int dy)
9580 if (dy <= 0)
9581 move_it_vertically_backward (it, -dy);
9582 else
9584 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
9585 move_it_to (it, ZV, -1, it->current_y + dy, -1,
9586 MOVE_TO_POS | MOVE_TO_Y);
9587 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
9589 /* If buffer ends in ZV without a newline, move to the start of
9590 the line to satisfy the post-condition. */
9591 if (IT_CHARPOS (*it) == ZV
9592 && ZV > BEGV
9593 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9594 move_it_by_lines (it, 0);
9599 /* Move iterator IT past the end of the text line it is in. */
9601 void
9602 move_it_past_eol (struct it *it)
9604 enum move_it_result rc;
9606 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
9607 if (rc == MOVE_NEWLINE_OR_CR)
9608 set_iterator_to_next (it, 0);
9612 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
9613 negative means move up. DVPOS == 0 means move to the start of the
9614 screen line.
9616 Optimization idea: If we would know that IT->f doesn't use
9617 a face with proportional font, we could be faster for
9618 truncate-lines nil. */
9620 void
9621 move_it_by_lines (struct it *it, ptrdiff_t dvpos)
9624 /* The commented-out optimization uses vmotion on terminals. This
9625 gives bad results, because elements like it->what, on which
9626 callers such as pos_visible_p rely, aren't updated. */
9627 /* struct position pos;
9628 if (!FRAME_WINDOW_P (it->f))
9630 struct text_pos textpos;
9632 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
9633 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
9634 reseat (it, textpos, 1);
9635 it->vpos += pos.vpos;
9636 it->current_y += pos.vpos;
9638 else */
9640 if (dvpos == 0)
9642 /* DVPOS == 0 means move to the start of the screen line. */
9643 move_it_vertically_backward (it, 0);
9644 /* Let next call to line_bottom_y calculate real line height. */
9645 last_height = 0;
9647 else if (dvpos > 0)
9649 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
9650 if (!IT_POS_VALID_AFTER_MOVE_P (it))
9652 /* Only move to the next buffer position if we ended up in a
9653 string from display property, not in an overlay string
9654 (before-string or after-string). That is because the
9655 latter don't conceal the underlying buffer position, so
9656 we can ask to move the iterator to the exact position we
9657 are interested in. Note that, even if we are already at
9658 IT_CHARPOS (*it), the call below is not a no-op, as it
9659 will detect that we are at the end of the string, pop the
9660 iterator, and compute it->current_x and it->hpos
9661 correctly. */
9662 move_it_to (it, IT_CHARPOS (*it) + it->string_from_display_prop_p,
9663 -1, -1, -1, MOVE_TO_POS);
9666 else
9668 struct it it2;
9669 void *it2data = NULL;
9670 ptrdiff_t start_charpos, i;
9671 int nchars_per_row
9672 = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
9673 bool hit_pos_limit = false;
9674 ptrdiff_t pos_limit;
9676 /* Start at the beginning of the screen line containing IT's
9677 position. This may actually move vertically backwards,
9678 in case of overlays, so adjust dvpos accordingly. */
9679 dvpos += it->vpos;
9680 move_it_vertically_backward (it, 0);
9681 dvpos -= it->vpos;
9683 /* Go back -DVPOS buffer lines, but no farther than -DVPOS full
9684 screen lines, and reseat the iterator there. */
9685 start_charpos = IT_CHARPOS (*it);
9686 if (it->line_wrap == TRUNCATE || nchars_per_row == 0)
9687 pos_limit = BEGV;
9688 else
9689 pos_limit = max (start_charpos + dvpos * nchars_per_row, BEGV);
9691 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > pos_limit; --i)
9692 back_to_previous_visible_line_start (it);
9693 if (i > 0 && IT_CHARPOS (*it) <= pos_limit)
9694 hit_pos_limit = true;
9695 reseat (it, it->current.pos, 1);
9697 /* Move further back if we end up in a string or an image. */
9698 while (!IT_POS_VALID_AFTER_MOVE_P (it))
9700 /* First try to move to start of display line. */
9701 dvpos += it->vpos;
9702 move_it_vertically_backward (it, 0);
9703 dvpos -= it->vpos;
9704 if (IT_POS_VALID_AFTER_MOVE_P (it))
9705 break;
9706 /* If start of line is still in string or image,
9707 move further back. */
9708 back_to_previous_visible_line_start (it);
9709 reseat (it, it->current.pos, 1);
9710 dvpos--;
9713 it->current_x = it->hpos = 0;
9715 /* Above call may have moved too far if continuation lines
9716 are involved. Scan forward and see if it did. */
9717 SAVE_IT (it2, *it, it2data);
9718 it2.vpos = it2.current_y = 0;
9719 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
9720 it->vpos -= it2.vpos;
9721 it->current_y -= it2.current_y;
9722 it->current_x = it->hpos = 0;
9724 /* If we moved too far back, move IT some lines forward. */
9725 if (it2.vpos > -dvpos)
9727 int delta = it2.vpos + dvpos;
9729 RESTORE_IT (&it2, &it2, it2data);
9730 SAVE_IT (it2, *it, it2data);
9731 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
9732 /* Move back again if we got too far ahead. */
9733 if (IT_CHARPOS (*it) >= start_charpos)
9734 RESTORE_IT (it, &it2, it2data);
9735 else
9736 bidi_unshelve_cache (it2data, 1);
9738 else if (hit_pos_limit && pos_limit > BEGV
9739 && dvpos < 0 && it2.vpos < -dvpos)
9741 /* If we hit the limit, but still didn't make it far enough
9742 back, that means there's a display string with a newline
9743 covering a large chunk of text, and that caused
9744 back_to_previous_visible_line_start try to go too far.
9745 Punish those who commit such atrocities by going back
9746 until we've reached DVPOS, after lifting the limit, which
9747 could make it slow for very long lines. "If it hurts,
9748 don't do that!" */
9749 dvpos += it2.vpos;
9750 RESTORE_IT (it, it, it2data);
9751 for (i = -dvpos; i > 0; --i)
9753 back_to_previous_visible_line_start (it);
9754 it->vpos--;
9756 reseat_1 (it, it->current.pos, 1);
9758 else
9759 RESTORE_IT (it, it, it2data);
9763 /* Return true if IT points into the middle of a display vector. */
9765 bool
9766 in_display_vector_p (struct it *it)
9768 return (it->method == GET_FROM_DISPLAY_VECTOR
9769 && it->current.dpvec_index > 0
9770 && it->dpvec + it->current.dpvec_index != it->dpend);
9773 DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_size, 0, 6, 0,
9774 doc: /* Return the size of the text of WINDOW's buffer in pixels.
9775 WINDOW must be a live window and defaults to the selected one. The
9776 return value is a cons of the maximum pixel-width of any text line and
9777 the maximum pixel-height of all text lines.
9779 The optional argument FROM, if non-nil, specifies the first text
9780 position and defaults to the minimum accessible position of the buffer.
9781 If FROM is t, use the minimum accessible position that is not a newline
9782 character. TO, if non-nil, specifies the last text position and
9783 defaults to the maximum accessible position of the buffer. If TO is t,
9784 use the maximum accessible position that is not a newline character.
9786 The optional argument X-LIMIT, if non-nil, specifies the maximum text
9787 width that can be returned. X-LIMIT nil or omitted, means to use the
9788 pixel-width of WINDOW's body; use this if you do not intend to change
9789 the width of WINDOW. Use the maximum width WINDOW may assume if you
9790 intend to change WINDOW's width. In any case, text whose x-coordinate
9791 is beyond X-LIMIT is ignored. Since calculating the width of long lines
9792 can take some time, it's always a good idea to make this argument as
9793 small as possible; in particular, if the buffer contains long lines that
9794 shall be truncated anyway.
9796 The optional argument Y-LIMIT, if non-nil, specifies the maximum text
9797 height that can be returned. Text lines whose y-coordinate is beyond
9798 Y-LIMIT are ignored. Since calculating the text height of a large
9799 buffer can take some time, it makes sense to specify this argument if
9800 the size of the buffer is unknown.
9802 Optional argument MODE-AND-HEADER-LINE nil or omitted means do not
9803 include the height of the mode- or header-line of WINDOW in the return
9804 value. If it is either the symbol `mode-line' or `header-line', include
9805 only the height of that line, if present, in the return value. If t,
9806 include the height of both, if present, in the return value. */)
9807 (Lisp_Object window, Lisp_Object from, Lisp_Object to, Lisp_Object x_limit, Lisp_Object y_limit,
9808 Lisp_Object mode_and_header_line)
9810 struct window *w = decode_live_window (window);
9811 Lisp_Object buf;
9812 struct buffer *b;
9813 struct it it;
9814 struct buffer *old_buffer = NULL;
9815 ptrdiff_t start, end, pos;
9816 struct text_pos startp;
9817 void *itdata = NULL;
9818 int c, max_y = -1, x = 0, y = 0;
9820 buf = w->contents;
9821 CHECK_BUFFER (buf);
9822 b = XBUFFER (buf);
9824 if (b != current_buffer)
9826 old_buffer = current_buffer;
9827 set_buffer_internal (b);
9830 if (NILP (from))
9831 start = BEGV;
9832 else if (EQ (from, Qt))
9834 start = pos = BEGV;
9835 while ((pos++ < ZV) && (c = FETCH_CHAR (pos))
9836 && (c == ' ' || c == '\t' || c == '\n' || c == '\r'))
9837 start = pos;
9838 while ((pos-- > BEGV) && (c = FETCH_CHAR (pos)) && (c == ' ' || c == '\t'))
9839 start = pos;
9841 else
9843 CHECK_NUMBER_COERCE_MARKER (from);
9844 start = min (max (XINT (from), BEGV), ZV);
9847 if (NILP (to))
9848 end = ZV;
9849 else if (EQ (to, Qt))
9851 end = pos = ZV;
9852 while ((pos-- > BEGV) && (c = FETCH_CHAR (pos))
9853 && (c == ' ' || c == '\t' || c == '\n' || c == '\r'))
9854 end = pos;
9855 while ((pos++ < ZV) && (c = FETCH_CHAR (pos)) && (c == ' ' || c == '\t'))
9856 end = pos;
9858 else
9860 CHECK_NUMBER_COERCE_MARKER (to);
9861 end = max (start, min (XINT (to), ZV));
9864 if (!NILP (y_limit))
9866 CHECK_NUMBER (y_limit);
9867 max_y = min (XINT (y_limit), INT_MAX);
9870 itdata = bidi_shelve_cache ();
9871 SET_TEXT_POS (startp, start, CHAR_TO_BYTE (start));
9872 start_display (&it, w, startp);
9874 if (NILP (x_limit))
9875 x = move_it_to (&it, end, -1, max_y, -1, MOVE_TO_POS | MOVE_TO_Y);
9876 else
9878 CHECK_NUMBER (x_limit);
9879 it.last_visible_x = min (XINT (x_limit), INFINITY);
9880 /* Actually, we never want move_it_to stop at to_x. But to make
9881 sure that move_it_in_display_line_to always moves far enough,
9882 we set it to INT_MAX and specify MOVE_TO_X. */
9883 x = move_it_to (&it, end, INT_MAX, max_y, -1,
9884 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
9887 y = it.current_y + it.max_ascent + it.max_descent;
9889 if (!EQ (mode_and_header_line, Qheader_line)
9890 && !EQ (mode_and_header_line, Qt))
9891 /* Do not count the header-line which was counted automatically by
9892 start_display. */
9893 y = y - WINDOW_HEADER_LINE_HEIGHT (w);
9895 if (EQ (mode_and_header_line, Qmode_line)
9896 || EQ (mode_and_header_line, Qt))
9897 /* Do count the mode-line which is not included automatically by
9898 start_display. */
9899 y = y + WINDOW_MODE_LINE_HEIGHT (w);
9901 bidi_unshelve_cache (itdata, 0);
9903 if (old_buffer)
9904 set_buffer_internal (old_buffer);
9906 return Fcons (make_number (x), make_number (y));
9909 /***********************************************************************
9910 Messages
9911 ***********************************************************************/
9914 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
9915 to *Messages*. */
9917 void
9918 add_to_log (const char *format, Lisp_Object arg1, Lisp_Object arg2)
9920 Lisp_Object args[3];
9921 Lisp_Object msg, fmt;
9922 char *buffer;
9923 ptrdiff_t len;
9924 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
9925 USE_SAFE_ALLOCA;
9927 fmt = msg = Qnil;
9928 GCPRO4 (fmt, msg, arg1, arg2);
9930 args[0] = fmt = build_string (format);
9931 args[1] = arg1;
9932 args[2] = arg2;
9933 msg = Fformat (3, args);
9935 len = SBYTES (msg) + 1;
9936 buffer = SAFE_ALLOCA (len);
9937 memcpy (buffer, SDATA (msg), len);
9939 message_dolog (buffer, len - 1, 1, 0);
9940 SAFE_FREE ();
9942 UNGCPRO;
9946 /* Output a newline in the *Messages* buffer if "needs" one. */
9948 void
9949 message_log_maybe_newline (void)
9951 if (message_log_need_newline)
9952 message_dolog ("", 0, 1, 0);
9956 /* Add a string M of length NBYTES to the message log, optionally
9957 terminated with a newline when NLFLAG is true. MULTIBYTE, if
9958 true, means interpret the contents of M as multibyte. This
9959 function calls low-level routines in order to bypass text property
9960 hooks, etc. which might not be safe to run.
9962 This may GC (insert may run before/after change hooks),
9963 so the buffer M must NOT point to a Lisp string. */
9965 void
9966 message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte)
9968 const unsigned char *msg = (const unsigned char *) m;
9970 if (!NILP (Vmemory_full))
9971 return;
9973 if (!NILP (Vmessage_log_max))
9975 struct buffer *oldbuf;
9976 Lisp_Object oldpoint, oldbegv, oldzv;
9977 int old_windows_or_buffers_changed = windows_or_buffers_changed;
9978 ptrdiff_t point_at_end = 0;
9979 ptrdiff_t zv_at_end = 0;
9980 Lisp_Object old_deactivate_mark;
9981 struct gcpro gcpro1;
9983 old_deactivate_mark = Vdeactivate_mark;
9984 oldbuf = current_buffer;
9986 /* Ensure the Messages buffer exists, and switch to it.
9987 If we created it, set the major-mode. */
9989 int newbuffer = 0;
9990 if (NILP (Fget_buffer (Vmessages_buffer_name))) newbuffer = 1;
9992 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
9994 if (newbuffer
9995 && !NILP (Ffboundp (intern ("messages-buffer-mode"))))
9996 call0 (intern ("messages-buffer-mode"));
9999 bset_undo_list (current_buffer, Qt);
10000 bset_cache_long_scans (current_buffer, Qnil);
10002 oldpoint = message_dolog_marker1;
10003 set_marker_restricted_both (oldpoint, Qnil, PT, PT_BYTE);
10004 oldbegv = message_dolog_marker2;
10005 set_marker_restricted_both (oldbegv, Qnil, BEGV, BEGV_BYTE);
10006 oldzv = message_dolog_marker3;
10007 set_marker_restricted_both (oldzv, Qnil, ZV, ZV_BYTE);
10008 GCPRO1 (old_deactivate_mark);
10010 if (PT == Z)
10011 point_at_end = 1;
10012 if (ZV == Z)
10013 zv_at_end = 1;
10015 BEGV = BEG;
10016 BEGV_BYTE = BEG_BYTE;
10017 ZV = Z;
10018 ZV_BYTE = Z_BYTE;
10019 TEMP_SET_PT_BOTH (Z, Z_BYTE);
10021 /* Insert the string--maybe converting multibyte to single byte
10022 or vice versa, so that all the text fits the buffer. */
10023 if (multibyte
10024 && NILP (BVAR (current_buffer, enable_multibyte_characters)))
10026 ptrdiff_t i;
10027 int c, char_bytes;
10028 char work[1];
10030 /* Convert a multibyte string to single-byte
10031 for the *Message* buffer. */
10032 for (i = 0; i < nbytes; i += char_bytes)
10034 c = string_char_and_length (msg + i, &char_bytes);
10035 work[0] = CHAR_TO_BYTE8 (c);
10036 insert_1_both (work, 1, 1, 1, 0, 0);
10039 else if (! multibyte
10040 && ! NILP (BVAR (current_buffer, enable_multibyte_characters)))
10042 ptrdiff_t i;
10043 int c, char_bytes;
10044 unsigned char str[MAX_MULTIBYTE_LENGTH];
10045 /* Convert a single-byte string to multibyte
10046 for the *Message* buffer. */
10047 for (i = 0; i < nbytes; i++)
10049 c = msg[i];
10050 MAKE_CHAR_MULTIBYTE (c);
10051 char_bytes = CHAR_STRING (c, str);
10052 insert_1_both ((char *) str, 1, char_bytes, 1, 0, 0);
10055 else if (nbytes)
10056 insert_1_both (m, chars_in_text (msg, nbytes), nbytes, 1, 0, 0);
10058 if (nlflag)
10060 ptrdiff_t this_bol, this_bol_byte, prev_bol, prev_bol_byte;
10061 printmax_t dups;
10063 insert_1_both ("\n", 1, 1, 1, 0, 0);
10065 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
10066 this_bol = PT;
10067 this_bol_byte = PT_BYTE;
10069 /* See if this line duplicates the previous one.
10070 If so, combine duplicates. */
10071 if (this_bol > BEG)
10073 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
10074 prev_bol = PT;
10075 prev_bol_byte = PT_BYTE;
10077 dups = message_log_check_duplicate (prev_bol_byte,
10078 this_bol_byte);
10079 if (dups)
10081 del_range_both (prev_bol, prev_bol_byte,
10082 this_bol, this_bol_byte, 0);
10083 if (dups > 1)
10085 char dupstr[sizeof " [ times]"
10086 + INT_STRLEN_BOUND (printmax_t)];
10088 /* If you change this format, don't forget to also
10089 change message_log_check_duplicate. */
10090 int duplen = sprintf (dupstr, " [%"pMd" times]", dups);
10091 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
10092 insert_1_both (dupstr, duplen, duplen, 1, 0, 1);
10097 /* If we have more than the desired maximum number of lines
10098 in the *Messages* buffer now, delete the oldest ones.
10099 This is safe because we don't have undo in this buffer. */
10101 if (NATNUMP (Vmessage_log_max))
10103 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
10104 -XFASTINT (Vmessage_log_max) - 1, 0);
10105 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
10108 BEGV = marker_position (oldbegv);
10109 BEGV_BYTE = marker_byte_position (oldbegv);
10111 if (zv_at_end)
10113 ZV = Z;
10114 ZV_BYTE = Z_BYTE;
10116 else
10118 ZV = marker_position (oldzv);
10119 ZV_BYTE = marker_byte_position (oldzv);
10122 if (point_at_end)
10123 TEMP_SET_PT_BOTH (Z, Z_BYTE);
10124 else
10125 /* We can't do Fgoto_char (oldpoint) because it will run some
10126 Lisp code. */
10127 TEMP_SET_PT_BOTH (marker_position (oldpoint),
10128 marker_byte_position (oldpoint));
10130 UNGCPRO;
10131 unchain_marker (XMARKER (oldpoint));
10132 unchain_marker (XMARKER (oldbegv));
10133 unchain_marker (XMARKER (oldzv));
10135 /* We called insert_1_both above with its 5th argument (PREPARE)
10136 zero, which prevents insert_1_both from calling
10137 prepare_to_modify_buffer, which in turns prevents us from
10138 incrementing windows_or_buffers_changed even if *Messages* is
10139 shown in some window. So we must manually set
10140 windows_or_buffers_changed here to make up for that. */
10141 windows_or_buffers_changed = old_windows_or_buffers_changed;
10142 bset_redisplay (current_buffer);
10144 set_buffer_internal (oldbuf);
10146 message_log_need_newline = !nlflag;
10147 Vdeactivate_mark = old_deactivate_mark;
10152 /* We are at the end of the buffer after just having inserted a newline.
10153 (Note: We depend on the fact we won't be crossing the gap.)
10154 Check to see if the most recent message looks a lot like the previous one.
10155 Return 0 if different, 1 if the new one should just replace it, or a
10156 value N > 1 if we should also append " [N times]". */
10158 static intmax_t
10159 message_log_check_duplicate (ptrdiff_t prev_bol_byte, ptrdiff_t this_bol_byte)
10161 ptrdiff_t i;
10162 ptrdiff_t len = Z_BYTE - 1 - this_bol_byte;
10163 int seen_dots = 0;
10164 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
10165 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
10167 for (i = 0; i < len; i++)
10169 if (i >= 3 && p1[i - 3] == '.' && p1[i - 2] == '.' && p1[i - 1] == '.')
10170 seen_dots = 1;
10171 if (p1[i] != p2[i])
10172 return seen_dots;
10174 p1 += len;
10175 if (*p1 == '\n')
10176 return 2;
10177 if (*p1++ == ' ' && *p1++ == '[')
10179 char *pend;
10180 intmax_t n = strtoimax ((char *) p1, &pend, 10);
10181 if (0 < n && n < INTMAX_MAX && strncmp (pend, " times]\n", 8) == 0)
10182 return n + 1;
10184 return 0;
10188 /* Display an echo area message M with a specified length of NBYTES
10189 bytes. The string may include null characters. If M is not a
10190 string, clear out any existing message, and let the mini-buffer
10191 text show through.
10193 This function cancels echoing. */
10195 void
10196 message3 (Lisp_Object m)
10198 struct gcpro gcpro1;
10200 GCPRO1 (m);
10201 clear_message (true, true);
10202 cancel_echoing ();
10204 /* First flush out any partial line written with print. */
10205 message_log_maybe_newline ();
10206 if (STRINGP (m))
10208 ptrdiff_t nbytes = SBYTES (m);
10209 bool multibyte = STRING_MULTIBYTE (m);
10210 char *buffer;
10211 USE_SAFE_ALLOCA;
10212 SAFE_ALLOCA_STRING (buffer, m);
10213 message_dolog (buffer, nbytes, 1, multibyte);
10214 SAFE_FREE ();
10216 message3_nolog (m);
10218 UNGCPRO;
10222 /* The non-logging version of message3.
10223 This does not cancel echoing, because it is used for echoing.
10224 Perhaps we need to make a separate function for echoing
10225 and make this cancel echoing. */
10227 void
10228 message3_nolog (Lisp_Object m)
10230 struct frame *sf = SELECTED_FRAME ();
10232 if (FRAME_INITIAL_P (sf))
10234 if (noninteractive_need_newline)
10235 putc ('\n', stderr);
10236 noninteractive_need_newline = 0;
10237 if (STRINGP (m))
10239 Lisp_Object s = ENCODE_SYSTEM (m);
10241 fwrite (SDATA (s), SBYTES (s), 1, stderr);
10243 if (cursor_in_echo_area == 0)
10244 fprintf (stderr, "\n");
10245 fflush (stderr);
10247 /* Error messages get reported properly by cmd_error, so this must be just an
10248 informative message; if the frame hasn't really been initialized yet, just
10249 toss it. */
10250 else if (INTERACTIVE && sf->glyphs_initialized_p)
10252 /* Get the frame containing the mini-buffer
10253 that the selected frame is using. */
10254 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
10255 Lisp_Object frame = XWINDOW (mini_window)->frame;
10256 struct frame *f = XFRAME (frame);
10258 if (FRAME_VISIBLE_P (sf) && !FRAME_VISIBLE_P (f))
10259 Fmake_frame_visible (frame);
10261 if (STRINGP (m) && SCHARS (m) > 0)
10263 set_message (m);
10264 if (minibuffer_auto_raise)
10265 Fraise_frame (frame);
10266 /* Assume we are not echoing.
10267 (If we are, echo_now will override this.) */
10268 echo_message_buffer = Qnil;
10270 else
10271 clear_message (true, true);
10273 do_pending_window_change (0);
10274 echo_area_display (1);
10275 do_pending_window_change (0);
10276 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
10277 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
10282 /* Display a null-terminated echo area message M. If M is 0, clear
10283 out any existing message, and let the mini-buffer text show through.
10285 The buffer M must continue to exist until after the echo area gets
10286 cleared or some other message gets displayed there. Do not pass
10287 text that is stored in a Lisp string. Do not pass text in a buffer
10288 that was alloca'd. */
10290 void
10291 message1 (const char *m)
10293 message3 (m ? build_unibyte_string (m) : Qnil);
10297 /* The non-logging counterpart of message1. */
10299 void
10300 message1_nolog (const char *m)
10302 message3_nolog (m ? build_unibyte_string (m) : Qnil);
10305 /* Display a message M which contains a single %s
10306 which gets replaced with STRING. */
10308 void
10309 message_with_string (const char *m, Lisp_Object string, int log)
10311 CHECK_STRING (string);
10313 if (noninteractive)
10315 if (m)
10317 /* ENCODE_SYSTEM below can GC and/or relocate the
10318 Lisp data, so make sure we don't use it here. */
10319 eassert (relocatable_string_data_p (m) != 1);
10321 if (noninteractive_need_newline)
10322 putc ('\n', stderr);
10323 noninteractive_need_newline = 0;
10324 fprintf (stderr, m, SDATA (ENCODE_SYSTEM (string)));
10325 if (!cursor_in_echo_area)
10326 fprintf (stderr, "\n");
10327 fflush (stderr);
10330 else if (INTERACTIVE)
10332 /* The frame whose minibuffer we're going to display the message on.
10333 It may be larger than the selected frame, so we need
10334 to use its buffer, not the selected frame's buffer. */
10335 Lisp_Object mini_window;
10336 struct frame *f, *sf = SELECTED_FRAME ();
10338 /* Get the frame containing the minibuffer
10339 that the selected frame is using. */
10340 mini_window = FRAME_MINIBUF_WINDOW (sf);
10341 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10343 /* Error messages get reported properly by cmd_error, so this must be
10344 just an informative message; if the frame hasn't really been
10345 initialized yet, just toss it. */
10346 if (f->glyphs_initialized_p)
10348 Lisp_Object args[2], msg;
10349 struct gcpro gcpro1, gcpro2;
10351 args[0] = build_string (m);
10352 args[1] = msg = string;
10353 GCPRO2 (args[0], msg);
10354 gcpro1.nvars = 2;
10356 msg = Fformat (2, args);
10358 if (log)
10359 message3 (msg);
10360 else
10361 message3_nolog (msg);
10363 UNGCPRO;
10365 /* Print should start at the beginning of the message
10366 buffer next time. */
10367 message_buf_print = 0;
10373 /* Dump an informative message to the minibuf. If M is 0, clear out
10374 any existing message, and let the mini-buffer text show through. */
10376 static void
10377 vmessage (const char *m, va_list ap)
10379 if (noninteractive)
10381 if (m)
10383 if (noninteractive_need_newline)
10384 putc ('\n', stderr);
10385 noninteractive_need_newline = 0;
10386 vfprintf (stderr, m, ap);
10387 if (cursor_in_echo_area == 0)
10388 fprintf (stderr, "\n");
10389 fflush (stderr);
10392 else if (INTERACTIVE)
10394 /* The frame whose mini-buffer we're going to display the message
10395 on. It may be larger than the selected frame, so we need to
10396 use its buffer, not the selected frame's buffer. */
10397 Lisp_Object mini_window;
10398 struct frame *f, *sf = SELECTED_FRAME ();
10400 /* Get the frame containing the mini-buffer
10401 that the selected frame is using. */
10402 mini_window = FRAME_MINIBUF_WINDOW (sf);
10403 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10405 /* Error messages get reported properly by cmd_error, so this must be
10406 just an informative message; if the frame hasn't really been
10407 initialized yet, just toss it. */
10408 if (f->glyphs_initialized_p)
10410 if (m)
10412 ptrdiff_t len;
10413 ptrdiff_t maxsize = FRAME_MESSAGE_BUF_SIZE (f);
10414 USE_SAFE_ALLOCA;
10415 char *message_buf = SAFE_ALLOCA (maxsize + 1);
10417 len = doprnt (message_buf, maxsize, m, 0, ap);
10419 message3 (make_string (message_buf, len));
10420 SAFE_FREE ();
10422 else
10423 message1 (0);
10425 /* Print should start at the beginning of the message
10426 buffer next time. */
10427 message_buf_print = 0;
10432 void
10433 message (const char *m, ...)
10435 va_list ap;
10436 va_start (ap, m);
10437 vmessage (m, ap);
10438 va_end (ap);
10442 #if 0
10443 /* The non-logging version of message. */
10445 void
10446 message_nolog (const char *m, ...)
10448 Lisp_Object old_log_max;
10449 va_list ap;
10450 va_start (ap, m);
10451 old_log_max = Vmessage_log_max;
10452 Vmessage_log_max = Qnil;
10453 vmessage (m, ap);
10454 Vmessage_log_max = old_log_max;
10455 va_end (ap);
10457 #endif
10460 /* Display the current message in the current mini-buffer. This is
10461 only called from error handlers in process.c, and is not time
10462 critical. */
10464 void
10465 update_echo_area (void)
10467 if (!NILP (echo_area_buffer[0]))
10469 Lisp_Object string;
10470 string = Fcurrent_message ();
10471 message3 (string);
10476 /* Make sure echo area buffers in `echo_buffers' are live.
10477 If they aren't, make new ones. */
10479 static void
10480 ensure_echo_area_buffers (void)
10482 int i;
10484 for (i = 0; i < 2; ++i)
10485 if (!BUFFERP (echo_buffer[i])
10486 || !BUFFER_LIVE_P (XBUFFER (echo_buffer[i])))
10488 char name[30];
10489 Lisp_Object old_buffer;
10490 int j;
10492 old_buffer = echo_buffer[i];
10493 echo_buffer[i] = Fget_buffer_create
10494 (make_formatted_string (name, " *Echo Area %d*", i));
10495 bset_truncate_lines (XBUFFER (echo_buffer[i]), Qnil);
10496 /* to force word wrap in echo area -
10497 it was decided to postpone this*/
10498 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
10500 for (j = 0; j < 2; ++j)
10501 if (EQ (old_buffer, echo_area_buffer[j]))
10502 echo_area_buffer[j] = echo_buffer[i];
10507 /* Call FN with args A1..A2 with either the current or last displayed
10508 echo_area_buffer as current buffer.
10510 WHICH zero means use the current message buffer
10511 echo_area_buffer[0]. If that is nil, choose a suitable buffer
10512 from echo_buffer[] and clear it.
10514 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
10515 suitable buffer from echo_buffer[] and clear it.
10517 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
10518 that the current message becomes the last displayed one, make
10519 choose a suitable buffer for echo_area_buffer[0], and clear it.
10521 Value is what FN returns. */
10523 static int
10524 with_echo_area_buffer (struct window *w, int which,
10525 int (*fn) (ptrdiff_t, Lisp_Object),
10526 ptrdiff_t a1, Lisp_Object a2)
10528 Lisp_Object buffer;
10529 int this_one, the_other, clear_buffer_p, rc;
10530 ptrdiff_t count = SPECPDL_INDEX ();
10532 /* If buffers aren't live, make new ones. */
10533 ensure_echo_area_buffers ();
10535 clear_buffer_p = 0;
10537 if (which == 0)
10538 this_one = 0, the_other = 1;
10539 else if (which > 0)
10540 this_one = 1, the_other = 0;
10541 else
10543 this_one = 0, the_other = 1;
10544 clear_buffer_p = true;
10546 /* We need a fresh one in case the current echo buffer equals
10547 the one containing the last displayed echo area message. */
10548 if (!NILP (echo_area_buffer[this_one])
10549 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
10550 echo_area_buffer[this_one] = Qnil;
10553 /* Choose a suitable buffer from echo_buffer[] is we don't
10554 have one. */
10555 if (NILP (echo_area_buffer[this_one]))
10557 echo_area_buffer[this_one]
10558 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
10559 ? echo_buffer[the_other]
10560 : echo_buffer[this_one]);
10561 clear_buffer_p = true;
10564 buffer = echo_area_buffer[this_one];
10566 /* Don't get confused by reusing the buffer used for echoing
10567 for a different purpose. */
10568 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
10569 cancel_echoing ();
10571 record_unwind_protect (unwind_with_echo_area_buffer,
10572 with_echo_area_buffer_unwind_data (w));
10574 /* Make the echo area buffer current. Note that for display
10575 purposes, it is not necessary that the displayed window's buffer
10576 == current_buffer, except for text property lookup. So, let's
10577 only set that buffer temporarily here without doing a full
10578 Fset_window_buffer. We must also change w->pointm, though,
10579 because otherwise an assertions in unshow_buffer fails, and Emacs
10580 aborts. */
10581 set_buffer_internal_1 (XBUFFER (buffer));
10582 if (w)
10584 wset_buffer (w, buffer);
10585 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
10586 set_marker_both (w->old_pointm, buffer, BEG, BEG_BYTE);
10589 bset_undo_list (current_buffer, Qt);
10590 bset_read_only (current_buffer, Qnil);
10591 specbind (Qinhibit_read_only, Qt);
10592 specbind (Qinhibit_modification_hooks, Qt);
10594 if (clear_buffer_p && Z > BEG)
10595 del_range (BEG, Z);
10597 eassert (BEGV >= BEG);
10598 eassert (ZV <= Z && ZV >= BEGV);
10600 rc = fn (a1, a2);
10602 eassert (BEGV >= BEG);
10603 eassert (ZV <= Z && ZV >= BEGV);
10605 unbind_to (count, Qnil);
10606 return rc;
10610 /* Save state that should be preserved around the call to the function
10611 FN called in with_echo_area_buffer. */
10613 static Lisp_Object
10614 with_echo_area_buffer_unwind_data (struct window *w)
10616 int i = 0;
10617 Lisp_Object vector, tmp;
10619 /* Reduce consing by keeping one vector in
10620 Vwith_echo_area_save_vector. */
10621 vector = Vwith_echo_area_save_vector;
10622 Vwith_echo_area_save_vector = Qnil;
10624 if (NILP (vector))
10625 vector = Fmake_vector (make_number (11), Qnil);
10627 XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
10628 ASET (vector, i, Vdeactivate_mark); ++i;
10629 ASET (vector, i, make_number (windows_or_buffers_changed)); ++i;
10631 if (w)
10633 XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i;
10634 ASET (vector, i, w->contents); ++i;
10635 ASET (vector, i, make_number (marker_position (w->pointm))); ++i;
10636 ASET (vector, i, make_number (marker_byte_position (w->pointm))); ++i;
10637 ASET (vector, i, make_number (marker_position (w->old_pointm))); ++i;
10638 ASET (vector, i, make_number (marker_byte_position (w->old_pointm))); ++i;
10639 ASET (vector, i, make_number (marker_position (w->start))); ++i;
10640 ASET (vector, i, make_number (marker_byte_position (w->start))); ++i;
10642 else
10644 int end = i + 8;
10645 for (; i < end; ++i)
10646 ASET (vector, i, Qnil);
10649 eassert (i == ASIZE (vector));
10650 return vector;
10654 /* Restore global state from VECTOR which was created by
10655 with_echo_area_buffer_unwind_data. */
10657 static void
10658 unwind_with_echo_area_buffer (Lisp_Object vector)
10660 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
10661 Vdeactivate_mark = AREF (vector, 1);
10662 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
10664 if (WINDOWP (AREF (vector, 3)))
10666 struct window *w;
10667 Lisp_Object buffer;
10669 w = XWINDOW (AREF (vector, 3));
10670 buffer = AREF (vector, 4);
10672 wset_buffer (w, buffer);
10673 set_marker_both (w->pointm, buffer,
10674 XFASTINT (AREF (vector, 5)),
10675 XFASTINT (AREF (vector, 6)));
10676 set_marker_both (w->old_pointm, buffer,
10677 XFASTINT (AREF (vector, 7)),
10678 XFASTINT (AREF (vector, 8)));
10679 set_marker_both (w->start, buffer,
10680 XFASTINT (AREF (vector, 9)),
10681 XFASTINT (AREF (vector, 10)));
10684 Vwith_echo_area_save_vector = vector;
10688 /* Set up the echo area for use by print functions. MULTIBYTE_P
10689 non-zero means we will print multibyte. */
10691 void
10692 setup_echo_area_for_printing (int multibyte_p)
10694 /* If we can't find an echo area any more, exit. */
10695 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
10696 Fkill_emacs (Qnil);
10698 ensure_echo_area_buffers ();
10700 if (!message_buf_print)
10702 /* A message has been output since the last time we printed.
10703 Choose a fresh echo area buffer. */
10704 if (EQ (echo_area_buffer[1], echo_buffer[0]))
10705 echo_area_buffer[0] = echo_buffer[1];
10706 else
10707 echo_area_buffer[0] = echo_buffer[0];
10709 /* Switch to that buffer and clear it. */
10710 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
10711 bset_truncate_lines (current_buffer, Qnil);
10713 if (Z > BEG)
10715 ptrdiff_t count = SPECPDL_INDEX ();
10716 specbind (Qinhibit_read_only, Qt);
10717 /* Note that undo recording is always disabled. */
10718 del_range (BEG, Z);
10719 unbind_to (count, Qnil);
10721 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
10723 /* Set up the buffer for the multibyteness we need. */
10724 if (multibyte_p
10725 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
10726 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
10728 /* Raise the frame containing the echo area. */
10729 if (minibuffer_auto_raise)
10731 struct frame *sf = SELECTED_FRAME ();
10732 Lisp_Object mini_window;
10733 mini_window = FRAME_MINIBUF_WINDOW (sf);
10734 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
10737 message_log_maybe_newline ();
10738 message_buf_print = 1;
10740 else
10742 if (NILP (echo_area_buffer[0]))
10744 if (EQ (echo_area_buffer[1], echo_buffer[0]))
10745 echo_area_buffer[0] = echo_buffer[1];
10746 else
10747 echo_area_buffer[0] = echo_buffer[0];
10750 if (current_buffer != XBUFFER (echo_area_buffer[0]))
10752 /* Someone switched buffers between print requests. */
10753 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
10754 bset_truncate_lines (current_buffer, Qnil);
10760 /* Display an echo area message in window W. Value is non-zero if W's
10761 height is changed. If display_last_displayed_message_p is
10762 non-zero, display the message that was last displayed, otherwise
10763 display the current message. */
10765 static int
10766 display_echo_area (struct window *w)
10768 int i, no_message_p, window_height_changed_p;
10770 /* Temporarily disable garbage collections while displaying the echo
10771 area. This is done because a GC can print a message itself.
10772 That message would modify the echo area buffer's contents while a
10773 redisplay of the buffer is going on, and seriously confuse
10774 redisplay. */
10775 ptrdiff_t count = inhibit_garbage_collection ();
10777 /* If there is no message, we must call display_echo_area_1
10778 nevertheless because it resizes the window. But we will have to
10779 reset the echo_area_buffer in question to nil at the end because
10780 with_echo_area_buffer will sets it to an empty buffer. */
10781 i = display_last_displayed_message_p ? 1 : 0;
10782 no_message_p = NILP (echo_area_buffer[i]);
10784 window_height_changed_p
10785 = with_echo_area_buffer (w, display_last_displayed_message_p,
10786 display_echo_area_1,
10787 (intptr_t) w, Qnil);
10789 if (no_message_p)
10790 echo_area_buffer[i] = Qnil;
10792 unbind_to (count, Qnil);
10793 return window_height_changed_p;
10797 /* Helper for display_echo_area. Display the current buffer which
10798 contains the current echo area message in window W, a mini-window,
10799 a pointer to which is passed in A1. A2..A4 are currently not used.
10800 Change the height of W so that all of the message is displayed.
10801 Value is non-zero if height of W was changed. */
10803 static int
10804 display_echo_area_1 (ptrdiff_t a1, Lisp_Object a2)
10806 intptr_t i1 = a1;
10807 struct window *w = (struct window *) i1;
10808 Lisp_Object window;
10809 struct text_pos start;
10810 int window_height_changed_p = 0;
10812 /* Do this before displaying, so that we have a large enough glyph
10813 matrix for the display. If we can't get enough space for the
10814 whole text, display the last N lines. That works by setting w->start. */
10815 window_height_changed_p = resize_mini_window (w, 0);
10817 /* Use the starting position chosen by resize_mini_window. */
10818 SET_TEXT_POS_FROM_MARKER (start, w->start);
10820 /* Display. */
10821 clear_glyph_matrix (w->desired_matrix);
10822 XSETWINDOW (window, w);
10823 try_window (window, start, 0);
10825 return window_height_changed_p;
10829 /* Resize the echo area window to exactly the size needed for the
10830 currently displayed message, if there is one. If a mini-buffer
10831 is active, don't shrink it. */
10833 void
10834 resize_echo_area_exactly (void)
10836 if (BUFFERP (echo_area_buffer[0])
10837 && WINDOWP (echo_area_window))
10839 struct window *w = XWINDOW (echo_area_window);
10840 Lisp_Object resize_exactly = (minibuf_level == 0 ? Qt : Qnil);
10841 int resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
10842 (intptr_t) w, resize_exactly);
10843 if (resized_p)
10845 windows_or_buffers_changed = 42;
10846 update_mode_lines = 30;
10847 redisplay_internal ();
10853 /* Callback function for with_echo_area_buffer, when used from
10854 resize_echo_area_exactly. A1 contains a pointer to the window to
10855 resize, EXACTLY non-nil means resize the mini-window exactly to the
10856 size of the text displayed. A3 and A4 are not used. Value is what
10857 resize_mini_window returns. */
10859 static int
10860 resize_mini_window_1 (ptrdiff_t a1, Lisp_Object exactly)
10862 intptr_t i1 = a1;
10863 return resize_mini_window ((struct window *) i1, !NILP (exactly));
10867 /* Resize mini-window W to fit the size of its contents. EXACT_P
10868 means size the window exactly to the size needed. Otherwise, it's
10869 only enlarged until W's buffer is empty.
10871 Set W->start to the right place to begin display. If the whole
10872 contents fit, start at the beginning. Otherwise, start so as
10873 to make the end of the contents appear. This is particularly
10874 important for y-or-n-p, but seems desirable generally.
10876 Value is non-zero if the window height has been changed. */
10879 resize_mini_window (struct window *w, int exact_p)
10881 struct frame *f = XFRAME (w->frame);
10882 int window_height_changed_p = 0;
10884 eassert (MINI_WINDOW_P (w));
10886 /* By default, start display at the beginning. */
10887 set_marker_both (w->start, w->contents,
10888 BUF_BEGV (XBUFFER (w->contents)),
10889 BUF_BEGV_BYTE (XBUFFER (w->contents)));
10891 /* Don't resize windows while redisplaying a window; it would
10892 confuse redisplay functions when the size of the window they are
10893 displaying changes from under them. Such a resizing can happen,
10894 for instance, when which-func prints a long message while
10895 we are running fontification-functions. We're running these
10896 functions with safe_call which binds inhibit-redisplay to t. */
10897 if (!NILP (Vinhibit_redisplay))
10898 return 0;
10900 /* Nil means don't try to resize. */
10901 if (NILP (Vresize_mini_windows)
10902 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
10903 return 0;
10905 if (!FRAME_MINIBUF_ONLY_P (f))
10907 struct it it;
10908 int total_height = (WINDOW_PIXEL_HEIGHT (XWINDOW (FRAME_ROOT_WINDOW (f)))
10909 + WINDOW_PIXEL_HEIGHT (w));
10910 int unit = FRAME_LINE_HEIGHT (f);
10911 int height, max_height;
10912 struct text_pos start;
10913 struct buffer *old_current_buffer = NULL;
10915 if (current_buffer != XBUFFER (w->contents))
10917 old_current_buffer = current_buffer;
10918 set_buffer_internal (XBUFFER (w->contents));
10921 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
10923 /* Compute the max. number of lines specified by the user. */
10924 if (FLOATP (Vmax_mini_window_height))
10925 max_height = XFLOATINT (Vmax_mini_window_height) * total_height;
10926 else if (INTEGERP (Vmax_mini_window_height))
10927 max_height = XINT (Vmax_mini_window_height) * unit;
10928 else
10929 max_height = total_height / 4;
10931 /* Correct that max. height if it's bogus. */
10932 max_height = clip_to_bounds (unit, max_height, total_height);
10934 /* Find out the height of the text in the window. */
10935 if (it.line_wrap == TRUNCATE)
10936 height = unit;
10937 else
10939 last_height = 0;
10940 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
10941 if (it.max_ascent == 0 && it.max_descent == 0)
10942 height = it.current_y + last_height;
10943 else
10944 height = it.current_y + it.max_ascent + it.max_descent;
10945 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
10948 /* Compute a suitable window start. */
10949 if (height > max_height)
10951 height = (max_height / unit) * unit;
10952 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
10953 move_it_vertically_backward (&it, height - unit);
10954 start = it.current.pos;
10956 else
10957 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
10958 SET_MARKER_FROM_TEXT_POS (w->start, start);
10960 if (EQ (Vresize_mini_windows, Qgrow_only))
10962 /* Let it grow only, until we display an empty message, in which
10963 case the window shrinks again. */
10964 if (height > WINDOW_PIXEL_HEIGHT (w))
10966 int old_height = WINDOW_PIXEL_HEIGHT (w);
10968 FRAME_WINDOWS_FROZEN (f) = 1;
10969 grow_mini_window (w, height - WINDOW_PIXEL_HEIGHT (w), 1);
10970 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
10972 else if (height < WINDOW_PIXEL_HEIGHT (w)
10973 && (exact_p || BEGV == ZV))
10975 int old_height = WINDOW_PIXEL_HEIGHT (w);
10977 FRAME_WINDOWS_FROZEN (f) = 0;
10978 shrink_mini_window (w, 1);
10979 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
10982 else
10984 /* Always resize to exact size needed. */
10985 if (height > WINDOW_PIXEL_HEIGHT (w))
10987 int old_height = WINDOW_PIXEL_HEIGHT (w);
10989 FRAME_WINDOWS_FROZEN (f) = 1;
10990 grow_mini_window (w, height - WINDOW_PIXEL_HEIGHT (w), 1);
10991 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
10993 else if (height < WINDOW_PIXEL_HEIGHT (w))
10995 int old_height = WINDOW_PIXEL_HEIGHT (w);
10997 FRAME_WINDOWS_FROZEN (f) = 0;
10998 shrink_mini_window (w, 1);
11000 if (height)
11002 FRAME_WINDOWS_FROZEN (f) = 1;
11003 grow_mini_window (w, height - WINDOW_PIXEL_HEIGHT (w), 1);
11006 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
11010 if (old_current_buffer)
11011 set_buffer_internal (old_current_buffer);
11014 return window_height_changed_p;
11018 /* Value is the current message, a string, or nil if there is no
11019 current message. */
11021 Lisp_Object
11022 current_message (void)
11024 Lisp_Object msg;
11026 if (!BUFFERP (echo_area_buffer[0]))
11027 msg = Qnil;
11028 else
11030 with_echo_area_buffer (0, 0, current_message_1,
11031 (intptr_t) &msg, Qnil);
11032 if (NILP (msg))
11033 echo_area_buffer[0] = Qnil;
11036 return msg;
11040 static int
11041 current_message_1 (ptrdiff_t a1, Lisp_Object a2)
11043 intptr_t i1 = a1;
11044 Lisp_Object *msg = (Lisp_Object *) i1;
11046 if (Z > BEG)
11047 *msg = make_buffer_string (BEG, Z, 1);
11048 else
11049 *msg = Qnil;
11050 return 0;
11054 /* Push the current message on Vmessage_stack for later restoration
11055 by restore_message. Value is non-zero if the current message isn't
11056 empty. This is a relatively infrequent operation, so it's not
11057 worth optimizing. */
11059 bool
11060 push_message (void)
11062 Lisp_Object msg = current_message ();
11063 Vmessage_stack = Fcons (msg, Vmessage_stack);
11064 return STRINGP (msg);
11068 /* Restore message display from the top of Vmessage_stack. */
11070 void
11071 restore_message (void)
11073 eassert (CONSP (Vmessage_stack));
11074 message3_nolog (XCAR (Vmessage_stack));
11078 /* Handler for unwind-protect calling pop_message. */
11080 void
11081 pop_message_unwind (void)
11083 /* Pop the top-most entry off Vmessage_stack. */
11084 eassert (CONSP (Vmessage_stack));
11085 Vmessage_stack = XCDR (Vmessage_stack);
11089 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
11090 exits. If the stack is not empty, we have a missing pop_message
11091 somewhere. */
11093 void
11094 check_message_stack (void)
11096 if (!NILP (Vmessage_stack))
11097 emacs_abort ();
11101 /* Truncate to NCHARS what will be displayed in the echo area the next
11102 time we display it---but don't redisplay it now. */
11104 void
11105 truncate_echo_area (ptrdiff_t nchars)
11107 if (nchars == 0)
11108 echo_area_buffer[0] = Qnil;
11109 else if (!noninteractive
11110 && INTERACTIVE
11111 && !NILP (echo_area_buffer[0]))
11113 struct frame *sf = SELECTED_FRAME ();
11114 /* Error messages get reported properly by cmd_error, so this must be
11115 just an informative message; if the frame hasn't really been
11116 initialized yet, just toss it. */
11117 if (sf->glyphs_initialized_p)
11118 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil);
11123 /* Helper function for truncate_echo_area. Truncate the current
11124 message to at most NCHARS characters. */
11126 static int
11127 truncate_message_1 (ptrdiff_t nchars, Lisp_Object a2)
11129 if (BEG + nchars < Z)
11130 del_range (BEG + nchars, Z);
11131 if (Z == BEG)
11132 echo_area_buffer[0] = Qnil;
11133 return 0;
11136 /* Set the current message to STRING. */
11138 static void
11139 set_message (Lisp_Object string)
11141 eassert (STRINGP (string));
11143 message_enable_multibyte = STRING_MULTIBYTE (string);
11145 with_echo_area_buffer (0, -1, set_message_1, 0, string);
11146 message_buf_print = 0;
11147 help_echo_showing_p = 0;
11149 if (STRINGP (Vdebug_on_message)
11150 && STRINGP (string)
11151 && fast_string_match (Vdebug_on_message, string) >= 0)
11152 call_debugger (list2 (Qerror, string));
11156 /* Helper function for set_message. First argument is ignored and second
11157 argument has the same meaning as for set_message.
11158 This function is called with the echo area buffer being current. */
11160 static int
11161 set_message_1 (ptrdiff_t a1, Lisp_Object string)
11163 eassert (STRINGP (string));
11165 /* Change multibyteness of the echo buffer appropriately. */
11166 if (message_enable_multibyte
11167 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
11168 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
11170 bset_truncate_lines (current_buffer, message_truncate_lines ? Qt : Qnil);
11171 if (!NILP (BVAR (current_buffer, bidi_display_reordering)))
11172 bset_bidi_paragraph_direction (current_buffer, Qleft_to_right);
11174 /* Insert new message at BEG. */
11175 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
11177 /* This function takes care of single/multibyte conversion.
11178 We just have to ensure that the echo area buffer has the right
11179 setting of enable_multibyte_characters. */
11180 insert_from_string (string, 0, 0, SCHARS (string), SBYTES (string), 1);
11182 return 0;
11186 /* Clear messages. CURRENT_P non-zero means clear the current
11187 message. LAST_DISPLAYED_P non-zero means clear the message
11188 last displayed. */
11190 void
11191 clear_message (bool current_p, bool last_displayed_p)
11193 if (current_p)
11195 echo_area_buffer[0] = Qnil;
11196 message_cleared_p = true;
11199 if (last_displayed_p)
11200 echo_area_buffer[1] = Qnil;
11202 message_buf_print = 0;
11205 /* Clear garbaged frames.
11207 This function is used where the old redisplay called
11208 redraw_garbaged_frames which in turn called redraw_frame which in
11209 turn called clear_frame. The call to clear_frame was a source of
11210 flickering. I believe a clear_frame is not necessary. It should
11211 suffice in the new redisplay to invalidate all current matrices,
11212 and ensure a complete redisplay of all windows. */
11214 static void
11215 clear_garbaged_frames (void)
11217 if (frame_garbaged)
11219 Lisp_Object tail, frame;
11221 FOR_EACH_FRAME (tail, frame)
11223 struct frame *f = XFRAME (frame);
11225 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
11227 if (f->resized_p)
11228 redraw_frame (f);
11229 else
11230 clear_current_matrices (f);
11231 fset_redisplay (f);
11232 f->garbaged = false;
11233 f->resized_p = false;
11237 frame_garbaged = false;
11242 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
11243 is non-zero update selected_frame. Value is non-zero if the
11244 mini-windows height has been changed. */
11246 static int
11247 echo_area_display (int update_frame_p)
11249 Lisp_Object mini_window;
11250 struct window *w;
11251 struct frame *f;
11252 int window_height_changed_p = 0;
11253 struct frame *sf = SELECTED_FRAME ();
11255 mini_window = FRAME_MINIBUF_WINDOW (sf);
11256 w = XWINDOW (mini_window);
11257 f = XFRAME (WINDOW_FRAME (w));
11259 /* Don't display if frame is invisible or not yet initialized. */
11260 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
11261 return 0;
11263 #ifdef HAVE_WINDOW_SYSTEM
11264 /* When Emacs starts, selected_frame may be the initial terminal
11265 frame. If we let this through, a message would be displayed on
11266 the terminal. */
11267 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
11268 return 0;
11269 #endif /* HAVE_WINDOW_SYSTEM */
11271 /* Redraw garbaged frames. */
11272 clear_garbaged_frames ();
11274 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
11276 echo_area_window = mini_window;
11277 window_height_changed_p = display_echo_area (w);
11278 w->must_be_updated_p = true;
11280 /* Update the display, unless called from redisplay_internal.
11281 Also don't update the screen during redisplay itself. The
11282 update will happen at the end of redisplay, and an update
11283 here could cause confusion. */
11284 if (update_frame_p && !redisplaying_p)
11286 int n = 0;
11288 /* If the display update has been interrupted by pending
11289 input, update mode lines in the frame. Due to the
11290 pending input, it might have been that redisplay hasn't
11291 been called, so that mode lines above the echo area are
11292 garbaged. This looks odd, so we prevent it here. */
11293 if (!display_completed)
11294 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), false);
11296 if (window_height_changed_p
11297 /* Don't do this if Emacs is shutting down. Redisplay
11298 needs to run hooks. */
11299 && !NILP (Vrun_hooks))
11301 /* Must update other windows. Likewise as in other
11302 cases, don't let this update be interrupted by
11303 pending input. */
11304 ptrdiff_t count = SPECPDL_INDEX ();
11305 specbind (Qredisplay_dont_pause, Qt);
11306 windows_or_buffers_changed = 44;
11307 redisplay_internal ();
11308 unbind_to (count, Qnil);
11310 else if (FRAME_WINDOW_P (f) && n == 0)
11312 /* Window configuration is the same as before.
11313 Can do with a display update of the echo area,
11314 unless we displayed some mode lines. */
11315 update_single_window (w, 1);
11316 flush_frame (f);
11318 else
11319 update_frame (f, 1, 1);
11321 /* If cursor is in the echo area, make sure that the next
11322 redisplay displays the minibuffer, so that the cursor will
11323 be replaced with what the minibuffer wants. */
11324 if (cursor_in_echo_area)
11325 wset_redisplay (XWINDOW (mini_window));
11328 else if (!EQ (mini_window, selected_window))
11329 wset_redisplay (XWINDOW (mini_window));
11331 /* Last displayed message is now the current message. */
11332 echo_area_buffer[1] = echo_area_buffer[0];
11333 /* Inform read_char that we're not echoing. */
11334 echo_message_buffer = Qnil;
11336 /* Prevent redisplay optimization in redisplay_internal by resetting
11337 this_line_start_pos. This is done because the mini-buffer now
11338 displays the message instead of its buffer text. */
11339 if (EQ (mini_window, selected_window))
11340 CHARPOS (this_line_start_pos) = 0;
11342 return window_height_changed_p;
11345 /* Nonzero if W's buffer was changed but not saved. */
11347 static int
11348 window_buffer_changed (struct window *w)
11350 struct buffer *b = XBUFFER (w->contents);
11352 eassert (BUFFER_LIVE_P (b));
11354 return (((BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) != w->last_had_star));
11357 /* Nonzero if W has %c in its mode line and mode line should be updated. */
11359 static int
11360 mode_line_update_needed (struct window *w)
11362 return (w->column_number_displayed != -1
11363 && !(PT == w->last_point && !window_outdated (w))
11364 && (w->column_number_displayed != current_column ()));
11367 /* Nonzero if window start of W is frozen and may not be changed during
11368 redisplay. */
11370 static bool
11371 window_frozen_p (struct window *w)
11373 if (FRAME_WINDOWS_FROZEN (XFRAME (WINDOW_FRAME (w))))
11375 Lisp_Object window;
11377 XSETWINDOW (window, w);
11378 if (MINI_WINDOW_P (w))
11379 return 0;
11380 else if (EQ (window, selected_window))
11381 return 0;
11382 else if (MINI_WINDOW_P (XWINDOW (selected_window))
11383 && EQ (window, Vminibuf_scroll_window))
11384 /* This special window can't be frozen too. */
11385 return 0;
11386 else
11387 return 1;
11389 return 0;
11392 /***********************************************************************
11393 Mode Lines and Frame Titles
11394 ***********************************************************************/
11396 /* A buffer for constructing non-propertized mode-line strings and
11397 frame titles in it; allocated from the heap in init_xdisp and
11398 resized as needed in store_mode_line_noprop_char. */
11400 static char *mode_line_noprop_buf;
11402 /* The buffer's end, and a current output position in it. */
11404 static char *mode_line_noprop_buf_end;
11405 static char *mode_line_noprop_ptr;
11407 #define MODE_LINE_NOPROP_LEN(start) \
11408 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
11410 static enum {
11411 MODE_LINE_DISPLAY = 0,
11412 MODE_LINE_TITLE,
11413 MODE_LINE_NOPROP,
11414 MODE_LINE_STRING
11415 } mode_line_target;
11417 /* Alist that caches the results of :propertize.
11418 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
11419 static Lisp_Object mode_line_proptrans_alist;
11421 /* List of strings making up the mode-line. */
11422 static Lisp_Object mode_line_string_list;
11424 /* Base face property when building propertized mode line string. */
11425 static Lisp_Object mode_line_string_face;
11426 static Lisp_Object mode_line_string_face_prop;
11429 /* Unwind data for mode line strings */
11431 static Lisp_Object Vmode_line_unwind_vector;
11433 static Lisp_Object
11434 format_mode_line_unwind_data (struct frame *target_frame,
11435 struct buffer *obuf,
11436 Lisp_Object owin,
11437 int save_proptrans)
11439 Lisp_Object vector, tmp;
11441 /* Reduce consing by keeping one vector in
11442 Vwith_echo_area_save_vector. */
11443 vector = Vmode_line_unwind_vector;
11444 Vmode_line_unwind_vector = Qnil;
11446 if (NILP (vector))
11447 vector = Fmake_vector (make_number (10), Qnil);
11449 ASET (vector, 0, make_number (mode_line_target));
11450 ASET (vector, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
11451 ASET (vector, 2, mode_line_string_list);
11452 ASET (vector, 3, save_proptrans ? mode_line_proptrans_alist : Qt);
11453 ASET (vector, 4, mode_line_string_face);
11454 ASET (vector, 5, mode_line_string_face_prop);
11456 if (obuf)
11457 XSETBUFFER (tmp, obuf);
11458 else
11459 tmp = Qnil;
11460 ASET (vector, 6, tmp);
11461 ASET (vector, 7, owin);
11462 if (target_frame)
11464 /* Similarly to `with-selected-window', if the operation selects
11465 a window on another frame, we must restore that frame's
11466 selected window, and (for a tty) the top-frame. */
11467 ASET (vector, 8, target_frame->selected_window);
11468 if (FRAME_TERMCAP_P (target_frame))
11469 ASET (vector, 9, FRAME_TTY (target_frame)->top_frame);
11472 return vector;
11475 static void
11476 unwind_format_mode_line (Lisp_Object vector)
11478 Lisp_Object old_window = AREF (vector, 7);
11479 Lisp_Object target_frame_window = AREF (vector, 8);
11480 Lisp_Object old_top_frame = AREF (vector, 9);
11482 mode_line_target = XINT (AREF (vector, 0));
11483 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
11484 mode_line_string_list = AREF (vector, 2);
11485 if (! EQ (AREF (vector, 3), Qt))
11486 mode_line_proptrans_alist = AREF (vector, 3);
11487 mode_line_string_face = AREF (vector, 4);
11488 mode_line_string_face_prop = AREF (vector, 5);
11490 /* Select window before buffer, since it may change the buffer. */
11491 if (!NILP (old_window))
11493 /* If the operation that we are unwinding had selected a window
11494 on a different frame, reset its frame-selected-window. For a
11495 text terminal, reset its top-frame if necessary. */
11496 if (!NILP (target_frame_window))
11498 Lisp_Object frame
11499 = WINDOW_FRAME (XWINDOW (target_frame_window));
11501 if (!EQ (frame, WINDOW_FRAME (XWINDOW (old_window))))
11502 Fselect_window (target_frame_window, Qt);
11504 if (!NILP (old_top_frame) && !EQ (old_top_frame, frame))
11505 Fselect_frame (old_top_frame, Qt);
11508 Fselect_window (old_window, Qt);
11511 if (!NILP (AREF (vector, 6)))
11513 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
11514 ASET (vector, 6, Qnil);
11517 Vmode_line_unwind_vector = vector;
11521 /* Store a single character C for the frame title in mode_line_noprop_buf.
11522 Re-allocate mode_line_noprop_buf if necessary. */
11524 static void
11525 store_mode_line_noprop_char (char c)
11527 /* If output position has reached the end of the allocated buffer,
11528 increase the buffer's size. */
11529 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
11531 ptrdiff_t len = MODE_LINE_NOPROP_LEN (0);
11532 ptrdiff_t size = len;
11533 mode_line_noprop_buf =
11534 xpalloc (mode_line_noprop_buf, &size, 1, STRING_BYTES_BOUND, 1);
11535 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
11536 mode_line_noprop_ptr = mode_line_noprop_buf + len;
11539 *mode_line_noprop_ptr++ = c;
11543 /* Store part of a frame title in mode_line_noprop_buf, beginning at
11544 mode_line_noprop_ptr. STRING is the string to store. Do not copy
11545 characters that yield more columns than PRECISION; PRECISION <= 0
11546 means copy the whole string. Pad with spaces until FIELD_WIDTH
11547 number of characters have been copied; FIELD_WIDTH <= 0 means don't
11548 pad. Called from display_mode_element when it is used to build a
11549 frame title. */
11551 static int
11552 store_mode_line_noprop (const char *string, int field_width, int precision)
11554 const unsigned char *str = (const unsigned char *) string;
11555 int n = 0;
11556 ptrdiff_t dummy, nbytes;
11558 /* Copy at most PRECISION chars from STR. */
11559 nbytes = strlen (string);
11560 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
11561 while (nbytes--)
11562 store_mode_line_noprop_char (*str++);
11564 /* Fill up with spaces until FIELD_WIDTH reached. */
11565 while (field_width > 0
11566 && n < field_width)
11568 store_mode_line_noprop_char (' ');
11569 ++n;
11572 return n;
11575 /***********************************************************************
11576 Frame Titles
11577 ***********************************************************************/
11579 #ifdef HAVE_WINDOW_SYSTEM
11581 /* Set the title of FRAME, if it has changed. The title format is
11582 Vicon_title_format if FRAME is iconified, otherwise it is
11583 frame_title_format. */
11585 static void
11586 x_consider_frame_title (Lisp_Object frame)
11588 struct frame *f = XFRAME (frame);
11590 if (FRAME_WINDOW_P (f)
11591 || FRAME_MINIBUF_ONLY_P (f)
11592 || f->explicit_name)
11594 /* Do we have more than one visible frame on this X display? */
11595 Lisp_Object tail, other_frame, fmt;
11596 ptrdiff_t title_start;
11597 char *title;
11598 ptrdiff_t len;
11599 struct it it;
11600 ptrdiff_t count = SPECPDL_INDEX ();
11602 FOR_EACH_FRAME (tail, other_frame)
11604 struct frame *tf = XFRAME (other_frame);
11606 if (tf != f
11607 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
11608 && !FRAME_MINIBUF_ONLY_P (tf)
11609 && !EQ (other_frame, tip_frame)
11610 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
11611 break;
11614 /* Set global variable indicating that multiple frames exist. */
11615 multiple_frames = CONSP (tail);
11617 /* Switch to the buffer of selected window of the frame. Set up
11618 mode_line_target so that display_mode_element will output into
11619 mode_line_noprop_buf; then display the title. */
11620 record_unwind_protect (unwind_format_mode_line,
11621 format_mode_line_unwind_data
11622 (f, current_buffer, selected_window, 0));
11624 Fselect_window (f->selected_window, Qt);
11625 set_buffer_internal_1
11626 (XBUFFER (XWINDOW (f->selected_window)->contents));
11627 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
11629 mode_line_target = MODE_LINE_TITLE;
11630 title_start = MODE_LINE_NOPROP_LEN (0);
11631 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
11632 NULL, DEFAULT_FACE_ID);
11633 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
11634 len = MODE_LINE_NOPROP_LEN (title_start);
11635 title = mode_line_noprop_buf + title_start;
11636 unbind_to (count, Qnil);
11638 /* Set the title only if it's changed. This avoids consing in
11639 the common case where it hasn't. (If it turns out that we've
11640 already wasted too much time by walking through the list with
11641 display_mode_element, then we might need to optimize at a
11642 higher level than this.) */
11643 if (! STRINGP (f->name)
11644 || SBYTES (f->name) != len
11645 || memcmp (title, SDATA (f->name), len) != 0)
11646 x_implicitly_set_name (f, make_string (title, len), Qnil);
11650 #endif /* not HAVE_WINDOW_SYSTEM */
11653 /***********************************************************************
11654 Menu Bars
11655 ***********************************************************************/
11657 /* Non-zero if we will not redisplay all visible windows. */
11658 #define REDISPLAY_SOME_P() \
11659 ((windows_or_buffers_changed == 0 \
11660 || windows_or_buffers_changed == REDISPLAY_SOME) \
11661 && (update_mode_lines == 0 \
11662 || update_mode_lines == REDISPLAY_SOME))
11664 /* Prepare for redisplay by updating menu-bar item lists when
11665 appropriate. This can call eval. */
11667 static void
11668 prepare_menu_bars (void)
11670 bool all_windows = windows_or_buffers_changed || update_mode_lines;
11671 bool some_windows = REDISPLAY_SOME_P ();
11672 struct gcpro gcpro1, gcpro2;
11673 Lisp_Object tooltip_frame;
11675 #ifdef HAVE_WINDOW_SYSTEM
11676 tooltip_frame = tip_frame;
11677 #else
11678 tooltip_frame = Qnil;
11679 #endif
11681 if (FUNCTIONP (Vpre_redisplay_function))
11683 Lisp_Object windows = all_windows ? Qt : Qnil;
11684 if (all_windows && some_windows)
11686 Lisp_Object ws = window_list ();
11687 for (windows = Qnil; CONSP (ws); ws = XCDR (ws))
11689 Lisp_Object this = XCAR (ws);
11690 struct window *w = XWINDOW (this);
11691 if (w->redisplay
11692 || XFRAME (w->frame)->redisplay
11693 || XBUFFER (w->contents)->text->redisplay)
11695 windows = Fcons (this, windows);
11699 safe__call1 (true, Vpre_redisplay_function, windows);
11702 /* Update all frame titles based on their buffer names, etc. We do
11703 this before the menu bars so that the buffer-menu will show the
11704 up-to-date frame titles. */
11705 #ifdef HAVE_WINDOW_SYSTEM
11706 if (all_windows)
11708 Lisp_Object tail, frame;
11710 FOR_EACH_FRAME (tail, frame)
11712 struct frame *f = XFRAME (frame);
11713 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
11714 if (some_windows
11715 && !f->redisplay
11716 && !w->redisplay
11717 && !XBUFFER (w->contents)->text->redisplay)
11718 continue;
11720 if (!EQ (frame, tooltip_frame)
11721 && (FRAME_ICONIFIED_P (f)
11722 || FRAME_VISIBLE_P (f) == 1
11723 /* Exclude TTY frames that are obscured because they
11724 are not the top frame on their console. This is
11725 because x_consider_frame_title actually switches
11726 to the frame, which for TTY frames means it is
11727 marked as garbaged, and will be completely
11728 redrawn on the next redisplay cycle. This causes
11729 TTY frames to be completely redrawn, when there
11730 are more than one of them, even though nothing
11731 should be changed on display. */
11732 || (FRAME_VISIBLE_P (f) == 2 && FRAME_WINDOW_P (f))))
11733 x_consider_frame_title (frame);
11736 #endif /* HAVE_WINDOW_SYSTEM */
11738 /* Update the menu bar item lists, if appropriate. This has to be
11739 done before any actual redisplay or generation of display lines. */
11741 if (all_windows)
11743 Lisp_Object tail, frame;
11744 ptrdiff_t count = SPECPDL_INDEX ();
11745 /* 1 means that update_menu_bar has run its hooks
11746 so any further calls to update_menu_bar shouldn't do so again. */
11747 int menu_bar_hooks_run = 0;
11749 record_unwind_save_match_data ();
11751 FOR_EACH_FRAME (tail, frame)
11753 struct frame *f = XFRAME (frame);
11754 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
11756 /* Ignore tooltip frame. */
11757 if (EQ (frame, tooltip_frame))
11758 continue;
11760 if (some_windows
11761 && !f->redisplay
11762 && !w->redisplay
11763 && !XBUFFER (w->contents)->text->redisplay)
11764 continue;
11766 /* If a window on this frame changed size, report that to
11767 the user and clear the size-change flag. */
11768 if (FRAME_WINDOW_SIZES_CHANGED (f))
11770 Lisp_Object functions;
11772 /* Clear flag first in case we get an error below. */
11773 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
11774 functions = Vwindow_size_change_functions;
11775 GCPRO2 (tail, functions);
11777 while (CONSP (functions))
11779 if (!EQ (XCAR (functions), Qt))
11780 call1 (XCAR (functions), frame);
11781 functions = XCDR (functions);
11783 UNGCPRO;
11786 GCPRO1 (tail);
11787 menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
11788 #ifdef HAVE_WINDOW_SYSTEM
11789 update_tool_bar (f, 0);
11790 #endif
11791 #ifdef HAVE_NS
11792 if (windows_or_buffers_changed
11793 && FRAME_NS_P (f))
11794 ns_set_doc_edited
11795 (f, Fbuffer_modified_p (XWINDOW (f->selected_window)->contents));
11796 #endif
11797 UNGCPRO;
11800 unbind_to (count, Qnil);
11802 else
11804 struct frame *sf = SELECTED_FRAME ();
11805 update_menu_bar (sf, 1, 0);
11806 #ifdef HAVE_WINDOW_SYSTEM
11807 update_tool_bar (sf, 1);
11808 #endif
11813 /* Update the menu bar item list for frame F. This has to be done
11814 before we start to fill in any display lines, because it can call
11815 eval.
11817 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
11819 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
11820 already ran the menu bar hooks for this redisplay, so there
11821 is no need to run them again. The return value is the
11822 updated value of this flag, to pass to the next call. */
11824 static int
11825 update_menu_bar (struct frame *f, int save_match_data, int hooks_run)
11827 Lisp_Object window;
11828 register struct window *w;
11830 /* If called recursively during a menu update, do nothing. This can
11831 happen when, for instance, an activate-menubar-hook causes a
11832 redisplay. */
11833 if (inhibit_menubar_update)
11834 return hooks_run;
11836 window = FRAME_SELECTED_WINDOW (f);
11837 w = XWINDOW (window);
11839 if (FRAME_WINDOW_P (f)
11841 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11842 || defined (HAVE_NS) || defined (USE_GTK)
11843 FRAME_EXTERNAL_MENU_BAR (f)
11844 #else
11845 FRAME_MENU_BAR_LINES (f) > 0
11846 #endif
11847 : FRAME_MENU_BAR_LINES (f) > 0)
11849 /* If the user has switched buffers or windows, we need to
11850 recompute to reflect the new bindings. But we'll
11851 recompute when update_mode_lines is set too; that means
11852 that people can use force-mode-line-update to request
11853 that the menu bar be recomputed. The adverse effect on
11854 the rest of the redisplay algorithm is about the same as
11855 windows_or_buffers_changed anyway. */
11856 if (windows_or_buffers_changed
11857 /* This used to test w->update_mode_line, but we believe
11858 there is no need to recompute the menu in that case. */
11859 || update_mode_lines
11860 || window_buffer_changed (w))
11862 struct buffer *prev = current_buffer;
11863 ptrdiff_t count = SPECPDL_INDEX ();
11865 specbind (Qinhibit_menubar_update, Qt);
11867 set_buffer_internal_1 (XBUFFER (w->contents));
11868 if (save_match_data)
11869 record_unwind_save_match_data ();
11870 if (NILP (Voverriding_local_map_menu_flag))
11872 specbind (Qoverriding_terminal_local_map, Qnil);
11873 specbind (Qoverriding_local_map, Qnil);
11876 if (!hooks_run)
11878 /* Run the Lucid hook. */
11879 safe_run_hooks (Qactivate_menubar_hook);
11881 /* If it has changed current-menubar from previous value,
11882 really recompute the menu-bar from the value. */
11883 if (! NILP (Vlucid_menu_bar_dirty_flag))
11884 call0 (Qrecompute_lucid_menubar);
11886 safe_run_hooks (Qmenu_bar_update_hook);
11888 hooks_run = 1;
11891 XSETFRAME (Vmenu_updating_frame, f);
11892 fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f)));
11894 /* Redisplay the menu bar in case we changed it. */
11895 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11896 || defined (HAVE_NS) || defined (USE_GTK)
11897 if (FRAME_WINDOW_P (f))
11899 #if defined (HAVE_NS)
11900 /* All frames on Mac OS share the same menubar. So only
11901 the selected frame should be allowed to set it. */
11902 if (f == SELECTED_FRAME ())
11903 #endif
11904 set_frame_menubar (f, 0, 0);
11906 else
11907 /* On a terminal screen, the menu bar is an ordinary screen
11908 line, and this makes it get updated. */
11909 w->update_mode_line = 1;
11910 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11911 /* In the non-toolkit version, the menu bar is an ordinary screen
11912 line, and this makes it get updated. */
11913 w->update_mode_line = 1;
11914 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11916 unbind_to (count, Qnil);
11917 set_buffer_internal_1 (prev);
11921 return hooks_run;
11924 /***********************************************************************
11925 Tool-bars
11926 ***********************************************************************/
11928 #ifdef HAVE_WINDOW_SYSTEM
11930 /* Select `frame' temporarily without running all the code in
11931 do_switch_frame.
11932 FIXME: Maybe do_switch_frame should be trimmed down similarly
11933 when `norecord' is set. */
11934 static void
11935 fast_set_selected_frame (Lisp_Object frame)
11937 if (!EQ (selected_frame, frame))
11939 selected_frame = frame;
11940 selected_window = XFRAME (frame)->selected_window;
11944 /* Update the tool-bar item list for frame F. This has to be done
11945 before we start to fill in any display lines. Called from
11946 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
11947 and restore it here. */
11949 static void
11950 update_tool_bar (struct frame *f, int save_match_data)
11952 #if defined (USE_GTK) || defined (HAVE_NS)
11953 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
11954 #else
11955 int do_update = (WINDOWP (f->tool_bar_window)
11956 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0);
11957 #endif
11959 if (do_update)
11961 Lisp_Object window;
11962 struct window *w;
11964 window = FRAME_SELECTED_WINDOW (f);
11965 w = XWINDOW (window);
11967 /* If the user has switched buffers or windows, we need to
11968 recompute to reflect the new bindings. But we'll
11969 recompute when update_mode_lines is set too; that means
11970 that people can use force-mode-line-update to request
11971 that the menu bar be recomputed. The adverse effect on
11972 the rest of the redisplay algorithm is about the same as
11973 windows_or_buffers_changed anyway. */
11974 if (windows_or_buffers_changed
11975 || w->update_mode_line
11976 || update_mode_lines
11977 || window_buffer_changed (w))
11979 struct buffer *prev = current_buffer;
11980 ptrdiff_t count = SPECPDL_INDEX ();
11981 Lisp_Object frame, new_tool_bar;
11982 int new_n_tool_bar;
11983 struct gcpro gcpro1;
11985 /* Set current_buffer to the buffer of the selected
11986 window of the frame, so that we get the right local
11987 keymaps. */
11988 set_buffer_internal_1 (XBUFFER (w->contents));
11990 /* Save match data, if we must. */
11991 if (save_match_data)
11992 record_unwind_save_match_data ();
11994 /* Make sure that we don't accidentally use bogus keymaps. */
11995 if (NILP (Voverriding_local_map_menu_flag))
11997 specbind (Qoverriding_terminal_local_map, Qnil);
11998 specbind (Qoverriding_local_map, Qnil);
12001 GCPRO1 (new_tool_bar);
12003 /* We must temporarily set the selected frame to this frame
12004 before calling tool_bar_items, because the calculation of
12005 the tool-bar keymap uses the selected frame (see
12006 `tool-bar-make-keymap' in tool-bar.el). */
12007 eassert (EQ (selected_window,
12008 /* Since we only explicitly preserve selected_frame,
12009 check that selected_window would be redundant. */
12010 XFRAME (selected_frame)->selected_window));
12011 record_unwind_protect (fast_set_selected_frame, selected_frame);
12012 XSETFRAME (frame, f);
12013 fast_set_selected_frame (frame);
12015 /* Build desired tool-bar items from keymaps. */
12016 new_tool_bar
12017 = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
12018 &new_n_tool_bar);
12020 /* Redisplay the tool-bar if we changed it. */
12021 if (new_n_tool_bar != f->n_tool_bar_items
12022 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
12024 /* Redisplay that happens asynchronously due to an expose event
12025 may access f->tool_bar_items. Make sure we update both
12026 variables within BLOCK_INPUT so no such event interrupts. */
12027 block_input ();
12028 fset_tool_bar_items (f, new_tool_bar);
12029 f->n_tool_bar_items = new_n_tool_bar;
12030 w->update_mode_line = 1;
12031 unblock_input ();
12034 UNGCPRO;
12036 unbind_to (count, Qnil);
12037 set_buffer_internal_1 (prev);
12042 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
12044 /* Set F->desired_tool_bar_string to a Lisp string representing frame
12045 F's desired tool-bar contents. F->tool_bar_items must have
12046 been set up previously by calling prepare_menu_bars. */
12048 static void
12049 build_desired_tool_bar_string (struct frame *f)
12051 int i, size, size_needed;
12052 struct gcpro gcpro1, gcpro2;
12053 Lisp_Object image, plist;
12055 image = plist = Qnil;
12056 GCPRO2 (image, plist);
12058 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
12059 Otherwise, make a new string. */
12061 /* The size of the string we might be able to reuse. */
12062 size = (STRINGP (f->desired_tool_bar_string)
12063 ? SCHARS (f->desired_tool_bar_string)
12064 : 0);
12066 /* We need one space in the string for each image. */
12067 size_needed = f->n_tool_bar_items;
12069 /* Reuse f->desired_tool_bar_string, if possible. */
12070 if (size < size_needed || NILP (f->desired_tool_bar_string))
12071 fset_desired_tool_bar_string
12072 (f, Fmake_string (make_number (size_needed), make_number (' ')));
12073 else
12075 AUTO_LIST4 (props, Qdisplay, Qnil, Qmenu_item, Qnil);
12076 struct gcpro gcpro1;
12077 GCPRO1 (props);
12078 Fremove_text_properties (make_number (0), make_number (size),
12079 props, f->desired_tool_bar_string);
12080 UNGCPRO;
12083 /* Put a `display' property on the string for the images to display,
12084 put a `menu_item' property on tool-bar items with a value that
12085 is the index of the item in F's tool-bar item vector. */
12086 for (i = 0; i < f->n_tool_bar_items; ++i)
12088 #define PROP(IDX) \
12089 AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
12091 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
12092 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
12093 int hmargin, vmargin, relief, idx, end;
12095 /* If image is a vector, choose the image according to the
12096 button state. */
12097 image = PROP (TOOL_BAR_ITEM_IMAGES);
12098 if (VECTORP (image))
12100 if (enabled_p)
12101 idx = (selected_p
12102 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
12103 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
12104 else
12105 idx = (selected_p
12106 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
12107 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
12109 eassert (ASIZE (image) >= idx);
12110 image = AREF (image, idx);
12112 else
12113 idx = -1;
12115 /* Ignore invalid image specifications. */
12116 if (!valid_image_p (image))
12117 continue;
12119 /* Display the tool-bar button pressed, or depressed. */
12120 plist = Fcopy_sequence (XCDR (image));
12122 /* Compute margin and relief to draw. */
12123 relief = (tool_bar_button_relief >= 0
12124 ? tool_bar_button_relief
12125 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
12126 hmargin = vmargin = relief;
12128 if (RANGED_INTEGERP (1, Vtool_bar_button_margin,
12129 INT_MAX - max (hmargin, vmargin)))
12131 hmargin += XFASTINT (Vtool_bar_button_margin);
12132 vmargin += XFASTINT (Vtool_bar_button_margin);
12134 else if (CONSP (Vtool_bar_button_margin))
12136 if (RANGED_INTEGERP (1, XCAR (Vtool_bar_button_margin),
12137 INT_MAX - hmargin))
12138 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
12140 if (RANGED_INTEGERP (1, XCDR (Vtool_bar_button_margin),
12141 INT_MAX - vmargin))
12142 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
12145 if (auto_raise_tool_bar_buttons_p)
12147 /* Add a `:relief' property to the image spec if the item is
12148 selected. */
12149 if (selected_p)
12151 plist = Fplist_put (plist, QCrelief, make_number (-relief));
12152 hmargin -= relief;
12153 vmargin -= relief;
12156 else
12158 /* If image is selected, display it pressed, i.e. with a
12159 negative relief. If it's not selected, display it with a
12160 raised relief. */
12161 plist = Fplist_put (plist, QCrelief,
12162 (selected_p
12163 ? make_number (-relief)
12164 : make_number (relief)));
12165 hmargin -= relief;
12166 vmargin -= relief;
12169 /* Put a margin around the image. */
12170 if (hmargin || vmargin)
12172 if (hmargin == vmargin)
12173 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
12174 else
12175 plist = Fplist_put (plist, QCmargin,
12176 Fcons (make_number (hmargin),
12177 make_number (vmargin)));
12180 /* If button is not enabled, and we don't have special images
12181 for the disabled state, make the image appear disabled by
12182 applying an appropriate algorithm to it. */
12183 if (!enabled_p && idx < 0)
12184 plist = Fplist_put (plist, QCconversion, Qdisabled);
12186 /* Put a `display' text property on the string for the image to
12187 display. Put a `menu-item' property on the string that gives
12188 the start of this item's properties in the tool-bar items
12189 vector. */
12190 image = Fcons (Qimage, plist);
12191 AUTO_LIST4 (props, Qdisplay, image, Qmenu_item,
12192 make_number (i * TOOL_BAR_ITEM_NSLOTS));
12193 struct gcpro gcpro1;
12194 GCPRO1 (props);
12196 /* Let the last image hide all remaining spaces in the tool bar
12197 string. The string can be longer than needed when we reuse a
12198 previous string. */
12199 if (i + 1 == f->n_tool_bar_items)
12200 end = SCHARS (f->desired_tool_bar_string);
12201 else
12202 end = i + 1;
12203 Fadd_text_properties (make_number (i), make_number (end),
12204 props, f->desired_tool_bar_string);
12205 UNGCPRO;
12206 #undef PROP
12209 UNGCPRO;
12213 /* Display one line of the tool-bar of frame IT->f.
12215 HEIGHT specifies the desired height of the tool-bar line.
12216 If the actual height of the glyph row is less than HEIGHT, the
12217 row's height is increased to HEIGHT, and the icons are centered
12218 vertically in the new height.
12220 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
12221 count a final empty row in case the tool-bar width exactly matches
12222 the window width.
12225 static void
12226 display_tool_bar_line (struct it *it, int height)
12228 struct glyph_row *row = it->glyph_row;
12229 int max_x = it->last_visible_x;
12230 struct glyph *last;
12232 /* Don't extend on a previously drawn tool bar items (Bug#16058). */
12233 clear_glyph_row (row);
12234 row->enabled_p = true;
12235 row->y = it->current_y;
12237 /* Note that this isn't made use of if the face hasn't a box,
12238 so there's no need to check the face here. */
12239 it->start_of_box_run_p = 1;
12241 while (it->current_x < max_x)
12243 int x, n_glyphs_before, i, nglyphs;
12244 struct it it_before;
12246 /* Get the next display element. */
12247 if (!get_next_display_element (it))
12249 /* Don't count empty row if we are counting needed tool-bar lines. */
12250 if (height < 0 && !it->hpos)
12251 return;
12252 break;
12255 /* Produce glyphs. */
12256 n_glyphs_before = row->used[TEXT_AREA];
12257 it_before = *it;
12259 PRODUCE_GLYPHS (it);
12261 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
12262 i = 0;
12263 x = it_before.current_x;
12264 while (i < nglyphs)
12266 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
12268 if (x + glyph->pixel_width > max_x)
12270 /* Glyph doesn't fit on line. Backtrack. */
12271 row->used[TEXT_AREA] = n_glyphs_before;
12272 *it = it_before;
12273 /* If this is the only glyph on this line, it will never fit on the
12274 tool-bar, so skip it. But ensure there is at least one glyph,
12275 so we don't accidentally disable the tool-bar. */
12276 if (n_glyphs_before == 0
12277 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
12278 break;
12279 goto out;
12282 ++it->hpos;
12283 x += glyph->pixel_width;
12284 ++i;
12287 /* Stop at line end. */
12288 if (ITERATOR_AT_END_OF_LINE_P (it))
12289 break;
12291 set_iterator_to_next (it, 1);
12294 out:;
12296 row->displays_text_p = row->used[TEXT_AREA] != 0;
12298 /* Use default face for the border below the tool bar.
12300 FIXME: When auto-resize-tool-bars is grow-only, there is
12301 no additional border below the possibly empty tool-bar lines.
12302 So to make the extra empty lines look "normal", we have to
12303 use the tool-bar face for the border too. */
12304 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
12305 && !EQ (Vauto_resize_tool_bars, Qgrow_only))
12306 it->face_id = DEFAULT_FACE_ID;
12308 extend_face_to_end_of_line (it);
12309 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
12310 last->right_box_line_p = 1;
12311 if (last == row->glyphs[TEXT_AREA])
12312 last->left_box_line_p = 1;
12314 /* Make line the desired height and center it vertically. */
12315 if ((height -= it->max_ascent + it->max_descent) > 0)
12317 /* Don't add more than one line height. */
12318 height %= FRAME_LINE_HEIGHT (it->f);
12319 it->max_ascent += height / 2;
12320 it->max_descent += (height + 1) / 2;
12323 compute_line_metrics (it);
12325 /* If line is empty, make it occupy the rest of the tool-bar. */
12326 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row))
12328 row->height = row->phys_height = it->last_visible_y - row->y;
12329 row->visible_height = row->height;
12330 row->ascent = row->phys_ascent = 0;
12331 row->extra_line_spacing = 0;
12334 row->full_width_p = 1;
12335 row->continued_p = 0;
12336 row->truncated_on_left_p = 0;
12337 row->truncated_on_right_p = 0;
12339 it->current_x = it->hpos = 0;
12340 it->current_y += row->height;
12341 ++it->vpos;
12342 ++it->glyph_row;
12346 /* Value is the number of pixels needed to make all tool-bar items of
12347 frame F visible. The actual number of glyph rows needed is
12348 returned in *N_ROWS if non-NULL. */
12349 static int
12350 tool_bar_height (struct frame *f, int *n_rows, bool pixelwise)
12352 struct window *w = XWINDOW (f->tool_bar_window);
12353 struct it it;
12354 /* tool_bar_height is called from redisplay_tool_bar after building
12355 the desired matrix, so use (unused) mode-line row as temporary row to
12356 avoid destroying the first tool-bar row. */
12357 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
12359 /* Initialize an iterator for iteration over
12360 F->desired_tool_bar_string in the tool-bar window of frame F. */
12361 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
12362 temp_row->reversed_p = false;
12363 it.first_visible_x = 0;
12364 it.last_visible_x = WINDOW_PIXEL_WIDTH (w);
12365 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
12366 it.paragraph_embedding = L2R;
12368 while (!ITERATOR_AT_END_P (&it))
12370 clear_glyph_row (temp_row);
12371 it.glyph_row = temp_row;
12372 display_tool_bar_line (&it, -1);
12374 clear_glyph_row (temp_row);
12376 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
12377 if (n_rows)
12378 *n_rows = it.vpos > 0 ? it.vpos : -1;
12380 if (pixelwise)
12381 return it.current_y;
12382 else
12383 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
12386 #endif /* !USE_GTK && !HAVE_NS */
12388 DEFUN ("tool-bar-height", Ftool_bar_height, Stool_bar_height,
12389 0, 2, 0,
12390 doc: /* Return the number of lines occupied by the tool bar of FRAME.
12391 If FRAME is nil or omitted, use the selected frame. Optional argument
12392 PIXELWISE non-nil means return the height of the tool bar in pixels. */)
12393 (Lisp_Object frame, Lisp_Object pixelwise)
12395 int height = 0;
12397 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
12398 struct frame *f = decode_any_frame (frame);
12400 if (WINDOWP (f->tool_bar_window)
12401 && WINDOW_PIXEL_HEIGHT (XWINDOW (f->tool_bar_window)) > 0)
12403 update_tool_bar (f, 1);
12404 if (f->n_tool_bar_items)
12406 build_desired_tool_bar_string (f);
12407 height = tool_bar_height (f, NULL, NILP (pixelwise) ? 0 : 1);
12410 #endif
12412 return make_number (height);
12416 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
12417 height should be changed. */
12418 static int
12419 redisplay_tool_bar (struct frame *f)
12421 #if defined (USE_GTK) || defined (HAVE_NS)
12423 if (FRAME_EXTERNAL_TOOL_BAR (f))
12424 update_frame_tool_bar (f);
12425 return 0;
12427 #else /* !USE_GTK && !HAVE_NS */
12429 struct window *w;
12430 struct it it;
12431 struct glyph_row *row;
12433 /* If frame hasn't a tool-bar window or if it is zero-height, don't
12434 do anything. This means you must start with tool-bar-lines
12435 non-zero to get the auto-sizing effect. Or in other words, you
12436 can turn off tool-bars by specifying tool-bar-lines zero. */
12437 if (!WINDOWP (f->tool_bar_window)
12438 || (w = XWINDOW (f->tool_bar_window),
12439 WINDOW_TOTAL_LINES (w) == 0))
12440 return 0;
12442 /* Set up an iterator for the tool-bar window. */
12443 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
12444 it.first_visible_x = 0;
12445 it.last_visible_x = WINDOW_PIXEL_WIDTH (w);
12446 row = it.glyph_row;
12447 row->reversed_p = false;
12449 /* Build a string that represents the contents of the tool-bar. */
12450 build_desired_tool_bar_string (f);
12451 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
12452 /* FIXME: This should be controlled by a user option. But it
12453 doesn't make sense to have an R2L tool bar if the menu bar cannot
12454 be drawn also R2L, and making the menu bar R2L is tricky due
12455 toolkit-specific code that implements it. If an R2L tool bar is
12456 ever supported, display_tool_bar_line should also be augmented to
12457 call unproduce_glyphs like display_line and display_string
12458 do. */
12459 it.paragraph_embedding = L2R;
12461 if (f->n_tool_bar_rows == 0)
12463 int new_height = tool_bar_height (f, &f->n_tool_bar_rows, 1);
12465 if (new_height != WINDOW_PIXEL_HEIGHT (w))
12467 x_change_tool_bar_height (f, new_height);
12468 /* Always do that now. */
12469 clear_glyph_matrix (w->desired_matrix);
12470 f->fonts_changed = 1;
12471 return 1;
12475 /* Display as many lines as needed to display all tool-bar items. */
12477 if (f->n_tool_bar_rows > 0)
12479 int border, rows, height, extra;
12481 if (TYPE_RANGED_INTEGERP (int, Vtool_bar_border))
12482 border = XINT (Vtool_bar_border);
12483 else if (EQ (Vtool_bar_border, Qinternal_border_width))
12484 border = FRAME_INTERNAL_BORDER_WIDTH (f);
12485 else if (EQ (Vtool_bar_border, Qborder_width))
12486 border = f->border_width;
12487 else
12488 border = 0;
12489 if (border < 0)
12490 border = 0;
12492 rows = f->n_tool_bar_rows;
12493 height = max (1, (it.last_visible_y - border) / rows);
12494 extra = it.last_visible_y - border - height * rows;
12496 while (it.current_y < it.last_visible_y)
12498 int h = 0;
12499 if (extra > 0 && rows-- > 0)
12501 h = (extra + rows - 1) / rows;
12502 extra -= h;
12504 display_tool_bar_line (&it, height + h);
12507 else
12509 while (it.current_y < it.last_visible_y)
12510 display_tool_bar_line (&it, 0);
12513 /* It doesn't make much sense to try scrolling in the tool-bar
12514 window, so don't do it. */
12515 w->desired_matrix->no_scrolling_p = 1;
12516 w->must_be_updated_p = 1;
12518 if (!NILP (Vauto_resize_tool_bars))
12520 int change_height_p = 0;
12522 /* If we couldn't display everything, change the tool-bar's
12523 height if there is room for more. */
12524 if (IT_STRING_CHARPOS (it) < it.end_charpos)
12525 change_height_p = 1;
12527 /* We subtract 1 because display_tool_bar_line advances the
12528 glyph_row pointer before returning to its caller. We want to
12529 examine the last glyph row produced by
12530 display_tool_bar_line. */
12531 row = it.glyph_row - 1;
12533 /* If there are blank lines at the end, except for a partially
12534 visible blank line at the end that is smaller than
12535 FRAME_LINE_HEIGHT, change the tool-bar's height. */
12536 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
12537 && row->height >= FRAME_LINE_HEIGHT (f))
12538 change_height_p = 1;
12540 /* If row displays tool-bar items, but is partially visible,
12541 change the tool-bar's height. */
12542 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12543 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
12544 change_height_p = 1;
12546 /* Resize windows as needed by changing the `tool-bar-lines'
12547 frame parameter. */
12548 if (change_height_p)
12550 int nrows;
12551 int new_height = tool_bar_height (f, &nrows, 1);
12553 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
12554 && !f->minimize_tool_bar_window_p)
12555 ? (new_height > WINDOW_PIXEL_HEIGHT (w))
12556 : (new_height != WINDOW_PIXEL_HEIGHT (w)));
12557 f->minimize_tool_bar_window_p = 0;
12559 if (change_height_p)
12561 x_change_tool_bar_height (f, new_height);
12562 clear_glyph_matrix (w->desired_matrix);
12563 f->n_tool_bar_rows = nrows;
12564 f->fonts_changed = 1;
12566 return 1;
12571 f->minimize_tool_bar_window_p = 0;
12572 return 0;
12574 #endif /* USE_GTK || HAVE_NS */
12577 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
12579 /* Get information about the tool-bar item which is displayed in GLYPH
12580 on frame F. Return in *PROP_IDX the index where tool-bar item
12581 properties start in F->tool_bar_items. Value is zero if
12582 GLYPH doesn't display a tool-bar item. */
12584 static int
12585 tool_bar_item_info (struct frame *f, struct glyph *glyph, int *prop_idx)
12587 Lisp_Object prop;
12588 int success_p;
12589 int charpos;
12591 /* This function can be called asynchronously, which means we must
12592 exclude any possibility that Fget_text_property signals an
12593 error. */
12594 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
12595 charpos = max (0, charpos);
12597 /* Get the text property `menu-item' at pos. The value of that
12598 property is the start index of this item's properties in
12599 F->tool_bar_items. */
12600 prop = Fget_text_property (make_number (charpos),
12601 Qmenu_item, f->current_tool_bar_string);
12602 if (INTEGERP (prop))
12604 *prop_idx = XINT (prop);
12605 success_p = 1;
12607 else
12608 success_p = 0;
12610 return success_p;
12614 /* Get information about the tool-bar item at position X/Y on frame F.
12615 Return in *GLYPH a pointer to the glyph of the tool-bar item in
12616 the current matrix of the tool-bar window of F, or NULL if not
12617 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
12618 item in F->tool_bar_items. Value is
12620 -1 if X/Y is not on a tool-bar item
12621 0 if X/Y is on the same item that was highlighted before.
12622 1 otherwise. */
12624 static int
12625 get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
12626 int *hpos, int *vpos, int *prop_idx)
12628 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12629 struct window *w = XWINDOW (f->tool_bar_window);
12630 int area;
12632 /* Find the glyph under X/Y. */
12633 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
12634 if (*glyph == NULL)
12635 return -1;
12637 /* Get the start of this tool-bar item's properties in
12638 f->tool_bar_items. */
12639 if (!tool_bar_item_info (f, *glyph, prop_idx))
12640 return -1;
12642 /* Is mouse on the highlighted item? */
12643 if (EQ (f->tool_bar_window, hlinfo->mouse_face_window)
12644 && *vpos >= hlinfo->mouse_face_beg_row
12645 && *vpos <= hlinfo->mouse_face_end_row
12646 && (*vpos > hlinfo->mouse_face_beg_row
12647 || *hpos >= hlinfo->mouse_face_beg_col)
12648 && (*vpos < hlinfo->mouse_face_end_row
12649 || *hpos < hlinfo->mouse_face_end_col
12650 || hlinfo->mouse_face_past_end))
12651 return 0;
12653 return 1;
12657 /* EXPORT:
12658 Handle mouse button event on the tool-bar of frame F, at
12659 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
12660 0 for button release. MODIFIERS is event modifiers for button
12661 release. */
12663 void
12664 handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
12665 int modifiers)
12667 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12668 struct window *w = XWINDOW (f->tool_bar_window);
12669 int hpos, vpos, prop_idx;
12670 struct glyph *glyph;
12671 Lisp_Object enabled_p;
12672 int ts;
12674 /* If not on the highlighted tool-bar item, and mouse-highlight is
12675 non-nil, return. This is so we generate the tool-bar button
12676 click only when the mouse button is released on the same item as
12677 where it was pressed. However, when mouse-highlight is disabled,
12678 generate the click when the button is released regardless of the
12679 highlight, since tool-bar items are not highlighted in that
12680 case. */
12681 frame_to_window_pixel_xy (w, &x, &y);
12682 ts = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
12683 if (ts == -1
12684 || (ts != 0 && !NILP (Vmouse_highlight)))
12685 return;
12687 /* When mouse-highlight is off, generate the click for the item
12688 where the button was pressed, disregarding where it was
12689 released. */
12690 if (NILP (Vmouse_highlight) && !down_p)
12691 prop_idx = f->last_tool_bar_item;
12693 /* If item is disabled, do nothing. */
12694 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
12695 if (NILP (enabled_p))
12696 return;
12698 if (down_p)
12700 /* Show item in pressed state. */
12701 if (!NILP (Vmouse_highlight))
12702 show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN);
12703 f->last_tool_bar_item = prop_idx;
12705 else
12707 Lisp_Object key, frame;
12708 struct input_event event;
12709 EVENT_INIT (event);
12711 /* Show item in released state. */
12712 if (!NILP (Vmouse_highlight))
12713 show_mouse_face (hlinfo, DRAW_IMAGE_RAISED);
12715 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
12717 XSETFRAME (frame, f);
12718 event.kind = TOOL_BAR_EVENT;
12719 event.frame_or_window = frame;
12720 event.arg = frame;
12721 kbd_buffer_store_event (&event);
12723 event.kind = TOOL_BAR_EVENT;
12724 event.frame_or_window = frame;
12725 event.arg = key;
12726 event.modifiers = modifiers;
12727 kbd_buffer_store_event (&event);
12728 f->last_tool_bar_item = -1;
12733 /* Possibly highlight a tool-bar item on frame F when mouse moves to
12734 tool-bar window-relative coordinates X/Y. Called from
12735 note_mouse_highlight. */
12737 static void
12738 note_tool_bar_highlight (struct frame *f, int x, int y)
12740 Lisp_Object window = f->tool_bar_window;
12741 struct window *w = XWINDOW (window);
12742 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
12743 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12744 int hpos, vpos;
12745 struct glyph *glyph;
12746 struct glyph_row *row;
12747 int i;
12748 Lisp_Object enabled_p;
12749 int prop_idx;
12750 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
12751 int mouse_down_p, rc;
12753 /* Function note_mouse_highlight is called with negative X/Y
12754 values when mouse moves outside of the frame. */
12755 if (x <= 0 || y <= 0)
12757 clear_mouse_face (hlinfo);
12758 return;
12761 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
12762 if (rc < 0)
12764 /* Not on tool-bar item. */
12765 clear_mouse_face (hlinfo);
12766 return;
12768 else if (rc == 0)
12769 /* On same tool-bar item as before. */
12770 goto set_help_echo;
12772 clear_mouse_face (hlinfo);
12774 /* Mouse is down, but on different tool-bar item? */
12775 mouse_down_p = (x_mouse_grabbed (dpyinfo)
12776 && f == dpyinfo->last_mouse_frame);
12778 if (mouse_down_p && f->last_tool_bar_item != prop_idx)
12779 return;
12781 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
12783 /* If tool-bar item is not enabled, don't highlight it. */
12784 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
12785 if (!NILP (enabled_p) && !NILP (Vmouse_highlight))
12787 /* Compute the x-position of the glyph. In front and past the
12788 image is a space. We include this in the highlighted area. */
12789 row = MATRIX_ROW (w->current_matrix, vpos);
12790 for (i = x = 0; i < hpos; ++i)
12791 x += row->glyphs[TEXT_AREA][i].pixel_width;
12793 /* Record this as the current active region. */
12794 hlinfo->mouse_face_beg_col = hpos;
12795 hlinfo->mouse_face_beg_row = vpos;
12796 hlinfo->mouse_face_beg_x = x;
12797 hlinfo->mouse_face_past_end = 0;
12799 hlinfo->mouse_face_end_col = hpos + 1;
12800 hlinfo->mouse_face_end_row = vpos;
12801 hlinfo->mouse_face_end_x = x + glyph->pixel_width;
12802 hlinfo->mouse_face_window = window;
12803 hlinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
12805 /* Display it as active. */
12806 show_mouse_face (hlinfo, draw);
12809 set_help_echo:
12811 /* Set help_echo_string to a help string to display for this tool-bar item.
12812 XTread_socket does the rest. */
12813 help_echo_object = help_echo_window = Qnil;
12814 help_echo_pos = -1;
12815 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
12816 if (NILP (help_echo_string))
12817 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
12820 #endif /* !USE_GTK && !HAVE_NS */
12822 #endif /* HAVE_WINDOW_SYSTEM */
12826 /************************************************************************
12827 Horizontal scrolling
12828 ************************************************************************/
12830 static int hscroll_window_tree (Lisp_Object);
12831 static int hscroll_windows (Lisp_Object);
12833 /* For all leaf windows in the window tree rooted at WINDOW, set their
12834 hscroll value so that PT is (i) visible in the window, and (ii) so
12835 that it is not within a certain margin at the window's left and
12836 right border. Value is non-zero if any window's hscroll has been
12837 changed. */
12839 static int
12840 hscroll_window_tree (Lisp_Object window)
12842 int hscrolled_p = 0;
12843 int hscroll_relative_p = FLOATP (Vhscroll_step);
12844 int hscroll_step_abs = 0;
12845 double hscroll_step_rel = 0;
12847 if (hscroll_relative_p)
12849 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
12850 if (hscroll_step_rel < 0)
12852 hscroll_relative_p = 0;
12853 hscroll_step_abs = 0;
12856 else if (TYPE_RANGED_INTEGERP (int, Vhscroll_step))
12858 hscroll_step_abs = XINT (Vhscroll_step);
12859 if (hscroll_step_abs < 0)
12860 hscroll_step_abs = 0;
12862 else
12863 hscroll_step_abs = 0;
12865 while (WINDOWP (window))
12867 struct window *w = XWINDOW (window);
12869 if (WINDOWP (w->contents))
12870 hscrolled_p |= hscroll_window_tree (w->contents);
12871 else if (w->cursor.vpos >= 0)
12873 int h_margin;
12874 int text_area_width;
12875 struct glyph_row *cursor_row;
12876 struct glyph_row *bottom_row;
12877 int row_r2l_p;
12879 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->desired_matrix, w);
12880 if (w->cursor.vpos < bottom_row - w->desired_matrix->rows)
12881 cursor_row = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
12882 else
12883 cursor_row = bottom_row - 1;
12885 if (!cursor_row->enabled_p)
12887 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12888 if (w->cursor.vpos < bottom_row - w->current_matrix->rows)
12889 cursor_row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
12890 else
12891 cursor_row = bottom_row - 1;
12893 row_r2l_p = cursor_row->reversed_p;
12895 text_area_width = window_box_width (w, TEXT_AREA);
12897 /* Scroll when cursor is inside this scroll margin. */
12898 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
12900 /* If the position of this window's point has explicitly
12901 changed, no more suspend auto hscrolling. */
12902 if (NILP (Fequal (Fwindow_point (window), Fwindow_old_point (window))))
12903 w->suspend_auto_hscroll = 0;
12905 /* Remember window point. */
12906 Fset_marker (w->old_pointm,
12907 ((w == XWINDOW (selected_window))
12908 ? make_number (BUF_PT (XBUFFER (w->contents)))
12909 : Fmarker_position (w->pointm)),
12910 w->contents);
12912 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->contents))
12913 && w->suspend_auto_hscroll == 0
12914 /* In some pathological cases, like restoring a window
12915 configuration into a frame that is much smaller than
12916 the one from which the configuration was saved, we
12917 get glyph rows whose start and end have zero buffer
12918 positions, which we cannot handle below. Just skip
12919 such windows. */
12920 && CHARPOS (cursor_row->start.pos) >= BUF_BEG (w->contents)
12921 /* For left-to-right rows, hscroll when cursor is either
12922 (i) inside the right hscroll margin, or (ii) if it is
12923 inside the left margin and the window is already
12924 hscrolled. */
12925 && ((!row_r2l_p
12926 && ((w->hscroll && w->cursor.x <= h_margin)
12927 || (cursor_row->enabled_p
12928 && cursor_row->truncated_on_right_p
12929 && (w->cursor.x >= text_area_width - h_margin))))
12930 /* For right-to-left rows, the logic is similar,
12931 except that rules for scrolling to left and right
12932 are reversed. E.g., if cursor.x <= h_margin, we
12933 need to hscroll "to the right" unconditionally,
12934 and that will scroll the screen to the left so as
12935 to reveal the next portion of the row. */
12936 || (row_r2l_p
12937 && ((cursor_row->enabled_p
12938 /* FIXME: It is confusing to set the
12939 truncated_on_right_p flag when R2L rows
12940 are actually truncated on the left. */
12941 && cursor_row->truncated_on_right_p
12942 && w->cursor.x <= h_margin)
12943 || (w->hscroll
12944 && (w->cursor.x >= text_area_width - h_margin))))))
12946 struct it it;
12947 ptrdiff_t hscroll;
12948 struct buffer *saved_current_buffer;
12949 ptrdiff_t pt;
12950 int wanted_x;
12952 /* Find point in a display of infinite width. */
12953 saved_current_buffer = current_buffer;
12954 current_buffer = XBUFFER (w->contents);
12956 if (w == XWINDOW (selected_window))
12957 pt = PT;
12958 else
12959 pt = clip_to_bounds (BEGV, marker_position (w->pointm), ZV);
12961 /* Move iterator to pt starting at cursor_row->start in
12962 a line with infinite width. */
12963 init_to_row_start (&it, w, cursor_row);
12964 it.last_visible_x = INFINITY;
12965 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
12966 current_buffer = saved_current_buffer;
12968 /* Position cursor in window. */
12969 if (!hscroll_relative_p && hscroll_step_abs == 0)
12970 hscroll = max (0, (it.current_x
12971 - (ITERATOR_AT_END_OF_LINE_P (&it)
12972 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
12973 : (text_area_width / 2))))
12974 / FRAME_COLUMN_WIDTH (it.f);
12975 else if ((!row_r2l_p
12976 && w->cursor.x >= text_area_width - h_margin)
12977 || (row_r2l_p && w->cursor.x <= h_margin))
12979 if (hscroll_relative_p)
12980 wanted_x = text_area_width * (1 - hscroll_step_rel)
12981 - h_margin;
12982 else
12983 wanted_x = text_area_width
12984 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
12985 - h_margin;
12986 hscroll
12987 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
12989 else
12991 if (hscroll_relative_p)
12992 wanted_x = text_area_width * hscroll_step_rel
12993 + h_margin;
12994 else
12995 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
12996 + h_margin;
12997 hscroll
12998 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
13000 hscroll = max (hscroll, w->min_hscroll);
13002 /* Don't prevent redisplay optimizations if hscroll
13003 hasn't changed, as it will unnecessarily slow down
13004 redisplay. */
13005 if (w->hscroll != hscroll)
13007 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
13008 w->hscroll = hscroll;
13009 hscrolled_p = 1;
13014 window = w->next;
13017 /* Value is non-zero if hscroll of any leaf window has been changed. */
13018 return hscrolled_p;
13022 /* Set hscroll so that cursor is visible and not inside horizontal
13023 scroll margins for all windows in the tree rooted at WINDOW. See
13024 also hscroll_window_tree above. Value is non-zero if any window's
13025 hscroll has been changed. If it has, desired matrices on the frame
13026 of WINDOW are cleared. */
13028 static int
13029 hscroll_windows (Lisp_Object window)
13031 int hscrolled_p = hscroll_window_tree (window);
13032 if (hscrolled_p)
13033 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
13034 return hscrolled_p;
13039 /************************************************************************
13040 Redisplay
13041 ************************************************************************/
13043 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
13044 to a non-zero value. This is sometimes handy to have in a debugger
13045 session. */
13047 #ifdef GLYPH_DEBUG
13049 /* First and last unchanged row for try_window_id. */
13051 static int debug_first_unchanged_at_end_vpos;
13052 static int debug_last_unchanged_at_beg_vpos;
13054 /* Delta vpos and y. */
13056 static int debug_dvpos, debug_dy;
13058 /* Delta in characters and bytes for try_window_id. */
13060 static ptrdiff_t debug_delta, debug_delta_bytes;
13062 /* Values of window_end_pos and window_end_vpos at the end of
13063 try_window_id. */
13065 static ptrdiff_t debug_end_vpos;
13067 /* Append a string to W->desired_matrix->method. FMT is a printf
13068 format string. If trace_redisplay_p is true also printf the
13069 resulting string to stderr. */
13071 static void debug_method_add (struct window *, char const *, ...)
13072 ATTRIBUTE_FORMAT_PRINTF (2, 3);
13074 static void
13075 debug_method_add (struct window *w, char const *fmt, ...)
13077 void *ptr = w;
13078 char *method = w->desired_matrix->method;
13079 int len = strlen (method);
13080 int size = sizeof w->desired_matrix->method;
13081 int remaining = size - len - 1;
13082 va_list ap;
13084 if (len && remaining)
13086 method[len] = '|';
13087 --remaining, ++len;
13090 va_start (ap, fmt);
13091 vsnprintf (method + len, remaining + 1, fmt, ap);
13092 va_end (ap);
13094 if (trace_redisplay_p)
13095 fprintf (stderr, "%p (%s): %s\n",
13096 ptr,
13097 ((BUFFERP (w->contents)
13098 && STRINGP (BVAR (XBUFFER (w->contents), name)))
13099 ? SSDATA (BVAR (XBUFFER (w->contents), name))
13100 : "no buffer"),
13101 method + len);
13104 #endif /* GLYPH_DEBUG */
13107 /* Value is non-zero if all changes in window W, which displays
13108 current_buffer, are in the text between START and END. START is a
13109 buffer position, END is given as a distance from Z. Used in
13110 redisplay_internal for display optimization. */
13112 static int
13113 text_outside_line_unchanged_p (struct window *w,
13114 ptrdiff_t start, ptrdiff_t end)
13116 int unchanged_p = 1;
13118 /* If text or overlays have changed, see where. */
13119 if (window_outdated (w))
13121 /* Gap in the line? */
13122 if (GPT < start || Z - GPT < end)
13123 unchanged_p = 0;
13125 /* Changes start in front of the line, or end after it? */
13126 if (unchanged_p
13127 && (BEG_UNCHANGED < start - 1
13128 || END_UNCHANGED < end))
13129 unchanged_p = 0;
13131 /* If selective display, can't optimize if changes start at the
13132 beginning of the line. */
13133 if (unchanged_p
13134 && INTEGERP (BVAR (current_buffer, selective_display))
13135 && XINT (BVAR (current_buffer, selective_display)) > 0
13136 && (BEG_UNCHANGED < start || GPT <= start))
13137 unchanged_p = 0;
13139 /* If there are overlays at the start or end of the line, these
13140 may have overlay strings with newlines in them. A change at
13141 START, for instance, may actually concern the display of such
13142 overlay strings as well, and they are displayed on different
13143 lines. So, quickly rule out this case. (For the future, it
13144 might be desirable to implement something more telling than
13145 just BEG/END_UNCHANGED.) */
13146 if (unchanged_p)
13148 if (BEG + BEG_UNCHANGED == start
13149 && overlay_touches_p (start))
13150 unchanged_p = 0;
13151 if (END_UNCHANGED == end
13152 && overlay_touches_p (Z - end))
13153 unchanged_p = 0;
13156 /* Under bidi reordering, adding or deleting a character in the
13157 beginning of a paragraph, before the first strong directional
13158 character, can change the base direction of the paragraph (unless
13159 the buffer specifies a fixed paragraph direction), which will
13160 require to redisplay the whole paragraph. It might be worthwhile
13161 to find the paragraph limits and widen the range of redisplayed
13162 lines to that, but for now just give up this optimization. */
13163 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
13164 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
13165 unchanged_p = 0;
13168 return unchanged_p;
13172 /* Do a frame update, taking possible shortcuts into account. This is
13173 the main external entry point for redisplay.
13175 If the last redisplay displayed an echo area message and that message
13176 is no longer requested, we clear the echo area or bring back the
13177 mini-buffer if that is in use. */
13179 void
13180 redisplay (void)
13182 redisplay_internal ();
13186 static Lisp_Object
13187 overlay_arrow_string_or_property (Lisp_Object var)
13189 Lisp_Object val;
13191 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
13192 return val;
13194 return Voverlay_arrow_string;
13197 /* Return 1 if there are any overlay-arrows in current_buffer. */
13198 static int
13199 overlay_arrow_in_current_buffer_p (void)
13201 Lisp_Object vlist;
13203 for (vlist = Voverlay_arrow_variable_list;
13204 CONSP (vlist);
13205 vlist = XCDR (vlist))
13207 Lisp_Object var = XCAR (vlist);
13208 Lisp_Object val;
13210 if (!SYMBOLP (var))
13211 continue;
13212 val = find_symbol_value (var);
13213 if (MARKERP (val)
13214 && current_buffer == XMARKER (val)->buffer)
13215 return 1;
13217 return 0;
13221 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
13222 has changed. */
13224 static int
13225 overlay_arrows_changed_p (void)
13227 Lisp_Object vlist;
13229 for (vlist = Voverlay_arrow_variable_list;
13230 CONSP (vlist);
13231 vlist = XCDR (vlist))
13233 Lisp_Object var = XCAR (vlist);
13234 Lisp_Object val, pstr;
13236 if (!SYMBOLP (var))
13237 continue;
13238 val = find_symbol_value (var);
13239 if (!MARKERP (val))
13240 continue;
13241 if (! EQ (COERCE_MARKER (val),
13242 Fget (var, Qlast_arrow_position))
13243 || ! (pstr = overlay_arrow_string_or_property (var),
13244 EQ (pstr, Fget (var, Qlast_arrow_string))))
13245 return 1;
13247 return 0;
13250 /* Mark overlay arrows to be updated on next redisplay. */
13252 static void
13253 update_overlay_arrows (int up_to_date)
13255 Lisp_Object vlist;
13257 for (vlist = Voverlay_arrow_variable_list;
13258 CONSP (vlist);
13259 vlist = XCDR (vlist))
13261 Lisp_Object var = XCAR (vlist);
13263 if (!SYMBOLP (var))
13264 continue;
13266 if (up_to_date > 0)
13268 Lisp_Object val = find_symbol_value (var);
13269 Fput (var, Qlast_arrow_position,
13270 COERCE_MARKER (val));
13271 Fput (var, Qlast_arrow_string,
13272 overlay_arrow_string_or_property (var));
13274 else if (up_to_date < 0
13275 || !NILP (Fget (var, Qlast_arrow_position)))
13277 Fput (var, Qlast_arrow_position, Qt);
13278 Fput (var, Qlast_arrow_string, Qt);
13284 /* Return overlay arrow string to display at row.
13285 Return integer (bitmap number) for arrow bitmap in left fringe.
13286 Return nil if no overlay arrow. */
13288 static Lisp_Object
13289 overlay_arrow_at_row (struct it *it, struct glyph_row *row)
13291 Lisp_Object vlist;
13293 for (vlist = Voverlay_arrow_variable_list;
13294 CONSP (vlist);
13295 vlist = XCDR (vlist))
13297 Lisp_Object var = XCAR (vlist);
13298 Lisp_Object val;
13300 if (!SYMBOLP (var))
13301 continue;
13303 val = find_symbol_value (var);
13305 if (MARKERP (val)
13306 && current_buffer == XMARKER (val)->buffer
13307 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
13309 if (FRAME_WINDOW_P (it->f)
13310 /* FIXME: if ROW->reversed_p is set, this should test
13311 the right fringe, not the left one. */
13312 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
13314 #ifdef HAVE_WINDOW_SYSTEM
13315 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
13317 int fringe_bitmap;
13318 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
13319 return make_number (fringe_bitmap);
13321 #endif
13322 return make_number (-1); /* Use default arrow bitmap. */
13324 return overlay_arrow_string_or_property (var);
13328 return Qnil;
13331 /* Return 1 if point moved out of or into a composition. Otherwise
13332 return 0. PREV_BUF and PREV_PT are the last point buffer and
13333 position. BUF and PT are the current point buffer and position. */
13335 static int
13336 check_point_in_composition (struct buffer *prev_buf, ptrdiff_t prev_pt,
13337 struct buffer *buf, ptrdiff_t pt)
13339 ptrdiff_t start, end;
13340 Lisp_Object prop;
13341 Lisp_Object buffer;
13343 XSETBUFFER (buffer, buf);
13344 /* Check a composition at the last point if point moved within the
13345 same buffer. */
13346 if (prev_buf == buf)
13348 if (prev_pt == pt)
13349 /* Point didn't move. */
13350 return 0;
13352 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
13353 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
13354 && composition_valid_p (start, end, prop)
13355 && start < prev_pt && end > prev_pt)
13356 /* The last point was within the composition. Return 1 iff
13357 point moved out of the composition. */
13358 return (pt <= start || pt >= end);
13361 /* Check a composition at the current point. */
13362 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
13363 && find_composition (pt, -1, &start, &end, &prop, buffer)
13364 && composition_valid_p (start, end, prop)
13365 && start < pt && end > pt);
13368 /* Reconsider the clip changes of buffer which is displayed in W. */
13370 static void
13371 reconsider_clip_changes (struct window *w)
13373 struct buffer *b = XBUFFER (w->contents);
13375 if (b->clip_changed
13376 && w->window_end_valid
13377 && w->current_matrix->buffer == b
13378 && w->current_matrix->zv == BUF_ZV (b)
13379 && w->current_matrix->begv == BUF_BEGV (b))
13380 b->clip_changed = 0;
13382 /* If display wasn't paused, and W is not a tool bar window, see if
13383 point has been moved into or out of a composition. In that case,
13384 we set b->clip_changed to 1 to force updating the screen. If
13385 b->clip_changed has already been set to 1, we can skip this
13386 check. */
13387 if (!b->clip_changed && w->window_end_valid)
13389 ptrdiff_t pt = (w == XWINDOW (selected_window)
13390 ? PT : marker_position (w->pointm));
13392 if ((w->current_matrix->buffer != b || pt != w->last_point)
13393 && check_point_in_composition (w->current_matrix->buffer,
13394 w->last_point, b, pt))
13395 b->clip_changed = 1;
13399 static void
13400 propagate_buffer_redisplay (void)
13401 { /* Resetting b->text->redisplay is problematic!
13402 We can't just reset it in the case that some window that displays
13403 it has not been redisplayed; and such a window can stay
13404 unredisplayed for a long time if it's currently invisible.
13405 But we do want to reset it at the end of redisplay otherwise
13406 its displayed windows will keep being redisplayed over and over
13407 again.
13408 So we copy all b->text->redisplay flags up to their windows here,
13409 such that mark_window_display_accurate can safely reset
13410 b->text->redisplay. */
13411 Lisp_Object ws = window_list ();
13412 for (; CONSP (ws); ws = XCDR (ws))
13414 struct window *thisw = XWINDOW (XCAR (ws));
13415 struct buffer *thisb = XBUFFER (thisw->contents);
13416 if (thisb->text->redisplay)
13417 thisw->redisplay = true;
13421 #define STOP_POLLING \
13422 do { if (! polling_stopped_here) stop_polling (); \
13423 polling_stopped_here = 1; } while (0)
13425 #define RESUME_POLLING \
13426 do { if (polling_stopped_here) start_polling (); \
13427 polling_stopped_here = 0; } while (0)
13430 /* Perhaps in the future avoid recentering windows if it
13431 is not necessary; currently that causes some problems. */
13433 static void
13434 redisplay_internal (void)
13436 struct window *w = XWINDOW (selected_window);
13437 struct window *sw;
13438 struct frame *fr;
13439 int pending;
13440 bool must_finish = 0, match_p;
13441 struct text_pos tlbufpos, tlendpos;
13442 int number_of_visible_frames;
13443 ptrdiff_t count;
13444 struct frame *sf;
13445 int polling_stopped_here = 0;
13446 Lisp_Object tail, frame;
13448 /* True means redisplay has to consider all windows on all
13449 frames. False, only selected_window is considered. */
13450 bool consider_all_windows_p;
13452 /* True means redisplay has to redisplay the miniwindow. */
13453 bool update_miniwindow_p = false;
13455 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
13457 /* No redisplay if running in batch mode or frame is not yet fully
13458 initialized, or redisplay is explicitly turned off by setting
13459 Vinhibit_redisplay. */
13460 if (FRAME_INITIAL_P (SELECTED_FRAME ())
13461 || !NILP (Vinhibit_redisplay))
13462 return;
13464 /* Don't examine these until after testing Vinhibit_redisplay.
13465 When Emacs is shutting down, perhaps because its connection to
13466 X has dropped, we should not look at them at all. */
13467 fr = XFRAME (w->frame);
13468 sf = SELECTED_FRAME ();
13470 if (!fr->glyphs_initialized_p)
13471 return;
13473 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
13474 if (popup_activated ())
13475 return;
13476 #endif
13478 /* I don't think this happens but let's be paranoid. */
13479 if (redisplaying_p)
13480 return;
13482 /* Record a function that clears redisplaying_p
13483 when we leave this function. */
13484 count = SPECPDL_INDEX ();
13485 record_unwind_protect_void (unwind_redisplay);
13486 redisplaying_p = 1;
13487 specbind (Qinhibit_free_realized_faces, Qnil);
13489 /* Record this function, so it appears on the profiler's backtraces. */
13490 record_in_backtrace (Qredisplay_internal, &Qnil, 0);
13492 FOR_EACH_FRAME (tail, frame)
13493 XFRAME (frame)->already_hscrolled_p = 0;
13495 retry:
13496 /* Remember the currently selected window. */
13497 sw = w;
13499 pending = 0;
13500 last_escape_glyph_frame = NULL;
13501 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
13502 last_glyphless_glyph_frame = NULL;
13503 last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
13505 /* If face_change_count is non-zero, init_iterator will free all
13506 realized faces, which includes the faces referenced from current
13507 matrices. So, we can't reuse current matrices in this case. */
13508 if (face_change_count)
13509 windows_or_buffers_changed = 47;
13511 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
13512 && FRAME_TTY (sf)->previous_frame != sf)
13514 /* Since frames on a single ASCII terminal share the same
13515 display area, displaying a different frame means redisplay
13516 the whole thing. */
13517 SET_FRAME_GARBAGED (sf);
13518 #ifndef DOS_NT
13519 set_tty_color_mode (FRAME_TTY (sf), sf);
13520 #endif
13521 FRAME_TTY (sf)->previous_frame = sf;
13524 /* Set the visible flags for all frames. Do this before checking for
13525 resized or garbaged frames; they want to know if their frames are
13526 visible. See the comment in frame.h for FRAME_SAMPLE_VISIBILITY. */
13527 number_of_visible_frames = 0;
13529 FOR_EACH_FRAME (tail, frame)
13531 struct frame *f = XFRAME (frame);
13533 if (FRAME_VISIBLE_P (f))
13535 ++number_of_visible_frames;
13536 /* Adjust matrices for visible frames only. */
13537 if (f->fonts_changed)
13539 adjust_frame_glyphs (f);
13540 f->fonts_changed = 0;
13542 /* If cursor type has been changed on the frame
13543 other than selected, consider all frames. */
13544 if (f != sf && f->cursor_type_changed)
13545 update_mode_lines = 31;
13547 clear_desired_matrices (f);
13550 /* Notice any pending interrupt request to change frame size. */
13551 do_pending_window_change (1);
13553 /* do_pending_window_change could change the selected_window due to
13554 frame resizing which makes the selected window too small. */
13555 if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw)
13556 sw = w;
13558 /* Clear frames marked as garbaged. */
13559 clear_garbaged_frames ();
13561 /* Build menubar and tool-bar items. */
13562 if (NILP (Vmemory_full))
13563 prepare_menu_bars ();
13565 reconsider_clip_changes (w);
13567 /* In most cases selected window displays current buffer. */
13568 match_p = XBUFFER (w->contents) == current_buffer;
13569 if (match_p)
13571 /* Detect case that we need to write or remove a star in the mode line. */
13572 if ((SAVE_MODIFF < MODIFF) != w->last_had_star)
13573 w->update_mode_line = 1;
13575 if (mode_line_update_needed (w))
13576 w->update_mode_line = 1;
13578 /* If reconsider_clip_changes above decided that the narrowing
13579 in the current buffer changed, make sure all other windows
13580 showing that buffer will be redisplayed. */
13581 if (current_buffer->clip_changed)
13582 bset_update_mode_line (current_buffer);
13585 /* Normally the message* functions will have already displayed and
13586 updated the echo area, but the frame may have been trashed, or
13587 the update may have been preempted, so display the echo area
13588 again here. Checking message_cleared_p captures the case that
13589 the echo area should be cleared. */
13590 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
13591 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
13592 || (message_cleared_p
13593 && minibuf_level == 0
13594 /* If the mini-window is currently selected, this means the
13595 echo-area doesn't show through. */
13596 && !MINI_WINDOW_P (XWINDOW (selected_window))))
13598 int window_height_changed_p = echo_area_display (0);
13600 if (message_cleared_p)
13601 update_miniwindow_p = true;
13603 must_finish = 1;
13605 /* If we don't display the current message, don't clear the
13606 message_cleared_p flag, because, if we did, we wouldn't clear
13607 the echo area in the next redisplay which doesn't preserve
13608 the echo area. */
13609 if (!display_last_displayed_message_p)
13610 message_cleared_p = 0;
13612 if (window_height_changed_p)
13614 windows_or_buffers_changed = 50;
13616 /* If window configuration was changed, frames may have been
13617 marked garbaged. Clear them or we will experience
13618 surprises wrt scrolling. */
13619 clear_garbaged_frames ();
13622 else if (EQ (selected_window, minibuf_window)
13623 && (current_buffer->clip_changed || window_outdated (w))
13624 && resize_mini_window (w, 0))
13626 /* Resized active mini-window to fit the size of what it is
13627 showing if its contents might have changed. */
13628 must_finish = 1;
13630 /* If window configuration was changed, frames may have been
13631 marked garbaged. Clear them or we will experience
13632 surprises wrt scrolling. */
13633 clear_garbaged_frames ();
13636 if (windows_or_buffers_changed && !update_mode_lines)
13637 /* Code that sets windows_or_buffers_changed doesn't distinguish whether
13638 only the windows's contents needs to be refreshed, or whether the
13639 mode-lines also need a refresh. */
13640 update_mode_lines = (windows_or_buffers_changed == REDISPLAY_SOME
13641 ? REDISPLAY_SOME : 32);
13643 /* If specs for an arrow have changed, do thorough redisplay
13644 to ensure we remove any arrow that should no longer exist. */
13645 if (overlay_arrows_changed_p ())
13646 /* Apparently, this is the only case where we update other windows,
13647 without updating other mode-lines. */
13648 windows_or_buffers_changed = 49;
13650 consider_all_windows_p = (update_mode_lines
13651 || windows_or_buffers_changed);
13653 #define AINC(a,i) \
13654 if (VECTORP (a) && i >= 0 && i < ASIZE (a) && INTEGERP (AREF (a, i))) \
13655 ASET (a, i, make_number (1 + XINT (AREF (a, i))))
13657 AINC (Vredisplay__all_windows_cause, windows_or_buffers_changed);
13658 AINC (Vredisplay__mode_lines_cause, update_mode_lines);
13660 /* Optimize the case that only the line containing the cursor in the
13661 selected window has changed. Variables starting with this_ are
13662 set in display_line and record information about the line
13663 containing the cursor. */
13664 tlbufpos = this_line_start_pos;
13665 tlendpos = this_line_end_pos;
13666 if (!consider_all_windows_p
13667 && CHARPOS (tlbufpos) > 0
13668 && !w->update_mode_line
13669 && !current_buffer->clip_changed
13670 && !current_buffer->prevent_redisplay_optimizations_p
13671 && FRAME_VISIBLE_P (XFRAME (w->frame))
13672 && !FRAME_OBSCURED_P (XFRAME (w->frame))
13673 && !XFRAME (w->frame)->cursor_type_changed
13674 /* Make sure recorded data applies to current buffer, etc. */
13675 && this_line_buffer == current_buffer
13676 && match_p
13677 && !w->force_start
13678 && !w->optional_new_start
13679 /* Point must be on the line that we have info recorded about. */
13680 && PT >= CHARPOS (tlbufpos)
13681 && PT <= Z - CHARPOS (tlendpos)
13682 /* All text outside that line, including its final newline,
13683 must be unchanged. */
13684 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
13685 CHARPOS (tlendpos)))
13687 if (CHARPOS (tlbufpos) > BEGV
13688 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
13689 && (CHARPOS (tlbufpos) == ZV
13690 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
13691 /* Former continuation line has disappeared by becoming empty. */
13692 goto cancel;
13693 else if (window_outdated (w) || MINI_WINDOW_P (w))
13695 /* We have to handle the case of continuation around a
13696 wide-column character (see the comment in indent.c around
13697 line 1340).
13699 For instance, in the following case:
13701 -------- Insert --------
13702 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
13703 J_I_ ==> J_I_ `^^' are cursors.
13704 ^^ ^^
13705 -------- --------
13707 As we have to redraw the line above, we cannot use this
13708 optimization. */
13710 struct it it;
13711 int line_height_before = this_line_pixel_height;
13713 /* Note that start_display will handle the case that the
13714 line starting at tlbufpos is a continuation line. */
13715 start_display (&it, w, tlbufpos);
13717 /* Implementation note: It this still necessary? */
13718 if (it.current_x != this_line_start_x)
13719 goto cancel;
13721 TRACE ((stderr, "trying display optimization 1\n"));
13722 w->cursor.vpos = -1;
13723 overlay_arrow_seen = 0;
13724 it.vpos = this_line_vpos;
13725 it.current_y = this_line_y;
13726 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
13727 display_line (&it);
13729 /* If line contains point, is not continued,
13730 and ends at same distance from eob as before, we win. */
13731 if (w->cursor.vpos >= 0
13732 /* Line is not continued, otherwise this_line_start_pos
13733 would have been set to 0 in display_line. */
13734 && CHARPOS (this_line_start_pos)
13735 /* Line ends as before. */
13736 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
13737 /* Line has same height as before. Otherwise other lines
13738 would have to be shifted up or down. */
13739 && this_line_pixel_height == line_height_before)
13741 /* If this is not the window's last line, we must adjust
13742 the charstarts of the lines below. */
13743 if (it.current_y < it.last_visible_y)
13745 struct glyph_row *row
13746 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
13747 ptrdiff_t delta, delta_bytes;
13749 /* We used to distinguish between two cases here,
13750 conditioned by Z - CHARPOS (tlendpos) == ZV, for
13751 when the line ends in a newline or the end of the
13752 buffer's accessible portion. But both cases did
13753 the same, so they were collapsed. */
13754 delta = (Z
13755 - CHARPOS (tlendpos)
13756 - MATRIX_ROW_START_CHARPOS (row));
13757 delta_bytes = (Z_BYTE
13758 - BYTEPOS (tlendpos)
13759 - MATRIX_ROW_START_BYTEPOS (row));
13761 increment_matrix_positions (w->current_matrix,
13762 this_line_vpos + 1,
13763 w->current_matrix->nrows,
13764 delta, delta_bytes);
13767 /* If this row displays text now but previously didn't,
13768 or vice versa, w->window_end_vpos may have to be
13769 adjusted. */
13770 if (MATRIX_ROW_DISPLAYS_TEXT_P (it.glyph_row - 1))
13772 if (w->window_end_vpos < this_line_vpos)
13773 w->window_end_vpos = this_line_vpos;
13775 else if (w->window_end_vpos == this_line_vpos
13776 && this_line_vpos > 0)
13777 w->window_end_vpos = this_line_vpos - 1;
13778 w->window_end_valid = 0;
13780 /* Update hint: No need to try to scroll in update_window. */
13781 w->desired_matrix->no_scrolling_p = 1;
13783 #ifdef GLYPH_DEBUG
13784 *w->desired_matrix->method = 0;
13785 debug_method_add (w, "optimization 1");
13786 #endif
13787 #ifdef HAVE_WINDOW_SYSTEM
13788 update_window_fringes (w, 0);
13789 #endif
13790 goto update;
13792 else
13793 goto cancel;
13795 else if (/* Cursor position hasn't changed. */
13796 PT == w->last_point
13797 /* Make sure the cursor was last displayed
13798 in this window. Otherwise we have to reposition it. */
13800 /* PXW: Must be converted to pixels, probably. */
13801 && 0 <= w->cursor.vpos
13802 && w->cursor.vpos < WINDOW_TOTAL_LINES (w))
13804 if (!must_finish)
13806 do_pending_window_change (1);
13807 /* If selected_window changed, redisplay again. */
13808 if (WINDOWP (selected_window)
13809 && (w = XWINDOW (selected_window)) != sw)
13810 goto retry;
13812 /* We used to always goto end_of_redisplay here, but this
13813 isn't enough if we have a blinking cursor. */
13814 if (w->cursor_off_p == w->last_cursor_off_p)
13815 goto end_of_redisplay;
13817 goto update;
13819 /* If highlighting the region, or if the cursor is in the echo area,
13820 then we can't just move the cursor. */
13821 else if (NILP (Vshow_trailing_whitespace)
13822 && !cursor_in_echo_area)
13824 struct it it;
13825 struct glyph_row *row;
13827 /* Skip from tlbufpos to PT and see where it is. Note that
13828 PT may be in invisible text. If so, we will end at the
13829 next visible position. */
13830 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
13831 NULL, DEFAULT_FACE_ID);
13832 it.current_x = this_line_start_x;
13833 it.current_y = this_line_y;
13834 it.vpos = this_line_vpos;
13836 /* The call to move_it_to stops in front of PT, but
13837 moves over before-strings. */
13838 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
13840 if (it.vpos == this_line_vpos
13841 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
13842 row->enabled_p))
13844 eassert (this_line_vpos == it.vpos);
13845 eassert (this_line_y == it.current_y);
13846 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13847 #ifdef GLYPH_DEBUG
13848 *w->desired_matrix->method = 0;
13849 debug_method_add (w, "optimization 3");
13850 #endif
13851 goto update;
13853 else
13854 goto cancel;
13857 cancel:
13858 /* Text changed drastically or point moved off of line. */
13859 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, false);
13862 CHARPOS (this_line_start_pos) = 0;
13863 ++clear_face_cache_count;
13864 #ifdef HAVE_WINDOW_SYSTEM
13865 ++clear_image_cache_count;
13866 #endif
13868 /* Build desired matrices, and update the display. If
13869 consider_all_windows_p is non-zero, do it for all windows on all
13870 frames. Otherwise do it for selected_window, only. */
13872 if (consider_all_windows_p)
13874 FOR_EACH_FRAME (tail, frame)
13875 XFRAME (frame)->updated_p = 0;
13877 propagate_buffer_redisplay ();
13879 FOR_EACH_FRAME (tail, frame)
13881 struct frame *f = XFRAME (frame);
13883 /* We don't have to do anything for unselected terminal
13884 frames. */
13885 if ((FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
13886 && !EQ (FRAME_TTY (f)->top_frame, frame))
13887 continue;
13889 retry_frame:
13891 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
13893 bool gcscrollbars
13894 /* Only GC scrollbars when we redisplay the whole frame. */
13895 = f->redisplay || !REDISPLAY_SOME_P ();
13896 /* Mark all the scroll bars to be removed; we'll redeem
13897 the ones we want when we redisplay their windows. */
13898 if (gcscrollbars && FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
13899 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
13901 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
13902 redisplay_windows (FRAME_ROOT_WINDOW (f));
13903 /* Remember that the invisible frames need to be redisplayed next
13904 time they're visible. */
13905 else if (!REDISPLAY_SOME_P ())
13906 f->redisplay = true;
13908 /* The X error handler may have deleted that frame. */
13909 if (!FRAME_LIVE_P (f))
13910 continue;
13912 /* Any scroll bars which redisplay_windows should have
13913 nuked should now go away. */
13914 if (gcscrollbars && FRAME_TERMINAL (f)->judge_scroll_bars_hook)
13915 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
13917 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
13919 /* If fonts changed on visible frame, display again. */
13920 if (f->fonts_changed)
13922 adjust_frame_glyphs (f);
13923 f->fonts_changed = 0;
13924 goto retry_frame;
13927 /* See if we have to hscroll. */
13928 if (!f->already_hscrolled_p)
13930 f->already_hscrolled_p = 1;
13931 if (hscroll_windows (f->root_window))
13932 goto retry_frame;
13935 /* Prevent various kinds of signals during display
13936 update. stdio is not robust about handling
13937 signals, which can cause an apparent I/O error. */
13938 if (interrupt_input)
13939 unrequest_sigio ();
13940 STOP_POLLING;
13942 pending |= update_frame (f, 0, 0);
13943 f->cursor_type_changed = 0;
13944 f->updated_p = 1;
13949 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
13951 if (!pending)
13953 /* Do the mark_window_display_accurate after all windows have
13954 been redisplayed because this call resets flags in buffers
13955 which are needed for proper redisplay. */
13956 FOR_EACH_FRAME (tail, frame)
13958 struct frame *f = XFRAME (frame);
13959 if (f->updated_p)
13961 f->redisplay = false;
13962 mark_window_display_accurate (f->root_window, 1);
13963 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
13964 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
13969 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
13971 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
13972 struct frame *mini_frame;
13974 displayed_buffer = XBUFFER (XWINDOW (selected_window)->contents);
13975 /* Use list_of_error, not Qerror, so that
13976 we catch only errors and don't run the debugger. */
13977 internal_condition_case_1 (redisplay_window_1, selected_window,
13978 list_of_error,
13979 redisplay_window_error);
13980 if (update_miniwindow_p)
13981 internal_condition_case_1 (redisplay_window_1, mini_window,
13982 list_of_error,
13983 redisplay_window_error);
13985 /* Compare desired and current matrices, perform output. */
13987 update:
13988 /* If fonts changed, display again. */
13989 if (sf->fonts_changed)
13990 goto retry;
13992 /* Prevent various kinds of signals during display update.
13993 stdio is not robust about handling signals,
13994 which can cause an apparent I/O error. */
13995 if (interrupt_input)
13996 unrequest_sigio ();
13997 STOP_POLLING;
13999 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
14001 if (hscroll_windows (selected_window))
14002 goto retry;
14004 XWINDOW (selected_window)->must_be_updated_p = true;
14005 pending = update_frame (sf, 0, 0);
14006 sf->cursor_type_changed = 0;
14009 /* We may have called echo_area_display at the top of this
14010 function. If the echo area is on another frame, that may
14011 have put text on a frame other than the selected one, so the
14012 above call to update_frame would not have caught it. Catch
14013 it here. */
14014 mini_window = FRAME_MINIBUF_WINDOW (sf);
14015 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
14017 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
14019 XWINDOW (mini_window)->must_be_updated_p = true;
14020 pending |= update_frame (mini_frame, 0, 0);
14021 mini_frame->cursor_type_changed = 0;
14022 if (!pending && hscroll_windows (mini_window))
14023 goto retry;
14027 /* If display was paused because of pending input, make sure we do a
14028 thorough update the next time. */
14029 if (pending)
14031 /* Prevent the optimization at the beginning of
14032 redisplay_internal that tries a single-line update of the
14033 line containing the cursor in the selected window. */
14034 CHARPOS (this_line_start_pos) = 0;
14036 /* Let the overlay arrow be updated the next time. */
14037 update_overlay_arrows (0);
14039 /* If we pause after scrolling, some rows in the current
14040 matrices of some windows are not valid. */
14041 if (!WINDOW_FULL_WIDTH_P (w)
14042 && !FRAME_WINDOW_P (XFRAME (w->frame)))
14043 update_mode_lines = 36;
14045 else
14047 if (!consider_all_windows_p)
14049 /* This has already been done above if
14050 consider_all_windows_p is set. */
14051 if (XBUFFER (w->contents)->text->redisplay
14052 && buffer_window_count (XBUFFER (w->contents)) > 1)
14053 /* This can happen if b->text->redisplay was set during
14054 jit-lock. */
14055 propagate_buffer_redisplay ();
14056 mark_window_display_accurate_1 (w, 1);
14058 /* Say overlay arrows are up to date. */
14059 update_overlay_arrows (1);
14061 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
14062 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
14065 update_mode_lines = 0;
14066 windows_or_buffers_changed = 0;
14069 /* Start SIGIO interrupts coming again. Having them off during the
14070 code above makes it less likely one will discard output, but not
14071 impossible, since there might be stuff in the system buffer here.
14072 But it is much hairier to try to do anything about that. */
14073 if (interrupt_input)
14074 request_sigio ();
14075 RESUME_POLLING;
14077 /* If a frame has become visible which was not before, redisplay
14078 again, so that we display it. Expose events for such a frame
14079 (which it gets when becoming visible) don't call the parts of
14080 redisplay constructing glyphs, so simply exposing a frame won't
14081 display anything in this case. So, we have to display these
14082 frames here explicitly. */
14083 if (!pending)
14085 int new_count = 0;
14087 FOR_EACH_FRAME (tail, frame)
14089 if (XFRAME (frame)->visible)
14090 new_count++;
14093 if (new_count != number_of_visible_frames)
14094 windows_or_buffers_changed = 52;
14097 /* Change frame size now if a change is pending. */
14098 do_pending_window_change (1);
14100 /* If we just did a pending size change, or have additional
14101 visible frames, or selected_window changed, redisplay again. */
14102 if ((windows_or_buffers_changed && !pending)
14103 || (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw))
14104 goto retry;
14106 /* Clear the face and image caches.
14108 We used to do this only if consider_all_windows_p. But the cache
14109 needs to be cleared if a timer creates images in the current
14110 buffer (e.g. the test case in Bug#6230). */
14112 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
14114 clear_face_cache (0);
14115 clear_face_cache_count = 0;
14118 #ifdef HAVE_WINDOW_SYSTEM
14119 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
14121 clear_image_caches (Qnil);
14122 clear_image_cache_count = 0;
14124 #endif /* HAVE_WINDOW_SYSTEM */
14126 end_of_redisplay:
14127 if (interrupt_input && interrupts_deferred)
14128 request_sigio ();
14130 unbind_to (count, Qnil);
14131 RESUME_POLLING;
14135 /* Redisplay, but leave alone any recent echo area message unless
14136 another message has been requested in its place.
14138 This is useful in situations where you need to redisplay but no
14139 user action has occurred, making it inappropriate for the message
14140 area to be cleared. See tracking_off and
14141 wait_reading_process_output for examples of these situations.
14143 FROM_WHERE is an integer saying from where this function was
14144 called. This is useful for debugging. */
14146 void
14147 redisplay_preserve_echo_area (int from_where)
14149 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
14151 if (!NILP (echo_area_buffer[1]))
14153 /* We have a previously displayed message, but no current
14154 message. Redisplay the previous message. */
14155 display_last_displayed_message_p = 1;
14156 redisplay_internal ();
14157 display_last_displayed_message_p = 0;
14159 else
14160 redisplay_internal ();
14162 flush_frame (SELECTED_FRAME ());
14166 /* Function registered with record_unwind_protect in redisplay_internal. */
14168 static void
14169 unwind_redisplay (void)
14171 redisplaying_p = 0;
14175 /* Mark the display of leaf window W as accurate or inaccurate.
14176 If ACCURATE_P is non-zero mark display of W as accurate. If
14177 ACCURATE_P is zero, arrange for W to be redisplayed the next
14178 time redisplay_internal is called. */
14180 static void
14181 mark_window_display_accurate_1 (struct window *w, int accurate_p)
14183 struct buffer *b = XBUFFER (w->contents);
14185 w->last_modified = accurate_p ? BUF_MODIFF (b) : 0;
14186 w->last_overlay_modified = accurate_p ? BUF_OVERLAY_MODIFF (b) : 0;
14187 w->last_had_star = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b);
14189 if (accurate_p)
14191 b->clip_changed = false;
14192 b->prevent_redisplay_optimizations_p = false;
14193 eassert (buffer_window_count (b) > 0);
14194 /* Resetting b->text->redisplay is problematic!
14195 In order to make it safer to do it here, redisplay_internal must
14196 have copied all b->text->redisplay to their respective windows. */
14197 b->text->redisplay = false;
14199 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
14200 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
14201 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
14202 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
14204 w->current_matrix->buffer = b;
14205 w->current_matrix->begv = BUF_BEGV (b);
14206 w->current_matrix->zv = BUF_ZV (b);
14208 w->last_cursor_vpos = w->cursor.vpos;
14209 w->last_cursor_off_p = w->cursor_off_p;
14211 if (w == XWINDOW (selected_window))
14212 w->last_point = BUF_PT (b);
14213 else
14214 w->last_point = marker_position (w->pointm);
14216 w->window_end_valid = true;
14217 w->update_mode_line = false;
14220 w->redisplay = !accurate_p;
14224 /* Mark the display of windows in the window tree rooted at WINDOW as
14225 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
14226 windows as accurate. If ACCURATE_P is zero, arrange for windows to
14227 be redisplayed the next time redisplay_internal is called. */
14229 void
14230 mark_window_display_accurate (Lisp_Object window, int accurate_p)
14232 struct window *w;
14234 for (; !NILP (window); window = w->next)
14236 w = XWINDOW (window);
14237 if (WINDOWP (w->contents))
14238 mark_window_display_accurate (w->contents, accurate_p);
14239 else
14240 mark_window_display_accurate_1 (w, accurate_p);
14243 if (accurate_p)
14244 update_overlay_arrows (1);
14245 else
14246 /* Force a thorough redisplay the next time by setting
14247 last_arrow_position and last_arrow_string to t, which is
14248 unequal to any useful value of Voverlay_arrow_... */
14249 update_overlay_arrows (-1);
14253 /* Return value in display table DP (Lisp_Char_Table *) for character
14254 C. Since a display table doesn't have any parent, we don't have to
14255 follow parent. Do not call this function directly but use the
14256 macro DISP_CHAR_VECTOR. */
14258 Lisp_Object
14259 disp_char_vector (struct Lisp_Char_Table *dp, int c)
14261 Lisp_Object val;
14263 if (ASCII_CHAR_P (c))
14265 val = dp->ascii;
14266 if (SUB_CHAR_TABLE_P (val))
14267 val = XSUB_CHAR_TABLE (val)->contents[c];
14269 else
14271 Lisp_Object table;
14273 XSETCHAR_TABLE (table, dp);
14274 val = char_table_ref (table, c);
14276 if (NILP (val))
14277 val = dp->defalt;
14278 return val;
14283 /***********************************************************************
14284 Window Redisplay
14285 ***********************************************************************/
14287 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
14289 static void
14290 redisplay_windows (Lisp_Object window)
14292 while (!NILP (window))
14294 struct window *w = XWINDOW (window);
14296 if (WINDOWP (w->contents))
14297 redisplay_windows (w->contents);
14298 else if (BUFFERP (w->contents))
14300 displayed_buffer = XBUFFER (w->contents);
14301 /* Use list_of_error, not Qerror, so that
14302 we catch only errors and don't run the debugger. */
14303 internal_condition_case_1 (redisplay_window_0, window,
14304 list_of_error,
14305 redisplay_window_error);
14308 window = w->next;
14312 static Lisp_Object
14313 redisplay_window_error (Lisp_Object ignore)
14315 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
14316 return Qnil;
14319 static Lisp_Object
14320 redisplay_window_0 (Lisp_Object window)
14322 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
14323 redisplay_window (window, false);
14324 return Qnil;
14327 static Lisp_Object
14328 redisplay_window_1 (Lisp_Object window)
14330 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
14331 redisplay_window (window, true);
14332 return Qnil;
14336 /* Set cursor position of W. PT is assumed to be displayed in ROW.
14337 DELTA and DELTA_BYTES are the numbers of characters and bytes by
14338 which positions recorded in ROW differ from current buffer
14339 positions.
14341 Return 0 if cursor is not on this row, 1 otherwise. */
14343 static int
14344 set_cursor_from_row (struct window *w, struct glyph_row *row,
14345 struct glyph_matrix *matrix,
14346 ptrdiff_t delta, ptrdiff_t delta_bytes,
14347 int dy, int dvpos)
14349 struct glyph *glyph = row->glyphs[TEXT_AREA];
14350 struct glyph *end = glyph + row->used[TEXT_AREA];
14351 struct glyph *cursor = NULL;
14352 /* The last known character position in row. */
14353 ptrdiff_t last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
14354 int x = row->x;
14355 ptrdiff_t pt_old = PT - delta;
14356 ptrdiff_t pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
14357 ptrdiff_t pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
14358 struct glyph *glyph_before = glyph - 1, *glyph_after = end;
14359 /* A glyph beyond the edge of TEXT_AREA which we should never
14360 touch. */
14361 struct glyph *glyphs_end = end;
14362 /* Non-zero means we've found a match for cursor position, but that
14363 glyph has the avoid_cursor_p flag set. */
14364 int match_with_avoid_cursor = 0;
14365 /* Non-zero means we've seen at least one glyph that came from a
14366 display string. */
14367 int string_seen = 0;
14368 /* Largest and smallest buffer positions seen so far during scan of
14369 glyph row. */
14370 ptrdiff_t bpos_max = pos_before;
14371 ptrdiff_t bpos_min = pos_after;
14372 /* Last buffer position covered by an overlay string with an integer
14373 `cursor' property. */
14374 ptrdiff_t bpos_covered = 0;
14375 /* Non-zero means the display string on which to display the cursor
14376 comes from a text property, not from an overlay. */
14377 int string_from_text_prop = 0;
14379 /* Don't even try doing anything if called for a mode-line or
14380 header-line row, since the rest of the code isn't prepared to
14381 deal with such calamities. */
14382 eassert (!row->mode_line_p);
14383 if (row->mode_line_p)
14384 return 0;
14386 /* Skip over glyphs not having an object at the start and the end of
14387 the row. These are special glyphs like truncation marks on
14388 terminal frames. */
14389 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
14391 if (!row->reversed_p)
14393 while (glyph < end
14394 && INTEGERP (glyph->object)
14395 && glyph->charpos < 0)
14397 x += glyph->pixel_width;
14398 ++glyph;
14400 while (end > glyph
14401 && INTEGERP ((end - 1)->object)
14402 /* CHARPOS is zero for blanks and stretch glyphs
14403 inserted by extend_face_to_end_of_line. */
14404 && (end - 1)->charpos <= 0)
14405 --end;
14406 glyph_before = glyph - 1;
14407 glyph_after = end;
14409 else
14411 struct glyph *g;
14413 /* If the glyph row is reversed, we need to process it from back
14414 to front, so swap the edge pointers. */
14415 glyphs_end = end = glyph - 1;
14416 glyph += row->used[TEXT_AREA] - 1;
14418 while (glyph > end + 1
14419 && INTEGERP (glyph->object)
14420 && glyph->charpos < 0)
14422 --glyph;
14423 x -= glyph->pixel_width;
14425 if (INTEGERP (glyph->object) && glyph->charpos < 0)
14426 --glyph;
14427 /* By default, in reversed rows we put the cursor on the
14428 rightmost (first in the reading order) glyph. */
14429 for (g = end + 1; g < glyph; g++)
14430 x += g->pixel_width;
14431 while (end < glyph
14432 && INTEGERP ((end + 1)->object)
14433 && (end + 1)->charpos <= 0)
14434 ++end;
14435 glyph_before = glyph + 1;
14436 glyph_after = end;
14439 else if (row->reversed_p)
14441 /* In R2L rows that don't display text, put the cursor on the
14442 rightmost glyph. Case in point: an empty last line that is
14443 part of an R2L paragraph. */
14444 cursor = end - 1;
14445 /* Avoid placing the cursor on the last glyph of the row, where
14446 on terminal frames we hold the vertical border between
14447 adjacent windows. */
14448 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w))
14449 && !WINDOW_RIGHTMOST_P (w)
14450 && cursor == row->glyphs[LAST_AREA] - 1)
14451 cursor--;
14452 x = -1; /* will be computed below, at label compute_x */
14455 /* Step 1: Try to find the glyph whose character position
14456 corresponds to point. If that's not possible, find 2 glyphs
14457 whose character positions are the closest to point, one before
14458 point, the other after it. */
14459 if (!row->reversed_p)
14460 while (/* not marched to end of glyph row */
14461 glyph < end
14462 /* glyph was not inserted by redisplay for internal purposes */
14463 && !INTEGERP (glyph->object))
14465 if (BUFFERP (glyph->object))
14467 ptrdiff_t dpos = glyph->charpos - pt_old;
14469 if (glyph->charpos > bpos_max)
14470 bpos_max = glyph->charpos;
14471 if (glyph->charpos < bpos_min)
14472 bpos_min = glyph->charpos;
14473 if (!glyph->avoid_cursor_p)
14475 /* If we hit point, we've found the glyph on which to
14476 display the cursor. */
14477 if (dpos == 0)
14479 match_with_avoid_cursor = 0;
14480 break;
14482 /* See if we've found a better approximation to
14483 POS_BEFORE or to POS_AFTER. */
14484 if (0 > dpos && dpos > pos_before - pt_old)
14486 pos_before = glyph->charpos;
14487 glyph_before = glyph;
14489 else if (0 < dpos && dpos < pos_after - pt_old)
14491 pos_after = glyph->charpos;
14492 glyph_after = glyph;
14495 else if (dpos == 0)
14496 match_with_avoid_cursor = 1;
14498 else if (STRINGP (glyph->object))
14500 Lisp_Object chprop;
14501 ptrdiff_t glyph_pos = glyph->charpos;
14503 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
14504 glyph->object);
14505 if (!NILP (chprop))
14507 /* If the string came from a `display' text property,
14508 look up the buffer position of that property and
14509 use that position to update bpos_max, as if we
14510 actually saw such a position in one of the row's
14511 glyphs. This helps with supporting integer values
14512 of `cursor' property on the display string in
14513 situations where most or all of the row's buffer
14514 text is completely covered by display properties,
14515 so that no glyph with valid buffer positions is
14516 ever seen in the row. */
14517 ptrdiff_t prop_pos =
14518 string_buffer_position_lim (glyph->object, pos_before,
14519 pos_after, 0);
14521 if (prop_pos >= pos_before)
14522 bpos_max = prop_pos;
14524 if (INTEGERP (chprop))
14526 bpos_covered = bpos_max + XINT (chprop);
14527 /* If the `cursor' property covers buffer positions up
14528 to and including point, we should display cursor on
14529 this glyph. Note that, if a `cursor' property on one
14530 of the string's characters has an integer value, we
14531 will break out of the loop below _before_ we get to
14532 the position match above. IOW, integer values of
14533 the `cursor' property override the "exact match for
14534 point" strategy of positioning the cursor. */
14535 /* Implementation note: bpos_max == pt_old when, e.g.,
14536 we are in an empty line, where bpos_max is set to
14537 MATRIX_ROW_START_CHARPOS, see above. */
14538 if (bpos_max <= pt_old && bpos_covered >= pt_old)
14540 cursor = glyph;
14541 break;
14545 string_seen = 1;
14547 x += glyph->pixel_width;
14548 ++glyph;
14550 else if (glyph > end) /* row is reversed */
14551 while (!INTEGERP (glyph->object))
14553 if (BUFFERP (glyph->object))
14555 ptrdiff_t dpos = glyph->charpos - pt_old;
14557 if (glyph->charpos > bpos_max)
14558 bpos_max = glyph->charpos;
14559 if (glyph->charpos < bpos_min)
14560 bpos_min = glyph->charpos;
14561 if (!glyph->avoid_cursor_p)
14563 if (dpos == 0)
14565 match_with_avoid_cursor = 0;
14566 break;
14568 if (0 > dpos && dpos > pos_before - pt_old)
14570 pos_before = glyph->charpos;
14571 glyph_before = glyph;
14573 else if (0 < dpos && dpos < pos_after - pt_old)
14575 pos_after = glyph->charpos;
14576 glyph_after = glyph;
14579 else if (dpos == 0)
14580 match_with_avoid_cursor = 1;
14582 else if (STRINGP (glyph->object))
14584 Lisp_Object chprop;
14585 ptrdiff_t glyph_pos = glyph->charpos;
14587 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
14588 glyph->object);
14589 if (!NILP (chprop))
14591 ptrdiff_t prop_pos =
14592 string_buffer_position_lim (glyph->object, pos_before,
14593 pos_after, 0);
14595 if (prop_pos >= pos_before)
14596 bpos_max = prop_pos;
14598 if (INTEGERP (chprop))
14600 bpos_covered = bpos_max + XINT (chprop);
14601 /* If the `cursor' property covers buffer positions up
14602 to and including point, we should display cursor on
14603 this glyph. */
14604 if (bpos_max <= pt_old && bpos_covered >= pt_old)
14606 cursor = glyph;
14607 break;
14610 string_seen = 1;
14612 --glyph;
14613 if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
14615 x--; /* can't use any pixel_width */
14616 break;
14618 x -= glyph->pixel_width;
14621 /* Step 2: If we didn't find an exact match for point, we need to
14622 look for a proper place to put the cursor among glyphs between
14623 GLYPH_BEFORE and GLYPH_AFTER. */
14624 if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
14625 && BUFFERP (glyph->object) && glyph->charpos == pt_old)
14626 && !(bpos_max <= pt_old && pt_old <= bpos_covered))
14628 /* An empty line has a single glyph whose OBJECT is zero and
14629 whose CHARPOS is the position of a newline on that line.
14630 Note that on a TTY, there are more glyphs after that, which
14631 were produced by extend_face_to_end_of_line, but their
14632 CHARPOS is zero or negative. */
14633 int empty_line_p =
14634 (row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
14635 && INTEGERP (glyph->object) && glyph->charpos > 0
14636 /* On a TTY, continued and truncated rows also have a glyph at
14637 their end whose OBJECT is zero and whose CHARPOS is
14638 positive (the continuation and truncation glyphs), but such
14639 rows are obviously not "empty". */
14640 && !(row->continued_p || row->truncated_on_right_p);
14642 if (row->ends_in_ellipsis_p && pos_after == last_pos)
14644 ptrdiff_t ellipsis_pos;
14646 /* Scan back over the ellipsis glyphs. */
14647 if (!row->reversed_p)
14649 ellipsis_pos = (glyph - 1)->charpos;
14650 while (glyph > row->glyphs[TEXT_AREA]
14651 && (glyph - 1)->charpos == ellipsis_pos)
14652 glyph--, x -= glyph->pixel_width;
14653 /* That loop always goes one position too far, including
14654 the glyph before the ellipsis. So scan forward over
14655 that one. */
14656 x += glyph->pixel_width;
14657 glyph++;
14659 else /* row is reversed */
14661 ellipsis_pos = (glyph + 1)->charpos;
14662 while (glyph < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14663 && (glyph + 1)->charpos == ellipsis_pos)
14664 glyph++, x += glyph->pixel_width;
14665 x -= glyph->pixel_width;
14666 glyph--;
14669 else if (match_with_avoid_cursor)
14671 cursor = glyph_after;
14672 x = -1;
14674 else if (string_seen)
14676 int incr = row->reversed_p ? -1 : +1;
14678 /* Need to find the glyph that came out of a string which is
14679 present at point. That glyph is somewhere between
14680 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
14681 positioned between POS_BEFORE and POS_AFTER in the
14682 buffer. */
14683 struct glyph *start, *stop;
14684 ptrdiff_t pos = pos_before;
14686 x = -1;
14688 /* If the row ends in a newline from a display string,
14689 reordering could have moved the glyphs belonging to the
14690 string out of the [GLYPH_BEFORE..GLYPH_AFTER] range. So
14691 in this case we extend the search to the last glyph in
14692 the row that was not inserted by redisplay. */
14693 if (row->ends_in_newline_from_string_p)
14695 glyph_after = end;
14696 pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
14699 /* GLYPH_BEFORE and GLYPH_AFTER are the glyphs that
14700 correspond to POS_BEFORE and POS_AFTER, respectively. We
14701 need START and STOP in the order that corresponds to the
14702 row's direction as given by its reversed_p flag. If the
14703 directionality of characters between POS_BEFORE and
14704 POS_AFTER is the opposite of the row's base direction,
14705 these characters will have been reordered for display,
14706 and we need to reverse START and STOP. */
14707 if (!row->reversed_p)
14709 start = min (glyph_before, glyph_after);
14710 stop = max (glyph_before, glyph_after);
14712 else
14714 start = max (glyph_before, glyph_after);
14715 stop = min (glyph_before, glyph_after);
14717 for (glyph = start + incr;
14718 row->reversed_p ? glyph > stop : glyph < stop; )
14721 /* Any glyphs that come from the buffer are here because
14722 of bidi reordering. Skip them, and only pay
14723 attention to glyphs that came from some string. */
14724 if (STRINGP (glyph->object))
14726 Lisp_Object str;
14727 ptrdiff_t tem;
14728 /* If the display property covers the newline, we
14729 need to search for it one position farther. */
14730 ptrdiff_t lim = pos_after
14731 + (pos_after == MATRIX_ROW_END_CHARPOS (row) + delta);
14733 string_from_text_prop = 0;
14734 str = glyph->object;
14735 tem = string_buffer_position_lim (str, pos, lim, 0);
14736 if (tem == 0 /* from overlay */
14737 || pos <= tem)
14739 /* If the string from which this glyph came is
14740 found in the buffer at point, or at position
14741 that is closer to point than pos_after, then
14742 we've found the glyph we've been looking for.
14743 If it comes from an overlay (tem == 0), and
14744 it has the `cursor' property on one of its
14745 glyphs, record that glyph as a candidate for
14746 displaying the cursor. (As in the
14747 unidirectional version, we will display the
14748 cursor on the last candidate we find.) */
14749 if (tem == 0
14750 || tem == pt_old
14751 || (tem - pt_old > 0 && tem < pos_after))
14753 /* The glyphs from this string could have
14754 been reordered. Find the one with the
14755 smallest string position. Or there could
14756 be a character in the string with the
14757 `cursor' property, which means display
14758 cursor on that character's glyph. */
14759 ptrdiff_t strpos = glyph->charpos;
14761 if (tem)
14763 cursor = glyph;
14764 string_from_text_prop = 1;
14766 for ( ;
14767 (row->reversed_p ? glyph > stop : glyph < stop)
14768 && EQ (glyph->object, str);
14769 glyph += incr)
14771 Lisp_Object cprop;
14772 ptrdiff_t gpos = glyph->charpos;
14774 cprop = Fget_char_property (make_number (gpos),
14775 Qcursor,
14776 glyph->object);
14777 if (!NILP (cprop))
14779 cursor = glyph;
14780 break;
14782 if (tem && glyph->charpos < strpos)
14784 strpos = glyph->charpos;
14785 cursor = glyph;
14789 if (tem == pt_old
14790 || (tem - pt_old > 0 && tem < pos_after))
14791 goto compute_x;
14793 if (tem)
14794 pos = tem + 1; /* don't find previous instances */
14796 /* This string is not what we want; skip all of the
14797 glyphs that came from it. */
14798 while ((row->reversed_p ? glyph > stop : glyph < stop)
14799 && EQ (glyph->object, str))
14800 glyph += incr;
14802 else
14803 glyph += incr;
14806 /* If we reached the end of the line, and END was from a string,
14807 the cursor is not on this line. */
14808 if (cursor == NULL
14809 && (row->reversed_p ? glyph <= end : glyph >= end)
14810 && (row->reversed_p ? end > glyphs_end : end < glyphs_end)
14811 && STRINGP (end->object)
14812 && row->continued_p)
14813 return 0;
14815 /* A truncated row may not include PT among its character positions.
14816 Setting the cursor inside the scroll margin will trigger
14817 recalculation of hscroll in hscroll_window_tree. But if a
14818 display string covers point, defer to the string-handling
14819 code below to figure this out. */
14820 else if (row->truncated_on_left_p && pt_old < bpos_min)
14822 cursor = glyph_before;
14823 x = -1;
14825 else if ((row->truncated_on_right_p && pt_old > bpos_max)
14826 /* Zero-width characters produce no glyphs. */
14827 || (!empty_line_p
14828 && (row->reversed_p
14829 ? glyph_after > glyphs_end
14830 : glyph_after < glyphs_end)))
14832 cursor = glyph_after;
14833 x = -1;
14837 compute_x:
14838 if (cursor != NULL)
14839 glyph = cursor;
14840 else if (glyph == glyphs_end
14841 && pos_before == pos_after
14842 && STRINGP ((row->reversed_p
14843 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14844 : row->glyphs[TEXT_AREA])->object))
14846 /* If all the glyphs of this row came from strings, put the
14847 cursor on the first glyph of the row. This avoids having the
14848 cursor outside of the text area in this very rare and hard
14849 use case. */
14850 glyph =
14851 row->reversed_p
14852 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14853 : row->glyphs[TEXT_AREA];
14855 if (x < 0)
14857 struct glyph *g;
14859 /* Need to compute x that corresponds to GLYPH. */
14860 for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++)
14862 if (g >= row->glyphs[TEXT_AREA] + row->used[TEXT_AREA])
14863 emacs_abort ();
14864 x += g->pixel_width;
14868 /* ROW could be part of a continued line, which, under bidi
14869 reordering, might have other rows whose start and end charpos
14870 occlude point. Only set w->cursor if we found a better
14871 approximation to the cursor position than we have from previously
14872 examined candidate rows belonging to the same continued line. */
14873 if (/* We already have a candidate row. */
14874 w->cursor.vpos >= 0
14875 /* That candidate is not the row we are processing. */
14876 && MATRIX_ROW (matrix, w->cursor.vpos) != row
14877 /* Make sure cursor.vpos specifies a row whose start and end
14878 charpos occlude point, and it is valid candidate for being a
14879 cursor-row. This is because some callers of this function
14880 leave cursor.vpos at the row where the cursor was displayed
14881 during the last redisplay cycle. */
14882 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old
14883 && pt_old <= MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14884 && cursor_row_p (MATRIX_ROW (matrix, w->cursor.vpos)))
14886 struct glyph *g1
14887 = MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
14889 /* Don't consider glyphs that are outside TEXT_AREA. */
14890 if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
14891 return 0;
14892 /* Keep the candidate whose buffer position is the closest to
14893 point or has the `cursor' property. */
14894 if (/* Previous candidate is a glyph in TEXT_AREA of that row. */
14895 w->cursor.hpos >= 0
14896 && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
14897 && ((BUFFERP (g1->object)
14898 && (g1->charpos == pt_old /* An exact match always wins. */
14899 || (BUFFERP (glyph->object)
14900 && eabs (g1->charpos - pt_old)
14901 < eabs (glyph->charpos - pt_old))))
14902 /* Previous candidate is a glyph from a string that has
14903 a non-nil `cursor' property. */
14904 || (STRINGP (g1->object)
14905 && (!NILP (Fget_char_property (make_number (g1->charpos),
14906 Qcursor, g1->object))
14907 /* Previous candidate is from the same display
14908 string as this one, and the display string
14909 came from a text property. */
14910 || (EQ (g1->object, glyph->object)
14911 && string_from_text_prop)
14912 /* this candidate is from newline and its
14913 position is not an exact match */
14914 || (INTEGERP (glyph->object)
14915 && glyph->charpos != pt_old)))))
14916 return 0;
14917 /* If this candidate gives an exact match, use that. */
14918 if (!((BUFFERP (glyph->object) && glyph->charpos == pt_old)
14919 /* If this candidate is a glyph created for the
14920 terminating newline of a line, and point is on that
14921 newline, it wins because it's an exact match. */
14922 || (!row->continued_p
14923 && INTEGERP (glyph->object)
14924 && glyph->charpos == 0
14925 && pt_old == MATRIX_ROW_END_CHARPOS (row) - 1))
14926 /* Otherwise, keep the candidate that comes from a row
14927 spanning less buffer positions. This may win when one or
14928 both candidate positions are on glyphs that came from
14929 display strings, for which we cannot compare buffer
14930 positions. */
14931 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14932 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14933 < MATRIX_ROW_END_CHARPOS (row) - MATRIX_ROW_START_CHARPOS (row))
14934 return 0;
14936 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
14937 w->cursor.x = x;
14938 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
14939 w->cursor.y = row->y + dy;
14941 if (w == XWINDOW (selected_window))
14943 if (!row->continued_p
14944 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
14945 && row->x == 0)
14947 this_line_buffer = XBUFFER (w->contents);
14949 CHARPOS (this_line_start_pos)
14950 = MATRIX_ROW_START_CHARPOS (row) + delta;
14951 BYTEPOS (this_line_start_pos)
14952 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
14954 CHARPOS (this_line_end_pos)
14955 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
14956 BYTEPOS (this_line_end_pos)
14957 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
14959 this_line_y = w->cursor.y;
14960 this_line_pixel_height = row->height;
14961 this_line_vpos = w->cursor.vpos;
14962 this_line_start_x = row->x;
14964 else
14965 CHARPOS (this_line_start_pos) = 0;
14968 return 1;
14972 /* Run window scroll functions, if any, for WINDOW with new window
14973 start STARTP. Sets the window start of WINDOW to that position.
14975 We assume that the window's buffer is really current. */
14977 static struct text_pos
14978 run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
14980 struct window *w = XWINDOW (window);
14981 SET_MARKER_FROM_TEXT_POS (w->start, startp);
14983 eassert (current_buffer == XBUFFER (w->contents));
14985 if (!NILP (Vwindow_scroll_functions))
14987 run_hook_with_args_2 (Qwindow_scroll_functions, window,
14988 make_number (CHARPOS (startp)));
14989 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14990 /* In case the hook functions switch buffers. */
14991 set_buffer_internal (XBUFFER (w->contents));
14994 return startp;
14998 /* Make sure the line containing the cursor is fully visible.
14999 A value of 1 means there is nothing to be done.
15000 (Either the line is fully visible, or it cannot be made so,
15001 or we cannot tell.)
15003 If FORCE_P is non-zero, return 0 even if partial visible cursor row
15004 is higher than window.
15006 If CURRENT_MATRIX_P is non-zero, use the information from the
15007 window's current glyph matrix; otherwise use the desired glyph
15008 matrix.
15010 A value of 0 means the caller should do scrolling
15011 as if point had gone off the screen. */
15013 static int
15014 cursor_row_fully_visible_p (struct window *w, int force_p, int current_matrix_p)
15016 struct glyph_matrix *matrix;
15017 struct glyph_row *row;
15018 int window_height;
15020 if (!make_cursor_line_fully_visible_p)
15021 return 1;
15023 /* It's not always possible to find the cursor, e.g, when a window
15024 is full of overlay strings. Don't do anything in that case. */
15025 if (w->cursor.vpos < 0)
15026 return 1;
15028 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
15029 row = MATRIX_ROW (matrix, w->cursor.vpos);
15031 /* If the cursor row is not partially visible, there's nothing to do. */
15032 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
15033 return 1;
15035 /* If the row the cursor is in is taller than the window's height,
15036 it's not clear what to do, so do nothing. */
15037 window_height = window_box_height (w);
15038 if (row->height >= window_height)
15040 if (!force_p || MINI_WINDOW_P (w)
15041 || w->vscroll || w->cursor.vpos == 0)
15042 return 1;
15044 return 0;
15048 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
15049 non-zero means only WINDOW is redisplayed in redisplay_internal.
15050 TEMP_SCROLL_STEP has the same meaning as emacs_scroll_step, and is used
15051 in redisplay_window to bring a partially visible line into view in
15052 the case that only the cursor has moved.
15054 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
15055 last screen line's vertical height extends past the end of the screen.
15057 Value is
15059 1 if scrolling succeeded
15061 0 if scrolling didn't find point.
15063 -1 if new fonts have been loaded so that we must interrupt
15064 redisplay, adjust glyph matrices, and try again. */
15066 enum
15068 SCROLLING_SUCCESS,
15069 SCROLLING_FAILED,
15070 SCROLLING_NEED_LARGER_MATRICES
15073 /* If scroll-conservatively is more than this, never recenter.
15075 If you change this, don't forget to update the doc string of
15076 `scroll-conservatively' and the Emacs manual. */
15077 #define SCROLL_LIMIT 100
15079 static int
15080 try_scrolling (Lisp_Object window, int just_this_one_p,
15081 ptrdiff_t arg_scroll_conservatively, ptrdiff_t scroll_step,
15082 int temp_scroll_step, int last_line_misfit)
15084 struct window *w = XWINDOW (window);
15085 struct frame *f = XFRAME (w->frame);
15086 struct text_pos pos, startp;
15087 struct it it;
15088 int this_scroll_margin, scroll_max, rc, height;
15089 int dy = 0, amount_to_scroll = 0, scroll_down_p = 0;
15090 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
15091 Lisp_Object aggressive;
15092 /* We will never try scrolling more than this number of lines. */
15093 int scroll_limit = SCROLL_LIMIT;
15094 int frame_line_height = default_line_pixel_height (w);
15095 int window_total_lines
15096 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
15098 #ifdef GLYPH_DEBUG
15099 debug_method_add (w, "try_scrolling");
15100 #endif
15102 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15104 /* Compute scroll margin height in pixels. We scroll when point is
15105 within this distance from the top or bottom of the window. */
15106 if (scroll_margin > 0)
15107 this_scroll_margin = min (scroll_margin, window_total_lines / 4)
15108 * frame_line_height;
15109 else
15110 this_scroll_margin = 0;
15112 /* Force arg_scroll_conservatively to have a reasonable value, to
15113 avoid scrolling too far away with slow move_it_* functions. Note
15114 that the user can supply scroll-conservatively equal to
15115 `most-positive-fixnum', which can be larger than INT_MAX. */
15116 if (arg_scroll_conservatively > scroll_limit)
15118 arg_scroll_conservatively = scroll_limit + 1;
15119 scroll_max = scroll_limit * frame_line_height;
15121 else if (scroll_step || arg_scroll_conservatively || temp_scroll_step)
15122 /* Compute how much we should try to scroll maximally to bring
15123 point into view. */
15124 scroll_max = (max (scroll_step,
15125 max (arg_scroll_conservatively, temp_scroll_step))
15126 * frame_line_height);
15127 else if (NUMBERP (BVAR (current_buffer, scroll_down_aggressively))
15128 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively)))
15129 /* We're trying to scroll because of aggressive scrolling but no
15130 scroll_step is set. Choose an arbitrary one. */
15131 scroll_max = 10 * frame_line_height;
15132 else
15133 scroll_max = 0;
15135 too_near_end:
15137 /* Decide whether to scroll down. */
15138 if (PT > CHARPOS (startp))
15140 int scroll_margin_y;
15142 /* Compute the pixel ypos of the scroll margin, then move IT to
15143 either that ypos or PT, whichever comes first. */
15144 start_display (&it, w, startp);
15145 scroll_margin_y = it.last_visible_y - this_scroll_margin
15146 - frame_line_height * extra_scroll_margin_lines;
15147 move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
15148 (MOVE_TO_POS | MOVE_TO_Y));
15150 if (PT > CHARPOS (it.current.pos))
15152 int y0 = line_bottom_y (&it);
15153 /* Compute how many pixels below window bottom to stop searching
15154 for PT. This avoids costly search for PT that is far away if
15155 the user limited scrolling by a small number of lines, but
15156 always finds PT if scroll_conservatively is set to a large
15157 number, such as most-positive-fixnum. */
15158 int slack = max (scroll_max, 10 * frame_line_height);
15159 int y_to_move = it.last_visible_y + slack;
15161 /* Compute the distance from the scroll margin to PT or to
15162 the scroll limit, whichever comes first. This should
15163 include the height of the cursor line, to make that line
15164 fully visible. */
15165 move_it_to (&it, PT, -1, y_to_move,
15166 -1, MOVE_TO_POS | MOVE_TO_Y);
15167 dy = line_bottom_y (&it) - y0;
15169 if (dy > scroll_max)
15170 return SCROLLING_FAILED;
15172 if (dy > 0)
15173 scroll_down_p = 1;
15177 if (scroll_down_p)
15179 /* Point is in or below the bottom scroll margin, so move the
15180 window start down. If scrolling conservatively, move it just
15181 enough down to make point visible. If scroll_step is set,
15182 move it down by scroll_step. */
15183 if (arg_scroll_conservatively)
15184 amount_to_scroll
15185 = min (max (dy, frame_line_height),
15186 frame_line_height * arg_scroll_conservatively);
15187 else if (scroll_step || temp_scroll_step)
15188 amount_to_scroll = scroll_max;
15189 else
15191 aggressive = BVAR (current_buffer, scroll_up_aggressively);
15192 height = WINDOW_BOX_TEXT_HEIGHT (w);
15193 if (NUMBERP (aggressive))
15195 double float_amount = XFLOATINT (aggressive) * height;
15196 int aggressive_scroll = float_amount;
15197 if (aggressive_scroll == 0 && float_amount > 0)
15198 aggressive_scroll = 1;
15199 /* Don't let point enter the scroll margin near top of
15200 the window. This could happen if the value of
15201 scroll_up_aggressively is too large and there are
15202 non-zero margins, because scroll_up_aggressively
15203 means put point that fraction of window height
15204 _from_the_bottom_margin_. */
15205 if (aggressive_scroll + 2*this_scroll_margin > height)
15206 aggressive_scroll = height - 2*this_scroll_margin;
15207 amount_to_scroll = dy + aggressive_scroll;
15211 if (amount_to_scroll <= 0)
15212 return SCROLLING_FAILED;
15214 start_display (&it, w, startp);
15215 if (arg_scroll_conservatively <= scroll_limit)
15216 move_it_vertically (&it, amount_to_scroll);
15217 else
15219 /* Extra precision for users who set scroll-conservatively
15220 to a large number: make sure the amount we scroll
15221 the window start is never less than amount_to_scroll,
15222 which was computed as distance from window bottom to
15223 point. This matters when lines at window top and lines
15224 below window bottom have different height. */
15225 struct it it1;
15226 void *it1data = NULL;
15227 /* We use a temporary it1 because line_bottom_y can modify
15228 its argument, if it moves one line down; see there. */
15229 int start_y;
15231 SAVE_IT (it1, it, it1data);
15232 start_y = line_bottom_y (&it1);
15233 do {
15234 RESTORE_IT (&it, &it, it1data);
15235 move_it_by_lines (&it, 1);
15236 SAVE_IT (it1, it, it1data);
15237 } while (line_bottom_y (&it1) - start_y < amount_to_scroll);
15240 /* If STARTP is unchanged, move it down another screen line. */
15241 if (CHARPOS (it.current.pos) == CHARPOS (startp))
15242 move_it_by_lines (&it, 1);
15243 startp = it.current.pos;
15245 else
15247 struct text_pos scroll_margin_pos = startp;
15248 int y_offset = 0;
15250 /* See if point is inside the scroll margin at the top of the
15251 window. */
15252 if (this_scroll_margin)
15254 int y_start;
15256 start_display (&it, w, startp);
15257 y_start = it.current_y;
15258 move_it_vertically (&it, this_scroll_margin);
15259 scroll_margin_pos = it.current.pos;
15260 /* If we didn't move enough before hitting ZV, request
15261 additional amount of scroll, to move point out of the
15262 scroll margin. */
15263 if (IT_CHARPOS (it) == ZV
15264 && it.current_y - y_start < this_scroll_margin)
15265 y_offset = this_scroll_margin - (it.current_y - y_start);
15268 if (PT < CHARPOS (scroll_margin_pos))
15270 /* Point is in the scroll margin at the top of the window or
15271 above what is displayed in the window. */
15272 int y0, y_to_move;
15274 /* Compute the vertical distance from PT to the scroll
15275 margin position. Move as far as scroll_max allows, or
15276 one screenful, or 10 screen lines, whichever is largest.
15277 Give up if distance is greater than scroll_max or if we
15278 didn't reach the scroll margin position. */
15279 SET_TEXT_POS (pos, PT, PT_BYTE);
15280 start_display (&it, w, pos);
15281 y0 = it.current_y;
15282 y_to_move = max (it.last_visible_y,
15283 max (scroll_max, 10 * frame_line_height));
15284 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
15285 y_to_move, -1,
15286 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
15287 dy = it.current_y - y0;
15288 if (dy > scroll_max
15289 || IT_CHARPOS (it) < CHARPOS (scroll_margin_pos))
15290 return SCROLLING_FAILED;
15292 /* Additional scroll for when ZV was too close to point. */
15293 dy += y_offset;
15295 /* Compute new window start. */
15296 start_display (&it, w, startp);
15298 if (arg_scroll_conservatively)
15299 amount_to_scroll = max (dy, frame_line_height *
15300 max (scroll_step, temp_scroll_step));
15301 else if (scroll_step || temp_scroll_step)
15302 amount_to_scroll = scroll_max;
15303 else
15305 aggressive = BVAR (current_buffer, scroll_down_aggressively);
15306 height = WINDOW_BOX_TEXT_HEIGHT (w);
15307 if (NUMBERP (aggressive))
15309 double float_amount = XFLOATINT (aggressive) * height;
15310 int aggressive_scroll = float_amount;
15311 if (aggressive_scroll == 0 && float_amount > 0)
15312 aggressive_scroll = 1;
15313 /* Don't let point enter the scroll margin near
15314 bottom of the window, if the value of
15315 scroll_down_aggressively happens to be too
15316 large. */
15317 if (aggressive_scroll + 2*this_scroll_margin > height)
15318 aggressive_scroll = height - 2*this_scroll_margin;
15319 amount_to_scroll = dy + aggressive_scroll;
15323 if (amount_to_scroll <= 0)
15324 return SCROLLING_FAILED;
15326 move_it_vertically_backward (&it, amount_to_scroll);
15327 startp = it.current.pos;
15331 /* Run window scroll functions. */
15332 startp = run_window_scroll_functions (window, startp);
15334 /* Display the window. Give up if new fonts are loaded, or if point
15335 doesn't appear. */
15336 if (!try_window (window, startp, 0))
15337 rc = SCROLLING_NEED_LARGER_MATRICES;
15338 else if (w->cursor.vpos < 0)
15340 clear_glyph_matrix (w->desired_matrix);
15341 rc = SCROLLING_FAILED;
15343 else
15345 /* Maybe forget recorded base line for line number display. */
15346 if (!just_this_one_p
15347 || current_buffer->clip_changed
15348 || BEG_UNCHANGED < CHARPOS (startp))
15349 w->base_line_number = 0;
15351 /* If cursor ends up on a partially visible line,
15352 treat that as being off the bottom of the screen. */
15353 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0)
15354 /* It's possible that the cursor is on the first line of the
15355 buffer, which is partially obscured due to a vscroll
15356 (Bug#7537). In that case, avoid looping forever. */
15357 && extra_scroll_margin_lines < w->desired_matrix->nrows - 1)
15359 clear_glyph_matrix (w->desired_matrix);
15360 ++extra_scroll_margin_lines;
15361 goto too_near_end;
15363 rc = SCROLLING_SUCCESS;
15366 return rc;
15370 /* Compute a suitable window start for window W if display of W starts
15371 on a continuation line. Value is non-zero if a new window start
15372 was computed.
15374 The new window start will be computed, based on W's width, starting
15375 from the start of the continued line. It is the start of the
15376 screen line with the minimum distance from the old start W->start. */
15378 static int
15379 compute_window_start_on_continuation_line (struct window *w)
15381 struct text_pos pos, start_pos;
15382 int window_start_changed_p = 0;
15384 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
15386 /* If window start is on a continuation line... Window start may be
15387 < BEGV in case there's invisible text at the start of the
15388 buffer (M-x rmail, for example). */
15389 if (CHARPOS (start_pos) > BEGV
15390 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
15392 struct it it;
15393 struct glyph_row *row;
15395 /* Handle the case that the window start is out of range. */
15396 if (CHARPOS (start_pos) < BEGV)
15397 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
15398 else if (CHARPOS (start_pos) > ZV)
15399 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
15401 /* Find the start of the continued line. This should be fast
15402 because find_newline is fast (newline cache). */
15403 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
15404 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
15405 row, DEFAULT_FACE_ID);
15406 reseat_at_previous_visible_line_start (&it);
15408 /* If the line start is "too far" away from the window start,
15409 say it takes too much time to compute a new window start. */
15410 if (CHARPOS (start_pos) - IT_CHARPOS (it)
15411 /* PXW: Do we need upper bounds here? */
15412 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
15414 int min_distance, distance;
15416 /* Move forward by display lines to find the new window
15417 start. If window width was enlarged, the new start can
15418 be expected to be > the old start. If window width was
15419 decreased, the new window start will be < the old start.
15420 So, we're looking for the display line start with the
15421 minimum distance from the old window start. */
15422 pos = it.current.pos;
15423 min_distance = INFINITY;
15424 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
15425 distance < min_distance)
15427 min_distance = distance;
15428 pos = it.current.pos;
15429 if (it.line_wrap == WORD_WRAP)
15431 /* Under WORD_WRAP, move_it_by_lines is likely to
15432 overshoot and stop not at the first, but the
15433 second character from the left margin. So in
15434 that case, we need a more tight control on the X
15435 coordinate of the iterator than move_it_by_lines
15436 promises in its contract. The method is to first
15437 go to the last (rightmost) visible character of a
15438 line, then move to the leftmost character on the
15439 next line in a separate call. */
15440 move_it_to (&it, ZV, it.last_visible_x, it.current_y, -1,
15441 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
15442 move_it_to (&it, ZV, 0,
15443 it.current_y + it.max_ascent + it.max_descent, -1,
15444 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
15446 else
15447 move_it_by_lines (&it, 1);
15450 /* Set the window start there. */
15451 SET_MARKER_FROM_TEXT_POS (w->start, pos);
15452 window_start_changed_p = 1;
15456 return window_start_changed_p;
15460 /* Try cursor movement in case text has not changed in window WINDOW,
15461 with window start STARTP. Value is
15463 CURSOR_MOVEMENT_SUCCESS if successful
15465 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
15467 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
15468 display. *SCROLL_STEP is set to 1, under certain circumstances, if
15469 we want to scroll as if scroll-step were set to 1. See the code.
15471 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
15472 which case we have to abort this redisplay, and adjust matrices
15473 first. */
15475 enum
15477 CURSOR_MOVEMENT_SUCCESS,
15478 CURSOR_MOVEMENT_CANNOT_BE_USED,
15479 CURSOR_MOVEMENT_MUST_SCROLL,
15480 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
15483 static int
15484 try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_step)
15486 struct window *w = XWINDOW (window);
15487 struct frame *f = XFRAME (w->frame);
15488 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
15490 #ifdef GLYPH_DEBUG
15491 if (inhibit_try_cursor_movement)
15492 return rc;
15493 #endif
15495 /* Previously, there was a check for Lisp integer in the
15496 if-statement below. Now, this field is converted to
15497 ptrdiff_t, thus zero means invalid position in a buffer. */
15498 eassert (w->last_point > 0);
15499 /* Likewise there was a check whether window_end_vpos is nil or larger
15500 than the window. Now window_end_vpos is int and so never nil, but
15501 let's leave eassert to check whether it fits in the window. */
15502 eassert (w->window_end_vpos < w->current_matrix->nrows);
15504 /* Handle case where text has not changed, only point, and it has
15505 not moved off the frame. */
15506 if (/* Point may be in this window. */
15507 PT >= CHARPOS (startp)
15508 /* Selective display hasn't changed. */
15509 && !current_buffer->clip_changed
15510 /* Function force-mode-line-update is used to force a thorough
15511 redisplay. It sets either windows_or_buffers_changed or
15512 update_mode_lines. So don't take a shortcut here for these
15513 cases. */
15514 && !update_mode_lines
15515 && !windows_or_buffers_changed
15516 && !f->cursor_type_changed
15517 && NILP (Vshow_trailing_whitespace)
15518 /* This code is not used for mini-buffer for the sake of the case
15519 of redisplaying to replace an echo area message; since in
15520 that case the mini-buffer contents per se are usually
15521 unchanged. This code is of no real use in the mini-buffer
15522 since the handling of this_line_start_pos, etc., in redisplay
15523 handles the same cases. */
15524 && !EQ (window, minibuf_window)
15525 && (FRAME_WINDOW_P (f)
15526 || !overlay_arrow_in_current_buffer_p ()))
15528 int this_scroll_margin, top_scroll_margin;
15529 struct glyph_row *row = NULL;
15530 int frame_line_height = default_line_pixel_height (w);
15531 int window_total_lines
15532 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
15534 #ifdef GLYPH_DEBUG
15535 debug_method_add (w, "cursor movement");
15536 #endif
15538 /* Scroll if point within this distance from the top or bottom
15539 of the window. This is a pixel value. */
15540 if (scroll_margin > 0)
15542 this_scroll_margin = min (scroll_margin, window_total_lines / 4);
15543 this_scroll_margin *= frame_line_height;
15545 else
15546 this_scroll_margin = 0;
15548 top_scroll_margin = this_scroll_margin;
15549 if (WINDOW_WANTS_HEADER_LINE_P (w))
15550 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
15552 /* Start with the row the cursor was displayed during the last
15553 not paused redisplay. Give up if that row is not valid. */
15554 if (w->last_cursor_vpos < 0
15555 || w->last_cursor_vpos >= w->current_matrix->nrows)
15556 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15557 else
15559 row = MATRIX_ROW (w->current_matrix, w->last_cursor_vpos);
15560 if (row->mode_line_p)
15561 ++row;
15562 if (!row->enabled_p)
15563 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15566 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
15568 int scroll_p = 0, must_scroll = 0;
15569 int last_y = window_text_bottom_y (w) - this_scroll_margin;
15571 if (PT > w->last_point)
15573 /* Point has moved forward. */
15574 while (MATRIX_ROW_END_CHARPOS (row) < PT
15575 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
15577 eassert (row->enabled_p);
15578 ++row;
15581 /* If the end position of a row equals the start
15582 position of the next row, and PT is at that position,
15583 we would rather display cursor in the next line. */
15584 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15585 && MATRIX_ROW_END_CHARPOS (row) == PT
15586 && row < MATRIX_MODE_LINE_ROW (w->current_matrix)
15587 && MATRIX_ROW_START_CHARPOS (row+1) == PT
15588 && !cursor_row_p (row))
15589 ++row;
15591 /* If within the scroll margin, scroll. Note that
15592 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
15593 the next line would be drawn, and that
15594 this_scroll_margin can be zero. */
15595 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
15596 || PT > MATRIX_ROW_END_CHARPOS (row)
15597 /* Line is completely visible last line in window
15598 and PT is to be set in the next line. */
15599 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
15600 && PT == MATRIX_ROW_END_CHARPOS (row)
15601 && !row->ends_at_zv_p
15602 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
15603 scroll_p = 1;
15605 else if (PT < w->last_point)
15607 /* Cursor has to be moved backward. Note that PT >=
15608 CHARPOS (startp) because of the outer if-statement. */
15609 while (!row->mode_line_p
15610 && (MATRIX_ROW_START_CHARPOS (row) > PT
15611 || (MATRIX_ROW_START_CHARPOS (row) == PT
15612 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
15613 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
15614 row > w->current_matrix->rows
15615 && (row-1)->ends_in_newline_from_string_p))))
15616 && (row->y > top_scroll_margin
15617 || CHARPOS (startp) == BEGV))
15619 eassert (row->enabled_p);
15620 --row;
15623 /* Consider the following case: Window starts at BEGV,
15624 there is invisible, intangible text at BEGV, so that
15625 display starts at some point START > BEGV. It can
15626 happen that we are called with PT somewhere between
15627 BEGV and START. Try to handle that case. */
15628 if (row < w->current_matrix->rows
15629 || row->mode_line_p)
15631 row = w->current_matrix->rows;
15632 if (row->mode_line_p)
15633 ++row;
15636 /* Due to newlines in overlay strings, we may have to
15637 skip forward over overlay strings. */
15638 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15639 && MATRIX_ROW_END_CHARPOS (row) == PT
15640 && !cursor_row_p (row))
15641 ++row;
15643 /* If within the scroll margin, scroll. */
15644 if (row->y < top_scroll_margin
15645 && CHARPOS (startp) != BEGV)
15646 scroll_p = 1;
15648 else
15650 /* Cursor did not move. So don't scroll even if cursor line
15651 is partially visible, as it was so before. */
15652 rc = CURSOR_MOVEMENT_SUCCESS;
15655 if (PT < MATRIX_ROW_START_CHARPOS (row)
15656 || PT > MATRIX_ROW_END_CHARPOS (row))
15658 /* if PT is not in the glyph row, give up. */
15659 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15660 must_scroll = 1;
15662 else if (rc != CURSOR_MOVEMENT_SUCCESS
15663 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
15665 struct glyph_row *row1;
15667 /* If rows are bidi-reordered and point moved, back up
15668 until we find a row that does not belong to a
15669 continuation line. This is because we must consider
15670 all rows of a continued line as candidates for the
15671 new cursor positioning, since row start and end
15672 positions change non-linearly with vertical position
15673 in such rows. */
15674 /* FIXME: Revisit this when glyph ``spilling'' in
15675 continuation lines' rows is implemented for
15676 bidi-reordered rows. */
15677 for (row1 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
15678 MATRIX_ROW_CONTINUATION_LINE_P (row);
15679 --row)
15681 /* If we hit the beginning of the displayed portion
15682 without finding the first row of a continued
15683 line, give up. */
15684 if (row <= row1)
15686 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15687 break;
15689 eassert (row->enabled_p);
15692 if (must_scroll)
15694 else if (rc != CURSOR_MOVEMENT_SUCCESS
15695 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
15696 /* Make sure this isn't a header line by any chance, since
15697 then MATRIX_ROW_PARTIALLY_VISIBLE_P might yield non-zero. */
15698 && !row->mode_line_p
15699 && make_cursor_line_fully_visible_p)
15701 if (PT == MATRIX_ROW_END_CHARPOS (row)
15702 && !row->ends_at_zv_p
15703 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
15704 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15705 else if (row->height > window_box_height (w))
15707 /* If we end up in a partially visible line, let's
15708 make it fully visible, except when it's taller
15709 than the window, in which case we can't do much
15710 about it. */
15711 *scroll_step = 1;
15712 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15714 else
15716 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
15717 if (!cursor_row_fully_visible_p (w, 0, 1))
15718 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15719 else
15720 rc = CURSOR_MOVEMENT_SUCCESS;
15723 else if (scroll_p)
15724 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15725 else if (rc != CURSOR_MOVEMENT_SUCCESS
15726 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
15728 /* With bidi-reordered rows, there could be more than
15729 one candidate row whose start and end positions
15730 occlude point. We need to let set_cursor_from_row
15731 find the best candidate. */
15732 /* FIXME: Revisit this when glyph ``spilling'' in
15733 continuation lines' rows is implemented for
15734 bidi-reordered rows. */
15735 int rv = 0;
15739 int at_zv_p = 0, exact_match_p = 0;
15741 if (MATRIX_ROW_START_CHARPOS (row) <= PT
15742 && PT <= MATRIX_ROW_END_CHARPOS (row)
15743 && cursor_row_p (row))
15744 rv |= set_cursor_from_row (w, row, w->current_matrix,
15745 0, 0, 0, 0);
15746 /* As soon as we've found the exact match for point,
15747 or the first suitable row whose ends_at_zv_p flag
15748 is set, we are done. */
15749 if (rv)
15751 at_zv_p = MATRIX_ROW (w->current_matrix,
15752 w->cursor.vpos)->ends_at_zv_p;
15753 if (!at_zv_p
15754 && w->cursor.hpos >= 0
15755 && w->cursor.hpos < MATRIX_ROW_USED (w->current_matrix,
15756 w->cursor.vpos))
15758 struct glyph_row *candidate =
15759 MATRIX_ROW (w->current_matrix, w->cursor.vpos);
15760 struct glyph *g =
15761 candidate->glyphs[TEXT_AREA] + w->cursor.hpos;
15762 ptrdiff_t endpos = MATRIX_ROW_END_CHARPOS (candidate);
15764 exact_match_p =
15765 (BUFFERP (g->object) && g->charpos == PT)
15766 || (INTEGERP (g->object)
15767 && (g->charpos == PT
15768 || (g->charpos == 0 && endpos - 1 == PT)));
15770 if (at_zv_p || exact_match_p)
15772 rc = CURSOR_MOVEMENT_SUCCESS;
15773 break;
15776 if (MATRIX_ROW_BOTTOM_Y (row) == last_y)
15777 break;
15778 ++row;
15780 while (((MATRIX_ROW_CONTINUATION_LINE_P (row)
15781 || row->continued_p)
15782 && MATRIX_ROW_BOTTOM_Y (row) <= last_y)
15783 || (MATRIX_ROW_START_CHARPOS (row) == PT
15784 && MATRIX_ROW_BOTTOM_Y (row) < last_y));
15785 /* If we didn't find any candidate rows, or exited the
15786 loop before all the candidates were examined, signal
15787 to the caller that this method failed. */
15788 if (rc != CURSOR_MOVEMENT_SUCCESS
15789 && !(rv
15790 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
15791 && !row->continued_p))
15792 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15793 else if (rv)
15794 rc = CURSOR_MOVEMENT_SUCCESS;
15796 else
15800 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
15802 rc = CURSOR_MOVEMENT_SUCCESS;
15803 break;
15805 ++row;
15807 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15808 && MATRIX_ROW_START_CHARPOS (row) == PT
15809 && cursor_row_p (row));
15814 return rc;
15818 void
15819 set_vertical_scroll_bar (struct window *w)
15821 ptrdiff_t start, end, whole;
15823 /* Calculate the start and end positions for the current window.
15824 At some point, it would be nice to choose between scrollbars
15825 which reflect the whole buffer size, with special markers
15826 indicating narrowing, and scrollbars which reflect only the
15827 visible region.
15829 Note that mini-buffers sometimes aren't displaying any text. */
15830 if (!MINI_WINDOW_P (w)
15831 || (w == XWINDOW (minibuf_window)
15832 && NILP (echo_area_buffer[0])))
15834 struct buffer *buf = XBUFFER (w->contents);
15835 whole = BUF_ZV (buf) - BUF_BEGV (buf);
15836 start = marker_position (w->start) - BUF_BEGV (buf);
15837 /* I don't think this is guaranteed to be right. For the
15838 moment, we'll pretend it is. */
15839 end = BUF_Z (buf) - w->window_end_pos - BUF_BEGV (buf);
15841 if (end < start)
15842 end = start;
15843 if (whole < (end - start))
15844 whole = end - start;
15846 else
15847 start = end = whole = 0;
15849 /* Indicate what this scroll bar ought to be displaying now. */
15850 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
15851 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
15852 (w, end - start, whole, start);
15856 void
15857 set_horizontal_scroll_bar (struct window *w)
15859 int start, end, whole, portion;
15861 if (!MINI_WINDOW_P (w)
15862 || (w == XWINDOW (minibuf_window)
15863 && NILP (echo_area_buffer[0])))
15865 struct buffer *b = XBUFFER (w->contents);
15866 struct buffer *old_buffer = NULL;
15867 struct it it;
15868 struct text_pos startp;
15870 if (b != current_buffer)
15872 old_buffer = current_buffer;
15873 set_buffer_internal (b);
15876 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15877 start_display (&it, w, startp);
15878 it.last_visible_x = INT_MAX;
15879 whole = move_it_to (&it, -1, INT_MAX, window_box_height (w), -1,
15880 MOVE_TO_X | MOVE_TO_Y);
15881 /* whole = move_it_to (&it, w->window_end_pos, INT_MAX,
15882 window_box_height (w), -1,
15883 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); */
15885 start = w->hscroll * FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w));
15886 end = start + window_box_width (w, TEXT_AREA);
15887 portion = end - start;
15888 /* After enlarging a horizontally scrolled window such that it
15889 gets at least as wide as the text it contains, make sure that
15890 the thumb doesn't fill the entire scroll bar so we can still
15891 drag it back to see the entire text. */
15892 whole = max (whole, end);
15894 if (it.bidi_p)
15896 Lisp_Object pdir;
15898 pdir = Fcurrent_bidi_paragraph_direction (Qnil);
15899 if (EQ (pdir, Qright_to_left))
15901 start = whole - end;
15902 end = start + portion;
15906 if (old_buffer)
15907 set_buffer_internal (old_buffer);
15909 else
15910 start = end = whole = portion = 0;
15912 w->hscroll_whole = whole;
15914 /* Indicate what this scroll bar ought to be displaying now. */
15915 if (FRAME_TERMINAL (XFRAME (w->frame))->set_horizontal_scroll_bar_hook)
15916 (*FRAME_TERMINAL (XFRAME (w->frame))->set_horizontal_scroll_bar_hook)
15917 (w, portion, whole, start);
15921 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
15922 selected_window is redisplayed.
15924 We can return without actually redisplaying the window if fonts has been
15925 changed on window's frame. In that case, redisplay_internal will retry.
15927 As one of the important parts of redisplaying a window, we need to
15928 decide whether the previous window-start position (stored in the
15929 window's w->start marker position) is still valid, and if it isn't,
15930 recompute it. Some details about that:
15932 . The previous window-start could be in a continuation line, in
15933 which case we need to recompute it when the window width
15934 changes. See compute_window_start_on_continuation_line and its
15935 call below.
15937 . The text that changed since last redisplay could include the
15938 previous window-start position. In that case, we try to salvage
15939 what we can from the current glyph matrix by calling
15940 try_scrolling, which see.
15942 . Some Emacs command could force us to use a specific window-start
15943 position by setting the window's force_start flag, or gently
15944 propose doing that by setting the window's optional_new_start
15945 flag. In these cases, we try using the specified start point if
15946 that succeeds (i.e. the window desired matrix is successfully
15947 recomputed, and point location is within the window). In case
15948 of optional_new_start, we first check if the specified start
15949 position is feasible, i.e. if it will allow point to be
15950 displayed in the window. If using the specified start point
15951 fails, e.g., if new fonts are needed to be loaded, we abort the
15952 redisplay cycle and leave it up to the next cycle to figure out
15953 things.
15955 . Note that the window's force_start flag is sometimes set by
15956 redisplay itself, when it decides that the previous window start
15957 point is fine and should be kept. Search for "goto force_start"
15958 below to see the details. Like the values of window-start
15959 specified outside of redisplay, these internally-deduced values
15960 are tested for feasibility, and ignored if found to be
15961 unfeasible.
15963 . Note that the function try_window, used to completely redisplay
15964 a window, accepts the window's start point as its argument.
15965 This is used several times in the redisplay code to control
15966 where the window start will be, according to user options such
15967 as scroll-conservatively, and also to ensure the screen line
15968 showing point will be fully (as opposed to partially) visible on
15969 display. */
15971 static void
15972 redisplay_window (Lisp_Object window, bool just_this_one_p)
15974 struct window *w = XWINDOW (window);
15975 struct frame *f = XFRAME (w->frame);
15976 struct buffer *buffer = XBUFFER (w->contents);
15977 struct buffer *old = current_buffer;
15978 struct text_pos lpoint, opoint, startp;
15979 int update_mode_line;
15980 int tem;
15981 struct it it;
15982 /* Record it now because it's overwritten. */
15983 bool current_matrix_up_to_date_p = false;
15984 bool used_current_matrix_p = false;
15985 /* This is less strict than current_matrix_up_to_date_p.
15986 It indicates that the buffer contents and narrowing are unchanged. */
15987 bool buffer_unchanged_p = false;
15988 int temp_scroll_step = 0;
15989 ptrdiff_t count = SPECPDL_INDEX ();
15990 int rc;
15991 int centering_position = -1;
15992 int last_line_misfit = 0;
15993 ptrdiff_t beg_unchanged, end_unchanged;
15994 int frame_line_height;
15996 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15997 opoint = lpoint;
15999 #ifdef GLYPH_DEBUG
16000 *w->desired_matrix->method = 0;
16001 #endif
16003 if (!just_this_one_p
16004 && REDISPLAY_SOME_P ()
16005 && !w->redisplay
16006 && !f->redisplay
16007 && !buffer->text->redisplay
16008 && BUF_PT (buffer) == w->last_point)
16009 return;
16011 /* Make sure that both W's markers are valid. */
16012 eassert (XMARKER (w->start)->buffer == buffer);
16013 eassert (XMARKER (w->pointm)->buffer == buffer);
16015 /* We come here again if we need to run window-text-change-functions
16016 below. */
16017 restart:
16018 reconsider_clip_changes (w);
16019 frame_line_height = default_line_pixel_height (w);
16021 /* Has the mode line to be updated? */
16022 update_mode_line = (w->update_mode_line
16023 || update_mode_lines
16024 || buffer->clip_changed
16025 || buffer->prevent_redisplay_optimizations_p);
16027 if (!just_this_one_p)
16028 /* If `just_this_one_p' is set, we apparently set must_be_updated_p more
16029 cleverly elsewhere. */
16030 w->must_be_updated_p = true;
16032 if (MINI_WINDOW_P (w))
16034 if (w == XWINDOW (echo_area_window)
16035 && !NILP (echo_area_buffer[0]))
16037 if (update_mode_line)
16038 /* We may have to update a tty frame's menu bar or a
16039 tool-bar. Example `M-x C-h C-h C-g'. */
16040 goto finish_menu_bars;
16041 else
16042 /* We've already displayed the echo area glyphs in this window. */
16043 goto finish_scroll_bars;
16045 else if ((w != XWINDOW (minibuf_window)
16046 || minibuf_level == 0)
16047 /* When buffer is nonempty, redisplay window normally. */
16048 && BUF_Z (XBUFFER (w->contents)) == BUF_BEG (XBUFFER (w->contents))
16049 /* Quail displays non-mini buffers in minibuffer window.
16050 In that case, redisplay the window normally. */
16051 && !NILP (Fmemq (w->contents, Vminibuffer_list)))
16053 /* W is a mini-buffer window, but it's not active, so clear
16054 it. */
16055 int yb = window_text_bottom_y (w);
16056 struct glyph_row *row;
16057 int y;
16059 for (y = 0, row = w->desired_matrix->rows;
16060 y < yb;
16061 y += row->height, ++row)
16062 blank_row (w, row, y);
16063 goto finish_scroll_bars;
16066 clear_glyph_matrix (w->desired_matrix);
16069 /* Otherwise set up data on this window; select its buffer and point
16070 value. */
16071 /* Really select the buffer, for the sake of buffer-local
16072 variables. */
16073 set_buffer_internal_1 (XBUFFER (w->contents));
16075 current_matrix_up_to_date_p
16076 = (w->window_end_valid
16077 && !current_buffer->clip_changed
16078 && !current_buffer->prevent_redisplay_optimizations_p
16079 && !window_outdated (w));
16081 /* Run the window-text-change-functions
16082 if it is possible that the text on the screen has changed
16083 (either due to modification of the text, or any other reason). */
16084 if (!current_matrix_up_to_date_p
16085 && !NILP (Vwindow_text_change_functions))
16087 safe_run_hooks (Qwindow_text_change_functions);
16088 goto restart;
16091 beg_unchanged = BEG_UNCHANGED;
16092 end_unchanged = END_UNCHANGED;
16094 SET_TEXT_POS (opoint, PT, PT_BYTE);
16096 specbind (Qinhibit_point_motion_hooks, Qt);
16098 buffer_unchanged_p
16099 = (w->window_end_valid
16100 && !current_buffer->clip_changed
16101 && !window_outdated (w));
16103 /* When windows_or_buffers_changed is non-zero, we can't rely
16104 on the window end being valid, so set it to zero there. */
16105 if (windows_or_buffers_changed)
16107 /* If window starts on a continuation line, maybe adjust the
16108 window start in case the window's width changed. */
16109 if (XMARKER (w->start)->buffer == current_buffer)
16110 compute_window_start_on_continuation_line (w);
16112 w->window_end_valid = false;
16113 /* If so, we also can't rely on current matrix
16114 and should not fool try_cursor_movement below. */
16115 current_matrix_up_to_date_p = false;
16118 /* Some sanity checks. */
16119 CHECK_WINDOW_END (w);
16120 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
16121 emacs_abort ();
16122 if (BYTEPOS (opoint) < CHARPOS (opoint))
16123 emacs_abort ();
16125 if (mode_line_update_needed (w))
16126 update_mode_line = 1;
16128 /* Point refers normally to the selected window. For any other
16129 window, set up appropriate value. */
16130 if (!EQ (window, selected_window))
16132 ptrdiff_t new_pt = marker_position (w->pointm);
16133 ptrdiff_t new_pt_byte = marker_byte_position (w->pointm);
16135 if (new_pt < BEGV)
16137 new_pt = BEGV;
16138 new_pt_byte = BEGV_BYTE;
16139 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
16141 else if (new_pt > (ZV - 1))
16143 new_pt = ZV;
16144 new_pt_byte = ZV_BYTE;
16145 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
16148 /* We don't use SET_PT so that the point-motion hooks don't run. */
16149 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
16152 /* If any of the character widths specified in the display table
16153 have changed, invalidate the width run cache. It's true that
16154 this may be a bit late to catch such changes, but the rest of
16155 redisplay goes (non-fatally) haywire when the display table is
16156 changed, so why should we worry about doing any better? */
16157 if (current_buffer->width_run_cache
16158 || (current_buffer->base_buffer
16159 && current_buffer->base_buffer->width_run_cache))
16161 struct Lisp_Char_Table *disptab = buffer_display_table ();
16163 if (! disptab_matches_widthtab
16164 (disptab, XVECTOR (BVAR (current_buffer, width_table))))
16166 struct buffer *buf = current_buffer;
16168 if (buf->base_buffer)
16169 buf = buf->base_buffer;
16170 invalidate_region_cache (buf, buf->width_run_cache, BEG, Z);
16171 recompute_width_table (current_buffer, disptab);
16175 /* If window-start is screwed up, choose a new one. */
16176 if (XMARKER (w->start)->buffer != current_buffer)
16177 goto recenter;
16179 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16181 /* If someone specified a new starting point but did not insist,
16182 check whether it can be used. */
16183 if ((w->optional_new_start || window_frozen_p (w))
16184 && CHARPOS (startp) >= BEGV
16185 && CHARPOS (startp) <= ZV)
16187 ptrdiff_t it_charpos;
16189 w->optional_new_start = 0;
16190 start_display (&it, w, startp);
16191 move_it_to (&it, PT, 0, it.last_visible_y, -1,
16192 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
16193 /* Record IT's position now, since line_bottom_y might change
16194 that. */
16195 it_charpos = IT_CHARPOS (it);
16196 /* Make sure we set the force_start flag only if the cursor row
16197 will be fully visible. Otherwise, the code under force_start
16198 label below will try to move point back into view, which is
16199 not what the code which sets optional_new_start wants. */
16200 if ((it.current_y == 0 || line_bottom_y (&it) < it.last_visible_y)
16201 && !w->force_start)
16203 if (it_charpos == PT)
16204 w->force_start = 1;
16205 /* IT may overshoot PT if text at PT is invisible. */
16206 else if (it_charpos > PT && CHARPOS (startp) <= PT)
16207 w->force_start = 1;
16208 #ifdef GLYPH_DEBUG
16209 if (w->force_start)
16211 if (window_frozen_p (w))
16212 debug_method_add (w, "set force_start from frozen window start");
16213 else
16214 debug_method_add (w, "set force_start from optional_new_start");
16216 #endif
16220 force_start:
16222 /* Handle case where place to start displaying has been specified,
16223 unless the specified location is outside the accessible range. */
16224 if (w->force_start)
16226 /* We set this later on if we have to adjust point. */
16227 int new_vpos = -1;
16229 w->force_start = 0;
16230 w->vscroll = 0;
16231 w->window_end_valid = 0;
16233 /* Forget any recorded base line for line number display. */
16234 if (!buffer_unchanged_p)
16235 w->base_line_number = 0;
16237 /* Redisplay the mode line. Select the buffer properly for that.
16238 Also, run the hook window-scroll-functions
16239 because we have scrolled. */
16240 /* Note, we do this after clearing force_start because
16241 if there's an error, it is better to forget about force_start
16242 than to get into an infinite loop calling the hook functions
16243 and having them get more errors. */
16244 if (!update_mode_line
16245 || ! NILP (Vwindow_scroll_functions))
16247 update_mode_line = 1;
16248 w->update_mode_line = 1;
16249 startp = run_window_scroll_functions (window, startp);
16252 if (CHARPOS (startp) < BEGV)
16253 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
16254 else if (CHARPOS (startp) > ZV)
16255 SET_TEXT_POS (startp, ZV, ZV_BYTE);
16257 /* Redisplay, then check if cursor has been set during the
16258 redisplay. Give up if new fonts were loaded. */
16259 /* We used to issue a CHECK_MARGINS argument to try_window here,
16260 but this causes scrolling to fail when point begins inside
16261 the scroll margin (bug#148) -- cyd */
16262 if (!try_window (window, startp, 0))
16264 w->force_start = 1;
16265 clear_glyph_matrix (w->desired_matrix);
16266 goto need_larger_matrices;
16269 if (w->cursor.vpos < 0)
16271 /* If point does not appear, try to move point so it does
16272 appear. The desired matrix has been built above, so we
16273 can use it here. */
16274 new_vpos = window_box_height (w) / 2;
16277 if (!cursor_row_fully_visible_p (w, 0, 0))
16279 /* Point does appear, but on a line partly visible at end of window.
16280 Move it back to a fully-visible line. */
16281 new_vpos = window_box_height (w);
16282 /* But if window_box_height suggests a Y coordinate that is
16283 not less than we already have, that line will clearly not
16284 be fully visible, so give up and scroll the display.
16285 This can happen when the default face uses a font whose
16286 dimensions are different from the frame's default
16287 font. */
16288 if (new_vpos >= w->cursor.y)
16290 w->cursor.vpos = -1;
16291 clear_glyph_matrix (w->desired_matrix);
16292 goto try_to_scroll;
16295 else if (w->cursor.vpos >= 0)
16297 /* Some people insist on not letting point enter the scroll
16298 margin, even though this part handles windows that didn't
16299 scroll at all. */
16300 int window_total_lines
16301 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
16302 int margin = min (scroll_margin, window_total_lines / 4);
16303 int pixel_margin = margin * frame_line_height;
16304 bool header_line = WINDOW_WANTS_HEADER_LINE_P (w);
16306 /* Note: We add an extra FRAME_LINE_HEIGHT, because the loop
16307 below, which finds the row to move point to, advances by
16308 the Y coordinate of the _next_ row, see the definition of
16309 MATRIX_ROW_BOTTOM_Y. */
16310 if (w->cursor.vpos < margin + header_line)
16312 w->cursor.vpos = -1;
16313 clear_glyph_matrix (w->desired_matrix);
16314 goto try_to_scroll;
16316 else
16318 int window_height = window_box_height (w);
16320 if (header_line)
16321 window_height += CURRENT_HEADER_LINE_HEIGHT (w);
16322 if (w->cursor.y >= window_height - pixel_margin)
16324 w->cursor.vpos = -1;
16325 clear_glyph_matrix (w->desired_matrix);
16326 goto try_to_scroll;
16331 /* If we need to move point for either of the above reasons,
16332 now actually do it. */
16333 if (new_vpos >= 0)
16335 struct glyph_row *row;
16337 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
16338 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
16339 ++row;
16341 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
16342 MATRIX_ROW_START_BYTEPOS (row));
16344 if (w != XWINDOW (selected_window))
16345 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
16346 else if (current_buffer == old)
16347 SET_TEXT_POS (lpoint, PT, PT_BYTE);
16349 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
16351 /* If we are highlighting the region, then we just changed
16352 the region, so redisplay to show it. */
16353 /* FIXME: We need to (re)run pre-redisplay-function! */
16354 /* if (markpos_of_region () >= 0)
16356 clear_glyph_matrix (w->desired_matrix);
16357 if (!try_window (window, startp, 0))
16358 goto need_larger_matrices;
16362 if (w->cursor.vpos < 0 || !cursor_row_fully_visible_p (w, 0, 0))
16364 clear_glyph_matrix (w->desired_matrix);
16365 goto try_to_scroll;
16368 #ifdef GLYPH_DEBUG
16369 debug_method_add (w, "forced window start");
16370 #endif
16371 goto done;
16374 /* Handle case where text has not changed, only point, and it has
16375 not moved off the frame, and we are not retrying after hscroll.
16376 (current_matrix_up_to_date_p is nonzero when retrying.) */
16377 if (current_matrix_up_to_date_p
16378 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
16379 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
16381 switch (rc)
16383 case CURSOR_MOVEMENT_SUCCESS:
16384 used_current_matrix_p = 1;
16385 goto done;
16387 case CURSOR_MOVEMENT_MUST_SCROLL:
16388 goto try_to_scroll;
16390 default:
16391 emacs_abort ();
16394 /* If current starting point was originally the beginning of a line
16395 but no longer is, find a new starting point. */
16396 else if (w->start_at_line_beg
16397 && !(CHARPOS (startp) <= BEGV
16398 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
16400 #ifdef GLYPH_DEBUG
16401 debug_method_add (w, "recenter 1");
16402 #endif
16403 goto recenter;
16406 /* Try scrolling with try_window_id. Value is > 0 if update has
16407 been done, it is -1 if we know that the same window start will
16408 not work. It is 0 if unsuccessful for some other reason. */
16409 else if ((tem = try_window_id (w)) != 0)
16411 #ifdef GLYPH_DEBUG
16412 debug_method_add (w, "try_window_id %d", tem);
16413 #endif
16415 if (f->fonts_changed)
16416 goto need_larger_matrices;
16417 if (tem > 0)
16418 goto done;
16420 /* Otherwise try_window_id has returned -1 which means that we
16421 don't want the alternative below this comment to execute. */
16423 else if (CHARPOS (startp) >= BEGV
16424 && CHARPOS (startp) <= ZV
16425 && PT >= CHARPOS (startp)
16426 && (CHARPOS (startp) < ZV
16427 /* Avoid starting at end of buffer. */
16428 || CHARPOS (startp) == BEGV
16429 || !window_outdated (w)))
16431 int d1, d2, d5, d6;
16432 int rtop, rbot;
16434 /* If first window line is a continuation line, and window start
16435 is inside the modified region, but the first change is before
16436 current window start, we must select a new window start.
16438 However, if this is the result of a down-mouse event (e.g. by
16439 extending the mouse-drag-overlay), we don't want to select a
16440 new window start, since that would change the position under
16441 the mouse, resulting in an unwanted mouse-movement rather
16442 than a simple mouse-click. */
16443 if (!w->start_at_line_beg
16444 && NILP (do_mouse_tracking)
16445 && CHARPOS (startp) > BEGV
16446 && CHARPOS (startp) > BEG + beg_unchanged
16447 && CHARPOS (startp) <= Z - end_unchanged
16448 /* Even if w->start_at_line_beg is nil, a new window may
16449 start at a line_beg, since that's how set_buffer_window
16450 sets it. So, we need to check the return value of
16451 compute_window_start_on_continuation_line. (See also
16452 bug#197). */
16453 && XMARKER (w->start)->buffer == current_buffer
16454 && compute_window_start_on_continuation_line (w)
16455 /* It doesn't make sense to force the window start like we
16456 do at label force_start if it is already known that point
16457 will not be fully visible in the resulting window, because
16458 doing so will move point from its correct position
16459 instead of scrolling the window to bring point into view.
16460 See bug#9324. */
16461 && pos_visible_p (w, PT, &d1, &d2, &rtop, &rbot, &d5, &d6)
16462 /* A very tall row could need more than the window height,
16463 in which case we accept that it is partially visible. */
16464 && (rtop != 0) == (rbot != 0))
16466 w->force_start = 1;
16467 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16468 #ifdef GLYPH_DEBUG
16469 debug_method_add (w, "recomputed window start in continuation line");
16470 #endif
16471 goto force_start;
16474 #ifdef GLYPH_DEBUG
16475 debug_method_add (w, "same window start");
16476 #endif
16478 /* Try to redisplay starting at same place as before.
16479 If point has not moved off frame, accept the results. */
16480 if (!current_matrix_up_to_date_p
16481 /* Don't use try_window_reusing_current_matrix in this case
16482 because a window scroll function can have changed the
16483 buffer. */
16484 || !NILP (Vwindow_scroll_functions)
16485 || MINI_WINDOW_P (w)
16486 || !(used_current_matrix_p
16487 = try_window_reusing_current_matrix (w)))
16489 IF_DEBUG (debug_method_add (w, "1"));
16490 if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
16491 /* -1 means we need to scroll.
16492 0 means we need new matrices, but fonts_changed
16493 is set in that case, so we will detect it below. */
16494 goto try_to_scroll;
16497 if (f->fonts_changed)
16498 goto need_larger_matrices;
16500 if (w->cursor.vpos >= 0)
16502 if (!just_this_one_p
16503 || current_buffer->clip_changed
16504 || BEG_UNCHANGED < CHARPOS (startp))
16505 /* Forget any recorded base line for line number display. */
16506 w->base_line_number = 0;
16508 if (!cursor_row_fully_visible_p (w, 1, 0))
16510 clear_glyph_matrix (w->desired_matrix);
16511 last_line_misfit = 1;
16513 /* Drop through and scroll. */
16514 else
16515 goto done;
16517 else
16518 clear_glyph_matrix (w->desired_matrix);
16521 try_to_scroll:
16523 /* Redisplay the mode line. Select the buffer properly for that. */
16524 if (!update_mode_line)
16526 update_mode_line = 1;
16527 w->update_mode_line = 1;
16530 /* Try to scroll by specified few lines. */
16531 if ((scroll_conservatively
16532 || emacs_scroll_step
16533 || temp_scroll_step
16534 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively))
16535 || NUMBERP (BVAR (current_buffer, scroll_down_aggressively)))
16536 && CHARPOS (startp) >= BEGV
16537 && CHARPOS (startp) <= ZV)
16539 /* The function returns -1 if new fonts were loaded, 1 if
16540 successful, 0 if not successful. */
16541 int ss = try_scrolling (window, just_this_one_p,
16542 scroll_conservatively,
16543 emacs_scroll_step,
16544 temp_scroll_step, last_line_misfit);
16545 switch (ss)
16547 case SCROLLING_SUCCESS:
16548 goto done;
16550 case SCROLLING_NEED_LARGER_MATRICES:
16551 goto need_larger_matrices;
16553 case SCROLLING_FAILED:
16554 break;
16556 default:
16557 emacs_abort ();
16561 /* Finally, just choose a place to start which positions point
16562 according to user preferences. */
16564 recenter:
16566 #ifdef GLYPH_DEBUG
16567 debug_method_add (w, "recenter");
16568 #endif
16570 /* Forget any previously recorded base line for line number display. */
16571 if (!buffer_unchanged_p)
16572 w->base_line_number = 0;
16574 /* Determine the window start relative to point. */
16575 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
16576 it.current_y = it.last_visible_y;
16577 if (centering_position < 0)
16579 int window_total_lines
16580 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
16581 int margin =
16582 scroll_margin > 0
16583 ? min (scroll_margin, window_total_lines / 4)
16584 : 0;
16585 ptrdiff_t margin_pos = CHARPOS (startp);
16586 Lisp_Object aggressive;
16587 int scrolling_up;
16589 /* If there is a scroll margin at the top of the window, find
16590 its character position. */
16591 if (margin
16592 /* Cannot call start_display if startp is not in the
16593 accessible region of the buffer. This can happen when we
16594 have just switched to a different buffer and/or changed
16595 its restriction. In that case, startp is initialized to
16596 the character position 1 (BEGV) because we did not yet
16597 have chance to display the buffer even once. */
16598 && BEGV <= CHARPOS (startp) && CHARPOS (startp) <= ZV)
16600 struct it it1;
16601 void *it1data = NULL;
16603 SAVE_IT (it1, it, it1data);
16604 start_display (&it1, w, startp);
16605 move_it_vertically (&it1, margin * frame_line_height);
16606 margin_pos = IT_CHARPOS (it1);
16607 RESTORE_IT (&it, &it, it1data);
16609 scrolling_up = PT > margin_pos;
16610 aggressive =
16611 scrolling_up
16612 ? BVAR (current_buffer, scroll_up_aggressively)
16613 : BVAR (current_buffer, scroll_down_aggressively);
16615 if (!MINI_WINDOW_P (w)
16616 && (scroll_conservatively > SCROLL_LIMIT || NUMBERP (aggressive)))
16618 int pt_offset = 0;
16620 /* Setting scroll-conservatively overrides
16621 scroll-*-aggressively. */
16622 if (!scroll_conservatively && NUMBERP (aggressive))
16624 double float_amount = XFLOATINT (aggressive);
16626 pt_offset = float_amount * WINDOW_BOX_TEXT_HEIGHT (w);
16627 if (pt_offset == 0 && float_amount > 0)
16628 pt_offset = 1;
16629 if (pt_offset && margin > 0)
16630 margin -= 1;
16632 /* Compute how much to move the window start backward from
16633 point so that point will be displayed where the user
16634 wants it. */
16635 if (scrolling_up)
16637 centering_position = it.last_visible_y;
16638 if (pt_offset)
16639 centering_position -= pt_offset;
16640 centering_position -=
16641 frame_line_height * (1 + margin + (last_line_misfit != 0))
16642 + WINDOW_HEADER_LINE_HEIGHT (w);
16643 /* Don't let point enter the scroll margin near top of
16644 the window. */
16645 if (centering_position < margin * frame_line_height)
16646 centering_position = margin * frame_line_height;
16648 else
16649 centering_position = margin * frame_line_height + pt_offset;
16651 else
16652 /* Set the window start half the height of the window backward
16653 from point. */
16654 centering_position = window_box_height (w) / 2;
16656 move_it_vertically_backward (&it, centering_position);
16658 eassert (IT_CHARPOS (it) >= BEGV);
16660 /* The function move_it_vertically_backward may move over more
16661 than the specified y-distance. If it->w is small, e.g. a
16662 mini-buffer window, we may end up in front of the window's
16663 display area. Start displaying at the start of the line
16664 containing PT in this case. */
16665 if (it.current_y <= 0)
16667 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
16668 move_it_vertically_backward (&it, 0);
16669 it.current_y = 0;
16672 it.current_x = it.hpos = 0;
16674 /* Set the window start position here explicitly, to avoid an
16675 infinite loop in case the functions in window-scroll-functions
16676 get errors. */
16677 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
16679 /* Run scroll hooks. */
16680 startp = run_window_scroll_functions (window, it.current.pos);
16682 /* Redisplay the window. */
16683 if (!current_matrix_up_to_date_p
16684 || windows_or_buffers_changed
16685 || f->cursor_type_changed
16686 /* Don't use try_window_reusing_current_matrix in this case
16687 because it can have changed the buffer. */
16688 || !NILP (Vwindow_scroll_functions)
16689 || !just_this_one_p
16690 || MINI_WINDOW_P (w)
16691 || !(used_current_matrix_p
16692 = try_window_reusing_current_matrix (w)))
16693 try_window (window, startp, 0);
16695 /* If new fonts have been loaded (due to fontsets), give up. We
16696 have to start a new redisplay since we need to re-adjust glyph
16697 matrices. */
16698 if (f->fonts_changed)
16699 goto need_larger_matrices;
16701 /* If cursor did not appear assume that the middle of the window is
16702 in the first line of the window. Do it again with the next line.
16703 (Imagine a window of height 100, displaying two lines of height
16704 60. Moving back 50 from it->last_visible_y will end in the first
16705 line.) */
16706 if (w->cursor.vpos < 0)
16708 if (w->window_end_valid && PT >= Z - w->window_end_pos)
16710 clear_glyph_matrix (w->desired_matrix);
16711 move_it_by_lines (&it, 1);
16712 try_window (window, it.current.pos, 0);
16714 else if (PT < IT_CHARPOS (it))
16716 clear_glyph_matrix (w->desired_matrix);
16717 move_it_by_lines (&it, -1);
16718 try_window (window, it.current.pos, 0);
16720 else
16722 /* Not much we can do about it. */
16726 /* Consider the following case: Window starts at BEGV, there is
16727 invisible, intangible text at BEGV, so that display starts at
16728 some point START > BEGV. It can happen that we are called with
16729 PT somewhere between BEGV and START. Try to handle that case,
16730 and similar ones. */
16731 if (w->cursor.vpos < 0)
16733 /* First, try locating the proper glyph row for PT. */
16734 struct glyph_row *row =
16735 row_containing_pos (w, PT, w->current_matrix->rows, NULL, 0);
16737 /* Sometimes point is at the beginning of invisible text that is
16738 before the 1st character displayed in the row. In that case,
16739 row_containing_pos fails to find the row, because no glyphs
16740 with appropriate buffer positions are present in the row.
16741 Therefore, we next try to find the row which shows the 1st
16742 position after the invisible text. */
16743 if (!row)
16745 Lisp_Object val =
16746 get_char_property_and_overlay (make_number (PT), Qinvisible,
16747 Qnil, NULL);
16749 if (TEXT_PROP_MEANS_INVISIBLE (val))
16751 ptrdiff_t alt_pos;
16752 Lisp_Object invis_end =
16753 Fnext_single_char_property_change (make_number (PT), Qinvisible,
16754 Qnil, Qnil);
16756 if (NATNUMP (invis_end))
16757 alt_pos = XFASTINT (invis_end);
16758 else
16759 alt_pos = ZV;
16760 row = row_containing_pos (w, alt_pos, w->current_matrix->rows,
16761 NULL, 0);
16764 /* Finally, fall back on the first row of the window after the
16765 header line (if any). This is slightly better than not
16766 displaying the cursor at all. */
16767 if (!row)
16769 row = w->current_matrix->rows;
16770 if (row->mode_line_p)
16771 ++row;
16773 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
16776 if (!cursor_row_fully_visible_p (w, 0, 0))
16778 /* If vscroll is enabled, disable it and try again. */
16779 if (w->vscroll)
16781 w->vscroll = 0;
16782 clear_glyph_matrix (w->desired_matrix);
16783 goto recenter;
16786 /* Users who set scroll-conservatively to a large number want
16787 point just above/below the scroll margin. If we ended up
16788 with point's row partially visible, move the window start to
16789 make that row fully visible and out of the margin. */
16790 if (scroll_conservatively > SCROLL_LIMIT)
16792 int window_total_lines
16793 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) * frame_line_height;
16794 int margin =
16795 scroll_margin > 0
16796 ? min (scroll_margin, window_total_lines / 4)
16797 : 0;
16798 int move_down = w->cursor.vpos >= window_total_lines / 2;
16800 move_it_by_lines (&it, move_down ? margin + 1 : -(margin + 1));
16801 clear_glyph_matrix (w->desired_matrix);
16802 if (1 == try_window (window, it.current.pos,
16803 TRY_WINDOW_CHECK_MARGINS))
16804 goto done;
16807 /* If centering point failed to make the whole line visible,
16808 put point at the top instead. That has to make the whole line
16809 visible, if it can be done. */
16810 if (centering_position == 0)
16811 goto done;
16813 clear_glyph_matrix (w->desired_matrix);
16814 centering_position = 0;
16815 goto recenter;
16818 done:
16820 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16821 w->start_at_line_beg = (CHARPOS (startp) == BEGV
16822 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n');
16824 /* Display the mode line, if we must. */
16825 if ((update_mode_line
16826 /* If window not full width, must redo its mode line
16827 if (a) the window to its side is being redone and
16828 (b) we do a frame-based redisplay. This is a consequence
16829 of how inverted lines are drawn in frame-based redisplay. */
16830 || (!just_this_one_p
16831 && !FRAME_WINDOW_P (f)
16832 && !WINDOW_FULL_WIDTH_P (w))
16833 /* Line number to display. */
16834 || w->base_line_pos > 0
16835 /* Column number is displayed and different from the one displayed. */
16836 || (w->column_number_displayed != -1
16837 && (w->column_number_displayed != current_column ())))
16838 /* This means that the window has a mode line. */
16839 && (WINDOW_WANTS_MODELINE_P (w)
16840 || WINDOW_WANTS_HEADER_LINE_P (w)))
16843 display_mode_lines (w);
16845 /* If mode line height has changed, arrange for a thorough
16846 immediate redisplay using the correct mode line height. */
16847 if (WINDOW_WANTS_MODELINE_P (w)
16848 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
16850 f->fonts_changed = 1;
16851 w->mode_line_height = -1;
16852 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
16853 = DESIRED_MODE_LINE_HEIGHT (w);
16856 /* If header line height has changed, arrange for a thorough
16857 immediate redisplay using the correct header line height. */
16858 if (WINDOW_WANTS_HEADER_LINE_P (w)
16859 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
16861 f->fonts_changed = 1;
16862 w->header_line_height = -1;
16863 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
16864 = DESIRED_HEADER_LINE_HEIGHT (w);
16867 if (f->fonts_changed)
16868 goto need_larger_matrices;
16871 if (!line_number_displayed && w->base_line_pos != -1)
16873 w->base_line_pos = 0;
16874 w->base_line_number = 0;
16877 finish_menu_bars:
16879 /* When we reach a frame's selected window, redo the frame's menu bar. */
16880 if (update_mode_line
16881 && EQ (FRAME_SELECTED_WINDOW (f), window))
16883 int redisplay_menu_p = 0;
16885 if (FRAME_WINDOW_P (f))
16887 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
16888 || defined (HAVE_NS) || defined (USE_GTK)
16889 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
16890 #else
16891 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
16892 #endif
16894 else
16895 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
16897 if (redisplay_menu_p)
16898 display_menu_bar (w);
16900 #ifdef HAVE_WINDOW_SYSTEM
16901 if (FRAME_WINDOW_P (f))
16903 #if defined (USE_GTK) || defined (HAVE_NS)
16904 if (FRAME_EXTERNAL_TOOL_BAR (f))
16905 redisplay_tool_bar (f);
16906 #else
16907 if (WINDOWP (f->tool_bar_window)
16908 && (FRAME_TOOL_BAR_LINES (f) > 0
16909 || !NILP (Vauto_resize_tool_bars))
16910 && redisplay_tool_bar (f))
16911 ignore_mouse_drag_p = 1;
16912 #endif
16914 #endif
16917 #ifdef HAVE_WINDOW_SYSTEM
16918 if (FRAME_WINDOW_P (f)
16919 && update_window_fringes (w, (just_this_one_p
16920 || (!used_current_matrix_p && !overlay_arrow_seen)
16921 || w->pseudo_window_p)))
16923 update_begin (f);
16924 block_input ();
16925 if (draw_window_fringes (w, 1))
16927 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
16928 x_draw_right_divider (w);
16929 else
16930 x_draw_vertical_border (w);
16932 unblock_input ();
16933 update_end (f);
16936 if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
16937 x_draw_bottom_divider (w);
16938 #endif /* HAVE_WINDOW_SYSTEM */
16940 /* We go to this label, with fonts_changed set, if it is
16941 necessary to try again using larger glyph matrices.
16942 We have to redeem the scroll bar even in this case,
16943 because the loop in redisplay_internal expects that. */
16944 need_larger_matrices:
16946 finish_scroll_bars:
16948 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w) || WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w))
16950 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
16951 /* Set the thumb's position and size. */
16952 set_vertical_scroll_bar (w);
16954 if (WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w))
16955 /* Set the thumb's position and size. */
16956 set_horizontal_scroll_bar (w);
16958 /* Note that we actually used the scroll bar attached to this
16959 window, so it shouldn't be deleted at the end of redisplay. */
16960 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
16961 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
16964 /* Restore current_buffer and value of point in it. The window
16965 update may have changed the buffer, so first make sure `opoint'
16966 is still valid (Bug#6177). */
16967 if (CHARPOS (opoint) < BEGV)
16968 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
16969 else if (CHARPOS (opoint) > ZV)
16970 TEMP_SET_PT_BOTH (Z, Z_BYTE);
16971 else
16972 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
16974 set_buffer_internal_1 (old);
16975 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
16976 shorter. This can be caused by log truncation in *Messages*. */
16977 if (CHARPOS (lpoint) <= ZV)
16978 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
16980 unbind_to (count, Qnil);
16984 /* Build the complete desired matrix of WINDOW with a window start
16985 buffer position POS.
16987 Value is 1 if successful. It is zero if fonts were loaded during
16988 redisplay which makes re-adjusting glyph matrices necessary, and -1
16989 if point would appear in the scroll margins.
16990 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
16991 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
16992 set in FLAGS.) */
16995 try_window (Lisp_Object window, struct text_pos pos, int flags)
16997 struct window *w = XWINDOW (window);
16998 struct it it;
16999 struct glyph_row *last_text_row = NULL;
17000 struct frame *f = XFRAME (w->frame);
17001 int frame_line_height = default_line_pixel_height (w);
17003 /* Make POS the new window start. */
17004 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
17006 /* Mark cursor position as unknown. No overlay arrow seen. */
17007 w->cursor.vpos = -1;
17008 overlay_arrow_seen = 0;
17010 /* Initialize iterator and info to start at POS. */
17011 start_display (&it, w, pos);
17012 it.glyph_row->reversed_p = false;
17014 /* Display all lines of W. */
17015 while (it.current_y < it.last_visible_y)
17017 if (display_line (&it))
17018 last_text_row = it.glyph_row - 1;
17019 if (f->fonts_changed && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
17020 return 0;
17023 /* Don't let the cursor end in the scroll margins. */
17024 if ((flags & TRY_WINDOW_CHECK_MARGINS)
17025 && !MINI_WINDOW_P (w))
17027 int this_scroll_margin;
17028 int window_total_lines
17029 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
17031 if (scroll_margin > 0)
17033 this_scroll_margin = min (scroll_margin, window_total_lines / 4);
17034 this_scroll_margin *= frame_line_height;
17036 else
17037 this_scroll_margin = 0;
17039 if ((w->cursor.y >= 0 /* not vscrolled */
17040 && w->cursor.y < this_scroll_margin
17041 && CHARPOS (pos) > BEGV
17042 && IT_CHARPOS (it) < ZV)
17043 /* rms: considering make_cursor_line_fully_visible_p here
17044 seems to give wrong results. We don't want to recenter
17045 when the last line is partly visible, we want to allow
17046 that case to be handled in the usual way. */
17047 || w->cursor.y > it.last_visible_y - this_scroll_margin - 1)
17049 w->cursor.vpos = -1;
17050 clear_glyph_matrix (w->desired_matrix);
17051 return -1;
17055 /* If bottom moved off end of frame, change mode line percentage. */
17056 if (w->window_end_pos <= 0 && Z != IT_CHARPOS (it))
17057 w->update_mode_line = 1;
17059 /* Set window_end_pos to the offset of the last character displayed
17060 on the window from the end of current_buffer. Set
17061 window_end_vpos to its row number. */
17062 if (last_text_row)
17064 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
17065 adjust_window_ends (w, last_text_row, 0);
17066 eassert
17067 (MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->desired_matrix,
17068 w->window_end_vpos)));
17070 else
17072 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
17073 w->window_end_pos = Z - ZV;
17074 w->window_end_vpos = 0;
17077 /* But that is not valid info until redisplay finishes. */
17078 w->window_end_valid = 0;
17079 return 1;
17084 /************************************************************************
17085 Window redisplay reusing current matrix when buffer has not changed
17086 ************************************************************************/
17088 /* Try redisplay of window W showing an unchanged buffer with a
17089 different window start than the last time it was displayed by
17090 reusing its current matrix. Value is non-zero if successful.
17091 W->start is the new window start. */
17093 static int
17094 try_window_reusing_current_matrix (struct window *w)
17096 struct frame *f = XFRAME (w->frame);
17097 struct glyph_row *bottom_row;
17098 struct it it;
17099 struct run run;
17100 struct text_pos start, new_start;
17101 int nrows_scrolled, i;
17102 struct glyph_row *last_text_row;
17103 struct glyph_row *last_reused_text_row;
17104 struct glyph_row *start_row;
17105 int start_vpos, min_y, max_y;
17107 #ifdef GLYPH_DEBUG
17108 if (inhibit_try_window_reusing)
17109 return 0;
17110 #endif
17112 if (/* This function doesn't handle terminal frames. */
17113 !FRAME_WINDOW_P (f)
17114 /* Don't try to reuse the display if windows have been split
17115 or such. */
17116 || windows_or_buffers_changed
17117 || f->cursor_type_changed)
17118 return 0;
17120 /* Can't do this if showing trailing whitespace. */
17121 if (!NILP (Vshow_trailing_whitespace))
17122 return 0;
17124 /* If top-line visibility has changed, give up. */
17125 if (WINDOW_WANTS_HEADER_LINE_P (w)
17126 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
17127 return 0;
17129 /* Give up if old or new display is scrolled vertically. We could
17130 make this function handle this, but right now it doesn't. */
17131 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
17132 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
17133 return 0;
17135 /* The variable new_start now holds the new window start. The old
17136 start `start' can be determined from the current matrix. */
17137 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
17138 start = start_row->minpos;
17139 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
17141 /* Clear the desired matrix for the display below. */
17142 clear_glyph_matrix (w->desired_matrix);
17144 if (CHARPOS (new_start) <= CHARPOS (start))
17146 /* Don't use this method if the display starts with an ellipsis
17147 displayed for invisible text. It's not easy to handle that case
17148 below, and it's certainly not worth the effort since this is
17149 not a frequent case. */
17150 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
17151 return 0;
17153 IF_DEBUG (debug_method_add (w, "twu1"));
17155 /* Display up to a row that can be reused. The variable
17156 last_text_row is set to the last row displayed that displays
17157 text. Note that it.vpos == 0 if or if not there is a
17158 header-line; it's not the same as the MATRIX_ROW_VPOS! */
17159 start_display (&it, w, new_start);
17160 w->cursor.vpos = -1;
17161 last_text_row = last_reused_text_row = NULL;
17163 while (it.current_y < it.last_visible_y && !f->fonts_changed)
17165 /* If we have reached into the characters in the START row,
17166 that means the line boundaries have changed. So we
17167 can't start copying with the row START. Maybe it will
17168 work to start copying with the following row. */
17169 while (IT_CHARPOS (it) > CHARPOS (start))
17171 /* Advance to the next row as the "start". */
17172 start_row++;
17173 start = start_row->minpos;
17174 /* If there are no more rows to try, or just one, give up. */
17175 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
17176 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
17177 || CHARPOS (start) == ZV)
17179 clear_glyph_matrix (w->desired_matrix);
17180 return 0;
17183 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
17185 /* If we have reached alignment, we can copy the rest of the
17186 rows. */
17187 if (IT_CHARPOS (it) == CHARPOS (start)
17188 /* Don't accept "alignment" inside a display vector,
17189 since start_row could have started in the middle of
17190 that same display vector (thus their character
17191 positions match), and we have no way of telling if
17192 that is the case. */
17193 && it.current.dpvec_index < 0)
17194 break;
17196 it.glyph_row->reversed_p = false;
17197 if (display_line (&it))
17198 last_text_row = it.glyph_row - 1;
17202 /* A value of current_y < last_visible_y means that we stopped
17203 at the previous window start, which in turn means that we
17204 have at least one reusable row. */
17205 if (it.current_y < it.last_visible_y)
17207 struct glyph_row *row;
17209 /* IT.vpos always starts from 0; it counts text lines. */
17210 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
17212 /* Find PT if not already found in the lines displayed. */
17213 if (w->cursor.vpos < 0)
17215 int dy = it.current_y - start_row->y;
17217 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
17218 row = row_containing_pos (w, PT, row, NULL, dy);
17219 if (row)
17220 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
17221 dy, nrows_scrolled);
17222 else
17224 clear_glyph_matrix (w->desired_matrix);
17225 return 0;
17229 /* Scroll the display. Do it before the current matrix is
17230 changed. The problem here is that update has not yet
17231 run, i.e. part of the current matrix is not up to date.
17232 scroll_run_hook will clear the cursor, and use the
17233 current matrix to get the height of the row the cursor is
17234 in. */
17235 run.current_y = start_row->y;
17236 run.desired_y = it.current_y;
17237 run.height = it.last_visible_y - it.current_y;
17239 if (run.height > 0 && run.current_y != run.desired_y)
17241 update_begin (f);
17242 FRAME_RIF (f)->update_window_begin_hook (w);
17243 FRAME_RIF (f)->clear_window_mouse_face (w);
17244 FRAME_RIF (f)->scroll_run_hook (w, &run);
17245 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
17246 update_end (f);
17249 /* Shift current matrix down by nrows_scrolled lines. */
17250 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
17251 rotate_matrix (w->current_matrix,
17252 start_vpos,
17253 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
17254 nrows_scrolled);
17256 /* Disable lines that must be updated. */
17257 for (i = 0; i < nrows_scrolled; ++i)
17258 (start_row + i)->enabled_p = false;
17260 /* Re-compute Y positions. */
17261 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
17262 max_y = it.last_visible_y;
17263 for (row = start_row + nrows_scrolled;
17264 row < bottom_row;
17265 ++row)
17267 row->y = it.current_y;
17268 row->visible_height = row->height;
17270 if (row->y < min_y)
17271 row->visible_height -= min_y - row->y;
17272 if (row->y + row->height > max_y)
17273 row->visible_height -= row->y + row->height - max_y;
17274 if (row->fringe_bitmap_periodic_p)
17275 row->redraw_fringe_bitmaps_p = 1;
17277 it.current_y += row->height;
17279 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
17280 last_reused_text_row = row;
17281 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
17282 break;
17285 /* Disable lines in the current matrix which are now
17286 below the window. */
17287 for (++row; row < bottom_row; ++row)
17288 row->enabled_p = row->mode_line_p = 0;
17291 /* Update window_end_pos etc.; last_reused_text_row is the last
17292 reused row from the current matrix containing text, if any.
17293 The value of last_text_row is the last displayed line
17294 containing text. */
17295 if (last_reused_text_row)
17296 adjust_window_ends (w, last_reused_text_row, 1);
17297 else if (last_text_row)
17298 adjust_window_ends (w, last_text_row, 0);
17299 else
17301 /* This window must be completely empty. */
17302 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
17303 w->window_end_pos = Z - ZV;
17304 w->window_end_vpos = 0;
17306 w->window_end_valid = 0;
17308 /* Update hint: don't try scrolling again in update_window. */
17309 w->desired_matrix->no_scrolling_p = 1;
17311 #ifdef GLYPH_DEBUG
17312 debug_method_add (w, "try_window_reusing_current_matrix 1");
17313 #endif
17314 return 1;
17316 else if (CHARPOS (new_start) > CHARPOS (start))
17318 struct glyph_row *pt_row, *row;
17319 struct glyph_row *first_reusable_row;
17320 struct glyph_row *first_row_to_display;
17321 int dy;
17322 int yb = window_text_bottom_y (w);
17324 /* Find the row starting at new_start, if there is one. Don't
17325 reuse a partially visible line at the end. */
17326 first_reusable_row = start_row;
17327 while (first_reusable_row->enabled_p
17328 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
17329 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
17330 < CHARPOS (new_start)))
17331 ++first_reusable_row;
17333 /* Give up if there is no row to reuse. */
17334 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
17335 || !first_reusable_row->enabled_p
17336 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
17337 != CHARPOS (new_start)))
17338 return 0;
17340 /* We can reuse fully visible rows beginning with
17341 first_reusable_row to the end of the window. Set
17342 first_row_to_display to the first row that cannot be reused.
17343 Set pt_row to the row containing point, if there is any. */
17344 pt_row = NULL;
17345 for (first_row_to_display = first_reusable_row;
17346 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
17347 ++first_row_to_display)
17349 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
17350 && (PT < MATRIX_ROW_END_CHARPOS (first_row_to_display)
17351 || (PT == MATRIX_ROW_END_CHARPOS (first_row_to_display)
17352 && first_row_to_display->ends_at_zv_p
17353 && pt_row == NULL)))
17354 pt_row = first_row_to_display;
17357 /* Start displaying at the start of first_row_to_display. */
17358 eassert (first_row_to_display->y < yb);
17359 init_to_row_start (&it, w, first_row_to_display);
17361 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
17362 - start_vpos);
17363 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
17364 - nrows_scrolled);
17365 it.current_y = (first_row_to_display->y - first_reusable_row->y
17366 + WINDOW_HEADER_LINE_HEIGHT (w));
17368 /* Display lines beginning with first_row_to_display in the
17369 desired matrix. Set last_text_row to the last row displayed
17370 that displays text. */
17371 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
17372 if (pt_row == NULL)
17373 w->cursor.vpos = -1;
17374 last_text_row = NULL;
17375 while (it.current_y < it.last_visible_y && !f->fonts_changed)
17376 if (display_line (&it))
17377 last_text_row = it.glyph_row - 1;
17379 /* If point is in a reused row, adjust y and vpos of the cursor
17380 position. */
17381 if (pt_row)
17383 w->cursor.vpos -= nrows_scrolled;
17384 w->cursor.y -= first_reusable_row->y - start_row->y;
17387 /* Give up if point isn't in a row displayed or reused. (This
17388 also handles the case where w->cursor.vpos < nrows_scrolled
17389 after the calls to display_line, which can happen with scroll
17390 margins. See bug#1295.) */
17391 if (w->cursor.vpos < 0)
17393 clear_glyph_matrix (w->desired_matrix);
17394 return 0;
17397 /* Scroll the display. */
17398 run.current_y = first_reusable_row->y;
17399 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
17400 run.height = it.last_visible_y - run.current_y;
17401 dy = run.current_y - run.desired_y;
17403 if (run.height)
17405 update_begin (f);
17406 FRAME_RIF (f)->update_window_begin_hook (w);
17407 FRAME_RIF (f)->clear_window_mouse_face (w);
17408 FRAME_RIF (f)->scroll_run_hook (w, &run);
17409 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
17410 update_end (f);
17413 /* Adjust Y positions of reused rows. */
17414 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
17415 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
17416 max_y = it.last_visible_y;
17417 for (row = first_reusable_row; row < first_row_to_display; ++row)
17419 row->y -= dy;
17420 row->visible_height = row->height;
17421 if (row->y < min_y)
17422 row->visible_height -= min_y - row->y;
17423 if (row->y + row->height > max_y)
17424 row->visible_height -= row->y + row->height - max_y;
17425 if (row->fringe_bitmap_periodic_p)
17426 row->redraw_fringe_bitmaps_p = 1;
17429 /* Scroll the current matrix. */
17430 eassert (nrows_scrolled > 0);
17431 rotate_matrix (w->current_matrix,
17432 start_vpos,
17433 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
17434 -nrows_scrolled);
17436 /* Disable rows not reused. */
17437 for (row -= nrows_scrolled; row < bottom_row; ++row)
17438 row->enabled_p = false;
17440 /* Point may have moved to a different line, so we cannot assume that
17441 the previous cursor position is valid; locate the correct row. */
17442 if (pt_row)
17444 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
17445 row < bottom_row
17446 && PT >= MATRIX_ROW_END_CHARPOS (row)
17447 && !row->ends_at_zv_p;
17448 row++)
17450 w->cursor.vpos++;
17451 w->cursor.y = row->y;
17453 if (row < bottom_row)
17455 /* Can't simply scan the row for point with
17456 bidi-reordered glyph rows. Let set_cursor_from_row
17457 figure out where to put the cursor, and if it fails,
17458 give up. */
17459 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
17461 if (!set_cursor_from_row (w, row, w->current_matrix,
17462 0, 0, 0, 0))
17464 clear_glyph_matrix (w->desired_matrix);
17465 return 0;
17468 else
17470 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
17471 struct glyph *end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
17473 for (; glyph < end
17474 && (!BUFFERP (glyph->object)
17475 || glyph->charpos < PT);
17476 glyph++)
17478 w->cursor.hpos++;
17479 w->cursor.x += glyph->pixel_width;
17485 /* Adjust window end. A null value of last_text_row means that
17486 the window end is in reused rows which in turn means that
17487 only its vpos can have changed. */
17488 if (last_text_row)
17489 adjust_window_ends (w, last_text_row, 0);
17490 else
17491 w->window_end_vpos -= nrows_scrolled;
17493 w->window_end_valid = 0;
17494 w->desired_matrix->no_scrolling_p = 1;
17496 #ifdef GLYPH_DEBUG
17497 debug_method_add (w, "try_window_reusing_current_matrix 2");
17498 #endif
17499 return 1;
17502 return 0;
17507 /************************************************************************
17508 Window redisplay reusing current matrix when buffer has changed
17509 ************************************************************************/
17511 static struct glyph_row *find_last_unchanged_at_beg_row (struct window *);
17512 static struct glyph_row *find_first_unchanged_at_end_row (struct window *,
17513 ptrdiff_t *, ptrdiff_t *);
17514 static struct glyph_row *
17515 find_last_row_displaying_text (struct glyph_matrix *, struct it *,
17516 struct glyph_row *);
17519 /* Return the last row in MATRIX displaying text. If row START is
17520 non-null, start searching with that row. IT gives the dimensions
17521 of the display. Value is null if matrix is empty; otherwise it is
17522 a pointer to the row found. */
17524 static struct glyph_row *
17525 find_last_row_displaying_text (struct glyph_matrix *matrix, struct it *it,
17526 struct glyph_row *start)
17528 struct glyph_row *row, *row_found;
17530 /* Set row_found to the last row in IT->w's current matrix
17531 displaying text. The loop looks funny but think of partially
17532 visible lines. */
17533 row_found = NULL;
17534 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
17535 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
17537 eassert (row->enabled_p);
17538 row_found = row;
17539 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
17540 break;
17541 ++row;
17544 return row_found;
17548 /* Return the last row in the current matrix of W that is not affected
17549 by changes at the start of current_buffer that occurred since W's
17550 current matrix was built. Value is null if no such row exists.
17552 BEG_UNCHANGED us the number of characters unchanged at the start of
17553 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
17554 first changed character in current_buffer. Characters at positions <
17555 BEG + BEG_UNCHANGED are at the same buffer positions as they were
17556 when the current matrix was built. */
17558 static struct glyph_row *
17559 find_last_unchanged_at_beg_row (struct window *w)
17561 ptrdiff_t first_changed_pos = BEG + BEG_UNCHANGED;
17562 struct glyph_row *row;
17563 struct glyph_row *row_found = NULL;
17564 int yb = window_text_bottom_y (w);
17566 /* Find the last row displaying unchanged text. */
17567 for (row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
17568 MATRIX_ROW_DISPLAYS_TEXT_P (row)
17569 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos;
17570 ++row)
17572 if (/* If row ends before first_changed_pos, it is unchanged,
17573 except in some case. */
17574 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
17575 /* When row ends in ZV and we write at ZV it is not
17576 unchanged. */
17577 && !row->ends_at_zv_p
17578 /* When first_changed_pos is the end of a continued line,
17579 row is not unchanged because it may be no longer
17580 continued. */
17581 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
17582 && (row->continued_p
17583 || row->exact_window_width_line_p))
17584 /* If ROW->end is beyond ZV, then ROW->end is outdated and
17585 needs to be recomputed, so don't consider this row as
17586 unchanged. This happens when the last line was
17587 bidi-reordered and was killed immediately before this
17588 redisplay cycle. In that case, ROW->end stores the
17589 buffer position of the first visual-order character of
17590 the killed text, which is now beyond ZV. */
17591 && CHARPOS (row->end.pos) <= ZV)
17592 row_found = row;
17594 /* Stop if last visible row. */
17595 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
17596 break;
17599 return row_found;
17603 /* Find the first glyph row in the current matrix of W that is not
17604 affected by changes at the end of current_buffer since the
17605 time W's current matrix was built.
17607 Return in *DELTA the number of chars by which buffer positions in
17608 unchanged text at the end of current_buffer must be adjusted.
17610 Return in *DELTA_BYTES the corresponding number of bytes.
17612 Value is null if no such row exists, i.e. all rows are affected by
17613 changes. */
17615 static struct glyph_row *
17616 find_first_unchanged_at_end_row (struct window *w,
17617 ptrdiff_t *delta, ptrdiff_t *delta_bytes)
17619 struct glyph_row *row;
17620 struct glyph_row *row_found = NULL;
17622 *delta = *delta_bytes = 0;
17624 /* Display must not have been paused, otherwise the current matrix
17625 is not up to date. */
17626 eassert (w->window_end_valid);
17628 /* A value of window_end_pos >= END_UNCHANGED means that the window
17629 end is in the range of changed text. If so, there is no
17630 unchanged row at the end of W's current matrix. */
17631 if (w->window_end_pos >= END_UNCHANGED)
17632 return NULL;
17634 /* Set row to the last row in W's current matrix displaying text. */
17635 row = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
17637 /* If matrix is entirely empty, no unchanged row exists. */
17638 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
17640 /* The value of row is the last glyph row in the matrix having a
17641 meaningful buffer position in it. The end position of row
17642 corresponds to window_end_pos. This allows us to translate
17643 buffer positions in the current matrix to current buffer
17644 positions for characters not in changed text. */
17645 ptrdiff_t Z_old =
17646 MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos;
17647 ptrdiff_t Z_BYTE_old =
17648 MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
17649 ptrdiff_t last_unchanged_pos, last_unchanged_pos_old;
17650 struct glyph_row *first_text_row
17651 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
17653 *delta = Z - Z_old;
17654 *delta_bytes = Z_BYTE - Z_BYTE_old;
17656 /* Set last_unchanged_pos to the buffer position of the last
17657 character in the buffer that has not been changed. Z is the
17658 index + 1 of the last character in current_buffer, i.e. by
17659 subtracting END_UNCHANGED we get the index of the last
17660 unchanged character, and we have to add BEG to get its buffer
17661 position. */
17662 last_unchanged_pos = Z - END_UNCHANGED + BEG;
17663 last_unchanged_pos_old = last_unchanged_pos - *delta;
17665 /* Search backward from ROW for a row displaying a line that
17666 starts at a minimum position >= last_unchanged_pos_old. */
17667 for (; row > first_text_row; --row)
17669 /* This used to abort, but it can happen.
17670 It is ok to just stop the search instead here. KFS. */
17671 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
17672 break;
17674 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
17675 row_found = row;
17679 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
17681 return row_found;
17685 /* Make sure that glyph rows in the current matrix of window W
17686 reference the same glyph memory as corresponding rows in the
17687 frame's frame matrix. This function is called after scrolling W's
17688 current matrix on a terminal frame in try_window_id and
17689 try_window_reusing_current_matrix. */
17691 static void
17692 sync_frame_with_window_matrix_rows (struct window *w)
17694 struct frame *f = XFRAME (w->frame);
17695 struct glyph_row *window_row, *window_row_end, *frame_row;
17697 /* Preconditions: W must be a leaf window and full-width. Its frame
17698 must have a frame matrix. */
17699 eassert (BUFFERP (w->contents));
17700 eassert (WINDOW_FULL_WIDTH_P (w));
17701 eassert (!FRAME_WINDOW_P (f));
17703 /* If W is a full-width window, glyph pointers in W's current matrix
17704 have, by definition, to be the same as glyph pointers in the
17705 corresponding frame matrix. Note that frame matrices have no
17706 marginal areas (see build_frame_matrix). */
17707 window_row = w->current_matrix->rows;
17708 window_row_end = window_row + w->current_matrix->nrows;
17709 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
17710 while (window_row < window_row_end)
17712 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
17713 struct glyph *end = window_row->glyphs[LAST_AREA];
17715 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
17716 frame_row->glyphs[TEXT_AREA] = start;
17717 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
17718 frame_row->glyphs[LAST_AREA] = end;
17720 /* Disable frame rows whose corresponding window rows have
17721 been disabled in try_window_id. */
17722 if (!window_row->enabled_p)
17723 frame_row->enabled_p = false;
17725 ++window_row, ++frame_row;
17730 /* Find the glyph row in window W containing CHARPOS. Consider all
17731 rows between START and END (not inclusive). END null means search
17732 all rows to the end of the display area of W. Value is the row
17733 containing CHARPOS or null. */
17735 struct glyph_row *
17736 row_containing_pos (struct window *w, ptrdiff_t charpos,
17737 struct glyph_row *start, struct glyph_row *end, int dy)
17739 struct glyph_row *row = start;
17740 struct glyph_row *best_row = NULL;
17741 ptrdiff_t mindif = BUF_ZV (XBUFFER (w->contents)) + 1;
17742 int last_y;
17744 /* If we happen to start on a header-line, skip that. */
17745 if (row->mode_line_p)
17746 ++row;
17748 if ((end && row >= end) || !row->enabled_p)
17749 return NULL;
17751 last_y = window_text_bottom_y (w) - dy;
17753 while (1)
17755 /* Give up if we have gone too far. */
17756 if (end && row >= end)
17757 return NULL;
17758 /* This formerly returned if they were equal.
17759 I think that both quantities are of a "last plus one" type;
17760 if so, when they are equal, the row is within the screen. -- rms. */
17761 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
17762 return NULL;
17764 /* If it is in this row, return this row. */
17765 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
17766 || (MATRIX_ROW_END_CHARPOS (row) == charpos
17767 /* The end position of a row equals the start
17768 position of the next row. If CHARPOS is there, we
17769 would rather consider it displayed in the next
17770 line, except when this line ends in ZV. */
17771 && !row_for_charpos_p (row, charpos)))
17772 && charpos >= MATRIX_ROW_START_CHARPOS (row))
17774 struct glyph *g;
17776 if (NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
17777 || (!best_row && !row->continued_p))
17778 return row;
17779 /* In bidi-reordered rows, there could be several rows whose
17780 edges surround CHARPOS, all of these rows belonging to
17781 the same continued line. We need to find the row which
17782 fits CHARPOS the best. */
17783 for (g = row->glyphs[TEXT_AREA];
17784 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
17785 g++)
17787 if (!STRINGP (g->object))
17789 if (g->charpos > 0 && eabs (g->charpos - charpos) < mindif)
17791 mindif = eabs (g->charpos - charpos);
17792 best_row = row;
17793 /* Exact match always wins. */
17794 if (mindif == 0)
17795 return best_row;
17800 else if (best_row && !row->continued_p)
17801 return best_row;
17802 ++row;
17807 /* Try to redisplay window W by reusing its existing display. W's
17808 current matrix must be up to date when this function is called,
17809 i.e. window_end_valid must be nonzero.
17811 Value is
17813 >= 1 if successful, i.e. display has been updated
17814 specifically:
17815 1 means the changes were in front of a newline that precedes
17816 the window start, and the whole current matrix was reused
17817 2 means the changes were after the last position displayed
17818 in the window, and the whole current matrix was reused
17819 3 means portions of the current matrix were reused, while
17820 some of the screen lines were redrawn
17821 -1 if redisplay with same window start is known not to succeed
17822 0 if otherwise unsuccessful
17824 The following steps are performed:
17826 1. Find the last row in the current matrix of W that is not
17827 affected by changes at the start of current_buffer. If no such row
17828 is found, give up.
17830 2. Find the first row in W's current matrix that is not affected by
17831 changes at the end of current_buffer. Maybe there is no such row.
17833 3. Display lines beginning with the row + 1 found in step 1 to the
17834 row found in step 2 or, if step 2 didn't find a row, to the end of
17835 the window.
17837 4. If cursor is not known to appear on the window, give up.
17839 5. If display stopped at the row found in step 2, scroll the
17840 display and current matrix as needed.
17842 6. Maybe display some lines at the end of W, if we must. This can
17843 happen under various circumstances, like a partially visible line
17844 becoming fully visible, or because newly displayed lines are displayed
17845 in smaller font sizes.
17847 7. Update W's window end information. */
17849 static int
17850 try_window_id (struct window *w)
17852 struct frame *f = XFRAME (w->frame);
17853 struct glyph_matrix *current_matrix = w->current_matrix;
17854 struct glyph_matrix *desired_matrix = w->desired_matrix;
17855 struct glyph_row *last_unchanged_at_beg_row;
17856 struct glyph_row *first_unchanged_at_end_row;
17857 struct glyph_row *row;
17858 struct glyph_row *bottom_row;
17859 int bottom_vpos;
17860 struct it it;
17861 ptrdiff_t delta = 0, delta_bytes = 0, stop_pos;
17862 int dvpos, dy;
17863 struct text_pos start_pos;
17864 struct run run;
17865 int first_unchanged_at_end_vpos = 0;
17866 struct glyph_row *last_text_row, *last_text_row_at_end;
17867 struct text_pos start;
17868 ptrdiff_t first_changed_charpos, last_changed_charpos;
17870 #ifdef GLYPH_DEBUG
17871 if (inhibit_try_window_id)
17872 return 0;
17873 #endif
17875 /* This is handy for debugging. */
17876 #if 0
17877 #define GIVE_UP(X) \
17878 do { \
17879 fprintf (stderr, "try_window_id give up %d\n", (X)); \
17880 return 0; \
17881 } while (0)
17882 #else
17883 #define GIVE_UP(X) return 0
17884 #endif
17886 SET_TEXT_POS_FROM_MARKER (start, w->start);
17888 /* Don't use this for mini-windows because these can show
17889 messages and mini-buffers, and we don't handle that here. */
17890 if (MINI_WINDOW_P (w))
17891 GIVE_UP (1);
17893 /* This flag is used to prevent redisplay optimizations. */
17894 if (windows_or_buffers_changed || f->cursor_type_changed)
17895 GIVE_UP (2);
17897 /* This function's optimizations cannot be used if overlays have
17898 changed in the buffer displayed by the window, so give up if they
17899 have. */
17900 if (w->last_overlay_modified != OVERLAY_MODIFF)
17901 GIVE_UP (21);
17903 /* Verify that narrowing has not changed.
17904 Also verify that we were not told to prevent redisplay optimizations.
17905 It would be nice to further
17906 reduce the number of cases where this prevents try_window_id. */
17907 if (current_buffer->clip_changed
17908 || current_buffer->prevent_redisplay_optimizations_p)
17909 GIVE_UP (3);
17911 /* Window must either use window-based redisplay or be full width. */
17912 if (!FRAME_WINDOW_P (f)
17913 && (!FRAME_LINE_INS_DEL_OK (f)
17914 || !WINDOW_FULL_WIDTH_P (w)))
17915 GIVE_UP (4);
17917 /* Give up if point is known NOT to appear in W. */
17918 if (PT < CHARPOS (start))
17919 GIVE_UP (5);
17921 /* Another way to prevent redisplay optimizations. */
17922 if (w->last_modified == 0)
17923 GIVE_UP (6);
17925 /* Verify that window is not hscrolled. */
17926 if (w->hscroll != 0)
17927 GIVE_UP (7);
17929 /* Verify that display wasn't paused. */
17930 if (!w->window_end_valid)
17931 GIVE_UP (8);
17933 /* Likewise if highlighting trailing whitespace. */
17934 if (!NILP (Vshow_trailing_whitespace))
17935 GIVE_UP (11);
17937 /* Can't use this if overlay arrow position and/or string have
17938 changed. */
17939 if (overlay_arrows_changed_p ())
17940 GIVE_UP (12);
17942 /* When word-wrap is on, adding a space to the first word of a
17943 wrapped line can change the wrap position, altering the line
17944 above it. It might be worthwhile to handle this more
17945 intelligently, but for now just redisplay from scratch. */
17946 if (!NILP (BVAR (XBUFFER (w->contents), word_wrap)))
17947 GIVE_UP (21);
17949 /* Under bidi reordering, adding or deleting a character in the
17950 beginning of a paragraph, before the first strong directional
17951 character, can change the base direction of the paragraph (unless
17952 the buffer specifies a fixed paragraph direction), which will
17953 require to redisplay the whole paragraph. It might be worthwhile
17954 to find the paragraph limits and widen the range of redisplayed
17955 lines to that, but for now just give up this optimization and
17956 redisplay from scratch. */
17957 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
17958 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
17959 GIVE_UP (22);
17961 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
17962 only if buffer has really changed. The reason is that the gap is
17963 initially at Z for freshly visited files. The code below would
17964 set end_unchanged to 0 in that case. */
17965 if (MODIFF > SAVE_MODIFF
17966 /* This seems to happen sometimes after saving a buffer. */
17967 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
17969 if (GPT - BEG < BEG_UNCHANGED)
17970 BEG_UNCHANGED = GPT - BEG;
17971 if (Z - GPT < END_UNCHANGED)
17972 END_UNCHANGED = Z - GPT;
17975 /* The position of the first and last character that has been changed. */
17976 first_changed_charpos = BEG + BEG_UNCHANGED;
17977 last_changed_charpos = Z - END_UNCHANGED;
17979 /* If window starts after a line end, and the last change is in
17980 front of that newline, then changes don't affect the display.
17981 This case happens with stealth-fontification. Note that although
17982 the display is unchanged, glyph positions in the matrix have to
17983 be adjusted, of course. */
17984 row = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
17985 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
17986 && ((last_changed_charpos < CHARPOS (start)
17987 && CHARPOS (start) == BEGV)
17988 || (last_changed_charpos < CHARPOS (start) - 1
17989 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
17991 ptrdiff_t Z_old, Z_delta, Z_BYTE_old, Z_delta_bytes;
17992 struct glyph_row *r0;
17994 /* Compute how many chars/bytes have been added to or removed
17995 from the buffer. */
17996 Z_old = MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos;
17997 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
17998 Z_delta = Z - Z_old;
17999 Z_delta_bytes = Z_BYTE - Z_BYTE_old;
18001 /* Give up if PT is not in the window. Note that it already has
18002 been checked at the start of try_window_id that PT is not in
18003 front of the window start. */
18004 if (PT >= MATRIX_ROW_END_CHARPOS (row) + Z_delta)
18005 GIVE_UP (13);
18007 /* If window start is unchanged, we can reuse the whole matrix
18008 as is, after adjusting glyph positions. No need to compute
18009 the window end again, since its offset from Z hasn't changed. */
18010 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
18011 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + Z_delta
18012 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + Z_delta_bytes
18013 /* PT must not be in a partially visible line. */
18014 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + Z_delta
18015 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
18017 /* Adjust positions in the glyph matrix. */
18018 if (Z_delta || Z_delta_bytes)
18020 struct glyph_row *r1
18021 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
18022 increment_matrix_positions (w->current_matrix,
18023 MATRIX_ROW_VPOS (r0, current_matrix),
18024 MATRIX_ROW_VPOS (r1, current_matrix),
18025 Z_delta, Z_delta_bytes);
18028 /* Set the cursor. */
18029 row = row_containing_pos (w, PT, r0, NULL, 0);
18030 if (row)
18031 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
18032 return 1;
18036 /* Handle the case that changes are all below what is displayed in
18037 the window, and that PT is in the window. This shortcut cannot
18038 be taken if ZV is visible in the window, and text has been added
18039 there that is visible in the window. */
18040 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
18041 /* ZV is not visible in the window, or there are no
18042 changes at ZV, actually. */
18043 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
18044 || first_changed_charpos == last_changed_charpos))
18046 struct glyph_row *r0;
18048 /* Give up if PT is not in the window. Note that it already has
18049 been checked at the start of try_window_id that PT is not in
18050 front of the window start. */
18051 if (PT >= MATRIX_ROW_END_CHARPOS (row))
18052 GIVE_UP (14);
18054 /* If window start is unchanged, we can reuse the whole matrix
18055 as is, without changing glyph positions since no text has
18056 been added/removed in front of the window end. */
18057 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
18058 if (TEXT_POS_EQUAL_P (start, r0->minpos)
18059 /* PT must not be in a partially visible line. */
18060 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
18061 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
18063 /* We have to compute the window end anew since text
18064 could have been added/removed after it. */
18065 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
18066 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
18068 /* Set the cursor. */
18069 row = row_containing_pos (w, PT, r0, NULL, 0);
18070 if (row)
18071 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
18072 return 2;
18076 /* Give up if window start is in the changed area.
18078 The condition used to read
18080 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
18082 but why that was tested escapes me at the moment. */
18083 if (CHARPOS (start) >= first_changed_charpos
18084 && CHARPOS (start) <= last_changed_charpos)
18085 GIVE_UP (15);
18087 /* Check that window start agrees with the start of the first glyph
18088 row in its current matrix. Check this after we know the window
18089 start is not in changed text, otherwise positions would not be
18090 comparable. */
18091 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
18092 if (!TEXT_POS_EQUAL_P (start, row->minpos))
18093 GIVE_UP (16);
18095 /* Give up if the window ends in strings. Overlay strings
18096 at the end are difficult to handle, so don't try. */
18097 row = MATRIX_ROW (current_matrix, w->window_end_vpos);
18098 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
18099 GIVE_UP (20);
18101 /* Compute the position at which we have to start displaying new
18102 lines. Some of the lines at the top of the window might be
18103 reusable because they are not displaying changed text. Find the
18104 last row in W's current matrix not affected by changes at the
18105 start of current_buffer. Value is null if changes start in the
18106 first line of window. */
18107 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
18108 if (last_unchanged_at_beg_row)
18110 /* Avoid starting to display in the middle of a character, a TAB
18111 for instance. This is easier than to set up the iterator
18112 exactly, and it's not a frequent case, so the additional
18113 effort wouldn't really pay off. */
18114 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
18115 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
18116 && last_unchanged_at_beg_row > w->current_matrix->rows)
18117 --last_unchanged_at_beg_row;
18119 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
18120 GIVE_UP (17);
18122 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
18123 GIVE_UP (18);
18124 start_pos = it.current.pos;
18126 /* Start displaying new lines in the desired matrix at the same
18127 vpos we would use in the current matrix, i.e. below
18128 last_unchanged_at_beg_row. */
18129 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
18130 current_matrix);
18131 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
18132 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
18134 eassert (it.hpos == 0 && it.current_x == 0);
18136 else
18138 /* There are no reusable lines at the start of the window.
18139 Start displaying in the first text line. */
18140 start_display (&it, w, start);
18141 it.vpos = it.first_vpos;
18142 start_pos = it.current.pos;
18145 /* Find the first row that is not affected by changes at the end of
18146 the buffer. Value will be null if there is no unchanged row, in
18147 which case we must redisplay to the end of the window. delta
18148 will be set to the value by which buffer positions beginning with
18149 first_unchanged_at_end_row have to be adjusted due to text
18150 changes. */
18151 first_unchanged_at_end_row
18152 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
18153 IF_DEBUG (debug_delta = delta);
18154 IF_DEBUG (debug_delta_bytes = delta_bytes);
18156 /* Set stop_pos to the buffer position up to which we will have to
18157 display new lines. If first_unchanged_at_end_row != NULL, this
18158 is the buffer position of the start of the line displayed in that
18159 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
18160 that we don't stop at a buffer position. */
18161 stop_pos = 0;
18162 if (first_unchanged_at_end_row)
18164 eassert (last_unchanged_at_beg_row == NULL
18165 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
18167 /* If this is a continuation line, move forward to the next one
18168 that isn't. Changes in lines above affect this line.
18169 Caution: this may move first_unchanged_at_end_row to a row
18170 not displaying text. */
18171 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
18172 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
18173 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
18174 < it.last_visible_y))
18175 ++first_unchanged_at_end_row;
18177 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
18178 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
18179 >= it.last_visible_y))
18180 first_unchanged_at_end_row = NULL;
18181 else
18183 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
18184 + delta);
18185 first_unchanged_at_end_vpos
18186 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
18187 eassert (stop_pos >= Z - END_UNCHANGED);
18190 else if (last_unchanged_at_beg_row == NULL)
18191 GIVE_UP (19);
18194 #ifdef GLYPH_DEBUG
18196 /* Either there is no unchanged row at the end, or the one we have
18197 now displays text. This is a necessary condition for the window
18198 end pos calculation at the end of this function. */
18199 eassert (first_unchanged_at_end_row == NULL
18200 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
18202 debug_last_unchanged_at_beg_vpos
18203 = (last_unchanged_at_beg_row
18204 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
18205 : -1);
18206 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
18208 #endif /* GLYPH_DEBUG */
18211 /* Display new lines. Set last_text_row to the last new line
18212 displayed which has text on it, i.e. might end up as being the
18213 line where the window_end_vpos is. */
18214 w->cursor.vpos = -1;
18215 last_text_row = NULL;
18216 overlay_arrow_seen = 0;
18217 if (it.current_y < it.last_visible_y
18218 && !f->fonts_changed
18219 && (first_unchanged_at_end_row == NULL
18220 || IT_CHARPOS (it) < stop_pos))
18221 it.glyph_row->reversed_p = false;
18222 while (it.current_y < it.last_visible_y
18223 && !f->fonts_changed
18224 && (first_unchanged_at_end_row == NULL
18225 || IT_CHARPOS (it) < stop_pos))
18227 if (display_line (&it))
18228 last_text_row = it.glyph_row - 1;
18231 if (f->fonts_changed)
18232 return -1;
18235 /* Compute differences in buffer positions, y-positions etc. for
18236 lines reused at the bottom of the window. Compute what we can
18237 scroll. */
18238 if (first_unchanged_at_end_row
18239 /* No lines reused because we displayed everything up to the
18240 bottom of the window. */
18241 && it.current_y < it.last_visible_y)
18243 dvpos = (it.vpos
18244 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
18245 current_matrix));
18246 dy = it.current_y - first_unchanged_at_end_row->y;
18247 run.current_y = first_unchanged_at_end_row->y;
18248 run.desired_y = run.current_y + dy;
18249 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
18251 else
18253 delta = delta_bytes = dvpos = dy
18254 = run.current_y = run.desired_y = run.height = 0;
18255 first_unchanged_at_end_row = NULL;
18257 IF_DEBUG ((debug_dvpos = dvpos, debug_dy = dy));
18260 /* Find the cursor if not already found. We have to decide whether
18261 PT will appear on this window (it sometimes doesn't, but this is
18262 not a very frequent case.) This decision has to be made before
18263 the current matrix is altered. A value of cursor.vpos < 0 means
18264 that PT is either in one of the lines beginning at
18265 first_unchanged_at_end_row or below the window. Don't care for
18266 lines that might be displayed later at the window end; as
18267 mentioned, this is not a frequent case. */
18268 if (w->cursor.vpos < 0)
18270 /* Cursor in unchanged rows at the top? */
18271 if (PT < CHARPOS (start_pos)
18272 && last_unchanged_at_beg_row)
18274 row = row_containing_pos (w, PT,
18275 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
18276 last_unchanged_at_beg_row + 1, 0);
18277 if (row)
18278 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
18281 /* Start from first_unchanged_at_end_row looking for PT. */
18282 else if (first_unchanged_at_end_row)
18284 row = row_containing_pos (w, PT - delta,
18285 first_unchanged_at_end_row, NULL, 0);
18286 if (row)
18287 set_cursor_from_row (w, row, w->current_matrix, delta,
18288 delta_bytes, dy, dvpos);
18291 /* Give up if cursor was not found. */
18292 if (w->cursor.vpos < 0)
18294 clear_glyph_matrix (w->desired_matrix);
18295 return -1;
18299 /* Don't let the cursor end in the scroll margins. */
18301 int this_scroll_margin, cursor_height;
18302 int frame_line_height = default_line_pixel_height (w);
18303 int window_total_lines
18304 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (it.f) / frame_line_height;
18306 this_scroll_margin =
18307 max (0, min (scroll_margin, window_total_lines / 4));
18308 this_scroll_margin *= frame_line_height;
18309 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
18311 if ((w->cursor.y < this_scroll_margin
18312 && CHARPOS (start) > BEGV)
18313 /* Old redisplay didn't take scroll margin into account at the bottom,
18314 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
18315 || (w->cursor.y + (make_cursor_line_fully_visible_p
18316 ? cursor_height + this_scroll_margin
18317 : 1)) > it.last_visible_y)
18319 w->cursor.vpos = -1;
18320 clear_glyph_matrix (w->desired_matrix);
18321 return -1;
18325 /* Scroll the display. Do it before changing the current matrix so
18326 that xterm.c doesn't get confused about where the cursor glyph is
18327 found. */
18328 if (dy && run.height)
18330 update_begin (f);
18332 if (FRAME_WINDOW_P (f))
18334 FRAME_RIF (f)->update_window_begin_hook (w);
18335 FRAME_RIF (f)->clear_window_mouse_face (w);
18336 FRAME_RIF (f)->scroll_run_hook (w, &run);
18337 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
18339 else
18341 /* Terminal frame. In this case, dvpos gives the number of
18342 lines to scroll by; dvpos < 0 means scroll up. */
18343 int from_vpos
18344 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
18345 int from = WINDOW_TOP_EDGE_LINE (w) + from_vpos;
18346 int end = (WINDOW_TOP_EDGE_LINE (w)
18347 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
18348 + window_internal_height (w));
18350 #if defined (HAVE_GPM) || defined (MSDOS)
18351 x_clear_window_mouse_face (w);
18352 #endif
18353 /* Perform the operation on the screen. */
18354 if (dvpos > 0)
18356 /* Scroll last_unchanged_at_beg_row to the end of the
18357 window down dvpos lines. */
18358 set_terminal_window (f, end);
18360 /* On dumb terminals delete dvpos lines at the end
18361 before inserting dvpos empty lines. */
18362 if (!FRAME_SCROLL_REGION_OK (f))
18363 ins_del_lines (f, end - dvpos, -dvpos);
18365 /* Insert dvpos empty lines in front of
18366 last_unchanged_at_beg_row. */
18367 ins_del_lines (f, from, dvpos);
18369 else if (dvpos < 0)
18371 /* Scroll up last_unchanged_at_beg_vpos to the end of
18372 the window to last_unchanged_at_beg_vpos - |dvpos|. */
18373 set_terminal_window (f, end);
18375 /* Delete dvpos lines in front of
18376 last_unchanged_at_beg_vpos. ins_del_lines will set
18377 the cursor to the given vpos and emit |dvpos| delete
18378 line sequences. */
18379 ins_del_lines (f, from + dvpos, dvpos);
18381 /* On a dumb terminal insert dvpos empty lines at the
18382 end. */
18383 if (!FRAME_SCROLL_REGION_OK (f))
18384 ins_del_lines (f, end + dvpos, -dvpos);
18387 set_terminal_window (f, 0);
18390 update_end (f);
18393 /* Shift reused rows of the current matrix to the right position.
18394 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
18395 text. */
18396 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
18397 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
18398 if (dvpos < 0)
18400 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
18401 bottom_vpos, dvpos);
18402 clear_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
18403 bottom_vpos);
18405 else if (dvpos > 0)
18407 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
18408 bottom_vpos, dvpos);
18409 clear_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
18410 first_unchanged_at_end_vpos + dvpos);
18413 /* For frame-based redisplay, make sure that current frame and window
18414 matrix are in sync with respect to glyph memory. */
18415 if (!FRAME_WINDOW_P (f))
18416 sync_frame_with_window_matrix_rows (w);
18418 /* Adjust buffer positions in reused rows. */
18419 if (delta || delta_bytes)
18420 increment_matrix_positions (current_matrix,
18421 first_unchanged_at_end_vpos + dvpos,
18422 bottom_vpos, delta, delta_bytes);
18424 /* Adjust Y positions. */
18425 if (dy)
18426 shift_glyph_matrix (w, current_matrix,
18427 first_unchanged_at_end_vpos + dvpos,
18428 bottom_vpos, dy);
18430 if (first_unchanged_at_end_row)
18432 first_unchanged_at_end_row += dvpos;
18433 if (first_unchanged_at_end_row->y >= it.last_visible_y
18434 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
18435 first_unchanged_at_end_row = NULL;
18438 /* If scrolling up, there may be some lines to display at the end of
18439 the window. */
18440 last_text_row_at_end = NULL;
18441 if (dy < 0)
18443 /* Scrolling up can leave for example a partially visible line
18444 at the end of the window to be redisplayed. */
18445 /* Set last_row to the glyph row in the current matrix where the
18446 window end line is found. It has been moved up or down in
18447 the matrix by dvpos. */
18448 int last_vpos = w->window_end_vpos + dvpos;
18449 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
18451 /* If last_row is the window end line, it should display text. */
18452 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_row));
18454 /* If window end line was partially visible before, begin
18455 displaying at that line. Otherwise begin displaying with the
18456 line following it. */
18457 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
18459 init_to_row_start (&it, w, last_row);
18460 it.vpos = last_vpos;
18461 it.current_y = last_row->y;
18463 else
18465 init_to_row_end (&it, w, last_row);
18466 it.vpos = 1 + last_vpos;
18467 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
18468 ++last_row;
18471 /* We may start in a continuation line. If so, we have to
18472 get the right continuation_lines_width and current_x. */
18473 it.continuation_lines_width = last_row->continuation_lines_width;
18474 it.hpos = it.current_x = 0;
18476 /* Display the rest of the lines at the window end. */
18477 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
18478 while (it.current_y < it.last_visible_y && !f->fonts_changed)
18480 /* Is it always sure that the display agrees with lines in
18481 the current matrix? I don't think so, so we mark rows
18482 displayed invalid in the current matrix by setting their
18483 enabled_p flag to zero. */
18484 SET_MATRIX_ROW_ENABLED_P (w->current_matrix, it.vpos, false);
18485 if (display_line (&it))
18486 last_text_row_at_end = it.glyph_row - 1;
18490 /* Update window_end_pos and window_end_vpos. */
18491 if (first_unchanged_at_end_row && !last_text_row_at_end)
18493 /* Window end line if one of the preserved rows from the current
18494 matrix. Set row to the last row displaying text in current
18495 matrix starting at first_unchanged_at_end_row, after
18496 scrolling. */
18497 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
18498 row = find_last_row_displaying_text (w->current_matrix, &it,
18499 first_unchanged_at_end_row);
18500 eassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
18501 adjust_window_ends (w, row, 1);
18502 eassert (w->window_end_bytepos >= 0);
18503 IF_DEBUG (debug_method_add (w, "A"));
18505 else if (last_text_row_at_end)
18507 adjust_window_ends (w, last_text_row_at_end, 0);
18508 eassert (w->window_end_bytepos >= 0);
18509 IF_DEBUG (debug_method_add (w, "B"));
18511 else if (last_text_row)
18513 /* We have displayed either to the end of the window or at the
18514 end of the window, i.e. the last row with text is to be found
18515 in the desired matrix. */
18516 adjust_window_ends (w, last_text_row, 0);
18517 eassert (w->window_end_bytepos >= 0);
18519 else if (first_unchanged_at_end_row == NULL
18520 && last_text_row == NULL
18521 && last_text_row_at_end == NULL)
18523 /* Displayed to end of window, but no line containing text was
18524 displayed. Lines were deleted at the end of the window. */
18525 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
18526 int vpos = w->window_end_vpos;
18527 struct glyph_row *current_row = current_matrix->rows + vpos;
18528 struct glyph_row *desired_row = desired_matrix->rows + vpos;
18530 for (row = NULL;
18531 row == NULL && vpos >= first_vpos;
18532 --vpos, --current_row, --desired_row)
18534 if (desired_row->enabled_p)
18536 if (MATRIX_ROW_DISPLAYS_TEXT_P (desired_row))
18537 row = desired_row;
18539 else if (MATRIX_ROW_DISPLAYS_TEXT_P (current_row))
18540 row = current_row;
18543 eassert (row != NULL);
18544 w->window_end_vpos = vpos + 1;
18545 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
18546 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
18547 eassert (w->window_end_bytepos >= 0);
18548 IF_DEBUG (debug_method_add (w, "C"));
18550 else
18551 emacs_abort ();
18553 IF_DEBUG ((debug_end_pos = w->window_end_pos,
18554 debug_end_vpos = w->window_end_vpos));
18556 /* Record that display has not been completed. */
18557 w->window_end_valid = 0;
18558 w->desired_matrix->no_scrolling_p = 1;
18559 return 3;
18561 #undef GIVE_UP
18566 /***********************************************************************
18567 More debugging support
18568 ***********************************************************************/
18570 #ifdef GLYPH_DEBUG
18572 void dump_glyph_row (struct glyph_row *, int, int) EXTERNALLY_VISIBLE;
18573 void dump_glyph_matrix (struct glyph_matrix *, int) EXTERNALLY_VISIBLE;
18574 void dump_glyph (struct glyph_row *, struct glyph *, int) EXTERNALLY_VISIBLE;
18577 /* Dump the contents of glyph matrix MATRIX on stderr.
18579 GLYPHS 0 means don't show glyph contents.
18580 GLYPHS 1 means show glyphs in short form
18581 GLYPHS > 1 means show glyphs in long form. */
18583 void
18584 dump_glyph_matrix (struct glyph_matrix *matrix, int glyphs)
18586 int i;
18587 for (i = 0; i < matrix->nrows; ++i)
18588 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
18592 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
18593 the glyph row and area where the glyph comes from. */
18595 void
18596 dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
18598 if (glyph->type == CHAR_GLYPH
18599 || glyph->type == GLYPHLESS_GLYPH)
18601 fprintf (stderr,
18602 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
18603 glyph - row->glyphs[TEXT_AREA],
18604 (glyph->type == CHAR_GLYPH
18605 ? 'C'
18606 : 'G'),
18607 glyph->charpos,
18608 (BUFFERP (glyph->object)
18609 ? 'B'
18610 : (STRINGP (glyph->object)
18611 ? 'S'
18612 : (INTEGERP (glyph->object)
18613 ? '0'
18614 : '-'))),
18615 glyph->pixel_width,
18616 glyph->u.ch,
18617 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
18618 ? glyph->u.ch
18619 : '.'),
18620 glyph->face_id,
18621 glyph->left_box_line_p,
18622 glyph->right_box_line_p);
18624 else if (glyph->type == STRETCH_GLYPH)
18626 fprintf (stderr,
18627 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
18628 glyph - row->glyphs[TEXT_AREA],
18629 'S',
18630 glyph->charpos,
18631 (BUFFERP (glyph->object)
18632 ? 'B'
18633 : (STRINGP (glyph->object)
18634 ? 'S'
18635 : (INTEGERP (glyph->object)
18636 ? '0'
18637 : '-'))),
18638 glyph->pixel_width,
18640 ' ',
18641 glyph->face_id,
18642 glyph->left_box_line_p,
18643 glyph->right_box_line_p);
18645 else if (glyph->type == IMAGE_GLYPH)
18647 fprintf (stderr,
18648 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
18649 glyph - row->glyphs[TEXT_AREA],
18650 'I',
18651 glyph->charpos,
18652 (BUFFERP (glyph->object)
18653 ? 'B'
18654 : (STRINGP (glyph->object)
18655 ? 'S'
18656 : (INTEGERP (glyph->object)
18657 ? '0'
18658 : '-'))),
18659 glyph->pixel_width,
18660 glyph->u.img_id,
18661 '.',
18662 glyph->face_id,
18663 glyph->left_box_line_p,
18664 glyph->right_box_line_p);
18666 else if (glyph->type == COMPOSITE_GLYPH)
18668 fprintf (stderr,
18669 " %5"pD"d %c %9"pI"d %c %3d 0x%06x",
18670 glyph - row->glyphs[TEXT_AREA],
18671 '+',
18672 glyph->charpos,
18673 (BUFFERP (glyph->object)
18674 ? 'B'
18675 : (STRINGP (glyph->object)
18676 ? 'S'
18677 : (INTEGERP (glyph->object)
18678 ? '0'
18679 : '-'))),
18680 glyph->pixel_width,
18681 glyph->u.cmp.id);
18682 if (glyph->u.cmp.automatic)
18683 fprintf (stderr,
18684 "[%d-%d]",
18685 glyph->slice.cmp.from, glyph->slice.cmp.to);
18686 fprintf (stderr, " . %4d %1.1d%1.1d\n",
18687 glyph->face_id,
18688 glyph->left_box_line_p,
18689 glyph->right_box_line_p);
18694 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
18695 GLYPHS 0 means don't show glyph contents.
18696 GLYPHS 1 means show glyphs in short form
18697 GLYPHS > 1 means show glyphs in long form. */
18699 void
18700 dump_glyph_row (struct glyph_row *row, int vpos, int glyphs)
18702 if (glyphs != 1)
18704 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
18705 fprintf (stderr, "==============================================================================\n");
18707 fprintf (stderr, "%3d %9"pI"d %9"pI"d %4d %1.1d%1.1d%1.1d%1.1d\
18708 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
18709 vpos,
18710 MATRIX_ROW_START_CHARPOS (row),
18711 MATRIX_ROW_END_CHARPOS (row),
18712 row->used[TEXT_AREA],
18713 row->contains_overlapping_glyphs_p,
18714 row->enabled_p,
18715 row->truncated_on_left_p,
18716 row->truncated_on_right_p,
18717 row->continued_p,
18718 MATRIX_ROW_CONTINUATION_LINE_P (row),
18719 MATRIX_ROW_DISPLAYS_TEXT_P (row),
18720 row->ends_at_zv_p,
18721 row->fill_line_p,
18722 row->ends_in_middle_of_char_p,
18723 row->starts_in_middle_of_char_p,
18724 row->mouse_face_p,
18725 row->x,
18726 row->y,
18727 row->pixel_width,
18728 row->height,
18729 row->visible_height,
18730 row->ascent,
18731 row->phys_ascent);
18732 /* The next 3 lines should align to "Start" in the header. */
18733 fprintf (stderr, " %9"pD"d %9"pD"d\t%5d\n", row->start.overlay_string_index,
18734 row->end.overlay_string_index,
18735 row->continuation_lines_width);
18736 fprintf (stderr, " %9"pI"d %9"pI"d\n",
18737 CHARPOS (row->start.string_pos),
18738 CHARPOS (row->end.string_pos));
18739 fprintf (stderr, " %9d %9d\n", row->start.dpvec_index,
18740 row->end.dpvec_index);
18743 if (glyphs > 1)
18745 int area;
18747 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18749 struct glyph *glyph = row->glyphs[area];
18750 struct glyph *glyph_end = glyph + row->used[area];
18752 /* Glyph for a line end in text. */
18753 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
18754 ++glyph_end;
18756 if (glyph < glyph_end)
18757 fprintf (stderr, " Glyph# Type Pos O W Code C Face LR\n");
18759 for (; glyph < glyph_end; ++glyph)
18760 dump_glyph (row, glyph, area);
18763 else if (glyphs == 1)
18765 int area;
18766 char s[SHRT_MAX + 4];
18768 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18770 int i;
18772 for (i = 0; i < row->used[area]; ++i)
18774 struct glyph *glyph = row->glyphs[area] + i;
18775 if (i == row->used[area] - 1
18776 && area == TEXT_AREA
18777 && INTEGERP (glyph->object)
18778 && glyph->type == CHAR_GLYPH
18779 && glyph->u.ch == ' ')
18781 strcpy (&s[i], "[\\n]");
18782 i += 4;
18784 else if (glyph->type == CHAR_GLYPH
18785 && glyph->u.ch < 0x80
18786 && glyph->u.ch >= ' ')
18787 s[i] = glyph->u.ch;
18788 else
18789 s[i] = '.';
18792 s[i] = '\0';
18793 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
18799 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
18800 Sdump_glyph_matrix, 0, 1, "p",
18801 doc: /* Dump the current matrix of the selected window to stderr.
18802 Shows contents of glyph row structures. With non-nil
18803 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
18804 glyphs in short form, otherwise show glyphs in long form. */)
18805 (Lisp_Object glyphs)
18807 struct window *w = XWINDOW (selected_window);
18808 struct buffer *buffer = XBUFFER (w->contents);
18810 fprintf (stderr, "PT = %"pI"d, BEGV = %"pI"d. ZV = %"pI"d\n",
18811 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
18812 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
18813 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
18814 fprintf (stderr, "=============================================\n");
18815 dump_glyph_matrix (w->current_matrix,
18816 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 0);
18817 return Qnil;
18821 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
18822 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
18823 (void)
18825 struct frame *f = XFRAME (selected_frame);
18826 dump_glyph_matrix (f->current_matrix, 1);
18827 return Qnil;
18831 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
18832 doc: /* Dump glyph row ROW to stderr.
18833 GLYPH 0 means don't dump glyphs.
18834 GLYPH 1 means dump glyphs in short form.
18835 GLYPH > 1 or omitted means dump glyphs in long form. */)
18836 (Lisp_Object row, Lisp_Object glyphs)
18838 struct glyph_matrix *matrix;
18839 EMACS_INT vpos;
18841 CHECK_NUMBER (row);
18842 matrix = XWINDOW (selected_window)->current_matrix;
18843 vpos = XINT (row);
18844 if (vpos >= 0 && vpos < matrix->nrows)
18845 dump_glyph_row (MATRIX_ROW (matrix, vpos),
18846 vpos,
18847 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
18848 return Qnil;
18852 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
18853 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
18854 GLYPH 0 means don't dump glyphs.
18855 GLYPH 1 means dump glyphs in short form.
18856 GLYPH > 1 or omitted means dump glyphs in long form.
18858 If there's no tool-bar, or if the tool-bar is not drawn by Emacs,
18859 do nothing. */)
18860 (Lisp_Object row, Lisp_Object glyphs)
18862 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
18863 struct frame *sf = SELECTED_FRAME ();
18864 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
18865 EMACS_INT vpos;
18867 CHECK_NUMBER (row);
18868 vpos = XINT (row);
18869 if (vpos >= 0 && vpos < m->nrows)
18870 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
18871 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
18872 #endif
18873 return Qnil;
18877 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
18878 doc: /* Toggle tracing of redisplay.
18879 With ARG, turn tracing on if and only if ARG is positive. */)
18880 (Lisp_Object arg)
18882 if (NILP (arg))
18883 trace_redisplay_p = !trace_redisplay_p;
18884 else
18886 arg = Fprefix_numeric_value (arg);
18887 trace_redisplay_p = XINT (arg) > 0;
18890 return Qnil;
18894 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
18895 doc: /* Like `format', but print result to stderr.
18896 usage: (trace-to-stderr STRING &rest OBJECTS) */)
18897 (ptrdiff_t nargs, Lisp_Object *args)
18899 Lisp_Object s = Fformat (nargs, args);
18900 fprintf (stderr, "%s", SDATA (s));
18901 return Qnil;
18904 #endif /* GLYPH_DEBUG */
18908 /***********************************************************************
18909 Building Desired Matrix Rows
18910 ***********************************************************************/
18912 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
18913 Used for non-window-redisplay windows, and for windows w/o left fringe. */
18915 static struct glyph_row *
18916 get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
18918 struct frame *f = XFRAME (WINDOW_FRAME (w));
18919 struct buffer *buffer = XBUFFER (w->contents);
18920 struct buffer *old = current_buffer;
18921 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
18922 ptrdiff_t arrow_len = SCHARS (overlay_arrow_string);
18923 const unsigned char *arrow_end = arrow_string + arrow_len;
18924 const unsigned char *p;
18925 struct it it;
18926 bool multibyte_p;
18927 int n_glyphs_before;
18929 set_buffer_temp (buffer);
18930 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
18931 scratch_glyph_row.reversed_p = false;
18932 it.glyph_row->used[TEXT_AREA] = 0;
18933 SET_TEXT_POS (it.position, 0, 0);
18935 multibyte_p = !NILP (BVAR (buffer, enable_multibyte_characters));
18936 p = arrow_string;
18937 while (p < arrow_end)
18939 Lisp_Object face, ilisp;
18941 /* Get the next character. */
18942 if (multibyte_p)
18943 it.c = it.char_to_display = string_char_and_length (p, &it.len);
18944 else
18946 it.c = it.char_to_display = *p, it.len = 1;
18947 if (! ASCII_CHAR_P (it.c))
18948 it.char_to_display = BYTE8_TO_CHAR (it.c);
18950 p += it.len;
18952 /* Get its face. */
18953 ilisp = make_number (p - arrow_string);
18954 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
18955 it.face_id = compute_char_face (f, it.char_to_display, face);
18957 /* Compute its width, get its glyphs. */
18958 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
18959 SET_TEXT_POS (it.position, -1, -1);
18960 PRODUCE_GLYPHS (&it);
18962 /* If this character doesn't fit any more in the line, we have
18963 to remove some glyphs. */
18964 if (it.current_x > it.last_visible_x)
18966 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
18967 break;
18971 set_buffer_temp (old);
18972 return it.glyph_row;
18976 /* Insert truncation glyphs at the start of IT->glyph_row. Which
18977 glyphs to insert is determined by produce_special_glyphs. */
18979 static void
18980 insert_left_trunc_glyphs (struct it *it)
18982 struct it truncate_it;
18983 struct glyph *from, *end, *to, *toend;
18985 eassert (!FRAME_WINDOW_P (it->f)
18986 || (!it->glyph_row->reversed_p
18987 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)
18988 || (it->glyph_row->reversed_p
18989 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0));
18991 /* Get the truncation glyphs. */
18992 truncate_it = *it;
18993 truncate_it.current_x = 0;
18994 truncate_it.face_id = DEFAULT_FACE_ID;
18995 truncate_it.glyph_row = &scratch_glyph_row;
18996 truncate_it.area = TEXT_AREA;
18997 truncate_it.glyph_row->used[TEXT_AREA] = 0;
18998 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
18999 truncate_it.object = make_number (0);
19000 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
19002 /* Overwrite glyphs from IT with truncation glyphs. */
19003 if (!it->glyph_row->reversed_p)
19005 short tused = truncate_it.glyph_row->used[TEXT_AREA];
19007 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
19008 end = from + tused;
19009 to = it->glyph_row->glyphs[TEXT_AREA];
19010 toend = to + it->glyph_row->used[TEXT_AREA];
19011 if (FRAME_WINDOW_P (it->f))
19013 /* On GUI frames, when variable-size fonts are displayed,
19014 the truncation glyphs may need more pixels than the row's
19015 glyphs they overwrite. We overwrite more glyphs to free
19016 enough screen real estate, and enlarge the stretch glyph
19017 on the right (see display_line), if there is one, to
19018 preserve the screen position of the truncation glyphs on
19019 the right. */
19020 int w = 0;
19021 struct glyph *g = to;
19022 short used;
19024 /* The first glyph could be partially visible, in which case
19025 it->glyph_row->x will be negative. But we want the left
19026 truncation glyphs to be aligned at the left margin of the
19027 window, so we override the x coordinate at which the row
19028 will begin. */
19029 it->glyph_row->x = 0;
19030 while (g < toend && w < it->truncation_pixel_width)
19032 w += g->pixel_width;
19033 ++g;
19035 if (g - to - tused > 0)
19037 memmove (to + tused, g, (toend - g) * sizeof(*g));
19038 it->glyph_row->used[TEXT_AREA] -= g - to - tused;
19040 used = it->glyph_row->used[TEXT_AREA];
19041 if (it->glyph_row->truncated_on_right_p
19042 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
19043 && it->glyph_row->glyphs[TEXT_AREA][used - 2].type
19044 == STRETCH_GLYPH)
19046 int extra = w - it->truncation_pixel_width;
19048 it->glyph_row->glyphs[TEXT_AREA][used - 2].pixel_width += extra;
19052 while (from < end)
19053 *to++ = *from++;
19055 /* There may be padding glyphs left over. Overwrite them too. */
19056 if (!FRAME_WINDOW_P (it->f))
19058 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
19060 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
19061 while (from < end)
19062 *to++ = *from++;
19066 if (to > toend)
19067 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
19069 else
19071 short tused = truncate_it.glyph_row->used[TEXT_AREA];
19073 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
19074 that back to front. */
19075 end = truncate_it.glyph_row->glyphs[TEXT_AREA];
19076 from = end + truncate_it.glyph_row->used[TEXT_AREA] - 1;
19077 toend = it->glyph_row->glyphs[TEXT_AREA];
19078 to = toend + it->glyph_row->used[TEXT_AREA] - 1;
19079 if (FRAME_WINDOW_P (it->f))
19081 int w = 0;
19082 struct glyph *g = to;
19084 while (g >= toend && w < it->truncation_pixel_width)
19086 w += g->pixel_width;
19087 --g;
19089 if (to - g - tused > 0)
19090 to = g + tused;
19091 if (it->glyph_row->truncated_on_right_p
19092 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0
19093 && it->glyph_row->glyphs[TEXT_AREA][1].type == STRETCH_GLYPH)
19095 int extra = w - it->truncation_pixel_width;
19097 it->glyph_row->glyphs[TEXT_AREA][1].pixel_width += extra;
19101 while (from >= end && to >= toend)
19102 *to-- = *from--;
19103 if (!FRAME_WINDOW_P (it->f))
19105 while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
19107 from =
19108 truncate_it.glyph_row->glyphs[TEXT_AREA]
19109 + truncate_it.glyph_row->used[TEXT_AREA] - 1;
19110 while (from >= end && to >= toend)
19111 *to-- = *from--;
19114 if (from >= end)
19116 /* Need to free some room before prepending additional
19117 glyphs. */
19118 int move_by = from - end + 1;
19119 struct glyph *g0 = it->glyph_row->glyphs[TEXT_AREA];
19120 struct glyph *g = g0 + it->glyph_row->used[TEXT_AREA] - 1;
19122 for ( ; g >= g0; g--)
19123 g[move_by] = *g;
19124 while (from >= end)
19125 *to-- = *from--;
19126 it->glyph_row->used[TEXT_AREA] += move_by;
19131 /* Compute the hash code for ROW. */
19132 unsigned
19133 row_hash (struct glyph_row *row)
19135 int area, k;
19136 unsigned hashval = 0;
19138 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
19139 for (k = 0; k < row->used[area]; ++k)
19140 hashval = ((((hashval << 4) + (hashval >> 24)) & 0x0fffffff)
19141 + row->glyphs[area][k].u.val
19142 + row->glyphs[area][k].face_id
19143 + row->glyphs[area][k].padding_p
19144 + (row->glyphs[area][k].type << 2));
19146 return hashval;
19149 /* Compute the pixel height and width of IT->glyph_row.
19151 Most of the time, ascent and height of a display line will be equal
19152 to the max_ascent and max_height values of the display iterator
19153 structure. This is not the case if
19155 1. We hit ZV without displaying anything. In this case, max_ascent
19156 and max_height will be zero.
19158 2. We have some glyphs that don't contribute to the line height.
19159 (The glyph row flag contributes_to_line_height_p is for future
19160 pixmap extensions).
19162 The first case is easily covered by using default values because in
19163 these cases, the line height does not really matter, except that it
19164 must not be zero. */
19166 static void
19167 compute_line_metrics (struct it *it)
19169 struct glyph_row *row = it->glyph_row;
19171 if (FRAME_WINDOW_P (it->f))
19173 int i, min_y, max_y;
19175 /* The line may consist of one space only, that was added to
19176 place the cursor on it. If so, the row's height hasn't been
19177 computed yet. */
19178 if (row->height == 0)
19180 if (it->max_ascent + it->max_descent == 0)
19181 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
19182 row->ascent = it->max_ascent;
19183 row->height = it->max_ascent + it->max_descent;
19184 row->phys_ascent = it->max_phys_ascent;
19185 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
19186 row->extra_line_spacing = it->max_extra_line_spacing;
19189 /* Compute the width of this line. */
19190 row->pixel_width = row->x;
19191 for (i = 0; i < row->used[TEXT_AREA]; ++i)
19192 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
19194 eassert (row->pixel_width >= 0);
19195 eassert (row->ascent >= 0 && row->height > 0);
19197 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
19198 || MATRIX_ROW_OVERLAPS_PRED_P (row));
19200 /* If first line's physical ascent is larger than its logical
19201 ascent, use the physical ascent, and make the row taller.
19202 This makes accented characters fully visible. */
19203 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
19204 && row->phys_ascent > row->ascent)
19206 row->height += row->phys_ascent - row->ascent;
19207 row->ascent = row->phys_ascent;
19210 /* Compute how much of the line is visible. */
19211 row->visible_height = row->height;
19213 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
19214 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
19216 if (row->y < min_y)
19217 row->visible_height -= min_y - row->y;
19218 if (row->y + row->height > max_y)
19219 row->visible_height -= row->y + row->height - max_y;
19221 else
19223 row->pixel_width = row->used[TEXT_AREA];
19224 if (row->continued_p)
19225 row->pixel_width -= it->continuation_pixel_width;
19226 else if (row->truncated_on_right_p)
19227 row->pixel_width -= it->truncation_pixel_width;
19228 row->ascent = row->phys_ascent = 0;
19229 row->height = row->phys_height = row->visible_height = 1;
19230 row->extra_line_spacing = 0;
19233 /* Compute a hash code for this row. */
19234 row->hash = row_hash (row);
19236 it->max_ascent = it->max_descent = 0;
19237 it->max_phys_ascent = it->max_phys_descent = 0;
19241 /* Append one space to the glyph row of iterator IT if doing a
19242 window-based redisplay. The space has the same face as
19243 IT->face_id. Value is non-zero if a space was added.
19245 This function is called to make sure that there is always one glyph
19246 at the end of a glyph row that the cursor can be set on under
19247 window-systems. (If there weren't such a glyph we would not know
19248 how wide and tall a box cursor should be displayed).
19250 At the same time this space let's a nicely handle clearing to the
19251 end of the line if the row ends in italic text. */
19253 static int
19254 append_space_for_newline (struct it *it, int default_face_p)
19256 if (FRAME_WINDOW_P (it->f))
19258 int n = it->glyph_row->used[TEXT_AREA];
19260 if (it->glyph_row->glyphs[TEXT_AREA] + n
19261 < it->glyph_row->glyphs[1 + TEXT_AREA])
19263 /* Save some values that must not be changed.
19264 Must save IT->c and IT->len because otherwise
19265 ITERATOR_AT_END_P wouldn't work anymore after
19266 append_space_for_newline has been called. */
19267 enum display_element_type saved_what = it->what;
19268 int saved_c = it->c, saved_len = it->len;
19269 int saved_char_to_display = it->char_to_display;
19270 int saved_x = it->current_x;
19271 int saved_face_id = it->face_id;
19272 int saved_box_end = it->end_of_box_run_p;
19273 struct text_pos saved_pos;
19274 Lisp_Object saved_object;
19275 struct face *face;
19277 saved_object = it->object;
19278 saved_pos = it->position;
19280 it->what = IT_CHARACTER;
19281 memset (&it->position, 0, sizeof it->position);
19282 it->object = make_number (0);
19283 it->c = it->char_to_display = ' ';
19284 it->len = 1;
19286 /* If the default face was remapped, be sure to use the
19287 remapped face for the appended newline. */
19288 if (default_face_p)
19289 it->face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
19290 else if (it->face_before_selective_p)
19291 it->face_id = it->saved_face_id;
19292 face = FACE_FROM_ID (it->f, it->face_id);
19293 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
19294 /* In R2L rows, we will prepend a stretch glyph that will
19295 have the end_of_box_run_p flag set for it, so there's no
19296 need for the appended newline glyph to have that flag
19297 set. */
19298 if (it->glyph_row->reversed_p
19299 /* But if the appended newline glyph goes all the way to
19300 the end of the row, there will be no stretch glyph,
19301 so leave the box flag set. */
19302 && saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x)
19303 it->end_of_box_run_p = 0;
19305 PRODUCE_GLYPHS (it);
19307 it->override_ascent = -1;
19308 it->constrain_row_ascent_descent_p = 0;
19309 it->current_x = saved_x;
19310 it->object = saved_object;
19311 it->position = saved_pos;
19312 it->what = saved_what;
19313 it->face_id = saved_face_id;
19314 it->len = saved_len;
19315 it->c = saved_c;
19316 it->char_to_display = saved_char_to_display;
19317 it->end_of_box_run_p = saved_box_end;
19318 return 1;
19322 return 0;
19326 /* Extend the face of the last glyph in the text area of IT->glyph_row
19327 to the end of the display line. Called from display_line. If the
19328 glyph row is empty, add a space glyph to it so that we know the
19329 face to draw. Set the glyph row flag fill_line_p. If the glyph
19330 row is R2L, prepend a stretch glyph to cover the empty space to the
19331 left of the leftmost glyph. */
19333 static void
19334 extend_face_to_end_of_line (struct it *it)
19336 struct face *face, *default_face;
19337 struct frame *f = it->f;
19339 /* If line is already filled, do nothing. Non window-system frames
19340 get a grace of one more ``pixel'' because their characters are
19341 1-``pixel'' wide, so they hit the equality too early. This grace
19342 is needed only for R2L rows that are not continued, to produce
19343 one extra blank where we could display the cursor. */
19344 if ((it->current_x >= it->last_visible_x
19345 + (!FRAME_WINDOW_P (f)
19346 && it->glyph_row->reversed_p
19347 && !it->glyph_row->continued_p))
19348 /* If the window has display margins, we will need to extend
19349 their face even if the text area is filled. */
19350 && !(WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
19351 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0))
19352 return;
19354 /* The default face, possibly remapped. */
19355 default_face = FACE_FROM_ID (f, lookup_basic_face (f, DEFAULT_FACE_ID));
19357 /* Face extension extends the background and box of IT->face_id
19358 to the end of the line. If the background equals the background
19359 of the frame, we don't have to do anything. */
19360 if (it->face_before_selective_p)
19361 face = FACE_FROM_ID (f, it->saved_face_id);
19362 else
19363 face = FACE_FROM_ID (f, it->face_id);
19365 if (FRAME_WINDOW_P (f)
19366 && MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row)
19367 && face->box == FACE_NO_BOX
19368 && face->background == FRAME_BACKGROUND_PIXEL (f)
19369 #ifdef HAVE_WINDOW_SYSTEM
19370 && !face->stipple
19371 #endif
19372 && !it->glyph_row->reversed_p)
19373 return;
19375 /* Set the glyph row flag indicating that the face of the last glyph
19376 in the text area has to be drawn to the end of the text area. */
19377 it->glyph_row->fill_line_p = 1;
19379 /* If current character of IT is not ASCII, make sure we have the
19380 ASCII face. This will be automatically undone the next time
19381 get_next_display_element returns a multibyte character. Note
19382 that the character will always be single byte in unibyte
19383 text. */
19384 if (!ASCII_CHAR_P (it->c))
19386 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
19389 if (FRAME_WINDOW_P (f))
19391 /* If the row is empty, add a space with the current face of IT,
19392 so that we know which face to draw. */
19393 if (it->glyph_row->used[TEXT_AREA] == 0)
19395 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
19396 it->glyph_row->glyphs[TEXT_AREA][0].face_id = face->id;
19397 it->glyph_row->used[TEXT_AREA] = 1;
19399 /* Mode line and the header line don't have margins, and
19400 likewise the frame's tool-bar window, if there is any. */
19401 if (!(it->glyph_row->mode_line_p
19402 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
19403 || (WINDOWP (f->tool_bar_window)
19404 && it->w == XWINDOW (f->tool_bar_window))
19405 #endif
19408 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
19409 && it->glyph_row->used[LEFT_MARGIN_AREA] == 0)
19411 it->glyph_row->glyphs[LEFT_MARGIN_AREA][0] = space_glyph;
19412 it->glyph_row->glyphs[LEFT_MARGIN_AREA][0].face_id =
19413 default_face->id;
19414 it->glyph_row->used[LEFT_MARGIN_AREA] = 1;
19416 if (WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0
19417 && it->glyph_row->used[RIGHT_MARGIN_AREA] == 0)
19419 it->glyph_row->glyphs[RIGHT_MARGIN_AREA][0] = space_glyph;
19420 it->glyph_row->glyphs[RIGHT_MARGIN_AREA][0].face_id =
19421 default_face->id;
19422 it->glyph_row->used[RIGHT_MARGIN_AREA] = 1;
19425 #ifdef HAVE_WINDOW_SYSTEM
19426 if (it->glyph_row->reversed_p)
19428 /* Prepend a stretch glyph to the row, such that the
19429 rightmost glyph will be drawn flushed all the way to the
19430 right margin of the window. The stretch glyph that will
19431 occupy the empty space, if any, to the left of the
19432 glyphs. */
19433 struct font *font = face->font ? face->font : FRAME_FONT (f);
19434 struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA];
19435 struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA];
19436 struct glyph *g;
19437 int row_width, stretch_ascent, stretch_width;
19438 struct text_pos saved_pos;
19439 int saved_face_id, saved_avoid_cursor, saved_box_start;
19441 for (row_width = 0, g = row_start; g < row_end; g++)
19442 row_width += g->pixel_width;
19444 /* FIXME: There are various minor display glitches in R2L
19445 rows when only one of the fringes is missing. The
19446 strange condition below produces the least bad effect. */
19447 if ((WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)
19448 == (WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0)
19449 || WINDOW_RIGHT_FRINGE_WIDTH (it->w) != 0)
19450 stretch_width = window_box_width (it->w, TEXT_AREA);
19451 else
19452 stretch_width = it->last_visible_x - it->first_visible_x;
19453 stretch_width -= row_width;
19455 if (stretch_width > 0)
19457 stretch_ascent =
19458 (((it->ascent + it->descent)
19459 * FONT_BASE (font)) / FONT_HEIGHT (font));
19460 saved_pos = it->position;
19461 memset (&it->position, 0, sizeof it->position);
19462 saved_avoid_cursor = it->avoid_cursor_p;
19463 it->avoid_cursor_p = 1;
19464 saved_face_id = it->face_id;
19465 saved_box_start = it->start_of_box_run_p;
19466 /* The last row's stretch glyph should get the default
19467 face, to avoid painting the rest of the window with
19468 the region face, if the region ends at ZV. */
19469 if (it->glyph_row->ends_at_zv_p)
19470 it->face_id = default_face->id;
19471 else
19472 it->face_id = face->id;
19473 it->start_of_box_run_p = 0;
19474 append_stretch_glyph (it, make_number (0), stretch_width,
19475 it->ascent + it->descent, stretch_ascent);
19476 it->position = saved_pos;
19477 it->avoid_cursor_p = saved_avoid_cursor;
19478 it->face_id = saved_face_id;
19479 it->start_of_box_run_p = saved_box_start;
19481 /* If stretch_width comes out negative, it means that the
19482 last glyph is only partially visible. In R2L rows, we
19483 want the leftmost glyph to be partially visible, so we
19484 need to give the row the corresponding left offset. */
19485 if (stretch_width < 0)
19486 it->glyph_row->x = stretch_width;
19488 #endif /* HAVE_WINDOW_SYSTEM */
19490 else
19492 /* Save some values that must not be changed. */
19493 int saved_x = it->current_x;
19494 struct text_pos saved_pos;
19495 Lisp_Object saved_object;
19496 enum display_element_type saved_what = it->what;
19497 int saved_face_id = it->face_id;
19499 saved_object = it->object;
19500 saved_pos = it->position;
19502 it->what = IT_CHARACTER;
19503 memset (&it->position, 0, sizeof it->position);
19504 it->object = make_number (0);
19505 it->c = it->char_to_display = ' ';
19506 it->len = 1;
19508 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
19509 && (it->glyph_row->used[LEFT_MARGIN_AREA]
19510 < WINDOW_LEFT_MARGIN_WIDTH (it->w))
19511 && !it->glyph_row->mode_line_p
19512 && default_face->background != FRAME_BACKGROUND_PIXEL (f))
19514 struct glyph *g = it->glyph_row->glyphs[LEFT_MARGIN_AREA];
19515 struct glyph *e = g + it->glyph_row->used[LEFT_MARGIN_AREA];
19517 for (it->current_x = 0; g < e; g++)
19518 it->current_x += g->pixel_width;
19520 it->area = LEFT_MARGIN_AREA;
19521 it->face_id = default_face->id;
19522 while (it->glyph_row->used[LEFT_MARGIN_AREA]
19523 < WINDOW_LEFT_MARGIN_WIDTH (it->w))
19525 PRODUCE_GLYPHS (it);
19526 /* term.c:produce_glyphs advances it->current_x only for
19527 TEXT_AREA. */
19528 it->current_x += it->pixel_width;
19531 it->current_x = saved_x;
19532 it->area = TEXT_AREA;
19535 /* The last row's blank glyphs should get the default face, to
19536 avoid painting the rest of the window with the region face,
19537 if the region ends at ZV. */
19538 if (it->glyph_row->ends_at_zv_p)
19539 it->face_id = default_face->id;
19540 else
19541 it->face_id = face->id;
19542 PRODUCE_GLYPHS (it);
19544 while (it->current_x <= it->last_visible_x)
19545 PRODUCE_GLYPHS (it);
19547 if (WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0
19548 && (it->glyph_row->used[RIGHT_MARGIN_AREA]
19549 < WINDOW_RIGHT_MARGIN_WIDTH (it->w))
19550 && !it->glyph_row->mode_line_p
19551 && default_face->background != FRAME_BACKGROUND_PIXEL (f))
19553 struct glyph *g = it->glyph_row->glyphs[RIGHT_MARGIN_AREA];
19554 struct glyph *e = g + it->glyph_row->used[RIGHT_MARGIN_AREA];
19556 for ( ; g < e; g++)
19557 it->current_x += g->pixel_width;
19559 it->area = RIGHT_MARGIN_AREA;
19560 it->face_id = default_face->id;
19561 while (it->glyph_row->used[RIGHT_MARGIN_AREA]
19562 < WINDOW_RIGHT_MARGIN_WIDTH (it->w))
19564 PRODUCE_GLYPHS (it);
19565 it->current_x += it->pixel_width;
19568 it->area = TEXT_AREA;
19571 /* Don't count these blanks really. It would let us insert a left
19572 truncation glyph below and make us set the cursor on them, maybe. */
19573 it->current_x = saved_x;
19574 it->object = saved_object;
19575 it->position = saved_pos;
19576 it->what = saved_what;
19577 it->face_id = saved_face_id;
19582 /* Value is non-zero if text starting at CHARPOS in current_buffer is
19583 trailing whitespace. */
19585 static int
19586 trailing_whitespace_p (ptrdiff_t charpos)
19588 ptrdiff_t bytepos = CHAR_TO_BYTE (charpos);
19589 int c = 0;
19591 while (bytepos < ZV_BYTE
19592 && (c = FETCH_CHAR (bytepos),
19593 c == ' ' || c == '\t'))
19594 ++bytepos;
19596 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
19598 if (bytepos != PT_BYTE)
19599 return 1;
19601 return 0;
19605 /* Highlight trailing whitespace, if any, in ROW. */
19607 static void
19608 highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
19610 int used = row->used[TEXT_AREA];
19612 if (used)
19614 struct glyph *start = row->glyphs[TEXT_AREA];
19615 struct glyph *glyph = start + used - 1;
19617 if (row->reversed_p)
19619 /* Right-to-left rows need to be processed in the opposite
19620 direction, so swap the edge pointers. */
19621 glyph = start;
19622 start = row->glyphs[TEXT_AREA] + used - 1;
19625 /* Skip over glyphs inserted to display the cursor at the
19626 end of a line, for extending the face of the last glyph
19627 to the end of the line on terminals, and for truncation
19628 and continuation glyphs. */
19629 if (!row->reversed_p)
19631 while (glyph >= start
19632 && glyph->type == CHAR_GLYPH
19633 && INTEGERP (glyph->object))
19634 --glyph;
19636 else
19638 while (glyph <= start
19639 && glyph->type == CHAR_GLYPH
19640 && INTEGERP (glyph->object))
19641 ++glyph;
19644 /* If last glyph is a space or stretch, and it's trailing
19645 whitespace, set the face of all trailing whitespace glyphs in
19646 IT->glyph_row to `trailing-whitespace'. */
19647 if ((row->reversed_p ? glyph <= start : glyph >= start)
19648 && BUFFERP (glyph->object)
19649 && (glyph->type == STRETCH_GLYPH
19650 || (glyph->type == CHAR_GLYPH
19651 && glyph->u.ch == ' '))
19652 && trailing_whitespace_p (glyph->charpos))
19654 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
19655 if (face_id < 0)
19656 return;
19658 if (!row->reversed_p)
19660 while (glyph >= start
19661 && BUFFERP (glyph->object)
19662 && (glyph->type == STRETCH_GLYPH
19663 || (glyph->type == CHAR_GLYPH
19664 && glyph->u.ch == ' ')))
19665 (glyph--)->face_id = face_id;
19667 else
19669 while (glyph <= start
19670 && BUFFERP (glyph->object)
19671 && (glyph->type == STRETCH_GLYPH
19672 || (glyph->type == CHAR_GLYPH
19673 && glyph->u.ch == ' ')))
19674 (glyph++)->face_id = face_id;
19681 /* Value is non-zero if glyph row ROW should be
19682 considered to hold the buffer position CHARPOS. */
19684 static int
19685 row_for_charpos_p (struct glyph_row *row, ptrdiff_t charpos)
19687 int result = 1;
19689 if (charpos == CHARPOS (row->end.pos)
19690 || charpos == MATRIX_ROW_END_CHARPOS (row))
19692 /* Suppose the row ends on a string.
19693 Unless the row is continued, that means it ends on a newline
19694 in the string. If it's anything other than a display string
19695 (e.g., a before-string from an overlay), we don't want the
19696 cursor there. (This heuristic seems to give the optimal
19697 behavior for the various types of multi-line strings.)
19698 One exception: if the string has `cursor' property on one of
19699 its characters, we _do_ want the cursor there. */
19700 if (CHARPOS (row->end.string_pos) >= 0)
19702 if (row->continued_p)
19703 result = 1;
19704 else
19706 /* Check for `display' property. */
19707 struct glyph *beg = row->glyphs[TEXT_AREA];
19708 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
19709 struct glyph *glyph;
19711 result = 0;
19712 for (glyph = end; glyph >= beg; --glyph)
19713 if (STRINGP (glyph->object))
19715 Lisp_Object prop
19716 = Fget_char_property (make_number (charpos),
19717 Qdisplay, Qnil);
19718 result =
19719 (!NILP (prop)
19720 && display_prop_string_p (prop, glyph->object));
19721 /* If there's a `cursor' property on one of the
19722 string's characters, this row is a cursor row,
19723 even though this is not a display string. */
19724 if (!result)
19726 Lisp_Object s = glyph->object;
19728 for ( ; glyph >= beg && EQ (glyph->object, s); --glyph)
19730 ptrdiff_t gpos = glyph->charpos;
19732 if (!NILP (Fget_char_property (make_number (gpos),
19733 Qcursor, s)))
19735 result = 1;
19736 break;
19740 break;
19744 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
19746 /* If the row ends in middle of a real character,
19747 and the line is continued, we want the cursor here.
19748 That's because CHARPOS (ROW->end.pos) would equal
19749 PT if PT is before the character. */
19750 if (!row->ends_in_ellipsis_p)
19751 result = row->continued_p;
19752 else
19753 /* If the row ends in an ellipsis, then
19754 CHARPOS (ROW->end.pos) will equal point after the
19755 invisible text. We want that position to be displayed
19756 after the ellipsis. */
19757 result = 0;
19759 /* If the row ends at ZV, display the cursor at the end of that
19760 row instead of at the start of the row below. */
19761 else if (row->ends_at_zv_p)
19762 result = 1;
19763 else
19764 result = 0;
19767 return result;
19770 /* Value is non-zero if glyph row ROW should be
19771 used to hold the cursor. */
19773 static int
19774 cursor_row_p (struct glyph_row *row)
19776 return row_for_charpos_p (row, PT);
19781 /* Push the property PROP so that it will be rendered at the current
19782 position in IT. Return 1 if PROP was successfully pushed, 0
19783 otherwise. Called from handle_line_prefix to handle the
19784 `line-prefix' and `wrap-prefix' properties. */
19786 static int
19787 push_prefix_prop (struct it *it, Lisp_Object prop)
19789 struct text_pos pos =
19790 STRINGP (it->string) ? it->current.string_pos : it->current.pos;
19792 eassert (it->method == GET_FROM_BUFFER
19793 || it->method == GET_FROM_DISPLAY_VECTOR
19794 || it->method == GET_FROM_STRING);
19796 /* We need to save the current buffer/string position, so it will be
19797 restored by pop_it, because iterate_out_of_display_property
19798 depends on that being set correctly, but some situations leave
19799 it->position not yet set when this function is called. */
19800 push_it (it, &pos);
19802 if (STRINGP (prop))
19804 if (SCHARS (prop) == 0)
19806 pop_it (it);
19807 return 0;
19810 it->string = prop;
19811 it->string_from_prefix_prop_p = 1;
19812 it->multibyte_p = STRING_MULTIBYTE (it->string);
19813 it->current.overlay_string_index = -1;
19814 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
19815 it->end_charpos = it->string_nchars = SCHARS (it->string);
19816 it->method = GET_FROM_STRING;
19817 it->stop_charpos = 0;
19818 it->prev_stop = 0;
19819 it->base_level_stop = 0;
19821 /* Force paragraph direction to be that of the parent
19822 buffer/string. */
19823 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
19824 it->paragraph_embedding = it->bidi_it.paragraph_dir;
19825 else
19826 it->paragraph_embedding = L2R;
19828 /* Set up the bidi iterator for this display string. */
19829 if (it->bidi_p)
19831 it->bidi_it.string.lstring = it->string;
19832 it->bidi_it.string.s = NULL;
19833 it->bidi_it.string.schars = it->end_charpos;
19834 it->bidi_it.string.bufpos = IT_CHARPOS (*it);
19835 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
19836 it->bidi_it.string.unibyte = !it->multibyte_p;
19837 it->bidi_it.w = it->w;
19838 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
19841 else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
19843 it->method = GET_FROM_STRETCH;
19844 it->object = prop;
19846 #ifdef HAVE_WINDOW_SYSTEM
19847 else if (IMAGEP (prop))
19849 it->what = IT_IMAGE;
19850 it->image_id = lookup_image (it->f, prop);
19851 it->method = GET_FROM_IMAGE;
19853 #endif /* HAVE_WINDOW_SYSTEM */
19854 else
19856 pop_it (it); /* bogus display property, give up */
19857 return 0;
19860 return 1;
19863 /* Return the character-property PROP at the current position in IT. */
19865 static Lisp_Object
19866 get_it_property (struct it *it, Lisp_Object prop)
19868 Lisp_Object position, object = it->object;
19870 if (STRINGP (object))
19871 position = make_number (IT_STRING_CHARPOS (*it));
19872 else if (BUFFERP (object))
19874 position = make_number (IT_CHARPOS (*it));
19875 object = it->window;
19877 else
19878 return Qnil;
19880 return Fget_char_property (position, prop, object);
19883 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
19885 static void
19886 handle_line_prefix (struct it *it)
19888 Lisp_Object prefix;
19890 if (it->continuation_lines_width > 0)
19892 prefix = get_it_property (it, Qwrap_prefix);
19893 if (NILP (prefix))
19894 prefix = Vwrap_prefix;
19896 else
19898 prefix = get_it_property (it, Qline_prefix);
19899 if (NILP (prefix))
19900 prefix = Vline_prefix;
19902 if (! NILP (prefix) && push_prefix_prop (it, prefix))
19904 /* If the prefix is wider than the window, and we try to wrap
19905 it, it would acquire its own wrap prefix, and so on till the
19906 iterator stack overflows. So, don't wrap the prefix. */
19907 it->line_wrap = TRUNCATE;
19908 it->avoid_cursor_p = 1;
19914 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
19915 only for R2L lines from display_line and display_string, when they
19916 decide that too many glyphs were produced by PRODUCE_GLYPHS, and
19917 the line/string needs to be continued on the next glyph row. */
19918 static void
19919 unproduce_glyphs (struct it *it, int n)
19921 struct glyph *glyph, *end;
19923 eassert (it->glyph_row);
19924 eassert (it->glyph_row->reversed_p);
19925 eassert (it->area == TEXT_AREA);
19926 eassert (n <= it->glyph_row->used[TEXT_AREA]);
19928 if (n > it->glyph_row->used[TEXT_AREA])
19929 n = it->glyph_row->used[TEXT_AREA];
19930 glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
19931 end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
19932 for ( ; glyph < end; glyph++)
19933 glyph[-n] = *glyph;
19936 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
19937 and ROW->maxpos. */
19938 static void
19939 find_row_edges (struct it *it, struct glyph_row *row,
19940 ptrdiff_t min_pos, ptrdiff_t min_bpos,
19941 ptrdiff_t max_pos, ptrdiff_t max_bpos)
19943 /* FIXME: Revisit this when glyph ``spilling'' in continuation
19944 lines' rows is implemented for bidi-reordered rows. */
19946 /* ROW->minpos is the value of min_pos, the minimal buffer position
19947 we have in ROW, or ROW->start.pos if that is smaller. */
19948 if (min_pos <= ZV && min_pos < row->start.pos.charpos)
19949 SET_TEXT_POS (row->minpos, min_pos, min_bpos);
19950 else
19951 /* We didn't find buffer positions smaller than ROW->start, or
19952 didn't find _any_ valid buffer positions in any of the glyphs,
19953 so we must trust the iterator's computed positions. */
19954 row->minpos = row->start.pos;
19955 if (max_pos <= 0)
19957 max_pos = CHARPOS (it->current.pos);
19958 max_bpos = BYTEPOS (it->current.pos);
19961 /* Here are the various use-cases for ending the row, and the
19962 corresponding values for ROW->maxpos:
19964 Line ends in a newline from buffer eol_pos + 1
19965 Line is continued from buffer max_pos + 1
19966 Line is truncated on right it->current.pos
19967 Line ends in a newline from string max_pos + 1(*)
19968 (*) + 1 only when line ends in a forward scan
19969 Line is continued from string max_pos
19970 Line is continued from display vector max_pos
19971 Line is entirely from a string min_pos == max_pos
19972 Line is entirely from a display vector min_pos == max_pos
19973 Line that ends at ZV ZV
19975 If you discover other use-cases, please add them here as
19976 appropriate. */
19977 if (row->ends_at_zv_p)
19978 row->maxpos = it->current.pos;
19979 else if (row->used[TEXT_AREA])
19981 int seen_this_string = 0;
19982 struct glyph_row *r1 = row - 1;
19984 /* Did we see the same display string on the previous row? */
19985 if (STRINGP (it->object)
19986 /* this is not the first row */
19987 && row > it->w->desired_matrix->rows
19988 /* previous row is not the header line */
19989 && !r1->mode_line_p
19990 /* previous row also ends in a newline from a string */
19991 && r1->ends_in_newline_from_string_p)
19993 struct glyph *start, *end;
19995 /* Search for the last glyph of the previous row that came
19996 from buffer or string. Depending on whether the row is
19997 L2R or R2L, we need to process it front to back or the
19998 other way round. */
19999 if (!r1->reversed_p)
20001 start = r1->glyphs[TEXT_AREA];
20002 end = start + r1->used[TEXT_AREA];
20003 /* Glyphs inserted by redisplay have an integer (zero)
20004 as their object. */
20005 while (end > start
20006 && INTEGERP ((end - 1)->object)
20007 && (end - 1)->charpos <= 0)
20008 --end;
20009 if (end > start)
20011 if (EQ ((end - 1)->object, it->object))
20012 seen_this_string = 1;
20014 else
20015 /* If all the glyphs of the previous row were inserted
20016 by redisplay, it means the previous row was
20017 produced from a single newline, which is only
20018 possible if that newline came from the same string
20019 as the one which produced this ROW. */
20020 seen_this_string = 1;
20022 else
20024 end = r1->glyphs[TEXT_AREA] - 1;
20025 start = end + r1->used[TEXT_AREA];
20026 while (end < start
20027 && INTEGERP ((end + 1)->object)
20028 && (end + 1)->charpos <= 0)
20029 ++end;
20030 if (end < start)
20032 if (EQ ((end + 1)->object, it->object))
20033 seen_this_string = 1;
20035 else
20036 seen_this_string = 1;
20039 /* Take note of each display string that covers a newline only
20040 once, the first time we see it. This is for when a display
20041 string includes more than one newline in it. */
20042 if (row->ends_in_newline_from_string_p && !seen_this_string)
20044 /* If we were scanning the buffer forward when we displayed
20045 the string, we want to account for at least one buffer
20046 position that belongs to this row (position covered by
20047 the display string), so that cursor positioning will
20048 consider this row as a candidate when point is at the end
20049 of the visual line represented by this row. This is not
20050 required when scanning back, because max_pos will already
20051 have a much larger value. */
20052 if (CHARPOS (row->end.pos) > max_pos)
20053 INC_BOTH (max_pos, max_bpos);
20054 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
20056 else if (CHARPOS (it->eol_pos) > 0)
20057 SET_TEXT_POS (row->maxpos,
20058 CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
20059 else if (row->continued_p)
20061 /* If max_pos is different from IT's current position, it
20062 means IT->method does not belong to the display element
20063 at max_pos. However, it also means that the display
20064 element at max_pos was displayed in its entirety on this
20065 line, which is equivalent to saying that the next line
20066 starts at the next buffer position. */
20067 if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
20068 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
20069 else
20071 INC_BOTH (max_pos, max_bpos);
20072 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
20075 else if (row->truncated_on_right_p)
20076 /* display_line already called reseat_at_next_visible_line_start,
20077 which puts the iterator at the beginning of the next line, in
20078 the logical order. */
20079 row->maxpos = it->current.pos;
20080 else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
20081 /* A line that is entirely from a string/image/stretch... */
20082 row->maxpos = row->minpos;
20083 else
20084 emacs_abort ();
20086 else
20087 row->maxpos = it->current.pos;
20090 /* Construct the glyph row IT->glyph_row in the desired matrix of
20091 IT->w from text at the current position of IT. See dispextern.h
20092 for an overview of struct it. Value is non-zero if
20093 IT->glyph_row displays text, as opposed to a line displaying ZV
20094 only. */
20096 static int
20097 display_line (struct it *it)
20099 struct glyph_row *row = it->glyph_row;
20100 Lisp_Object overlay_arrow_string;
20101 struct it wrap_it;
20102 void *wrap_data = NULL;
20103 int may_wrap = 0, wrap_x IF_LINT (= 0);
20104 int wrap_row_used = -1;
20105 int wrap_row_ascent IF_LINT (= 0), wrap_row_height IF_LINT (= 0);
20106 int wrap_row_phys_ascent IF_LINT (= 0), wrap_row_phys_height IF_LINT (= 0);
20107 int wrap_row_extra_line_spacing IF_LINT (= 0);
20108 ptrdiff_t wrap_row_min_pos IF_LINT (= 0), wrap_row_min_bpos IF_LINT (= 0);
20109 ptrdiff_t wrap_row_max_pos IF_LINT (= 0), wrap_row_max_bpos IF_LINT (= 0);
20110 int cvpos;
20111 ptrdiff_t min_pos = ZV + 1, max_pos = 0;
20112 ptrdiff_t min_bpos IF_LINT (= 0), max_bpos IF_LINT (= 0);
20113 bool pending_handle_line_prefix = false;
20115 /* We always start displaying at hpos zero even if hscrolled. */
20116 eassert (it->hpos == 0 && it->current_x == 0);
20118 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
20119 >= it->w->desired_matrix->nrows)
20121 it->w->nrows_scale_factor++;
20122 it->f->fonts_changed = 1;
20123 return 0;
20126 /* Clear the result glyph row and enable it. */
20127 prepare_desired_row (it->w, row, false);
20129 row->y = it->current_y;
20130 row->start = it->start;
20131 row->continuation_lines_width = it->continuation_lines_width;
20132 row->displays_text_p = 1;
20133 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
20134 it->starts_in_middle_of_char_p = 0;
20136 /* Arrange the overlays nicely for our purposes. Usually, we call
20137 display_line on only one line at a time, in which case this
20138 can't really hurt too much, or we call it on lines which appear
20139 one after another in the buffer, in which case all calls to
20140 recenter_overlay_lists but the first will be pretty cheap. */
20141 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
20143 /* Move over display elements that are not visible because we are
20144 hscrolled. This may stop at an x-position < IT->first_visible_x
20145 if the first glyph is partially visible or if we hit a line end. */
20146 if (it->current_x < it->first_visible_x)
20148 enum move_it_result move_result;
20150 this_line_min_pos = row->start.pos;
20151 move_result = move_it_in_display_line_to (it, ZV, it->first_visible_x,
20152 MOVE_TO_POS | MOVE_TO_X);
20153 /* If we are under a large hscroll, move_it_in_display_line_to
20154 could hit the end of the line without reaching
20155 it->first_visible_x. Pretend that we did reach it. This is
20156 especially important on a TTY, where we will call
20157 extend_face_to_end_of_line, which needs to know how many
20158 blank glyphs to produce. */
20159 if (it->current_x < it->first_visible_x
20160 && (move_result == MOVE_NEWLINE_OR_CR
20161 || move_result == MOVE_POS_MATCH_OR_ZV))
20162 it->current_x = it->first_visible_x;
20164 /* Record the smallest positions seen while we moved over
20165 display elements that are not visible. This is needed by
20166 redisplay_internal for optimizing the case where the cursor
20167 stays inside the same line. The rest of this function only
20168 considers positions that are actually displayed, so
20169 RECORD_MAX_MIN_POS will not otherwise record positions that
20170 are hscrolled to the left of the left edge of the window. */
20171 min_pos = CHARPOS (this_line_min_pos);
20172 min_bpos = BYTEPOS (this_line_min_pos);
20174 else if (it->area == TEXT_AREA)
20176 /* We only do this when not calling move_it_in_display_line_to
20177 above, because that function calls itself handle_line_prefix. */
20178 handle_line_prefix (it);
20180 else
20182 /* Line-prefix and wrap-prefix are always displayed in the text
20183 area. But if this is the first call to display_line after
20184 init_iterator, the iterator might have been set up to write
20185 into a marginal area, e.g. if the line begins with some
20186 display property that writes to the margins. So we need to
20187 wait with the call to handle_line_prefix until whatever
20188 writes to the margin has done its job. */
20189 pending_handle_line_prefix = true;
20192 /* Get the initial row height. This is either the height of the
20193 text hscrolled, if there is any, or zero. */
20194 row->ascent = it->max_ascent;
20195 row->height = it->max_ascent + it->max_descent;
20196 row->phys_ascent = it->max_phys_ascent;
20197 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
20198 row->extra_line_spacing = it->max_extra_line_spacing;
20200 /* Utility macro to record max and min buffer positions seen until now. */
20201 #define RECORD_MAX_MIN_POS(IT) \
20202 do \
20204 int composition_p = !STRINGP ((IT)->string) \
20205 && ((IT)->what == IT_COMPOSITION); \
20206 ptrdiff_t current_pos = \
20207 composition_p ? (IT)->cmp_it.charpos \
20208 : IT_CHARPOS (*(IT)); \
20209 ptrdiff_t current_bpos = \
20210 composition_p ? CHAR_TO_BYTE (current_pos) \
20211 : IT_BYTEPOS (*(IT)); \
20212 if (current_pos < min_pos) \
20214 min_pos = current_pos; \
20215 min_bpos = current_bpos; \
20217 if (IT_CHARPOS (*it) > max_pos) \
20219 max_pos = IT_CHARPOS (*it); \
20220 max_bpos = IT_BYTEPOS (*it); \
20223 while (0)
20225 /* Loop generating characters. The loop is left with IT on the next
20226 character to display. */
20227 while (1)
20229 int n_glyphs_before, hpos_before, x_before;
20230 int x, nglyphs;
20231 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
20233 /* Retrieve the next thing to display. Value is zero if end of
20234 buffer reached. */
20235 if (!get_next_display_element (it))
20237 /* Maybe add a space at the end of this line that is used to
20238 display the cursor there under X. Set the charpos of the
20239 first glyph of blank lines not corresponding to any text
20240 to -1. */
20241 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
20242 row->exact_window_width_line_p = 1;
20243 else if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
20244 || row->used[TEXT_AREA] == 0)
20246 row->glyphs[TEXT_AREA]->charpos = -1;
20247 row->displays_text_p = 0;
20249 if (!NILP (BVAR (XBUFFER (it->w->contents), indicate_empty_lines))
20250 && (!MINI_WINDOW_P (it->w)
20251 || (minibuf_level && EQ (it->window, minibuf_window))))
20252 row->indicate_empty_line_p = 1;
20255 it->continuation_lines_width = 0;
20256 row->ends_at_zv_p = 1;
20257 /* A row that displays right-to-left text must always have
20258 its last face extended all the way to the end of line,
20259 even if this row ends in ZV, because we still write to
20260 the screen left to right. We also need to extend the
20261 last face if the default face is remapped to some
20262 different face, otherwise the functions that clear
20263 portions of the screen will clear with the default face's
20264 background color. */
20265 if (row->reversed_p
20266 || lookup_basic_face (it->f, DEFAULT_FACE_ID) != DEFAULT_FACE_ID)
20267 extend_face_to_end_of_line (it);
20268 break;
20271 /* Now, get the metrics of what we want to display. This also
20272 generates glyphs in `row' (which is IT->glyph_row). */
20273 n_glyphs_before = row->used[TEXT_AREA];
20274 x = it->current_x;
20276 /* Remember the line height so far in case the next element doesn't
20277 fit on the line. */
20278 if (it->line_wrap != TRUNCATE)
20280 ascent = it->max_ascent;
20281 descent = it->max_descent;
20282 phys_ascent = it->max_phys_ascent;
20283 phys_descent = it->max_phys_descent;
20285 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
20287 if (IT_DISPLAYING_WHITESPACE (it))
20288 may_wrap = 1;
20289 else if (may_wrap)
20291 SAVE_IT (wrap_it, *it, wrap_data);
20292 wrap_x = x;
20293 wrap_row_used = row->used[TEXT_AREA];
20294 wrap_row_ascent = row->ascent;
20295 wrap_row_height = row->height;
20296 wrap_row_phys_ascent = row->phys_ascent;
20297 wrap_row_phys_height = row->phys_height;
20298 wrap_row_extra_line_spacing = row->extra_line_spacing;
20299 wrap_row_min_pos = min_pos;
20300 wrap_row_min_bpos = min_bpos;
20301 wrap_row_max_pos = max_pos;
20302 wrap_row_max_bpos = max_bpos;
20303 may_wrap = 0;
20308 PRODUCE_GLYPHS (it);
20310 /* If this display element was in marginal areas, continue with
20311 the next one. */
20312 if (it->area != TEXT_AREA)
20314 row->ascent = max (row->ascent, it->max_ascent);
20315 row->height = max (row->height, it->max_ascent + it->max_descent);
20316 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
20317 row->phys_height = max (row->phys_height,
20318 it->max_phys_ascent + it->max_phys_descent);
20319 row->extra_line_spacing = max (row->extra_line_spacing,
20320 it->max_extra_line_spacing);
20321 set_iterator_to_next (it, 1);
20322 /* If we didn't handle the line/wrap prefix above, and the
20323 call to set_iterator_to_next just switched to TEXT_AREA,
20324 process the prefix now. */
20325 if (it->area == TEXT_AREA && pending_handle_line_prefix)
20327 pending_handle_line_prefix = false;
20328 handle_line_prefix (it);
20330 continue;
20333 /* Does the display element fit on the line? If we truncate
20334 lines, we should draw past the right edge of the window. If
20335 we don't truncate, we want to stop so that we can display the
20336 continuation glyph before the right margin. If lines are
20337 continued, there are two possible strategies for characters
20338 resulting in more than 1 glyph (e.g. tabs): Display as many
20339 glyphs as possible in this line and leave the rest for the
20340 continuation line, or display the whole element in the next
20341 line. Original redisplay did the former, so we do it also. */
20342 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
20343 hpos_before = it->hpos;
20344 x_before = x;
20346 if (/* Not a newline. */
20347 nglyphs > 0
20348 /* Glyphs produced fit entirely in the line. */
20349 && it->current_x < it->last_visible_x)
20351 it->hpos += nglyphs;
20352 row->ascent = max (row->ascent, it->max_ascent);
20353 row->height = max (row->height, it->max_ascent + it->max_descent);
20354 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
20355 row->phys_height = max (row->phys_height,
20356 it->max_phys_ascent + it->max_phys_descent);
20357 row->extra_line_spacing = max (row->extra_line_spacing,
20358 it->max_extra_line_spacing);
20359 if (it->current_x - it->pixel_width < it->first_visible_x
20360 /* In R2L rows, we arrange in extend_face_to_end_of_line
20361 to add a right offset to the line, by a suitable
20362 change to the stretch glyph that is the leftmost
20363 glyph of the line. */
20364 && !row->reversed_p)
20365 row->x = x - it->first_visible_x;
20366 /* Record the maximum and minimum buffer positions seen so
20367 far in glyphs that will be displayed by this row. */
20368 if (it->bidi_p)
20369 RECORD_MAX_MIN_POS (it);
20371 else
20373 int i, new_x;
20374 struct glyph *glyph;
20376 for (i = 0; i < nglyphs; ++i, x = new_x)
20378 /* Identify the glyphs added by the last call to
20379 PRODUCE_GLYPHS. In R2L rows, they are prepended to
20380 the previous glyphs. */
20381 if (!row->reversed_p)
20382 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
20383 else
20384 glyph = row->glyphs[TEXT_AREA] + nglyphs - 1 - i;
20385 new_x = x + glyph->pixel_width;
20387 if (/* Lines are continued. */
20388 it->line_wrap != TRUNCATE
20389 && (/* Glyph doesn't fit on the line. */
20390 new_x > it->last_visible_x
20391 /* Or it fits exactly on a window system frame. */
20392 || (new_x == it->last_visible_x
20393 && FRAME_WINDOW_P (it->f)
20394 && (row->reversed_p
20395 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
20396 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
20398 /* End of a continued line. */
20400 if (it->hpos == 0
20401 || (new_x == it->last_visible_x
20402 && FRAME_WINDOW_P (it->f)
20403 && (row->reversed_p
20404 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
20405 : WINDOW_RIGHT_FRINGE_WIDTH (it->w))))
20407 /* Current glyph is the only one on the line or
20408 fits exactly on the line. We must continue
20409 the line because we can't draw the cursor
20410 after the glyph. */
20411 row->continued_p = 1;
20412 it->current_x = new_x;
20413 it->continuation_lines_width += new_x;
20414 ++it->hpos;
20415 if (i == nglyphs - 1)
20417 /* If line-wrap is on, check if a previous
20418 wrap point was found. */
20419 if (wrap_row_used > 0
20420 /* Even if there is a previous wrap
20421 point, continue the line here as
20422 usual, if (i) the previous character
20423 was a space or tab AND (ii) the
20424 current character is not. */
20425 && (!may_wrap
20426 || IT_DISPLAYING_WHITESPACE (it)))
20427 goto back_to_wrap;
20429 /* Record the maximum and minimum buffer
20430 positions seen so far in glyphs that will be
20431 displayed by this row. */
20432 if (it->bidi_p)
20433 RECORD_MAX_MIN_POS (it);
20434 set_iterator_to_next (it, 1);
20435 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
20437 if (!get_next_display_element (it))
20439 row->exact_window_width_line_p = 1;
20440 it->continuation_lines_width = 0;
20441 row->continued_p = 0;
20442 row->ends_at_zv_p = 1;
20444 else if (ITERATOR_AT_END_OF_LINE_P (it))
20446 row->continued_p = 0;
20447 row->exact_window_width_line_p = 1;
20451 else if (it->bidi_p)
20452 RECORD_MAX_MIN_POS (it);
20453 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
20454 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)
20455 extend_face_to_end_of_line (it);
20457 else if (CHAR_GLYPH_PADDING_P (*glyph)
20458 && !FRAME_WINDOW_P (it->f))
20460 /* A padding glyph that doesn't fit on this line.
20461 This means the whole character doesn't fit
20462 on the line. */
20463 if (row->reversed_p)
20464 unproduce_glyphs (it, row->used[TEXT_AREA]
20465 - n_glyphs_before);
20466 row->used[TEXT_AREA] = n_glyphs_before;
20468 /* Fill the rest of the row with continuation
20469 glyphs like in 20.x. */
20470 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
20471 < row->glyphs[1 + TEXT_AREA])
20472 produce_special_glyphs (it, IT_CONTINUATION);
20474 row->continued_p = 1;
20475 it->current_x = x_before;
20476 it->continuation_lines_width += x_before;
20478 /* Restore the height to what it was before the
20479 element not fitting on the line. */
20480 it->max_ascent = ascent;
20481 it->max_descent = descent;
20482 it->max_phys_ascent = phys_ascent;
20483 it->max_phys_descent = phys_descent;
20484 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
20485 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)
20486 extend_face_to_end_of_line (it);
20488 else if (wrap_row_used > 0)
20490 back_to_wrap:
20491 if (row->reversed_p)
20492 unproduce_glyphs (it,
20493 row->used[TEXT_AREA] - wrap_row_used);
20494 RESTORE_IT (it, &wrap_it, wrap_data);
20495 it->continuation_lines_width += wrap_x;
20496 row->used[TEXT_AREA] = wrap_row_used;
20497 row->ascent = wrap_row_ascent;
20498 row->height = wrap_row_height;
20499 row->phys_ascent = wrap_row_phys_ascent;
20500 row->phys_height = wrap_row_phys_height;
20501 row->extra_line_spacing = wrap_row_extra_line_spacing;
20502 min_pos = wrap_row_min_pos;
20503 min_bpos = wrap_row_min_bpos;
20504 max_pos = wrap_row_max_pos;
20505 max_bpos = wrap_row_max_bpos;
20506 row->continued_p = 1;
20507 row->ends_at_zv_p = 0;
20508 row->exact_window_width_line_p = 0;
20509 it->continuation_lines_width += x;
20511 /* Make sure that a non-default face is extended
20512 up to the right margin of the window. */
20513 extend_face_to_end_of_line (it);
20515 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
20517 /* A TAB that extends past the right edge of the
20518 window. This produces a single glyph on
20519 window system frames. We leave the glyph in
20520 this row and let it fill the row, but don't
20521 consume the TAB. */
20522 if ((row->reversed_p
20523 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
20524 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
20525 produce_special_glyphs (it, IT_CONTINUATION);
20526 it->continuation_lines_width += it->last_visible_x;
20527 row->ends_in_middle_of_char_p = 1;
20528 row->continued_p = 1;
20529 glyph->pixel_width = it->last_visible_x - x;
20530 it->starts_in_middle_of_char_p = 1;
20531 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
20532 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)
20533 extend_face_to_end_of_line (it);
20535 else
20537 /* Something other than a TAB that draws past
20538 the right edge of the window. Restore
20539 positions to values before the element. */
20540 if (row->reversed_p)
20541 unproduce_glyphs (it, row->used[TEXT_AREA]
20542 - (n_glyphs_before + i));
20543 row->used[TEXT_AREA] = n_glyphs_before + i;
20545 /* Display continuation glyphs. */
20546 it->current_x = x_before;
20547 it->continuation_lines_width += x;
20548 if (!FRAME_WINDOW_P (it->f)
20549 || (row->reversed_p
20550 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
20551 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
20552 produce_special_glyphs (it, IT_CONTINUATION);
20553 row->continued_p = 1;
20555 extend_face_to_end_of_line (it);
20557 if (nglyphs > 1 && i > 0)
20559 row->ends_in_middle_of_char_p = 1;
20560 it->starts_in_middle_of_char_p = 1;
20563 /* Restore the height to what it was before the
20564 element not fitting on the line. */
20565 it->max_ascent = ascent;
20566 it->max_descent = descent;
20567 it->max_phys_ascent = phys_ascent;
20568 it->max_phys_descent = phys_descent;
20571 break;
20573 else if (new_x > it->first_visible_x)
20575 /* Increment number of glyphs actually displayed. */
20576 ++it->hpos;
20578 /* Record the maximum and minimum buffer positions
20579 seen so far in glyphs that will be displayed by
20580 this row. */
20581 if (it->bidi_p)
20582 RECORD_MAX_MIN_POS (it);
20584 if (x < it->first_visible_x && !row->reversed_p)
20585 /* Glyph is partially visible, i.e. row starts at
20586 negative X position. Don't do that in R2L
20587 rows, where we arrange to add a right offset to
20588 the line in extend_face_to_end_of_line, by a
20589 suitable change to the stretch glyph that is
20590 the leftmost glyph of the line. */
20591 row->x = x - it->first_visible_x;
20592 /* When the last glyph of an R2L row only fits
20593 partially on the line, we need to set row->x to a
20594 negative offset, so that the leftmost glyph is
20595 the one that is partially visible. But if we are
20596 going to produce the truncation glyph, this will
20597 be taken care of in produce_special_glyphs. */
20598 if (row->reversed_p
20599 && new_x > it->last_visible_x
20600 && !(it->line_wrap == TRUNCATE
20601 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0))
20603 eassert (FRAME_WINDOW_P (it->f));
20604 row->x = it->last_visible_x - new_x;
20607 else
20609 /* Glyph is completely off the left margin of the
20610 window. This should not happen because of the
20611 move_it_in_display_line at the start of this
20612 function, unless the text display area of the
20613 window is empty. */
20614 eassert (it->first_visible_x <= it->last_visible_x);
20617 /* Even if this display element produced no glyphs at all,
20618 we want to record its position. */
20619 if (it->bidi_p && nglyphs == 0)
20620 RECORD_MAX_MIN_POS (it);
20622 row->ascent = max (row->ascent, it->max_ascent);
20623 row->height = max (row->height, it->max_ascent + it->max_descent);
20624 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
20625 row->phys_height = max (row->phys_height,
20626 it->max_phys_ascent + it->max_phys_descent);
20627 row->extra_line_spacing = max (row->extra_line_spacing,
20628 it->max_extra_line_spacing);
20630 /* End of this display line if row is continued. */
20631 if (row->continued_p || row->ends_at_zv_p)
20632 break;
20635 at_end_of_line:
20636 /* Is this a line end? If yes, we're also done, after making
20637 sure that a non-default face is extended up to the right
20638 margin of the window. */
20639 if (ITERATOR_AT_END_OF_LINE_P (it))
20641 int used_before = row->used[TEXT_AREA];
20643 row->ends_in_newline_from_string_p = STRINGP (it->object);
20645 /* Add a space at the end of the line that is used to
20646 display the cursor there. */
20647 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
20648 append_space_for_newline (it, 0);
20650 /* Extend the face to the end of the line. */
20651 extend_face_to_end_of_line (it);
20653 /* Make sure we have the position. */
20654 if (used_before == 0)
20655 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
20657 /* Record the position of the newline, for use in
20658 find_row_edges. */
20659 it->eol_pos = it->current.pos;
20661 /* Consume the line end. This skips over invisible lines. */
20662 set_iterator_to_next (it, 1);
20663 it->continuation_lines_width = 0;
20664 break;
20667 /* Proceed with next display element. Note that this skips
20668 over lines invisible because of selective display. */
20669 set_iterator_to_next (it, 1);
20671 /* If we truncate lines, we are done when the last displayed
20672 glyphs reach past the right margin of the window. */
20673 if (it->line_wrap == TRUNCATE
20674 && ((FRAME_WINDOW_P (it->f)
20675 /* Images are preprocessed in produce_image_glyph such
20676 that they are cropped at the right edge of the
20677 window, so an image glyph will always end exactly at
20678 last_visible_x, even if there's no right fringe. */
20679 && ((row->reversed_p
20680 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
20681 : WINDOW_RIGHT_FRINGE_WIDTH (it->w))
20682 || it->what == IT_IMAGE))
20683 ? (it->current_x >= it->last_visible_x)
20684 : (it->current_x > it->last_visible_x)))
20686 /* Maybe add truncation glyphs. */
20687 if (!FRAME_WINDOW_P (it->f)
20688 || (row->reversed_p
20689 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
20690 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
20692 int i, n;
20694 if (!row->reversed_p)
20696 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
20697 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
20698 break;
20700 else
20702 for (i = 0; i < row->used[TEXT_AREA]; i++)
20703 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
20704 break;
20705 /* Remove any padding glyphs at the front of ROW, to
20706 make room for the truncation glyphs we will be
20707 adding below. The loop below always inserts at
20708 least one truncation glyph, so also remove the
20709 last glyph added to ROW. */
20710 unproduce_glyphs (it, i + 1);
20711 /* Adjust i for the loop below. */
20712 i = row->used[TEXT_AREA] - (i + 1);
20715 /* produce_special_glyphs overwrites the last glyph, so
20716 we don't want that if we want to keep that last
20717 glyph, which means it's an image. */
20718 if (it->current_x > it->last_visible_x)
20720 it->current_x = x_before;
20721 if (!FRAME_WINDOW_P (it->f))
20723 for (n = row->used[TEXT_AREA]; i < n; ++i)
20725 row->used[TEXT_AREA] = i;
20726 produce_special_glyphs (it, IT_TRUNCATION);
20729 else
20731 row->used[TEXT_AREA] = i;
20732 produce_special_glyphs (it, IT_TRUNCATION);
20734 it->hpos = hpos_before;
20737 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
20739 /* Don't truncate if we can overflow newline into fringe. */
20740 if (!get_next_display_element (it))
20742 it->continuation_lines_width = 0;
20743 row->ends_at_zv_p = 1;
20744 row->exact_window_width_line_p = 1;
20745 break;
20747 if (ITERATOR_AT_END_OF_LINE_P (it))
20749 row->exact_window_width_line_p = 1;
20750 goto at_end_of_line;
20752 it->current_x = x_before;
20753 it->hpos = hpos_before;
20756 row->truncated_on_right_p = 1;
20757 it->continuation_lines_width = 0;
20758 reseat_at_next_visible_line_start (it, 0);
20759 /* We insist below that IT's position be at ZV because in
20760 bidi-reordered lines the character at visible line start
20761 might not be the character that follows the newline in
20762 the logical order. */
20763 if (IT_BYTEPOS (*it) > BEG_BYTE)
20764 row->ends_at_zv_p =
20765 IT_BYTEPOS (*it) >= ZV_BYTE && FETCH_BYTE (ZV_BYTE - 1) != '\n';
20766 else
20767 row->ends_at_zv_p = false;
20768 break;
20772 if (wrap_data)
20773 bidi_unshelve_cache (wrap_data, 1);
20775 /* If line is not empty and hscrolled, maybe insert truncation glyphs
20776 at the left window margin. */
20777 if (it->first_visible_x
20778 && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
20780 if (!FRAME_WINDOW_P (it->f)
20781 || (((row->reversed_p
20782 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
20783 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
20784 /* Don't let insert_left_trunc_glyphs overwrite the
20785 first glyph of the row if it is an image. */
20786 && row->glyphs[TEXT_AREA]->type != IMAGE_GLYPH))
20787 insert_left_trunc_glyphs (it);
20788 row->truncated_on_left_p = 1;
20791 /* Remember the position at which this line ends.
20793 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
20794 cannot be before the call to find_row_edges below, since that is
20795 where these positions are determined. */
20796 row->end = it->current;
20797 if (!it->bidi_p)
20799 row->minpos = row->start.pos;
20800 row->maxpos = row->end.pos;
20802 else
20804 /* ROW->minpos and ROW->maxpos must be the smallest and
20805 `1 + the largest' buffer positions in ROW. But if ROW was
20806 bidi-reordered, these two positions can be anywhere in the
20807 row, so we must determine them now. */
20808 find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
20811 /* If the start of this line is the overlay arrow-position, then
20812 mark this glyph row as the one containing the overlay arrow.
20813 This is clearly a mess with variable size fonts. It would be
20814 better to let it be displayed like cursors under X. */
20815 if ((MATRIX_ROW_DISPLAYS_TEXT_P (row) || !overlay_arrow_seen)
20816 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
20817 !NILP (overlay_arrow_string)))
20819 /* Overlay arrow in window redisplay is a fringe bitmap. */
20820 if (STRINGP (overlay_arrow_string))
20822 struct glyph_row *arrow_row
20823 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
20824 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
20825 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
20826 struct glyph *p = row->glyphs[TEXT_AREA];
20827 struct glyph *p2, *end;
20829 /* Copy the arrow glyphs. */
20830 while (glyph < arrow_end)
20831 *p++ = *glyph++;
20833 /* Throw away padding glyphs. */
20834 p2 = p;
20835 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
20836 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
20837 ++p2;
20838 if (p2 > p)
20840 while (p2 < end)
20841 *p++ = *p2++;
20842 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
20845 else
20847 eassert (INTEGERP (overlay_arrow_string));
20848 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
20850 overlay_arrow_seen = 1;
20853 /* Highlight trailing whitespace. */
20854 if (!NILP (Vshow_trailing_whitespace))
20855 highlight_trailing_whitespace (it->f, it->glyph_row);
20857 /* Compute pixel dimensions of this line. */
20858 compute_line_metrics (it);
20860 /* Implementation note: No changes in the glyphs of ROW or in their
20861 faces can be done past this point, because compute_line_metrics
20862 computes ROW's hash value and stores it within the glyph_row
20863 structure. */
20865 /* Record whether this row ends inside an ellipsis. */
20866 row->ends_in_ellipsis_p
20867 = (it->method == GET_FROM_DISPLAY_VECTOR
20868 && it->ellipsis_p);
20870 /* Save fringe bitmaps in this row. */
20871 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
20872 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
20873 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
20874 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
20876 it->left_user_fringe_bitmap = 0;
20877 it->left_user_fringe_face_id = 0;
20878 it->right_user_fringe_bitmap = 0;
20879 it->right_user_fringe_face_id = 0;
20881 /* Maybe set the cursor. */
20882 cvpos = it->w->cursor.vpos;
20883 if ((cvpos < 0
20884 /* In bidi-reordered rows, keep checking for proper cursor
20885 position even if one has been found already, because buffer
20886 positions in such rows change non-linearly with ROW->VPOS,
20887 when a line is continued. One exception: when we are at ZV,
20888 display cursor on the first suitable glyph row, since all
20889 the empty rows after that also have their position set to ZV. */
20890 /* FIXME: Revisit this when glyph ``spilling'' in continuation
20891 lines' rows is implemented for bidi-reordered rows. */
20892 || (it->bidi_p
20893 && !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
20894 && PT >= MATRIX_ROW_START_CHARPOS (row)
20895 && PT <= MATRIX_ROW_END_CHARPOS (row)
20896 && cursor_row_p (row))
20897 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
20899 /* Prepare for the next line. This line starts horizontally at (X
20900 HPOS) = (0 0). Vertical positions are incremented. As a
20901 convenience for the caller, IT->glyph_row is set to the next
20902 row to be used. */
20903 it->current_x = it->hpos = 0;
20904 it->current_y += row->height;
20905 SET_TEXT_POS (it->eol_pos, 0, 0);
20906 ++it->vpos;
20907 ++it->glyph_row;
20908 /* The next row should by default use the same value of the
20909 reversed_p flag as this one. set_iterator_to_next decides when
20910 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
20911 the flag accordingly. */
20912 if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
20913 it->glyph_row->reversed_p = row->reversed_p;
20914 it->start = row->end;
20915 return MATRIX_ROW_DISPLAYS_TEXT_P (row);
20917 #undef RECORD_MAX_MIN_POS
20920 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,
20921 Scurrent_bidi_paragraph_direction, 0, 1, 0,
20922 doc: /* Return paragraph direction at point in BUFFER.
20923 Value is either `left-to-right' or `right-to-left'.
20924 If BUFFER is omitted or nil, it defaults to the current buffer.
20926 Paragraph direction determines how the text in the paragraph is displayed.
20927 In left-to-right paragraphs, text begins at the left margin of the window
20928 and the reading direction is generally left to right. In right-to-left
20929 paragraphs, text begins at the right margin and is read from right to left.
20931 See also `bidi-paragraph-direction'. */)
20932 (Lisp_Object buffer)
20934 struct buffer *buf = current_buffer;
20935 struct buffer *old = buf;
20937 if (! NILP (buffer))
20939 CHECK_BUFFER (buffer);
20940 buf = XBUFFER (buffer);
20943 if (NILP (BVAR (buf, bidi_display_reordering))
20944 || NILP (BVAR (buf, enable_multibyte_characters))
20945 /* When we are loading loadup.el, the character property tables
20946 needed for bidi iteration are not yet available. */
20947 || !NILP (Vpurify_flag))
20948 return Qleft_to_right;
20949 else if (!NILP (BVAR (buf, bidi_paragraph_direction)))
20950 return BVAR (buf, bidi_paragraph_direction);
20951 else
20953 /* Determine the direction from buffer text. We could try to
20954 use current_matrix if it is up to date, but this seems fast
20955 enough as it is. */
20956 struct bidi_it itb;
20957 ptrdiff_t pos = BUF_PT (buf);
20958 ptrdiff_t bytepos = BUF_PT_BYTE (buf);
20959 int c;
20960 void *itb_data = bidi_shelve_cache ();
20962 set_buffer_temp (buf);
20963 /* bidi_paragraph_init finds the base direction of the paragraph
20964 by searching forward from paragraph start. We need the base
20965 direction of the current or _previous_ paragraph, so we need
20966 to make sure we are within that paragraph. To that end, find
20967 the previous non-empty line. */
20968 if (pos >= ZV && pos > BEGV)
20969 DEC_BOTH (pos, bytepos);
20970 AUTO_STRING (trailing_white_space, "[\f\t ]*\n");
20971 if (fast_looking_at (trailing_white_space,
20972 pos, bytepos, ZV, ZV_BYTE, Qnil) > 0)
20974 while ((c = FETCH_BYTE (bytepos)) == '\n'
20975 || c == ' ' || c == '\t' || c == '\f')
20977 if (bytepos <= BEGV_BYTE)
20978 break;
20979 bytepos--;
20980 pos--;
20982 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos)))
20983 bytepos--;
20985 bidi_init_it (pos, bytepos, FRAME_WINDOW_P (SELECTED_FRAME ()), &itb);
20986 itb.paragraph_dir = NEUTRAL_DIR;
20987 itb.string.s = NULL;
20988 itb.string.lstring = Qnil;
20989 itb.string.bufpos = 0;
20990 itb.string.from_disp_str = 0;
20991 itb.string.unibyte = 0;
20992 /* We have no window to use here for ignoring window-specific
20993 overlays. Using NULL for window pointer will cause
20994 compute_display_string_pos to use the current buffer. */
20995 itb.w = NULL;
20996 bidi_paragraph_init (NEUTRAL_DIR, &itb, 1);
20997 bidi_unshelve_cache (itb_data, 0);
20998 set_buffer_temp (old);
20999 switch (itb.paragraph_dir)
21001 case L2R:
21002 return Qleft_to_right;
21003 break;
21004 case R2L:
21005 return Qright_to_left;
21006 break;
21007 default:
21008 emacs_abort ();
21013 DEFUN ("move-point-visually", Fmove_point_visually,
21014 Smove_point_visually, 1, 1, 0,
21015 doc: /* Move point in the visual order in the specified DIRECTION.
21016 DIRECTION can be 1, meaning move to the right, or -1, which moves to the
21017 left.
21019 Value is the new character position of point. */)
21020 (Lisp_Object direction)
21022 struct window *w = XWINDOW (selected_window);
21023 struct buffer *b = XBUFFER (w->contents);
21024 struct glyph_row *row;
21025 int dir;
21026 Lisp_Object paragraph_dir;
21028 #define ROW_GLYPH_NEWLINE_P(ROW,GLYPH) \
21029 (!(ROW)->continued_p \
21030 && INTEGERP ((GLYPH)->object) \
21031 && (GLYPH)->type == CHAR_GLYPH \
21032 && (GLYPH)->u.ch == ' ' \
21033 && (GLYPH)->charpos >= 0 \
21034 && !(GLYPH)->avoid_cursor_p)
21036 CHECK_NUMBER (direction);
21037 dir = XINT (direction);
21038 if (dir > 0)
21039 dir = 1;
21040 else
21041 dir = -1;
21043 /* If current matrix is up-to-date, we can use the information
21044 recorded in the glyphs, at least as long as the goal is on the
21045 screen. */
21046 if (w->window_end_valid
21047 && !windows_or_buffers_changed
21048 && b
21049 && !b->clip_changed
21050 && !b->prevent_redisplay_optimizations_p
21051 && !window_outdated (w)
21052 /* We rely below on the cursor coordinates to be up to date, but
21053 we cannot trust them if some command moved point since the
21054 last complete redisplay. */
21055 && w->last_point == BUF_PT (b)
21056 && w->cursor.vpos >= 0
21057 && w->cursor.vpos < w->current_matrix->nrows
21058 && (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos))->enabled_p)
21060 struct glyph *g = row->glyphs[TEXT_AREA];
21061 struct glyph *e = dir > 0 ? g + row->used[TEXT_AREA] : g - 1;
21062 struct glyph *gpt = g + w->cursor.hpos;
21064 for (g = gpt + dir; (dir > 0 ? g < e : g > e); g += dir)
21066 if (BUFFERP (g->object) && g->charpos != PT)
21068 SET_PT (g->charpos);
21069 w->cursor.vpos = -1;
21070 return make_number (PT);
21072 else if (!INTEGERP (g->object) && !EQ (g->object, gpt->object))
21074 ptrdiff_t new_pos;
21076 if (BUFFERP (gpt->object))
21078 new_pos = PT;
21079 if ((gpt->resolved_level - row->reversed_p) % 2 == 0)
21080 new_pos += (row->reversed_p ? -dir : dir);
21081 else
21082 new_pos -= (row->reversed_p ? -dir : dir);
21084 else if (BUFFERP (g->object))
21085 new_pos = g->charpos;
21086 else
21087 break;
21088 SET_PT (new_pos);
21089 w->cursor.vpos = -1;
21090 return make_number (PT);
21092 else if (ROW_GLYPH_NEWLINE_P (row, g))
21094 /* Glyphs inserted at the end of a non-empty line for
21095 positioning the cursor have zero charpos, so we must
21096 deduce the value of point by other means. */
21097 if (g->charpos > 0)
21098 SET_PT (g->charpos);
21099 else if (row->ends_at_zv_p && PT != ZV)
21100 SET_PT (ZV);
21101 else if (PT != MATRIX_ROW_END_CHARPOS (row) - 1)
21102 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
21103 else
21104 break;
21105 w->cursor.vpos = -1;
21106 return make_number (PT);
21109 if (g == e || INTEGERP (g->object))
21111 if (row->truncated_on_left_p || row->truncated_on_right_p)
21112 goto simulate_display;
21113 if (!row->reversed_p)
21114 row += dir;
21115 else
21116 row -= dir;
21117 if (row < MATRIX_FIRST_TEXT_ROW (w->current_matrix)
21118 || row > MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
21119 goto simulate_display;
21121 if (dir > 0)
21123 if (row->reversed_p && !row->continued_p)
21125 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
21126 w->cursor.vpos = -1;
21127 return make_number (PT);
21129 g = row->glyphs[TEXT_AREA];
21130 e = g + row->used[TEXT_AREA];
21131 for ( ; g < e; g++)
21133 if (BUFFERP (g->object)
21134 /* Empty lines have only one glyph, which stands
21135 for the newline, and whose charpos is the
21136 buffer position of the newline. */
21137 || ROW_GLYPH_NEWLINE_P (row, g)
21138 /* When the buffer ends in a newline, the line at
21139 EOB also has one glyph, but its charpos is -1. */
21140 || (row->ends_at_zv_p
21141 && !row->reversed_p
21142 && INTEGERP (g->object)
21143 && g->type == CHAR_GLYPH
21144 && g->u.ch == ' '))
21146 if (g->charpos > 0)
21147 SET_PT (g->charpos);
21148 else if (!row->reversed_p
21149 && row->ends_at_zv_p
21150 && PT != ZV)
21151 SET_PT (ZV);
21152 else
21153 continue;
21154 w->cursor.vpos = -1;
21155 return make_number (PT);
21159 else
21161 if (!row->reversed_p && !row->continued_p)
21163 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
21164 w->cursor.vpos = -1;
21165 return make_number (PT);
21167 e = row->glyphs[TEXT_AREA];
21168 g = e + row->used[TEXT_AREA] - 1;
21169 for ( ; g >= e; g--)
21171 if (BUFFERP (g->object)
21172 || (ROW_GLYPH_NEWLINE_P (row, g)
21173 && g->charpos > 0)
21174 /* Empty R2L lines on GUI frames have the buffer
21175 position of the newline stored in the stretch
21176 glyph. */
21177 || g->type == STRETCH_GLYPH
21178 || (row->ends_at_zv_p
21179 && row->reversed_p
21180 && INTEGERP (g->object)
21181 && g->type == CHAR_GLYPH
21182 && g->u.ch == ' '))
21184 if (g->charpos > 0)
21185 SET_PT (g->charpos);
21186 else if (row->reversed_p
21187 && row->ends_at_zv_p
21188 && PT != ZV)
21189 SET_PT (ZV);
21190 else
21191 continue;
21192 w->cursor.vpos = -1;
21193 return make_number (PT);
21200 simulate_display:
21202 /* If we wind up here, we failed to move by using the glyphs, so we
21203 need to simulate display instead. */
21205 if (b)
21206 paragraph_dir = Fcurrent_bidi_paragraph_direction (w->contents);
21207 else
21208 paragraph_dir = Qleft_to_right;
21209 if (EQ (paragraph_dir, Qright_to_left))
21210 dir = -dir;
21211 if (PT <= BEGV && dir < 0)
21212 xsignal0 (Qbeginning_of_buffer);
21213 else if (PT >= ZV && dir > 0)
21214 xsignal0 (Qend_of_buffer);
21215 else
21217 struct text_pos pt;
21218 struct it it;
21219 int pt_x, target_x, pixel_width, pt_vpos;
21220 bool at_eol_p;
21221 bool overshoot_expected = false;
21222 bool target_is_eol_p = false;
21224 /* Setup the arena. */
21225 SET_TEXT_POS (pt, PT, PT_BYTE);
21226 start_display (&it, w, pt);
21228 if (it.cmp_it.id < 0
21229 && it.method == GET_FROM_STRING
21230 && it.area == TEXT_AREA
21231 && it.string_from_display_prop_p
21232 && (it.sp > 0 && it.stack[it.sp - 1].method == GET_FROM_BUFFER))
21233 overshoot_expected = true;
21235 /* Find the X coordinate of point. We start from the beginning
21236 of this or previous line to make sure we are before point in
21237 the logical order (since the move_it_* functions can only
21238 move forward). */
21239 reseat:
21240 reseat_at_previous_visible_line_start (&it);
21241 it.current_x = it.hpos = it.current_y = it.vpos = 0;
21242 if (IT_CHARPOS (it) != PT)
21244 move_it_to (&it, overshoot_expected ? PT - 1 : PT,
21245 -1, -1, -1, MOVE_TO_POS);
21246 /* If we missed point because the character there is
21247 displayed out of a display vector that has more than one
21248 glyph, retry expecting overshoot. */
21249 if (it.method == GET_FROM_DISPLAY_VECTOR
21250 && it.current.dpvec_index > 0
21251 && !overshoot_expected)
21253 overshoot_expected = true;
21254 goto reseat;
21256 else if (IT_CHARPOS (it) != PT && !overshoot_expected)
21257 move_it_in_display_line (&it, PT, -1, MOVE_TO_POS);
21259 pt_x = it.current_x;
21260 pt_vpos = it.vpos;
21261 if (dir > 0 || overshoot_expected)
21263 struct glyph_row *row = it.glyph_row;
21265 /* When point is at beginning of line, we don't have
21266 information about the glyph there loaded into struct
21267 it. Calling get_next_display_element fixes that. */
21268 if (pt_x == 0)
21269 get_next_display_element (&it);
21270 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
21271 it.glyph_row = NULL;
21272 PRODUCE_GLYPHS (&it); /* compute it.pixel_width */
21273 it.glyph_row = row;
21274 /* PRODUCE_GLYPHS advances it.current_x, so we must restore
21275 it, lest it will become out of sync with it's buffer
21276 position. */
21277 it.current_x = pt_x;
21279 else
21280 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
21281 pixel_width = it.pixel_width;
21282 if (overshoot_expected && at_eol_p)
21283 pixel_width = 0;
21284 else if (pixel_width <= 0)
21285 pixel_width = 1;
21287 /* If there's a display string (or something similar) at point,
21288 we are actually at the glyph to the left of point, so we need
21289 to correct the X coordinate. */
21290 if (overshoot_expected)
21292 if (it.bidi_p)
21293 pt_x += pixel_width * it.bidi_it.scan_dir;
21294 else
21295 pt_x += pixel_width;
21298 /* Compute target X coordinate, either to the left or to the
21299 right of point. On TTY frames, all characters have the same
21300 pixel width of 1, so we can use that. On GUI frames we don't
21301 have an easy way of getting at the pixel width of the
21302 character to the left of point, so we use a different method
21303 of getting to that place. */
21304 if (dir > 0)
21305 target_x = pt_x + pixel_width;
21306 else
21307 target_x = pt_x - (!FRAME_WINDOW_P (it.f)) * pixel_width;
21309 /* Target X coordinate could be one line above or below the line
21310 of point, in which case we need to adjust the target X
21311 coordinate. Also, if moving to the left, we need to begin at
21312 the left edge of the point's screen line. */
21313 if (dir < 0)
21315 if (pt_x > 0)
21317 start_display (&it, w, pt);
21318 reseat_at_previous_visible_line_start (&it);
21319 it.current_x = it.current_y = it.hpos = 0;
21320 if (pt_vpos != 0)
21321 move_it_by_lines (&it, pt_vpos);
21323 else
21325 move_it_by_lines (&it, -1);
21326 target_x = it.last_visible_x - !FRAME_WINDOW_P (it.f);
21327 target_is_eol_p = true;
21328 /* Under word-wrap, we don't know the x coordinate of
21329 the last character displayed on the previous line,
21330 which immediately precedes the wrap point. To find
21331 out its x coordinate, we try moving to the right
21332 margin of the window, which will stop at the wrap
21333 point, and then reset target_x to point at the
21334 character that precedes the wrap point. This is not
21335 needed on GUI frames, because (see below) there we
21336 move from the left margin one grapheme cluster at a
21337 time, and stop when we hit the wrap point. */
21338 if (!FRAME_WINDOW_P (it.f) && it.line_wrap == WORD_WRAP)
21340 void *it_data = NULL;
21341 struct it it2;
21343 SAVE_IT (it2, it, it_data);
21344 move_it_in_display_line_to (&it, ZV, target_x,
21345 MOVE_TO_POS | MOVE_TO_X);
21346 /* If we arrived at target_x, that _is_ the last
21347 character on the previous line. */
21348 if (it.current_x != target_x)
21349 target_x = it.current_x - 1;
21350 RESTORE_IT (&it, &it2, it_data);
21354 else
21356 if (at_eol_p
21357 || (target_x >= it.last_visible_x
21358 && it.line_wrap != TRUNCATE))
21360 if (pt_x > 0)
21361 move_it_by_lines (&it, 0);
21362 move_it_by_lines (&it, 1);
21363 target_x = 0;
21367 /* Move to the target X coordinate. */
21368 #ifdef HAVE_WINDOW_SYSTEM
21369 /* On GUI frames, as we don't know the X coordinate of the
21370 character to the left of point, moving point to the left
21371 requires walking, one grapheme cluster at a time, until we
21372 find ourself at a place immediately to the left of the
21373 character at point. */
21374 if (FRAME_WINDOW_P (it.f) && dir < 0)
21376 struct text_pos new_pos;
21377 enum move_it_result rc = MOVE_X_REACHED;
21379 if (it.current_x == 0)
21380 get_next_display_element (&it);
21381 if (it.what == IT_COMPOSITION)
21383 new_pos.charpos = it.cmp_it.charpos;
21384 new_pos.bytepos = -1;
21386 else
21387 new_pos = it.current.pos;
21389 while (it.current_x + it.pixel_width <= target_x
21390 && (rc == MOVE_X_REACHED
21391 /* Under word-wrap, move_it_in_display_line_to
21392 stops at correct coordinates, but sometimes
21393 returns MOVE_POS_MATCH_OR_ZV. */
21394 || (it.line_wrap == WORD_WRAP
21395 && rc == MOVE_POS_MATCH_OR_ZV)))
21397 int new_x = it.current_x + it.pixel_width;
21399 /* For composed characters, we want the position of the
21400 first character in the grapheme cluster (usually, the
21401 composition's base character), whereas it.current
21402 might give us the position of the _last_ one, e.g. if
21403 the composition is rendered in reverse due to bidi
21404 reordering. */
21405 if (it.what == IT_COMPOSITION)
21407 new_pos.charpos = it.cmp_it.charpos;
21408 new_pos.bytepos = -1;
21410 else
21411 new_pos = it.current.pos;
21412 if (new_x == it.current_x)
21413 new_x++;
21414 rc = move_it_in_display_line_to (&it, ZV, new_x,
21415 MOVE_TO_POS | MOVE_TO_X);
21416 if (ITERATOR_AT_END_OF_LINE_P (&it) && !target_is_eol_p)
21417 break;
21419 /* The previous position we saw in the loop is the one we
21420 want. */
21421 if (new_pos.bytepos == -1)
21422 new_pos.bytepos = CHAR_TO_BYTE (new_pos.charpos);
21423 it.current.pos = new_pos;
21425 else
21426 #endif
21427 if (it.current_x != target_x)
21428 move_it_in_display_line_to (&it, ZV, target_x, MOVE_TO_POS | MOVE_TO_X);
21430 /* When lines are truncated, the above loop will stop at the
21431 window edge. But we want to get to the end of line, even if
21432 it is beyond the window edge; automatic hscroll will then
21433 scroll the window to show point as appropriate. */
21434 if (target_is_eol_p && it.line_wrap == TRUNCATE
21435 && get_next_display_element (&it))
21437 struct text_pos new_pos = it.current.pos;
21439 while (!ITERATOR_AT_END_OF_LINE_P (&it))
21441 set_iterator_to_next (&it, 0);
21442 if (it.method == GET_FROM_BUFFER)
21443 new_pos = it.current.pos;
21444 if (!get_next_display_element (&it))
21445 break;
21448 it.current.pos = new_pos;
21451 /* If we ended up in a display string that covers point, move to
21452 buffer position to the right in the visual order. */
21453 if (dir > 0)
21455 while (IT_CHARPOS (it) == PT)
21457 set_iterator_to_next (&it, 0);
21458 if (!get_next_display_element (&it))
21459 break;
21463 /* Move point to that position. */
21464 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
21467 return make_number (PT);
21469 #undef ROW_GLYPH_NEWLINE_P
21472 DEFUN ("bidi-resolved-levels", Fbidi_resolved_levels,
21473 Sbidi_resolved_levels, 0, 1, 0,
21474 doc: /* Return the resolved bidirectional levels of characters at VPOS.
21476 The resolved levels are produced by the Emacs bidi reordering engine
21477 that implements the UBA, the Unicode Bidirectional Algorithm. Please
21478 read the Unicode Standard Annex 9 (UAX#9) for background information
21479 about these levels.
21481 VPOS is the zero-based number of the current window's screen line
21482 for which to produce the resolved levels. If VPOS is nil or omitted,
21483 it defaults to the screen line of point. If the window displays a
21484 header line, VPOS of zero will report on the header line, and first
21485 line of text in the window will have VPOS of 1.
21487 Value is an array of resolved levels, indexed by glyph number.
21488 Glyphs are numbered from zero starting from the beginning of the
21489 screen line, i.e. the left edge of the window for left-to-right lines
21490 and from the right edge for right-to-left lines. The resolved levels
21491 are produced only for the window's text area; text in display margins
21492 is not included.
21494 If the selected window's display is not up-to-date, or if the specified
21495 screen line does not display text, this function returns nil. It is
21496 highly recommended to bind this function to some simple key, like F8,
21497 in order to avoid these problems.
21499 This function exists mainly for testing the correctness of the
21500 Emacs UBA implementation, in particular with the test suite. */)
21501 (Lisp_Object vpos)
21503 struct window *w = XWINDOW (selected_window);
21504 struct buffer *b = XBUFFER (w->contents);
21505 int nrow;
21506 struct glyph_row *row;
21508 if (NILP (vpos))
21510 int d1, d2, d3, d4, d5;
21512 pos_visible_p (w, PT, &d1, &d2, &d3, &d4, &d5, &nrow);
21514 else
21516 CHECK_NUMBER_COERCE_MARKER (vpos);
21517 nrow = XINT (vpos);
21520 /* We require up-to-date glyph matrix for this window. */
21521 if (w->window_end_valid
21522 && !windows_or_buffers_changed
21523 && b
21524 && !b->clip_changed
21525 && !b->prevent_redisplay_optimizations_p
21526 && !window_outdated (w)
21527 && nrow >= 0
21528 && nrow < w->current_matrix->nrows
21529 && (row = MATRIX_ROW (w->current_matrix, nrow))->enabled_p
21530 && MATRIX_ROW_DISPLAYS_TEXT_P (row))
21532 struct glyph *g, *e, *g1;
21533 int nglyphs, i;
21534 Lisp_Object levels;
21536 if (!row->reversed_p) /* Left-to-right glyph row. */
21538 g = g1 = row->glyphs[TEXT_AREA];
21539 e = g + row->used[TEXT_AREA];
21541 /* Skip over glyphs at the start of the row that was
21542 generated by redisplay for its own needs. */
21543 while (g < e
21544 && INTEGERP (g->object)
21545 && g->charpos < 0)
21546 g++;
21547 g1 = g;
21549 /* Count the "interesting" glyphs in this row. */
21550 for (nglyphs = 0; g < e && !INTEGERP (g->object); g++)
21551 nglyphs++;
21553 /* Create and fill the array. */
21554 levels = make_uninit_vector (nglyphs);
21555 for (i = 0; g1 < g; i++, g1++)
21556 ASET (levels, i, make_number (g1->resolved_level));
21558 else /* Right-to-left glyph row. */
21560 g = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
21561 e = row->glyphs[TEXT_AREA] - 1;
21562 while (g > e
21563 && INTEGERP (g->object)
21564 && g->charpos < 0)
21565 g--;
21566 g1 = g;
21567 for (nglyphs = 0; g > e && !INTEGERP (g->object); g--)
21568 nglyphs++;
21569 levels = make_uninit_vector (nglyphs);
21570 for (i = 0; g1 > g; i++, g1--)
21571 ASET (levels, i, make_number (g1->resolved_level));
21573 return levels;
21575 else
21576 return Qnil;
21581 /***********************************************************************
21582 Menu Bar
21583 ***********************************************************************/
21585 /* Redisplay the menu bar in the frame for window W.
21587 The menu bar of X frames that don't have X toolkit support is
21588 displayed in a special window W->frame->menu_bar_window.
21590 The menu bar of terminal frames is treated specially as far as
21591 glyph matrices are concerned. Menu bar lines are not part of
21592 windows, so the update is done directly on the frame matrix rows
21593 for the menu bar. */
21595 static void
21596 display_menu_bar (struct window *w)
21598 struct frame *f = XFRAME (WINDOW_FRAME (w));
21599 struct it it;
21600 Lisp_Object items;
21601 int i;
21603 /* Don't do all this for graphical frames. */
21604 #ifdef HAVE_NTGUI
21605 if (FRAME_W32_P (f))
21606 return;
21607 #endif
21608 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
21609 if (FRAME_X_P (f))
21610 return;
21611 #endif
21613 #ifdef HAVE_NS
21614 if (FRAME_NS_P (f))
21615 return;
21616 #endif /* HAVE_NS */
21618 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
21619 eassert (!FRAME_WINDOW_P (f));
21620 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
21621 it.first_visible_x = 0;
21622 it.last_visible_x = FRAME_PIXEL_WIDTH (f);
21623 #elif defined (HAVE_X_WINDOWS) /* X without toolkit. */
21624 if (FRAME_WINDOW_P (f))
21626 /* Menu bar lines are displayed in the desired matrix of the
21627 dummy window menu_bar_window. */
21628 struct window *menu_w;
21629 menu_w = XWINDOW (f->menu_bar_window);
21630 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
21631 MENU_FACE_ID);
21632 it.first_visible_x = 0;
21633 it.last_visible_x = FRAME_PIXEL_WIDTH (f);
21635 else
21636 #endif /* not USE_X_TOOLKIT and not USE_GTK */
21638 /* This is a TTY frame, i.e. character hpos/vpos are used as
21639 pixel x/y. */
21640 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
21641 MENU_FACE_ID);
21642 it.first_visible_x = 0;
21643 it.last_visible_x = FRAME_COLS (f);
21646 /* FIXME: This should be controlled by a user option. See the
21647 comments in redisplay_tool_bar and display_mode_line about
21648 this. */
21649 it.paragraph_embedding = L2R;
21651 /* Clear all rows of the menu bar. */
21652 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
21654 struct glyph_row *row = it.glyph_row + i;
21655 clear_glyph_row (row);
21656 row->enabled_p = true;
21657 row->full_width_p = 1;
21658 row->reversed_p = false;
21661 /* Display all items of the menu bar. */
21662 items = FRAME_MENU_BAR_ITEMS (it.f);
21663 for (i = 0; i < ASIZE (items); i += 4)
21665 Lisp_Object string;
21667 /* Stop at nil string. */
21668 string = AREF (items, i + 1);
21669 if (NILP (string))
21670 break;
21672 /* Remember where item was displayed. */
21673 ASET (items, i + 3, make_number (it.hpos));
21675 /* Display the item, pad with one space. */
21676 if (it.current_x < it.last_visible_x)
21677 display_string (NULL, string, Qnil, 0, 0, &it,
21678 SCHARS (string) + 1, 0, 0, -1);
21681 /* Fill out the line with spaces. */
21682 if (it.current_x < it.last_visible_x)
21683 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
21685 /* Compute the total height of the lines. */
21686 compute_line_metrics (&it);
21689 /* Deep copy of a glyph row, including the glyphs. */
21690 static void
21691 deep_copy_glyph_row (struct glyph_row *to, struct glyph_row *from)
21693 struct glyph *pointers[1 + LAST_AREA];
21694 int to_used = to->used[TEXT_AREA];
21696 /* Save glyph pointers of TO. */
21697 memcpy (pointers, to->glyphs, sizeof to->glyphs);
21699 /* Do a structure assignment. */
21700 *to = *from;
21702 /* Restore original glyph pointers of TO. */
21703 memcpy (to->glyphs, pointers, sizeof to->glyphs);
21705 /* Copy the glyphs. */
21706 memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA],
21707 min (from->used[TEXT_AREA], to_used) * sizeof (struct glyph));
21709 /* If we filled only part of the TO row, fill the rest with
21710 space_glyph (which will display as empty space). */
21711 if (to_used > from->used[TEXT_AREA])
21712 fill_up_frame_row_with_spaces (to, to_used);
21715 /* Display one menu item on a TTY, by overwriting the glyphs in the
21716 frame F's desired glyph matrix with glyphs produced from the menu
21717 item text. Called from term.c to display TTY drop-down menus one
21718 item at a time.
21720 ITEM_TEXT is the menu item text as a C string.
21722 FACE_ID is the face ID to be used for this menu item. FACE_ID
21723 could specify one of 3 faces: a face for an enabled item, a face
21724 for a disabled item, or a face for a selected item.
21726 X and Y are coordinates of the first glyph in the frame's desired
21727 matrix to be overwritten by the menu item. Since this is a TTY, Y
21728 is the zero-based number of the glyph row and X is the zero-based
21729 glyph number in the row, starting from left, where to start
21730 displaying the item.
21732 SUBMENU non-zero means this menu item drops down a submenu, which
21733 should be indicated by displaying a proper visual cue after the
21734 item text. */
21736 void
21737 display_tty_menu_item (const char *item_text, int width, int face_id,
21738 int x, int y, int submenu)
21740 struct it it;
21741 struct frame *f = SELECTED_FRAME ();
21742 struct window *w = XWINDOW (f->selected_window);
21743 int saved_used, saved_truncated, saved_width, saved_reversed;
21744 struct glyph_row *row;
21745 size_t item_len = strlen (item_text);
21747 eassert (FRAME_TERMCAP_P (f));
21749 /* Don't write beyond the matrix's last row. This can happen for
21750 TTY screens that are not high enough to show the entire menu.
21751 (This is actually a bit of defensive programming, as
21752 tty_menu_display already limits the number of menu items to one
21753 less than the number of screen lines.) */
21754 if (y >= f->desired_matrix->nrows)
21755 return;
21757 init_iterator (&it, w, -1, -1, f->desired_matrix->rows + y, MENU_FACE_ID);
21758 it.first_visible_x = 0;
21759 it.last_visible_x = FRAME_COLS (f) - 1;
21760 row = it.glyph_row;
21761 /* Start with the row contents from the current matrix. */
21762 deep_copy_glyph_row (row, f->current_matrix->rows + y);
21763 saved_width = row->full_width_p;
21764 row->full_width_p = 1;
21765 saved_reversed = row->reversed_p;
21766 row->reversed_p = 0;
21767 row->enabled_p = true;
21769 /* Arrange for the menu item glyphs to start at (X,Y) and have the
21770 desired face. */
21771 eassert (x < f->desired_matrix->matrix_w);
21772 it.current_x = it.hpos = x;
21773 it.current_y = it.vpos = y;
21774 saved_used = row->used[TEXT_AREA];
21775 saved_truncated = row->truncated_on_right_p;
21776 row->used[TEXT_AREA] = x;
21777 it.face_id = face_id;
21778 it.line_wrap = TRUNCATE;
21780 /* FIXME: This should be controlled by a user option. See the
21781 comments in redisplay_tool_bar and display_mode_line about this.
21782 Also, if paragraph_embedding could ever be R2L, changes will be
21783 needed to avoid shifting to the right the row characters in
21784 term.c:append_glyph. */
21785 it.paragraph_embedding = L2R;
21787 /* Pad with a space on the left. */
21788 display_string (" ", Qnil, Qnil, 0, 0, &it, 1, 0, FRAME_COLS (f) - 1, -1);
21789 width--;
21790 /* Display the menu item, pad with spaces to WIDTH. */
21791 if (submenu)
21793 display_string (item_text, Qnil, Qnil, 0, 0, &it,
21794 item_len, 0, FRAME_COLS (f) - 1, -1);
21795 width -= item_len;
21796 /* Indicate with " >" that there's a submenu. */
21797 display_string (" >", Qnil, Qnil, 0, 0, &it, width, 0,
21798 FRAME_COLS (f) - 1, -1);
21800 else
21801 display_string (item_text, Qnil, Qnil, 0, 0, &it,
21802 width, 0, FRAME_COLS (f) - 1, -1);
21804 row->used[TEXT_AREA] = max (saved_used, row->used[TEXT_AREA]);
21805 row->truncated_on_right_p = saved_truncated;
21806 row->hash = row_hash (row);
21807 row->full_width_p = saved_width;
21808 row->reversed_p = saved_reversed;
21811 /***********************************************************************
21812 Mode Line
21813 ***********************************************************************/
21815 /* Redisplay mode lines in the window tree whose root is WINDOW. If
21816 FORCE is non-zero, redisplay mode lines unconditionally.
21817 Otherwise, redisplay only mode lines that are garbaged. Value is
21818 the number of windows whose mode lines were redisplayed. */
21820 static int
21821 redisplay_mode_lines (Lisp_Object window, bool force)
21823 int nwindows = 0;
21825 while (!NILP (window))
21827 struct window *w = XWINDOW (window);
21829 if (WINDOWP (w->contents))
21830 nwindows += redisplay_mode_lines (w->contents, force);
21831 else if (force
21832 || FRAME_GARBAGED_P (XFRAME (w->frame))
21833 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
21835 struct text_pos lpoint;
21836 struct buffer *old = current_buffer;
21838 /* Set the window's buffer for the mode line display. */
21839 SET_TEXT_POS (lpoint, PT, PT_BYTE);
21840 set_buffer_internal_1 (XBUFFER (w->contents));
21842 /* Point refers normally to the selected window. For any
21843 other window, set up appropriate value. */
21844 if (!EQ (window, selected_window))
21846 struct text_pos pt;
21848 CLIP_TEXT_POS_FROM_MARKER (pt, w->pointm);
21849 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
21852 /* Display mode lines. */
21853 clear_glyph_matrix (w->desired_matrix);
21854 if (display_mode_lines (w))
21855 ++nwindows;
21857 /* Restore old settings. */
21858 set_buffer_internal_1 (old);
21859 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
21862 window = w->next;
21865 return nwindows;
21869 /* Display the mode and/or header line of window W. Value is the
21870 sum number of mode lines and header lines displayed. */
21872 static int
21873 display_mode_lines (struct window *w)
21875 Lisp_Object old_selected_window = selected_window;
21876 Lisp_Object old_selected_frame = selected_frame;
21877 Lisp_Object new_frame = w->frame;
21878 Lisp_Object old_frame_selected_window = XFRAME (new_frame)->selected_window;
21879 int n = 0;
21881 selected_frame = new_frame;
21882 /* FIXME: If we were to allow the mode-line's computation changing the buffer
21883 or window's point, then we'd need select_window_1 here as well. */
21884 XSETWINDOW (selected_window, w);
21885 XFRAME (new_frame)->selected_window = selected_window;
21887 /* These will be set while the mode line specs are processed. */
21888 line_number_displayed = 0;
21889 w->column_number_displayed = -1;
21891 if (WINDOW_WANTS_MODELINE_P (w))
21893 struct window *sel_w = XWINDOW (old_selected_window);
21895 /* Select mode line face based on the real selected window. */
21896 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
21897 BVAR (current_buffer, mode_line_format));
21898 ++n;
21901 if (WINDOW_WANTS_HEADER_LINE_P (w))
21903 display_mode_line (w, HEADER_LINE_FACE_ID,
21904 BVAR (current_buffer, header_line_format));
21905 ++n;
21908 XFRAME (new_frame)->selected_window = old_frame_selected_window;
21909 selected_frame = old_selected_frame;
21910 selected_window = old_selected_window;
21911 if (n > 0)
21912 w->must_be_updated_p = true;
21913 return n;
21917 /* Display mode or header line of window W. FACE_ID specifies which
21918 line to display; it is either MODE_LINE_FACE_ID or
21919 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
21920 display. Value is the pixel height of the mode/header line
21921 displayed. */
21923 static int
21924 display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
21926 struct it it;
21927 struct face *face;
21928 ptrdiff_t count = SPECPDL_INDEX ();
21930 init_iterator (&it, w, -1, -1, NULL, face_id);
21931 /* Don't extend on a previously drawn mode-line.
21932 This may happen if called from pos_visible_p. */
21933 it.glyph_row->enabled_p = false;
21934 prepare_desired_row (w, it.glyph_row, true);
21936 it.glyph_row->mode_line_p = 1;
21938 /* FIXME: This should be controlled by a user option. But
21939 supporting such an option is not trivial, since the mode line is
21940 made up of many separate strings. */
21941 it.paragraph_embedding = L2R;
21943 record_unwind_protect (unwind_format_mode_line,
21944 format_mode_line_unwind_data (NULL, NULL, Qnil, 0));
21946 mode_line_target = MODE_LINE_DISPLAY;
21948 /* Temporarily make frame's keyboard the current kboard so that
21949 kboard-local variables in the mode_line_format will get the right
21950 values. */
21951 push_kboard (FRAME_KBOARD (it.f));
21952 record_unwind_save_match_data ();
21953 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
21954 pop_kboard ();
21956 unbind_to (count, Qnil);
21958 /* Fill up with spaces. */
21959 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
21961 compute_line_metrics (&it);
21962 it.glyph_row->full_width_p = 1;
21963 it.glyph_row->continued_p = 0;
21964 it.glyph_row->truncated_on_left_p = 0;
21965 it.glyph_row->truncated_on_right_p = 0;
21967 /* Make a 3D mode-line have a shadow at its right end. */
21968 face = FACE_FROM_ID (it.f, face_id);
21969 extend_face_to_end_of_line (&it);
21970 if (face->box != FACE_NO_BOX)
21972 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
21973 + it.glyph_row->used[TEXT_AREA] - 1);
21974 last->right_box_line_p = 1;
21977 return it.glyph_row->height;
21980 /* Move element ELT in LIST to the front of LIST.
21981 Return the updated list. */
21983 static Lisp_Object
21984 move_elt_to_front (Lisp_Object elt, Lisp_Object list)
21986 register Lisp_Object tail, prev;
21987 register Lisp_Object tem;
21989 tail = list;
21990 prev = Qnil;
21991 while (CONSP (tail))
21993 tem = XCAR (tail);
21995 if (EQ (elt, tem))
21997 /* Splice out the link TAIL. */
21998 if (NILP (prev))
21999 list = XCDR (tail);
22000 else
22001 Fsetcdr (prev, XCDR (tail));
22003 /* Now make it the first. */
22004 Fsetcdr (tail, list);
22005 return tail;
22007 else
22008 prev = tail;
22009 tail = XCDR (tail);
22010 QUIT;
22013 /* Not found--return unchanged LIST. */
22014 return list;
22017 /* Contribute ELT to the mode line for window IT->w. How it
22018 translates into text depends on its data type.
22020 IT describes the display environment in which we display, as usual.
22022 DEPTH is the depth in recursion. It is used to prevent
22023 infinite recursion here.
22025 FIELD_WIDTH is the number of characters the display of ELT should
22026 occupy in the mode line, and PRECISION is the maximum number of
22027 characters to display from ELT's representation. See
22028 display_string for details.
22030 Returns the hpos of the end of the text generated by ELT.
22032 PROPS is a property list to add to any string we encounter.
22034 If RISKY is nonzero, remove (disregard) any properties in any string
22035 we encounter, and ignore :eval and :propertize.
22037 The global variable `mode_line_target' determines whether the
22038 output is passed to `store_mode_line_noprop',
22039 `store_mode_line_string', or `display_string'. */
22041 static int
22042 display_mode_element (struct it *it, int depth, int field_width, int precision,
22043 Lisp_Object elt, Lisp_Object props, int risky)
22045 int n = 0, field, prec;
22046 int literal = 0;
22048 tail_recurse:
22049 if (depth > 100)
22050 elt = build_string ("*too-deep*");
22052 depth++;
22054 switch (XTYPE (elt))
22056 case Lisp_String:
22058 /* A string: output it and check for %-constructs within it. */
22059 unsigned char c;
22060 ptrdiff_t offset = 0;
22062 if (SCHARS (elt) > 0
22063 && (!NILP (props) || risky))
22065 Lisp_Object oprops, aelt;
22066 oprops = Ftext_properties_at (make_number (0), elt);
22068 /* If the starting string's properties are not what
22069 we want, translate the string. Also, if the string
22070 is risky, do that anyway. */
22072 if (NILP (Fequal (props, oprops)) || risky)
22074 /* If the starting string has properties,
22075 merge the specified ones onto the existing ones. */
22076 if (! NILP (oprops) && !risky)
22078 Lisp_Object tem;
22080 oprops = Fcopy_sequence (oprops);
22081 tem = props;
22082 while (CONSP (tem))
22084 oprops = Fplist_put (oprops, XCAR (tem),
22085 XCAR (XCDR (tem)));
22086 tem = XCDR (XCDR (tem));
22088 props = oprops;
22091 aelt = Fassoc (elt, mode_line_proptrans_alist);
22092 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
22094 /* AELT is what we want. Move it to the front
22095 without consing. */
22096 elt = XCAR (aelt);
22097 mode_line_proptrans_alist
22098 = move_elt_to_front (aelt, mode_line_proptrans_alist);
22100 else
22102 Lisp_Object tem;
22104 /* If AELT has the wrong props, it is useless.
22105 so get rid of it. */
22106 if (! NILP (aelt))
22107 mode_line_proptrans_alist
22108 = Fdelq (aelt, mode_line_proptrans_alist);
22110 elt = Fcopy_sequence (elt);
22111 Fset_text_properties (make_number (0), Flength (elt),
22112 props, elt);
22113 /* Add this item to mode_line_proptrans_alist. */
22114 mode_line_proptrans_alist
22115 = Fcons (Fcons (elt, props),
22116 mode_line_proptrans_alist);
22117 /* Truncate mode_line_proptrans_alist
22118 to at most 50 elements. */
22119 tem = Fnthcdr (make_number (50),
22120 mode_line_proptrans_alist);
22121 if (! NILP (tem))
22122 XSETCDR (tem, Qnil);
22127 offset = 0;
22129 if (literal)
22131 prec = precision - n;
22132 switch (mode_line_target)
22134 case MODE_LINE_NOPROP:
22135 case MODE_LINE_TITLE:
22136 n += store_mode_line_noprop (SSDATA (elt), -1, prec);
22137 break;
22138 case MODE_LINE_STRING:
22139 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
22140 break;
22141 case MODE_LINE_DISPLAY:
22142 n += display_string (NULL, elt, Qnil, 0, 0, it,
22143 0, prec, 0, STRING_MULTIBYTE (elt));
22144 break;
22147 break;
22150 /* Handle the non-literal case. */
22152 while ((precision <= 0 || n < precision)
22153 && SREF (elt, offset) != 0
22154 && (mode_line_target != MODE_LINE_DISPLAY
22155 || it->current_x < it->last_visible_x))
22157 ptrdiff_t last_offset = offset;
22159 /* Advance to end of string or next format specifier. */
22160 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
22163 if (offset - 1 != last_offset)
22165 ptrdiff_t nchars, nbytes;
22167 /* Output to end of string or up to '%'. Field width
22168 is length of string. Don't output more than
22169 PRECISION allows us. */
22170 offset--;
22172 prec = c_string_width (SDATA (elt) + last_offset,
22173 offset - last_offset, precision - n,
22174 &nchars, &nbytes);
22176 switch (mode_line_target)
22178 case MODE_LINE_NOPROP:
22179 case MODE_LINE_TITLE:
22180 n += store_mode_line_noprop (SSDATA (elt) + last_offset, 0, prec);
22181 break;
22182 case MODE_LINE_STRING:
22184 ptrdiff_t bytepos = last_offset;
22185 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
22186 ptrdiff_t endpos = (precision <= 0
22187 ? string_byte_to_char (elt, offset)
22188 : charpos + nchars);
22190 n += store_mode_line_string (NULL,
22191 Fsubstring (elt, make_number (charpos),
22192 make_number (endpos)),
22193 0, 0, 0, Qnil);
22195 break;
22196 case MODE_LINE_DISPLAY:
22198 ptrdiff_t bytepos = last_offset;
22199 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
22201 if (precision <= 0)
22202 nchars = string_byte_to_char (elt, offset) - charpos;
22203 n += display_string (NULL, elt, Qnil, 0, charpos,
22204 it, 0, nchars, 0,
22205 STRING_MULTIBYTE (elt));
22207 break;
22210 else /* c == '%' */
22212 ptrdiff_t percent_position = offset;
22214 /* Get the specified minimum width. Zero means
22215 don't pad. */
22216 field = 0;
22217 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
22218 field = field * 10 + c - '0';
22220 /* Don't pad beyond the total padding allowed. */
22221 if (field_width - n > 0 && field > field_width - n)
22222 field = field_width - n;
22224 /* Note that either PRECISION <= 0 or N < PRECISION. */
22225 prec = precision - n;
22227 if (c == 'M')
22228 n += display_mode_element (it, depth, field, prec,
22229 Vglobal_mode_string, props,
22230 risky);
22231 else if (c != 0)
22233 bool multibyte;
22234 ptrdiff_t bytepos, charpos;
22235 const char *spec;
22236 Lisp_Object string;
22238 bytepos = percent_position;
22239 charpos = (STRING_MULTIBYTE (elt)
22240 ? string_byte_to_char (elt, bytepos)
22241 : bytepos);
22242 spec = decode_mode_spec (it->w, c, field, &string);
22243 multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
22245 switch (mode_line_target)
22247 case MODE_LINE_NOPROP:
22248 case MODE_LINE_TITLE:
22249 n += store_mode_line_noprop (spec, field, prec);
22250 break;
22251 case MODE_LINE_STRING:
22253 Lisp_Object tem = build_string (spec);
22254 props = Ftext_properties_at (make_number (charpos), elt);
22255 /* Should only keep face property in props */
22256 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
22258 break;
22259 case MODE_LINE_DISPLAY:
22261 int nglyphs_before, nwritten;
22263 nglyphs_before = it->glyph_row->used[TEXT_AREA];
22264 nwritten = display_string (spec, string, elt,
22265 charpos, 0, it,
22266 field, prec, 0,
22267 multibyte);
22269 /* Assign to the glyphs written above the
22270 string where the `%x' came from, position
22271 of the `%'. */
22272 if (nwritten > 0)
22274 struct glyph *glyph
22275 = (it->glyph_row->glyphs[TEXT_AREA]
22276 + nglyphs_before);
22277 int i;
22279 for (i = 0; i < nwritten; ++i)
22281 glyph[i].object = elt;
22282 glyph[i].charpos = charpos;
22285 n += nwritten;
22288 break;
22291 else /* c == 0 */
22292 break;
22296 break;
22298 case Lisp_Symbol:
22299 /* A symbol: process the value of the symbol recursively
22300 as if it appeared here directly. Avoid error if symbol void.
22301 Special case: if value of symbol is a string, output the string
22302 literally. */
22304 register Lisp_Object tem;
22306 /* If the variable is not marked as risky to set
22307 then its contents are risky to use. */
22308 if (NILP (Fget (elt, Qrisky_local_variable)))
22309 risky = 1;
22311 tem = Fboundp (elt);
22312 if (!NILP (tem))
22314 tem = Fsymbol_value (elt);
22315 /* If value is a string, output that string literally:
22316 don't check for % within it. */
22317 if (STRINGP (tem))
22318 literal = 1;
22320 if (!EQ (tem, elt))
22322 /* Give up right away for nil or t. */
22323 elt = tem;
22324 goto tail_recurse;
22328 break;
22330 case Lisp_Cons:
22332 register Lisp_Object car, tem;
22334 /* A cons cell: five distinct cases.
22335 If first element is :eval or :propertize, do something special.
22336 If first element is a string or a cons, process all the elements
22337 and effectively concatenate them.
22338 If first element is a negative number, truncate displaying cdr to
22339 at most that many characters. If positive, pad (with spaces)
22340 to at least that many characters.
22341 If first element is a symbol, process the cadr or caddr recursively
22342 according to whether the symbol's value is non-nil or nil. */
22343 car = XCAR (elt);
22344 if (EQ (car, QCeval))
22346 /* An element of the form (:eval FORM) means evaluate FORM
22347 and use the result as mode line elements. */
22349 if (risky)
22350 break;
22352 if (CONSP (XCDR (elt)))
22354 Lisp_Object spec;
22355 spec = safe__eval (true, XCAR (XCDR (elt)));
22356 n += display_mode_element (it, depth, field_width - n,
22357 precision - n, spec, props,
22358 risky);
22361 else if (EQ (car, QCpropertize))
22363 /* An element of the form (:propertize ELT PROPS...)
22364 means display ELT but applying properties PROPS. */
22366 if (risky)
22367 break;
22369 if (CONSP (XCDR (elt)))
22370 n += display_mode_element (it, depth, field_width - n,
22371 precision - n, XCAR (XCDR (elt)),
22372 XCDR (XCDR (elt)), risky);
22374 else if (SYMBOLP (car))
22376 tem = Fboundp (car);
22377 elt = XCDR (elt);
22378 if (!CONSP (elt))
22379 goto invalid;
22380 /* elt is now the cdr, and we know it is a cons cell.
22381 Use its car if CAR has a non-nil value. */
22382 if (!NILP (tem))
22384 tem = Fsymbol_value (car);
22385 if (!NILP (tem))
22387 elt = XCAR (elt);
22388 goto tail_recurse;
22391 /* Symbol's value is nil (or symbol is unbound)
22392 Get the cddr of the original list
22393 and if possible find the caddr and use that. */
22394 elt = XCDR (elt);
22395 if (NILP (elt))
22396 break;
22397 else if (!CONSP (elt))
22398 goto invalid;
22399 elt = XCAR (elt);
22400 goto tail_recurse;
22402 else if (INTEGERP (car))
22404 register int lim = XINT (car);
22405 elt = XCDR (elt);
22406 if (lim < 0)
22408 /* Negative int means reduce maximum width. */
22409 if (precision <= 0)
22410 precision = -lim;
22411 else
22412 precision = min (precision, -lim);
22414 else if (lim > 0)
22416 /* Padding specified. Don't let it be more than
22417 current maximum. */
22418 if (precision > 0)
22419 lim = min (precision, lim);
22421 /* If that's more padding than already wanted, queue it.
22422 But don't reduce padding already specified even if
22423 that is beyond the current truncation point. */
22424 field_width = max (lim, field_width);
22426 goto tail_recurse;
22428 else if (STRINGP (car) || CONSP (car))
22430 Lisp_Object halftail = elt;
22431 int len = 0;
22433 while (CONSP (elt)
22434 && (precision <= 0 || n < precision))
22436 n += display_mode_element (it, depth,
22437 /* Do padding only after the last
22438 element in the list. */
22439 (! CONSP (XCDR (elt))
22440 ? field_width - n
22441 : 0),
22442 precision - n, XCAR (elt),
22443 props, risky);
22444 elt = XCDR (elt);
22445 len++;
22446 if ((len & 1) == 0)
22447 halftail = XCDR (halftail);
22448 /* Check for cycle. */
22449 if (EQ (halftail, elt))
22450 break;
22454 break;
22456 default:
22457 invalid:
22458 elt = build_string ("*invalid*");
22459 goto tail_recurse;
22462 /* Pad to FIELD_WIDTH. */
22463 if (field_width > 0 && n < field_width)
22465 switch (mode_line_target)
22467 case MODE_LINE_NOPROP:
22468 case MODE_LINE_TITLE:
22469 n += store_mode_line_noprop ("", field_width - n, 0);
22470 break;
22471 case MODE_LINE_STRING:
22472 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
22473 break;
22474 case MODE_LINE_DISPLAY:
22475 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
22476 0, 0, 0);
22477 break;
22481 return n;
22484 /* Store a mode-line string element in mode_line_string_list.
22486 If STRING is non-null, display that C string. Otherwise, the Lisp
22487 string LISP_STRING is displayed.
22489 FIELD_WIDTH is the minimum number of output glyphs to produce.
22490 If STRING has fewer characters than FIELD_WIDTH, pad to the right
22491 with spaces. FIELD_WIDTH <= 0 means don't pad.
22493 PRECISION is the maximum number of characters to output from
22494 STRING. PRECISION <= 0 means don't truncate the string.
22496 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
22497 properties to the string.
22499 PROPS are the properties to add to the string.
22500 The mode_line_string_face face property is always added to the string.
22503 static int
22504 store_mode_line_string (const char *string, Lisp_Object lisp_string, int copy_string,
22505 int field_width, int precision, Lisp_Object props)
22507 ptrdiff_t len;
22508 int n = 0;
22510 if (string != NULL)
22512 len = strlen (string);
22513 if (precision > 0 && len > precision)
22514 len = precision;
22515 lisp_string = make_string (string, len);
22516 if (NILP (props))
22517 props = mode_line_string_face_prop;
22518 else if (!NILP (mode_line_string_face))
22520 Lisp_Object face = Fplist_get (props, Qface);
22521 props = Fcopy_sequence (props);
22522 if (NILP (face))
22523 face = mode_line_string_face;
22524 else
22525 face = list2 (face, mode_line_string_face);
22526 props = Fplist_put (props, Qface, face);
22528 Fadd_text_properties (make_number (0), make_number (len),
22529 props, lisp_string);
22531 else
22533 len = XFASTINT (Flength (lisp_string));
22534 if (precision > 0 && len > precision)
22536 len = precision;
22537 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
22538 precision = -1;
22540 if (!NILP (mode_line_string_face))
22542 Lisp_Object face;
22543 if (NILP (props))
22544 props = Ftext_properties_at (make_number (0), lisp_string);
22545 face = Fplist_get (props, Qface);
22546 if (NILP (face))
22547 face = mode_line_string_face;
22548 else
22549 face = list2 (face, mode_line_string_face);
22550 props = list2 (Qface, face);
22551 if (copy_string)
22552 lisp_string = Fcopy_sequence (lisp_string);
22554 if (!NILP (props))
22555 Fadd_text_properties (make_number (0), make_number (len),
22556 props, lisp_string);
22559 if (len > 0)
22561 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
22562 n += len;
22565 if (field_width > len)
22567 field_width -= len;
22568 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
22569 if (!NILP (props))
22570 Fadd_text_properties (make_number (0), make_number (field_width),
22571 props, lisp_string);
22572 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
22573 n += field_width;
22576 return n;
22580 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
22581 1, 4, 0,
22582 doc: /* Format a string out of a mode line format specification.
22583 First arg FORMAT specifies the mode line format (see `mode-line-format'
22584 for details) to use.
22586 By default, the format is evaluated for the currently selected window.
22588 Optional second arg FACE specifies the face property to put on all
22589 characters for which no face is specified. The value nil means the
22590 default face. The value t means whatever face the window's mode line
22591 currently uses (either `mode-line' or `mode-line-inactive',
22592 depending on whether the window is the selected window or not).
22593 An integer value means the value string has no text
22594 properties.
22596 Optional third and fourth args WINDOW and BUFFER specify the window
22597 and buffer to use as the context for the formatting (defaults
22598 are the selected window and the WINDOW's buffer). */)
22599 (Lisp_Object format, Lisp_Object face,
22600 Lisp_Object window, Lisp_Object buffer)
22602 struct it it;
22603 int len;
22604 struct window *w;
22605 struct buffer *old_buffer = NULL;
22606 int face_id;
22607 int no_props = INTEGERP (face);
22608 ptrdiff_t count = SPECPDL_INDEX ();
22609 Lisp_Object str;
22610 int string_start = 0;
22612 w = decode_any_window (window);
22613 XSETWINDOW (window, w);
22615 if (NILP (buffer))
22616 buffer = w->contents;
22617 CHECK_BUFFER (buffer);
22619 /* Make formatting the modeline a non-op when noninteractive, otherwise
22620 there will be problems later caused by a partially initialized frame. */
22621 if (NILP (format) || noninteractive)
22622 return empty_unibyte_string;
22624 if (no_props)
22625 face = Qnil;
22627 face_id = (NILP (face) || EQ (face, Qdefault)) ? DEFAULT_FACE_ID
22628 : EQ (face, Qt) ? (EQ (window, selected_window)
22629 ? MODE_LINE_FACE_ID : MODE_LINE_INACTIVE_FACE_ID)
22630 : EQ (face, Qmode_line) ? MODE_LINE_FACE_ID
22631 : EQ (face, Qmode_line_inactive) ? MODE_LINE_INACTIVE_FACE_ID
22632 : EQ (face, Qheader_line) ? HEADER_LINE_FACE_ID
22633 : EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID
22634 : DEFAULT_FACE_ID;
22636 old_buffer = current_buffer;
22638 /* Save things including mode_line_proptrans_alist,
22639 and set that to nil so that we don't alter the outer value. */
22640 record_unwind_protect (unwind_format_mode_line,
22641 format_mode_line_unwind_data
22642 (XFRAME (WINDOW_FRAME (w)),
22643 old_buffer, selected_window, 1));
22644 mode_line_proptrans_alist = Qnil;
22646 Fselect_window (window, Qt);
22647 set_buffer_internal_1 (XBUFFER (buffer));
22649 init_iterator (&it, w, -1, -1, NULL, face_id);
22651 if (no_props)
22653 mode_line_target = MODE_LINE_NOPROP;
22654 mode_line_string_face_prop = Qnil;
22655 mode_line_string_list = Qnil;
22656 string_start = MODE_LINE_NOPROP_LEN (0);
22658 else
22660 mode_line_target = MODE_LINE_STRING;
22661 mode_line_string_list = Qnil;
22662 mode_line_string_face = face;
22663 mode_line_string_face_prop
22664 = NILP (face) ? Qnil : list2 (Qface, face);
22667 push_kboard (FRAME_KBOARD (it.f));
22668 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
22669 pop_kboard ();
22671 if (no_props)
22673 len = MODE_LINE_NOPROP_LEN (string_start);
22674 str = make_string (mode_line_noprop_buf + string_start, len);
22676 else
22678 mode_line_string_list = Fnreverse (mode_line_string_list);
22679 str = Fmapconcat (intern ("identity"), mode_line_string_list,
22680 empty_unibyte_string);
22683 unbind_to (count, Qnil);
22684 return str;
22687 /* Write a null-terminated, right justified decimal representation of
22688 the positive integer D to BUF using a minimal field width WIDTH. */
22690 static void
22691 pint2str (register char *buf, register int width, register ptrdiff_t d)
22693 register char *p = buf;
22695 if (d <= 0)
22696 *p++ = '0';
22697 else
22699 while (d > 0)
22701 *p++ = d % 10 + '0';
22702 d /= 10;
22706 for (width -= (int) (p - buf); width > 0; --width)
22707 *p++ = ' ';
22708 *p-- = '\0';
22709 while (p > buf)
22711 d = *buf;
22712 *buf++ = *p;
22713 *p-- = d;
22717 /* Write a null-terminated, right justified decimal and "human
22718 readable" representation of the nonnegative integer D to BUF using
22719 a minimal field width WIDTH. D should be smaller than 999.5e24. */
22721 static const char power_letter[] =
22723 0, /* no letter */
22724 'k', /* kilo */
22725 'M', /* mega */
22726 'G', /* giga */
22727 'T', /* tera */
22728 'P', /* peta */
22729 'E', /* exa */
22730 'Z', /* zetta */
22731 'Y' /* yotta */
22734 static void
22735 pint2hrstr (char *buf, int width, ptrdiff_t d)
22737 /* We aim to represent the nonnegative integer D as
22738 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
22739 ptrdiff_t quotient = d;
22740 int remainder = 0;
22741 /* -1 means: do not use TENTHS. */
22742 int tenths = -1;
22743 int exponent = 0;
22745 /* Length of QUOTIENT.TENTHS as a string. */
22746 int length;
22748 char * psuffix;
22749 char * p;
22751 if (quotient >= 1000)
22753 /* Scale to the appropriate EXPONENT. */
22756 remainder = quotient % 1000;
22757 quotient /= 1000;
22758 exponent++;
22760 while (quotient >= 1000);
22762 /* Round to nearest and decide whether to use TENTHS or not. */
22763 if (quotient <= 9)
22765 tenths = remainder / 100;
22766 if (remainder % 100 >= 50)
22768 if (tenths < 9)
22769 tenths++;
22770 else
22772 quotient++;
22773 if (quotient == 10)
22774 tenths = -1;
22775 else
22776 tenths = 0;
22780 else
22781 if (remainder >= 500)
22783 if (quotient < 999)
22784 quotient++;
22785 else
22787 quotient = 1;
22788 exponent++;
22789 tenths = 0;
22794 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
22795 if (tenths == -1 && quotient <= 99)
22796 if (quotient <= 9)
22797 length = 1;
22798 else
22799 length = 2;
22800 else
22801 length = 3;
22802 p = psuffix = buf + max (width, length);
22804 /* Print EXPONENT. */
22805 *psuffix++ = power_letter[exponent];
22806 *psuffix = '\0';
22808 /* Print TENTHS. */
22809 if (tenths >= 0)
22811 *--p = '0' + tenths;
22812 *--p = '.';
22815 /* Print QUOTIENT. */
22818 int digit = quotient % 10;
22819 *--p = '0' + digit;
22821 while ((quotient /= 10) != 0);
22823 /* Print leading spaces. */
22824 while (buf < p)
22825 *--p = ' ';
22828 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
22829 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
22830 type of CODING_SYSTEM. Return updated pointer into BUF. */
22832 static unsigned char invalid_eol_type[] = "(*invalid*)";
22834 static char *
22835 decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_flag)
22837 Lisp_Object val;
22838 bool multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
22839 const unsigned char *eol_str;
22840 int eol_str_len;
22841 /* The EOL conversion we are using. */
22842 Lisp_Object eoltype;
22844 val = CODING_SYSTEM_SPEC (coding_system);
22845 eoltype = Qnil;
22847 if (!VECTORP (val)) /* Not yet decided. */
22849 *buf++ = multibyte ? '-' : ' ';
22850 if (eol_flag)
22851 eoltype = eol_mnemonic_undecided;
22852 /* Don't mention EOL conversion if it isn't decided. */
22854 else
22856 Lisp_Object attrs;
22857 Lisp_Object eolvalue;
22859 attrs = AREF (val, 0);
22860 eolvalue = AREF (val, 2);
22862 *buf++ = multibyte
22863 ? XFASTINT (CODING_ATTR_MNEMONIC (attrs))
22864 : ' ';
22866 if (eol_flag)
22868 /* The EOL conversion that is normal on this system. */
22870 if (NILP (eolvalue)) /* Not yet decided. */
22871 eoltype = eol_mnemonic_undecided;
22872 else if (VECTORP (eolvalue)) /* Not yet decided. */
22873 eoltype = eol_mnemonic_undecided;
22874 else /* eolvalue is Qunix, Qdos, or Qmac. */
22875 eoltype = (EQ (eolvalue, Qunix)
22876 ? eol_mnemonic_unix
22877 : (EQ (eolvalue, Qdos) == 1
22878 ? eol_mnemonic_dos : eol_mnemonic_mac));
22882 if (eol_flag)
22884 /* Mention the EOL conversion if it is not the usual one. */
22885 if (STRINGP (eoltype))
22887 eol_str = SDATA (eoltype);
22888 eol_str_len = SBYTES (eoltype);
22890 else if (CHARACTERP (eoltype))
22892 int c = XFASTINT (eoltype);
22893 return buf + CHAR_STRING (c, (unsigned char *) buf);
22895 else
22897 eol_str = invalid_eol_type;
22898 eol_str_len = sizeof (invalid_eol_type) - 1;
22900 memcpy (buf, eol_str, eol_str_len);
22901 buf += eol_str_len;
22904 return buf;
22907 /* Return a string for the output of a mode line %-spec for window W,
22908 generated by character C. FIELD_WIDTH > 0 means pad the string
22909 returned with spaces to that value. Return a Lisp string in
22910 *STRING if the resulting string is taken from that Lisp string.
22912 Note we operate on the current buffer for most purposes. */
22914 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
22916 static const char *
22917 decode_mode_spec (struct window *w, register int c, int field_width,
22918 Lisp_Object *string)
22920 Lisp_Object obj;
22921 struct frame *f = XFRAME (WINDOW_FRAME (w));
22922 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
22923 /* We are going to use f->decode_mode_spec_buffer as the buffer to
22924 produce strings from numerical values, so limit preposterously
22925 large values of FIELD_WIDTH to avoid overrunning the buffer's
22926 end. The size of the buffer is enough for FRAME_MESSAGE_BUF_SIZE
22927 bytes plus the terminating null. */
22928 int width = min (field_width, FRAME_MESSAGE_BUF_SIZE (f));
22929 struct buffer *b = current_buffer;
22931 obj = Qnil;
22932 *string = Qnil;
22934 switch (c)
22936 case '*':
22937 if (!NILP (BVAR (b, read_only)))
22938 return "%";
22939 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
22940 return "*";
22941 return "-";
22943 case '+':
22944 /* This differs from %* only for a modified read-only buffer. */
22945 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
22946 return "*";
22947 if (!NILP (BVAR (b, read_only)))
22948 return "%";
22949 return "-";
22951 case '&':
22952 /* This differs from %* in ignoring read-only-ness. */
22953 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
22954 return "*";
22955 return "-";
22957 case '%':
22958 return "%";
22960 case '[':
22962 int i;
22963 char *p;
22965 if (command_loop_level > 5)
22966 return "[[[... ";
22967 p = decode_mode_spec_buf;
22968 for (i = 0; i < command_loop_level; i++)
22969 *p++ = '[';
22970 *p = 0;
22971 return decode_mode_spec_buf;
22974 case ']':
22976 int i;
22977 char *p;
22979 if (command_loop_level > 5)
22980 return " ...]]]";
22981 p = decode_mode_spec_buf;
22982 for (i = 0; i < command_loop_level; i++)
22983 *p++ = ']';
22984 *p = 0;
22985 return decode_mode_spec_buf;
22988 case '-':
22990 register int i;
22992 /* Let lots_of_dashes be a string of infinite length. */
22993 if (mode_line_target == MODE_LINE_NOPROP
22994 || mode_line_target == MODE_LINE_STRING)
22995 return "--";
22996 if (field_width <= 0
22997 || field_width > sizeof (lots_of_dashes))
22999 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
23000 decode_mode_spec_buf[i] = '-';
23001 decode_mode_spec_buf[i] = '\0';
23002 return decode_mode_spec_buf;
23004 else
23005 return lots_of_dashes;
23008 case 'b':
23009 obj = BVAR (b, name);
23010 break;
23012 case 'c':
23013 /* %c and %l are ignored in `frame-title-format'.
23014 (In redisplay_internal, the frame title is drawn _before_ the
23015 windows are updated, so the stuff which depends on actual
23016 window contents (such as %l) may fail to render properly, or
23017 even crash emacs.) */
23018 if (mode_line_target == MODE_LINE_TITLE)
23019 return "";
23020 else
23022 ptrdiff_t col = current_column ();
23023 w->column_number_displayed = col;
23024 pint2str (decode_mode_spec_buf, width, col);
23025 return decode_mode_spec_buf;
23028 case 'e':
23029 #if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
23031 if (NILP (Vmemory_full))
23032 return "";
23033 else
23034 return "!MEM FULL! ";
23036 #else
23037 return "";
23038 #endif
23040 case 'F':
23041 /* %F displays the frame name. */
23042 if (!NILP (f->title))
23043 return SSDATA (f->title);
23044 if (f->explicit_name || ! FRAME_WINDOW_P (f))
23045 return SSDATA (f->name);
23046 return "Emacs";
23048 case 'f':
23049 obj = BVAR (b, filename);
23050 break;
23052 case 'i':
23054 ptrdiff_t size = ZV - BEGV;
23055 pint2str (decode_mode_spec_buf, width, size);
23056 return decode_mode_spec_buf;
23059 case 'I':
23061 ptrdiff_t size = ZV - BEGV;
23062 pint2hrstr (decode_mode_spec_buf, width, size);
23063 return decode_mode_spec_buf;
23066 case 'l':
23068 ptrdiff_t startpos, startpos_byte, line, linepos, linepos_byte;
23069 ptrdiff_t topline, nlines, height;
23070 ptrdiff_t junk;
23072 /* %c and %l are ignored in `frame-title-format'. */
23073 if (mode_line_target == MODE_LINE_TITLE)
23074 return "";
23076 startpos = marker_position (w->start);
23077 startpos_byte = marker_byte_position (w->start);
23078 height = WINDOW_TOTAL_LINES (w);
23080 /* If we decided that this buffer isn't suitable for line numbers,
23081 don't forget that too fast. */
23082 if (w->base_line_pos == -1)
23083 goto no_value;
23085 /* If the buffer is very big, don't waste time. */
23086 if (INTEGERP (Vline_number_display_limit)
23087 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
23089 w->base_line_pos = 0;
23090 w->base_line_number = 0;
23091 goto no_value;
23094 if (w->base_line_number > 0
23095 && w->base_line_pos > 0
23096 && w->base_line_pos <= startpos)
23098 line = w->base_line_number;
23099 linepos = w->base_line_pos;
23100 linepos_byte = buf_charpos_to_bytepos (b, linepos);
23102 else
23104 line = 1;
23105 linepos = BUF_BEGV (b);
23106 linepos_byte = BUF_BEGV_BYTE (b);
23109 /* Count lines from base line to window start position. */
23110 nlines = display_count_lines (linepos_byte,
23111 startpos_byte,
23112 startpos, &junk);
23114 topline = nlines + line;
23116 /* Determine a new base line, if the old one is too close
23117 or too far away, or if we did not have one.
23118 "Too close" means it's plausible a scroll-down would
23119 go back past it. */
23120 if (startpos == BUF_BEGV (b))
23122 w->base_line_number = topline;
23123 w->base_line_pos = BUF_BEGV (b);
23125 else if (nlines < height + 25 || nlines > height * 3 + 50
23126 || linepos == BUF_BEGV (b))
23128 ptrdiff_t limit = BUF_BEGV (b);
23129 ptrdiff_t limit_byte = BUF_BEGV_BYTE (b);
23130 ptrdiff_t position;
23131 ptrdiff_t distance =
23132 (height * 2 + 30) * line_number_display_limit_width;
23134 if (startpos - distance > limit)
23136 limit = startpos - distance;
23137 limit_byte = CHAR_TO_BYTE (limit);
23140 nlines = display_count_lines (startpos_byte,
23141 limit_byte,
23142 - (height * 2 + 30),
23143 &position);
23144 /* If we couldn't find the lines we wanted within
23145 line_number_display_limit_width chars per line,
23146 give up on line numbers for this window. */
23147 if (position == limit_byte && limit == startpos - distance)
23149 w->base_line_pos = -1;
23150 w->base_line_number = 0;
23151 goto no_value;
23154 w->base_line_number = topline - nlines;
23155 w->base_line_pos = BYTE_TO_CHAR (position);
23158 /* Now count lines from the start pos to point. */
23159 nlines = display_count_lines (startpos_byte,
23160 PT_BYTE, PT, &junk);
23162 /* Record that we did display the line number. */
23163 line_number_displayed = 1;
23165 /* Make the string to show. */
23166 pint2str (decode_mode_spec_buf, width, topline + nlines);
23167 return decode_mode_spec_buf;
23168 no_value:
23170 char *p = decode_mode_spec_buf;
23171 int pad = width - 2;
23172 while (pad-- > 0)
23173 *p++ = ' ';
23174 *p++ = '?';
23175 *p++ = '?';
23176 *p = '\0';
23177 return decode_mode_spec_buf;
23180 break;
23182 case 'm':
23183 obj = BVAR (b, mode_name);
23184 break;
23186 case 'n':
23187 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
23188 return " Narrow";
23189 break;
23191 case 'p':
23193 ptrdiff_t pos = marker_position (w->start);
23194 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
23196 if (w->window_end_pos <= BUF_Z (b) - BUF_ZV (b))
23198 if (pos <= BUF_BEGV (b))
23199 return "All";
23200 else
23201 return "Bottom";
23203 else if (pos <= BUF_BEGV (b))
23204 return "Top";
23205 else
23207 if (total > 1000000)
23208 /* Do it differently for a large value, to avoid overflow. */
23209 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
23210 else
23211 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
23212 /* We can't normally display a 3-digit number,
23213 so get us a 2-digit number that is close. */
23214 if (total == 100)
23215 total = 99;
23216 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
23217 return decode_mode_spec_buf;
23221 /* Display percentage of size above the bottom of the screen. */
23222 case 'P':
23224 ptrdiff_t toppos = marker_position (w->start);
23225 ptrdiff_t botpos = BUF_Z (b) - w->window_end_pos;
23226 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
23228 if (botpos >= BUF_ZV (b))
23230 if (toppos <= BUF_BEGV (b))
23231 return "All";
23232 else
23233 return "Bottom";
23235 else
23237 if (total > 1000000)
23238 /* Do it differently for a large value, to avoid overflow. */
23239 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
23240 else
23241 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
23242 /* We can't normally display a 3-digit number,
23243 so get us a 2-digit number that is close. */
23244 if (total == 100)
23245 total = 99;
23246 if (toppos <= BUF_BEGV (b))
23247 sprintf (decode_mode_spec_buf, "Top%2"pD"d%%", total);
23248 else
23249 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
23250 return decode_mode_spec_buf;
23254 case 's':
23255 /* status of process */
23256 obj = Fget_buffer_process (Fcurrent_buffer ());
23257 if (NILP (obj))
23258 return "no process";
23259 #ifndef MSDOS
23260 obj = Fsymbol_name (Fprocess_status (obj));
23261 #endif
23262 break;
23264 case '@':
23266 ptrdiff_t count = inhibit_garbage_collection ();
23267 Lisp_Object curdir = BVAR (current_buffer, directory);
23268 Lisp_Object val = Qnil;
23270 if (STRINGP (curdir))
23271 val = call1 (intern ("file-remote-p"), curdir);
23273 unbind_to (count, Qnil);
23275 if (NILP (val))
23276 return "-";
23277 else
23278 return "@";
23281 case 'z':
23282 /* coding-system (not including end-of-line format) */
23283 case 'Z':
23284 /* coding-system (including end-of-line type) */
23286 int eol_flag = (c == 'Z');
23287 char *p = decode_mode_spec_buf;
23289 if (! FRAME_WINDOW_P (f))
23291 /* No need to mention EOL here--the terminal never needs
23292 to do EOL conversion. */
23293 p = decode_mode_spec_coding (CODING_ID_NAME
23294 (FRAME_KEYBOARD_CODING (f)->id),
23295 p, 0);
23296 p = decode_mode_spec_coding (CODING_ID_NAME
23297 (FRAME_TERMINAL_CODING (f)->id),
23298 p, 0);
23300 p = decode_mode_spec_coding (BVAR (b, buffer_file_coding_system),
23301 p, eol_flag);
23303 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
23304 #ifdef subprocesses
23305 obj = Fget_buffer_process (Fcurrent_buffer ());
23306 if (PROCESSP (obj))
23308 p = decode_mode_spec_coding
23309 (XPROCESS (obj)->decode_coding_system, p, eol_flag);
23310 p = decode_mode_spec_coding
23311 (XPROCESS (obj)->encode_coding_system, p, eol_flag);
23313 #endif /* subprocesses */
23314 #endif /* 0 */
23315 *p = 0;
23316 return decode_mode_spec_buf;
23320 if (STRINGP (obj))
23322 *string = obj;
23323 return SSDATA (obj);
23325 else
23326 return "";
23330 /* Count up to COUNT lines starting from START_BYTE. COUNT negative
23331 means count lines back from START_BYTE. But don't go beyond
23332 LIMIT_BYTE. Return the number of lines thus found (always
23333 nonnegative).
23335 Set *BYTE_POS_PTR to the byte position where we stopped. This is
23336 either the position COUNT lines after/before START_BYTE, if we
23337 found COUNT lines, or LIMIT_BYTE if we hit the limit before finding
23338 COUNT lines. */
23340 static ptrdiff_t
23341 display_count_lines (ptrdiff_t start_byte,
23342 ptrdiff_t limit_byte, ptrdiff_t count,
23343 ptrdiff_t *byte_pos_ptr)
23345 register unsigned char *cursor;
23346 unsigned char *base;
23348 register ptrdiff_t ceiling;
23349 register unsigned char *ceiling_addr;
23350 ptrdiff_t orig_count = count;
23352 /* If we are not in selective display mode,
23353 check only for newlines. */
23354 int selective_display = (!NILP (BVAR (current_buffer, selective_display))
23355 && !INTEGERP (BVAR (current_buffer, selective_display)));
23357 if (count > 0)
23359 while (start_byte < limit_byte)
23361 ceiling = BUFFER_CEILING_OF (start_byte);
23362 ceiling = min (limit_byte - 1, ceiling);
23363 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
23364 base = (cursor = BYTE_POS_ADDR (start_byte));
23368 if (selective_display)
23370 while (*cursor != '\n' && *cursor != 015
23371 && ++cursor != ceiling_addr)
23372 continue;
23373 if (cursor == ceiling_addr)
23374 break;
23376 else
23378 cursor = memchr (cursor, '\n', ceiling_addr - cursor);
23379 if (! cursor)
23380 break;
23383 cursor++;
23385 if (--count == 0)
23387 start_byte += cursor - base;
23388 *byte_pos_ptr = start_byte;
23389 return orig_count;
23392 while (cursor < ceiling_addr);
23394 start_byte += ceiling_addr - base;
23397 else
23399 while (start_byte > limit_byte)
23401 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
23402 ceiling = max (limit_byte, ceiling);
23403 ceiling_addr = BYTE_POS_ADDR (ceiling);
23404 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
23405 while (1)
23407 if (selective_display)
23409 while (--cursor >= ceiling_addr
23410 && *cursor != '\n' && *cursor != 015)
23411 continue;
23412 if (cursor < ceiling_addr)
23413 break;
23415 else
23417 cursor = memrchr (ceiling_addr, '\n', cursor - ceiling_addr);
23418 if (! cursor)
23419 break;
23422 if (++count == 0)
23424 start_byte += cursor - base + 1;
23425 *byte_pos_ptr = start_byte;
23426 /* When scanning backwards, we should
23427 not count the newline posterior to which we stop. */
23428 return - orig_count - 1;
23431 start_byte += ceiling_addr - base;
23435 *byte_pos_ptr = limit_byte;
23437 if (count < 0)
23438 return - orig_count + count;
23439 return orig_count - count;
23445 /***********************************************************************
23446 Displaying strings
23447 ***********************************************************************/
23449 /* Display a NUL-terminated string, starting with index START.
23451 If STRING is non-null, display that C string. Otherwise, the Lisp
23452 string LISP_STRING is displayed. There's a case that STRING is
23453 non-null and LISP_STRING is not nil. It means STRING is a string
23454 data of LISP_STRING. In that case, we display LISP_STRING while
23455 ignoring its text properties.
23457 If FACE_STRING is not nil, FACE_STRING_POS is a position in
23458 FACE_STRING. Display STRING or LISP_STRING with the face at
23459 FACE_STRING_POS in FACE_STRING:
23461 Display the string in the environment given by IT, but use the
23462 standard display table, temporarily.
23464 FIELD_WIDTH is the minimum number of output glyphs to produce.
23465 If STRING has fewer characters than FIELD_WIDTH, pad to the right
23466 with spaces. If STRING has more characters, more than FIELD_WIDTH
23467 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
23469 PRECISION is the maximum number of characters to output from
23470 STRING. PRECISION < 0 means don't truncate the string.
23472 This is roughly equivalent to printf format specifiers:
23474 FIELD_WIDTH PRECISION PRINTF
23475 ----------------------------------------
23476 -1 -1 %s
23477 -1 10 %.10s
23478 10 -1 %10s
23479 20 10 %20.10s
23481 MULTIBYTE zero means do not display multibyte chars, > 0 means do
23482 display them, and < 0 means obey the current buffer's value of
23483 enable_multibyte_characters.
23485 Value is the number of columns displayed. */
23487 static int
23488 display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_string,
23489 ptrdiff_t face_string_pos, ptrdiff_t start, struct it *it,
23490 int field_width, int precision, int max_x, int multibyte)
23492 int hpos_at_start = it->hpos;
23493 int saved_face_id = it->face_id;
23494 struct glyph_row *row = it->glyph_row;
23495 ptrdiff_t it_charpos;
23497 /* Initialize the iterator IT for iteration over STRING beginning
23498 with index START. */
23499 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
23500 precision, field_width, multibyte);
23501 if (string && STRINGP (lisp_string))
23502 /* LISP_STRING is the one returned by decode_mode_spec. We should
23503 ignore its text properties. */
23504 it->stop_charpos = it->end_charpos;
23506 /* If displaying STRING, set up the face of the iterator from
23507 FACE_STRING, if that's given. */
23508 if (STRINGP (face_string))
23510 ptrdiff_t endptr;
23511 struct face *face;
23513 it->face_id
23514 = face_at_string_position (it->w, face_string, face_string_pos,
23515 0, &endptr, it->base_face_id, 0);
23516 face = FACE_FROM_ID (it->f, it->face_id);
23517 it->face_box_p = face->box != FACE_NO_BOX;
23520 /* Set max_x to the maximum allowed X position. Don't let it go
23521 beyond the right edge of the window. */
23522 if (max_x <= 0)
23523 max_x = it->last_visible_x;
23524 else
23525 max_x = min (max_x, it->last_visible_x);
23527 /* Skip over display elements that are not visible. because IT->w is
23528 hscrolled. */
23529 if (it->current_x < it->first_visible_x)
23530 move_it_in_display_line_to (it, 100000, it->first_visible_x,
23531 MOVE_TO_POS | MOVE_TO_X);
23533 row->ascent = it->max_ascent;
23534 row->height = it->max_ascent + it->max_descent;
23535 row->phys_ascent = it->max_phys_ascent;
23536 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
23537 row->extra_line_spacing = it->max_extra_line_spacing;
23539 if (STRINGP (it->string))
23540 it_charpos = IT_STRING_CHARPOS (*it);
23541 else
23542 it_charpos = IT_CHARPOS (*it);
23544 /* This condition is for the case that we are called with current_x
23545 past last_visible_x. */
23546 while (it->current_x < max_x)
23548 int x_before, x, n_glyphs_before, i, nglyphs;
23550 /* Get the next display element. */
23551 if (!get_next_display_element (it))
23552 break;
23554 /* Produce glyphs. */
23555 x_before = it->current_x;
23556 n_glyphs_before = row->used[TEXT_AREA];
23557 PRODUCE_GLYPHS (it);
23559 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
23560 i = 0;
23561 x = x_before;
23562 while (i < nglyphs)
23564 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
23566 if (it->line_wrap != TRUNCATE
23567 && x + glyph->pixel_width > max_x)
23569 /* End of continued line or max_x reached. */
23570 if (CHAR_GLYPH_PADDING_P (*glyph))
23572 /* A wide character is unbreakable. */
23573 if (row->reversed_p)
23574 unproduce_glyphs (it, row->used[TEXT_AREA]
23575 - n_glyphs_before);
23576 row->used[TEXT_AREA] = n_glyphs_before;
23577 it->current_x = x_before;
23579 else
23581 if (row->reversed_p)
23582 unproduce_glyphs (it, row->used[TEXT_AREA]
23583 - (n_glyphs_before + i));
23584 row->used[TEXT_AREA] = n_glyphs_before + i;
23585 it->current_x = x;
23587 break;
23589 else if (x + glyph->pixel_width >= it->first_visible_x)
23591 /* Glyph is at least partially visible. */
23592 ++it->hpos;
23593 if (x < it->first_visible_x)
23594 row->x = x - it->first_visible_x;
23596 else
23598 /* Glyph is off the left margin of the display area.
23599 Should not happen. */
23600 emacs_abort ();
23603 row->ascent = max (row->ascent, it->max_ascent);
23604 row->height = max (row->height, it->max_ascent + it->max_descent);
23605 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
23606 row->phys_height = max (row->phys_height,
23607 it->max_phys_ascent + it->max_phys_descent);
23608 row->extra_line_spacing = max (row->extra_line_spacing,
23609 it->max_extra_line_spacing);
23610 x += glyph->pixel_width;
23611 ++i;
23614 /* Stop if max_x reached. */
23615 if (i < nglyphs)
23616 break;
23618 /* Stop at line ends. */
23619 if (ITERATOR_AT_END_OF_LINE_P (it))
23621 it->continuation_lines_width = 0;
23622 break;
23625 set_iterator_to_next (it, 1);
23626 if (STRINGP (it->string))
23627 it_charpos = IT_STRING_CHARPOS (*it);
23628 else
23629 it_charpos = IT_CHARPOS (*it);
23631 /* Stop if truncating at the right edge. */
23632 if (it->line_wrap == TRUNCATE
23633 && it->current_x >= it->last_visible_x)
23635 /* Add truncation mark, but don't do it if the line is
23636 truncated at a padding space. */
23637 if (it_charpos < it->string_nchars)
23639 if (!FRAME_WINDOW_P (it->f))
23641 int ii, n;
23643 if (it->current_x > it->last_visible_x)
23645 if (!row->reversed_p)
23647 for (ii = row->used[TEXT_AREA] - 1; ii > 0; --ii)
23648 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
23649 break;
23651 else
23653 for (ii = 0; ii < row->used[TEXT_AREA]; ii++)
23654 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
23655 break;
23656 unproduce_glyphs (it, ii + 1);
23657 ii = row->used[TEXT_AREA] - (ii + 1);
23659 for (n = row->used[TEXT_AREA]; ii < n; ++ii)
23661 row->used[TEXT_AREA] = ii;
23662 produce_special_glyphs (it, IT_TRUNCATION);
23665 produce_special_glyphs (it, IT_TRUNCATION);
23667 row->truncated_on_right_p = 1;
23669 break;
23673 /* Maybe insert a truncation at the left. */
23674 if (it->first_visible_x
23675 && it_charpos > 0)
23677 if (!FRAME_WINDOW_P (it->f)
23678 || (row->reversed_p
23679 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
23680 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
23681 insert_left_trunc_glyphs (it);
23682 row->truncated_on_left_p = 1;
23685 it->face_id = saved_face_id;
23687 /* Value is number of columns displayed. */
23688 return it->hpos - hpos_at_start;
23693 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
23694 appears as an element of LIST or as the car of an element of LIST.
23695 If PROPVAL is a list, compare each element against LIST in that
23696 way, and return 1/2 if any element of PROPVAL is found in LIST.
23697 Otherwise return 0. This function cannot quit.
23698 The return value is 2 if the text is invisible but with an ellipsis
23699 and 1 if it's invisible and without an ellipsis. */
23702 invisible_p (register Lisp_Object propval, Lisp_Object list)
23704 register Lisp_Object tail, proptail;
23706 for (tail = list; CONSP (tail); tail = XCDR (tail))
23708 register Lisp_Object tem;
23709 tem = XCAR (tail);
23710 if (EQ (propval, tem))
23711 return 1;
23712 if (CONSP (tem) && EQ (propval, XCAR (tem)))
23713 return NILP (XCDR (tem)) ? 1 : 2;
23716 if (CONSP (propval))
23718 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
23720 Lisp_Object propelt;
23721 propelt = XCAR (proptail);
23722 for (tail = list; CONSP (tail); tail = XCDR (tail))
23724 register Lisp_Object tem;
23725 tem = XCAR (tail);
23726 if (EQ (propelt, tem))
23727 return 1;
23728 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
23729 return NILP (XCDR (tem)) ? 1 : 2;
23734 return 0;
23737 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
23738 doc: /* Non-nil if the property makes the text invisible.
23739 POS-OR-PROP can be a marker or number, in which case it is taken to be
23740 a position in the current buffer and the value of the `invisible' property
23741 is checked; or it can be some other value, which is then presumed to be the
23742 value of the `invisible' property of the text of interest.
23743 The non-nil value returned can be t for truly invisible text or something
23744 else if the text is replaced by an ellipsis. */)
23745 (Lisp_Object pos_or_prop)
23747 Lisp_Object prop
23748 = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
23749 ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
23750 : pos_or_prop);
23751 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
23752 return (invis == 0 ? Qnil
23753 : invis == 1 ? Qt
23754 : make_number (invis));
23757 /* Calculate a width or height in pixels from a specification using
23758 the following elements:
23760 SPEC ::=
23761 NUM - a (fractional) multiple of the default font width/height
23762 (NUM) - specifies exactly NUM pixels
23763 UNIT - a fixed number of pixels, see below.
23764 ELEMENT - size of a display element in pixels, see below.
23765 (NUM . SPEC) - equals NUM * SPEC
23766 (+ SPEC SPEC ...) - add pixel values
23767 (- SPEC SPEC ...) - subtract pixel values
23768 (- SPEC) - negate pixel value
23770 NUM ::=
23771 INT or FLOAT - a number constant
23772 SYMBOL - use symbol's (buffer local) variable binding.
23774 UNIT ::=
23775 in - pixels per inch *)
23776 mm - pixels per 1/1000 meter *)
23777 cm - pixels per 1/100 meter *)
23778 width - width of current font in pixels.
23779 height - height of current font in pixels.
23781 *) using the ratio(s) defined in display-pixels-per-inch.
23783 ELEMENT ::=
23785 left-fringe - left fringe width in pixels
23786 right-fringe - right fringe width in pixels
23788 left-margin - left margin width in pixels
23789 right-margin - right margin width in pixels
23791 scroll-bar - scroll-bar area width in pixels
23793 Examples:
23795 Pixels corresponding to 5 inches:
23796 (5 . in)
23798 Total width of non-text areas on left side of window (if scroll-bar is on left):
23799 '(space :width (+ left-fringe left-margin scroll-bar))
23801 Align to first text column (in header line):
23802 '(space :align-to 0)
23804 Align to middle of text area minus half the width of variable `my-image'
23805 containing a loaded image:
23806 '(space :align-to (0.5 . (- text my-image)))
23808 Width of left margin minus width of 1 character in the default font:
23809 '(space :width (- left-margin 1))
23811 Width of left margin minus width of 2 characters in the current font:
23812 '(space :width (- left-margin (2 . width)))
23814 Center 1 character over left-margin (in header line):
23815 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
23817 Different ways to express width of left fringe plus left margin minus one pixel:
23818 '(space :width (- (+ left-fringe left-margin) (1)))
23819 '(space :width (+ left-fringe left-margin (- (1))))
23820 '(space :width (+ left-fringe left-margin (-1)))
23824 static int
23825 calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
23826 struct font *font, int width_p, int *align_to)
23828 double pixels;
23830 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
23831 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
23833 if (NILP (prop))
23834 return OK_PIXELS (0);
23836 eassert (FRAME_LIVE_P (it->f));
23838 if (SYMBOLP (prop))
23840 if (SCHARS (SYMBOL_NAME (prop)) == 2)
23842 char *unit = SSDATA (SYMBOL_NAME (prop));
23844 if (unit[0] == 'i' && unit[1] == 'n')
23845 pixels = 1.0;
23846 else if (unit[0] == 'm' && unit[1] == 'm')
23847 pixels = 25.4;
23848 else if (unit[0] == 'c' && unit[1] == 'm')
23849 pixels = 2.54;
23850 else
23851 pixels = 0;
23852 if (pixels > 0)
23854 double ppi = (width_p ? FRAME_RES_X (it->f)
23855 : FRAME_RES_Y (it->f));
23857 if (ppi > 0)
23858 return OK_PIXELS (ppi / pixels);
23859 return 0;
23863 #ifdef HAVE_WINDOW_SYSTEM
23864 if (EQ (prop, Qheight))
23865 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
23866 if (EQ (prop, Qwidth))
23867 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
23868 #else
23869 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
23870 return OK_PIXELS (1);
23871 #endif
23873 if (EQ (prop, Qtext))
23874 return OK_PIXELS (width_p
23875 ? window_box_width (it->w, TEXT_AREA)
23876 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
23878 if (align_to && *align_to < 0)
23880 *res = 0;
23881 if (EQ (prop, Qleft))
23882 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
23883 if (EQ (prop, Qright))
23884 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
23885 if (EQ (prop, Qcenter))
23886 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
23887 + window_box_width (it->w, TEXT_AREA) / 2);
23888 if (EQ (prop, Qleft_fringe))
23889 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
23890 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
23891 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
23892 if (EQ (prop, Qright_fringe))
23893 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
23894 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
23895 : window_box_right_offset (it->w, TEXT_AREA));
23896 if (EQ (prop, Qleft_margin))
23897 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
23898 if (EQ (prop, Qright_margin))
23899 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
23900 if (EQ (prop, Qscroll_bar))
23901 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
23903 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
23904 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
23905 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
23906 : 0)));
23908 else
23910 if (EQ (prop, Qleft_fringe))
23911 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
23912 if (EQ (prop, Qright_fringe))
23913 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
23914 if (EQ (prop, Qleft_margin))
23915 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
23916 if (EQ (prop, Qright_margin))
23917 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
23918 if (EQ (prop, Qscroll_bar))
23919 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
23922 prop = buffer_local_value (prop, it->w->contents);
23923 if (EQ (prop, Qunbound))
23924 prop = Qnil;
23927 if (INTEGERP (prop) || FLOATP (prop))
23929 int base_unit = (width_p
23930 ? FRAME_COLUMN_WIDTH (it->f)
23931 : FRAME_LINE_HEIGHT (it->f));
23932 return OK_PIXELS (XFLOATINT (prop) * base_unit);
23935 if (CONSP (prop))
23937 Lisp_Object car = XCAR (prop);
23938 Lisp_Object cdr = XCDR (prop);
23940 if (SYMBOLP (car))
23942 #ifdef HAVE_WINDOW_SYSTEM
23943 if (FRAME_WINDOW_P (it->f)
23944 && valid_image_p (prop))
23946 ptrdiff_t id = lookup_image (it->f, prop);
23947 struct image *img = IMAGE_FROM_ID (it->f, id);
23949 return OK_PIXELS (width_p ? img->width : img->height);
23951 #endif
23952 if (EQ (car, Qplus) || EQ (car, Qminus))
23954 int first = 1;
23955 double px;
23957 pixels = 0;
23958 while (CONSP (cdr))
23960 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
23961 font, width_p, align_to))
23962 return 0;
23963 if (first)
23964 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
23965 else
23966 pixels += px;
23967 cdr = XCDR (cdr);
23969 if (EQ (car, Qminus))
23970 pixels = -pixels;
23971 return OK_PIXELS (pixels);
23974 car = buffer_local_value (car, it->w->contents);
23975 if (EQ (car, Qunbound))
23976 car = Qnil;
23979 if (INTEGERP (car) || FLOATP (car))
23981 double fact;
23982 pixels = XFLOATINT (car);
23983 if (NILP (cdr))
23984 return OK_PIXELS (pixels);
23985 if (calc_pixel_width_or_height (&fact, it, cdr,
23986 font, width_p, align_to))
23987 return OK_PIXELS (pixels * fact);
23988 return 0;
23991 return 0;
23994 return 0;
23998 /***********************************************************************
23999 Glyph Display
24000 ***********************************************************************/
24002 #ifdef HAVE_WINDOW_SYSTEM
24004 #ifdef GLYPH_DEBUG
24006 void
24007 dump_glyph_string (struct glyph_string *s)
24009 fprintf (stderr, "glyph string\n");
24010 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
24011 s->x, s->y, s->width, s->height);
24012 fprintf (stderr, " ybase = %d\n", s->ybase);
24013 fprintf (stderr, " hl = %d\n", s->hl);
24014 fprintf (stderr, " left overhang = %d, right = %d\n",
24015 s->left_overhang, s->right_overhang);
24016 fprintf (stderr, " nchars = %d\n", s->nchars);
24017 fprintf (stderr, " extends to end of line = %d\n",
24018 s->extends_to_end_of_line_p);
24019 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
24020 fprintf (stderr, " bg width = %d\n", s->background_width);
24023 #endif /* GLYPH_DEBUG */
24025 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
24026 of XChar2b structures for S; it can't be allocated in
24027 init_glyph_string because it must be allocated via `alloca'. W
24028 is the window on which S is drawn. ROW and AREA are the glyph row
24029 and area within the row from which S is constructed. START is the
24030 index of the first glyph structure covered by S. HL is a
24031 face-override for drawing S. */
24033 #ifdef HAVE_NTGUI
24034 #define OPTIONAL_HDC(hdc) HDC hdc,
24035 #define DECLARE_HDC(hdc) HDC hdc;
24036 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
24037 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
24038 #endif
24040 #ifndef OPTIONAL_HDC
24041 #define OPTIONAL_HDC(hdc)
24042 #define DECLARE_HDC(hdc)
24043 #define ALLOCATE_HDC(hdc, f)
24044 #define RELEASE_HDC(hdc, f)
24045 #endif
24047 static void
24048 init_glyph_string (struct glyph_string *s,
24049 OPTIONAL_HDC (hdc)
24050 XChar2b *char2b, struct window *w, struct glyph_row *row,
24051 enum glyph_row_area area, int start, enum draw_glyphs_face hl)
24053 memset (s, 0, sizeof *s);
24054 s->w = w;
24055 s->f = XFRAME (w->frame);
24056 #ifdef HAVE_NTGUI
24057 s->hdc = hdc;
24058 #endif
24059 s->display = FRAME_X_DISPLAY (s->f);
24060 s->window = FRAME_X_WINDOW (s->f);
24061 s->char2b = char2b;
24062 s->hl = hl;
24063 s->row = row;
24064 s->area = area;
24065 s->first_glyph = row->glyphs[area] + start;
24066 s->height = row->height;
24067 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
24068 s->ybase = s->y + row->ascent;
24072 /* Append the list of glyph strings with head H and tail T to the list
24073 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
24075 static void
24076 append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
24077 struct glyph_string *h, struct glyph_string *t)
24079 if (h)
24081 if (*head)
24082 (*tail)->next = h;
24083 else
24084 *head = h;
24085 h->prev = *tail;
24086 *tail = t;
24091 /* Prepend the list of glyph strings with head H and tail T to the
24092 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
24093 result. */
24095 static void
24096 prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
24097 struct glyph_string *h, struct glyph_string *t)
24099 if (h)
24101 if (*head)
24102 (*head)->prev = t;
24103 else
24104 *tail = t;
24105 t->next = *head;
24106 *head = h;
24111 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
24112 Set *HEAD and *TAIL to the resulting list. */
24114 static void
24115 append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
24116 struct glyph_string *s)
24118 s->next = s->prev = NULL;
24119 append_glyph_string_lists (head, tail, s, s);
24123 /* Get face and two-byte form of character C in face FACE_ID on frame F.
24124 The encoding of C is returned in *CHAR2B. DISPLAY_P non-zero means
24125 make sure that X resources for the face returned are allocated.
24126 Value is a pointer to a realized face that is ready for display if
24127 DISPLAY_P is non-zero. */
24129 static struct face *
24130 get_char_face_and_encoding (struct frame *f, int c, int face_id,
24131 XChar2b *char2b, int display_p)
24133 struct face *face = FACE_FROM_ID (f, face_id);
24134 unsigned code = 0;
24136 if (face->font)
24138 code = face->font->driver->encode_char (face->font, c);
24140 if (code == FONT_INVALID_CODE)
24141 code = 0;
24143 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
24145 /* Make sure X resources of the face are allocated. */
24146 #ifdef HAVE_X_WINDOWS
24147 if (display_p)
24148 #endif
24150 eassert (face != NULL);
24151 prepare_face_for_display (f, face);
24154 return face;
24158 /* Get face and two-byte form of character glyph GLYPH on frame F.
24159 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
24160 a pointer to a realized face that is ready for display. */
24162 static struct face *
24163 get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
24164 XChar2b *char2b, int *two_byte_p)
24166 struct face *face;
24167 unsigned code = 0;
24169 eassert (glyph->type == CHAR_GLYPH);
24170 face = FACE_FROM_ID (f, glyph->face_id);
24172 /* Make sure X resources of the face are allocated. */
24173 eassert (face != NULL);
24174 prepare_face_for_display (f, face);
24176 if (two_byte_p)
24177 *two_byte_p = 0;
24179 if (face->font)
24181 if (CHAR_BYTE8_P (glyph->u.ch))
24182 code = CHAR_TO_BYTE8 (glyph->u.ch);
24183 else
24184 code = face->font->driver->encode_char (face->font, glyph->u.ch);
24186 if (code == FONT_INVALID_CODE)
24187 code = 0;
24190 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
24191 return face;
24195 /* Get glyph code of character C in FONT in the two-byte form CHAR2B.
24196 Return 1 if FONT has a glyph for C, otherwise return 0. */
24198 static int
24199 get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
24201 unsigned code;
24203 if (CHAR_BYTE8_P (c))
24204 code = CHAR_TO_BYTE8 (c);
24205 else
24206 code = font->driver->encode_char (font, c);
24208 if (code == FONT_INVALID_CODE)
24209 return 0;
24210 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
24211 return 1;
24215 /* Fill glyph string S with composition components specified by S->cmp.
24217 BASE_FACE is the base face of the composition.
24218 S->cmp_from is the index of the first component for S.
24220 OVERLAPS non-zero means S should draw the foreground only, and use
24221 its physical height for clipping. See also draw_glyphs.
24223 Value is the index of a component not in S. */
24225 static int
24226 fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
24227 int overlaps)
24229 int i;
24230 /* For all glyphs of this composition, starting at the offset
24231 S->cmp_from, until we reach the end of the definition or encounter a
24232 glyph that requires the different face, add it to S. */
24233 struct face *face;
24235 eassert (s);
24237 s->for_overlaps = overlaps;
24238 s->face = NULL;
24239 s->font = NULL;
24240 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
24242 int c = COMPOSITION_GLYPH (s->cmp, i);
24244 /* TAB in a composition means display glyphs with padding space
24245 on the left or right. */
24246 if (c != '\t')
24248 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
24249 -1, Qnil);
24251 face = get_char_face_and_encoding (s->f, c, face_id,
24252 s->char2b + i, 1);
24253 if (face)
24255 if (! s->face)
24257 s->face = face;
24258 s->font = s->face->font;
24260 else if (s->face != face)
24261 break;
24264 ++s->nchars;
24266 s->cmp_to = i;
24268 if (s->face == NULL)
24270 s->face = base_face->ascii_face;
24271 s->font = s->face->font;
24274 /* All glyph strings for the same composition has the same width,
24275 i.e. the width set for the first component of the composition. */
24276 s->width = s->first_glyph->pixel_width;
24278 /* If the specified font could not be loaded, use the frame's
24279 default font, but record the fact that we couldn't load it in
24280 the glyph string so that we can draw rectangles for the
24281 characters of the glyph string. */
24282 if (s->font == NULL)
24284 s->font_not_found_p = 1;
24285 s->font = FRAME_FONT (s->f);
24288 /* Adjust base line for subscript/superscript text. */
24289 s->ybase += s->first_glyph->voffset;
24291 /* This glyph string must always be drawn with 16-bit functions. */
24292 s->two_byte_p = 1;
24294 return s->cmp_to;
24297 static int
24298 fill_gstring_glyph_string (struct glyph_string *s, int face_id,
24299 int start, int end, int overlaps)
24301 struct glyph *glyph, *last;
24302 Lisp_Object lgstring;
24303 int i;
24305 s->for_overlaps = overlaps;
24306 glyph = s->row->glyphs[s->area] + start;
24307 last = s->row->glyphs[s->area] + end;
24308 s->cmp_id = glyph->u.cmp.id;
24309 s->cmp_from = glyph->slice.cmp.from;
24310 s->cmp_to = glyph->slice.cmp.to + 1;
24311 s->face = FACE_FROM_ID (s->f, face_id);
24312 lgstring = composition_gstring_from_id (s->cmp_id);
24313 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
24314 glyph++;
24315 while (glyph < last
24316 && glyph->u.cmp.automatic
24317 && glyph->u.cmp.id == s->cmp_id
24318 && s->cmp_to == glyph->slice.cmp.from)
24319 s->cmp_to = (glyph++)->slice.cmp.to + 1;
24321 for (i = s->cmp_from; i < s->cmp_to; i++)
24323 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
24324 unsigned code = LGLYPH_CODE (lglyph);
24326 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
24328 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
24329 return glyph - s->row->glyphs[s->area];
24333 /* Fill glyph string S from a sequence glyphs for glyphless characters.
24334 See the comment of fill_glyph_string for arguments.
24335 Value is the index of the first glyph not in S. */
24338 static int
24339 fill_glyphless_glyph_string (struct glyph_string *s, int face_id,
24340 int start, int end, int overlaps)
24342 struct glyph *glyph, *last;
24343 int voffset;
24345 eassert (s->first_glyph->type == GLYPHLESS_GLYPH);
24346 s->for_overlaps = overlaps;
24347 glyph = s->row->glyphs[s->area] + start;
24348 last = s->row->glyphs[s->area] + end;
24349 voffset = glyph->voffset;
24350 s->face = FACE_FROM_ID (s->f, face_id);
24351 s->font = s->face->font ? s->face->font : FRAME_FONT (s->f);
24352 s->nchars = 1;
24353 s->width = glyph->pixel_width;
24354 glyph++;
24355 while (glyph < last
24356 && glyph->type == GLYPHLESS_GLYPH
24357 && glyph->voffset == voffset
24358 && glyph->face_id == face_id)
24360 s->nchars++;
24361 s->width += glyph->pixel_width;
24362 glyph++;
24364 s->ybase += voffset;
24365 return glyph - s->row->glyphs[s->area];
24369 /* Fill glyph string S from a sequence of character glyphs.
24371 FACE_ID is the face id of the string. START is the index of the
24372 first glyph to consider, END is the index of the last + 1.
24373 OVERLAPS non-zero means S should draw the foreground only, and use
24374 its physical height for clipping. See also draw_glyphs.
24376 Value is the index of the first glyph not in S. */
24378 static int
24379 fill_glyph_string (struct glyph_string *s, int face_id,
24380 int start, int end, int overlaps)
24382 struct glyph *glyph, *last;
24383 int voffset;
24384 int glyph_not_available_p;
24386 eassert (s->f == XFRAME (s->w->frame));
24387 eassert (s->nchars == 0);
24388 eassert (start >= 0 && end > start);
24390 s->for_overlaps = overlaps;
24391 glyph = s->row->glyphs[s->area] + start;
24392 last = s->row->glyphs[s->area] + end;
24393 voffset = glyph->voffset;
24394 s->padding_p = glyph->padding_p;
24395 glyph_not_available_p = glyph->glyph_not_available_p;
24397 while (glyph < last
24398 && glyph->type == CHAR_GLYPH
24399 && glyph->voffset == voffset
24400 /* Same face id implies same font, nowadays. */
24401 && glyph->face_id == face_id
24402 && glyph->glyph_not_available_p == glyph_not_available_p)
24404 int two_byte_p;
24406 s->face = get_glyph_face_and_encoding (s->f, glyph,
24407 s->char2b + s->nchars,
24408 &two_byte_p);
24409 s->two_byte_p = two_byte_p;
24410 ++s->nchars;
24411 eassert (s->nchars <= end - start);
24412 s->width += glyph->pixel_width;
24413 if (glyph++->padding_p != s->padding_p)
24414 break;
24417 s->font = s->face->font;
24419 /* If the specified font could not be loaded, use the frame's font,
24420 but record the fact that we couldn't load it in
24421 S->font_not_found_p so that we can draw rectangles for the
24422 characters of the glyph string. */
24423 if (s->font == NULL || glyph_not_available_p)
24425 s->font_not_found_p = 1;
24426 s->font = FRAME_FONT (s->f);
24429 /* Adjust base line for subscript/superscript text. */
24430 s->ybase += voffset;
24432 eassert (s->face && s->face->gc);
24433 return glyph - s->row->glyphs[s->area];
24437 /* Fill glyph string S from image glyph S->first_glyph. */
24439 static void
24440 fill_image_glyph_string (struct glyph_string *s)
24442 eassert (s->first_glyph->type == IMAGE_GLYPH);
24443 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
24444 eassert (s->img);
24445 s->slice = s->first_glyph->slice.img;
24446 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
24447 s->font = s->face->font;
24448 s->width = s->first_glyph->pixel_width;
24450 /* Adjust base line for subscript/superscript text. */
24451 s->ybase += s->first_glyph->voffset;
24455 /* Fill glyph string S from a sequence of stretch glyphs.
24457 START is the index of the first glyph to consider,
24458 END is the index of the last + 1.
24460 Value is the index of the first glyph not in S. */
24462 static int
24463 fill_stretch_glyph_string (struct glyph_string *s, int start, int end)
24465 struct glyph *glyph, *last;
24466 int voffset, face_id;
24468 eassert (s->first_glyph->type == STRETCH_GLYPH);
24470 glyph = s->row->glyphs[s->area] + start;
24471 last = s->row->glyphs[s->area] + end;
24472 face_id = glyph->face_id;
24473 s->face = FACE_FROM_ID (s->f, face_id);
24474 s->font = s->face->font;
24475 s->width = glyph->pixel_width;
24476 s->nchars = 1;
24477 voffset = glyph->voffset;
24479 for (++glyph;
24480 (glyph < last
24481 && glyph->type == STRETCH_GLYPH
24482 && glyph->voffset == voffset
24483 && glyph->face_id == face_id);
24484 ++glyph)
24485 s->width += glyph->pixel_width;
24487 /* Adjust base line for subscript/superscript text. */
24488 s->ybase += voffset;
24490 /* The case that face->gc == 0 is handled when drawing the glyph
24491 string by calling prepare_face_for_display. */
24492 eassert (s->face);
24493 return glyph - s->row->glyphs[s->area];
24496 static struct font_metrics *
24497 get_per_char_metric (struct font *font, XChar2b *char2b)
24499 static struct font_metrics metrics;
24500 unsigned code;
24502 if (! font)
24503 return NULL;
24504 code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
24505 if (code == FONT_INVALID_CODE)
24506 return NULL;
24507 font->driver->text_extents (font, &code, 1, &metrics);
24508 return &metrics;
24511 /* EXPORT for RIF:
24512 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
24513 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
24514 assumed to be zero. */
24516 void
24517 x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *right)
24519 *left = *right = 0;
24521 if (glyph->type == CHAR_GLYPH)
24523 struct face *face;
24524 XChar2b char2b;
24525 struct font_metrics *pcm;
24527 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
24528 if (face->font && (pcm = get_per_char_metric (face->font, &char2b)))
24530 if (pcm->rbearing > pcm->width)
24531 *right = pcm->rbearing - pcm->width;
24532 if (pcm->lbearing < 0)
24533 *left = -pcm->lbearing;
24536 else if (glyph->type == COMPOSITE_GLYPH)
24538 if (! glyph->u.cmp.automatic)
24540 struct composition *cmp = composition_table[glyph->u.cmp.id];
24542 if (cmp->rbearing > cmp->pixel_width)
24543 *right = cmp->rbearing - cmp->pixel_width;
24544 if (cmp->lbearing < 0)
24545 *left = - cmp->lbearing;
24547 else
24549 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
24550 struct font_metrics metrics;
24552 composition_gstring_width (gstring, glyph->slice.cmp.from,
24553 glyph->slice.cmp.to + 1, &metrics);
24554 if (metrics.rbearing > metrics.width)
24555 *right = metrics.rbearing - metrics.width;
24556 if (metrics.lbearing < 0)
24557 *left = - metrics.lbearing;
24563 /* Return the index of the first glyph preceding glyph string S that
24564 is overwritten by S because of S's left overhang. Value is -1
24565 if no glyphs are overwritten. */
24567 static int
24568 left_overwritten (struct glyph_string *s)
24570 int k;
24572 if (s->left_overhang)
24574 int x = 0, i;
24575 struct glyph *glyphs = s->row->glyphs[s->area];
24576 int first = s->first_glyph - glyphs;
24578 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
24579 x -= glyphs[i].pixel_width;
24581 k = i + 1;
24583 else
24584 k = -1;
24586 return k;
24590 /* Return the index of the first glyph preceding glyph string S that
24591 is overwriting S because of its right overhang. Value is -1 if no
24592 glyph in front of S overwrites S. */
24594 static int
24595 left_overwriting (struct glyph_string *s)
24597 int i, k, x;
24598 struct glyph *glyphs = s->row->glyphs[s->area];
24599 int first = s->first_glyph - glyphs;
24601 k = -1;
24602 x = 0;
24603 for (i = first - 1; i >= 0; --i)
24605 int left, right;
24606 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
24607 if (x + right > 0)
24608 k = i;
24609 x -= glyphs[i].pixel_width;
24612 return k;
24616 /* Return the index of the last glyph following glyph string S that is
24617 overwritten by S because of S's right overhang. Value is -1 if
24618 no such glyph is found. */
24620 static int
24621 right_overwritten (struct glyph_string *s)
24623 int k = -1;
24625 if (s->right_overhang)
24627 int x = 0, i;
24628 struct glyph *glyphs = s->row->glyphs[s->area];
24629 int first = (s->first_glyph - glyphs
24630 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
24631 int end = s->row->used[s->area];
24633 for (i = first; i < end && s->right_overhang > x; ++i)
24634 x += glyphs[i].pixel_width;
24636 k = i;
24639 return k;
24643 /* Return the index of the last glyph following glyph string S that
24644 overwrites S because of its left overhang. Value is negative
24645 if no such glyph is found. */
24647 static int
24648 right_overwriting (struct glyph_string *s)
24650 int i, k, x;
24651 int end = s->row->used[s->area];
24652 struct glyph *glyphs = s->row->glyphs[s->area];
24653 int first = (s->first_glyph - glyphs
24654 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
24656 k = -1;
24657 x = 0;
24658 for (i = first; i < end; ++i)
24660 int left, right;
24661 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
24662 if (x - left < 0)
24663 k = i;
24664 x += glyphs[i].pixel_width;
24667 return k;
24671 /* Set background width of glyph string S. START is the index of the
24672 first glyph following S. LAST_X is the right-most x-position + 1
24673 in the drawing area. */
24675 static void
24676 set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
24678 /* If the face of this glyph string has to be drawn to the end of
24679 the drawing area, set S->extends_to_end_of_line_p. */
24681 if (start == s->row->used[s->area]
24682 && ((s->row->fill_line_p
24683 && (s->hl == DRAW_NORMAL_TEXT
24684 || s->hl == DRAW_IMAGE_RAISED
24685 || s->hl == DRAW_IMAGE_SUNKEN))
24686 || s->hl == DRAW_MOUSE_FACE))
24687 s->extends_to_end_of_line_p = 1;
24689 /* If S extends its face to the end of the line, set its
24690 background_width to the distance to the right edge of the drawing
24691 area. */
24692 if (s->extends_to_end_of_line_p)
24693 s->background_width = last_x - s->x + 1;
24694 else
24695 s->background_width = s->width;
24699 /* Compute overhangs and x-positions for glyph string S and its
24700 predecessors, or successors. X is the starting x-position for S.
24701 BACKWARD_P non-zero means process predecessors. */
24703 static void
24704 compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
24706 if (backward_p)
24708 while (s)
24710 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
24711 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
24712 x -= s->width;
24713 s->x = x;
24714 s = s->prev;
24717 else
24719 while (s)
24721 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
24722 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
24723 s->x = x;
24724 x += s->width;
24725 s = s->next;
24732 /* The following macros are only called from draw_glyphs below.
24733 They reference the following parameters of that function directly:
24734 `w', `row', `area', and `overlap_p'
24735 as well as the following local variables:
24736 `s', `f', and `hdc' (in W32) */
24738 #ifdef HAVE_NTGUI
24739 /* On W32, silently add local `hdc' variable to argument list of
24740 init_glyph_string. */
24741 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
24742 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
24743 #else
24744 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
24745 init_glyph_string (s, char2b, w, row, area, start, hl)
24746 #endif
24748 /* Add a glyph string for a stretch glyph to the list of strings
24749 between HEAD and TAIL. START is the index of the stretch glyph in
24750 row area AREA of glyph row ROW. END is the index of the last glyph
24751 in that glyph row area. X is the current output position assigned
24752 to the new glyph string constructed. HL overrides that face of the
24753 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
24754 is the right-most x-position of the drawing area. */
24756 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
24757 and below -- keep them on one line. */
24758 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
24759 do \
24761 s = alloca (sizeof *s); \
24762 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
24763 START = fill_stretch_glyph_string (s, START, END); \
24764 append_glyph_string (&HEAD, &TAIL, s); \
24765 s->x = (X); \
24767 while (0)
24770 /* Add a glyph string for an image glyph to the list of strings
24771 between HEAD and TAIL. START is the index of the image glyph in
24772 row area AREA of glyph row ROW. END is the index of the last glyph
24773 in that glyph row area. X is the current output position assigned
24774 to the new glyph string constructed. HL overrides that face of the
24775 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
24776 is the right-most x-position of the drawing area. */
24778 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
24779 do \
24781 s = alloca (sizeof *s); \
24782 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
24783 fill_image_glyph_string (s); \
24784 append_glyph_string (&HEAD, &TAIL, s); \
24785 ++START; \
24786 s->x = (X); \
24788 while (0)
24791 /* Add a glyph string for a sequence of character glyphs to the list
24792 of strings between HEAD and TAIL. START is the index of the first
24793 glyph in row area AREA of glyph row ROW that is part of the new
24794 glyph string. END is the index of the last glyph in that glyph row
24795 area. X is the current output position assigned to the new glyph
24796 string constructed. HL overrides that face of the glyph; e.g. it
24797 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
24798 right-most x-position of the drawing area. */
24800 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
24801 do \
24803 int face_id; \
24804 XChar2b *char2b; \
24806 face_id = (row)->glyphs[area][START].face_id; \
24808 s = alloca (sizeof *s); \
24809 SAFE_NALLOCA (char2b, 1, (END) - (START)); \
24810 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
24811 append_glyph_string (&HEAD, &TAIL, s); \
24812 s->x = (X); \
24813 START = fill_glyph_string (s, face_id, START, END, overlaps); \
24815 while (0)
24818 /* Add a glyph string for a composite sequence to the list of strings
24819 between HEAD and TAIL. START is the index of the first glyph in
24820 row area AREA of glyph row ROW that is part of the new glyph
24821 string. END is the index of the last glyph in that glyph row area.
24822 X is the current output position assigned to the new glyph string
24823 constructed. HL overrides that face of the glyph; e.g. it is
24824 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
24825 x-position of the drawing area. */
24827 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
24828 do { \
24829 int face_id = (row)->glyphs[area][START].face_id; \
24830 struct face *base_face = FACE_FROM_ID (f, face_id); \
24831 ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \
24832 struct composition *cmp = composition_table[cmp_id]; \
24833 XChar2b *char2b; \
24834 struct glyph_string *first_s = NULL; \
24835 int n; \
24837 SAFE_NALLOCA (char2b, 1, cmp->glyph_len); \
24839 /* Make glyph_strings for each glyph sequence that is drawable by \
24840 the same face, and append them to HEAD/TAIL. */ \
24841 for (n = 0; n < cmp->glyph_len;) \
24843 s = alloca (sizeof *s); \
24844 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
24845 append_glyph_string (&(HEAD), &(TAIL), s); \
24846 s->cmp = cmp; \
24847 s->cmp_from = n; \
24848 s->x = (X); \
24849 if (n == 0) \
24850 first_s = s; \
24851 n = fill_composite_glyph_string (s, base_face, overlaps); \
24854 ++START; \
24855 s = first_s; \
24856 } while (0)
24859 /* Add a glyph string for a glyph-string sequence to the list of strings
24860 between HEAD and TAIL. */
24862 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
24863 do { \
24864 int face_id; \
24865 XChar2b *char2b; \
24866 Lisp_Object gstring; \
24868 face_id = (row)->glyphs[area][START].face_id; \
24869 gstring = (composition_gstring_from_id \
24870 ((row)->glyphs[area][START].u.cmp.id)); \
24871 s = alloca (sizeof *s); \
24872 SAFE_NALLOCA (char2b, 1, LGSTRING_GLYPH_LEN (gstring)); \
24873 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
24874 append_glyph_string (&(HEAD), &(TAIL), s); \
24875 s->x = (X); \
24876 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
24877 } while (0)
24880 /* Add a glyph string for a sequence of glyphless character's glyphs
24881 to the list of strings between HEAD and TAIL. The meanings of
24882 arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */
24884 #define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
24885 do \
24887 int face_id; \
24889 face_id = (row)->glyphs[area][START].face_id; \
24891 s = alloca (sizeof *s); \
24892 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
24893 append_glyph_string (&HEAD, &TAIL, s); \
24894 s->x = (X); \
24895 START = fill_glyphless_glyph_string (s, face_id, START, END, \
24896 overlaps); \
24898 while (0)
24901 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
24902 of AREA of glyph row ROW on window W between indices START and END.
24903 HL overrides the face for drawing glyph strings, e.g. it is
24904 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
24905 x-positions of the drawing area.
24907 This is an ugly monster macro construct because we must use alloca
24908 to allocate glyph strings (because draw_glyphs can be called
24909 asynchronously). */
24911 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
24912 do \
24914 HEAD = TAIL = NULL; \
24915 while (START < END) \
24917 struct glyph *first_glyph = (row)->glyphs[area] + START; \
24918 switch (first_glyph->type) \
24920 case CHAR_GLYPH: \
24921 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
24922 HL, X, LAST_X); \
24923 break; \
24925 case COMPOSITE_GLYPH: \
24926 if (first_glyph->u.cmp.automatic) \
24927 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
24928 HL, X, LAST_X); \
24929 else \
24930 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
24931 HL, X, LAST_X); \
24932 break; \
24934 case STRETCH_GLYPH: \
24935 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
24936 HL, X, LAST_X); \
24937 break; \
24939 case IMAGE_GLYPH: \
24940 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
24941 HL, X, LAST_X); \
24942 break; \
24944 case GLYPHLESS_GLYPH: \
24945 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
24946 HL, X, LAST_X); \
24947 break; \
24949 default: \
24950 emacs_abort (); \
24953 if (s) \
24955 set_glyph_string_background_width (s, START, LAST_X); \
24956 (X) += s->width; \
24959 } while (0)
24962 /* Draw glyphs between START and END in AREA of ROW on window W,
24963 starting at x-position X. X is relative to AREA in W. HL is a
24964 face-override with the following meaning:
24966 DRAW_NORMAL_TEXT draw normally
24967 DRAW_CURSOR draw in cursor face
24968 DRAW_MOUSE_FACE draw in mouse face.
24969 DRAW_INVERSE_VIDEO draw in mode line face
24970 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
24971 DRAW_IMAGE_RAISED draw an image with a raised relief around it
24973 If OVERLAPS is non-zero, draw only the foreground of characters and
24974 clip to the physical height of ROW. Non-zero value also defines
24975 the overlapping part to be drawn:
24977 OVERLAPS_PRED overlap with preceding rows
24978 OVERLAPS_SUCC overlap with succeeding rows
24979 OVERLAPS_BOTH overlap with both preceding/succeeding rows
24980 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
24982 Value is the x-position reached, relative to AREA of W. */
24984 static int
24985 draw_glyphs (struct window *w, int x, struct glyph_row *row,
24986 enum glyph_row_area area, ptrdiff_t start, ptrdiff_t end,
24987 enum draw_glyphs_face hl, int overlaps)
24989 struct glyph_string *head, *tail;
24990 struct glyph_string *s;
24991 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
24992 int i, j, x_reached, last_x, area_left = 0;
24993 struct frame *f = XFRAME (WINDOW_FRAME (w));
24994 DECLARE_HDC (hdc);
24996 ALLOCATE_HDC (hdc, f);
24998 /* Let's rather be paranoid than getting a SEGV. */
24999 end = min (end, row->used[area]);
25000 start = clip_to_bounds (0, start, end);
25002 /* Translate X to frame coordinates. Set last_x to the right
25003 end of the drawing area. */
25004 if (row->full_width_p)
25006 /* X is relative to the left edge of W, without scroll bars
25007 or fringes. */
25008 area_left = WINDOW_LEFT_EDGE_X (w);
25009 last_x = (WINDOW_LEFT_EDGE_X (w) + WINDOW_PIXEL_WIDTH (w)
25010 - (row->mode_line_p ? WINDOW_RIGHT_DIVIDER_WIDTH (w) : 0));
25012 else
25014 area_left = window_box_left (w, area);
25015 last_x = area_left + window_box_width (w, area);
25017 x += area_left;
25019 /* Build a doubly-linked list of glyph_string structures between
25020 head and tail from what we have to draw. Note that the macro
25021 BUILD_GLYPH_STRINGS will modify its start parameter. That's
25022 the reason we use a separate variable `i'. */
25023 i = start;
25024 USE_SAFE_ALLOCA;
25025 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
25026 if (tail)
25027 x_reached = tail->x + tail->background_width;
25028 else
25029 x_reached = x;
25031 /* If there are any glyphs with lbearing < 0 or rbearing > width in
25032 the row, redraw some glyphs in front or following the glyph
25033 strings built above. */
25034 if (head && !overlaps && row->contains_overlapping_glyphs_p)
25036 struct glyph_string *h, *t;
25037 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
25038 int mouse_beg_col IF_LINT (= 0), mouse_end_col IF_LINT (= 0);
25039 int check_mouse_face = 0;
25040 int dummy_x = 0;
25042 /* If mouse highlighting is on, we may need to draw adjacent
25043 glyphs using mouse-face highlighting. */
25044 if (area == TEXT_AREA && row->mouse_face_p
25045 && hlinfo->mouse_face_beg_row >= 0
25046 && hlinfo->mouse_face_end_row >= 0)
25048 ptrdiff_t row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
25050 if (row_vpos >= hlinfo->mouse_face_beg_row
25051 && row_vpos <= hlinfo->mouse_face_end_row)
25053 check_mouse_face = 1;
25054 mouse_beg_col = (row_vpos == hlinfo->mouse_face_beg_row)
25055 ? hlinfo->mouse_face_beg_col : 0;
25056 mouse_end_col = (row_vpos == hlinfo->mouse_face_end_row)
25057 ? hlinfo->mouse_face_end_col
25058 : row->used[TEXT_AREA];
25062 /* Compute overhangs for all glyph strings. */
25063 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
25064 for (s = head; s; s = s->next)
25065 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
25067 /* Prepend glyph strings for glyphs in front of the first glyph
25068 string that are overwritten because of the first glyph
25069 string's left overhang. The background of all strings
25070 prepended must be drawn because the first glyph string
25071 draws over it. */
25072 i = left_overwritten (head);
25073 if (i >= 0)
25075 enum draw_glyphs_face overlap_hl;
25077 /* If this row contains mouse highlighting, attempt to draw
25078 the overlapped glyphs with the correct highlight. This
25079 code fails if the overlap encompasses more than one glyph
25080 and mouse-highlight spans only some of these glyphs.
25081 However, making it work perfectly involves a lot more
25082 code, and I don't know if the pathological case occurs in
25083 practice, so we'll stick to this for now. --- cyd */
25084 if (check_mouse_face
25085 && mouse_beg_col < start && mouse_end_col > i)
25086 overlap_hl = DRAW_MOUSE_FACE;
25087 else
25088 overlap_hl = DRAW_NORMAL_TEXT;
25090 if (hl != overlap_hl)
25091 clip_head = head;
25092 j = i;
25093 BUILD_GLYPH_STRINGS (j, start, h, t,
25094 overlap_hl, dummy_x, last_x);
25095 start = i;
25096 compute_overhangs_and_x (t, head->x, 1);
25097 prepend_glyph_string_lists (&head, &tail, h, t);
25098 if (clip_head == NULL)
25099 clip_head = head;
25102 /* Prepend glyph strings for glyphs in front of the first glyph
25103 string that overwrite that glyph string because of their
25104 right overhang. For these strings, only the foreground must
25105 be drawn, because it draws over the glyph string at `head'.
25106 The background must not be drawn because this would overwrite
25107 right overhangs of preceding glyphs for which no glyph
25108 strings exist. */
25109 i = left_overwriting (head);
25110 if (i >= 0)
25112 enum draw_glyphs_face overlap_hl;
25114 if (check_mouse_face
25115 && mouse_beg_col < start && mouse_end_col > i)
25116 overlap_hl = DRAW_MOUSE_FACE;
25117 else
25118 overlap_hl = DRAW_NORMAL_TEXT;
25120 if (hl == overlap_hl || clip_head == NULL)
25121 clip_head = head;
25122 BUILD_GLYPH_STRINGS (i, start, h, t,
25123 overlap_hl, dummy_x, last_x);
25124 for (s = h; s; s = s->next)
25125 s->background_filled_p = 1;
25126 compute_overhangs_and_x (t, head->x, 1);
25127 prepend_glyph_string_lists (&head, &tail, h, t);
25130 /* Append glyphs strings for glyphs following the last glyph
25131 string tail that are overwritten by tail. The background of
25132 these strings has to be drawn because tail's foreground draws
25133 over it. */
25134 i = right_overwritten (tail);
25135 if (i >= 0)
25137 enum draw_glyphs_face overlap_hl;
25139 if (check_mouse_face
25140 && mouse_beg_col < i && mouse_end_col > end)
25141 overlap_hl = DRAW_MOUSE_FACE;
25142 else
25143 overlap_hl = DRAW_NORMAL_TEXT;
25145 if (hl != overlap_hl)
25146 clip_tail = tail;
25147 BUILD_GLYPH_STRINGS (end, i, h, t,
25148 overlap_hl, x, last_x);
25149 /* Because BUILD_GLYPH_STRINGS updates the first argument,
25150 we don't have `end = i;' here. */
25151 compute_overhangs_and_x (h, tail->x + tail->width, 0);
25152 append_glyph_string_lists (&head, &tail, h, t);
25153 if (clip_tail == NULL)
25154 clip_tail = tail;
25157 /* Append glyph strings for glyphs following the last glyph
25158 string tail that overwrite tail. The foreground of such
25159 glyphs has to be drawn because it writes into the background
25160 of tail. The background must not be drawn because it could
25161 paint over the foreground of following glyphs. */
25162 i = right_overwriting (tail);
25163 if (i >= 0)
25165 enum draw_glyphs_face overlap_hl;
25166 if (check_mouse_face
25167 && mouse_beg_col < i && mouse_end_col > end)
25168 overlap_hl = DRAW_MOUSE_FACE;
25169 else
25170 overlap_hl = DRAW_NORMAL_TEXT;
25172 if (hl == overlap_hl || clip_tail == NULL)
25173 clip_tail = tail;
25174 i++; /* We must include the Ith glyph. */
25175 BUILD_GLYPH_STRINGS (end, i, h, t,
25176 overlap_hl, x, last_x);
25177 for (s = h; s; s = s->next)
25178 s->background_filled_p = 1;
25179 compute_overhangs_and_x (h, tail->x + tail->width, 0);
25180 append_glyph_string_lists (&head, &tail, h, t);
25182 if (clip_head || clip_tail)
25183 for (s = head; s; s = s->next)
25185 s->clip_head = clip_head;
25186 s->clip_tail = clip_tail;
25190 /* Draw all strings. */
25191 for (s = head; s; s = s->next)
25192 FRAME_RIF (f)->draw_glyph_string (s);
25194 #ifndef HAVE_NS
25195 /* When focus a sole frame and move horizontally, this sets on_p to 0
25196 causing a failure to erase prev cursor position. */
25197 if (area == TEXT_AREA
25198 && !row->full_width_p
25199 /* When drawing overlapping rows, only the glyph strings'
25200 foreground is drawn, which doesn't erase a cursor
25201 completely. */
25202 && !overlaps)
25204 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
25205 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
25206 : (tail ? tail->x + tail->background_width : x));
25207 x0 -= area_left;
25208 x1 -= area_left;
25210 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
25211 row->y, MATRIX_ROW_BOTTOM_Y (row));
25213 #endif
25215 /* Value is the x-position up to which drawn, relative to AREA of W.
25216 This doesn't include parts drawn because of overhangs. */
25217 if (row->full_width_p)
25218 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
25219 else
25220 x_reached -= area_left;
25222 RELEASE_HDC (hdc, f);
25224 SAFE_FREE ();
25225 return x_reached;
25228 /* Expand row matrix if too narrow. Don't expand if area
25229 is not present. */
25231 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
25233 if (!it->f->fonts_changed \
25234 && (it->glyph_row->glyphs[area] \
25235 < it->glyph_row->glyphs[area + 1])) \
25237 it->w->ncols_scale_factor++; \
25238 it->f->fonts_changed = 1; \
25242 /* Store one glyph for IT->char_to_display in IT->glyph_row.
25243 Called from x_produce_glyphs when IT->glyph_row is non-null. */
25245 static void
25246 append_glyph (struct it *it)
25248 struct glyph *glyph;
25249 enum glyph_row_area area = it->area;
25251 eassert (it->glyph_row);
25252 eassert (it->char_to_display != '\n' && it->char_to_display != '\t');
25254 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
25255 if (glyph < it->glyph_row->glyphs[area + 1])
25257 /* If the glyph row is reversed, we need to prepend the glyph
25258 rather than append it. */
25259 if (it->glyph_row->reversed_p && area == TEXT_AREA)
25261 struct glyph *g;
25263 /* Make room for the additional glyph. */
25264 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
25265 g[1] = *g;
25266 glyph = it->glyph_row->glyphs[area];
25268 glyph->charpos = CHARPOS (it->position);
25269 glyph->object = it->object;
25270 if (it->pixel_width > 0)
25272 glyph->pixel_width = it->pixel_width;
25273 glyph->padding_p = 0;
25275 else
25277 /* Assure at least 1-pixel width. Otherwise, cursor can't
25278 be displayed correctly. */
25279 glyph->pixel_width = 1;
25280 glyph->padding_p = 1;
25282 glyph->ascent = it->ascent;
25283 glyph->descent = it->descent;
25284 glyph->voffset = it->voffset;
25285 glyph->type = CHAR_GLYPH;
25286 glyph->avoid_cursor_p = it->avoid_cursor_p;
25287 glyph->multibyte_p = it->multibyte_p;
25288 if (it->glyph_row->reversed_p && area == TEXT_AREA)
25290 /* In R2L rows, the left and the right box edges need to be
25291 drawn in reverse direction. */
25292 glyph->right_box_line_p = it->start_of_box_run_p;
25293 glyph->left_box_line_p = it->end_of_box_run_p;
25295 else
25297 glyph->left_box_line_p = it->start_of_box_run_p;
25298 glyph->right_box_line_p = it->end_of_box_run_p;
25300 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
25301 || it->phys_descent > it->descent);
25302 glyph->glyph_not_available_p = it->glyph_not_available_p;
25303 glyph->face_id = it->face_id;
25304 glyph->u.ch = it->char_to_display;
25305 glyph->slice.img = null_glyph_slice;
25306 glyph->font_type = FONT_TYPE_UNKNOWN;
25307 if (it->bidi_p)
25309 glyph->resolved_level = it->bidi_it.resolved_level;
25310 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
25311 glyph->bidi_type = it->bidi_it.type;
25313 else
25315 glyph->resolved_level = 0;
25316 glyph->bidi_type = UNKNOWN_BT;
25318 ++it->glyph_row->used[area];
25320 else
25321 IT_EXPAND_MATRIX_WIDTH (it, area);
25324 /* Store one glyph for the composition IT->cmp_it.id in
25325 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
25326 non-null. */
25328 static void
25329 append_composite_glyph (struct it *it)
25331 struct glyph *glyph;
25332 enum glyph_row_area area = it->area;
25334 eassert (it->glyph_row);
25336 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
25337 if (glyph < it->glyph_row->glyphs[area + 1])
25339 /* If the glyph row is reversed, we need to prepend the glyph
25340 rather than append it. */
25341 if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
25343 struct glyph *g;
25345 /* Make room for the new glyph. */
25346 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
25347 g[1] = *g;
25348 glyph = it->glyph_row->glyphs[it->area];
25350 glyph->charpos = it->cmp_it.charpos;
25351 glyph->object = it->object;
25352 glyph->pixel_width = it->pixel_width;
25353 glyph->ascent = it->ascent;
25354 glyph->descent = it->descent;
25355 glyph->voffset = it->voffset;
25356 glyph->type = COMPOSITE_GLYPH;
25357 if (it->cmp_it.ch < 0)
25359 glyph->u.cmp.automatic = 0;
25360 glyph->u.cmp.id = it->cmp_it.id;
25361 glyph->slice.cmp.from = glyph->slice.cmp.to = 0;
25363 else
25365 glyph->u.cmp.automatic = 1;
25366 glyph->u.cmp.id = it->cmp_it.id;
25367 glyph->slice.cmp.from = it->cmp_it.from;
25368 glyph->slice.cmp.to = it->cmp_it.to - 1;
25370 glyph->avoid_cursor_p = it->avoid_cursor_p;
25371 glyph->multibyte_p = it->multibyte_p;
25372 if (it->glyph_row->reversed_p && area == TEXT_AREA)
25374 /* In R2L rows, the left and the right box edges need to be
25375 drawn in reverse direction. */
25376 glyph->right_box_line_p = it->start_of_box_run_p;
25377 glyph->left_box_line_p = it->end_of_box_run_p;
25379 else
25381 glyph->left_box_line_p = it->start_of_box_run_p;
25382 glyph->right_box_line_p = it->end_of_box_run_p;
25384 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
25385 || it->phys_descent > it->descent);
25386 glyph->padding_p = 0;
25387 glyph->glyph_not_available_p = 0;
25388 glyph->face_id = it->face_id;
25389 glyph->font_type = FONT_TYPE_UNKNOWN;
25390 if (it->bidi_p)
25392 glyph->resolved_level = it->bidi_it.resolved_level;
25393 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
25394 glyph->bidi_type = it->bidi_it.type;
25396 ++it->glyph_row->used[area];
25398 else
25399 IT_EXPAND_MATRIX_WIDTH (it, area);
25403 /* Change IT->ascent and IT->height according to the setting of
25404 IT->voffset. */
25406 static void
25407 take_vertical_position_into_account (struct it *it)
25409 if (it->voffset)
25411 if (it->voffset < 0)
25412 /* Increase the ascent so that we can display the text higher
25413 in the line. */
25414 it->ascent -= it->voffset;
25415 else
25416 /* Increase the descent so that we can display the text lower
25417 in the line. */
25418 it->descent += it->voffset;
25423 /* Produce glyphs/get display metrics for the image IT is loaded with.
25424 See the description of struct display_iterator in dispextern.h for
25425 an overview of struct display_iterator. */
25427 static void
25428 produce_image_glyph (struct it *it)
25430 struct image *img;
25431 struct face *face;
25432 int glyph_ascent, crop;
25433 struct glyph_slice slice;
25435 eassert (it->what == IT_IMAGE);
25437 face = FACE_FROM_ID (it->f, it->face_id);
25438 eassert (face);
25439 /* Make sure X resources of the face is loaded. */
25440 prepare_face_for_display (it->f, face);
25442 if (it->image_id < 0)
25444 /* Fringe bitmap. */
25445 it->ascent = it->phys_ascent = 0;
25446 it->descent = it->phys_descent = 0;
25447 it->pixel_width = 0;
25448 it->nglyphs = 0;
25449 return;
25452 img = IMAGE_FROM_ID (it->f, it->image_id);
25453 eassert (img);
25454 /* Make sure X resources of the image is loaded. */
25455 prepare_image_for_display (it->f, img);
25457 slice.x = slice.y = 0;
25458 slice.width = img->width;
25459 slice.height = img->height;
25461 if (INTEGERP (it->slice.x))
25462 slice.x = XINT (it->slice.x);
25463 else if (FLOATP (it->slice.x))
25464 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
25466 if (INTEGERP (it->slice.y))
25467 slice.y = XINT (it->slice.y);
25468 else if (FLOATP (it->slice.y))
25469 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
25471 if (INTEGERP (it->slice.width))
25472 slice.width = XINT (it->slice.width);
25473 else if (FLOATP (it->slice.width))
25474 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
25476 if (INTEGERP (it->slice.height))
25477 slice.height = XINT (it->slice.height);
25478 else if (FLOATP (it->slice.height))
25479 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
25481 if (slice.x >= img->width)
25482 slice.x = img->width;
25483 if (slice.y >= img->height)
25484 slice.y = img->height;
25485 if (slice.x + slice.width >= img->width)
25486 slice.width = img->width - slice.x;
25487 if (slice.y + slice.height > img->height)
25488 slice.height = img->height - slice.y;
25490 if (slice.width == 0 || slice.height == 0)
25491 return;
25493 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
25495 it->descent = slice.height - glyph_ascent;
25496 if (slice.y == 0)
25497 it->descent += img->vmargin;
25498 if (slice.y + slice.height == img->height)
25499 it->descent += img->vmargin;
25500 it->phys_descent = it->descent;
25502 it->pixel_width = slice.width;
25503 if (slice.x == 0)
25504 it->pixel_width += img->hmargin;
25505 if (slice.x + slice.width == img->width)
25506 it->pixel_width += img->hmargin;
25508 /* It's quite possible for images to have an ascent greater than
25509 their height, so don't get confused in that case. */
25510 if (it->descent < 0)
25511 it->descent = 0;
25513 it->nglyphs = 1;
25515 if (face->box != FACE_NO_BOX)
25517 if (face->box_line_width > 0)
25519 if (slice.y == 0)
25520 it->ascent += face->box_line_width;
25521 if (slice.y + slice.height == img->height)
25522 it->descent += face->box_line_width;
25525 if (it->start_of_box_run_p && slice.x == 0)
25526 it->pixel_width += eabs (face->box_line_width);
25527 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
25528 it->pixel_width += eabs (face->box_line_width);
25531 take_vertical_position_into_account (it);
25533 /* Automatically crop wide image glyphs at right edge so we can
25534 draw the cursor on same display row. */
25535 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
25536 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
25538 it->pixel_width -= crop;
25539 slice.width -= crop;
25542 if (it->glyph_row)
25544 struct glyph *glyph;
25545 enum glyph_row_area area = it->area;
25547 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
25548 if (glyph < it->glyph_row->glyphs[area + 1])
25550 glyph->charpos = CHARPOS (it->position);
25551 glyph->object = it->object;
25552 glyph->pixel_width = it->pixel_width;
25553 glyph->ascent = glyph_ascent;
25554 glyph->descent = it->descent;
25555 glyph->voffset = it->voffset;
25556 glyph->type = IMAGE_GLYPH;
25557 glyph->avoid_cursor_p = it->avoid_cursor_p;
25558 glyph->multibyte_p = it->multibyte_p;
25559 if (it->glyph_row->reversed_p && area == TEXT_AREA)
25561 /* In R2L rows, the left and the right box edges need to be
25562 drawn in reverse direction. */
25563 glyph->right_box_line_p = it->start_of_box_run_p;
25564 glyph->left_box_line_p = it->end_of_box_run_p;
25566 else
25568 glyph->left_box_line_p = it->start_of_box_run_p;
25569 glyph->right_box_line_p = it->end_of_box_run_p;
25571 glyph->overlaps_vertically_p = 0;
25572 glyph->padding_p = 0;
25573 glyph->glyph_not_available_p = 0;
25574 glyph->face_id = it->face_id;
25575 glyph->u.img_id = img->id;
25576 glyph->slice.img = slice;
25577 glyph->font_type = FONT_TYPE_UNKNOWN;
25578 if (it->bidi_p)
25580 glyph->resolved_level = it->bidi_it.resolved_level;
25581 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
25582 glyph->bidi_type = it->bidi_it.type;
25584 ++it->glyph_row->used[area];
25586 else
25587 IT_EXPAND_MATRIX_WIDTH (it, area);
25592 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
25593 of the glyph, WIDTH and HEIGHT are the width and height of the
25594 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
25596 static void
25597 append_stretch_glyph (struct it *it, Lisp_Object object,
25598 int width, int height, int ascent)
25600 struct glyph *glyph;
25601 enum glyph_row_area area = it->area;
25603 eassert (ascent >= 0 && ascent <= height);
25605 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
25606 if (glyph < it->glyph_row->glyphs[area + 1])
25608 /* If the glyph row is reversed, we need to prepend the glyph
25609 rather than append it. */
25610 if (it->glyph_row->reversed_p && area == TEXT_AREA)
25612 struct glyph *g;
25614 /* Make room for the additional glyph. */
25615 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
25616 g[1] = *g;
25617 glyph = it->glyph_row->glyphs[area];
25619 /* Decrease the width of the first glyph of the row that
25620 begins before first_visible_x (e.g., due to hscroll).
25621 This is so the overall width of the row becomes smaller
25622 by the scroll amount, and the stretch glyph appended by
25623 extend_face_to_end_of_line will be wider, to shift the
25624 row glyphs to the right. (In L2R rows, the corresponding
25625 left-shift effect is accomplished by setting row->x to a
25626 negative value, which won't work with R2L rows.)
25628 This must leave us with a positive value of WIDTH, since
25629 otherwise the call to move_it_in_display_line_to at the
25630 beginning of display_line would have got past the entire
25631 first glyph, and then it->current_x would have been
25632 greater or equal to it->first_visible_x. */
25633 if (it->current_x < it->first_visible_x)
25634 width -= it->first_visible_x - it->current_x;
25635 eassert (width > 0);
25637 glyph->charpos = CHARPOS (it->position);
25638 glyph->object = object;
25639 glyph->pixel_width = width;
25640 glyph->ascent = ascent;
25641 glyph->descent = height - ascent;
25642 glyph->voffset = it->voffset;
25643 glyph->type = STRETCH_GLYPH;
25644 glyph->avoid_cursor_p = it->avoid_cursor_p;
25645 glyph->multibyte_p = it->multibyte_p;
25646 if (it->glyph_row->reversed_p && area == TEXT_AREA)
25648 /* In R2L rows, the left and the right box edges need to be
25649 drawn in reverse direction. */
25650 glyph->right_box_line_p = it->start_of_box_run_p;
25651 glyph->left_box_line_p = it->end_of_box_run_p;
25653 else
25655 glyph->left_box_line_p = it->start_of_box_run_p;
25656 glyph->right_box_line_p = it->end_of_box_run_p;
25658 glyph->overlaps_vertically_p = 0;
25659 glyph->padding_p = 0;
25660 glyph->glyph_not_available_p = 0;
25661 glyph->face_id = it->face_id;
25662 glyph->u.stretch.ascent = ascent;
25663 glyph->u.stretch.height = height;
25664 glyph->slice.img = null_glyph_slice;
25665 glyph->font_type = FONT_TYPE_UNKNOWN;
25666 if (it->bidi_p)
25668 glyph->resolved_level = it->bidi_it.resolved_level;
25669 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
25670 glyph->bidi_type = it->bidi_it.type;
25672 else
25674 glyph->resolved_level = 0;
25675 glyph->bidi_type = UNKNOWN_BT;
25677 ++it->glyph_row->used[area];
25679 else
25680 IT_EXPAND_MATRIX_WIDTH (it, area);
25683 #endif /* HAVE_WINDOW_SYSTEM */
25685 /* Produce a stretch glyph for iterator IT. IT->object is the value
25686 of the glyph property displayed. The value must be a list
25687 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
25688 being recognized:
25690 1. `:width WIDTH' specifies that the space should be WIDTH *
25691 canonical char width wide. WIDTH may be an integer or floating
25692 point number.
25694 2. `:relative-width FACTOR' specifies that the width of the stretch
25695 should be computed from the width of the first character having the
25696 `glyph' property, and should be FACTOR times that width.
25698 3. `:align-to HPOS' specifies that the space should be wide enough
25699 to reach HPOS, a value in canonical character units.
25701 Exactly one of the above pairs must be present.
25703 4. `:height HEIGHT' specifies that the height of the stretch produced
25704 should be HEIGHT, measured in canonical character units.
25706 5. `:relative-height FACTOR' specifies that the height of the
25707 stretch should be FACTOR times the height of the characters having
25708 the glyph property.
25710 Either none or exactly one of 4 or 5 must be present.
25712 6. `:ascent ASCENT' specifies that ASCENT percent of the height
25713 of the stretch should be used for the ascent of the stretch.
25714 ASCENT must be in the range 0 <= ASCENT <= 100. */
25716 void
25717 produce_stretch_glyph (struct it *it)
25719 /* (space :width WIDTH :height HEIGHT ...) */
25720 Lisp_Object prop, plist;
25721 int width = 0, height = 0, align_to = -1;
25722 int zero_width_ok_p = 0;
25723 double tem;
25724 struct font *font = NULL;
25726 #ifdef HAVE_WINDOW_SYSTEM
25727 int ascent = 0;
25728 int zero_height_ok_p = 0;
25730 if (FRAME_WINDOW_P (it->f))
25732 struct face *face = FACE_FROM_ID (it->f, it->face_id);
25733 font = face->font ? face->font : FRAME_FONT (it->f);
25734 prepare_face_for_display (it->f, face);
25736 #endif
25738 /* List should start with `space'. */
25739 eassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
25740 plist = XCDR (it->object);
25742 /* Compute the width of the stretch. */
25743 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
25744 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
25746 /* Absolute width `:width WIDTH' specified and valid. */
25747 zero_width_ok_p = 1;
25748 width = (int)tem;
25750 #ifdef HAVE_WINDOW_SYSTEM
25751 else if (FRAME_WINDOW_P (it->f)
25752 && (prop = Fplist_get (plist, QCrelative_width), NUMVAL (prop) > 0))
25754 /* Relative width `:relative-width FACTOR' specified and valid.
25755 Compute the width of the characters having the `glyph'
25756 property. */
25757 struct it it2;
25758 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
25760 it2 = *it;
25761 if (it->multibyte_p)
25762 it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
25763 else
25765 it2.c = it2.char_to_display = *p, it2.len = 1;
25766 if (! ASCII_CHAR_P (it2.c))
25767 it2.char_to_display = BYTE8_TO_CHAR (it2.c);
25770 it2.glyph_row = NULL;
25771 it2.what = IT_CHARACTER;
25772 x_produce_glyphs (&it2);
25773 width = NUMVAL (prop) * it2.pixel_width;
25775 #endif /* HAVE_WINDOW_SYSTEM */
25776 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
25777 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
25779 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
25780 align_to = (align_to < 0
25782 : align_to - window_box_left_offset (it->w, TEXT_AREA));
25783 else if (align_to < 0)
25784 align_to = window_box_left_offset (it->w, TEXT_AREA);
25785 width = max (0, (int)tem + align_to - it->current_x);
25786 zero_width_ok_p = 1;
25788 else
25789 /* Nothing specified -> width defaults to canonical char width. */
25790 width = FRAME_COLUMN_WIDTH (it->f);
25792 if (width <= 0 && (width < 0 || !zero_width_ok_p))
25793 width = 1;
25795 #ifdef HAVE_WINDOW_SYSTEM
25796 /* Compute height. */
25797 if (FRAME_WINDOW_P (it->f))
25799 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
25800 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
25802 height = (int)tem;
25803 zero_height_ok_p = 1;
25805 else if (prop = Fplist_get (plist, QCrelative_height),
25806 NUMVAL (prop) > 0)
25807 height = FONT_HEIGHT (font) * NUMVAL (prop);
25808 else
25809 height = FONT_HEIGHT (font);
25811 if (height <= 0 && (height < 0 || !zero_height_ok_p))
25812 height = 1;
25814 /* Compute percentage of height used for ascent. If
25815 `:ascent ASCENT' is present and valid, use that. Otherwise,
25816 derive the ascent from the font in use. */
25817 if (prop = Fplist_get (plist, QCascent),
25818 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
25819 ascent = height * NUMVAL (prop) / 100.0;
25820 else if (!NILP (prop)
25821 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
25822 ascent = min (max (0, (int)tem), height);
25823 else
25824 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
25826 else
25827 #endif /* HAVE_WINDOW_SYSTEM */
25828 height = 1;
25830 if (width > 0 && it->line_wrap != TRUNCATE
25831 && it->current_x + width > it->last_visible_x)
25833 width = it->last_visible_x - it->current_x;
25834 #ifdef HAVE_WINDOW_SYSTEM
25835 /* Subtract one more pixel from the stretch width, but only on
25836 GUI frames, since on a TTY each glyph is one "pixel" wide. */
25837 width -= FRAME_WINDOW_P (it->f);
25838 #endif
25841 if (width > 0 && height > 0 && it->glyph_row)
25843 Lisp_Object o_object = it->object;
25844 Lisp_Object object = it->stack[it->sp - 1].string;
25845 int n = width;
25847 if (!STRINGP (object))
25848 object = it->w->contents;
25849 #ifdef HAVE_WINDOW_SYSTEM
25850 if (FRAME_WINDOW_P (it->f))
25851 append_stretch_glyph (it, object, width, height, ascent);
25852 else
25853 #endif
25855 it->object = object;
25856 it->char_to_display = ' ';
25857 it->pixel_width = it->len = 1;
25858 while (n--)
25859 tty_append_glyph (it);
25860 it->object = o_object;
25864 it->pixel_width = width;
25865 #ifdef HAVE_WINDOW_SYSTEM
25866 if (FRAME_WINDOW_P (it->f))
25868 it->ascent = it->phys_ascent = ascent;
25869 it->descent = it->phys_descent = height - it->ascent;
25870 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
25871 take_vertical_position_into_account (it);
25873 else
25874 #endif
25875 it->nglyphs = width;
25878 /* Get information about special display element WHAT in an
25879 environment described by IT. WHAT is one of IT_TRUNCATION or
25880 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
25881 non-null glyph_row member. This function ensures that fields like
25882 face_id, c, len of IT are left untouched. */
25884 static void
25885 produce_special_glyphs (struct it *it, enum display_element_type what)
25887 struct it temp_it;
25888 Lisp_Object gc;
25889 GLYPH glyph;
25891 temp_it = *it;
25892 temp_it.object = make_number (0);
25893 memset (&temp_it.current, 0, sizeof temp_it.current);
25895 if (what == IT_CONTINUATION)
25897 /* Continuation glyph. For R2L lines, we mirror it by hand. */
25898 if (it->bidi_it.paragraph_dir == R2L)
25899 SET_GLYPH_FROM_CHAR (glyph, '/');
25900 else
25901 SET_GLYPH_FROM_CHAR (glyph, '\\');
25902 if (it->dp
25903 && (gc = DISP_CONTINUE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
25905 /* FIXME: Should we mirror GC for R2L lines? */
25906 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
25907 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
25910 else if (what == IT_TRUNCATION)
25912 /* Truncation glyph. */
25913 SET_GLYPH_FROM_CHAR (glyph, '$');
25914 if (it->dp
25915 && (gc = DISP_TRUNC_GLYPH (it->dp), GLYPH_CODE_P (gc)))
25917 /* FIXME: Should we mirror GC for R2L lines? */
25918 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
25919 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
25922 else
25923 emacs_abort ();
25925 #ifdef HAVE_WINDOW_SYSTEM
25926 /* On a GUI frame, when the right fringe (left fringe for R2L rows)
25927 is turned off, we precede the truncation/continuation glyphs by a
25928 stretch glyph whose width is computed such that these special
25929 glyphs are aligned at the window margin, even when very different
25930 fonts are used in different glyph rows. */
25931 if (FRAME_WINDOW_P (temp_it.f)
25932 /* init_iterator calls this with it->glyph_row == NULL, and it
25933 wants only the pixel width of the truncation/continuation
25934 glyphs. */
25935 && temp_it.glyph_row
25936 /* insert_left_trunc_glyphs calls us at the beginning of the
25937 row, and it has its own calculation of the stretch glyph
25938 width. */
25939 && temp_it.glyph_row->used[TEXT_AREA] > 0
25940 && (temp_it.glyph_row->reversed_p
25941 ? WINDOW_LEFT_FRINGE_WIDTH (temp_it.w)
25942 : WINDOW_RIGHT_FRINGE_WIDTH (temp_it.w)) == 0)
25944 int stretch_width = temp_it.last_visible_x - temp_it.current_x;
25946 if (stretch_width > 0)
25948 struct face *face = FACE_FROM_ID (temp_it.f, temp_it.face_id);
25949 struct font *font =
25950 face->font ? face->font : FRAME_FONT (temp_it.f);
25951 int stretch_ascent =
25952 (((temp_it.ascent + temp_it.descent)
25953 * FONT_BASE (font)) / FONT_HEIGHT (font));
25955 append_stretch_glyph (&temp_it, make_number (0), stretch_width,
25956 temp_it.ascent + temp_it.descent,
25957 stretch_ascent);
25960 #endif
25962 temp_it.dp = NULL;
25963 temp_it.what = IT_CHARACTER;
25964 temp_it.c = temp_it.char_to_display = GLYPH_CHAR (glyph);
25965 temp_it.face_id = GLYPH_FACE (glyph);
25966 temp_it.len = CHAR_BYTES (temp_it.c);
25968 PRODUCE_GLYPHS (&temp_it);
25969 it->pixel_width = temp_it.pixel_width;
25970 it->nglyphs = temp_it.nglyphs;
25973 #ifdef HAVE_WINDOW_SYSTEM
25975 /* Calculate line-height and line-spacing properties.
25976 An integer value specifies explicit pixel value.
25977 A float value specifies relative value to current face height.
25978 A cons (float . face-name) specifies relative value to
25979 height of specified face font.
25981 Returns height in pixels, or nil. */
25984 static Lisp_Object
25985 calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
25986 int boff, int override)
25988 Lisp_Object face_name = Qnil;
25989 int ascent, descent, height;
25991 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
25992 return val;
25994 if (CONSP (val))
25996 face_name = XCAR (val);
25997 val = XCDR (val);
25998 if (!NUMBERP (val))
25999 val = make_number (1);
26000 if (NILP (face_name))
26002 height = it->ascent + it->descent;
26003 goto scale;
26007 if (NILP (face_name))
26009 font = FRAME_FONT (it->f);
26010 boff = FRAME_BASELINE_OFFSET (it->f);
26012 else if (EQ (face_name, Qt))
26014 override = 0;
26016 else
26018 int face_id;
26019 struct face *face;
26021 face_id = lookup_named_face (it->f, face_name, 0);
26022 if (face_id < 0)
26023 return make_number (-1);
26025 face = FACE_FROM_ID (it->f, face_id);
26026 font = face->font;
26027 if (font == NULL)
26028 return make_number (-1);
26029 boff = font->baseline_offset;
26030 if (font->vertical_centering)
26031 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
26034 ascent = FONT_BASE (font) + boff;
26035 descent = FONT_DESCENT (font) - boff;
26037 if (override)
26039 it->override_ascent = ascent;
26040 it->override_descent = descent;
26041 it->override_boff = boff;
26044 height = ascent + descent;
26046 scale:
26047 if (FLOATP (val))
26048 height = (int)(XFLOAT_DATA (val) * height);
26049 else if (INTEGERP (val))
26050 height *= XINT (val);
26052 return make_number (height);
26056 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
26057 is a face ID to be used for the glyph. FOR_NO_FONT is nonzero if
26058 and only if this is for a character for which no font was found.
26060 If the display method (it->glyphless_method) is
26061 GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
26062 length of the acronym or the hexadecimal string, UPPER_XOFF and
26063 UPPER_YOFF are pixel offsets for the upper part of the string,
26064 LOWER_XOFF and LOWER_YOFF are for the lower part.
26066 For the other display methods, LEN through LOWER_YOFF are zero. */
26068 static void
26069 append_glyphless_glyph (struct it *it, int face_id, int for_no_font, int len,
26070 short upper_xoff, short upper_yoff,
26071 short lower_xoff, short lower_yoff)
26073 struct glyph *glyph;
26074 enum glyph_row_area area = it->area;
26076 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
26077 if (glyph < it->glyph_row->glyphs[area + 1])
26079 /* If the glyph row is reversed, we need to prepend the glyph
26080 rather than append it. */
26081 if (it->glyph_row->reversed_p && area == TEXT_AREA)
26083 struct glyph *g;
26085 /* Make room for the additional glyph. */
26086 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
26087 g[1] = *g;
26088 glyph = it->glyph_row->glyphs[area];
26090 glyph->charpos = CHARPOS (it->position);
26091 glyph->object = it->object;
26092 glyph->pixel_width = it->pixel_width;
26093 glyph->ascent = it->ascent;
26094 glyph->descent = it->descent;
26095 glyph->voffset = it->voffset;
26096 glyph->type = GLYPHLESS_GLYPH;
26097 glyph->u.glyphless.method = it->glyphless_method;
26098 glyph->u.glyphless.for_no_font = for_no_font;
26099 glyph->u.glyphless.len = len;
26100 glyph->u.glyphless.ch = it->c;
26101 glyph->slice.glyphless.upper_xoff = upper_xoff;
26102 glyph->slice.glyphless.upper_yoff = upper_yoff;
26103 glyph->slice.glyphless.lower_xoff = lower_xoff;
26104 glyph->slice.glyphless.lower_yoff = lower_yoff;
26105 glyph->avoid_cursor_p = it->avoid_cursor_p;
26106 glyph->multibyte_p = it->multibyte_p;
26107 if (it->glyph_row->reversed_p && area == TEXT_AREA)
26109 /* In R2L rows, the left and the right box edges need to be
26110 drawn in reverse direction. */
26111 glyph->right_box_line_p = it->start_of_box_run_p;
26112 glyph->left_box_line_p = it->end_of_box_run_p;
26114 else
26116 glyph->left_box_line_p = it->start_of_box_run_p;
26117 glyph->right_box_line_p = it->end_of_box_run_p;
26119 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
26120 || it->phys_descent > it->descent);
26121 glyph->padding_p = 0;
26122 glyph->glyph_not_available_p = 0;
26123 glyph->face_id = face_id;
26124 glyph->font_type = FONT_TYPE_UNKNOWN;
26125 if (it->bidi_p)
26127 glyph->resolved_level = it->bidi_it.resolved_level;
26128 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
26129 glyph->bidi_type = it->bidi_it.type;
26131 ++it->glyph_row->used[area];
26133 else
26134 IT_EXPAND_MATRIX_WIDTH (it, area);
26138 /* Produce a glyph for a glyphless character for iterator IT.
26139 IT->glyphless_method specifies which method to use for displaying
26140 the character. See the description of enum
26141 glyphless_display_method in dispextern.h for the detail.
26143 FOR_NO_FONT is nonzero if and only if this is for a character for
26144 which no font was found. ACRONYM, if non-nil, is an acronym string
26145 for the character. */
26147 static void
26148 produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
26150 int face_id;
26151 struct face *face;
26152 struct font *font;
26153 int base_width, base_height, width, height;
26154 short upper_xoff, upper_yoff, lower_xoff, lower_yoff;
26155 int len;
26157 /* Get the metrics of the base font. We always refer to the current
26158 ASCII face. */
26159 face = FACE_FROM_ID (it->f, it->face_id)->ascii_face;
26160 font = face->font ? face->font : FRAME_FONT (it->f);
26161 it->ascent = FONT_BASE (font) + font->baseline_offset;
26162 it->descent = FONT_DESCENT (font) - font->baseline_offset;
26163 base_height = it->ascent + it->descent;
26164 base_width = font->average_width;
26166 face_id = merge_glyphless_glyph_face (it);
26168 if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
26170 it->pixel_width = THIN_SPACE_WIDTH;
26171 len = 0;
26172 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
26174 else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX)
26176 width = CHAR_WIDTH (it->c);
26177 if (width == 0)
26178 width = 1;
26179 else if (width > 4)
26180 width = 4;
26181 it->pixel_width = base_width * width;
26182 len = 0;
26183 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
26185 else
26187 char buf[7];
26188 const char *str;
26189 unsigned int code[6];
26190 int upper_len;
26191 int ascent, descent;
26192 struct font_metrics metrics_upper, metrics_lower;
26194 face = FACE_FROM_ID (it->f, face_id);
26195 font = face->font ? face->font : FRAME_FONT (it->f);
26196 prepare_face_for_display (it->f, face);
26198 if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM)
26200 if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
26201 acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
26202 if (CONSP (acronym))
26203 acronym = XCAR (acronym);
26204 str = STRINGP (acronym) ? SSDATA (acronym) : "";
26206 else
26208 eassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
26209 sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c);
26210 str = buf;
26212 for (len = 0; str[len] && ASCII_CHAR_P (str[len]) && len < 6; len++)
26213 code[len] = font->driver->encode_char (font, str[len]);
26214 upper_len = (len + 1) / 2;
26215 font->driver->text_extents (font, code, upper_len,
26216 &metrics_upper);
26217 font->driver->text_extents (font, code + upper_len, len - upper_len,
26218 &metrics_lower);
26222 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
26223 width = max (metrics_upper.width, metrics_lower.width) + 4;
26224 upper_xoff = upper_yoff = 2; /* the typical case */
26225 if (base_width >= width)
26227 /* Align the upper to the left, the lower to the right. */
26228 it->pixel_width = base_width;
26229 lower_xoff = base_width - 2 - metrics_lower.width;
26231 else
26233 /* Center the shorter one. */
26234 it->pixel_width = width;
26235 if (metrics_upper.width >= metrics_lower.width)
26236 lower_xoff = (width - metrics_lower.width) / 2;
26237 else
26239 /* FIXME: This code doesn't look right. It formerly was
26240 missing the "lower_xoff = 0;", which couldn't have
26241 been right since it left lower_xoff uninitialized. */
26242 lower_xoff = 0;
26243 upper_xoff = (width - metrics_upper.width) / 2;
26247 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
26248 top, bottom, and between upper and lower strings. */
26249 height = (metrics_upper.ascent + metrics_upper.descent
26250 + metrics_lower.ascent + metrics_lower.descent) + 5;
26251 /* Center vertically.
26252 H:base_height, D:base_descent
26253 h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent
26255 ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up
26256 descent = D - H/2 + h/2;
26257 lower_yoff = descent - 2 - ld;
26258 upper_yoff = lower_yoff - la - 1 - ud; */
26259 ascent = - (it->descent - (base_height + height + 1) / 2);
26260 descent = it->descent - (base_height - height) / 2;
26261 lower_yoff = descent - 2 - metrics_lower.descent;
26262 upper_yoff = (lower_yoff - metrics_lower.ascent - 1
26263 - metrics_upper.descent);
26264 /* Don't make the height shorter than the base height. */
26265 if (height > base_height)
26267 it->ascent = ascent;
26268 it->descent = descent;
26272 it->phys_ascent = it->ascent;
26273 it->phys_descent = it->descent;
26274 if (it->glyph_row)
26275 append_glyphless_glyph (it, face_id, for_no_font, len,
26276 upper_xoff, upper_yoff,
26277 lower_xoff, lower_yoff);
26278 it->nglyphs = 1;
26279 take_vertical_position_into_account (it);
26283 /* RIF:
26284 Produce glyphs/get display metrics for the display element IT is
26285 loaded with. See the description of struct it in dispextern.h
26286 for an overview of struct it. */
26288 void
26289 x_produce_glyphs (struct it *it)
26291 int extra_line_spacing = it->extra_line_spacing;
26293 it->glyph_not_available_p = 0;
26295 if (it->what == IT_CHARACTER)
26297 XChar2b char2b;
26298 struct face *face = FACE_FROM_ID (it->f, it->face_id);
26299 struct font *font = face->font;
26300 struct font_metrics *pcm = NULL;
26301 int boff; /* Baseline offset. */
26303 if (font == NULL)
26305 /* When no suitable font is found, display this character by
26306 the method specified in the first extra slot of
26307 Vglyphless_char_display. */
26308 Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
26310 eassert (it->what == IT_GLYPHLESS);
26311 produce_glyphless_glyph (it, 1, STRINGP (acronym) ? acronym : Qnil);
26312 goto done;
26315 boff = font->baseline_offset;
26316 if (font->vertical_centering)
26317 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
26319 if (it->char_to_display != '\n' && it->char_to_display != '\t')
26321 int stretched_p;
26323 it->nglyphs = 1;
26325 if (it->override_ascent >= 0)
26327 it->ascent = it->override_ascent;
26328 it->descent = it->override_descent;
26329 boff = it->override_boff;
26331 else
26333 it->ascent = FONT_BASE (font) + boff;
26334 it->descent = FONT_DESCENT (font) - boff;
26337 if (get_char_glyph_code (it->char_to_display, font, &char2b))
26339 pcm = get_per_char_metric (font, &char2b);
26340 if (pcm->width == 0
26341 && pcm->rbearing == 0 && pcm->lbearing == 0)
26342 pcm = NULL;
26345 if (pcm)
26347 it->phys_ascent = pcm->ascent + boff;
26348 it->phys_descent = pcm->descent - boff;
26349 it->pixel_width = pcm->width;
26351 else
26353 it->glyph_not_available_p = 1;
26354 it->phys_ascent = it->ascent;
26355 it->phys_descent = it->descent;
26356 it->pixel_width = font->space_width;
26359 if (it->constrain_row_ascent_descent_p)
26361 if (it->descent > it->max_descent)
26363 it->ascent += it->descent - it->max_descent;
26364 it->descent = it->max_descent;
26366 if (it->ascent > it->max_ascent)
26368 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
26369 it->ascent = it->max_ascent;
26371 it->phys_ascent = min (it->phys_ascent, it->ascent);
26372 it->phys_descent = min (it->phys_descent, it->descent);
26373 extra_line_spacing = 0;
26376 /* If this is a space inside a region of text with
26377 `space-width' property, change its width. */
26378 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
26379 if (stretched_p)
26380 it->pixel_width *= XFLOATINT (it->space_width);
26382 /* If face has a box, add the box thickness to the character
26383 height. If character has a box line to the left and/or
26384 right, add the box line width to the character's width. */
26385 if (face->box != FACE_NO_BOX)
26387 int thick = face->box_line_width;
26389 if (thick > 0)
26391 it->ascent += thick;
26392 it->descent += thick;
26394 else
26395 thick = -thick;
26397 if (it->start_of_box_run_p)
26398 it->pixel_width += thick;
26399 if (it->end_of_box_run_p)
26400 it->pixel_width += thick;
26403 /* If face has an overline, add the height of the overline
26404 (1 pixel) and a 1 pixel margin to the character height. */
26405 if (face->overline_p)
26406 it->ascent += overline_margin;
26408 if (it->constrain_row_ascent_descent_p)
26410 if (it->ascent > it->max_ascent)
26411 it->ascent = it->max_ascent;
26412 if (it->descent > it->max_descent)
26413 it->descent = it->max_descent;
26416 take_vertical_position_into_account (it);
26418 /* If we have to actually produce glyphs, do it. */
26419 if (it->glyph_row)
26421 if (stretched_p)
26423 /* Translate a space with a `space-width' property
26424 into a stretch glyph. */
26425 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
26426 / FONT_HEIGHT (font));
26427 append_stretch_glyph (it, it->object, it->pixel_width,
26428 it->ascent + it->descent, ascent);
26430 else
26431 append_glyph (it);
26433 /* If characters with lbearing or rbearing are displayed
26434 in this line, record that fact in a flag of the
26435 glyph row. This is used to optimize X output code. */
26436 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
26437 it->glyph_row->contains_overlapping_glyphs_p = 1;
26439 if (! stretched_p && it->pixel_width == 0)
26440 /* We assure that all visible glyphs have at least 1-pixel
26441 width. */
26442 it->pixel_width = 1;
26444 else if (it->char_to_display == '\n')
26446 /* A newline has no width, but we need the height of the
26447 line. But if previous part of the line sets a height,
26448 don't increase that height. */
26450 Lisp_Object height;
26451 Lisp_Object total_height = Qnil;
26453 it->override_ascent = -1;
26454 it->pixel_width = 0;
26455 it->nglyphs = 0;
26457 height = get_it_property (it, Qline_height);
26458 /* Split (line-height total-height) list. */
26459 if (CONSP (height)
26460 && CONSP (XCDR (height))
26461 && NILP (XCDR (XCDR (height))))
26463 total_height = XCAR (XCDR (height));
26464 height = XCAR (height);
26466 height = calc_line_height_property (it, height, font, boff, 1);
26468 if (it->override_ascent >= 0)
26470 it->ascent = it->override_ascent;
26471 it->descent = it->override_descent;
26472 boff = it->override_boff;
26474 else
26476 it->ascent = FONT_BASE (font) + boff;
26477 it->descent = FONT_DESCENT (font) - boff;
26480 if (EQ (height, Qt))
26482 if (it->descent > it->max_descent)
26484 it->ascent += it->descent - it->max_descent;
26485 it->descent = it->max_descent;
26487 if (it->ascent > it->max_ascent)
26489 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
26490 it->ascent = it->max_ascent;
26492 it->phys_ascent = min (it->phys_ascent, it->ascent);
26493 it->phys_descent = min (it->phys_descent, it->descent);
26494 it->constrain_row_ascent_descent_p = 1;
26495 extra_line_spacing = 0;
26497 else
26499 Lisp_Object spacing;
26501 it->phys_ascent = it->ascent;
26502 it->phys_descent = it->descent;
26504 if ((it->max_ascent > 0 || it->max_descent > 0)
26505 && face->box != FACE_NO_BOX
26506 && face->box_line_width > 0)
26508 it->ascent += face->box_line_width;
26509 it->descent += face->box_line_width;
26511 if (!NILP (height)
26512 && XINT (height) > it->ascent + it->descent)
26513 it->ascent = XINT (height) - it->descent;
26515 if (!NILP (total_height))
26516 spacing = calc_line_height_property (it, total_height, font, boff, 0);
26517 else
26519 spacing = get_it_property (it, Qline_spacing);
26520 spacing = calc_line_height_property (it, spacing, font, boff, 0);
26522 if (INTEGERP (spacing))
26524 extra_line_spacing = XINT (spacing);
26525 if (!NILP (total_height))
26526 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
26530 else /* i.e. (it->char_to_display == '\t') */
26532 if (font->space_width > 0)
26534 int tab_width = it->tab_width * font->space_width;
26535 int x = it->current_x + it->continuation_lines_width;
26536 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
26538 /* If the distance from the current position to the next tab
26539 stop is less than a space character width, use the
26540 tab stop after that. */
26541 if (next_tab_x - x < font->space_width)
26542 next_tab_x += tab_width;
26544 it->pixel_width = next_tab_x - x;
26545 it->nglyphs = 1;
26546 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
26547 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
26549 if (it->glyph_row)
26551 append_stretch_glyph (it, it->object, it->pixel_width,
26552 it->ascent + it->descent, it->ascent);
26555 else
26557 it->pixel_width = 0;
26558 it->nglyphs = 1;
26562 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
26564 /* A static composition.
26566 Note: A composition is represented as one glyph in the
26567 glyph matrix. There are no padding glyphs.
26569 Important note: pixel_width, ascent, and descent are the
26570 values of what is drawn by draw_glyphs (i.e. the values of
26571 the overall glyphs composed). */
26572 struct face *face = FACE_FROM_ID (it->f, it->face_id);
26573 int boff; /* baseline offset */
26574 struct composition *cmp = composition_table[it->cmp_it.id];
26575 int glyph_len = cmp->glyph_len;
26576 struct font *font = face->font;
26578 it->nglyphs = 1;
26580 /* If we have not yet calculated pixel size data of glyphs of
26581 the composition for the current face font, calculate them
26582 now. Theoretically, we have to check all fonts for the
26583 glyphs, but that requires much time and memory space. So,
26584 here we check only the font of the first glyph. This may
26585 lead to incorrect display, but it's very rare, and C-l
26586 (recenter-top-bottom) can correct the display anyway. */
26587 if (! cmp->font || cmp->font != font)
26589 /* Ascent and descent of the font of the first character
26590 of this composition (adjusted by baseline offset).
26591 Ascent and descent of overall glyphs should not be less
26592 than these, respectively. */
26593 int font_ascent, font_descent, font_height;
26594 /* Bounding box of the overall glyphs. */
26595 int leftmost, rightmost, lowest, highest;
26596 int lbearing, rbearing;
26597 int i, width, ascent, descent;
26598 int left_padded = 0, right_padded = 0;
26599 int c IF_LINT (= 0); /* cmp->glyph_len can't be zero; see Bug#8512 */
26600 XChar2b char2b;
26601 struct font_metrics *pcm;
26602 int font_not_found_p;
26603 ptrdiff_t pos;
26605 for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
26606 if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
26607 break;
26608 if (glyph_len < cmp->glyph_len)
26609 right_padded = 1;
26610 for (i = 0; i < glyph_len; i++)
26612 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
26613 break;
26614 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
26616 if (i > 0)
26617 left_padded = 1;
26619 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
26620 : IT_CHARPOS (*it));
26621 /* If no suitable font is found, use the default font. */
26622 font_not_found_p = font == NULL;
26623 if (font_not_found_p)
26625 face = face->ascii_face;
26626 font = face->font;
26628 boff = font->baseline_offset;
26629 if (font->vertical_centering)
26630 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
26631 font_ascent = FONT_BASE (font) + boff;
26632 font_descent = FONT_DESCENT (font) - boff;
26633 font_height = FONT_HEIGHT (font);
26635 cmp->font = font;
26637 pcm = NULL;
26638 if (! font_not_found_p)
26640 get_char_face_and_encoding (it->f, c, it->face_id,
26641 &char2b, 0);
26642 pcm = get_per_char_metric (font, &char2b);
26645 /* Initialize the bounding box. */
26646 if (pcm)
26648 width = cmp->glyph_len > 0 ? pcm->width : 0;
26649 ascent = pcm->ascent;
26650 descent = pcm->descent;
26651 lbearing = pcm->lbearing;
26652 rbearing = pcm->rbearing;
26654 else
26656 width = cmp->glyph_len > 0 ? font->space_width : 0;
26657 ascent = FONT_BASE (font);
26658 descent = FONT_DESCENT (font);
26659 lbearing = 0;
26660 rbearing = width;
26663 rightmost = width;
26664 leftmost = 0;
26665 lowest = - descent + boff;
26666 highest = ascent + boff;
26668 if (! font_not_found_p
26669 && font->default_ascent
26670 && CHAR_TABLE_P (Vuse_default_ascent)
26671 && !NILP (Faref (Vuse_default_ascent,
26672 make_number (it->char_to_display))))
26673 highest = font->default_ascent + boff;
26675 /* Draw the first glyph at the normal position. It may be
26676 shifted to right later if some other glyphs are drawn
26677 at the left. */
26678 cmp->offsets[i * 2] = 0;
26679 cmp->offsets[i * 2 + 1] = boff;
26680 cmp->lbearing = lbearing;
26681 cmp->rbearing = rbearing;
26683 /* Set cmp->offsets for the remaining glyphs. */
26684 for (i++; i < glyph_len; i++)
26686 int left, right, btm, top;
26687 int ch = COMPOSITION_GLYPH (cmp, i);
26688 int face_id;
26689 struct face *this_face;
26691 if (ch == '\t')
26692 ch = ' ';
26693 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
26694 this_face = FACE_FROM_ID (it->f, face_id);
26695 font = this_face->font;
26697 if (font == NULL)
26698 pcm = NULL;
26699 else
26701 get_char_face_and_encoding (it->f, ch, face_id,
26702 &char2b, 0);
26703 pcm = get_per_char_metric (font, &char2b);
26705 if (! pcm)
26706 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
26707 else
26709 width = pcm->width;
26710 ascent = pcm->ascent;
26711 descent = pcm->descent;
26712 lbearing = pcm->lbearing;
26713 rbearing = pcm->rbearing;
26714 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
26716 /* Relative composition with or without
26717 alternate chars. */
26718 left = (leftmost + rightmost - width) / 2;
26719 btm = - descent + boff;
26720 if (font->relative_compose
26721 && (! CHAR_TABLE_P (Vignore_relative_composition)
26722 || NILP (Faref (Vignore_relative_composition,
26723 make_number (ch)))))
26726 if (- descent >= font->relative_compose)
26727 /* One extra pixel between two glyphs. */
26728 btm = highest + 1;
26729 else if (ascent <= 0)
26730 /* One extra pixel between two glyphs. */
26731 btm = lowest - 1 - ascent - descent;
26734 else
26736 /* A composition rule is specified by an integer
26737 value that encodes global and new reference
26738 points (GREF and NREF). GREF and NREF are
26739 specified by numbers as below:
26741 0---1---2 -- ascent
26745 9--10--11 -- center
26747 ---3---4---5--- baseline
26749 6---7---8 -- descent
26751 int rule = COMPOSITION_RULE (cmp, i);
26752 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
26754 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
26755 grefx = gref % 3, nrefx = nref % 3;
26756 grefy = gref / 3, nrefy = nref / 3;
26757 if (xoff)
26758 xoff = font_height * (xoff - 128) / 256;
26759 if (yoff)
26760 yoff = font_height * (yoff - 128) / 256;
26762 left = (leftmost
26763 + grefx * (rightmost - leftmost) / 2
26764 - nrefx * width / 2
26765 + xoff);
26767 btm = ((grefy == 0 ? highest
26768 : grefy == 1 ? 0
26769 : grefy == 2 ? lowest
26770 : (highest + lowest) / 2)
26771 - (nrefy == 0 ? ascent + descent
26772 : nrefy == 1 ? descent - boff
26773 : nrefy == 2 ? 0
26774 : (ascent + descent) / 2)
26775 + yoff);
26778 cmp->offsets[i * 2] = left;
26779 cmp->offsets[i * 2 + 1] = btm + descent;
26781 /* Update the bounding box of the overall glyphs. */
26782 if (width > 0)
26784 right = left + width;
26785 if (left < leftmost)
26786 leftmost = left;
26787 if (right > rightmost)
26788 rightmost = right;
26790 top = btm + descent + ascent;
26791 if (top > highest)
26792 highest = top;
26793 if (btm < lowest)
26794 lowest = btm;
26796 if (cmp->lbearing > left + lbearing)
26797 cmp->lbearing = left + lbearing;
26798 if (cmp->rbearing < left + rbearing)
26799 cmp->rbearing = left + rbearing;
26803 /* If there are glyphs whose x-offsets are negative,
26804 shift all glyphs to the right and make all x-offsets
26805 non-negative. */
26806 if (leftmost < 0)
26808 for (i = 0; i < cmp->glyph_len; i++)
26809 cmp->offsets[i * 2] -= leftmost;
26810 rightmost -= leftmost;
26811 cmp->lbearing -= leftmost;
26812 cmp->rbearing -= leftmost;
26815 if (left_padded && cmp->lbearing < 0)
26817 for (i = 0; i < cmp->glyph_len; i++)
26818 cmp->offsets[i * 2] -= cmp->lbearing;
26819 rightmost -= cmp->lbearing;
26820 cmp->rbearing -= cmp->lbearing;
26821 cmp->lbearing = 0;
26823 if (right_padded && rightmost < cmp->rbearing)
26825 rightmost = cmp->rbearing;
26828 cmp->pixel_width = rightmost;
26829 cmp->ascent = highest;
26830 cmp->descent = - lowest;
26831 if (cmp->ascent < font_ascent)
26832 cmp->ascent = font_ascent;
26833 if (cmp->descent < font_descent)
26834 cmp->descent = font_descent;
26837 if (it->glyph_row
26838 && (cmp->lbearing < 0
26839 || cmp->rbearing > cmp->pixel_width))
26840 it->glyph_row->contains_overlapping_glyphs_p = 1;
26842 it->pixel_width = cmp->pixel_width;
26843 it->ascent = it->phys_ascent = cmp->ascent;
26844 it->descent = it->phys_descent = cmp->descent;
26845 if (face->box != FACE_NO_BOX)
26847 int thick = face->box_line_width;
26849 if (thick > 0)
26851 it->ascent += thick;
26852 it->descent += thick;
26854 else
26855 thick = - thick;
26857 if (it->start_of_box_run_p)
26858 it->pixel_width += thick;
26859 if (it->end_of_box_run_p)
26860 it->pixel_width += thick;
26863 /* If face has an overline, add the height of the overline
26864 (1 pixel) and a 1 pixel margin to the character height. */
26865 if (face->overline_p)
26866 it->ascent += overline_margin;
26868 take_vertical_position_into_account (it);
26869 if (it->ascent < 0)
26870 it->ascent = 0;
26871 if (it->descent < 0)
26872 it->descent = 0;
26874 if (it->glyph_row && cmp->glyph_len > 0)
26875 append_composite_glyph (it);
26877 else if (it->what == IT_COMPOSITION)
26879 /* A dynamic (automatic) composition. */
26880 struct face *face = FACE_FROM_ID (it->f, it->face_id);
26881 Lisp_Object gstring;
26882 struct font_metrics metrics;
26884 it->nglyphs = 1;
26886 gstring = composition_gstring_from_id (it->cmp_it.id);
26887 it->pixel_width
26888 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
26889 &metrics);
26890 if (it->glyph_row
26891 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
26892 it->glyph_row->contains_overlapping_glyphs_p = 1;
26893 it->ascent = it->phys_ascent = metrics.ascent;
26894 it->descent = it->phys_descent = metrics.descent;
26895 if (face->box != FACE_NO_BOX)
26897 int thick = face->box_line_width;
26899 if (thick > 0)
26901 it->ascent += thick;
26902 it->descent += thick;
26904 else
26905 thick = - thick;
26907 if (it->start_of_box_run_p)
26908 it->pixel_width += thick;
26909 if (it->end_of_box_run_p)
26910 it->pixel_width += thick;
26912 /* If face has an overline, add the height of the overline
26913 (1 pixel) and a 1 pixel margin to the character height. */
26914 if (face->overline_p)
26915 it->ascent += overline_margin;
26916 take_vertical_position_into_account (it);
26917 if (it->ascent < 0)
26918 it->ascent = 0;
26919 if (it->descent < 0)
26920 it->descent = 0;
26922 if (it->glyph_row)
26923 append_composite_glyph (it);
26925 else if (it->what == IT_GLYPHLESS)
26926 produce_glyphless_glyph (it, 0, Qnil);
26927 else if (it->what == IT_IMAGE)
26928 produce_image_glyph (it);
26929 else if (it->what == IT_STRETCH)
26930 produce_stretch_glyph (it);
26932 done:
26933 /* Accumulate dimensions. Note: can't assume that it->descent > 0
26934 because this isn't true for images with `:ascent 100'. */
26935 eassert (it->ascent >= 0 && it->descent >= 0);
26936 if (it->area == TEXT_AREA)
26937 it->current_x += it->pixel_width;
26939 if (extra_line_spacing > 0)
26941 it->descent += extra_line_spacing;
26942 if (extra_line_spacing > it->max_extra_line_spacing)
26943 it->max_extra_line_spacing = extra_line_spacing;
26946 it->max_ascent = max (it->max_ascent, it->ascent);
26947 it->max_descent = max (it->max_descent, it->descent);
26948 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
26949 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
26952 /* EXPORT for RIF:
26953 Output LEN glyphs starting at START at the nominal cursor position.
26954 Advance the nominal cursor over the text. UPDATED_ROW is the glyph row
26955 being updated, and UPDATED_AREA is the area of that row being updated. */
26957 void
26958 x_write_glyphs (struct window *w, struct glyph_row *updated_row,
26959 struct glyph *start, enum glyph_row_area updated_area, int len)
26961 int x, hpos, chpos = w->phys_cursor.hpos;
26963 eassert (updated_row);
26964 /* When the window is hscrolled, cursor hpos can legitimately be out
26965 of bounds, but we draw the cursor at the corresponding window
26966 margin in that case. */
26967 if (!updated_row->reversed_p && chpos < 0)
26968 chpos = 0;
26969 if (updated_row->reversed_p && chpos >= updated_row->used[TEXT_AREA])
26970 chpos = updated_row->used[TEXT_AREA] - 1;
26972 block_input ();
26974 /* Write glyphs. */
26976 hpos = start - updated_row->glyphs[updated_area];
26977 x = draw_glyphs (w, w->output_cursor.x,
26978 updated_row, updated_area,
26979 hpos, hpos + len,
26980 DRAW_NORMAL_TEXT, 0);
26982 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
26983 if (updated_area == TEXT_AREA
26984 && w->phys_cursor_on_p
26985 && w->phys_cursor.vpos == w->output_cursor.vpos
26986 && chpos >= hpos
26987 && chpos < hpos + len)
26988 w->phys_cursor_on_p = 0;
26990 unblock_input ();
26992 /* Advance the output cursor. */
26993 w->output_cursor.hpos += len;
26994 w->output_cursor.x = x;
26998 /* EXPORT for RIF:
26999 Insert LEN glyphs from START at the nominal cursor position. */
27001 void
27002 x_insert_glyphs (struct window *w, struct glyph_row *updated_row,
27003 struct glyph *start, enum glyph_row_area updated_area, int len)
27005 struct frame *f;
27006 int line_height, shift_by_width, shifted_region_width;
27007 struct glyph_row *row;
27008 struct glyph *glyph;
27009 int frame_x, frame_y;
27010 ptrdiff_t hpos;
27012 eassert (updated_row);
27013 block_input ();
27014 f = XFRAME (WINDOW_FRAME (w));
27016 /* Get the height of the line we are in. */
27017 row = updated_row;
27018 line_height = row->height;
27020 /* Get the width of the glyphs to insert. */
27021 shift_by_width = 0;
27022 for (glyph = start; glyph < start + len; ++glyph)
27023 shift_by_width += glyph->pixel_width;
27025 /* Get the width of the region to shift right. */
27026 shifted_region_width = (window_box_width (w, updated_area)
27027 - w->output_cursor.x
27028 - shift_by_width);
27030 /* Shift right. */
27031 frame_x = window_box_left (w, updated_area) + w->output_cursor.x;
27032 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, w->output_cursor.y);
27034 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
27035 line_height, shift_by_width);
27037 /* Write the glyphs. */
27038 hpos = start - row->glyphs[updated_area];
27039 draw_glyphs (w, w->output_cursor.x, row, updated_area,
27040 hpos, hpos + len,
27041 DRAW_NORMAL_TEXT, 0);
27043 /* Advance the output cursor. */
27044 w->output_cursor.hpos += len;
27045 w->output_cursor.x += shift_by_width;
27046 unblock_input ();
27050 /* EXPORT for RIF:
27051 Erase the current text line from the nominal cursor position
27052 (inclusive) to pixel column TO_X (exclusive). The idea is that
27053 everything from TO_X onward is already erased.
27055 TO_X is a pixel position relative to UPDATED_AREA of currently
27056 updated window W. TO_X == -1 means clear to the end of this area. */
27058 void
27059 x_clear_end_of_line (struct window *w, struct glyph_row *updated_row,
27060 enum glyph_row_area updated_area, int to_x)
27062 struct frame *f;
27063 int max_x, min_y, max_y;
27064 int from_x, from_y, to_y;
27066 eassert (updated_row);
27067 f = XFRAME (w->frame);
27069 if (updated_row->full_width_p)
27070 max_x = (WINDOW_PIXEL_WIDTH (w)
27071 - (updated_row->mode_line_p ? WINDOW_RIGHT_DIVIDER_WIDTH (w) : 0));
27072 else
27073 max_x = window_box_width (w, updated_area);
27074 max_y = window_text_bottom_y (w);
27076 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
27077 of window. For TO_X > 0, truncate to end of drawing area. */
27078 if (to_x == 0)
27079 return;
27080 else if (to_x < 0)
27081 to_x = max_x;
27082 else
27083 to_x = min (to_x, max_x);
27085 to_y = min (max_y, w->output_cursor.y + updated_row->height);
27087 /* Notice if the cursor will be cleared by this operation. */
27088 if (!updated_row->full_width_p)
27089 notice_overwritten_cursor (w, updated_area,
27090 w->output_cursor.x, -1,
27091 updated_row->y,
27092 MATRIX_ROW_BOTTOM_Y (updated_row));
27094 from_x = w->output_cursor.x;
27096 /* Translate to frame coordinates. */
27097 if (updated_row->full_width_p)
27099 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
27100 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
27102 else
27104 int area_left = window_box_left (w, updated_area);
27105 from_x += area_left;
27106 to_x += area_left;
27109 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
27110 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, w->output_cursor.y));
27111 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
27113 /* Prevent inadvertently clearing to end of the X window. */
27114 if (to_x > from_x && to_y > from_y)
27116 block_input ();
27117 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
27118 to_x - from_x, to_y - from_y);
27119 unblock_input ();
27123 #endif /* HAVE_WINDOW_SYSTEM */
27127 /***********************************************************************
27128 Cursor types
27129 ***********************************************************************/
27131 /* Value is the internal representation of the specified cursor type
27132 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
27133 of the bar cursor. */
27135 static enum text_cursor_kinds
27136 get_specified_cursor_type (Lisp_Object arg, int *width)
27138 enum text_cursor_kinds type;
27140 if (NILP (arg))
27141 return NO_CURSOR;
27143 if (EQ (arg, Qbox))
27144 return FILLED_BOX_CURSOR;
27146 if (EQ (arg, Qhollow))
27147 return HOLLOW_BOX_CURSOR;
27149 if (EQ (arg, Qbar))
27151 *width = 2;
27152 return BAR_CURSOR;
27155 if (CONSP (arg)
27156 && EQ (XCAR (arg), Qbar)
27157 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
27159 *width = XINT (XCDR (arg));
27160 return BAR_CURSOR;
27163 if (EQ (arg, Qhbar))
27165 *width = 2;
27166 return HBAR_CURSOR;
27169 if (CONSP (arg)
27170 && EQ (XCAR (arg), Qhbar)
27171 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
27173 *width = XINT (XCDR (arg));
27174 return HBAR_CURSOR;
27177 /* Treat anything unknown as "hollow box cursor".
27178 It was bad to signal an error; people have trouble fixing
27179 .Xdefaults with Emacs, when it has something bad in it. */
27180 type = HOLLOW_BOX_CURSOR;
27182 return type;
27185 /* Set the default cursor types for specified frame. */
27186 void
27187 set_frame_cursor_types (struct frame *f, Lisp_Object arg)
27189 int width = 1;
27190 Lisp_Object tem;
27192 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
27193 FRAME_CURSOR_WIDTH (f) = width;
27195 /* By default, set up the blink-off state depending on the on-state. */
27197 tem = Fassoc (arg, Vblink_cursor_alist);
27198 if (!NILP (tem))
27200 FRAME_BLINK_OFF_CURSOR (f)
27201 = get_specified_cursor_type (XCDR (tem), &width);
27202 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
27204 else
27205 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
27207 /* Make sure the cursor gets redrawn. */
27208 f->cursor_type_changed = 1;
27212 #ifdef HAVE_WINDOW_SYSTEM
27214 /* Return the cursor we want to be displayed in window W. Return
27215 width of bar/hbar cursor through WIDTH arg. Return with
27216 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
27217 (i.e. if the `system caret' should track this cursor).
27219 In a mini-buffer window, we want the cursor only to appear if we
27220 are reading input from this window. For the selected window, we
27221 want the cursor type given by the frame parameter or buffer local
27222 setting of cursor-type. If explicitly marked off, draw no cursor.
27223 In all other cases, we want a hollow box cursor. */
27225 static enum text_cursor_kinds
27226 get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
27227 int *active_cursor)
27229 struct frame *f = XFRAME (w->frame);
27230 struct buffer *b = XBUFFER (w->contents);
27231 int cursor_type = DEFAULT_CURSOR;
27232 Lisp_Object alt_cursor;
27233 int non_selected = 0;
27235 *active_cursor = 1;
27237 /* Echo area */
27238 if (cursor_in_echo_area
27239 && FRAME_HAS_MINIBUF_P (f)
27240 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
27242 if (w == XWINDOW (echo_area_window))
27244 if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
27246 *width = FRAME_CURSOR_WIDTH (f);
27247 return FRAME_DESIRED_CURSOR (f);
27249 else
27250 return get_specified_cursor_type (BVAR (b, cursor_type), width);
27253 *active_cursor = 0;
27254 non_selected = 1;
27257 /* Detect a nonselected window or nonselected frame. */
27258 else if (w != XWINDOW (f->selected_window)
27259 || f != FRAME_DISPLAY_INFO (f)->x_highlight_frame)
27261 *active_cursor = 0;
27263 if (MINI_WINDOW_P (w) && minibuf_level == 0)
27264 return NO_CURSOR;
27266 non_selected = 1;
27269 /* Never display a cursor in a window in which cursor-type is nil. */
27270 if (NILP (BVAR (b, cursor_type)))
27271 return NO_CURSOR;
27273 /* Get the normal cursor type for this window. */
27274 if (EQ (BVAR (b, cursor_type), Qt))
27276 cursor_type = FRAME_DESIRED_CURSOR (f);
27277 *width = FRAME_CURSOR_WIDTH (f);
27279 else
27280 cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
27282 /* Use cursor-in-non-selected-windows instead
27283 for non-selected window or frame. */
27284 if (non_selected)
27286 alt_cursor = BVAR (b, cursor_in_non_selected_windows);
27287 if (!EQ (Qt, alt_cursor))
27288 return get_specified_cursor_type (alt_cursor, width);
27289 /* t means modify the normal cursor type. */
27290 if (cursor_type == FILLED_BOX_CURSOR)
27291 cursor_type = HOLLOW_BOX_CURSOR;
27292 else if (cursor_type == BAR_CURSOR && *width > 1)
27293 --*width;
27294 return cursor_type;
27297 /* Use normal cursor if not blinked off. */
27298 if (!w->cursor_off_p)
27300 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
27302 if (cursor_type == FILLED_BOX_CURSOR)
27304 /* Using a block cursor on large images can be very annoying.
27305 So use a hollow cursor for "large" images.
27306 If image is not transparent (no mask), also use hollow cursor. */
27307 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
27308 if (img != NULL && IMAGEP (img->spec))
27310 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
27311 where N = size of default frame font size.
27312 This should cover most of the "tiny" icons people may use. */
27313 if (!img->mask
27314 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
27315 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
27316 cursor_type = HOLLOW_BOX_CURSOR;
27319 else if (cursor_type != NO_CURSOR)
27321 /* Display current only supports BOX and HOLLOW cursors for images.
27322 So for now, unconditionally use a HOLLOW cursor when cursor is
27323 not a solid box cursor. */
27324 cursor_type = HOLLOW_BOX_CURSOR;
27327 return cursor_type;
27330 /* Cursor is blinked off, so determine how to "toggle" it. */
27332 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
27333 if ((alt_cursor = Fassoc (BVAR (b, cursor_type), Vblink_cursor_alist), !NILP (alt_cursor)))
27334 return get_specified_cursor_type (XCDR (alt_cursor), width);
27336 /* Then see if frame has specified a specific blink off cursor type. */
27337 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
27339 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
27340 return FRAME_BLINK_OFF_CURSOR (f);
27343 #if 0
27344 /* Some people liked having a permanently visible blinking cursor,
27345 while others had very strong opinions against it. So it was
27346 decided to remove it. KFS 2003-09-03 */
27348 /* Finally perform built-in cursor blinking:
27349 filled box <-> hollow box
27350 wide [h]bar <-> narrow [h]bar
27351 narrow [h]bar <-> no cursor
27352 other type <-> no cursor */
27354 if (cursor_type == FILLED_BOX_CURSOR)
27355 return HOLLOW_BOX_CURSOR;
27357 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
27359 *width = 1;
27360 return cursor_type;
27362 #endif
27364 return NO_CURSOR;
27368 /* Notice when the text cursor of window W has been completely
27369 overwritten by a drawing operation that outputs glyphs in AREA
27370 starting at X0 and ending at X1 in the line starting at Y0 and
27371 ending at Y1. X coordinates are area-relative. X1 < 0 means all
27372 the rest of the line after X0 has been written. Y coordinates
27373 are window-relative. */
27375 static void
27376 notice_overwritten_cursor (struct window *w, enum glyph_row_area area,
27377 int x0, int x1, int y0, int y1)
27379 int cx0, cx1, cy0, cy1;
27380 struct glyph_row *row;
27382 if (!w->phys_cursor_on_p)
27383 return;
27384 if (area != TEXT_AREA)
27385 return;
27387 if (w->phys_cursor.vpos < 0
27388 || w->phys_cursor.vpos >= w->current_matrix->nrows
27389 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
27390 !(row->enabled_p && MATRIX_ROW_DISPLAYS_TEXT_P (row))))
27391 return;
27393 if (row->cursor_in_fringe_p)
27395 row->cursor_in_fringe_p = 0;
27396 draw_fringe_bitmap (w, row, row->reversed_p);
27397 w->phys_cursor_on_p = 0;
27398 return;
27401 cx0 = w->phys_cursor.x;
27402 cx1 = cx0 + w->phys_cursor_width;
27403 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
27404 return;
27406 /* The cursor image will be completely removed from the
27407 screen if the output area intersects the cursor area in
27408 y-direction. When we draw in [y0 y1[, and some part of
27409 the cursor is at y < y0, that part must have been drawn
27410 before. When scrolling, the cursor is erased before
27411 actually scrolling, so we don't come here. When not
27412 scrolling, the rows above the old cursor row must have
27413 changed, and in this case these rows must have written
27414 over the cursor image.
27416 Likewise if part of the cursor is below y1, with the
27417 exception of the cursor being in the first blank row at
27418 the buffer and window end because update_text_area
27419 doesn't draw that row. (Except when it does, but
27420 that's handled in update_text_area.) */
27422 cy0 = w->phys_cursor.y;
27423 cy1 = cy0 + w->phys_cursor_height;
27424 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
27425 return;
27427 w->phys_cursor_on_p = 0;
27430 #endif /* HAVE_WINDOW_SYSTEM */
27433 /************************************************************************
27434 Mouse Face
27435 ************************************************************************/
27437 #ifdef HAVE_WINDOW_SYSTEM
27439 /* EXPORT for RIF:
27440 Fix the display of area AREA of overlapping row ROW in window W
27441 with respect to the overlapping part OVERLAPS. */
27443 void
27444 x_fix_overlapping_area (struct window *w, struct glyph_row *row,
27445 enum glyph_row_area area, int overlaps)
27447 int i, x;
27449 block_input ();
27451 x = 0;
27452 for (i = 0; i < row->used[area];)
27454 if (row->glyphs[area][i].overlaps_vertically_p)
27456 int start = i, start_x = x;
27460 x += row->glyphs[area][i].pixel_width;
27461 ++i;
27463 while (i < row->used[area]
27464 && row->glyphs[area][i].overlaps_vertically_p);
27466 draw_glyphs (w, start_x, row, area,
27467 start, i,
27468 DRAW_NORMAL_TEXT, overlaps);
27470 else
27472 x += row->glyphs[area][i].pixel_width;
27473 ++i;
27477 unblock_input ();
27481 /* EXPORT:
27482 Draw the cursor glyph of window W in glyph row ROW. See the
27483 comment of draw_glyphs for the meaning of HL. */
27485 void
27486 draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
27487 enum draw_glyphs_face hl)
27489 /* If cursor hpos is out of bounds, don't draw garbage. This can
27490 happen in mini-buffer windows when switching between echo area
27491 glyphs and mini-buffer. */
27492 if ((row->reversed_p
27493 ? (w->phys_cursor.hpos >= 0)
27494 : (w->phys_cursor.hpos < row->used[TEXT_AREA])))
27496 int on_p = w->phys_cursor_on_p;
27497 int x1;
27498 int hpos = w->phys_cursor.hpos;
27500 /* When the window is hscrolled, cursor hpos can legitimately be
27501 out of bounds, but we draw the cursor at the corresponding
27502 window margin in that case. */
27503 if (!row->reversed_p && hpos < 0)
27504 hpos = 0;
27505 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
27506 hpos = row->used[TEXT_AREA] - 1;
27508 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA, hpos, hpos + 1,
27509 hl, 0);
27510 w->phys_cursor_on_p = on_p;
27512 if (hl == DRAW_CURSOR)
27513 w->phys_cursor_width = x1 - w->phys_cursor.x;
27514 /* When we erase the cursor, and ROW is overlapped by other
27515 rows, make sure that these overlapping parts of other rows
27516 are redrawn. */
27517 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
27519 w->phys_cursor_width = x1 - w->phys_cursor.x;
27521 if (row > w->current_matrix->rows
27522 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
27523 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
27524 OVERLAPS_ERASED_CURSOR);
27526 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
27527 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
27528 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
27529 OVERLAPS_ERASED_CURSOR);
27535 /* Erase the image of a cursor of window W from the screen. */
27537 void
27538 erase_phys_cursor (struct window *w)
27540 struct frame *f = XFRAME (w->frame);
27541 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
27542 int hpos = w->phys_cursor.hpos;
27543 int vpos = w->phys_cursor.vpos;
27544 int mouse_face_here_p = 0;
27545 struct glyph_matrix *active_glyphs = w->current_matrix;
27546 struct glyph_row *cursor_row;
27547 struct glyph *cursor_glyph;
27548 enum draw_glyphs_face hl;
27550 /* No cursor displayed or row invalidated => nothing to do on the
27551 screen. */
27552 if (w->phys_cursor_type == NO_CURSOR)
27553 goto mark_cursor_off;
27555 /* VPOS >= active_glyphs->nrows means that window has been resized.
27556 Don't bother to erase the cursor. */
27557 if (vpos >= active_glyphs->nrows)
27558 goto mark_cursor_off;
27560 /* If row containing cursor is marked invalid, there is nothing we
27561 can do. */
27562 cursor_row = MATRIX_ROW (active_glyphs, vpos);
27563 if (!cursor_row->enabled_p)
27564 goto mark_cursor_off;
27566 /* If line spacing is > 0, old cursor may only be partially visible in
27567 window after split-window. So adjust visible height. */
27568 cursor_row->visible_height = min (cursor_row->visible_height,
27569 window_text_bottom_y (w) - cursor_row->y);
27571 /* If row is completely invisible, don't attempt to delete a cursor which
27572 isn't there. This can happen if cursor is at top of a window, and
27573 we switch to a buffer with a header line in that window. */
27574 if (cursor_row->visible_height <= 0)
27575 goto mark_cursor_off;
27577 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
27578 if (cursor_row->cursor_in_fringe_p)
27580 cursor_row->cursor_in_fringe_p = 0;
27581 draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
27582 goto mark_cursor_off;
27585 /* This can happen when the new row is shorter than the old one.
27586 In this case, either draw_glyphs or clear_end_of_line
27587 should have cleared the cursor. Note that we wouldn't be
27588 able to erase the cursor in this case because we don't have a
27589 cursor glyph at hand. */
27590 if ((cursor_row->reversed_p
27591 ? (w->phys_cursor.hpos < 0)
27592 : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
27593 goto mark_cursor_off;
27595 /* When the window is hscrolled, cursor hpos can legitimately be out
27596 of bounds, but we draw the cursor at the corresponding window
27597 margin in that case. */
27598 if (!cursor_row->reversed_p && hpos < 0)
27599 hpos = 0;
27600 if (cursor_row->reversed_p && hpos >= cursor_row->used[TEXT_AREA])
27601 hpos = cursor_row->used[TEXT_AREA] - 1;
27603 /* If the cursor is in the mouse face area, redisplay that when
27604 we clear the cursor. */
27605 if (! NILP (hlinfo->mouse_face_window)
27606 && coords_in_mouse_face_p (w, hpos, vpos)
27607 /* Don't redraw the cursor's spot in mouse face if it is at the
27608 end of a line (on a newline). The cursor appears there, but
27609 mouse highlighting does not. */
27610 && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
27611 mouse_face_here_p = 1;
27613 /* Maybe clear the display under the cursor. */
27614 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
27616 int x, y;
27617 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
27618 int width;
27620 cursor_glyph = get_phys_cursor_glyph (w);
27621 if (cursor_glyph == NULL)
27622 goto mark_cursor_off;
27624 width = cursor_glyph->pixel_width;
27625 x = w->phys_cursor.x;
27626 if (x < 0)
27628 width += x;
27629 x = 0;
27631 width = min (width, window_box_width (w, TEXT_AREA) - x);
27632 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
27633 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
27635 if (width > 0)
27636 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
27639 /* Erase the cursor by redrawing the character underneath it. */
27640 if (mouse_face_here_p)
27641 hl = DRAW_MOUSE_FACE;
27642 else
27643 hl = DRAW_NORMAL_TEXT;
27644 draw_phys_cursor_glyph (w, cursor_row, hl);
27646 mark_cursor_off:
27647 w->phys_cursor_on_p = 0;
27648 w->phys_cursor_type = NO_CURSOR;
27652 /* EXPORT:
27653 Display or clear cursor of window W. If ON is zero, clear the
27654 cursor. If it is non-zero, display the cursor. If ON is nonzero,
27655 where to put the cursor is specified by HPOS, VPOS, X and Y. */
27657 void
27658 display_and_set_cursor (struct window *w, bool on,
27659 int hpos, int vpos, int x, int y)
27661 struct frame *f = XFRAME (w->frame);
27662 int new_cursor_type;
27663 int new_cursor_width;
27664 int active_cursor;
27665 struct glyph_row *glyph_row;
27666 struct glyph *glyph;
27668 /* This is pointless on invisible frames, and dangerous on garbaged
27669 windows and frames; in the latter case, the frame or window may
27670 be in the midst of changing its size, and x and y may be off the
27671 window. */
27672 if (! FRAME_VISIBLE_P (f)
27673 || FRAME_GARBAGED_P (f)
27674 || vpos >= w->current_matrix->nrows
27675 || hpos >= w->current_matrix->matrix_w)
27676 return;
27678 /* If cursor is off and we want it off, return quickly. */
27679 if (!on && !w->phys_cursor_on_p)
27680 return;
27682 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
27683 /* If cursor row is not enabled, we don't really know where to
27684 display the cursor. */
27685 if (!glyph_row->enabled_p)
27687 w->phys_cursor_on_p = 0;
27688 return;
27691 glyph = NULL;
27692 if (!glyph_row->exact_window_width_line_p
27693 || (0 <= hpos && hpos < glyph_row->used[TEXT_AREA]))
27694 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
27696 eassert (input_blocked_p ());
27698 /* Set new_cursor_type to the cursor we want to be displayed. */
27699 new_cursor_type = get_window_cursor_type (w, glyph,
27700 &new_cursor_width, &active_cursor);
27702 /* If cursor is currently being shown and we don't want it to be or
27703 it is in the wrong place, or the cursor type is not what we want,
27704 erase it. */
27705 if (w->phys_cursor_on_p
27706 && (!on
27707 || w->phys_cursor.x != x
27708 || w->phys_cursor.y != y
27709 /* HPOS can be negative in R2L rows whose
27710 exact_window_width_line_p flag is set (i.e. their newline
27711 would "overflow into the fringe"). */
27712 || hpos < 0
27713 || new_cursor_type != w->phys_cursor_type
27714 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
27715 && new_cursor_width != w->phys_cursor_width)))
27716 erase_phys_cursor (w);
27718 /* Don't check phys_cursor_on_p here because that flag is only set
27719 to zero in some cases where we know that the cursor has been
27720 completely erased, to avoid the extra work of erasing the cursor
27721 twice. In other words, phys_cursor_on_p can be 1 and the cursor
27722 still not be visible, or it has only been partly erased. */
27723 if (on)
27725 w->phys_cursor_ascent = glyph_row->ascent;
27726 w->phys_cursor_height = glyph_row->height;
27728 /* Set phys_cursor_.* before x_draw_.* is called because some
27729 of them may need the information. */
27730 w->phys_cursor.x = x;
27731 w->phys_cursor.y = glyph_row->y;
27732 w->phys_cursor.hpos = hpos;
27733 w->phys_cursor.vpos = vpos;
27736 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
27737 new_cursor_type, new_cursor_width,
27738 on, active_cursor);
27742 /* Switch the display of W's cursor on or off, according to the value
27743 of ON. */
27745 static void
27746 update_window_cursor (struct window *w, bool on)
27748 /* Don't update cursor in windows whose frame is in the process
27749 of being deleted. */
27750 if (w->current_matrix)
27752 int hpos = w->phys_cursor.hpos;
27753 int vpos = w->phys_cursor.vpos;
27754 struct glyph_row *row;
27756 if (vpos >= w->current_matrix->nrows
27757 || hpos >= w->current_matrix->matrix_w)
27758 return;
27760 row = MATRIX_ROW (w->current_matrix, vpos);
27762 /* When the window is hscrolled, cursor hpos can legitimately be
27763 out of bounds, but we draw the cursor at the corresponding
27764 window margin in that case. */
27765 if (!row->reversed_p && hpos < 0)
27766 hpos = 0;
27767 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
27768 hpos = row->used[TEXT_AREA] - 1;
27770 block_input ();
27771 display_and_set_cursor (w, on, hpos, vpos,
27772 w->phys_cursor.x, w->phys_cursor.y);
27773 unblock_input ();
27778 /* Call update_window_cursor with parameter ON_P on all leaf windows
27779 in the window tree rooted at W. */
27781 static void
27782 update_cursor_in_window_tree (struct window *w, bool on_p)
27784 while (w)
27786 if (WINDOWP (w->contents))
27787 update_cursor_in_window_tree (XWINDOW (w->contents), on_p);
27788 else
27789 update_window_cursor (w, on_p);
27791 w = NILP (w->next) ? 0 : XWINDOW (w->next);
27796 /* EXPORT:
27797 Display the cursor on window W, or clear it, according to ON_P.
27798 Don't change the cursor's position. */
27800 void
27801 x_update_cursor (struct frame *f, bool on_p)
27803 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
27807 /* EXPORT:
27808 Clear the cursor of window W to background color, and mark the
27809 cursor as not shown. This is used when the text where the cursor
27810 is about to be rewritten. */
27812 void
27813 x_clear_cursor (struct window *w)
27815 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
27816 update_window_cursor (w, 0);
27819 #endif /* HAVE_WINDOW_SYSTEM */
27821 /* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
27822 and MSDOS. */
27823 static void
27824 draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
27825 int start_hpos, int end_hpos,
27826 enum draw_glyphs_face draw)
27828 #ifdef HAVE_WINDOW_SYSTEM
27829 if (FRAME_WINDOW_P (XFRAME (w->frame)))
27831 draw_glyphs (w, start_x, row, TEXT_AREA, start_hpos, end_hpos, draw, 0);
27832 return;
27834 #endif
27835 #if defined (HAVE_GPM) || defined (MSDOS) || defined (WINDOWSNT)
27836 tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
27837 #endif
27840 /* Display the active region described by mouse_face_* according to DRAW. */
27842 static void
27843 show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
27845 struct window *w = XWINDOW (hlinfo->mouse_face_window);
27846 struct frame *f = XFRAME (WINDOW_FRAME (w));
27848 if (/* If window is in the process of being destroyed, don't bother
27849 to do anything. */
27850 w->current_matrix != NULL
27851 /* Don't update mouse highlight if hidden. */
27852 && (draw != DRAW_MOUSE_FACE || !hlinfo->mouse_face_hidden)
27853 /* Recognize when we are called to operate on rows that don't exist
27854 anymore. This can happen when a window is split. */
27855 && hlinfo->mouse_face_end_row < w->current_matrix->nrows)
27857 int phys_cursor_on_p = w->phys_cursor_on_p;
27858 struct glyph_row *row, *first, *last;
27860 first = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
27861 last = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
27863 for (row = first; row <= last && row->enabled_p; ++row)
27865 int start_hpos, end_hpos, start_x;
27867 /* For all but the first row, the highlight starts at column 0. */
27868 if (row == first)
27870 /* R2L rows have BEG and END in reversed order, but the
27871 screen drawing geometry is always left to right. So
27872 we need to mirror the beginning and end of the
27873 highlighted area in R2L rows. */
27874 if (!row->reversed_p)
27876 start_hpos = hlinfo->mouse_face_beg_col;
27877 start_x = hlinfo->mouse_face_beg_x;
27879 else if (row == last)
27881 start_hpos = hlinfo->mouse_face_end_col;
27882 start_x = hlinfo->mouse_face_end_x;
27884 else
27886 start_hpos = 0;
27887 start_x = 0;
27890 else if (row->reversed_p && row == last)
27892 start_hpos = hlinfo->mouse_face_end_col;
27893 start_x = hlinfo->mouse_face_end_x;
27895 else
27897 start_hpos = 0;
27898 start_x = 0;
27901 if (row == last)
27903 if (!row->reversed_p)
27904 end_hpos = hlinfo->mouse_face_end_col;
27905 else if (row == first)
27906 end_hpos = hlinfo->mouse_face_beg_col;
27907 else
27909 end_hpos = row->used[TEXT_AREA];
27910 if (draw == DRAW_NORMAL_TEXT)
27911 row->fill_line_p = 1; /* Clear to end of line */
27914 else if (row->reversed_p && row == first)
27915 end_hpos = hlinfo->mouse_face_beg_col;
27916 else
27918 end_hpos = row->used[TEXT_AREA];
27919 if (draw == DRAW_NORMAL_TEXT)
27920 row->fill_line_p = 1; /* Clear to end of line */
27923 if (end_hpos > start_hpos)
27925 draw_row_with_mouse_face (w, start_x, row,
27926 start_hpos, end_hpos, draw);
27928 row->mouse_face_p
27929 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
27933 #ifdef HAVE_WINDOW_SYSTEM
27934 /* When we've written over the cursor, arrange for it to
27935 be displayed again. */
27936 if (FRAME_WINDOW_P (f)
27937 && phys_cursor_on_p && !w->phys_cursor_on_p)
27939 int hpos = w->phys_cursor.hpos;
27941 /* When the window is hscrolled, cursor hpos can legitimately be
27942 out of bounds, but we draw the cursor at the corresponding
27943 window margin in that case. */
27944 if (!row->reversed_p && hpos < 0)
27945 hpos = 0;
27946 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
27947 hpos = row->used[TEXT_AREA] - 1;
27949 block_input ();
27950 display_and_set_cursor (w, 1, hpos, w->phys_cursor.vpos,
27951 w->phys_cursor.x, w->phys_cursor.y);
27952 unblock_input ();
27954 #endif /* HAVE_WINDOW_SYSTEM */
27957 #ifdef HAVE_WINDOW_SYSTEM
27958 /* Change the mouse cursor. */
27959 if (FRAME_WINDOW_P (f))
27961 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
27962 if (draw == DRAW_NORMAL_TEXT
27963 && !EQ (hlinfo->mouse_face_window, f->tool_bar_window))
27964 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
27965 else
27966 #endif
27967 if (draw == DRAW_MOUSE_FACE)
27968 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
27969 else
27970 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
27972 #endif /* HAVE_WINDOW_SYSTEM */
27975 /* EXPORT:
27976 Clear out the mouse-highlighted active region.
27977 Redraw it un-highlighted first. Value is non-zero if mouse
27978 face was actually drawn unhighlighted. */
27981 clear_mouse_face (Mouse_HLInfo *hlinfo)
27983 int cleared = 0;
27985 if (!hlinfo->mouse_face_hidden && !NILP (hlinfo->mouse_face_window))
27987 show_mouse_face (hlinfo, DRAW_NORMAL_TEXT);
27988 cleared = 1;
27991 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
27992 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
27993 hlinfo->mouse_face_window = Qnil;
27994 hlinfo->mouse_face_overlay = Qnil;
27995 return cleared;
27998 /* Return true if the coordinates HPOS and VPOS on windows W are
27999 within the mouse face on that window. */
28000 static bool
28001 coords_in_mouse_face_p (struct window *w, int hpos, int vpos)
28003 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
28005 /* Quickly resolve the easy cases. */
28006 if (!(WINDOWP (hlinfo->mouse_face_window)
28007 && XWINDOW (hlinfo->mouse_face_window) == w))
28008 return false;
28009 if (vpos < hlinfo->mouse_face_beg_row
28010 || vpos > hlinfo->mouse_face_end_row)
28011 return false;
28012 if (vpos > hlinfo->mouse_face_beg_row
28013 && vpos < hlinfo->mouse_face_end_row)
28014 return true;
28016 if (!MATRIX_ROW (w->current_matrix, vpos)->reversed_p)
28018 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
28020 if (hlinfo->mouse_face_beg_col <= hpos && hpos < hlinfo->mouse_face_end_col)
28021 return true;
28023 else if ((vpos == hlinfo->mouse_face_beg_row
28024 && hpos >= hlinfo->mouse_face_beg_col)
28025 || (vpos == hlinfo->mouse_face_end_row
28026 && hpos < hlinfo->mouse_face_end_col))
28027 return true;
28029 else
28031 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
28033 if (hlinfo->mouse_face_end_col < hpos && hpos <= hlinfo->mouse_face_beg_col)
28034 return true;
28036 else if ((vpos == hlinfo->mouse_face_beg_row
28037 && hpos <= hlinfo->mouse_face_beg_col)
28038 || (vpos == hlinfo->mouse_face_end_row
28039 && hpos > hlinfo->mouse_face_end_col))
28040 return true;
28042 return false;
28046 /* EXPORT:
28047 True if physical cursor of window W is within mouse face. */
28049 bool
28050 cursor_in_mouse_face_p (struct window *w)
28052 int hpos = w->phys_cursor.hpos;
28053 int vpos = w->phys_cursor.vpos;
28054 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
28056 /* When the window is hscrolled, cursor hpos can legitimately be out
28057 of bounds, but we draw the cursor at the corresponding window
28058 margin in that case. */
28059 if (!row->reversed_p && hpos < 0)
28060 hpos = 0;
28061 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
28062 hpos = row->used[TEXT_AREA] - 1;
28064 return coords_in_mouse_face_p (w, hpos, vpos);
28069 /* Find the glyph rows START_ROW and END_ROW of window W that display
28070 characters between buffer positions START_CHARPOS and END_CHARPOS
28071 (excluding END_CHARPOS). DISP_STRING is a display string that
28072 covers these buffer positions. This is similar to
28073 row_containing_pos, but is more accurate when bidi reordering makes
28074 buffer positions change non-linearly with glyph rows. */
28075 static void
28076 rows_from_pos_range (struct window *w,
28077 ptrdiff_t start_charpos, ptrdiff_t end_charpos,
28078 Lisp_Object disp_string,
28079 struct glyph_row **start, struct glyph_row **end)
28081 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
28082 int last_y = window_text_bottom_y (w);
28083 struct glyph_row *row;
28085 *start = NULL;
28086 *end = NULL;
28088 while (!first->enabled_p
28089 && first < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
28090 first++;
28092 /* Find the START row. */
28093 for (row = first;
28094 row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y;
28095 row++)
28097 /* A row can potentially be the START row if the range of the
28098 characters it displays intersects the range
28099 [START_CHARPOS..END_CHARPOS). */
28100 if (! ((start_charpos < MATRIX_ROW_START_CHARPOS (row)
28101 && end_charpos < MATRIX_ROW_START_CHARPOS (row))
28102 /* See the commentary in row_containing_pos, for the
28103 explanation of the complicated way to check whether
28104 some position is beyond the end of the characters
28105 displayed by a row. */
28106 || ((start_charpos > MATRIX_ROW_END_CHARPOS (row)
28107 || (start_charpos == MATRIX_ROW_END_CHARPOS (row)
28108 && !row->ends_at_zv_p
28109 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
28110 && (end_charpos > MATRIX_ROW_END_CHARPOS (row)
28111 || (end_charpos == MATRIX_ROW_END_CHARPOS (row)
28112 && !row->ends_at_zv_p
28113 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))))))
28115 /* Found a candidate row. Now make sure at least one of the
28116 glyphs it displays has a charpos from the range
28117 [START_CHARPOS..END_CHARPOS).
28119 This is not obvious because bidi reordering could make
28120 buffer positions of a row be 1,2,3,102,101,100, and if we
28121 want to highlight characters in [50..60), we don't want
28122 this row, even though [50..60) does intersect [1..103),
28123 the range of character positions given by the row's start
28124 and end positions. */
28125 struct glyph *g = row->glyphs[TEXT_AREA];
28126 struct glyph *e = g + row->used[TEXT_AREA];
28128 while (g < e)
28130 if (((BUFFERP (g->object) || INTEGERP (g->object))
28131 && start_charpos <= g->charpos && g->charpos < end_charpos)
28132 /* A glyph that comes from DISP_STRING is by
28133 definition to be highlighted. */
28134 || EQ (g->object, disp_string))
28135 *start = row;
28136 g++;
28138 if (*start)
28139 break;
28143 /* Find the END row. */
28144 if (!*start
28145 /* If the last row is partially visible, start looking for END
28146 from that row, instead of starting from FIRST. */
28147 && !(row->enabled_p
28148 && row->y < last_y && MATRIX_ROW_BOTTOM_Y (row) > last_y))
28149 row = first;
28150 for ( ; row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y; row++)
28152 struct glyph_row *next = row + 1;
28153 ptrdiff_t next_start = MATRIX_ROW_START_CHARPOS (next);
28155 if (!next->enabled_p
28156 || next >= MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)
28157 /* The first row >= START whose range of displayed characters
28158 does NOT intersect the range [START_CHARPOS..END_CHARPOS]
28159 is the row END + 1. */
28160 || (start_charpos < next_start
28161 && end_charpos < next_start)
28162 || ((start_charpos > MATRIX_ROW_END_CHARPOS (next)
28163 || (start_charpos == MATRIX_ROW_END_CHARPOS (next)
28164 && !next->ends_at_zv_p
28165 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))
28166 && (end_charpos > MATRIX_ROW_END_CHARPOS (next)
28167 || (end_charpos == MATRIX_ROW_END_CHARPOS (next)
28168 && !next->ends_at_zv_p
28169 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))))
28171 *end = row;
28172 break;
28174 else
28176 /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
28177 but none of the characters it displays are in the range, it is
28178 also END + 1. */
28179 struct glyph *g = next->glyphs[TEXT_AREA];
28180 struct glyph *s = g;
28181 struct glyph *e = g + next->used[TEXT_AREA];
28183 while (g < e)
28185 if (((BUFFERP (g->object) || INTEGERP (g->object))
28186 && ((start_charpos <= g->charpos && g->charpos < end_charpos)
28187 /* If the buffer position of the first glyph in
28188 the row is equal to END_CHARPOS, it means
28189 the last character to be highlighted is the
28190 newline of ROW, and we must consider NEXT as
28191 END, not END+1. */
28192 || (((!next->reversed_p && g == s)
28193 || (next->reversed_p && g == e - 1))
28194 && (g->charpos == end_charpos
28195 /* Special case for when NEXT is an
28196 empty line at ZV. */
28197 || (g->charpos == -1
28198 && !row->ends_at_zv_p
28199 && next_start == end_charpos)))))
28200 /* A glyph that comes from DISP_STRING is by
28201 definition to be highlighted. */
28202 || EQ (g->object, disp_string))
28203 break;
28204 g++;
28206 if (g == e)
28208 *end = row;
28209 break;
28211 /* The first row that ends at ZV must be the last to be
28212 highlighted. */
28213 else if (next->ends_at_zv_p)
28215 *end = next;
28216 break;
28222 /* This function sets the mouse_face_* elements of HLINFO, assuming
28223 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
28224 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
28225 for the overlay or run of text properties specifying the mouse
28226 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
28227 before-string and after-string that must also be highlighted.
28228 DISP_STRING, if non-nil, is a display string that may cover some
28229 or all of the highlighted text. */
28231 static void
28232 mouse_face_from_buffer_pos (Lisp_Object window,
28233 Mouse_HLInfo *hlinfo,
28234 ptrdiff_t mouse_charpos,
28235 ptrdiff_t start_charpos,
28236 ptrdiff_t end_charpos,
28237 Lisp_Object before_string,
28238 Lisp_Object after_string,
28239 Lisp_Object disp_string)
28241 struct window *w = XWINDOW (window);
28242 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
28243 struct glyph_row *r1, *r2;
28244 struct glyph *glyph, *end;
28245 ptrdiff_t ignore, pos;
28246 int x;
28248 eassert (NILP (disp_string) || STRINGP (disp_string));
28249 eassert (NILP (before_string) || STRINGP (before_string));
28250 eassert (NILP (after_string) || STRINGP (after_string));
28252 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
28253 rows_from_pos_range (w, start_charpos, end_charpos, disp_string, &r1, &r2);
28254 if (r1 == NULL)
28255 r1 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
28256 /* If the before-string or display-string contains newlines,
28257 rows_from_pos_range skips to its last row. Move back. */
28258 if (!NILP (before_string) || !NILP (disp_string))
28260 struct glyph_row *prev;
28261 while ((prev = r1 - 1, prev >= first)
28262 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
28263 && prev->used[TEXT_AREA] > 0)
28265 struct glyph *beg = prev->glyphs[TEXT_AREA];
28266 glyph = beg + prev->used[TEXT_AREA];
28267 while (--glyph >= beg && INTEGERP (glyph->object));
28268 if (glyph < beg
28269 || !(EQ (glyph->object, before_string)
28270 || EQ (glyph->object, disp_string)))
28271 break;
28272 r1 = prev;
28275 if (r2 == NULL)
28277 r2 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
28278 hlinfo->mouse_face_past_end = 1;
28280 else if (!NILP (after_string))
28282 /* If the after-string has newlines, advance to its last row. */
28283 struct glyph_row *next;
28284 struct glyph_row *last
28285 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
28287 for (next = r2 + 1;
28288 next <= last
28289 && next->used[TEXT_AREA] > 0
28290 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
28291 ++next)
28292 r2 = next;
28294 /* The rest of the display engine assumes that mouse_face_beg_row is
28295 either above mouse_face_end_row or identical to it. But with
28296 bidi-reordered continued lines, the row for START_CHARPOS could
28297 be below the row for END_CHARPOS. If so, swap the rows and store
28298 them in correct order. */
28299 if (r1->y > r2->y)
28301 struct glyph_row *tem = r2;
28303 r2 = r1;
28304 r1 = tem;
28307 hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
28308 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
28310 /* For a bidi-reordered row, the positions of BEFORE_STRING,
28311 AFTER_STRING, DISP_STRING, START_CHARPOS, and END_CHARPOS
28312 could be anywhere in the row and in any order. The strategy
28313 below is to find the leftmost and the rightmost glyph that
28314 belongs to either of these 3 strings, or whose position is
28315 between START_CHARPOS and END_CHARPOS, and highlight all the
28316 glyphs between those two. This may cover more than just the text
28317 between START_CHARPOS and END_CHARPOS if the range of characters
28318 strides the bidi level boundary, e.g. if the beginning is in R2L
28319 text while the end is in L2R text or vice versa. */
28320 if (!r1->reversed_p)
28322 /* This row is in a left to right paragraph. Scan it left to
28323 right. */
28324 glyph = r1->glyphs[TEXT_AREA];
28325 end = glyph + r1->used[TEXT_AREA];
28326 x = r1->x;
28328 /* Skip truncation glyphs at the start of the glyph row. */
28329 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
28330 for (; glyph < end
28331 && INTEGERP (glyph->object)
28332 && glyph->charpos < 0;
28333 ++glyph)
28334 x += glyph->pixel_width;
28336 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
28337 or DISP_STRING, and the first glyph from buffer whose
28338 position is between START_CHARPOS and END_CHARPOS. */
28339 for (; glyph < end
28340 && !INTEGERP (glyph->object)
28341 && !EQ (glyph->object, disp_string)
28342 && !(BUFFERP (glyph->object)
28343 && (glyph->charpos >= start_charpos
28344 && glyph->charpos < end_charpos));
28345 ++glyph)
28347 /* BEFORE_STRING or AFTER_STRING are only relevant if they
28348 are present at buffer positions between START_CHARPOS and
28349 END_CHARPOS, or if they come from an overlay. */
28350 if (EQ (glyph->object, before_string))
28352 pos = string_buffer_position (before_string,
28353 start_charpos);
28354 /* If pos == 0, it means before_string came from an
28355 overlay, not from a buffer position. */
28356 if (!pos || (pos >= start_charpos && pos < end_charpos))
28357 break;
28359 else if (EQ (glyph->object, after_string))
28361 pos = string_buffer_position (after_string, end_charpos);
28362 if (!pos || (pos >= start_charpos && pos < end_charpos))
28363 break;
28365 x += glyph->pixel_width;
28367 hlinfo->mouse_face_beg_x = x;
28368 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
28370 else
28372 /* This row is in a right to left paragraph. Scan it right to
28373 left. */
28374 struct glyph *g;
28376 end = r1->glyphs[TEXT_AREA] - 1;
28377 glyph = end + r1->used[TEXT_AREA];
28379 /* Skip truncation glyphs at the start of the glyph row. */
28380 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
28381 for (; glyph > end
28382 && INTEGERP (glyph->object)
28383 && glyph->charpos < 0;
28384 --glyph)
28387 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
28388 or DISP_STRING, and the first glyph from buffer whose
28389 position is between START_CHARPOS and END_CHARPOS. */
28390 for (; glyph > end
28391 && !INTEGERP (glyph->object)
28392 && !EQ (glyph->object, disp_string)
28393 && !(BUFFERP (glyph->object)
28394 && (glyph->charpos >= start_charpos
28395 && glyph->charpos < end_charpos));
28396 --glyph)
28398 /* BEFORE_STRING or AFTER_STRING are only relevant if they
28399 are present at buffer positions between START_CHARPOS and
28400 END_CHARPOS, or if they come from an overlay. */
28401 if (EQ (glyph->object, before_string))
28403 pos = string_buffer_position (before_string, start_charpos);
28404 /* If pos == 0, it means before_string came from an
28405 overlay, not from a buffer position. */
28406 if (!pos || (pos >= start_charpos && pos < end_charpos))
28407 break;
28409 else if (EQ (glyph->object, after_string))
28411 pos = string_buffer_position (after_string, end_charpos);
28412 if (!pos || (pos >= start_charpos && pos < end_charpos))
28413 break;
28417 glyph++; /* first glyph to the right of the highlighted area */
28418 for (g = r1->glyphs[TEXT_AREA], x = r1->x; g < glyph; g++)
28419 x += g->pixel_width;
28420 hlinfo->mouse_face_beg_x = x;
28421 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
28424 /* If the highlight ends in a different row, compute GLYPH and END
28425 for the end row. Otherwise, reuse the values computed above for
28426 the row where the highlight begins. */
28427 if (r2 != r1)
28429 if (!r2->reversed_p)
28431 glyph = r2->glyphs[TEXT_AREA];
28432 end = glyph + r2->used[TEXT_AREA];
28433 x = r2->x;
28435 else
28437 end = r2->glyphs[TEXT_AREA] - 1;
28438 glyph = end + r2->used[TEXT_AREA];
28442 if (!r2->reversed_p)
28444 /* Skip truncation and continuation glyphs near the end of the
28445 row, and also blanks and stretch glyphs inserted by
28446 extend_face_to_end_of_line. */
28447 while (end > glyph
28448 && INTEGERP ((end - 1)->object))
28449 --end;
28450 /* Scan the rest of the glyph row from the end, looking for the
28451 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
28452 DISP_STRING, or whose position is between START_CHARPOS
28453 and END_CHARPOS */
28454 for (--end;
28455 end > glyph
28456 && !INTEGERP (end->object)
28457 && !EQ (end->object, disp_string)
28458 && !(BUFFERP (end->object)
28459 && (end->charpos >= start_charpos
28460 && end->charpos < end_charpos));
28461 --end)
28463 /* BEFORE_STRING or AFTER_STRING are only relevant if they
28464 are present at buffer positions between START_CHARPOS and
28465 END_CHARPOS, or if they come from an overlay. */
28466 if (EQ (end->object, before_string))
28468 pos = string_buffer_position (before_string, start_charpos);
28469 if (!pos || (pos >= start_charpos && pos < end_charpos))
28470 break;
28472 else if (EQ (end->object, after_string))
28474 pos = string_buffer_position (after_string, end_charpos);
28475 if (!pos || (pos >= start_charpos && pos < end_charpos))
28476 break;
28479 /* Find the X coordinate of the last glyph to be highlighted. */
28480 for (; glyph <= end; ++glyph)
28481 x += glyph->pixel_width;
28483 hlinfo->mouse_face_end_x = x;
28484 hlinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
28486 else
28488 /* Skip truncation and continuation glyphs near the end of the
28489 row, and also blanks and stretch glyphs inserted by
28490 extend_face_to_end_of_line. */
28491 x = r2->x;
28492 end++;
28493 while (end < glyph
28494 && INTEGERP (end->object))
28496 x += end->pixel_width;
28497 ++end;
28499 /* Scan the rest of the glyph row from the end, looking for the
28500 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
28501 DISP_STRING, or whose position is between START_CHARPOS
28502 and END_CHARPOS */
28503 for ( ;
28504 end < glyph
28505 && !INTEGERP (end->object)
28506 && !EQ (end->object, disp_string)
28507 && !(BUFFERP (end->object)
28508 && (end->charpos >= start_charpos
28509 && end->charpos < end_charpos));
28510 ++end)
28512 /* BEFORE_STRING or AFTER_STRING are only relevant if they
28513 are present at buffer positions between START_CHARPOS and
28514 END_CHARPOS, or if they come from an overlay. */
28515 if (EQ (end->object, before_string))
28517 pos = string_buffer_position (before_string, start_charpos);
28518 if (!pos || (pos >= start_charpos && pos < end_charpos))
28519 break;
28521 else if (EQ (end->object, after_string))
28523 pos = string_buffer_position (after_string, end_charpos);
28524 if (!pos || (pos >= start_charpos && pos < end_charpos))
28525 break;
28527 x += end->pixel_width;
28529 /* If we exited the above loop because we arrived at the last
28530 glyph of the row, and its buffer position is still not in
28531 range, it means the last character in range is the preceding
28532 newline. Bump the end column and x values to get past the
28533 last glyph. */
28534 if (end == glyph
28535 && BUFFERP (end->object)
28536 && (end->charpos < start_charpos
28537 || end->charpos >= end_charpos))
28539 x += end->pixel_width;
28540 ++end;
28542 hlinfo->mouse_face_end_x = x;
28543 hlinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
28546 hlinfo->mouse_face_window = window;
28547 hlinfo->mouse_face_face_id
28548 = face_at_buffer_position (w, mouse_charpos, &ignore,
28549 mouse_charpos + 1,
28550 !hlinfo->mouse_face_hidden, -1);
28551 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
28554 /* The following function is not used anymore (replaced with
28555 mouse_face_from_string_pos), but I leave it here for the time
28556 being, in case someone would. */
28558 #if 0 /* not used */
28560 /* Find the position of the glyph for position POS in OBJECT in
28561 window W's current matrix, and return in *X, *Y the pixel
28562 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
28564 RIGHT_P non-zero means return the position of the right edge of the
28565 glyph, RIGHT_P zero means return the left edge position.
28567 If no glyph for POS exists in the matrix, return the position of
28568 the glyph with the next smaller position that is in the matrix, if
28569 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
28570 exists in the matrix, return the position of the glyph with the
28571 next larger position in OBJECT.
28573 Value is non-zero if a glyph was found. */
28575 static int
28576 fast_find_string_pos (struct window *w, ptrdiff_t pos, Lisp_Object object,
28577 int *hpos, int *vpos, int *x, int *y, int right_p)
28579 int yb = window_text_bottom_y (w);
28580 struct glyph_row *r;
28581 struct glyph *best_glyph = NULL;
28582 struct glyph_row *best_row = NULL;
28583 int best_x = 0;
28585 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
28586 r->enabled_p && r->y < yb;
28587 ++r)
28589 struct glyph *g = r->glyphs[TEXT_AREA];
28590 struct glyph *e = g + r->used[TEXT_AREA];
28591 int gx;
28593 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
28594 if (EQ (g->object, object))
28596 if (g->charpos == pos)
28598 best_glyph = g;
28599 best_x = gx;
28600 best_row = r;
28601 goto found;
28603 else if (best_glyph == NULL
28604 || ((eabs (g->charpos - pos)
28605 < eabs (best_glyph->charpos - pos))
28606 && (right_p
28607 ? g->charpos < pos
28608 : g->charpos > pos)))
28610 best_glyph = g;
28611 best_x = gx;
28612 best_row = r;
28617 found:
28619 if (best_glyph)
28621 *x = best_x;
28622 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
28624 if (right_p)
28626 *x += best_glyph->pixel_width;
28627 ++*hpos;
28630 *y = best_row->y;
28631 *vpos = MATRIX_ROW_VPOS (best_row, w->current_matrix);
28634 return best_glyph != NULL;
28636 #endif /* not used */
28638 /* Find the positions of the first and the last glyphs in window W's
28639 current matrix that occlude positions [STARTPOS..ENDPOS) in OBJECT
28640 (assumed to be a string), and return in HLINFO's mouse_face_*
28641 members the pixel and column/row coordinates of those glyphs. */
28643 static void
28644 mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
28645 Lisp_Object object,
28646 ptrdiff_t startpos, ptrdiff_t endpos)
28648 int yb = window_text_bottom_y (w);
28649 struct glyph_row *r;
28650 struct glyph *g, *e;
28651 int gx;
28652 int found = 0;
28654 /* Find the glyph row with at least one position in the range
28655 [STARTPOS..ENDPOS), and the first glyph in that row whose
28656 position belongs to that range. */
28657 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
28658 r->enabled_p && r->y < yb;
28659 ++r)
28661 if (!r->reversed_p)
28663 g = r->glyphs[TEXT_AREA];
28664 e = g + r->used[TEXT_AREA];
28665 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
28666 if (EQ (g->object, object)
28667 && startpos <= g->charpos && g->charpos < endpos)
28669 hlinfo->mouse_face_beg_row
28670 = MATRIX_ROW_VPOS (r, w->current_matrix);
28671 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
28672 hlinfo->mouse_face_beg_x = gx;
28673 found = 1;
28674 break;
28677 else
28679 struct glyph *g1;
28681 e = r->glyphs[TEXT_AREA];
28682 g = e + r->used[TEXT_AREA];
28683 for ( ; g > e; --g)
28684 if (EQ ((g-1)->object, object)
28685 && startpos <= (g-1)->charpos && (g-1)->charpos < endpos)
28687 hlinfo->mouse_face_beg_row
28688 = MATRIX_ROW_VPOS (r, w->current_matrix);
28689 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
28690 for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
28691 gx += g1->pixel_width;
28692 hlinfo->mouse_face_beg_x = gx;
28693 found = 1;
28694 break;
28697 if (found)
28698 break;
28701 if (!found)
28702 return;
28704 /* Starting with the next row, look for the first row which does NOT
28705 include any glyphs whose positions are in the range. */
28706 for (++r; r->enabled_p && r->y < yb; ++r)
28708 g = r->glyphs[TEXT_AREA];
28709 e = g + r->used[TEXT_AREA];
28710 found = 0;
28711 for ( ; g < e; ++g)
28712 if (EQ (g->object, object)
28713 && startpos <= g->charpos && g->charpos < endpos)
28715 found = 1;
28716 break;
28718 if (!found)
28719 break;
28722 /* The highlighted region ends on the previous row. */
28723 r--;
28725 /* Set the end row. */
28726 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r, w->current_matrix);
28728 /* Compute and set the end column and the end column's horizontal
28729 pixel coordinate. */
28730 if (!r->reversed_p)
28732 g = r->glyphs[TEXT_AREA];
28733 e = g + r->used[TEXT_AREA];
28734 for ( ; e > g; --e)
28735 if (EQ ((e-1)->object, object)
28736 && startpos <= (e-1)->charpos && (e-1)->charpos < endpos)
28737 break;
28738 hlinfo->mouse_face_end_col = e - g;
28740 for (gx = r->x; g < e; ++g)
28741 gx += g->pixel_width;
28742 hlinfo->mouse_face_end_x = gx;
28744 else
28746 e = r->glyphs[TEXT_AREA];
28747 g = e + r->used[TEXT_AREA];
28748 for (gx = r->x ; e < g; ++e)
28750 if (EQ (e->object, object)
28751 && startpos <= e->charpos && e->charpos < endpos)
28752 break;
28753 gx += e->pixel_width;
28755 hlinfo->mouse_face_end_col = e - r->glyphs[TEXT_AREA];
28756 hlinfo->mouse_face_end_x = gx;
28760 #ifdef HAVE_WINDOW_SYSTEM
28762 /* See if position X, Y is within a hot-spot of an image. */
28764 static int
28765 on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
28767 if (!CONSP (hot_spot))
28768 return 0;
28770 if (EQ (XCAR (hot_spot), Qrect))
28772 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
28773 Lisp_Object rect = XCDR (hot_spot);
28774 Lisp_Object tem;
28775 if (!CONSP (rect))
28776 return 0;
28777 if (!CONSP (XCAR (rect)))
28778 return 0;
28779 if (!CONSP (XCDR (rect)))
28780 return 0;
28781 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
28782 return 0;
28783 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
28784 return 0;
28785 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
28786 return 0;
28787 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
28788 return 0;
28789 return 1;
28791 else if (EQ (XCAR (hot_spot), Qcircle))
28793 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
28794 Lisp_Object circ = XCDR (hot_spot);
28795 Lisp_Object lr, lx0, ly0;
28796 if (CONSP (circ)
28797 && CONSP (XCAR (circ))
28798 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
28799 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
28800 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
28802 double r = XFLOATINT (lr);
28803 double dx = XINT (lx0) - x;
28804 double dy = XINT (ly0) - y;
28805 return (dx * dx + dy * dy <= r * r);
28808 else if (EQ (XCAR (hot_spot), Qpoly))
28810 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
28811 if (VECTORP (XCDR (hot_spot)))
28813 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
28814 Lisp_Object *poly = v->contents;
28815 ptrdiff_t n = v->header.size;
28816 ptrdiff_t i;
28817 int inside = 0;
28818 Lisp_Object lx, ly;
28819 int x0, y0;
28821 /* Need an even number of coordinates, and at least 3 edges. */
28822 if (n < 6 || n & 1)
28823 return 0;
28825 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
28826 If count is odd, we are inside polygon. Pixels on edges
28827 may or may not be included depending on actual geometry of the
28828 polygon. */
28829 if ((lx = poly[n-2], !INTEGERP (lx))
28830 || (ly = poly[n-1], !INTEGERP (lx)))
28831 return 0;
28832 x0 = XINT (lx), y0 = XINT (ly);
28833 for (i = 0; i < n; i += 2)
28835 int x1 = x0, y1 = y0;
28836 if ((lx = poly[i], !INTEGERP (lx))
28837 || (ly = poly[i+1], !INTEGERP (ly)))
28838 return 0;
28839 x0 = XINT (lx), y0 = XINT (ly);
28841 /* Does this segment cross the X line? */
28842 if (x0 >= x)
28844 if (x1 >= x)
28845 continue;
28847 else if (x1 < x)
28848 continue;
28849 if (y > y0 && y > y1)
28850 continue;
28851 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
28852 inside = !inside;
28854 return inside;
28857 return 0;
28860 Lisp_Object
28861 find_hot_spot (Lisp_Object map, int x, int y)
28863 while (CONSP (map))
28865 if (CONSP (XCAR (map))
28866 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
28867 return XCAR (map);
28868 map = XCDR (map);
28871 return Qnil;
28874 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
28875 3, 3, 0,
28876 doc: /* Lookup in image map MAP coordinates X and Y.
28877 An image map is an alist where each element has the format (AREA ID PLIST).
28878 An AREA is specified as either a rectangle, a circle, or a polygon:
28879 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
28880 pixel coordinates of the upper left and bottom right corners.
28881 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
28882 and the radius of the circle; r may be a float or integer.
28883 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
28884 vector describes one corner in the polygon.
28885 Returns the alist element for the first matching AREA in MAP. */)
28886 (Lisp_Object map, Lisp_Object x, Lisp_Object y)
28888 if (NILP (map))
28889 return Qnil;
28891 CHECK_NUMBER (x);
28892 CHECK_NUMBER (y);
28894 return find_hot_spot (map,
28895 clip_to_bounds (INT_MIN, XINT (x), INT_MAX),
28896 clip_to_bounds (INT_MIN, XINT (y), INT_MAX));
28900 /* Display frame CURSOR, optionally using shape defined by POINTER. */
28901 static void
28902 define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
28904 /* Do not change cursor shape while dragging mouse. */
28905 if (!NILP (do_mouse_tracking))
28906 return;
28908 if (!NILP (pointer))
28910 if (EQ (pointer, Qarrow))
28911 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
28912 else if (EQ (pointer, Qhand))
28913 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
28914 else if (EQ (pointer, Qtext))
28915 cursor = FRAME_X_OUTPUT (f)->text_cursor;
28916 else if (EQ (pointer, intern ("hdrag")))
28917 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
28918 else if (EQ (pointer, intern ("nhdrag")))
28919 cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
28920 #ifdef HAVE_X_WINDOWS
28921 else if (EQ (pointer, intern ("vdrag")))
28922 cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
28923 #endif
28924 else if (EQ (pointer, intern ("hourglass")))
28925 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
28926 else if (EQ (pointer, Qmodeline))
28927 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
28928 else
28929 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
28932 if (cursor != No_Cursor)
28933 FRAME_RIF (f)->define_frame_cursor (f, cursor);
28936 #endif /* HAVE_WINDOW_SYSTEM */
28938 /* Take proper action when mouse has moved to the mode or header line
28939 or marginal area AREA of window W, x-position X and y-position Y.
28940 X is relative to the start of the text display area of W, so the
28941 width of bitmap areas and scroll bars must be subtracted to get a
28942 position relative to the start of the mode line. */
28944 static void
28945 note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
28946 enum window_part area)
28948 struct window *w = XWINDOW (window);
28949 struct frame *f = XFRAME (w->frame);
28950 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
28951 #ifdef HAVE_WINDOW_SYSTEM
28952 Display_Info *dpyinfo;
28953 #endif
28954 Cursor cursor = No_Cursor;
28955 Lisp_Object pointer = Qnil;
28956 int dx, dy, width, height;
28957 ptrdiff_t charpos;
28958 Lisp_Object string, object = Qnil;
28959 Lisp_Object pos IF_LINT (= Qnil), help;
28961 Lisp_Object mouse_face;
28962 int original_x_pixel = x;
28963 struct glyph * glyph = NULL, * row_start_glyph = NULL;
28964 struct glyph_row *row IF_LINT (= 0);
28966 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
28968 int x0;
28969 struct glyph *end;
28971 /* Kludge alert: mode_line_string takes X/Y in pixels, but
28972 returns them in row/column units! */
28973 string = mode_line_string (w, area, &x, &y, &charpos,
28974 &object, &dx, &dy, &width, &height);
28976 row = (area == ON_MODE_LINE
28977 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
28978 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
28980 /* Find the glyph under the mouse pointer. */
28981 if (row->mode_line_p && row->enabled_p)
28983 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
28984 end = glyph + row->used[TEXT_AREA];
28986 for (x0 = original_x_pixel;
28987 glyph < end && x0 >= glyph->pixel_width;
28988 ++glyph)
28989 x0 -= glyph->pixel_width;
28991 if (glyph >= end)
28992 glyph = NULL;
28995 else
28997 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
28998 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
28999 returns them in row/column units! */
29000 string = marginal_area_string (w, area, &x, &y, &charpos,
29001 &object, &dx, &dy, &width, &height);
29004 help = Qnil;
29006 #ifdef HAVE_WINDOW_SYSTEM
29007 if (IMAGEP (object))
29009 Lisp_Object image_map, hotspot;
29010 if ((image_map = Fplist_get (XCDR (object), QCmap),
29011 !NILP (image_map))
29012 && (hotspot = find_hot_spot (image_map, dx, dy),
29013 CONSP (hotspot))
29014 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
29016 Lisp_Object plist;
29018 /* Could check XCAR (hotspot) to see if we enter/leave this hot-spot.
29019 If so, we could look for mouse-enter, mouse-leave
29020 properties in PLIST (and do something...). */
29021 hotspot = XCDR (hotspot);
29022 if (CONSP (hotspot)
29023 && (plist = XCAR (hotspot), CONSP (plist)))
29025 pointer = Fplist_get (plist, Qpointer);
29026 if (NILP (pointer))
29027 pointer = Qhand;
29028 help = Fplist_get (plist, Qhelp_echo);
29029 if (!NILP (help))
29031 help_echo_string = help;
29032 XSETWINDOW (help_echo_window, w);
29033 help_echo_object = w->contents;
29034 help_echo_pos = charpos;
29038 if (NILP (pointer))
29039 pointer = Fplist_get (XCDR (object), QCpointer);
29041 #endif /* HAVE_WINDOW_SYSTEM */
29043 if (STRINGP (string))
29044 pos = make_number (charpos);
29046 /* Set the help text and mouse pointer. If the mouse is on a part
29047 of the mode line without any text (e.g. past the right edge of
29048 the mode line text), use the default help text and pointer. */
29049 if (STRINGP (string) || area == ON_MODE_LINE)
29051 /* Arrange to display the help by setting the global variables
29052 help_echo_string, help_echo_object, and help_echo_pos. */
29053 if (NILP (help))
29055 if (STRINGP (string))
29056 help = Fget_text_property (pos, Qhelp_echo, string);
29058 if (!NILP (help))
29060 help_echo_string = help;
29061 XSETWINDOW (help_echo_window, w);
29062 help_echo_object = string;
29063 help_echo_pos = charpos;
29065 else if (area == ON_MODE_LINE)
29067 Lisp_Object default_help
29068 = buffer_local_value (Qmode_line_default_help_echo,
29069 w->contents);
29071 if (STRINGP (default_help))
29073 help_echo_string = default_help;
29074 XSETWINDOW (help_echo_window, w);
29075 help_echo_object = Qnil;
29076 help_echo_pos = -1;
29081 #ifdef HAVE_WINDOW_SYSTEM
29082 /* Change the mouse pointer according to what is under it. */
29083 if (FRAME_WINDOW_P (f))
29085 bool draggable = (! WINDOW_BOTTOMMOST_P (w)
29086 || minibuf_level
29087 || NILP (Vresize_mini_windows));
29089 dpyinfo = FRAME_DISPLAY_INFO (f);
29090 if (STRINGP (string))
29092 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
29094 if (NILP (pointer))
29095 pointer = Fget_text_property (pos, Qpointer, string);
29097 /* Change the mouse pointer according to what is under X/Y. */
29098 if (NILP (pointer)
29099 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
29101 Lisp_Object map;
29102 map = Fget_text_property (pos, Qlocal_map, string);
29103 if (!KEYMAPP (map))
29104 map = Fget_text_property (pos, Qkeymap, string);
29105 if (!KEYMAPP (map) && draggable)
29106 cursor = dpyinfo->vertical_scroll_bar_cursor;
29109 else if (draggable)
29110 /* Default mode-line pointer. */
29111 cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
29113 #endif
29116 /* Change the mouse face according to what is under X/Y. */
29117 if (STRINGP (string))
29119 mouse_face = Fget_text_property (pos, Qmouse_face, string);
29120 if (!NILP (Vmouse_highlight) && !NILP (mouse_face)
29121 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
29122 && glyph)
29124 Lisp_Object b, e;
29126 struct glyph * tmp_glyph;
29128 int gpos;
29129 int gseq_length;
29130 int total_pixel_width;
29131 ptrdiff_t begpos, endpos, ignore;
29133 int vpos, hpos;
29135 b = Fprevious_single_property_change (make_number (charpos + 1),
29136 Qmouse_face, string, Qnil);
29137 if (NILP (b))
29138 begpos = 0;
29139 else
29140 begpos = XINT (b);
29142 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
29143 if (NILP (e))
29144 endpos = SCHARS (string);
29145 else
29146 endpos = XINT (e);
29148 /* Calculate the glyph position GPOS of GLYPH in the
29149 displayed string, relative to the beginning of the
29150 highlighted part of the string.
29152 Note: GPOS is different from CHARPOS. CHARPOS is the
29153 position of GLYPH in the internal string object. A mode
29154 line string format has structures which are converted to
29155 a flattened string by the Emacs Lisp interpreter. The
29156 internal string is an element of those structures. The
29157 displayed string is the flattened string. */
29158 tmp_glyph = row_start_glyph;
29159 while (tmp_glyph < glyph
29160 && (!(EQ (tmp_glyph->object, glyph->object)
29161 && begpos <= tmp_glyph->charpos
29162 && tmp_glyph->charpos < endpos)))
29163 tmp_glyph++;
29164 gpos = glyph - tmp_glyph;
29166 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
29167 the highlighted part of the displayed string to which
29168 GLYPH belongs. Note: GSEQ_LENGTH is different from
29169 SCHARS (STRING), because the latter returns the length of
29170 the internal string. */
29171 for (tmp_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
29172 tmp_glyph > glyph
29173 && (!(EQ (tmp_glyph->object, glyph->object)
29174 && begpos <= tmp_glyph->charpos
29175 && tmp_glyph->charpos < endpos));
29176 tmp_glyph--)
29178 gseq_length = gpos + (tmp_glyph - glyph) + 1;
29180 /* Calculate the total pixel width of all the glyphs between
29181 the beginning of the highlighted area and GLYPH. */
29182 total_pixel_width = 0;
29183 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
29184 total_pixel_width += tmp_glyph->pixel_width;
29186 /* Pre calculation of re-rendering position. Note: X is in
29187 column units here, after the call to mode_line_string or
29188 marginal_area_string. */
29189 hpos = x - gpos;
29190 vpos = (area == ON_MODE_LINE
29191 ? (w->current_matrix)->nrows - 1
29192 : 0);
29194 /* If GLYPH's position is included in the region that is
29195 already drawn in mouse face, we have nothing to do. */
29196 if ( EQ (window, hlinfo->mouse_face_window)
29197 && (!row->reversed_p
29198 ? (hlinfo->mouse_face_beg_col <= hpos
29199 && hpos < hlinfo->mouse_face_end_col)
29200 /* In R2L rows we swap BEG and END, see below. */
29201 : (hlinfo->mouse_face_end_col <= hpos
29202 && hpos < hlinfo->mouse_face_beg_col))
29203 && hlinfo->mouse_face_beg_row == vpos )
29204 return;
29206 if (clear_mouse_face (hlinfo))
29207 cursor = No_Cursor;
29209 if (!row->reversed_p)
29211 hlinfo->mouse_face_beg_col = hpos;
29212 hlinfo->mouse_face_beg_x = original_x_pixel
29213 - (total_pixel_width + dx);
29214 hlinfo->mouse_face_end_col = hpos + gseq_length;
29215 hlinfo->mouse_face_end_x = 0;
29217 else
29219 /* In R2L rows, show_mouse_face expects BEG and END
29220 coordinates to be swapped. */
29221 hlinfo->mouse_face_end_col = hpos;
29222 hlinfo->mouse_face_end_x = original_x_pixel
29223 - (total_pixel_width + dx);
29224 hlinfo->mouse_face_beg_col = hpos + gseq_length;
29225 hlinfo->mouse_face_beg_x = 0;
29228 hlinfo->mouse_face_beg_row = vpos;
29229 hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row;
29230 hlinfo->mouse_face_past_end = 0;
29231 hlinfo->mouse_face_window = window;
29233 hlinfo->mouse_face_face_id = face_at_string_position (w, string,
29234 charpos,
29235 0, &ignore,
29236 glyph->face_id,
29238 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
29240 if (NILP (pointer))
29241 pointer = Qhand;
29243 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
29244 clear_mouse_face (hlinfo);
29246 #ifdef HAVE_WINDOW_SYSTEM
29247 if (FRAME_WINDOW_P (f))
29248 define_frame_cursor1 (f, cursor, pointer);
29249 #endif
29253 /* EXPORT:
29254 Take proper action when the mouse has moved to position X, Y on
29255 frame F with regards to highlighting portions of display that have
29256 mouse-face properties. Also de-highlight portions of display where
29257 the mouse was before, set the mouse pointer shape as appropriate
29258 for the mouse coordinates, and activate help echo (tooltips).
29259 X and Y can be negative or out of range. */
29261 void
29262 note_mouse_highlight (struct frame *f, int x, int y)
29264 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
29265 enum window_part part = ON_NOTHING;
29266 Lisp_Object window;
29267 struct window *w;
29268 Cursor cursor = No_Cursor;
29269 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
29270 struct buffer *b;
29272 /* When a menu is active, don't highlight because this looks odd. */
29273 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
29274 if (popup_activated ())
29275 return;
29276 #endif
29278 if (!f->glyphs_initialized_p
29279 || f->pointer_invisible)
29280 return;
29282 hlinfo->mouse_face_mouse_x = x;
29283 hlinfo->mouse_face_mouse_y = y;
29284 hlinfo->mouse_face_mouse_frame = f;
29286 if (hlinfo->mouse_face_defer)
29287 return;
29289 /* Which window is that in? */
29290 window = window_from_coordinates (f, x, y, &part, 1);
29292 /* If displaying active text in another window, clear that. */
29293 if (! EQ (window, hlinfo->mouse_face_window)
29294 /* Also clear if we move out of text area in same window. */
29295 || (!NILP (hlinfo->mouse_face_window)
29296 && !NILP (window)
29297 && part != ON_TEXT
29298 && part != ON_MODE_LINE
29299 && part != ON_HEADER_LINE))
29300 clear_mouse_face (hlinfo);
29302 /* Not on a window -> return. */
29303 if (!WINDOWP (window))
29304 return;
29306 /* Reset help_echo_string. It will get recomputed below. */
29307 help_echo_string = Qnil;
29309 /* Convert to window-relative pixel coordinates. */
29310 w = XWINDOW (window);
29311 frame_to_window_pixel_xy (w, &x, &y);
29313 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
29314 /* Handle tool-bar window differently since it doesn't display a
29315 buffer. */
29316 if (EQ (window, f->tool_bar_window))
29318 note_tool_bar_highlight (f, x, y);
29319 return;
29321 #endif
29323 /* Mouse is on the mode, header line or margin? */
29324 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
29325 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
29327 note_mode_line_or_margin_highlight (window, x, y, part);
29329 #ifdef HAVE_WINDOW_SYSTEM
29330 if (part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
29332 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
29333 /* Show non-text cursor (Bug#16647). */
29334 goto set_cursor;
29336 else
29337 #endif
29338 return;
29341 #ifdef HAVE_WINDOW_SYSTEM
29342 if (part == ON_VERTICAL_BORDER)
29344 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
29345 help_echo_string = build_string ("drag-mouse-1: resize");
29347 else if (part == ON_RIGHT_DIVIDER)
29349 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
29350 help_echo_string = build_string ("drag-mouse-1: resize");
29352 else if (part == ON_BOTTOM_DIVIDER)
29353 if (! WINDOW_BOTTOMMOST_P (w)
29354 || minibuf_level
29355 || NILP (Vresize_mini_windows))
29357 cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
29358 help_echo_string = build_string ("drag-mouse-1: resize");
29360 else
29361 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
29362 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
29363 || part == ON_VERTICAL_SCROLL_BAR
29364 || part == ON_HORIZONTAL_SCROLL_BAR)
29365 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
29366 else
29367 cursor = FRAME_X_OUTPUT (f)->text_cursor;
29368 #endif
29370 /* Are we in a window whose display is up to date?
29371 And verify the buffer's text has not changed. */
29372 b = XBUFFER (w->contents);
29373 if (part == ON_TEXT && w->window_end_valid && !window_outdated (w))
29375 int hpos, vpos, dx, dy, area = LAST_AREA;
29376 ptrdiff_t pos;
29377 struct glyph *glyph;
29378 Lisp_Object object;
29379 Lisp_Object mouse_face = Qnil, position;
29380 Lisp_Object *overlay_vec = NULL;
29381 ptrdiff_t i, noverlays;
29382 struct buffer *obuf;
29383 ptrdiff_t obegv, ozv;
29384 int same_region;
29386 /* Find the glyph under X/Y. */
29387 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
29389 #ifdef HAVE_WINDOW_SYSTEM
29390 /* Look for :pointer property on image. */
29391 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
29393 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
29394 if (img != NULL && IMAGEP (img->spec))
29396 Lisp_Object image_map, hotspot;
29397 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
29398 !NILP (image_map))
29399 && (hotspot = find_hot_spot (image_map,
29400 glyph->slice.img.x + dx,
29401 glyph->slice.img.y + dy),
29402 CONSP (hotspot))
29403 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
29405 Lisp_Object plist;
29407 /* Could check XCAR (hotspot) to see if we enter/leave
29408 this hot-spot.
29409 If so, we could look for mouse-enter, mouse-leave
29410 properties in PLIST (and do something...). */
29411 hotspot = XCDR (hotspot);
29412 if (CONSP (hotspot)
29413 && (plist = XCAR (hotspot), CONSP (plist)))
29415 pointer = Fplist_get (plist, Qpointer);
29416 if (NILP (pointer))
29417 pointer = Qhand;
29418 help_echo_string = Fplist_get (plist, Qhelp_echo);
29419 if (!NILP (help_echo_string))
29421 help_echo_window = window;
29422 help_echo_object = glyph->object;
29423 help_echo_pos = glyph->charpos;
29427 if (NILP (pointer))
29428 pointer = Fplist_get (XCDR (img->spec), QCpointer);
29431 #endif /* HAVE_WINDOW_SYSTEM */
29433 /* Clear mouse face if X/Y not over text. */
29434 if (glyph == NULL
29435 || area != TEXT_AREA
29436 || !MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->current_matrix, vpos))
29437 /* Glyph's OBJECT is an integer for glyphs inserted by the
29438 display engine for its internal purposes, like truncation
29439 and continuation glyphs and blanks beyond the end of
29440 line's text on text terminals. If we are over such a
29441 glyph, we are not over any text. */
29442 || INTEGERP (glyph->object)
29443 /* R2L rows have a stretch glyph at their front, which
29444 stands for no text, whereas L2R rows have no glyphs at
29445 all beyond the end of text. Treat such stretch glyphs
29446 like we do with NULL glyphs in L2R rows. */
29447 || (MATRIX_ROW (w->current_matrix, vpos)->reversed_p
29448 && glyph == MATRIX_ROW_GLYPH_START (w->current_matrix, vpos)
29449 && glyph->type == STRETCH_GLYPH
29450 && glyph->avoid_cursor_p))
29452 if (clear_mouse_face (hlinfo))
29453 cursor = No_Cursor;
29454 #ifdef HAVE_WINDOW_SYSTEM
29455 if (FRAME_WINDOW_P (f) && NILP (pointer))
29457 if (area != TEXT_AREA)
29458 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
29459 else
29460 pointer = Vvoid_text_area_pointer;
29462 #endif
29463 goto set_cursor;
29466 pos = glyph->charpos;
29467 object = glyph->object;
29468 if (!STRINGP (object) && !BUFFERP (object))
29469 goto set_cursor;
29471 /* If we get an out-of-range value, return now; avoid an error. */
29472 if (BUFFERP (object) && pos > BUF_Z (b))
29473 goto set_cursor;
29475 /* Make the window's buffer temporarily current for
29476 overlays_at and compute_char_face. */
29477 obuf = current_buffer;
29478 current_buffer = b;
29479 obegv = BEGV;
29480 ozv = ZV;
29481 BEGV = BEG;
29482 ZV = Z;
29484 /* Is this char mouse-active or does it have help-echo? */
29485 position = make_number (pos);
29487 USE_SAFE_ALLOCA;
29489 if (BUFFERP (object))
29491 /* Put all the overlays we want in a vector in overlay_vec. */
29492 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
29493 /* Sort overlays into increasing priority order. */
29494 noverlays = sort_overlays (overlay_vec, noverlays, w);
29496 else
29497 noverlays = 0;
29499 if (NILP (Vmouse_highlight))
29501 clear_mouse_face (hlinfo);
29502 goto check_help_echo;
29505 same_region = coords_in_mouse_face_p (w, hpos, vpos);
29507 if (same_region)
29508 cursor = No_Cursor;
29510 /* Check mouse-face highlighting. */
29511 if (! same_region
29512 /* If there exists an overlay with mouse-face overlapping
29513 the one we are currently highlighting, we have to
29514 check if we enter the overlapping overlay, and then
29515 highlight only that. */
29516 || (OVERLAYP (hlinfo->mouse_face_overlay)
29517 && mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
29519 /* Find the highest priority overlay with a mouse-face. */
29520 Lisp_Object overlay = Qnil;
29521 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
29523 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
29524 if (!NILP (mouse_face))
29525 overlay = overlay_vec[i];
29528 /* If we're highlighting the same overlay as before, there's
29529 no need to do that again. */
29530 if (!NILP (overlay) && EQ (overlay, hlinfo->mouse_face_overlay))
29531 goto check_help_echo;
29532 hlinfo->mouse_face_overlay = overlay;
29534 /* Clear the display of the old active region, if any. */
29535 if (clear_mouse_face (hlinfo))
29536 cursor = No_Cursor;
29538 /* If no overlay applies, get a text property. */
29539 if (NILP (overlay))
29540 mouse_face = Fget_text_property (position, Qmouse_face, object);
29542 /* Next, compute the bounds of the mouse highlighting and
29543 display it. */
29544 if (!NILP (mouse_face) && STRINGP (object))
29546 /* The mouse-highlighting comes from a display string
29547 with a mouse-face. */
29548 Lisp_Object s, e;
29549 ptrdiff_t ignore;
29551 s = Fprevious_single_property_change
29552 (make_number (pos + 1), Qmouse_face, object, Qnil);
29553 e = Fnext_single_property_change
29554 (position, Qmouse_face, object, Qnil);
29555 if (NILP (s))
29556 s = make_number (0);
29557 if (NILP (e))
29558 e = make_number (SCHARS (object));
29559 mouse_face_from_string_pos (w, hlinfo, object,
29560 XINT (s), XINT (e));
29561 hlinfo->mouse_face_past_end = 0;
29562 hlinfo->mouse_face_window = window;
29563 hlinfo->mouse_face_face_id
29564 = face_at_string_position (w, object, pos, 0, &ignore,
29565 glyph->face_id, 1);
29566 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
29567 cursor = No_Cursor;
29569 else
29571 /* The mouse-highlighting, if any, comes from an overlay
29572 or text property in the buffer. */
29573 Lisp_Object buffer IF_LINT (= Qnil);
29574 Lisp_Object disp_string IF_LINT (= Qnil);
29576 if (STRINGP (object))
29578 /* If we are on a display string with no mouse-face,
29579 check if the text under it has one. */
29580 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
29581 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
29582 pos = string_buffer_position (object, start);
29583 if (pos > 0)
29585 mouse_face = get_char_property_and_overlay
29586 (make_number (pos), Qmouse_face, w->contents, &overlay);
29587 buffer = w->contents;
29588 disp_string = object;
29591 else
29593 buffer = object;
29594 disp_string = Qnil;
29597 if (!NILP (mouse_face))
29599 Lisp_Object before, after;
29600 Lisp_Object before_string, after_string;
29601 /* To correctly find the limits of mouse highlight
29602 in a bidi-reordered buffer, we must not use the
29603 optimization of limiting the search in
29604 previous-single-property-change and
29605 next-single-property-change, because
29606 rows_from_pos_range needs the real start and end
29607 positions to DTRT in this case. That's because
29608 the first row visible in a window does not
29609 necessarily display the character whose position
29610 is the smallest. */
29611 Lisp_Object lim1
29612 = NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
29613 ? Fmarker_position (w->start)
29614 : Qnil;
29615 Lisp_Object lim2
29616 = NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
29617 ? make_number (BUF_Z (XBUFFER (buffer))
29618 - w->window_end_pos)
29619 : Qnil;
29621 if (NILP (overlay))
29623 /* Handle the text property case. */
29624 before = Fprevious_single_property_change
29625 (make_number (pos + 1), Qmouse_face, buffer, lim1);
29626 after = Fnext_single_property_change
29627 (make_number (pos), Qmouse_face, buffer, lim2);
29628 before_string = after_string = Qnil;
29630 else
29632 /* Handle the overlay case. */
29633 before = Foverlay_start (overlay);
29634 after = Foverlay_end (overlay);
29635 before_string = Foverlay_get (overlay, Qbefore_string);
29636 after_string = Foverlay_get (overlay, Qafter_string);
29638 if (!STRINGP (before_string)) before_string = Qnil;
29639 if (!STRINGP (after_string)) after_string = Qnil;
29642 mouse_face_from_buffer_pos (window, hlinfo, pos,
29643 NILP (before)
29645 : XFASTINT (before),
29646 NILP (after)
29647 ? BUF_Z (XBUFFER (buffer))
29648 : XFASTINT (after),
29649 before_string, after_string,
29650 disp_string);
29651 cursor = No_Cursor;
29656 check_help_echo:
29658 /* Look for a `help-echo' property. */
29659 if (NILP (help_echo_string)) {
29660 Lisp_Object help, overlay;
29662 /* Check overlays first. */
29663 help = overlay = Qnil;
29664 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
29666 overlay = overlay_vec[i];
29667 help = Foverlay_get (overlay, Qhelp_echo);
29670 if (!NILP (help))
29672 help_echo_string = help;
29673 help_echo_window = window;
29674 help_echo_object = overlay;
29675 help_echo_pos = pos;
29677 else
29679 Lisp_Object obj = glyph->object;
29680 ptrdiff_t charpos = glyph->charpos;
29682 /* Try text properties. */
29683 if (STRINGP (obj)
29684 && charpos >= 0
29685 && charpos < SCHARS (obj))
29687 help = Fget_text_property (make_number (charpos),
29688 Qhelp_echo, obj);
29689 if (NILP (help))
29691 /* If the string itself doesn't specify a help-echo,
29692 see if the buffer text ``under'' it does. */
29693 struct glyph_row *r
29694 = MATRIX_ROW (w->current_matrix, vpos);
29695 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
29696 ptrdiff_t p = string_buffer_position (obj, start);
29697 if (p > 0)
29699 help = Fget_char_property (make_number (p),
29700 Qhelp_echo, w->contents);
29701 if (!NILP (help))
29703 charpos = p;
29704 obj = w->contents;
29709 else if (BUFFERP (obj)
29710 && charpos >= BEGV
29711 && charpos < ZV)
29712 help = Fget_text_property (make_number (charpos), Qhelp_echo,
29713 obj);
29715 if (!NILP (help))
29717 help_echo_string = help;
29718 help_echo_window = window;
29719 help_echo_object = obj;
29720 help_echo_pos = charpos;
29725 #ifdef HAVE_WINDOW_SYSTEM
29726 /* Look for a `pointer' property. */
29727 if (FRAME_WINDOW_P (f) && NILP (pointer))
29729 /* Check overlays first. */
29730 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
29731 pointer = Foverlay_get (overlay_vec[i], Qpointer);
29733 if (NILP (pointer))
29735 Lisp_Object obj = glyph->object;
29736 ptrdiff_t charpos = glyph->charpos;
29738 /* Try text properties. */
29739 if (STRINGP (obj)
29740 && charpos >= 0
29741 && charpos < SCHARS (obj))
29743 pointer = Fget_text_property (make_number (charpos),
29744 Qpointer, obj);
29745 if (NILP (pointer))
29747 /* If the string itself doesn't specify a pointer,
29748 see if the buffer text ``under'' it does. */
29749 struct glyph_row *r
29750 = MATRIX_ROW (w->current_matrix, vpos);
29751 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
29752 ptrdiff_t p = string_buffer_position (obj, start);
29753 if (p > 0)
29754 pointer = Fget_char_property (make_number (p),
29755 Qpointer, w->contents);
29758 else if (BUFFERP (obj)
29759 && charpos >= BEGV
29760 && charpos < ZV)
29761 pointer = Fget_text_property (make_number (charpos),
29762 Qpointer, obj);
29765 #endif /* HAVE_WINDOW_SYSTEM */
29767 BEGV = obegv;
29768 ZV = ozv;
29769 current_buffer = obuf;
29770 SAFE_FREE ();
29773 set_cursor:
29775 #ifdef HAVE_WINDOW_SYSTEM
29776 if (FRAME_WINDOW_P (f))
29777 define_frame_cursor1 (f, cursor, pointer);
29778 #else
29779 /* This is here to prevent a compiler error, about "label at end of
29780 compound statement". */
29781 return;
29782 #endif
29786 /* EXPORT for RIF:
29787 Clear any mouse-face on window W. This function is part of the
29788 redisplay interface, and is called from try_window_id and similar
29789 functions to ensure the mouse-highlight is off. */
29791 void
29792 x_clear_window_mouse_face (struct window *w)
29794 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
29795 Lisp_Object window;
29797 block_input ();
29798 XSETWINDOW (window, w);
29799 if (EQ (window, hlinfo->mouse_face_window))
29800 clear_mouse_face (hlinfo);
29801 unblock_input ();
29805 /* EXPORT:
29806 Just discard the mouse face information for frame F, if any.
29807 This is used when the size of F is changed. */
29809 void
29810 cancel_mouse_face (struct frame *f)
29812 Lisp_Object window;
29813 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
29815 window = hlinfo->mouse_face_window;
29816 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
29817 reset_mouse_highlight (hlinfo);
29822 /***********************************************************************
29823 Exposure Events
29824 ***********************************************************************/
29826 #ifdef HAVE_WINDOW_SYSTEM
29828 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
29829 which intersects rectangle R. R is in window-relative coordinates. */
29831 static void
29832 expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
29833 enum glyph_row_area area)
29835 struct glyph *first = row->glyphs[area];
29836 struct glyph *end = row->glyphs[area] + row->used[area];
29837 struct glyph *last;
29838 int first_x, start_x, x;
29840 if (area == TEXT_AREA && row->fill_line_p)
29841 /* If row extends face to end of line write the whole line. */
29842 draw_glyphs (w, 0, row, area,
29843 0, row->used[area],
29844 DRAW_NORMAL_TEXT, 0);
29845 else
29847 /* Set START_X to the window-relative start position for drawing glyphs of
29848 AREA. The first glyph of the text area can be partially visible.
29849 The first glyphs of other areas cannot. */
29850 start_x = window_box_left_offset (w, area);
29851 x = start_x;
29852 if (area == TEXT_AREA)
29853 x += row->x;
29855 /* Find the first glyph that must be redrawn. */
29856 while (first < end
29857 && x + first->pixel_width < r->x)
29859 x += first->pixel_width;
29860 ++first;
29863 /* Find the last one. */
29864 last = first;
29865 first_x = x;
29866 while (last < end
29867 && x < r->x + r->width)
29869 x += last->pixel_width;
29870 ++last;
29873 /* Repaint. */
29874 if (last > first)
29875 draw_glyphs (w, first_x - start_x, row, area,
29876 first - row->glyphs[area], last - row->glyphs[area],
29877 DRAW_NORMAL_TEXT, 0);
29882 /* Redraw the parts of the glyph row ROW on window W intersecting
29883 rectangle R. R is in window-relative coordinates. Value is
29884 non-zero if mouse-face was overwritten. */
29886 static int
29887 expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
29889 eassert (row->enabled_p);
29891 if (row->mode_line_p || w->pseudo_window_p)
29892 draw_glyphs (w, 0, row, TEXT_AREA,
29893 0, row->used[TEXT_AREA],
29894 DRAW_NORMAL_TEXT, 0);
29895 else
29897 if (row->used[LEFT_MARGIN_AREA])
29898 expose_area (w, row, r, LEFT_MARGIN_AREA);
29899 if (row->used[TEXT_AREA])
29900 expose_area (w, row, r, TEXT_AREA);
29901 if (row->used[RIGHT_MARGIN_AREA])
29902 expose_area (w, row, r, RIGHT_MARGIN_AREA);
29903 draw_row_fringe_bitmaps (w, row);
29906 return row->mouse_face_p;
29910 /* Redraw those parts of glyphs rows during expose event handling that
29911 overlap other rows. Redrawing of an exposed line writes over parts
29912 of lines overlapping that exposed line; this function fixes that.
29914 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
29915 row in W's current matrix that is exposed and overlaps other rows.
29916 LAST_OVERLAPPING_ROW is the last such row. */
29918 static void
29919 expose_overlaps (struct window *w,
29920 struct glyph_row *first_overlapping_row,
29921 struct glyph_row *last_overlapping_row,
29922 XRectangle *r)
29924 struct glyph_row *row;
29926 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
29927 if (row->overlapping_p)
29929 eassert (row->enabled_p && !row->mode_line_p);
29931 row->clip = r;
29932 if (row->used[LEFT_MARGIN_AREA])
29933 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
29935 if (row->used[TEXT_AREA])
29936 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
29938 if (row->used[RIGHT_MARGIN_AREA])
29939 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
29940 row->clip = NULL;
29945 /* Return non-zero if W's cursor intersects rectangle R. */
29947 static int
29948 phys_cursor_in_rect_p (struct window *w, XRectangle *r)
29950 XRectangle cr, result;
29951 struct glyph *cursor_glyph;
29952 struct glyph_row *row;
29954 if (w->phys_cursor.vpos >= 0
29955 && w->phys_cursor.vpos < w->current_matrix->nrows
29956 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
29957 row->enabled_p)
29958 && row->cursor_in_fringe_p)
29960 /* Cursor is in the fringe. */
29961 cr.x = window_box_right_offset (w,
29962 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
29963 ? RIGHT_MARGIN_AREA
29964 : TEXT_AREA));
29965 cr.y = row->y;
29966 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
29967 cr.height = row->height;
29968 return x_intersect_rectangles (&cr, r, &result);
29971 cursor_glyph = get_phys_cursor_glyph (w);
29972 if (cursor_glyph)
29974 /* r is relative to W's box, but w->phys_cursor.x is relative
29975 to left edge of W's TEXT area. Adjust it. */
29976 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
29977 cr.y = w->phys_cursor.y;
29978 cr.width = cursor_glyph->pixel_width;
29979 cr.height = w->phys_cursor_height;
29980 /* ++KFS: W32 version used W32-specific IntersectRect here, but
29981 I assume the effect is the same -- and this is portable. */
29982 return x_intersect_rectangles (&cr, r, &result);
29984 /* If we don't understand the format, pretend we're not in the hot-spot. */
29985 return 0;
29989 /* EXPORT:
29990 Draw a vertical window border to the right of window W if W doesn't
29991 have vertical scroll bars. */
29993 void
29994 x_draw_vertical_border (struct window *w)
29996 struct frame *f = XFRAME (WINDOW_FRAME (w));
29998 /* We could do better, if we knew what type of scroll-bar the adjacent
29999 windows (on either side) have... But we don't :-(
30000 However, I think this works ok. ++KFS 2003-04-25 */
30002 /* Redraw borders between horizontally adjacent windows. Don't
30003 do it for frames with vertical scroll bars because either the
30004 right scroll bar of a window, or the left scroll bar of its
30005 neighbor will suffice as a border. */
30006 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f) || FRAME_RIGHT_DIVIDER_WIDTH (f))
30007 return;
30009 /* Note: It is necessary to redraw both the left and the right
30010 borders, for when only this single window W is being
30011 redisplayed. */
30012 if (!WINDOW_RIGHTMOST_P (w)
30013 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
30015 int x0, x1, y0, y1;
30017 window_box_edges (w, &x0, &y0, &x1, &y1);
30018 y1 -= 1;
30020 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
30021 x1 -= 1;
30023 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
30026 if (!WINDOW_LEFTMOST_P (w)
30027 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
30029 int x0, x1, y0, y1;
30031 window_box_edges (w, &x0, &y0, &x1, &y1);
30032 y1 -= 1;
30034 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
30035 x0 -= 1;
30037 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
30042 /* Draw window dividers for window W. */
30044 void
30045 x_draw_right_divider (struct window *w)
30047 struct frame *f = WINDOW_XFRAME (w);
30049 if (w->mini || w->pseudo_window_p)
30050 return;
30051 else if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
30053 int x0 = WINDOW_RIGHT_EDGE_X (w) - WINDOW_RIGHT_DIVIDER_WIDTH (w);
30054 int x1 = WINDOW_RIGHT_EDGE_X (w);
30055 int y0 = WINDOW_TOP_EDGE_Y (w);
30056 /* The bottom divider prevails. */
30057 int y1 = WINDOW_BOTTOM_EDGE_Y (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
30059 FRAME_RIF (f)->draw_window_divider (w, x0, x1, y0, y1);
30063 static void
30064 x_draw_bottom_divider (struct window *w)
30066 struct frame *f = XFRAME (WINDOW_FRAME (w));
30068 if (w->mini || w->pseudo_window_p)
30069 return;
30070 else if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
30072 int x0 = WINDOW_LEFT_EDGE_X (w);
30073 int x1 = WINDOW_RIGHT_EDGE_X (w);
30074 int y0 = WINDOW_BOTTOM_EDGE_Y (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
30075 int y1 = WINDOW_BOTTOM_EDGE_Y (w);
30077 FRAME_RIF (f)->draw_window_divider (w, x0, x1, y0, y1);
30081 /* Redraw the part of window W intersection rectangle FR. Pixel
30082 coordinates in FR are frame-relative. Call this function with
30083 input blocked. Value is non-zero if the exposure overwrites
30084 mouse-face. */
30086 static int
30087 expose_window (struct window *w, XRectangle *fr)
30089 struct frame *f = XFRAME (w->frame);
30090 XRectangle wr, r;
30091 int mouse_face_overwritten_p = 0;
30093 /* If window is not yet fully initialized, do nothing. This can
30094 happen when toolkit scroll bars are used and a window is split.
30095 Reconfiguring the scroll bar will generate an expose for a newly
30096 created window. */
30097 if (w->current_matrix == NULL)
30098 return 0;
30100 /* When we're currently updating the window, display and current
30101 matrix usually don't agree. Arrange for a thorough display
30102 later. */
30103 if (w->must_be_updated_p)
30105 SET_FRAME_GARBAGED (f);
30106 return 0;
30109 /* Frame-relative pixel rectangle of W. */
30110 wr.x = WINDOW_LEFT_EDGE_X (w);
30111 wr.y = WINDOW_TOP_EDGE_Y (w);
30112 wr.width = WINDOW_PIXEL_WIDTH (w);
30113 wr.height = WINDOW_PIXEL_HEIGHT (w);
30115 if (x_intersect_rectangles (fr, &wr, &r))
30117 int yb = window_text_bottom_y (w);
30118 struct glyph_row *row;
30119 int cursor_cleared_p, phys_cursor_on_p;
30120 struct glyph_row *first_overlapping_row, *last_overlapping_row;
30122 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
30123 r.x, r.y, r.width, r.height));
30125 /* Convert to window coordinates. */
30126 r.x -= WINDOW_LEFT_EDGE_X (w);
30127 r.y -= WINDOW_TOP_EDGE_Y (w);
30129 /* Turn off the cursor. */
30130 if (!w->pseudo_window_p
30131 && phys_cursor_in_rect_p (w, &r))
30133 x_clear_cursor (w);
30134 cursor_cleared_p = 1;
30136 else
30137 cursor_cleared_p = 0;
30139 /* If the row containing the cursor extends face to end of line,
30140 then expose_area might overwrite the cursor outside the
30141 rectangle and thus notice_overwritten_cursor might clear
30142 w->phys_cursor_on_p. We remember the original value and
30143 check later if it is changed. */
30144 phys_cursor_on_p = w->phys_cursor_on_p;
30146 /* Update lines intersecting rectangle R. */
30147 first_overlapping_row = last_overlapping_row = NULL;
30148 for (row = w->current_matrix->rows;
30149 row->enabled_p;
30150 ++row)
30152 int y0 = row->y;
30153 int y1 = MATRIX_ROW_BOTTOM_Y (row);
30155 if ((y0 >= r.y && y0 < r.y + r.height)
30156 || (y1 > r.y && y1 < r.y + r.height)
30157 || (r.y >= y0 && r.y < y1)
30158 || (r.y + r.height > y0 && r.y + r.height < y1))
30160 /* A header line may be overlapping, but there is no need
30161 to fix overlapping areas for them. KFS 2005-02-12 */
30162 if (row->overlapping_p && !row->mode_line_p)
30164 if (first_overlapping_row == NULL)
30165 first_overlapping_row = row;
30166 last_overlapping_row = row;
30169 row->clip = fr;
30170 if (expose_line (w, row, &r))
30171 mouse_face_overwritten_p = 1;
30172 row->clip = NULL;
30174 else if (row->overlapping_p)
30176 /* We must redraw a row overlapping the exposed area. */
30177 if (y0 < r.y
30178 ? y0 + row->phys_height > r.y
30179 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
30181 if (first_overlapping_row == NULL)
30182 first_overlapping_row = row;
30183 last_overlapping_row = row;
30187 if (y1 >= yb)
30188 break;
30191 /* Display the mode line if there is one. */
30192 if (WINDOW_WANTS_MODELINE_P (w)
30193 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
30194 row->enabled_p)
30195 && row->y < r.y + r.height)
30197 if (expose_line (w, row, &r))
30198 mouse_face_overwritten_p = 1;
30201 if (!w->pseudo_window_p)
30203 /* Fix the display of overlapping rows. */
30204 if (first_overlapping_row)
30205 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
30206 fr);
30208 /* Draw border between windows. */
30209 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
30210 x_draw_right_divider (w);
30211 else
30212 x_draw_vertical_border (w);
30214 if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
30215 x_draw_bottom_divider (w);
30217 /* Turn the cursor on again. */
30218 if (cursor_cleared_p
30219 || (phys_cursor_on_p && !w->phys_cursor_on_p))
30220 update_window_cursor (w, 1);
30224 return mouse_face_overwritten_p;
30229 /* Redraw (parts) of all windows in the window tree rooted at W that
30230 intersect R. R contains frame pixel coordinates. Value is
30231 non-zero if the exposure overwrites mouse-face. */
30233 static int
30234 expose_window_tree (struct window *w, XRectangle *r)
30236 struct frame *f = XFRAME (w->frame);
30237 int mouse_face_overwritten_p = 0;
30239 while (w && !FRAME_GARBAGED_P (f))
30241 if (WINDOWP (w->contents))
30242 mouse_face_overwritten_p
30243 |= expose_window_tree (XWINDOW (w->contents), r);
30244 else
30245 mouse_face_overwritten_p |= expose_window (w, r);
30247 w = NILP (w->next) ? NULL : XWINDOW (w->next);
30250 return mouse_face_overwritten_p;
30254 /* EXPORT:
30255 Redisplay an exposed area of frame F. X and Y are the upper-left
30256 corner of the exposed rectangle. W and H are width and height of
30257 the exposed area. All are pixel values. W or H zero means redraw
30258 the entire frame. */
30260 void
30261 expose_frame (struct frame *f, int x, int y, int w, int h)
30263 XRectangle r;
30264 int mouse_face_overwritten_p = 0;
30266 TRACE ((stderr, "expose_frame "));
30268 /* No need to redraw if frame will be redrawn soon. */
30269 if (FRAME_GARBAGED_P (f))
30271 TRACE ((stderr, " garbaged\n"));
30272 return;
30275 /* If basic faces haven't been realized yet, there is no point in
30276 trying to redraw anything. This can happen when we get an expose
30277 event while Emacs is starting, e.g. by moving another window. */
30278 if (FRAME_FACE_CACHE (f) == NULL
30279 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
30281 TRACE ((stderr, " no faces\n"));
30282 return;
30285 if (w == 0 || h == 0)
30287 r.x = r.y = 0;
30288 r.width = FRAME_TEXT_WIDTH (f);
30289 r.height = FRAME_TEXT_HEIGHT (f);
30291 else
30293 r.x = x;
30294 r.y = y;
30295 r.width = w;
30296 r.height = h;
30299 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
30300 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
30302 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
30303 if (WINDOWP (f->tool_bar_window))
30304 mouse_face_overwritten_p
30305 |= expose_window (XWINDOW (f->tool_bar_window), &r);
30306 #endif
30308 #ifdef HAVE_X_WINDOWS
30309 #ifndef MSDOS
30310 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
30311 if (WINDOWP (f->menu_bar_window))
30312 mouse_face_overwritten_p
30313 |= expose_window (XWINDOW (f->menu_bar_window), &r);
30314 #endif /* not USE_X_TOOLKIT and not USE_GTK */
30315 #endif
30316 #endif
30318 /* Some window managers support a focus-follows-mouse style with
30319 delayed raising of frames. Imagine a partially obscured frame,
30320 and moving the mouse into partially obscured mouse-face on that
30321 frame. The visible part of the mouse-face will be highlighted,
30322 then the WM raises the obscured frame. With at least one WM, KDE
30323 2.1, Emacs is not getting any event for the raising of the frame
30324 (even tried with SubstructureRedirectMask), only Expose events.
30325 These expose events will draw text normally, i.e. not
30326 highlighted. Which means we must redo the highlight here.
30327 Subsume it under ``we love X''. --gerd 2001-08-15 */
30328 /* Included in Windows version because Windows most likely does not
30329 do the right thing if any third party tool offers
30330 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
30331 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
30333 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
30334 if (f == hlinfo->mouse_face_mouse_frame)
30336 int mouse_x = hlinfo->mouse_face_mouse_x;
30337 int mouse_y = hlinfo->mouse_face_mouse_y;
30338 clear_mouse_face (hlinfo);
30339 note_mouse_highlight (f, mouse_x, mouse_y);
30345 /* EXPORT:
30346 Determine the intersection of two rectangles R1 and R2. Return
30347 the intersection in *RESULT. Value is non-zero if RESULT is not
30348 empty. */
30351 x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
30353 XRectangle *left, *right;
30354 XRectangle *upper, *lower;
30355 int intersection_p = 0;
30357 /* Rearrange so that R1 is the left-most rectangle. */
30358 if (r1->x < r2->x)
30359 left = r1, right = r2;
30360 else
30361 left = r2, right = r1;
30363 /* X0 of the intersection is right.x0, if this is inside R1,
30364 otherwise there is no intersection. */
30365 if (right->x <= left->x + left->width)
30367 result->x = right->x;
30369 /* The right end of the intersection is the minimum of
30370 the right ends of left and right. */
30371 result->width = (min (left->x + left->width, right->x + right->width)
30372 - result->x);
30374 /* Same game for Y. */
30375 if (r1->y < r2->y)
30376 upper = r1, lower = r2;
30377 else
30378 upper = r2, lower = r1;
30380 /* The upper end of the intersection is lower.y0, if this is inside
30381 of upper. Otherwise, there is no intersection. */
30382 if (lower->y <= upper->y + upper->height)
30384 result->y = lower->y;
30386 /* The lower end of the intersection is the minimum of the lower
30387 ends of upper and lower. */
30388 result->height = (min (lower->y + lower->height,
30389 upper->y + upper->height)
30390 - result->y);
30391 intersection_p = 1;
30395 return intersection_p;
30398 #endif /* HAVE_WINDOW_SYSTEM */
30401 /***********************************************************************
30402 Initialization
30403 ***********************************************************************/
30405 void
30406 syms_of_xdisp (void)
30408 Vwith_echo_area_save_vector = Qnil;
30409 staticpro (&Vwith_echo_area_save_vector);
30411 Vmessage_stack = Qnil;
30412 staticpro (&Vmessage_stack);
30414 DEFSYM (Qinhibit_redisplay, "inhibit-redisplay");
30415 DEFSYM (Qredisplay_internal, "redisplay_internal (C function)");
30417 message_dolog_marker1 = Fmake_marker ();
30418 staticpro (&message_dolog_marker1);
30419 message_dolog_marker2 = Fmake_marker ();
30420 staticpro (&message_dolog_marker2);
30421 message_dolog_marker3 = Fmake_marker ();
30422 staticpro (&message_dolog_marker3);
30424 #ifdef GLYPH_DEBUG
30425 defsubr (&Sdump_frame_glyph_matrix);
30426 defsubr (&Sdump_glyph_matrix);
30427 defsubr (&Sdump_glyph_row);
30428 defsubr (&Sdump_tool_bar_row);
30429 defsubr (&Strace_redisplay);
30430 defsubr (&Strace_to_stderr);
30431 #endif
30432 #ifdef HAVE_WINDOW_SYSTEM
30433 defsubr (&Stool_bar_height);
30434 defsubr (&Slookup_image_map);
30435 #endif
30436 defsubr (&Sline_pixel_height);
30437 defsubr (&Sformat_mode_line);
30438 defsubr (&Sinvisible_p);
30439 defsubr (&Scurrent_bidi_paragraph_direction);
30440 defsubr (&Swindow_text_pixel_size);
30441 defsubr (&Smove_point_visually);
30443 DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook");
30444 DEFSYM (Qoverriding_terminal_local_map, "overriding-terminal-local-map");
30445 DEFSYM (Qoverriding_local_map, "overriding-local-map");
30446 DEFSYM (Qwindow_scroll_functions, "window-scroll-functions");
30447 DEFSYM (Qwindow_text_change_functions, "window-text-change-functions");
30448 DEFSYM (Qredisplay_end_trigger_functions, "redisplay-end-trigger-functions");
30449 DEFSYM (Qinhibit_point_motion_hooks, "inhibit-point-motion-hooks");
30450 DEFSYM (Qeval, "eval");
30451 DEFSYM (QCdata, ":data");
30452 DEFSYM (Qdisplay, "display");
30453 DEFSYM (Qspace_width, "space-width");
30454 DEFSYM (Qraise, "raise");
30455 DEFSYM (Qslice, "slice");
30456 DEFSYM (Qspace, "space");
30457 DEFSYM (Qmargin, "margin");
30458 DEFSYM (Qpointer, "pointer");
30459 DEFSYM (Qleft_margin, "left-margin");
30460 DEFSYM (Qright_margin, "right-margin");
30461 DEFSYM (Qcenter, "center");
30462 DEFSYM (Qline_height, "line-height");
30463 DEFSYM (QCalign_to, ":align-to");
30464 DEFSYM (QCrelative_width, ":relative-width");
30465 DEFSYM (QCrelative_height, ":relative-height");
30466 DEFSYM (QCeval, ":eval");
30467 DEFSYM (QCpropertize, ":propertize");
30468 DEFSYM (QCfile, ":file");
30469 DEFSYM (Qfontified, "fontified");
30470 DEFSYM (Qfontification_functions, "fontification-functions");
30471 DEFSYM (Qtrailing_whitespace, "trailing-whitespace");
30472 DEFSYM (Qescape_glyph, "escape-glyph");
30473 DEFSYM (Qnobreak_space, "nobreak-space");
30474 DEFSYM (Qimage, "image");
30475 DEFSYM (Qtext, "text");
30476 DEFSYM (Qboth, "both");
30477 DEFSYM (Qboth_horiz, "both-horiz");
30478 DEFSYM (Qtext_image_horiz, "text-image-horiz");
30479 DEFSYM (QCmap, ":map");
30480 DEFSYM (QCpointer, ":pointer");
30481 DEFSYM (Qrect, "rect");
30482 DEFSYM (Qcircle, "circle");
30483 DEFSYM (Qpoly, "poly");
30484 DEFSYM (Qmessage_truncate_lines, "message-truncate-lines");
30485 DEFSYM (Qgrow_only, "grow-only");
30486 DEFSYM (Qinhibit_menubar_update, "inhibit-menubar-update");
30487 DEFSYM (Qinhibit_eval_during_redisplay, "inhibit-eval-during-redisplay");
30488 DEFSYM (Qposition, "position");
30489 DEFSYM (Qbuffer_position, "buffer-position");
30490 DEFSYM (Qobject, "object");
30491 DEFSYM (Qbar, "bar");
30492 DEFSYM (Qhbar, "hbar");
30493 DEFSYM (Qbox, "box");
30494 DEFSYM (Qhollow, "hollow");
30495 DEFSYM (Qhand, "hand");
30496 DEFSYM (Qarrow, "arrow");
30497 DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces");
30499 list_of_error = list1 (list2 (intern_c_string ("error"),
30500 intern_c_string ("void-variable")));
30501 staticpro (&list_of_error);
30503 DEFSYM (Qlast_arrow_position, "last-arrow-position");
30504 DEFSYM (Qlast_arrow_string, "last-arrow-string");
30505 DEFSYM (Qoverlay_arrow_string, "overlay-arrow-string");
30506 DEFSYM (Qoverlay_arrow_bitmap, "overlay-arrow-bitmap");
30508 echo_buffer[0] = echo_buffer[1] = Qnil;
30509 staticpro (&echo_buffer[0]);
30510 staticpro (&echo_buffer[1]);
30512 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
30513 staticpro (&echo_area_buffer[0]);
30514 staticpro (&echo_area_buffer[1]);
30516 Vmessages_buffer_name = build_pure_c_string ("*Messages*");
30517 staticpro (&Vmessages_buffer_name);
30519 mode_line_proptrans_alist = Qnil;
30520 staticpro (&mode_line_proptrans_alist);
30521 mode_line_string_list = Qnil;
30522 staticpro (&mode_line_string_list);
30523 mode_line_string_face = Qnil;
30524 staticpro (&mode_line_string_face);
30525 mode_line_string_face_prop = Qnil;
30526 staticpro (&mode_line_string_face_prop);
30527 Vmode_line_unwind_vector = Qnil;
30528 staticpro (&Vmode_line_unwind_vector);
30530 DEFSYM (Qmode_line_default_help_echo, "mode-line-default-help-echo");
30532 help_echo_string = Qnil;
30533 staticpro (&help_echo_string);
30534 help_echo_object = Qnil;
30535 staticpro (&help_echo_object);
30536 help_echo_window = Qnil;
30537 staticpro (&help_echo_window);
30538 previous_help_echo_string = Qnil;
30539 staticpro (&previous_help_echo_string);
30540 help_echo_pos = -1;
30542 DEFSYM (Qright_to_left, "right-to-left");
30543 DEFSYM (Qleft_to_right, "left-to-right");
30544 defsubr (&Sbidi_resolved_levels);
30546 #ifdef HAVE_WINDOW_SYSTEM
30547 DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p,
30548 doc: /* Non-nil means draw block cursor as wide as the glyph under it.
30549 For example, if a block cursor is over a tab, it will be drawn as
30550 wide as that tab on the display. */);
30551 x_stretch_cursor_p = 0;
30552 #endif
30554 DEFVAR_LISP ("show-trailing-whitespace", Vshow_trailing_whitespace,
30555 doc: /* Non-nil means highlight trailing whitespace.
30556 The face used for trailing whitespace is `trailing-whitespace'. */);
30557 Vshow_trailing_whitespace = Qnil;
30559 DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display,
30560 doc: /* Control highlighting of non-ASCII space and hyphen chars.
30561 If the value is t, Emacs highlights non-ASCII chars which have the
30562 same appearance as an ASCII space or hyphen, using the `nobreak-space'
30563 or `escape-glyph' face respectively.
30565 U+00A0 (no-break space), U+00AD (soft hyphen), U+2010 (hyphen), and
30566 U+2011 (non-breaking hyphen) are affected.
30568 Any other non-nil value means to display these characters as a escape
30569 glyph followed by an ordinary space or hyphen.
30571 A value of nil means no special handling of these characters. */);
30572 Vnobreak_char_display = Qt;
30574 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer,
30575 doc: /* The pointer shape to show in void text areas.
30576 A value of nil means to show the text pointer. Other options are
30577 `arrow', `text', `hand', `vdrag', `hdrag', `nhdrag', `modeline', and
30578 `hourglass'. */);
30579 Vvoid_text_area_pointer = Qarrow;
30581 DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay,
30582 doc: /* Non-nil means don't actually do any redisplay.
30583 This is used for internal purposes. */);
30584 Vinhibit_redisplay = Qnil;
30586 DEFVAR_LISP ("global-mode-string", Vglobal_mode_string,
30587 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
30588 Vglobal_mode_string = Qnil;
30590 DEFVAR_LISP ("overlay-arrow-position", Voverlay_arrow_position,
30591 doc: /* Marker for where to display an arrow on top of the buffer text.
30592 This must be the beginning of a line in order to work.
30593 See also `overlay-arrow-string'. */);
30594 Voverlay_arrow_position = Qnil;
30596 DEFVAR_LISP ("overlay-arrow-string", Voverlay_arrow_string,
30597 doc: /* String to display as an arrow in non-window frames.
30598 See also `overlay-arrow-position'. */);
30599 Voverlay_arrow_string = build_pure_c_string ("=>");
30601 DEFVAR_LISP ("overlay-arrow-variable-list", Voverlay_arrow_variable_list,
30602 doc: /* List of variables (symbols) which hold markers for overlay arrows.
30603 The symbols on this list are examined during redisplay to determine
30604 where to display overlay arrows. */);
30605 Voverlay_arrow_variable_list
30606 = list1 (intern_c_string ("overlay-arrow-position"));
30608 DEFVAR_INT ("scroll-step", emacs_scroll_step,
30609 doc: /* The number of lines to try scrolling a window by when point moves out.
30610 If that fails to bring point back on frame, point is centered instead.
30611 If this is zero, point is always centered after it moves off frame.
30612 If you want scrolling to always be a line at a time, you should set
30613 `scroll-conservatively' to a large value rather than set this to 1. */);
30615 DEFVAR_INT ("scroll-conservatively", scroll_conservatively,
30616 doc: /* Scroll up to this many lines, to bring point back on screen.
30617 If point moves off-screen, redisplay will scroll by up to
30618 `scroll-conservatively' lines in order to bring point just barely
30619 onto the screen again. If that cannot be done, then redisplay
30620 recenters point as usual.
30622 If the value is greater than 100, redisplay will never recenter point,
30623 but will always scroll just enough text to bring point into view, even
30624 if you move far away.
30626 A value of zero means always recenter point if it moves off screen. */);
30627 scroll_conservatively = 0;
30629 DEFVAR_INT ("scroll-margin", scroll_margin,
30630 doc: /* Number of lines of margin at the top and bottom of a window.
30631 Recenter the window whenever point gets within this many lines
30632 of the top or bottom of the window. */);
30633 scroll_margin = 0;
30635 DEFVAR_LISP ("display-pixels-per-inch", Vdisplay_pixels_per_inch,
30636 doc: /* Pixels per inch value for non-window system displays.
30637 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
30638 Vdisplay_pixels_per_inch = make_float (72.0);
30640 #ifdef GLYPH_DEBUG
30641 DEFVAR_INT ("debug-end-pos", debug_end_pos, doc: /* Don't ask. */);
30642 #endif
30644 DEFVAR_LISP ("truncate-partial-width-windows",
30645 Vtruncate_partial_width_windows,
30646 doc: /* Non-nil means truncate lines in windows narrower than the frame.
30647 For an integer value, truncate lines in each window narrower than the
30648 full frame width, provided the window width is less than that integer;
30649 otherwise, respect the value of `truncate-lines'.
30651 For any other non-nil value, truncate lines in all windows that do
30652 not span the full frame width.
30654 A value of nil means to respect the value of `truncate-lines'.
30656 If `word-wrap' is enabled, you might want to reduce this. */);
30657 Vtruncate_partial_width_windows = make_number (50);
30659 DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit,
30660 doc: /* Maximum buffer size for which line number should be displayed.
30661 If the buffer is bigger than this, the line number does not appear
30662 in the mode line. A value of nil means no limit. */);
30663 Vline_number_display_limit = Qnil;
30665 DEFVAR_INT ("line-number-display-limit-width",
30666 line_number_display_limit_width,
30667 doc: /* Maximum line width (in characters) for line number display.
30668 If the average length of the lines near point is bigger than this, then the
30669 line number may be omitted from the mode line. */);
30670 line_number_display_limit_width = 200;
30672 DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows,
30673 doc: /* Non-nil means highlight region even in nonselected windows. */);
30674 highlight_nonselected_windows = 0;
30676 DEFVAR_BOOL ("multiple-frames", multiple_frames,
30677 doc: /* Non-nil if more than one frame is visible on this display.
30678 Minibuffer-only frames don't count, but iconified frames do.
30679 This variable is not guaranteed to be accurate except while processing
30680 `frame-title-format' and `icon-title-format'. */);
30682 DEFVAR_LISP ("frame-title-format", Vframe_title_format,
30683 doc: /* Template for displaying the title bar of visible frames.
30684 \(Assuming the window manager supports this feature.)
30686 This variable has the same structure as `mode-line-format', except that
30687 the %c and %l constructs are ignored. It is used only on frames for
30688 which no explicit name has been set \(see `modify-frame-parameters'). */);
30690 DEFVAR_LISP ("icon-title-format", Vicon_title_format,
30691 doc: /* Template for displaying the title bar of an iconified frame.
30692 \(Assuming the window manager supports this feature.)
30693 This variable has the same structure as `mode-line-format' (which see),
30694 and is used only on frames for which no explicit name has been set
30695 \(see `modify-frame-parameters'). */);
30696 Vicon_title_format
30697 = Vframe_title_format
30698 = listn (CONSTYPE_PURE, 3,
30699 intern_c_string ("multiple-frames"),
30700 build_pure_c_string ("%b"),
30701 listn (CONSTYPE_PURE, 4,
30702 empty_unibyte_string,
30703 intern_c_string ("invocation-name"),
30704 build_pure_c_string ("@"),
30705 intern_c_string ("system-name")));
30707 DEFVAR_LISP ("message-log-max", Vmessage_log_max,
30708 doc: /* Maximum number of lines to keep in the message log buffer.
30709 If nil, disable message logging. If t, log messages but don't truncate
30710 the buffer when it becomes large. */);
30711 Vmessage_log_max = make_number (1000);
30713 DEFVAR_LISP ("window-size-change-functions", Vwindow_size_change_functions,
30714 doc: /* Functions called before redisplay, if window sizes have changed.
30715 The value should be a list of functions that take one argument.
30716 Just before redisplay, for each frame, if any of its windows have changed
30717 size since the last redisplay, or have been split or deleted,
30718 all the functions in the list are called, with the frame as argument. */);
30719 Vwindow_size_change_functions = Qnil;
30721 DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions,
30722 doc: /* List of functions to call before redisplaying a window with scrolling.
30723 Each function is called with two arguments, the window and its new
30724 display-start position. Note that these functions are also called by
30725 `set-window-buffer'. Also note that the value of `window-end' is not
30726 valid when these functions are called.
30728 Warning: Do not use this feature to alter the way the window
30729 is scrolled. It is not designed for that, and such use probably won't
30730 work. */);
30731 Vwindow_scroll_functions = Qnil;
30733 DEFVAR_LISP ("window-text-change-functions",
30734 Vwindow_text_change_functions,
30735 doc: /* Functions to call in redisplay when text in the window might change. */);
30736 Vwindow_text_change_functions = Qnil;
30738 DEFVAR_LISP ("redisplay-end-trigger-functions", Vredisplay_end_trigger_functions,
30739 doc: /* Functions called when redisplay of a window reaches the end trigger.
30740 Each function is called with two arguments, the window and the end trigger value.
30741 See `set-window-redisplay-end-trigger'. */);
30742 Vredisplay_end_trigger_functions = Qnil;
30744 DEFVAR_LISP ("mouse-autoselect-window", Vmouse_autoselect_window,
30745 doc: /* Non-nil means autoselect window with mouse pointer.
30746 If nil, do not autoselect windows.
30747 A positive number means delay autoselection by that many seconds: a
30748 window is autoselected only after the mouse has remained in that
30749 window for the duration of the delay.
30750 A negative number has a similar effect, but causes windows to be
30751 autoselected only after the mouse has stopped moving. \(Because of
30752 the way Emacs compares mouse events, you will occasionally wait twice
30753 that time before the window gets selected.\)
30754 Any other value means to autoselect window instantaneously when the
30755 mouse pointer enters it.
30757 Autoselection selects the minibuffer only if it is active, and never
30758 unselects the minibuffer if it is active.
30760 When customizing this variable make sure that the actual value of
30761 `focus-follows-mouse' matches the behavior of your window manager. */);
30762 Vmouse_autoselect_window = Qnil;
30764 DEFVAR_LISP ("auto-resize-tool-bars", Vauto_resize_tool_bars,
30765 doc: /* Non-nil means automatically resize tool-bars.
30766 This dynamically changes the tool-bar's height to the minimum height
30767 that is needed to make all tool-bar items visible.
30768 If value is `grow-only', the tool-bar's height is only increased
30769 automatically; to decrease the tool-bar height, use \\[recenter]. */);
30770 Vauto_resize_tool_bars = Qt;
30772 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p,
30773 doc: /* Non-nil means raise tool-bar buttons when the mouse moves over them. */);
30774 auto_raise_tool_bar_buttons_p = 1;
30776 DEFVAR_BOOL ("make-cursor-line-fully-visible", make_cursor_line_fully_visible_p,
30777 doc: /* Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
30778 make_cursor_line_fully_visible_p = 1;
30780 DEFVAR_LISP ("tool-bar-border", Vtool_bar_border,
30781 doc: /* Border below tool-bar in pixels.
30782 If an integer, use it as the height of the border.
30783 If it is one of `internal-border-width' or `border-width', use the
30784 value of the corresponding frame parameter.
30785 Otherwise, no border is added below the tool-bar. */);
30786 Vtool_bar_border = Qinternal_border_width;
30788 DEFVAR_LISP ("tool-bar-button-margin", Vtool_bar_button_margin,
30789 doc: /* Margin around tool-bar buttons in pixels.
30790 If an integer, use that for both horizontal and vertical margins.
30791 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
30792 HORZ specifying the horizontal margin, and VERT specifying the
30793 vertical margin. */);
30794 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
30796 DEFVAR_INT ("tool-bar-button-relief", tool_bar_button_relief,
30797 doc: /* Relief thickness of tool-bar buttons. */);
30798 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
30800 DEFVAR_LISP ("tool-bar-style", Vtool_bar_style,
30801 doc: /* Tool bar style to use.
30802 It can be one of
30803 image - show images only
30804 text - show text only
30805 both - show both, text below image
30806 both-horiz - show text to the right of the image
30807 text-image-horiz - show text to the left of the image
30808 any other - use system default or image if no system default.
30810 This variable only affects the GTK+ toolkit version of Emacs. */);
30811 Vtool_bar_style = Qnil;
30813 DEFVAR_INT ("tool-bar-max-label-size", tool_bar_max_label_size,
30814 doc: /* Maximum number of characters a label can have to be shown.
30815 The tool bar style must also show labels for this to have any effect, see
30816 `tool-bar-style'. */);
30817 tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
30819 DEFVAR_LISP ("fontification-functions", Vfontification_functions,
30820 doc: /* List of functions to call to fontify regions of text.
30821 Each function is called with one argument POS. Functions must
30822 fontify a region starting at POS in the current buffer, and give
30823 fontified regions the property `fontified'. */);
30824 Vfontification_functions = Qnil;
30825 Fmake_variable_buffer_local (Qfontification_functions);
30827 DEFVAR_BOOL ("unibyte-display-via-language-environment",
30828 unibyte_display_via_language_environment,
30829 doc: /* Non-nil means display unibyte text according to language environment.
30830 Specifically, this means that raw bytes in the range 160-255 decimal
30831 are displayed by converting them to the equivalent multibyte characters
30832 according to the current language environment. As a result, they are
30833 displayed according to the current fontset.
30835 Note that this variable affects only how these bytes are displayed,
30836 but does not change the fact they are interpreted as raw bytes. */);
30837 unibyte_display_via_language_environment = 0;
30839 DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height,
30840 doc: /* Maximum height for resizing mini-windows (the minibuffer and the echo area).
30841 If a float, it specifies a fraction of the mini-window frame's height.
30842 If an integer, it specifies a number of lines. */);
30843 Vmax_mini_window_height = make_float (0.25);
30845 DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows,
30846 doc: /* How to resize mini-windows (the minibuffer and the echo area).
30847 A value of nil means don't automatically resize mini-windows.
30848 A value of t means resize them to fit the text displayed in them.
30849 A value of `grow-only', the default, means let mini-windows grow only;
30850 they return to their normal size when the minibuffer is closed, or the
30851 echo area becomes empty. */);
30852 Vresize_mini_windows = Qgrow_only;
30854 DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist,
30855 doc: /* Alist specifying how to blink the cursor off.
30856 Each element has the form (ON-STATE . OFF-STATE). Whenever the
30857 `cursor-type' frame-parameter or variable equals ON-STATE,
30858 comparing using `equal', Emacs uses OFF-STATE to specify
30859 how to blink it off. ON-STATE and OFF-STATE are values for
30860 the `cursor-type' frame parameter.
30862 If a frame's ON-STATE has no entry in this list,
30863 the frame's other specifications determine how to blink the cursor off. */);
30864 Vblink_cursor_alist = Qnil;
30866 DEFVAR_BOOL ("auto-hscroll-mode", automatic_hscrolling_p,
30867 doc: /* Allow or disallow automatic horizontal scrolling of windows.
30868 If non-nil, windows are automatically scrolled horizontally to make
30869 point visible. */);
30870 automatic_hscrolling_p = 1;
30871 DEFSYM (Qauto_hscroll_mode, "auto-hscroll-mode");
30873 DEFVAR_INT ("hscroll-margin", hscroll_margin,
30874 doc: /* How many columns away from the window edge point is allowed to get
30875 before automatic hscrolling will horizontally scroll the window. */);
30876 hscroll_margin = 5;
30878 DEFVAR_LISP ("hscroll-step", Vhscroll_step,
30879 doc: /* How many columns to scroll the window when point gets too close to the edge.
30880 When point is less than `hscroll-margin' columns from the window
30881 edge, automatic hscrolling will scroll the window by the amount of columns
30882 determined by this variable. If its value is a positive integer, scroll that
30883 many columns. If it's a positive floating-point number, it specifies the
30884 fraction of the window's width to scroll. If it's nil or zero, point will be
30885 centered horizontally after the scroll. Any other value, including negative
30886 numbers, are treated as if the value were zero.
30888 Automatic hscrolling always moves point outside the scroll margin, so if
30889 point was more than scroll step columns inside the margin, the window will
30890 scroll more than the value given by the scroll step.
30892 Note that the lower bound for automatic hscrolling specified by `scroll-left'
30893 and `scroll-right' overrides this variable's effect. */);
30894 Vhscroll_step = make_number (0);
30896 DEFVAR_BOOL ("message-truncate-lines", message_truncate_lines,
30897 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
30898 Bind this around calls to `message' to let it take effect. */);
30899 message_truncate_lines = 0;
30901 DEFVAR_LISP ("menu-bar-update-hook", Vmenu_bar_update_hook,
30902 doc: /* Normal hook run to update the menu bar definitions.
30903 Redisplay runs this hook before it redisplays the menu bar.
30904 This is used to update menus such as Buffers, whose contents depend on
30905 various data. */);
30906 Vmenu_bar_update_hook = Qnil;
30908 DEFVAR_LISP ("menu-updating-frame", Vmenu_updating_frame,
30909 doc: /* Frame for which we are updating a menu.
30910 The enable predicate for a menu binding should check this variable. */);
30911 Vmenu_updating_frame = Qnil;
30913 DEFVAR_BOOL ("inhibit-menubar-update", inhibit_menubar_update,
30914 doc: /* Non-nil means don't update menu bars. Internal use only. */);
30915 inhibit_menubar_update = 0;
30917 DEFVAR_LISP ("wrap-prefix", Vwrap_prefix,
30918 doc: /* Prefix prepended to all continuation lines at display time.
30919 The value may be a string, an image, or a stretch-glyph; it is
30920 interpreted in the same way as the value of a `display' text property.
30922 This variable is overridden by any `wrap-prefix' text or overlay
30923 property.
30925 To add a prefix to non-continuation lines, use `line-prefix'. */);
30926 Vwrap_prefix = Qnil;
30927 DEFSYM (Qwrap_prefix, "wrap-prefix");
30928 Fmake_variable_buffer_local (Qwrap_prefix);
30930 DEFVAR_LISP ("line-prefix", Vline_prefix,
30931 doc: /* Prefix prepended to all non-continuation lines at display time.
30932 The value may be a string, an image, or a stretch-glyph; it is
30933 interpreted in the same way as the value of a `display' text property.
30935 This variable is overridden by any `line-prefix' text or overlay
30936 property.
30938 To add a prefix to continuation lines, use `wrap-prefix'. */);
30939 Vline_prefix = Qnil;
30940 DEFSYM (Qline_prefix, "line-prefix");
30941 Fmake_variable_buffer_local (Qline_prefix);
30943 DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay,
30944 doc: /* Non-nil means don't eval Lisp during redisplay. */);
30945 inhibit_eval_during_redisplay = 0;
30947 DEFVAR_BOOL ("inhibit-free-realized-faces", inhibit_free_realized_faces,
30948 doc: /* Non-nil means don't free realized faces. Internal use only. */);
30949 inhibit_free_realized_faces = 0;
30951 DEFVAR_BOOL ("inhibit-bidi-mirroring", inhibit_bidi_mirroring,
30952 doc: /* Non-nil means don't mirror characters even when bidi context requires that.
30953 Intended for use during debugging and for testing bidi display;
30954 see biditest.el in the test suite. */);
30955 inhibit_bidi_mirroring = 0;
30957 #ifdef GLYPH_DEBUG
30958 DEFVAR_BOOL ("inhibit-try-window-id", inhibit_try_window_id,
30959 doc: /* Inhibit try_window_id display optimization. */);
30960 inhibit_try_window_id = 0;
30962 DEFVAR_BOOL ("inhibit-try-window-reusing", inhibit_try_window_reusing,
30963 doc: /* Inhibit try_window_reusing display optimization. */);
30964 inhibit_try_window_reusing = 0;
30966 DEFVAR_BOOL ("inhibit-try-cursor-movement", inhibit_try_cursor_movement,
30967 doc: /* Inhibit try_cursor_movement display optimization. */);
30968 inhibit_try_cursor_movement = 0;
30969 #endif /* GLYPH_DEBUG */
30971 DEFVAR_INT ("overline-margin", overline_margin,
30972 doc: /* Space between overline and text, in pixels.
30973 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
30974 margin to the character height. */);
30975 overline_margin = 2;
30977 DEFVAR_INT ("underline-minimum-offset",
30978 underline_minimum_offset,
30979 doc: /* Minimum distance between baseline and underline.
30980 This can improve legibility of underlined text at small font sizes,
30981 particularly when using variable `x-use-underline-position-properties'
30982 with fonts that specify an UNDERLINE_POSITION relatively close to the
30983 baseline. The default value is 1. */);
30984 underline_minimum_offset = 1;
30986 DEFVAR_BOOL ("display-hourglass", display_hourglass_p,
30987 doc: /* Non-nil means show an hourglass pointer, when Emacs is busy.
30988 This feature only works when on a window system that can change
30989 cursor shapes. */);
30990 display_hourglass_p = 1;
30992 DEFVAR_LISP ("hourglass-delay", Vhourglass_delay,
30993 doc: /* Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
30994 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
30996 #ifdef HAVE_WINDOW_SYSTEM
30997 hourglass_atimer = NULL;
30998 hourglass_shown_p = 0;
30999 #endif /* HAVE_WINDOW_SYSTEM */
31001 DEFSYM (Qglyphless_char, "glyphless-char");
31002 DEFSYM (Qhex_code, "hex-code");
31003 DEFSYM (Qempty_box, "empty-box");
31004 DEFSYM (Qthin_space, "thin-space");
31005 DEFSYM (Qzero_width, "zero-width");
31007 DEFVAR_LISP ("pre-redisplay-function", Vpre_redisplay_function,
31008 doc: /* Function run just before redisplay.
31009 It is called with one argument, which is the set of windows that are to
31010 be redisplayed. This set can be nil (meaning, only the selected window),
31011 or t (meaning all windows). */);
31012 Vpre_redisplay_function = intern ("ignore");
31014 DEFSYM (Qglyphless_char_display, "glyphless-char-display");
31015 Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
31017 DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display,
31018 doc: /* Char-table defining glyphless characters.
31019 Each element, if non-nil, should be one of the following:
31020 an ASCII acronym string: display this string in a box
31021 `hex-code': display the hexadecimal code of a character in a box
31022 `empty-box': display as an empty box
31023 `thin-space': display as 1-pixel width space
31024 `zero-width': don't display
31025 An element may also be a cons cell (GRAPHICAL . TEXT), which specifies the
31026 display method for graphical terminals and text terminals respectively.
31027 GRAPHICAL and TEXT should each have one of the values listed above.
31029 The char-table has one extra slot to control the display of a character for
31030 which no font is found. This slot only takes effect on graphical terminals.
31031 Its value should be an ASCII acronym string, `hex-code', `empty-box', or
31032 `thin-space'. The default is `empty-box'.
31034 If a character has a non-nil entry in an active display table, the
31035 display table takes effect; in this case, Emacs does not consult
31036 `glyphless-char-display' at all. */);
31037 Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
31038 Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
31039 Qempty_box);
31041 DEFVAR_LISP ("debug-on-message", Vdebug_on_message,
31042 doc: /* If non-nil, debug if a message matching this regexp is displayed. */);
31043 Vdebug_on_message = Qnil;
31045 DEFVAR_LISP ("redisplay--all-windows-cause", Vredisplay__all_windows_cause,
31046 doc: /* */);
31047 Vredisplay__all_windows_cause
31048 = Fmake_vector (make_number (100), make_number (0));
31050 DEFVAR_LISP ("redisplay--mode-lines-cause", Vredisplay__mode_lines_cause,
31051 doc: /* */);
31052 Vredisplay__mode_lines_cause
31053 = Fmake_vector (make_number (100), make_number (0));
31057 /* Initialize this module when Emacs starts. */
31059 void
31060 init_xdisp (void)
31062 CHARPOS (this_line_start_pos) = 0;
31064 if (!noninteractive)
31066 struct window *m = XWINDOW (minibuf_window);
31067 Lisp_Object frame = m->frame;
31068 struct frame *f = XFRAME (frame);
31069 Lisp_Object root = FRAME_ROOT_WINDOW (f);
31070 struct window *r = XWINDOW (root);
31071 int i;
31073 echo_area_window = minibuf_window;
31075 r->top_line = FRAME_TOP_MARGIN (f);
31076 r->pixel_top = r->top_line * FRAME_LINE_HEIGHT (f);
31077 r->total_cols = FRAME_COLS (f);
31078 r->pixel_width = r->total_cols * FRAME_COLUMN_WIDTH (f);
31079 r->total_lines = FRAME_TOTAL_LINES (f) - 1 - FRAME_TOP_MARGIN (f);
31080 r->pixel_height = r->total_lines * FRAME_LINE_HEIGHT (f);
31082 m->top_line = FRAME_TOTAL_LINES (f) - 1;
31083 m->pixel_top = m->top_line * FRAME_LINE_HEIGHT (f);
31084 m->total_cols = FRAME_COLS (f);
31085 m->pixel_width = m->total_cols * FRAME_COLUMN_WIDTH (f);
31086 m->total_lines = 1;
31087 m->pixel_height = m->total_lines * FRAME_LINE_HEIGHT (f);
31089 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
31090 scratch_glyph_row.glyphs[TEXT_AREA + 1]
31091 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
31093 /* The default ellipsis glyphs `...'. */
31094 for (i = 0; i < 3; ++i)
31095 default_invis_vector[i] = make_number ('.');
31099 /* Allocate the buffer for frame titles.
31100 Also used for `format-mode-line'. */
31101 int size = 100;
31102 mode_line_noprop_buf = xmalloc (size);
31103 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
31104 mode_line_noprop_ptr = mode_line_noprop_buf;
31105 mode_line_target = MODE_LINE_DISPLAY;
31108 help_echo_showing_p = 0;
31111 #ifdef HAVE_WINDOW_SYSTEM
31113 /* Platform-independent portion of hourglass implementation. */
31115 /* Timer function of hourglass_atimer. */
31117 static void
31118 show_hourglass (struct atimer *timer)
31120 /* The timer implementation will cancel this timer automatically
31121 after this function has run. Set hourglass_atimer to null
31122 so that we know the timer doesn't have to be canceled. */
31123 hourglass_atimer = NULL;
31125 if (!hourglass_shown_p)
31127 Lisp_Object tail, frame;
31129 block_input ();
31131 FOR_EACH_FRAME (tail, frame)
31133 struct frame *f = XFRAME (frame);
31135 if (FRAME_LIVE_P (f) && FRAME_WINDOW_P (f)
31136 && FRAME_RIF (f)->show_hourglass)
31137 FRAME_RIF (f)->show_hourglass (f);
31140 hourglass_shown_p = 1;
31141 unblock_input ();
31145 /* Cancel a currently active hourglass timer, and start a new one. */
31147 void
31148 start_hourglass (void)
31150 struct timespec delay;
31152 cancel_hourglass ();
31154 if (INTEGERP (Vhourglass_delay)
31155 && XINT (Vhourglass_delay) > 0)
31156 delay = make_timespec (min (XINT (Vhourglass_delay),
31157 TYPE_MAXIMUM (time_t)),
31159 else if (FLOATP (Vhourglass_delay)
31160 && XFLOAT_DATA (Vhourglass_delay) > 0)
31161 delay = dtotimespec (XFLOAT_DATA (Vhourglass_delay));
31162 else
31163 delay = make_timespec (DEFAULT_HOURGLASS_DELAY, 0);
31165 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
31166 show_hourglass, NULL);
31169 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
31170 shown. */
31172 void
31173 cancel_hourglass (void)
31175 if (hourglass_atimer)
31177 cancel_atimer (hourglass_atimer);
31178 hourglass_atimer = NULL;
31181 if (hourglass_shown_p)
31183 Lisp_Object tail, frame;
31185 block_input ();
31187 FOR_EACH_FRAME (tail, frame)
31189 struct frame *f = XFRAME (frame);
31191 if (FRAME_LIVE_P (f) && FRAME_WINDOW_P (f)
31192 && FRAME_RIF (f)->hide_hourglass)
31193 FRAME_RIF (f)->hide_hourglass (f);
31194 #ifdef HAVE_NTGUI
31195 /* No cursors on non GUI frames - restore to stock arrow cursor. */
31196 else if (!FRAME_W32_P (f))
31197 w32_arrow_cursor ();
31198 #endif
31201 hourglass_shown_p = 0;
31202 unblock_input ();
31206 #endif /* HAVE_WINDOW_SYSTEM */