* doc/lispref/frames.texi (Display Feature Testing): Add indexes.
[emacs.git] / src / xdisp.c
blob37f2c94b5f80f26e4316090943e0098008a72958
1 /* Display generation from window structure and buffer text.
3 Copyright (C) 1985-1988, 1993-1995, 1997-2013 Free Software Foundation,
4 Inc.
6 This file is part of GNU Emacs.
8 GNU Emacs is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21 /* New redisplay written by Gerd Moellmann <gerd@gnu.org>.
23 Redisplay.
25 Emacs separates the task of updating the display from code
26 modifying global state, e.g. buffer text. This way functions
27 operating on buffers don't also have to be concerned with updating
28 the display.
30 Updating the display is triggered by the Lisp interpreter when it
31 decides it's time to do it. This is done either automatically for
32 you as part of the interpreter's command loop or as the result of
33 calling Lisp functions like `sit-for'. The C function `redisplay'
34 in xdisp.c is the only entry into the inner redisplay code.
36 The following diagram shows how redisplay code is invoked. As you
37 can see, Lisp calls redisplay and vice versa. Under window systems
38 like X, some portions of the redisplay code are also called
39 asynchronously during mouse movement or expose events. It is very
40 important that these code parts do NOT use the C library (malloc,
41 free) because many C libraries under Unix are not reentrant. They
42 may also NOT call functions of the Lisp interpreter which could
43 change the interpreter's state. If you don't follow these rules,
44 you will encounter bugs which are very hard to explain.
46 +--------------+ redisplay +----------------+
47 | Lisp machine |---------------->| Redisplay code |<--+
48 +--------------+ (xdisp.c) +----------------+ |
49 ^ | |
50 +----------------------------------+ |
51 Don't use this path when called |
52 asynchronously! |
54 expose_window (asynchronous) |
56 X expose events -----+
58 What does redisplay do? Obviously, it has to figure out somehow what
59 has been changed since the last time the display has been updated,
60 and to make these changes visible. Preferably it would do that in
61 a moderately intelligent way, i.e. fast.
63 Changes in buffer text can be deduced from window and buffer
64 structures, and from some global variables like `beg_unchanged' and
65 `end_unchanged'. The contents of the display are additionally
66 recorded in a `glyph matrix', a two-dimensional matrix of glyph
67 structures. Each row in such a matrix corresponds to a line on the
68 display, and each glyph in a row corresponds to a column displaying
69 a character, an image, or what else. This matrix is called the
70 `current glyph matrix' or `current matrix' in redisplay
71 terminology.
73 For buffer parts that have been changed since the last update, a
74 second glyph matrix is constructed, the so called `desired glyph
75 matrix' or short `desired matrix'. Current and desired matrix are
76 then compared to find a cheap way to update the display, e.g. by
77 reusing part of the display by scrolling lines.
79 You will find a lot of redisplay optimizations when you start
80 looking at the innards of redisplay. The overall goal of all these
81 optimizations is to make redisplay fast because it is done
82 frequently. Some of these optimizations are implemented by the
83 following functions:
85 . try_cursor_movement
87 This function tries to update the display if the text in the
88 window did not change and did not scroll, only point moved, and
89 it did not move off the displayed portion of the text.
91 . try_window_reusing_current_matrix
93 This function reuses the current matrix of a window when text
94 has not changed, but the window start changed (e.g., due to
95 scrolling).
97 . try_window_id
99 This function attempts to redisplay a window by reusing parts of
100 its existing display. It finds and reuses the part that was not
101 changed, and redraws the rest.
103 . try_window
105 This function performs the full redisplay of a single window
106 assuming that its fonts were not changed and that the cursor
107 will not end up in the scroll margins. (Loading fonts requires
108 re-adjustment of dimensions of glyph matrices, which makes this
109 method impossible to use.)
111 These optimizations are tried in sequence (some can be skipped if
112 it is known that they are not applicable). If none of the
113 optimizations were successful, redisplay calls redisplay_windows,
114 which performs a full redisplay of all windows.
116 Desired matrices.
118 Desired matrices are always built per Emacs window. The function
119 `display_line' is the central function to look at if you are
120 interested. It constructs one row in a desired matrix given an
121 iterator structure containing both a buffer position and a
122 description of the environment in which the text is to be
123 displayed. But this is too early, read on.
125 Characters and pixmaps displayed for a range of buffer text depend
126 on various settings of buffers and windows, on overlays and text
127 properties, on display tables, on selective display. The good news
128 is that all this hairy stuff is hidden behind a small set of
129 interface functions taking an iterator structure (struct it)
130 argument.
132 Iteration over things to be displayed is then simple. It is
133 started by initializing an iterator with a call to init_iterator,
134 passing it the buffer position where to start iteration. For
135 iteration over strings, pass -1 as the position to init_iterator,
136 and call reseat_to_string when the string is ready, to initialize
137 the iterator for that string. Thereafter, calls to
138 get_next_display_element fill the iterator structure with relevant
139 information about the next thing to display. Calls to
140 set_iterator_to_next move the iterator to the next thing.
142 Besides this, an iterator also contains information about the
143 display environment in which glyphs for display elements are to be
144 produced. It has fields for the width and height of the display,
145 the information whether long lines are truncated or continued, a
146 current X and Y position, and lots of other stuff you can better
147 see in dispextern.h.
149 Glyphs in a desired matrix are normally constructed in a loop
150 calling get_next_display_element and then PRODUCE_GLYPHS. The call
151 to PRODUCE_GLYPHS will fill the iterator structure with pixel
152 information about the element being displayed and at the same time
153 produce glyphs for it. If the display element fits on the line
154 being displayed, set_iterator_to_next is called next, otherwise the
155 glyphs produced are discarded. The function display_line is the
156 workhorse of filling glyph rows in the desired matrix with glyphs.
157 In addition to producing glyphs, it also handles line truncation
158 and continuation, word wrap, and cursor positioning (for the
159 latter, see also set_cursor_from_row).
161 Frame matrices.
163 That just couldn't be all, could it? What about terminal types not
164 supporting operations on sub-windows of the screen? To update the
165 display on such a terminal, window-based glyph matrices are not
166 well suited. To be able to reuse part of the display (scrolling
167 lines up and down), we must instead have a view of the whole
168 screen. This is what `frame matrices' are for. They are a trick.
170 Frames on terminals like above have a glyph pool. Windows on such
171 a frame sub-allocate their glyph memory from their frame's glyph
172 pool. The frame itself is given its own glyph matrices. By
173 coincidence---or maybe something else---rows in window glyph
174 matrices are slices of corresponding rows in frame matrices. Thus
175 writing to window matrices implicitly updates a frame matrix which
176 provides us with the view of the whole screen that we originally
177 wanted to have without having to move many bytes around. To be
178 honest, there is a little bit more done, but not much more. If you
179 plan to extend that code, take a look at dispnew.c. The function
180 build_frame_matrix is a good starting point.
182 Bidirectional display.
184 Bidirectional display adds quite some hair to this already complex
185 design. The good news are that a large portion of that hairy stuff
186 is hidden in bidi.c behind only 3 interfaces. bidi.c implements a
187 reordering engine which is called by set_iterator_to_next and
188 returns the next character to display in the visual order. See
189 commentary on bidi.c for more details. As far as redisplay is
190 concerned, the effect of calling bidi_move_to_visually_next, the
191 main interface of the reordering engine, is that the iterator gets
192 magically placed on the buffer or string position that is to be
193 displayed next. In other words, a linear iteration through the
194 buffer/string is replaced with a non-linear one. All the rest of
195 the redisplay is oblivious to the bidi reordering.
197 Well, almost oblivious---there are still complications, most of
198 them due to the fact that buffer and string positions no longer
199 change monotonously with glyph indices in a glyph row. Moreover,
200 for continued lines, the buffer positions may not even be
201 monotonously changing with vertical positions. Also, accounting
202 for face changes, overlays, etc. becomes more complex because
203 non-linear iteration could potentially skip many positions with
204 changes, and then cross them again on the way back...
206 One other prominent effect of bidirectional display is that some
207 paragraphs of text need to be displayed starting at the right
208 margin of the window---the so-called right-to-left, or R2L
209 paragraphs. R2L paragraphs are displayed with R2L glyph rows,
210 which have their reversed_p flag set. The bidi reordering engine
211 produces characters in such rows starting from the character which
212 should be the rightmost on display. PRODUCE_GLYPHS then reverses
213 the order, when it fills up the glyph row whose reversed_p flag is
214 set, by prepending each new glyph to what is already there, instead
215 of appending it. When the glyph row is complete, the function
216 extend_face_to_end_of_line fills the empty space to the left of the
217 leftmost character with special glyphs, which will display as,
218 well, empty. On text terminals, these special glyphs are simply
219 blank characters. On graphics terminals, there's a single stretch
220 glyph of a suitably computed width. Both the blanks and the
221 stretch glyph are given the face of the background of the line.
222 This way, the terminal-specific back-end can still draw the glyphs
223 left to right, even for R2L lines.
225 Bidirectional display and character compositions
227 Some scripts cannot be displayed by drawing each character
228 individually, because adjacent characters change each other's shape
229 on display. For example, Arabic and Indic scripts belong to this
230 category.
232 Emacs display supports this by providing "character compositions",
233 most of which is implemented in composite.c. During the buffer
234 scan that delivers characters to PRODUCE_GLYPHS, if the next
235 character to be delivered is a composed character, the iteration
236 calls composition_reseat_it and next_element_from_composition. If
237 they succeed to compose the character with one or more of the
238 following characters, the whole sequence of characters that where
239 composed is recorded in the `struct composition_it' object that is
240 part of the buffer iterator. The composed sequence could produce
241 one or more font glyphs (called "grapheme clusters") on the screen.
242 Each of these grapheme clusters is then delivered to PRODUCE_GLYPHS
243 in the direction corresponding to the current bidi scan direction
244 (recorded in the scan_dir member of the `struct bidi_it' object
245 that is part of the buffer iterator). In particular, if the bidi
246 iterator currently scans the buffer backwards, the grapheme
247 clusters are delivered back to front. This reorders the grapheme
248 clusters as appropriate for the current bidi context. Note that
249 this means that the grapheme clusters are always stored in the
250 LGSTRING object (see composite.c) in the logical order.
252 Moving an iterator in bidirectional text
253 without producing glyphs
255 Note one important detail mentioned above: that the bidi reordering
256 engine, driven by the iterator, produces characters in R2L rows
257 starting at the character that will be the rightmost on display.
258 As far as the iterator is concerned, the geometry of such rows is
259 still left to right, i.e. the iterator "thinks" the first character
260 is at the leftmost pixel position. The iterator does not know that
261 PRODUCE_GLYPHS reverses the order of the glyphs that the iterator
262 delivers. This is important when functions from the move_it_*
263 family are used to get to certain screen position or to match
264 screen coordinates with buffer coordinates: these functions use the
265 iterator geometry, which is left to right even in R2L paragraphs.
266 This works well with most callers of move_it_*, because they need
267 to get to a specific column, and columns are still numbered in the
268 reading order, i.e. the rightmost character in a R2L paragraph is
269 still column zero. But some callers do not get well with this; a
270 notable example is mouse clicks that need to find the character
271 that corresponds to certain pixel coordinates. See
272 buffer_posn_from_coords in dispnew.c for how this is handled. */
274 #include <config.h>
275 #include <stdio.h>
276 #include <limits.h>
278 #include "lisp.h"
279 #include "atimer.h"
280 #include "keyboard.h"
281 #include "frame.h"
282 #include "window.h"
283 #include "termchar.h"
284 #include "dispextern.h"
285 #include "character.h"
286 #include "buffer.h"
287 #include "charset.h"
288 #include "indent.h"
289 #include "commands.h"
290 #include "keymap.h"
291 #include "macros.h"
292 #include "disptab.h"
293 #include "termhooks.h"
294 #include "termopts.h"
295 #include "intervals.h"
296 #include "coding.h"
297 #include "process.h"
298 #include "region-cache.h"
299 #include "font.h"
300 #include "fontset.h"
301 #include "blockinput.h"
303 #ifdef HAVE_X_WINDOWS
304 #include "xterm.h"
305 #endif
306 #ifdef HAVE_NTGUI
307 #include "w32term.h"
308 #endif
309 #ifdef HAVE_NS
310 #include "nsterm.h"
311 #endif
312 #ifdef USE_GTK
313 #include "gtkutil.h"
314 #endif
316 #ifndef FRAME_X_OUTPUT
317 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
318 #endif
320 #define INFINITY 10000000
322 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
323 Lisp_Object Qwindow_scroll_functions;
324 static Lisp_Object Qwindow_text_change_functions;
325 static Lisp_Object Qredisplay_end_trigger_functions;
326 Lisp_Object Qinhibit_point_motion_hooks;
327 static Lisp_Object QCeval, QCpropertize;
328 Lisp_Object QCfile, QCdata;
329 static Lisp_Object Qfontified;
330 static Lisp_Object Qgrow_only;
331 static Lisp_Object Qinhibit_eval_during_redisplay;
332 static Lisp_Object Qbuffer_position, Qposition, Qobject;
333 static Lisp_Object Qright_to_left, Qleft_to_right;
335 /* Cursor shapes. */
336 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
338 /* Pointer shapes. */
339 static Lisp_Object Qarrow, Qhand;
340 Lisp_Object Qtext;
342 /* Holds the list (error). */
343 static Lisp_Object list_of_error;
345 static Lisp_Object Qfontification_functions;
347 static Lisp_Object Qwrap_prefix;
348 static Lisp_Object Qline_prefix;
349 static Lisp_Object Qredisplay_internal;
351 /* Non-nil means don't actually do any redisplay. */
353 Lisp_Object Qinhibit_redisplay;
355 /* Names of text properties relevant for redisplay. */
357 Lisp_Object Qdisplay;
359 Lisp_Object Qspace, QCalign_to;
360 static Lisp_Object QCrelative_width, QCrelative_height;
361 Lisp_Object Qleft_margin, Qright_margin;
362 static Lisp_Object Qspace_width, Qraise;
363 static Lisp_Object Qslice;
364 Lisp_Object Qcenter;
365 static Lisp_Object Qmargin, Qpointer;
366 static Lisp_Object Qline_height;
368 #ifdef HAVE_WINDOW_SYSTEM
370 /* Test if overflow newline into fringe. Called with iterator IT
371 at or past right window margin, and with IT->current_x set. */
373 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(IT) \
374 (!NILP (Voverflow_newline_into_fringe) \
375 && FRAME_WINDOW_P ((IT)->f) \
376 && ((IT)->bidi_it.paragraph_dir == R2L \
377 ? (WINDOW_LEFT_FRINGE_WIDTH ((IT)->w) > 0) \
378 : (WINDOW_RIGHT_FRINGE_WIDTH ((IT)->w) > 0)) \
379 && (IT)->current_x == (IT)->last_visible_x)
381 #else /* !HAVE_WINDOW_SYSTEM */
382 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) 0
383 #endif /* HAVE_WINDOW_SYSTEM */
385 /* Test if the display element loaded in IT, or the underlying buffer
386 or string character, is a space or a TAB character. This is used
387 to determine where word wrapping can occur. */
389 #define IT_DISPLAYING_WHITESPACE(it) \
390 ((it->what == IT_CHARACTER && (it->c == ' ' || it->c == '\t')) \
391 || ((STRINGP (it->string) \
392 && (SREF (it->string, IT_STRING_BYTEPOS (*it)) == ' ' \
393 || SREF (it->string, IT_STRING_BYTEPOS (*it)) == '\t')) \
394 || (it->s \
395 && (it->s[IT_BYTEPOS (*it)] == ' ' \
396 || it->s[IT_BYTEPOS (*it)] == '\t')) \
397 || (IT_BYTEPOS (*it) < ZV_BYTE \
398 && (*BYTE_POS_ADDR (IT_BYTEPOS (*it)) == ' ' \
399 || *BYTE_POS_ADDR (IT_BYTEPOS (*it)) == '\t')))) \
401 /* Name of the face used to highlight trailing whitespace. */
403 static Lisp_Object Qtrailing_whitespace;
405 /* Name and number of the face used to highlight escape glyphs. */
407 static Lisp_Object Qescape_glyph;
409 /* Name and number of the face used to highlight non-breaking spaces. */
411 static Lisp_Object Qnobreak_space;
413 /* The symbol `image' which is the car of the lists used to represent
414 images in Lisp. Also a tool bar style. */
416 Lisp_Object Qimage;
418 /* The image map types. */
419 Lisp_Object QCmap;
420 static Lisp_Object QCpointer;
421 static Lisp_Object Qrect, Qcircle, Qpoly;
423 /* Tool bar styles */
424 Lisp_Object Qboth, Qboth_horiz, Qtext_image_horiz;
426 /* Non-zero means print newline to stdout before next mini-buffer
427 message. */
429 int noninteractive_need_newline;
431 /* Non-zero means print newline to message log before next message. */
433 static int message_log_need_newline;
435 /* Three markers that message_dolog uses.
436 It could allocate them itself, but that causes trouble
437 in handling memory-full errors. */
438 static Lisp_Object message_dolog_marker1;
439 static Lisp_Object message_dolog_marker2;
440 static Lisp_Object message_dolog_marker3;
442 /* The buffer position of the first character appearing entirely or
443 partially on the line of the selected window which contains the
444 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
445 redisplay optimization in redisplay_internal. */
447 static struct text_pos this_line_start_pos;
449 /* Number of characters past the end of the line above, including the
450 terminating newline. */
452 static struct text_pos this_line_end_pos;
454 /* The vertical positions and the height of this line. */
456 static int this_line_vpos;
457 static int this_line_y;
458 static int this_line_pixel_height;
460 /* X position at which this display line starts. Usually zero;
461 negative if first character is partially visible. */
463 static int this_line_start_x;
465 /* The smallest character position seen by move_it_* functions as they
466 move across display lines. Used to set MATRIX_ROW_START_CHARPOS of
467 hscrolled lines, see display_line. */
469 static struct text_pos this_line_min_pos;
471 /* Buffer that this_line_.* variables are referring to. */
473 static struct buffer *this_line_buffer;
476 /* Values of those variables at last redisplay are stored as
477 properties on `overlay-arrow-position' symbol. However, if
478 Voverlay_arrow_position is a marker, last-arrow-position is its
479 numerical position. */
481 static Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
483 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
484 properties on a symbol in overlay-arrow-variable-list. */
486 static Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
488 Lisp_Object Qmenu_bar_update_hook;
490 /* Nonzero if an overlay arrow has been displayed in this window. */
492 static int overlay_arrow_seen;
494 /* Vector containing glyphs for an ellipsis `...'. */
496 static Lisp_Object default_invis_vector[3];
498 /* This is the window where the echo area message was displayed. It
499 is always a mini-buffer window, but it may not be the same window
500 currently active as a mini-buffer. */
502 Lisp_Object echo_area_window;
504 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
505 pushes the current message and the value of
506 message_enable_multibyte on the stack, the function restore_message
507 pops the stack and displays MESSAGE again. */
509 static Lisp_Object Vmessage_stack;
511 /* Nonzero means multibyte characters were enabled when the echo area
512 message was specified. */
514 static int message_enable_multibyte;
516 /* Nonzero if we should redraw the mode lines on the next redisplay. */
518 int update_mode_lines;
520 /* Nonzero if window sizes or contents have changed since last
521 redisplay that finished. */
523 int windows_or_buffers_changed;
525 /* Nonzero means a frame's cursor type has been changed. */
527 int cursor_type_changed;
529 /* Nonzero after display_mode_line if %l was used and it displayed a
530 line number. */
532 static int line_number_displayed;
534 /* The name of the *Messages* buffer, a string. */
536 static Lisp_Object Vmessages_buffer_name;
538 /* Current, index 0, and last displayed echo area message. Either
539 buffers from echo_buffers, or nil to indicate no message. */
541 Lisp_Object echo_area_buffer[2];
543 /* The buffers referenced from echo_area_buffer. */
545 static Lisp_Object echo_buffer[2];
547 /* A vector saved used in with_area_buffer to reduce consing. */
549 static Lisp_Object Vwith_echo_area_save_vector;
551 /* Non-zero means display_echo_area should display the last echo area
552 message again. Set by redisplay_preserve_echo_area. */
554 static int display_last_displayed_message_p;
556 /* Nonzero if echo area is being used by print; zero if being used by
557 message. */
559 static int message_buf_print;
561 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
563 static Lisp_Object Qinhibit_menubar_update;
564 static Lisp_Object Qmessage_truncate_lines;
566 /* Set to 1 in clear_message to make redisplay_internal aware
567 of an emptied echo area. */
569 static int message_cleared_p;
571 /* A scratch glyph row with contents used for generating truncation
572 glyphs. Also used in direct_output_for_insert. */
574 #define MAX_SCRATCH_GLYPHS 100
575 static struct glyph_row scratch_glyph_row;
576 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
578 /* Ascent and height of the last line processed by move_it_to. */
580 static int last_height;
582 /* Non-zero if there's a help-echo in the echo area. */
584 int help_echo_showing_p;
586 /* If >= 0, computed, exact values of mode-line and header-line height
587 to use in the macros CURRENT_MODE_LINE_HEIGHT and
588 CURRENT_HEADER_LINE_HEIGHT. */
590 int current_mode_line_height, current_header_line_height;
592 /* The maximum distance to look ahead for text properties. Values
593 that are too small let us call compute_char_face and similar
594 functions too often which is expensive. Values that are too large
595 let us call compute_char_face and alike too often because we
596 might not be interested in text properties that far away. */
598 #define TEXT_PROP_DISTANCE_LIMIT 100
600 /* SAVE_IT and RESTORE_IT are called when we save a snapshot of the
601 iterator state and later restore it. This is needed because the
602 bidi iterator on bidi.c keeps a stacked cache of its states, which
603 is really a singleton. When we use scratch iterator objects to
604 move around the buffer, we can cause the bidi cache to be pushed or
605 popped, and therefore we need to restore the cache state when we
606 return to the original iterator. */
607 #define SAVE_IT(ITCOPY,ITORIG,CACHE) \
608 do { \
609 if (CACHE) \
610 bidi_unshelve_cache (CACHE, 1); \
611 ITCOPY = ITORIG; \
612 CACHE = bidi_shelve_cache (); \
613 } while (0)
615 #define RESTORE_IT(pITORIG,pITCOPY,CACHE) \
616 do { \
617 if (pITORIG != pITCOPY) \
618 *(pITORIG) = *(pITCOPY); \
619 bidi_unshelve_cache (CACHE, 0); \
620 CACHE = NULL; \
621 } while (0)
623 #ifdef GLYPH_DEBUG
625 /* Non-zero means print traces of redisplay if compiled with
626 GLYPH_DEBUG defined. */
628 int trace_redisplay_p;
630 #endif /* GLYPH_DEBUG */
632 #ifdef DEBUG_TRACE_MOVE
633 /* Non-zero means trace with TRACE_MOVE to stderr. */
634 int trace_move;
636 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
637 #else
638 #define TRACE_MOVE(x) (void) 0
639 #endif
641 static Lisp_Object Qauto_hscroll_mode;
643 /* Buffer being redisplayed -- for redisplay_window_error. */
645 static struct buffer *displayed_buffer;
647 /* Value returned from text property handlers (see below). */
649 enum prop_handled
651 HANDLED_NORMALLY,
652 HANDLED_RECOMPUTE_PROPS,
653 HANDLED_OVERLAY_STRING_CONSUMED,
654 HANDLED_RETURN
657 /* A description of text properties that redisplay is interested
658 in. */
660 struct props
662 /* The name of the property. */
663 Lisp_Object *name;
665 /* A unique index for the property. */
666 enum prop_idx idx;
668 /* A handler function called to set up iterator IT from the property
669 at IT's current position. Value is used to steer handle_stop. */
670 enum prop_handled (*handler) (struct it *it);
673 static enum prop_handled handle_face_prop (struct it *);
674 static enum prop_handled handle_invisible_prop (struct it *);
675 static enum prop_handled handle_display_prop (struct it *);
676 static enum prop_handled handle_composition_prop (struct it *);
677 static enum prop_handled handle_overlay_change (struct it *);
678 static enum prop_handled handle_fontified_prop (struct it *);
680 /* Properties handled by iterators. */
682 static struct props it_props[] =
684 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
685 /* Handle `face' before `display' because some sub-properties of
686 `display' need to know the face. */
687 {&Qface, FACE_PROP_IDX, handle_face_prop},
688 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
689 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
690 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
691 {NULL, 0, NULL}
694 /* Value is the position described by X. If X is a marker, value is
695 the marker_position of X. Otherwise, value is X. */
697 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
699 /* Enumeration returned by some move_it_.* functions internally. */
701 enum move_it_result
703 /* Not used. Undefined value. */
704 MOVE_UNDEFINED,
706 /* Move ended at the requested buffer position or ZV. */
707 MOVE_POS_MATCH_OR_ZV,
709 /* Move ended at the requested X pixel position. */
710 MOVE_X_REACHED,
712 /* Move within a line ended at the end of a line that must be
713 continued. */
714 MOVE_LINE_CONTINUED,
716 /* Move within a line ended at the end of a line that would
717 be displayed truncated. */
718 MOVE_LINE_TRUNCATED,
720 /* Move within a line ended at a line end. */
721 MOVE_NEWLINE_OR_CR
724 /* This counter is used to clear the face cache every once in a while
725 in redisplay_internal. It is incremented for each redisplay.
726 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
727 cleared. */
729 #define CLEAR_FACE_CACHE_COUNT 500
730 static int clear_face_cache_count;
732 /* Similarly for the image cache. */
734 #ifdef HAVE_WINDOW_SYSTEM
735 #define CLEAR_IMAGE_CACHE_COUNT 101
736 static int clear_image_cache_count;
738 /* Null glyph slice */
739 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
740 #endif
742 /* True while redisplay_internal is in progress. */
744 bool redisplaying_p;
746 static Lisp_Object Qinhibit_free_realized_faces;
747 static Lisp_Object Qmode_line_default_help_echo;
749 /* If a string, XTread_socket generates an event to display that string.
750 (The display is done in read_char.) */
752 Lisp_Object help_echo_string;
753 Lisp_Object help_echo_window;
754 Lisp_Object help_echo_object;
755 ptrdiff_t help_echo_pos;
757 /* Temporary variable for XTread_socket. */
759 Lisp_Object previous_help_echo_string;
761 /* Platform-independent portion of hourglass implementation. */
763 /* Non-zero means an hourglass cursor is currently shown. */
764 int hourglass_shown_p;
766 /* If non-null, an asynchronous timer that, when it expires, displays
767 an hourglass cursor on all frames. */
768 struct atimer *hourglass_atimer;
770 /* Name of the face used to display glyphless characters. */
771 Lisp_Object Qglyphless_char;
773 /* Symbol for the purpose of Vglyphless_char_display. */
774 static Lisp_Object Qglyphless_char_display;
776 /* Method symbols for Vglyphless_char_display. */
777 static Lisp_Object Qhex_code, Qempty_box, Qthin_space, Qzero_width;
779 /* Default pixel width of `thin-space' display method. */
780 #define THIN_SPACE_WIDTH 1
782 /* Default number of seconds to wait before displaying an hourglass
783 cursor. */
784 #define DEFAULT_HOURGLASS_DELAY 1
787 /* Function prototypes. */
789 static void setup_for_ellipsis (struct it *, int);
790 static void set_iterator_to_next (struct it *, int);
791 static void mark_window_display_accurate_1 (struct window *, int);
792 static int single_display_spec_string_p (Lisp_Object, Lisp_Object);
793 static int display_prop_string_p (Lisp_Object, Lisp_Object);
794 static int row_for_charpos_p (struct glyph_row *, ptrdiff_t);
795 static int cursor_row_p (struct glyph_row *);
796 static int redisplay_mode_lines (Lisp_Object, int);
797 static char *decode_mode_spec_coding (Lisp_Object, char *, int);
799 static Lisp_Object get_it_property (struct it *it, Lisp_Object prop);
801 static void handle_line_prefix (struct it *);
803 static void pint2str (char *, int, ptrdiff_t);
804 static void pint2hrstr (char *, int, ptrdiff_t);
805 static struct text_pos run_window_scroll_functions (Lisp_Object,
806 struct text_pos);
807 static int text_outside_line_unchanged_p (struct window *,
808 ptrdiff_t, ptrdiff_t);
809 static void store_mode_line_noprop_char (char);
810 static int store_mode_line_noprop (const char *, int, int);
811 static void handle_stop (struct it *);
812 static void handle_stop_backwards (struct it *, ptrdiff_t);
813 static void vmessage (const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (1, 0);
814 static void ensure_echo_area_buffers (void);
815 static void unwind_with_echo_area_buffer (Lisp_Object);
816 static Lisp_Object with_echo_area_buffer_unwind_data (struct window *);
817 static int with_echo_area_buffer (struct window *, int,
818 int (*) (ptrdiff_t, Lisp_Object),
819 ptrdiff_t, Lisp_Object);
820 static void clear_garbaged_frames (void);
821 static int current_message_1 (ptrdiff_t, Lisp_Object);
822 static int truncate_message_1 (ptrdiff_t, Lisp_Object);
823 static void set_message (Lisp_Object);
824 static int set_message_1 (ptrdiff_t, Lisp_Object);
825 static int display_echo_area (struct window *);
826 static int display_echo_area_1 (ptrdiff_t, Lisp_Object);
827 static int resize_mini_window_1 (ptrdiff_t, Lisp_Object);
828 static void unwind_redisplay (void);
829 static int string_char_and_length (const unsigned char *, int *);
830 static struct text_pos display_prop_end (struct it *, Lisp_Object,
831 struct text_pos);
832 static int compute_window_start_on_continuation_line (struct window *);
833 static void insert_left_trunc_glyphs (struct it *);
834 static struct glyph_row *get_overlay_arrow_glyph_row (struct window *,
835 Lisp_Object);
836 static void extend_face_to_end_of_line (struct it *);
837 static int append_space_for_newline (struct it *, int);
838 static int cursor_row_fully_visible_p (struct window *, int, int);
839 static int try_scrolling (Lisp_Object, int, ptrdiff_t, ptrdiff_t, int, int);
840 static int try_cursor_movement (Lisp_Object, struct text_pos, int *);
841 static int trailing_whitespace_p (ptrdiff_t);
842 static intmax_t message_log_check_duplicate (ptrdiff_t, ptrdiff_t);
843 static void push_it (struct it *, struct text_pos *);
844 static void iterate_out_of_display_property (struct it *);
845 static void pop_it (struct it *);
846 static void sync_frame_with_window_matrix_rows (struct window *);
847 static void redisplay_internal (void);
848 static int echo_area_display (int);
849 static void redisplay_windows (Lisp_Object);
850 static void redisplay_window (Lisp_Object, int);
851 static Lisp_Object redisplay_window_error (Lisp_Object);
852 static Lisp_Object redisplay_window_0 (Lisp_Object);
853 static Lisp_Object redisplay_window_1 (Lisp_Object);
854 static int set_cursor_from_row (struct window *, struct glyph_row *,
855 struct glyph_matrix *, ptrdiff_t, ptrdiff_t,
856 int, int);
857 static int update_menu_bar (struct frame *, int, int);
858 static int try_window_reusing_current_matrix (struct window *);
859 static int try_window_id (struct window *);
860 static int display_line (struct it *);
861 static int display_mode_lines (struct window *);
862 static int display_mode_line (struct window *, enum face_id, Lisp_Object);
863 static int display_mode_element (struct it *, int, int, int, Lisp_Object, Lisp_Object, int);
864 static int store_mode_line_string (const char *, Lisp_Object, int, int, int, Lisp_Object);
865 static const char *decode_mode_spec (struct window *, int, int, Lisp_Object *);
866 static void display_menu_bar (struct window *);
867 static ptrdiff_t display_count_lines (ptrdiff_t, ptrdiff_t, ptrdiff_t,
868 ptrdiff_t *);
869 static int display_string (const char *, Lisp_Object, Lisp_Object,
870 ptrdiff_t, ptrdiff_t, struct it *, int, int, int, int);
871 static void compute_line_metrics (struct it *);
872 static void run_redisplay_end_trigger_hook (struct it *);
873 static int get_overlay_strings (struct it *, ptrdiff_t);
874 static int get_overlay_strings_1 (struct it *, ptrdiff_t, int);
875 static void next_overlay_string (struct it *);
876 static void reseat (struct it *, struct text_pos, int);
877 static void reseat_1 (struct it *, struct text_pos, int);
878 static void back_to_previous_visible_line_start (struct it *);
879 static void reseat_at_next_visible_line_start (struct it *, int);
880 static int next_element_from_ellipsis (struct it *);
881 static int next_element_from_display_vector (struct it *);
882 static int next_element_from_string (struct it *);
883 static int next_element_from_c_string (struct it *);
884 static int next_element_from_buffer (struct it *);
885 static int next_element_from_composition (struct it *);
886 static int next_element_from_image (struct it *);
887 static int next_element_from_stretch (struct it *);
888 static void load_overlay_strings (struct it *, ptrdiff_t);
889 static int init_from_display_pos (struct it *, struct window *,
890 struct display_pos *);
891 static void reseat_to_string (struct it *, const char *,
892 Lisp_Object, ptrdiff_t, ptrdiff_t, int, int);
893 static int get_next_display_element (struct it *);
894 static enum move_it_result
895 move_it_in_display_line_to (struct it *, ptrdiff_t, int,
896 enum move_operation_enum);
897 static void get_visually_first_element (struct it *);
898 static void init_to_row_start (struct it *, struct window *,
899 struct glyph_row *);
900 static int init_to_row_end (struct it *, struct window *,
901 struct glyph_row *);
902 static void back_to_previous_line_start (struct it *);
903 static int forward_to_next_line_start (struct it *, int *, struct bidi_it *);
904 static struct text_pos string_pos_nchars_ahead (struct text_pos,
905 Lisp_Object, ptrdiff_t);
906 static struct text_pos string_pos (ptrdiff_t, Lisp_Object);
907 static struct text_pos c_string_pos (ptrdiff_t, const char *, bool);
908 static ptrdiff_t number_of_chars (const char *, bool);
909 static void compute_stop_pos (struct it *);
910 static void compute_string_pos (struct text_pos *, struct text_pos,
911 Lisp_Object);
912 static int face_before_or_after_it_pos (struct it *, int);
913 static ptrdiff_t next_overlay_change (ptrdiff_t);
914 static int handle_display_spec (struct it *, Lisp_Object, Lisp_Object,
915 Lisp_Object, struct text_pos *, ptrdiff_t, int);
916 static int handle_single_display_spec (struct it *, Lisp_Object,
917 Lisp_Object, Lisp_Object,
918 struct text_pos *, ptrdiff_t, int, int);
919 static int underlying_face_id (struct it *);
920 static int in_ellipses_for_invisible_text_p (struct display_pos *,
921 struct window *);
923 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
924 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
926 #ifdef HAVE_WINDOW_SYSTEM
928 static void x_consider_frame_title (Lisp_Object);
929 static int tool_bar_lines_needed (struct frame *, int *);
930 static void update_tool_bar (struct frame *, int);
931 static void build_desired_tool_bar_string (struct frame *f);
932 static int redisplay_tool_bar (struct frame *);
933 static void display_tool_bar_line (struct it *, int);
934 static void notice_overwritten_cursor (struct window *,
935 enum glyph_row_area,
936 int, int, int, int);
937 static void append_stretch_glyph (struct it *, Lisp_Object,
938 int, int, int);
941 #endif /* HAVE_WINDOW_SYSTEM */
943 static void produce_special_glyphs (struct it *, enum display_element_type);
944 static void show_mouse_face (Mouse_HLInfo *, enum draw_glyphs_face);
945 static int coords_in_mouse_face_p (struct window *, int, int);
949 /***********************************************************************
950 Window display dimensions
951 ***********************************************************************/
953 /* Return the bottom boundary y-position for text lines in window W.
954 This is the first y position at which a line cannot start.
955 It is relative to the top of the window.
957 This is the height of W minus the height of a mode line, if any. */
960 window_text_bottom_y (struct window *w)
962 int height = WINDOW_TOTAL_HEIGHT (w);
964 if (WINDOW_WANTS_MODELINE_P (w))
965 height -= CURRENT_MODE_LINE_HEIGHT (w);
966 return height;
969 /* Return the pixel width of display area AREA of window W. AREA < 0
970 means return the total width of W, not including fringes to
971 the left and right of the window. */
974 window_box_width (struct window *w, int area)
976 int cols = w->total_cols;
977 int pixels = 0;
979 if (!w->pseudo_window_p)
981 cols -= WINDOW_SCROLL_BAR_COLS (w);
983 if (area == TEXT_AREA)
985 if (INTEGERP (w->left_margin_cols))
986 cols -= XFASTINT (w->left_margin_cols);
987 if (INTEGERP (w->right_margin_cols))
988 cols -= XFASTINT (w->right_margin_cols);
989 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
991 else if (area == LEFT_MARGIN_AREA)
993 cols = (INTEGERP (w->left_margin_cols)
994 ? XFASTINT (w->left_margin_cols) : 0);
995 pixels = 0;
997 else if (area == RIGHT_MARGIN_AREA)
999 cols = (INTEGERP (w->right_margin_cols)
1000 ? XFASTINT (w->right_margin_cols) : 0);
1001 pixels = 0;
1005 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1009 /* Return the pixel height of the display area of window W, not
1010 including mode lines of W, if any. */
1013 window_box_height (struct window *w)
1015 struct frame *f = XFRAME (w->frame);
1016 int height = WINDOW_TOTAL_HEIGHT (w);
1018 eassert (height >= 0);
1020 /* Note: the code below that determines the mode-line/header-line
1021 height is essentially the same as that contained in the macro
1022 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1023 the appropriate glyph row has its `mode_line_p' flag set,
1024 and if it doesn't, uses estimate_mode_line_height instead. */
1026 if (WINDOW_WANTS_MODELINE_P (w))
1028 struct glyph_row *ml_row
1029 = (w->current_matrix && w->current_matrix->rows
1030 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1031 : 0);
1032 if (ml_row && ml_row->mode_line_p)
1033 height -= ml_row->height;
1034 else
1035 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1038 if (WINDOW_WANTS_HEADER_LINE_P (w))
1040 struct glyph_row *hl_row
1041 = (w->current_matrix && w->current_matrix->rows
1042 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1043 : 0);
1044 if (hl_row && hl_row->mode_line_p)
1045 height -= hl_row->height;
1046 else
1047 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1050 /* With a very small font and a mode-line that's taller than
1051 default, we might end up with a negative height. */
1052 return max (0, height);
1055 /* Return the window-relative coordinate of the left edge of display
1056 area AREA of window W. AREA < 0 means return the left edge of the
1057 whole window, to the right of the left fringe of W. */
1060 window_box_left_offset (struct window *w, int area)
1062 int x;
1064 if (w->pseudo_window_p)
1065 return 0;
1067 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1069 if (area == TEXT_AREA)
1070 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1071 + window_box_width (w, LEFT_MARGIN_AREA));
1072 else if (area == RIGHT_MARGIN_AREA)
1073 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1074 + window_box_width (w, LEFT_MARGIN_AREA)
1075 + window_box_width (w, TEXT_AREA)
1076 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1078 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1079 else if (area == LEFT_MARGIN_AREA
1080 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1081 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1083 return x;
1087 /* Return the window-relative coordinate of the right edge of display
1088 area AREA of window W. AREA < 0 means return the right edge of the
1089 whole window, to the left of the right fringe of W. */
1092 window_box_right_offset (struct window *w, int area)
1094 return window_box_left_offset (w, area) + window_box_width (w, area);
1097 /* Return the frame-relative coordinate of the left edge of display
1098 area AREA of window W. AREA < 0 means return the left edge of the
1099 whole window, to the right of the left fringe of W. */
1102 window_box_left (struct window *w, int area)
1104 struct frame *f = XFRAME (w->frame);
1105 int x;
1107 if (w->pseudo_window_p)
1108 return FRAME_INTERNAL_BORDER_WIDTH (f);
1110 x = (WINDOW_LEFT_EDGE_X (w)
1111 + window_box_left_offset (w, area));
1113 return x;
1117 /* Return the frame-relative coordinate of the right edge of display
1118 area AREA of window W. AREA < 0 means return the right edge of the
1119 whole window, to the left of the right fringe of W. */
1122 window_box_right (struct window *w, int area)
1124 return window_box_left (w, area) + window_box_width (w, area);
1127 /* Get the bounding box of the display area AREA of window W, without
1128 mode lines, in frame-relative coordinates. AREA < 0 means the
1129 whole window, not including the left and right fringes of
1130 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1131 coordinates of the upper-left corner of the box. Return in
1132 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1134 void
1135 window_box (struct window *w, int area, int *box_x, int *box_y,
1136 int *box_width, int *box_height)
1138 if (box_width)
1139 *box_width = window_box_width (w, area);
1140 if (box_height)
1141 *box_height = window_box_height (w);
1142 if (box_x)
1143 *box_x = window_box_left (w, area);
1144 if (box_y)
1146 *box_y = WINDOW_TOP_EDGE_Y (w);
1147 if (WINDOW_WANTS_HEADER_LINE_P (w))
1148 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1153 /* Get the bounding box of the display area AREA of window W, without
1154 mode lines. AREA < 0 means the whole window, not including the
1155 left and right fringe of the window. Return in *TOP_LEFT_X
1156 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1157 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1158 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1159 box. */
1161 static void
1162 window_box_edges (struct window *w, int area, int *top_left_x, int *top_left_y,
1163 int *bottom_right_x, int *bottom_right_y)
1165 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1166 bottom_right_y);
1167 *bottom_right_x += *top_left_x;
1168 *bottom_right_y += *top_left_y;
1173 /***********************************************************************
1174 Utilities
1175 ***********************************************************************/
1177 /* Return the bottom y-position of the line the iterator IT is in.
1178 This can modify IT's settings. */
1181 line_bottom_y (struct it *it)
1183 int line_height = it->max_ascent + it->max_descent;
1184 int line_top_y = it->current_y;
1186 if (line_height == 0)
1188 if (last_height)
1189 line_height = last_height;
1190 else if (IT_CHARPOS (*it) < ZV)
1192 move_it_by_lines (it, 1);
1193 line_height = (it->max_ascent || it->max_descent
1194 ? it->max_ascent + it->max_descent
1195 : last_height);
1197 else
1199 struct glyph_row *row = it->glyph_row;
1201 /* Use the default character height. */
1202 it->glyph_row = NULL;
1203 it->what = IT_CHARACTER;
1204 it->c = ' ';
1205 it->len = 1;
1206 PRODUCE_GLYPHS (it);
1207 line_height = it->ascent + it->descent;
1208 it->glyph_row = row;
1212 return line_top_y + line_height;
1215 DEFUN ("line-pixel-height", Fline_pixel_height,
1216 Sline_pixel_height, 0, 0, 0,
1217 doc: /* Return height in pixels of text line in the selected window.
1219 Value is the height in pixels of the line at point. */)
1220 (void)
1222 struct it it;
1223 struct text_pos pt;
1224 struct window *w = XWINDOW (selected_window);
1226 SET_TEXT_POS (pt, PT, PT_BYTE);
1227 start_display (&it, w, pt);
1228 it.vpos = it.current_y = 0;
1229 last_height = 0;
1230 return make_number (line_bottom_y (&it));
1233 /* Return the default pixel height of text lines in window W. The
1234 value is the canonical height of the W frame's default font, plus
1235 any extra space required by the line-spacing variable or frame
1236 parameter.
1238 Implementation note: this ignores any line-spacing text properties
1239 put on the newline characters. This is because those properties
1240 only affect the _screen_ line ending in the newline (i.e., in a
1241 continued line, only the last screen line will be affected), which
1242 means only a small number of lines in a buffer can ever use this
1243 feature. Since this function is used to compute the default pixel
1244 equivalent of text lines in a window, we can safely ignore those
1245 few lines. For the same reasons, we ignore the line-height
1246 properties. */
1248 default_line_pixel_height (struct window *w)
1250 struct frame *f = WINDOW_XFRAME (w);
1251 int height = FRAME_LINE_HEIGHT (f);
1253 if (!FRAME_INITIAL_P (f) && BUFFERP (w->contents))
1255 struct buffer *b = XBUFFER (w->contents);
1256 Lisp_Object val = BVAR (b, extra_line_spacing);
1258 if (NILP (val))
1259 val = BVAR (&buffer_defaults, extra_line_spacing);
1260 if (!NILP (val))
1262 if (RANGED_INTEGERP (0, val, INT_MAX))
1263 height += XFASTINT (val);
1264 else if (FLOATP (val))
1266 int addon = XFLOAT_DATA (val) * height + 0.5;
1268 if (addon >= 0)
1269 height += addon;
1272 else
1273 height += f->extra_line_spacing;
1276 return height;
1279 /* Subroutine of pos_visible_p below. Extracts a display string, if
1280 any, from the display spec given as its argument. */
1281 static Lisp_Object
1282 string_from_display_spec (Lisp_Object spec)
1284 if (CONSP (spec))
1286 while (CONSP (spec))
1288 if (STRINGP (XCAR (spec)))
1289 return XCAR (spec);
1290 spec = XCDR (spec);
1293 else if (VECTORP (spec))
1295 ptrdiff_t i;
1297 for (i = 0; i < ASIZE (spec); i++)
1299 if (STRINGP (AREF (spec, i)))
1300 return AREF (spec, i);
1302 return Qnil;
1305 return spec;
1309 /* Limit insanely large values of W->hscroll on frame F to the largest
1310 value that will still prevent first_visible_x and last_visible_x of
1311 'struct it' from overflowing an int. */
1312 static int
1313 window_hscroll_limited (struct window *w, struct frame *f)
1315 ptrdiff_t window_hscroll = w->hscroll;
1316 int window_text_width = window_box_width (w, TEXT_AREA);
1317 int colwidth = FRAME_COLUMN_WIDTH (f);
1319 if (window_hscroll > (INT_MAX - window_text_width) / colwidth - 1)
1320 window_hscroll = (INT_MAX - window_text_width) / colwidth - 1;
1322 return window_hscroll;
1325 /* Return 1 if position CHARPOS is visible in window W.
1326 CHARPOS < 0 means return info about WINDOW_END position.
1327 If visible, set *X and *Y to pixel coordinates of top left corner.
1328 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1329 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1332 pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
1333 int *rtop, int *rbot, int *rowh, int *vpos)
1335 struct it it;
1336 void *itdata = bidi_shelve_cache ();
1337 struct text_pos top;
1338 int visible_p = 0;
1339 struct buffer *old_buffer = NULL;
1341 if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w))))
1342 return visible_p;
1344 if (XBUFFER (w->contents) != current_buffer)
1346 old_buffer = current_buffer;
1347 set_buffer_internal_1 (XBUFFER (w->contents));
1350 SET_TEXT_POS_FROM_MARKER (top, w->start);
1351 /* Scrolling a minibuffer window via scroll bar when the echo area
1352 shows long text sometimes resets the minibuffer contents behind
1353 our backs. */
1354 if (CHARPOS (top) > ZV)
1355 SET_TEXT_POS (top, BEGV, BEGV_BYTE);
1357 /* Compute exact mode line heights. */
1358 if (WINDOW_WANTS_MODELINE_P (w))
1359 current_mode_line_height
1360 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1361 BVAR (current_buffer, mode_line_format));
1363 if (WINDOW_WANTS_HEADER_LINE_P (w))
1364 current_header_line_height
1365 = display_mode_line (w, HEADER_LINE_FACE_ID,
1366 BVAR (current_buffer, header_line_format));
1368 start_display (&it, w, top);
1369 move_it_to (&it, charpos, -1, it.last_visible_y - 1, -1,
1370 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
1372 if (charpos >= 0
1373 && (((!it.bidi_p || it.bidi_it.scan_dir == 1)
1374 && IT_CHARPOS (it) >= charpos)
1375 /* When scanning backwards under bidi iteration, move_it_to
1376 stops at or _before_ CHARPOS, because it stops at or to
1377 the _right_ of the character at CHARPOS. */
1378 || (it.bidi_p && it.bidi_it.scan_dir == -1
1379 && IT_CHARPOS (it) <= charpos)))
1381 /* We have reached CHARPOS, or passed it. How the call to
1382 move_it_to can overshoot: (i) If CHARPOS is on invisible text
1383 or covered by a display property, move_it_to stops at the end
1384 of the invisible text, to the right of CHARPOS. (ii) If
1385 CHARPOS is in a display vector, move_it_to stops on its last
1386 glyph. */
1387 int top_x = it.current_x;
1388 int top_y = it.current_y;
1389 /* Calling line_bottom_y may change it.method, it.position, etc. */
1390 enum it_method it_method = it.method;
1391 int bottom_y = (last_height = 0, line_bottom_y (&it));
1392 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1394 if (top_y < window_top_y)
1395 visible_p = bottom_y > window_top_y;
1396 else if (top_y < it.last_visible_y)
1397 visible_p = 1;
1398 if (bottom_y >= it.last_visible_y
1399 && it.bidi_p && it.bidi_it.scan_dir == -1
1400 && IT_CHARPOS (it) < charpos)
1402 /* When the last line of the window is scanned backwards
1403 under bidi iteration, we could be duped into thinking
1404 that we have passed CHARPOS, when in fact move_it_to
1405 simply stopped short of CHARPOS because it reached
1406 last_visible_y. To see if that's what happened, we call
1407 move_it_to again with a slightly larger vertical limit,
1408 and see if it actually moved vertically; if it did, we
1409 didn't really reach CHARPOS, which is beyond window end. */
1410 struct it save_it = it;
1411 /* Why 10? because we don't know how many canonical lines
1412 will the height of the next line(s) be. So we guess. */
1413 int ten_more_lines = 10 * default_line_pixel_height (w);
1415 move_it_to (&it, charpos, -1, bottom_y + ten_more_lines, -1,
1416 MOVE_TO_POS | MOVE_TO_Y);
1417 if (it.current_y > top_y)
1418 visible_p = 0;
1420 it = save_it;
1422 if (visible_p)
1424 if (it_method == GET_FROM_DISPLAY_VECTOR)
1426 /* We stopped on the last glyph of a display vector.
1427 Try and recompute. Hack alert! */
1428 if (charpos < 2 || top.charpos >= charpos)
1429 top_x = it.glyph_row->x;
1430 else
1432 struct it it2, it2_prev;
1433 /* The idea is to get to the previous buffer
1434 position, consume the character there, and use
1435 the pixel coordinates we get after that. But if
1436 the previous buffer position is also displayed
1437 from a display vector, we need to consume all of
1438 the glyphs from that display vector. */
1439 start_display (&it2, w, top);
1440 move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS);
1441 /* If we didn't get to CHARPOS - 1, there's some
1442 replacing display property at that position, and
1443 we stopped after it. That is exactly the place
1444 whose coordinates we want. */
1445 if (IT_CHARPOS (it2) != charpos - 1)
1446 it2_prev = it2;
1447 else
1449 /* Iterate until we get out of the display
1450 vector that displays the character at
1451 CHARPOS - 1. */
1452 do {
1453 get_next_display_element (&it2);
1454 PRODUCE_GLYPHS (&it2);
1455 it2_prev = it2;
1456 set_iterator_to_next (&it2, 1);
1457 } while (it2.method == GET_FROM_DISPLAY_VECTOR
1458 && IT_CHARPOS (it2) < charpos);
1460 if (ITERATOR_AT_END_OF_LINE_P (&it2_prev)
1461 || it2_prev.current_x > it2_prev.last_visible_x)
1462 top_x = it.glyph_row->x;
1463 else
1465 top_x = it2_prev.current_x;
1466 top_y = it2_prev.current_y;
1470 else if (IT_CHARPOS (it) != charpos)
1472 Lisp_Object cpos = make_number (charpos);
1473 Lisp_Object spec = Fget_char_property (cpos, Qdisplay, Qnil);
1474 Lisp_Object string = string_from_display_spec (spec);
1475 struct text_pos tpos;
1476 int replacing_spec_p;
1477 bool newline_in_string
1478 = (STRINGP (string)
1479 && memchr (SDATA (string), '\n', SBYTES (string)));
1481 SET_TEXT_POS (tpos, charpos, CHAR_TO_BYTE (charpos));
1482 replacing_spec_p
1483 = (!NILP (spec)
1484 && handle_display_spec (NULL, spec, Qnil, Qnil, &tpos,
1485 charpos, FRAME_WINDOW_P (it.f)));
1486 /* The tricky code below is needed because there's a
1487 discrepancy between move_it_to and how we set cursor
1488 when PT is at the beginning of a portion of text
1489 covered by a display property or an overlay with a
1490 display property, or the display line ends in a
1491 newline from a display string. move_it_to will stop
1492 _after_ such display strings, whereas
1493 set_cursor_from_row conspires with cursor_row_p to
1494 place the cursor on the first glyph produced from the
1495 display string. */
1497 /* We have overshoot PT because it is covered by a
1498 display property that replaces the text it covers.
1499 If the string includes embedded newlines, we are also
1500 in the wrong display line. Backtrack to the correct
1501 line, where the display property begins. */
1502 if (replacing_spec_p)
1504 Lisp_Object startpos, endpos;
1505 EMACS_INT start, end;
1506 struct it it3;
1507 int it3_moved;
1509 /* Find the first and the last buffer positions
1510 covered by the display string. */
1511 endpos =
1512 Fnext_single_char_property_change (cpos, Qdisplay,
1513 Qnil, Qnil);
1514 startpos =
1515 Fprevious_single_char_property_change (endpos, Qdisplay,
1516 Qnil, Qnil);
1517 start = XFASTINT (startpos);
1518 end = XFASTINT (endpos);
1519 /* Move to the last buffer position before the
1520 display property. */
1521 start_display (&it3, w, top);
1522 move_it_to (&it3, start - 1, -1, -1, -1, MOVE_TO_POS);
1523 /* Move forward one more line if the position before
1524 the display string is a newline or if it is the
1525 rightmost character on a line that is
1526 continued or word-wrapped. */
1527 if (it3.method == GET_FROM_BUFFER
1528 && (it3.c == '\n'
1529 || FETCH_BYTE (IT_BYTEPOS (it3)) == '\n'))
1530 move_it_by_lines (&it3, 1);
1531 else if (move_it_in_display_line_to (&it3, -1,
1532 it3.current_x
1533 + it3.pixel_width,
1534 MOVE_TO_X)
1535 == MOVE_LINE_CONTINUED)
1537 move_it_by_lines (&it3, 1);
1538 /* When we are under word-wrap, the #$@%!
1539 move_it_by_lines moves 2 lines, so we need to
1540 fix that up. */
1541 if (it3.line_wrap == WORD_WRAP)
1542 move_it_by_lines (&it3, -1);
1545 /* Record the vertical coordinate of the display
1546 line where we wound up. */
1547 top_y = it3.current_y;
1548 if (it3.bidi_p)
1550 /* When characters are reordered for display,
1551 the character displayed to the left of the
1552 display string could be _after_ the display
1553 property in the logical order. Use the
1554 smallest vertical position of these two. */
1555 start_display (&it3, w, top);
1556 move_it_to (&it3, end + 1, -1, -1, -1, MOVE_TO_POS);
1557 if (it3.current_y < top_y)
1558 top_y = it3.current_y;
1560 /* Move from the top of the window to the beginning
1561 of the display line where the display string
1562 begins. */
1563 start_display (&it3, w, top);
1564 move_it_to (&it3, -1, 0, top_y, -1, MOVE_TO_X | MOVE_TO_Y);
1565 /* If it3_moved stays zero after the 'while' loop
1566 below, that means we already were at a newline
1567 before the loop (e.g., the display string begins
1568 with a newline), so we don't need to (and cannot)
1569 inspect the glyphs of it3.glyph_row, because
1570 PRODUCE_GLYPHS will not produce anything for a
1571 newline, and thus it3.glyph_row stays at its
1572 stale content it got at top of the window. */
1573 it3_moved = 0;
1574 /* Finally, advance the iterator until we hit the
1575 first display element whose character position is
1576 CHARPOS, or until the first newline from the
1577 display string, which signals the end of the
1578 display line. */
1579 while (get_next_display_element (&it3))
1581 PRODUCE_GLYPHS (&it3);
1582 if (IT_CHARPOS (it3) == charpos
1583 || ITERATOR_AT_END_OF_LINE_P (&it3))
1584 break;
1585 it3_moved = 1;
1586 set_iterator_to_next (&it3, 0);
1588 top_x = it3.current_x - it3.pixel_width;
1589 /* Normally, we would exit the above loop because we
1590 found the display element whose character
1591 position is CHARPOS. For the contingency that we
1592 didn't, and stopped at the first newline from the
1593 display string, move back over the glyphs
1594 produced from the string, until we find the
1595 rightmost glyph not from the string. */
1596 if (it3_moved
1597 && newline_in_string
1598 && IT_CHARPOS (it3) != charpos && EQ (it3.object, string))
1600 struct glyph *g = it3.glyph_row->glyphs[TEXT_AREA]
1601 + it3.glyph_row->used[TEXT_AREA];
1603 while (EQ ((g - 1)->object, string))
1605 --g;
1606 top_x -= g->pixel_width;
1608 eassert (g < it3.glyph_row->glyphs[TEXT_AREA]
1609 + it3.glyph_row->used[TEXT_AREA]);
1614 *x = top_x;
1615 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1616 *rtop = max (0, window_top_y - top_y);
1617 *rbot = max (0, bottom_y - it.last_visible_y);
1618 *rowh = max (0, (min (bottom_y, it.last_visible_y)
1619 - max (top_y, window_top_y)));
1620 *vpos = it.vpos;
1623 else
1625 /* We were asked to provide info about WINDOW_END. */
1626 struct it it2;
1627 void *it2data = NULL;
1629 SAVE_IT (it2, it, it2data);
1630 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1631 move_it_by_lines (&it, 1);
1632 if (charpos < IT_CHARPOS (it)
1633 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1635 visible_p = 1;
1636 RESTORE_IT (&it2, &it2, it2data);
1637 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1638 *x = it2.current_x;
1639 *y = it2.current_y + it2.max_ascent - it2.ascent;
1640 *rtop = max (0, -it2.current_y);
1641 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1642 - it.last_visible_y));
1643 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
1644 it.last_visible_y)
1645 - max (it2.current_y,
1646 WINDOW_HEADER_LINE_HEIGHT (w))));
1647 *vpos = it2.vpos;
1649 else
1650 bidi_unshelve_cache (it2data, 1);
1652 bidi_unshelve_cache (itdata, 0);
1654 if (old_buffer)
1655 set_buffer_internal_1 (old_buffer);
1657 current_header_line_height = current_mode_line_height = -1;
1659 if (visible_p && w->hscroll > 0)
1660 *x -=
1661 window_hscroll_limited (w, WINDOW_XFRAME (w))
1662 * WINDOW_FRAME_COLUMN_WIDTH (w);
1664 #if 0
1665 /* Debugging code. */
1666 if (visible_p)
1667 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1668 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
1669 else
1670 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
1671 #endif
1673 return visible_p;
1677 /* Return the next character from STR. Return in *LEN the length of
1678 the character. This is like STRING_CHAR_AND_LENGTH but never
1679 returns an invalid character. If we find one, we return a `?', but
1680 with the length of the invalid character. */
1682 static int
1683 string_char_and_length (const unsigned char *str, int *len)
1685 int c;
1687 c = STRING_CHAR_AND_LENGTH (str, *len);
1688 if (!CHAR_VALID_P (c))
1689 /* We may not change the length here because other places in Emacs
1690 don't use this function, i.e. they silently accept invalid
1691 characters. */
1692 c = '?';
1694 return c;
1699 /* Given a position POS containing a valid character and byte position
1700 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1702 static struct text_pos
1703 string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, ptrdiff_t nchars)
1705 eassert (STRINGP (string) && nchars >= 0);
1707 if (STRING_MULTIBYTE (string))
1709 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1710 int len;
1712 while (nchars--)
1714 string_char_and_length (p, &len);
1715 p += len;
1716 CHARPOS (pos) += 1;
1717 BYTEPOS (pos) += len;
1720 else
1721 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1723 return pos;
1727 /* Value is the text position, i.e. character and byte position,
1728 for character position CHARPOS in STRING. */
1730 static struct text_pos
1731 string_pos (ptrdiff_t charpos, Lisp_Object string)
1733 struct text_pos pos;
1734 eassert (STRINGP (string));
1735 eassert (charpos >= 0);
1736 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1737 return pos;
1741 /* Value is a text position, i.e. character and byte position, for
1742 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1743 means recognize multibyte characters. */
1745 static struct text_pos
1746 c_string_pos (ptrdiff_t charpos, const char *s, bool multibyte_p)
1748 struct text_pos pos;
1750 eassert (s != NULL);
1751 eassert (charpos >= 0);
1753 if (multibyte_p)
1755 int len;
1757 SET_TEXT_POS (pos, 0, 0);
1758 while (charpos--)
1760 string_char_and_length ((const unsigned char *) s, &len);
1761 s += len;
1762 CHARPOS (pos) += 1;
1763 BYTEPOS (pos) += len;
1766 else
1767 SET_TEXT_POS (pos, charpos, charpos);
1769 return pos;
1773 /* Value is the number of characters in C string S. MULTIBYTE_P
1774 non-zero means recognize multibyte characters. */
1776 static ptrdiff_t
1777 number_of_chars (const char *s, bool multibyte_p)
1779 ptrdiff_t nchars;
1781 if (multibyte_p)
1783 ptrdiff_t rest = strlen (s);
1784 int len;
1785 const unsigned char *p = (const unsigned char *) s;
1787 for (nchars = 0; rest > 0; ++nchars)
1789 string_char_and_length (p, &len);
1790 rest -= len, p += len;
1793 else
1794 nchars = strlen (s);
1796 return nchars;
1800 /* Compute byte position NEWPOS->bytepos corresponding to
1801 NEWPOS->charpos. POS is a known position in string STRING.
1802 NEWPOS->charpos must be >= POS.charpos. */
1804 static void
1805 compute_string_pos (struct text_pos *newpos, struct text_pos pos, Lisp_Object string)
1807 eassert (STRINGP (string));
1808 eassert (CHARPOS (*newpos) >= CHARPOS (pos));
1810 if (STRING_MULTIBYTE (string))
1811 *newpos = string_pos_nchars_ahead (pos, string,
1812 CHARPOS (*newpos) - CHARPOS (pos));
1813 else
1814 BYTEPOS (*newpos) = CHARPOS (*newpos);
1817 /* EXPORT:
1818 Return an estimation of the pixel height of mode or header lines on
1819 frame F. FACE_ID specifies what line's height to estimate. */
1822 estimate_mode_line_height (struct frame *f, enum face_id face_id)
1824 #ifdef HAVE_WINDOW_SYSTEM
1825 if (FRAME_WINDOW_P (f))
1827 int height = FONT_HEIGHT (FRAME_FONT (f));
1829 /* This function is called so early when Emacs starts that the face
1830 cache and mode line face are not yet initialized. */
1831 if (FRAME_FACE_CACHE (f))
1833 struct face *face = FACE_FROM_ID (f, face_id);
1834 if (face)
1836 if (face->font)
1837 height = FONT_HEIGHT (face->font);
1838 if (face->box_line_width > 0)
1839 height += 2 * face->box_line_width;
1843 return height;
1845 #endif
1847 return 1;
1850 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1851 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1852 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1853 not force the value into range. */
1855 void
1856 pixel_to_glyph_coords (struct frame *f, register int pix_x, register int pix_y,
1857 int *x, int *y, NativeRectangle *bounds, int noclip)
1860 #ifdef HAVE_WINDOW_SYSTEM
1861 if (FRAME_WINDOW_P (f))
1863 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1864 even for negative values. */
1865 if (pix_x < 0)
1866 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1867 if (pix_y < 0)
1868 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1870 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1871 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1873 if (bounds)
1874 STORE_NATIVE_RECT (*bounds,
1875 FRAME_COL_TO_PIXEL_X (f, pix_x),
1876 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1877 FRAME_COLUMN_WIDTH (f) - 1,
1878 FRAME_LINE_HEIGHT (f) - 1);
1880 if (!noclip)
1882 if (pix_x < 0)
1883 pix_x = 0;
1884 else if (pix_x > FRAME_TOTAL_COLS (f))
1885 pix_x = FRAME_TOTAL_COLS (f);
1887 if (pix_y < 0)
1888 pix_y = 0;
1889 else if (pix_y > FRAME_LINES (f))
1890 pix_y = FRAME_LINES (f);
1893 #endif
1895 *x = pix_x;
1896 *y = pix_y;
1900 /* Find the glyph under window-relative coordinates X/Y in window W.
1901 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1902 strings. Return in *HPOS and *VPOS the row and column number of
1903 the glyph found. Return in *AREA the glyph area containing X.
1904 Value is a pointer to the glyph found or null if X/Y is not on
1905 text, or we can't tell because W's current matrix is not up to
1906 date. */
1908 static
1909 struct glyph *
1910 x_y_to_hpos_vpos (struct window *w, int x, int y, int *hpos, int *vpos,
1911 int *dx, int *dy, int *area)
1913 struct glyph *glyph, *end;
1914 struct glyph_row *row = NULL;
1915 int x0, i;
1917 /* Find row containing Y. Give up if some row is not enabled. */
1918 for (i = 0; i < w->current_matrix->nrows; ++i)
1920 row = MATRIX_ROW (w->current_matrix, i);
1921 if (!row->enabled_p)
1922 return NULL;
1923 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1924 break;
1927 *vpos = i;
1928 *hpos = 0;
1930 /* Give up if Y is not in the window. */
1931 if (i == w->current_matrix->nrows)
1932 return NULL;
1934 /* Get the glyph area containing X. */
1935 if (w->pseudo_window_p)
1937 *area = TEXT_AREA;
1938 x0 = 0;
1940 else
1942 if (x < window_box_left_offset (w, TEXT_AREA))
1944 *area = LEFT_MARGIN_AREA;
1945 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1947 else if (x < window_box_right_offset (w, TEXT_AREA))
1949 *area = TEXT_AREA;
1950 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1952 else
1954 *area = RIGHT_MARGIN_AREA;
1955 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1959 /* Find glyph containing X. */
1960 glyph = row->glyphs[*area];
1961 end = glyph + row->used[*area];
1962 x -= x0;
1963 while (glyph < end && x >= glyph->pixel_width)
1965 x -= glyph->pixel_width;
1966 ++glyph;
1969 if (glyph == end)
1970 return NULL;
1972 if (dx)
1974 *dx = x;
1975 *dy = y - (row->y + row->ascent - glyph->ascent);
1978 *hpos = glyph - row->glyphs[*area];
1979 return glyph;
1982 /* Convert frame-relative x/y to coordinates relative to window W.
1983 Takes pseudo-windows into account. */
1985 static void
1986 frame_to_window_pixel_xy (struct window *w, int *x, int *y)
1988 if (w->pseudo_window_p)
1990 /* A pseudo-window is always full-width, and starts at the
1991 left edge of the frame, plus a frame border. */
1992 struct frame *f = XFRAME (w->frame);
1993 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1994 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1996 else
1998 *x -= WINDOW_LEFT_EDGE_X (w);
1999 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
2003 #ifdef HAVE_WINDOW_SYSTEM
2005 /* EXPORT:
2006 Return in RECTS[] at most N clipping rectangles for glyph string S.
2007 Return the number of stored rectangles. */
2010 get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int n)
2012 XRectangle r;
2014 if (n <= 0)
2015 return 0;
2017 if (s->row->full_width_p)
2019 /* Draw full-width. X coordinates are relative to S->w->left_col. */
2020 r.x = WINDOW_LEFT_EDGE_X (s->w);
2021 r.width = WINDOW_TOTAL_WIDTH (s->w);
2023 /* Unless displaying a mode or menu bar line, which are always
2024 fully visible, clip to the visible part of the row. */
2025 if (s->w->pseudo_window_p)
2026 r.height = s->row->visible_height;
2027 else
2028 r.height = s->height;
2030 else
2032 /* This is a text line that may be partially visible. */
2033 r.x = window_box_left (s->w, s->area);
2034 r.width = window_box_width (s->w, s->area);
2035 r.height = s->row->visible_height;
2038 if (s->clip_head)
2039 if (r.x < s->clip_head->x)
2041 if (r.width >= s->clip_head->x - r.x)
2042 r.width -= s->clip_head->x - r.x;
2043 else
2044 r.width = 0;
2045 r.x = s->clip_head->x;
2047 if (s->clip_tail)
2048 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
2050 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
2051 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
2052 else
2053 r.width = 0;
2056 /* If S draws overlapping rows, it's sufficient to use the top and
2057 bottom of the window for clipping because this glyph string
2058 intentionally draws over other lines. */
2059 if (s->for_overlaps)
2061 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2062 r.height = window_text_bottom_y (s->w) - r.y;
2064 /* Alas, the above simple strategy does not work for the
2065 environments with anti-aliased text: if the same text is
2066 drawn onto the same place multiple times, it gets thicker.
2067 If the overlap we are processing is for the erased cursor, we
2068 take the intersection with the rectangle of the cursor. */
2069 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
2071 XRectangle rc, r_save = r;
2073 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
2074 rc.y = s->w->phys_cursor.y;
2075 rc.width = s->w->phys_cursor_width;
2076 rc.height = s->w->phys_cursor_height;
2078 x_intersect_rectangles (&r_save, &rc, &r);
2081 else
2083 /* Don't use S->y for clipping because it doesn't take partially
2084 visible lines into account. For example, it can be negative for
2085 partially visible lines at the top of a window. */
2086 if (!s->row->full_width_p
2087 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
2088 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2089 else
2090 r.y = max (0, s->row->y);
2093 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
2095 /* If drawing the cursor, don't let glyph draw outside its
2096 advertised boundaries. Cleartype does this under some circumstances. */
2097 if (s->hl == DRAW_CURSOR)
2099 struct glyph *glyph = s->first_glyph;
2100 int height, max_y;
2102 if (s->x > r.x)
2104 r.width -= s->x - r.x;
2105 r.x = s->x;
2107 r.width = min (r.width, glyph->pixel_width);
2109 /* If r.y is below window bottom, ensure that we still see a cursor. */
2110 height = min (glyph->ascent + glyph->descent,
2111 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
2112 max_y = window_text_bottom_y (s->w) - height;
2113 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
2114 if (s->ybase - glyph->ascent > max_y)
2116 r.y = max_y;
2117 r.height = height;
2119 else
2121 /* Don't draw cursor glyph taller than our actual glyph. */
2122 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
2123 if (height < r.height)
2125 max_y = r.y + r.height;
2126 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
2127 r.height = min (max_y - r.y, height);
2132 if (s->row->clip)
2134 XRectangle r_save = r;
2136 if (! x_intersect_rectangles (&r_save, s->row->clip, &r))
2137 r.width = 0;
2140 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
2141 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
2143 #ifdef CONVERT_FROM_XRECT
2144 CONVERT_FROM_XRECT (r, *rects);
2145 #else
2146 *rects = r;
2147 #endif
2148 return 1;
2150 else
2152 /* If we are processing overlapping and allowed to return
2153 multiple clipping rectangles, we exclude the row of the glyph
2154 string from the clipping rectangle. This is to avoid drawing
2155 the same text on the environment with anti-aliasing. */
2156 #ifdef CONVERT_FROM_XRECT
2157 XRectangle rs[2];
2158 #else
2159 XRectangle *rs = rects;
2160 #endif
2161 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
2163 if (s->for_overlaps & OVERLAPS_PRED)
2165 rs[i] = r;
2166 if (r.y + r.height > row_y)
2168 if (r.y < row_y)
2169 rs[i].height = row_y - r.y;
2170 else
2171 rs[i].height = 0;
2173 i++;
2175 if (s->for_overlaps & OVERLAPS_SUCC)
2177 rs[i] = r;
2178 if (r.y < row_y + s->row->visible_height)
2180 if (r.y + r.height > row_y + s->row->visible_height)
2182 rs[i].y = row_y + s->row->visible_height;
2183 rs[i].height = r.y + r.height - rs[i].y;
2185 else
2186 rs[i].height = 0;
2188 i++;
2191 n = i;
2192 #ifdef CONVERT_FROM_XRECT
2193 for (i = 0; i < n; i++)
2194 CONVERT_FROM_XRECT (rs[i], rects[i]);
2195 #endif
2196 return n;
2200 /* EXPORT:
2201 Return in *NR the clipping rectangle for glyph string S. */
2203 void
2204 get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr)
2206 get_glyph_string_clip_rects (s, nr, 1);
2210 /* EXPORT:
2211 Return the position and height of the phys cursor in window W.
2212 Set w->phys_cursor_width to width of phys cursor.
2215 void
2216 get_phys_cursor_geometry (struct window *w, struct glyph_row *row,
2217 struct glyph *glyph, int *xp, int *yp, int *heightp)
2219 struct frame *f = XFRAME (WINDOW_FRAME (w));
2220 int x, y, wd, h, h0, y0;
2222 /* Compute the width of the rectangle to draw. If on a stretch
2223 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2224 rectangle as wide as the glyph, but use a canonical character
2225 width instead. */
2226 wd = glyph->pixel_width - 1;
2227 #if defined (HAVE_NTGUI) || defined (HAVE_NS)
2228 wd++; /* Why? */
2229 #endif
2231 x = w->phys_cursor.x;
2232 if (x < 0)
2234 wd += x;
2235 x = 0;
2238 if (glyph->type == STRETCH_GLYPH
2239 && !x_stretch_cursor_p)
2240 wd = min (FRAME_COLUMN_WIDTH (f), wd);
2241 w->phys_cursor_width = wd;
2243 y = w->phys_cursor.y + row->ascent - glyph->ascent;
2245 /* If y is below window bottom, ensure that we still see a cursor. */
2246 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
2248 h = max (h0, glyph->ascent + glyph->descent);
2249 h0 = min (h0, glyph->ascent + glyph->descent);
2251 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
2252 if (y < y0)
2254 h = max (h - (y0 - y) + 1, h0);
2255 y = y0 - 1;
2257 else
2259 y0 = window_text_bottom_y (w) - h0;
2260 if (y > y0)
2262 h += y - y0;
2263 y = y0;
2267 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
2268 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
2269 *heightp = h;
2273 * Remember which glyph the mouse is over.
2276 void
2277 remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
2279 Lisp_Object window;
2280 struct window *w;
2281 struct glyph_row *r, *gr, *end_row;
2282 enum window_part part;
2283 enum glyph_row_area area;
2284 int x, y, width, height;
2286 /* Try to determine frame pixel position and size of the glyph under
2287 frame pixel coordinates X/Y on frame F. */
2289 if (!f->glyphs_initialized_p
2290 || (window = window_from_coordinates (f, gx, gy, &part, 0),
2291 NILP (window)))
2293 width = FRAME_SMALLEST_CHAR_WIDTH (f);
2294 height = FRAME_SMALLEST_FONT_HEIGHT (f);
2295 goto virtual_glyph;
2298 w = XWINDOW (window);
2299 width = WINDOW_FRAME_COLUMN_WIDTH (w);
2300 height = WINDOW_FRAME_LINE_HEIGHT (w);
2302 x = window_relative_x_coord (w, part, gx);
2303 y = gy - WINDOW_TOP_EDGE_Y (w);
2305 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
2306 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
2308 if (w->pseudo_window_p)
2310 area = TEXT_AREA;
2311 part = ON_MODE_LINE; /* Don't adjust margin. */
2312 goto text_glyph;
2315 switch (part)
2317 case ON_LEFT_MARGIN:
2318 area = LEFT_MARGIN_AREA;
2319 goto text_glyph;
2321 case ON_RIGHT_MARGIN:
2322 area = RIGHT_MARGIN_AREA;
2323 goto text_glyph;
2325 case ON_HEADER_LINE:
2326 case ON_MODE_LINE:
2327 gr = (part == ON_HEADER_LINE
2328 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
2329 : MATRIX_MODE_LINE_ROW (w->current_matrix));
2330 gy = gr->y;
2331 area = TEXT_AREA;
2332 goto text_glyph_row_found;
2334 case ON_TEXT:
2335 area = TEXT_AREA;
2337 text_glyph:
2338 gr = 0; gy = 0;
2339 for (; r <= end_row && r->enabled_p; ++r)
2340 if (r->y + r->height > y)
2342 gr = r; gy = r->y;
2343 break;
2346 text_glyph_row_found:
2347 if (gr && gy <= y)
2349 struct glyph *g = gr->glyphs[area];
2350 struct glyph *end = g + gr->used[area];
2352 height = gr->height;
2353 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2354 if (gx + g->pixel_width > x)
2355 break;
2357 if (g < end)
2359 if (g->type == IMAGE_GLYPH)
2361 /* Don't remember when mouse is over image, as
2362 image may have hot-spots. */
2363 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2364 return;
2366 width = g->pixel_width;
2368 else
2370 /* Use nominal char spacing at end of line. */
2371 x -= gx;
2372 gx += (x / width) * width;
2375 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2376 gx += window_box_left_offset (w, area);
2378 else
2380 /* Use nominal line height at end of window. */
2381 gx = (x / width) * width;
2382 y -= gy;
2383 gy += (y / height) * height;
2385 break;
2387 case ON_LEFT_FRINGE:
2388 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2389 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2390 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2391 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2392 goto row_glyph;
2394 case ON_RIGHT_FRINGE:
2395 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2396 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2397 : window_box_right_offset (w, TEXT_AREA));
2398 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2399 goto row_glyph;
2401 case ON_SCROLL_BAR:
2402 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2404 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2405 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2406 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2407 : 0)));
2408 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2410 row_glyph:
2411 gr = 0, gy = 0;
2412 for (; r <= end_row && r->enabled_p; ++r)
2413 if (r->y + r->height > y)
2415 gr = r; gy = r->y;
2416 break;
2419 if (gr && gy <= y)
2420 height = gr->height;
2421 else
2423 /* Use nominal line height at end of window. */
2424 y -= gy;
2425 gy += (y / height) * height;
2427 break;
2429 default:
2431 virtual_glyph:
2432 /* If there is no glyph under the mouse, then we divide the screen
2433 into a grid of the smallest glyph in the frame, and use that
2434 as our "glyph". */
2436 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2437 round down even for negative values. */
2438 if (gx < 0)
2439 gx -= width - 1;
2440 if (gy < 0)
2441 gy -= height - 1;
2443 gx = (gx / width) * width;
2444 gy = (gy / height) * height;
2446 goto store_rect;
2449 gx += WINDOW_LEFT_EDGE_X (w);
2450 gy += WINDOW_TOP_EDGE_Y (w);
2452 store_rect:
2453 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2455 /* Visible feedback for debugging. */
2456 #if 0
2457 #if HAVE_X_WINDOWS
2458 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2459 f->output_data.x->normal_gc,
2460 gx, gy, width, height);
2461 #endif
2462 #endif
2466 #endif /* HAVE_WINDOW_SYSTEM */
2469 /***********************************************************************
2470 Lisp form evaluation
2471 ***********************************************************************/
2473 /* Error handler for safe_eval and safe_call. */
2475 static Lisp_Object
2476 safe_eval_handler (Lisp_Object arg, ptrdiff_t nargs, Lisp_Object *args)
2478 add_to_log ("Error during redisplay: %S signaled %S",
2479 Flist (nargs, args), arg);
2480 return Qnil;
2483 /* Call function FUNC with the rest of NARGS - 1 arguments
2484 following. Return the result, or nil if something went
2485 wrong. Prevent redisplay during the evaluation. */
2487 Lisp_Object
2488 safe_call (ptrdiff_t nargs, Lisp_Object func, ...)
2490 Lisp_Object val;
2492 if (inhibit_eval_during_redisplay)
2493 val = Qnil;
2494 else
2496 va_list ap;
2497 ptrdiff_t i;
2498 ptrdiff_t count = SPECPDL_INDEX ();
2499 struct gcpro gcpro1;
2500 Lisp_Object *args = alloca (nargs * word_size);
2502 args[0] = func;
2503 va_start (ap, func);
2504 for (i = 1; i < nargs; i++)
2505 args[i] = va_arg (ap, Lisp_Object);
2506 va_end (ap);
2508 GCPRO1 (args[0]);
2509 gcpro1.nvars = nargs;
2510 specbind (Qinhibit_redisplay, Qt);
2511 /* Use Qt to ensure debugger does not run,
2512 so there is no possibility of wanting to redisplay. */
2513 val = internal_condition_case_n (Ffuncall, nargs, args, Qt,
2514 safe_eval_handler);
2515 UNGCPRO;
2516 val = unbind_to (count, val);
2519 return val;
2523 /* Call function FN with one argument ARG.
2524 Return the result, or nil if something went wrong. */
2526 Lisp_Object
2527 safe_call1 (Lisp_Object fn, Lisp_Object arg)
2529 return safe_call (2, fn, arg);
2532 static Lisp_Object Qeval;
2534 Lisp_Object
2535 safe_eval (Lisp_Object sexpr)
2537 return safe_call1 (Qeval, sexpr);
2540 /* Call function FN with two arguments ARG1 and ARG2.
2541 Return the result, or nil if something went wrong. */
2543 Lisp_Object
2544 safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
2546 return safe_call (3, fn, arg1, arg2);
2551 /***********************************************************************
2552 Debugging
2553 ***********************************************************************/
2555 #if 0
2557 /* Define CHECK_IT to perform sanity checks on iterators.
2558 This is for debugging. It is too slow to do unconditionally. */
2560 static void
2561 check_it (struct it *it)
2563 if (it->method == GET_FROM_STRING)
2565 eassert (STRINGP (it->string));
2566 eassert (IT_STRING_CHARPOS (*it) >= 0);
2568 else
2570 eassert (IT_STRING_CHARPOS (*it) < 0);
2571 if (it->method == GET_FROM_BUFFER)
2573 /* Check that character and byte positions agree. */
2574 eassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2578 if (it->dpvec)
2579 eassert (it->current.dpvec_index >= 0);
2580 else
2581 eassert (it->current.dpvec_index < 0);
2584 #define CHECK_IT(IT) check_it ((IT))
2586 #else /* not 0 */
2588 #define CHECK_IT(IT) (void) 0
2590 #endif /* not 0 */
2593 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2595 /* Check that the window end of window W is what we expect it
2596 to be---the last row in the current matrix displaying text. */
2598 static void
2599 check_window_end (struct window *w)
2601 if (!MINI_WINDOW_P (w) && w->window_end_valid)
2603 struct glyph_row *row;
2604 eassert ((row = MATRIX_ROW (w->current_matrix,
2605 XFASTINT (w->window_end_vpos)),
2606 !row->enabled_p
2607 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2608 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2612 #define CHECK_WINDOW_END(W) check_window_end ((W))
2614 #else
2616 #define CHECK_WINDOW_END(W) (void) 0
2618 #endif /* GLYPH_DEBUG and ENABLE_CHECKING */
2620 /* Return mark position if current buffer has the region of non-zero length,
2621 or -1 otherwise. */
2623 static ptrdiff_t
2624 markpos_of_region (void)
2626 if (!NILP (Vtransient_mark_mode)
2627 && !NILP (BVAR (current_buffer, mark_active))
2628 && XMARKER (BVAR (current_buffer, mark))->buffer != NULL)
2630 ptrdiff_t markpos = XMARKER (BVAR (current_buffer, mark))->charpos;
2632 if (markpos != PT)
2633 return markpos;
2635 return -1;
2638 /***********************************************************************
2639 Iterator initialization
2640 ***********************************************************************/
2642 /* Initialize IT for displaying current_buffer in window W, starting
2643 at character position CHARPOS. CHARPOS < 0 means that no buffer
2644 position is specified which is useful when the iterator is assigned
2645 a position later. BYTEPOS is the byte position corresponding to
2646 CHARPOS.
2648 If ROW is not null, calls to produce_glyphs with IT as parameter
2649 will produce glyphs in that row.
2651 BASE_FACE_ID is the id of a base face to use. It must be one of
2652 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2653 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2654 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2656 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2657 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2658 will be initialized to use the corresponding mode line glyph row of
2659 the desired matrix of W. */
2661 void
2662 init_iterator (struct it *it, struct window *w,
2663 ptrdiff_t charpos, ptrdiff_t bytepos,
2664 struct glyph_row *row, enum face_id base_face_id)
2666 ptrdiff_t markpos;
2667 enum face_id remapped_base_face_id = base_face_id;
2669 /* Some precondition checks. */
2670 eassert (w != NULL && it != NULL);
2671 eassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2672 && charpos <= ZV));
2674 /* If face attributes have been changed since the last redisplay,
2675 free realized faces now because they depend on face definitions
2676 that might have changed. Don't free faces while there might be
2677 desired matrices pending which reference these faces. */
2678 if (face_change_count && !inhibit_free_realized_faces)
2680 face_change_count = 0;
2681 free_all_realized_faces (Qnil);
2684 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
2685 if (! NILP (Vface_remapping_alist))
2686 remapped_base_face_id
2687 = lookup_basic_face (XFRAME (w->frame), base_face_id);
2689 /* Use one of the mode line rows of W's desired matrix if
2690 appropriate. */
2691 if (row == NULL)
2693 if (base_face_id == MODE_LINE_FACE_ID
2694 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2695 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2696 else if (base_face_id == HEADER_LINE_FACE_ID)
2697 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2700 /* Clear IT. */
2701 memset (it, 0, sizeof *it);
2702 it->current.overlay_string_index = -1;
2703 it->current.dpvec_index = -1;
2704 it->base_face_id = remapped_base_face_id;
2705 it->string = Qnil;
2706 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2707 it->paragraph_embedding = L2R;
2708 it->bidi_it.string.lstring = Qnil;
2709 it->bidi_it.string.s = NULL;
2710 it->bidi_it.string.bufpos = 0;
2711 it->bidi_it.w = w;
2713 /* The window in which we iterate over current_buffer: */
2714 XSETWINDOW (it->window, w);
2715 it->w = w;
2716 it->f = XFRAME (w->frame);
2718 it->cmp_it.id = -1;
2720 /* Extra space between lines (on window systems only). */
2721 if (base_face_id == DEFAULT_FACE_ID
2722 && FRAME_WINDOW_P (it->f))
2724 if (NATNUMP (BVAR (current_buffer, extra_line_spacing)))
2725 it->extra_line_spacing = XFASTINT (BVAR (current_buffer, extra_line_spacing));
2726 else if (FLOATP (BVAR (current_buffer, extra_line_spacing)))
2727 it->extra_line_spacing = (XFLOAT_DATA (BVAR (current_buffer, extra_line_spacing))
2728 * FRAME_LINE_HEIGHT (it->f));
2729 else if (it->f->extra_line_spacing > 0)
2730 it->extra_line_spacing = it->f->extra_line_spacing;
2731 it->max_extra_line_spacing = 0;
2734 /* If realized faces have been removed, e.g. because of face
2735 attribute changes of named faces, recompute them. When running
2736 in batch mode, the face cache of the initial frame is null. If
2737 we happen to get called, make a dummy face cache. */
2738 if (FRAME_FACE_CACHE (it->f) == NULL)
2739 init_frame_faces (it->f);
2740 if (FRAME_FACE_CACHE (it->f)->used == 0)
2741 recompute_basic_faces (it->f);
2743 /* Current value of the `slice', `space-width', and 'height' properties. */
2744 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2745 it->space_width = Qnil;
2746 it->font_height = Qnil;
2747 it->override_ascent = -1;
2749 /* Are control characters displayed as `^C'? */
2750 it->ctl_arrow_p = !NILP (BVAR (current_buffer, ctl_arrow));
2752 /* -1 means everything between a CR and the following line end
2753 is invisible. >0 means lines indented more than this value are
2754 invisible. */
2755 it->selective = (INTEGERP (BVAR (current_buffer, selective_display))
2756 ? (clip_to_bounds
2757 (-1, XINT (BVAR (current_buffer, selective_display)),
2758 PTRDIFF_MAX))
2759 : (!NILP (BVAR (current_buffer, selective_display))
2760 ? -1 : 0));
2761 it->selective_display_ellipsis_p
2762 = !NILP (BVAR (current_buffer, selective_display_ellipses));
2764 /* Display table to use. */
2765 it->dp = window_display_table (w);
2767 /* Are multibyte characters enabled in current_buffer? */
2768 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
2770 /* If visible region is of non-zero length, set IT->region_beg_charpos
2771 and IT->region_end_charpos to the start and end of a visible region
2772 in window IT->w. Set both to -1 to indicate no region. */
2773 markpos = markpos_of_region ();
2774 if (markpos >= 0
2775 /* Maybe highlight only in selected window. */
2776 && (/* Either show region everywhere. */
2777 highlight_nonselected_windows
2778 /* Or show region in the selected window. */
2779 || w == XWINDOW (selected_window)
2780 /* Or show the region if we are in the mini-buffer and W is
2781 the window the mini-buffer refers to. */
2782 || (MINI_WINDOW_P (XWINDOW (selected_window))
2783 && WINDOWP (minibuf_selected_window)
2784 && w == XWINDOW (minibuf_selected_window))))
2786 it->region_beg_charpos = min (PT, markpos);
2787 it->region_end_charpos = max (PT, markpos);
2789 else
2790 it->region_beg_charpos = it->region_end_charpos = -1;
2792 /* Get the position at which the redisplay_end_trigger hook should
2793 be run, if it is to be run at all. */
2794 if (MARKERP (w->redisplay_end_trigger)
2795 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2796 it->redisplay_end_trigger_charpos
2797 = marker_position (w->redisplay_end_trigger);
2798 else if (INTEGERP (w->redisplay_end_trigger))
2799 it->redisplay_end_trigger_charpos =
2800 clip_to_bounds (PTRDIFF_MIN, XINT (w->redisplay_end_trigger), PTRDIFF_MAX);
2802 it->tab_width = SANE_TAB_WIDTH (current_buffer);
2804 /* Are lines in the display truncated? */
2805 if (base_face_id != DEFAULT_FACE_ID
2806 || it->w->hscroll
2807 || (! WINDOW_FULL_WIDTH_P (it->w)
2808 && ((!NILP (Vtruncate_partial_width_windows)
2809 && !INTEGERP (Vtruncate_partial_width_windows))
2810 || (INTEGERP (Vtruncate_partial_width_windows)
2811 && (WINDOW_TOTAL_COLS (it->w)
2812 < XINT (Vtruncate_partial_width_windows))))))
2813 it->line_wrap = TRUNCATE;
2814 else if (NILP (BVAR (current_buffer, truncate_lines)))
2815 it->line_wrap = NILP (BVAR (current_buffer, word_wrap))
2816 ? WINDOW_WRAP : WORD_WRAP;
2817 else
2818 it->line_wrap = TRUNCATE;
2820 /* Get dimensions of truncation and continuation glyphs. These are
2821 displayed as fringe bitmaps under X, but we need them for such
2822 frames when the fringes are turned off. But leave the dimensions
2823 zero for tooltip frames, as these glyphs look ugly there and also
2824 sabotage calculations of tooltip dimensions in x-show-tip. */
2825 #ifdef HAVE_WINDOW_SYSTEM
2826 if (!(FRAME_WINDOW_P (it->f)
2827 && FRAMEP (tip_frame)
2828 && it->f == XFRAME (tip_frame)))
2829 #endif
2831 if (it->line_wrap == TRUNCATE)
2833 /* We will need the truncation glyph. */
2834 eassert (it->glyph_row == NULL);
2835 produce_special_glyphs (it, IT_TRUNCATION);
2836 it->truncation_pixel_width = it->pixel_width;
2838 else
2840 /* We will need the continuation glyph. */
2841 eassert (it->glyph_row == NULL);
2842 produce_special_glyphs (it, IT_CONTINUATION);
2843 it->continuation_pixel_width = it->pixel_width;
2847 /* Reset these values to zero because the produce_special_glyphs
2848 above has changed them. */
2849 it->pixel_width = it->ascent = it->descent = 0;
2850 it->phys_ascent = it->phys_descent = 0;
2852 /* Set this after getting the dimensions of truncation and
2853 continuation glyphs, so that we don't produce glyphs when calling
2854 produce_special_glyphs, above. */
2855 it->glyph_row = row;
2856 it->area = TEXT_AREA;
2858 /* Forget any previous info about this row being reversed. */
2859 if (it->glyph_row)
2860 it->glyph_row->reversed_p = 0;
2862 /* Get the dimensions of the display area. The display area
2863 consists of the visible window area plus a horizontally scrolled
2864 part to the left of the window. All x-values are relative to the
2865 start of this total display area. */
2866 if (base_face_id != DEFAULT_FACE_ID)
2868 /* Mode lines, menu bar in terminal frames. */
2869 it->first_visible_x = 0;
2870 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2872 else
2874 it->first_visible_x =
2875 window_hscroll_limited (it->w, it->f) * FRAME_COLUMN_WIDTH (it->f);
2876 it->last_visible_x = (it->first_visible_x
2877 + window_box_width (w, TEXT_AREA));
2879 /* If we truncate lines, leave room for the truncation glyph(s) at
2880 the right margin. Otherwise, leave room for the continuation
2881 glyph(s). Done only if the window has no fringes. Since we
2882 don't know at this point whether there will be any R2L lines in
2883 the window, we reserve space for truncation/continuation glyphs
2884 even if only one of the fringes is absent. */
2885 if (WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
2886 || (it->bidi_p && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0))
2888 if (it->line_wrap == TRUNCATE)
2889 it->last_visible_x -= it->truncation_pixel_width;
2890 else
2891 it->last_visible_x -= it->continuation_pixel_width;
2894 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2895 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2898 /* Leave room for a border glyph. */
2899 if (!FRAME_WINDOW_P (it->f)
2900 && !WINDOW_RIGHTMOST_P (it->w))
2901 it->last_visible_x -= 1;
2903 it->last_visible_y = window_text_bottom_y (w);
2905 /* For mode lines and alike, arrange for the first glyph having a
2906 left box line if the face specifies a box. */
2907 if (base_face_id != DEFAULT_FACE_ID)
2909 struct face *face;
2911 it->face_id = remapped_base_face_id;
2913 /* If we have a boxed mode line, make the first character appear
2914 with a left box line. */
2915 face = FACE_FROM_ID (it->f, remapped_base_face_id);
2916 if (face->box != FACE_NO_BOX)
2917 it->start_of_box_run_p = 1;
2920 /* If a buffer position was specified, set the iterator there,
2921 getting overlays and face properties from that position. */
2922 if (charpos >= BUF_BEG (current_buffer))
2924 it->end_charpos = ZV;
2925 eassert (charpos == BYTE_TO_CHAR (bytepos));
2926 IT_CHARPOS (*it) = charpos;
2927 IT_BYTEPOS (*it) = bytepos;
2929 /* We will rely on `reseat' to set this up properly, via
2930 handle_face_prop. */
2931 it->face_id = it->base_face_id;
2933 it->start = it->current;
2934 /* Do we need to reorder bidirectional text? Not if this is a
2935 unibyte buffer: by definition, none of the single-byte
2936 characters are strong R2L, so no reordering is needed. And
2937 bidi.c doesn't support unibyte buffers anyway. Also, don't
2938 reorder while we are loading loadup.el, since the tables of
2939 character properties needed for reordering are not yet
2940 available. */
2941 it->bidi_p =
2942 NILP (Vpurify_flag)
2943 && !NILP (BVAR (current_buffer, bidi_display_reordering))
2944 && it->multibyte_p;
2946 /* If we are to reorder bidirectional text, init the bidi
2947 iterator. */
2948 if (it->bidi_p)
2950 /* Note the paragraph direction that this buffer wants to
2951 use. */
2952 if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
2953 Qleft_to_right))
2954 it->paragraph_embedding = L2R;
2955 else if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
2956 Qright_to_left))
2957 it->paragraph_embedding = R2L;
2958 else
2959 it->paragraph_embedding = NEUTRAL_DIR;
2960 bidi_unshelve_cache (NULL, 0);
2961 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
2962 &it->bidi_it);
2965 /* Compute faces etc. */
2966 reseat (it, it->current.pos, 1);
2969 CHECK_IT (it);
2973 /* Initialize IT for the display of window W with window start POS. */
2975 void
2976 start_display (struct it *it, struct window *w, struct text_pos pos)
2978 struct glyph_row *row;
2979 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2981 row = w->desired_matrix->rows + first_vpos;
2982 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2983 it->first_vpos = first_vpos;
2985 /* Don't reseat to previous visible line start if current start
2986 position is in a string or image. */
2987 if (it->method == GET_FROM_BUFFER && it->line_wrap != TRUNCATE)
2989 int start_at_line_beg_p;
2990 int first_y = it->current_y;
2992 /* If window start is not at a line start, skip forward to POS to
2993 get the correct continuation lines width. */
2994 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2995 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2996 if (!start_at_line_beg_p)
2998 int new_x;
3000 reseat_at_previous_visible_line_start (it);
3001 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
3003 new_x = it->current_x + it->pixel_width;
3005 /* If lines are continued, this line may end in the middle
3006 of a multi-glyph character (e.g. a control character
3007 displayed as \003, or in the middle of an overlay
3008 string). In this case move_it_to above will not have
3009 taken us to the start of the continuation line but to the
3010 end of the continued line. */
3011 if (it->current_x > 0
3012 && it->line_wrap != TRUNCATE /* Lines are continued. */
3013 && (/* And glyph doesn't fit on the line. */
3014 new_x > it->last_visible_x
3015 /* Or it fits exactly and we're on a window
3016 system frame. */
3017 || (new_x == it->last_visible_x
3018 && FRAME_WINDOW_P (it->f)
3019 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
3020 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
3021 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
3023 if ((it->current.dpvec_index >= 0
3024 || it->current.overlay_string_index >= 0)
3025 /* If we are on a newline from a display vector or
3026 overlay string, then we are already at the end of
3027 a screen line; no need to go to the next line in
3028 that case, as this line is not really continued.
3029 (If we do go to the next line, C-e will not DTRT.) */
3030 && it->c != '\n')
3032 set_iterator_to_next (it, 1);
3033 move_it_in_display_line_to (it, -1, -1, 0);
3036 it->continuation_lines_width += it->current_x;
3038 /* If the character at POS is displayed via a display
3039 vector, move_it_to above stops at the final glyph of
3040 IT->dpvec. To make the caller redisplay that character
3041 again (a.k.a. start at POS), we need to reset the
3042 dpvec_index to the beginning of IT->dpvec. */
3043 else if (it->current.dpvec_index >= 0)
3044 it->current.dpvec_index = 0;
3046 /* We're starting a new display line, not affected by the
3047 height of the continued line, so clear the appropriate
3048 fields in the iterator structure. */
3049 it->max_ascent = it->max_descent = 0;
3050 it->max_phys_ascent = it->max_phys_descent = 0;
3052 it->current_y = first_y;
3053 it->vpos = 0;
3054 it->current_x = it->hpos = 0;
3060 /* Return 1 if POS is a position in ellipses displayed for invisible
3061 text. W is the window we display, for text property lookup. */
3063 static int
3064 in_ellipses_for_invisible_text_p (struct display_pos *pos, struct window *w)
3066 Lisp_Object prop, window;
3067 int ellipses_p = 0;
3068 ptrdiff_t charpos = CHARPOS (pos->pos);
3070 /* If POS specifies a position in a display vector, this might
3071 be for an ellipsis displayed for invisible text. We won't
3072 get the iterator set up for delivering that ellipsis unless
3073 we make sure that it gets aware of the invisible text. */
3074 if (pos->dpvec_index >= 0
3075 && pos->overlay_string_index < 0
3076 && CHARPOS (pos->string_pos) < 0
3077 && charpos > BEGV
3078 && (XSETWINDOW (window, w),
3079 prop = Fget_char_property (make_number (charpos),
3080 Qinvisible, window),
3081 !TEXT_PROP_MEANS_INVISIBLE (prop)))
3083 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
3084 window);
3085 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
3088 return ellipses_p;
3092 /* Initialize IT for stepping through current_buffer in window W,
3093 starting at position POS that includes overlay string and display
3094 vector/ control character translation position information. Value
3095 is zero if there are overlay strings with newlines at POS. */
3097 static int
3098 init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos)
3100 ptrdiff_t charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
3101 int i, overlay_strings_with_newlines = 0;
3103 /* If POS specifies a position in a display vector, this might
3104 be for an ellipsis displayed for invisible text. We won't
3105 get the iterator set up for delivering that ellipsis unless
3106 we make sure that it gets aware of the invisible text. */
3107 if (in_ellipses_for_invisible_text_p (pos, w))
3109 --charpos;
3110 bytepos = 0;
3113 /* Keep in mind: the call to reseat in init_iterator skips invisible
3114 text, so we might end up at a position different from POS. This
3115 is only a problem when POS is a row start after a newline and an
3116 overlay starts there with an after-string, and the overlay has an
3117 invisible property. Since we don't skip invisible text in
3118 display_line and elsewhere immediately after consuming the
3119 newline before the row start, such a POS will not be in a string,
3120 but the call to init_iterator below will move us to the
3121 after-string. */
3122 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
3124 /* This only scans the current chunk -- it should scan all chunks.
3125 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
3126 to 16 in 22.1 to make this a lesser problem. */
3127 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
3129 const char *s = SSDATA (it->overlay_strings[i]);
3130 const char *e = s + SBYTES (it->overlay_strings[i]);
3132 while (s < e && *s != '\n')
3133 ++s;
3135 if (s < e)
3137 overlay_strings_with_newlines = 1;
3138 break;
3142 /* If position is within an overlay string, set up IT to the right
3143 overlay string. */
3144 if (pos->overlay_string_index >= 0)
3146 int relative_index;
3148 /* If the first overlay string happens to have a `display'
3149 property for an image, the iterator will be set up for that
3150 image, and we have to undo that setup first before we can
3151 correct the overlay string index. */
3152 if (it->method == GET_FROM_IMAGE)
3153 pop_it (it);
3155 /* We already have the first chunk of overlay strings in
3156 IT->overlay_strings. Load more until the one for
3157 pos->overlay_string_index is in IT->overlay_strings. */
3158 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
3160 ptrdiff_t n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
3161 it->current.overlay_string_index = 0;
3162 while (n--)
3164 load_overlay_strings (it, 0);
3165 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
3169 it->current.overlay_string_index = pos->overlay_string_index;
3170 relative_index = (it->current.overlay_string_index
3171 % OVERLAY_STRING_CHUNK_SIZE);
3172 it->string = it->overlay_strings[relative_index];
3173 eassert (STRINGP (it->string));
3174 it->current.string_pos = pos->string_pos;
3175 it->method = GET_FROM_STRING;
3176 it->end_charpos = SCHARS (it->string);
3177 /* Set up the bidi iterator for this overlay string. */
3178 if (it->bidi_p)
3180 it->bidi_it.string.lstring = it->string;
3181 it->bidi_it.string.s = NULL;
3182 it->bidi_it.string.schars = SCHARS (it->string);
3183 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
3184 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
3185 it->bidi_it.string.unibyte = !it->multibyte_p;
3186 it->bidi_it.w = it->w;
3187 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3188 FRAME_WINDOW_P (it->f), &it->bidi_it);
3190 /* Synchronize the state of the bidi iterator with
3191 pos->string_pos. For any string position other than
3192 zero, this will be done automagically when we resume
3193 iteration over the string and get_visually_first_element
3194 is called. But if string_pos is zero, and the string is
3195 to be reordered for display, we need to resync manually,
3196 since it could be that the iteration state recorded in
3197 pos ended at string_pos of 0 moving backwards in string. */
3198 if (CHARPOS (pos->string_pos) == 0)
3200 get_visually_first_element (it);
3201 if (IT_STRING_CHARPOS (*it) != 0)
3202 do {
3203 /* Paranoia. */
3204 eassert (it->bidi_it.charpos < it->bidi_it.string.schars);
3205 bidi_move_to_visually_next (&it->bidi_it);
3206 } while (it->bidi_it.charpos != 0);
3208 eassert (IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
3209 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos);
3213 if (CHARPOS (pos->string_pos) >= 0)
3215 /* Recorded position is not in an overlay string, but in another
3216 string. This can only be a string from a `display' property.
3217 IT should already be filled with that string. */
3218 it->current.string_pos = pos->string_pos;
3219 eassert (STRINGP (it->string));
3220 if (it->bidi_p)
3221 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3222 FRAME_WINDOW_P (it->f), &it->bidi_it);
3225 /* Restore position in display vector translations, control
3226 character translations or ellipses. */
3227 if (pos->dpvec_index >= 0)
3229 if (it->dpvec == NULL)
3230 get_next_display_element (it);
3231 eassert (it->dpvec && it->current.dpvec_index == 0);
3232 it->current.dpvec_index = pos->dpvec_index;
3235 CHECK_IT (it);
3236 return !overlay_strings_with_newlines;
3240 /* Initialize IT for stepping through current_buffer in window W
3241 starting at ROW->start. */
3243 static void
3244 init_to_row_start (struct it *it, struct window *w, struct glyph_row *row)
3246 init_from_display_pos (it, w, &row->start);
3247 it->start = row->start;
3248 it->continuation_lines_width = row->continuation_lines_width;
3249 CHECK_IT (it);
3253 /* Initialize IT for stepping through current_buffer in window W
3254 starting in the line following ROW, i.e. starting at ROW->end.
3255 Value is zero if there are overlay strings with newlines at ROW's
3256 end position. */
3258 static int
3259 init_to_row_end (struct it *it, struct window *w, struct glyph_row *row)
3261 int success = 0;
3263 if (init_from_display_pos (it, w, &row->end))
3265 if (row->continued_p)
3266 it->continuation_lines_width
3267 = row->continuation_lines_width + row->pixel_width;
3268 CHECK_IT (it);
3269 success = 1;
3272 return success;
3278 /***********************************************************************
3279 Text properties
3280 ***********************************************************************/
3282 /* Called when IT reaches IT->stop_charpos. Handle text property and
3283 overlay changes. Set IT->stop_charpos to the next position where
3284 to stop. */
3286 static void
3287 handle_stop (struct it *it)
3289 enum prop_handled handled;
3290 int handle_overlay_change_p;
3291 struct props *p;
3293 it->dpvec = NULL;
3294 it->current.dpvec_index = -1;
3295 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
3296 it->ignore_overlay_strings_at_pos_p = 0;
3297 it->ellipsis_p = 0;
3299 /* Use face of preceding text for ellipsis (if invisible) */
3300 if (it->selective_display_ellipsis_p)
3301 it->saved_face_id = it->face_id;
3305 handled = HANDLED_NORMALLY;
3307 /* Call text property handlers. */
3308 for (p = it_props; p->handler; ++p)
3310 handled = p->handler (it);
3312 if (handled == HANDLED_RECOMPUTE_PROPS)
3313 break;
3314 else if (handled == HANDLED_RETURN)
3316 /* We still want to show before and after strings from
3317 overlays even if the actual buffer text is replaced. */
3318 if (!handle_overlay_change_p
3319 || it->sp > 1
3320 /* Don't call get_overlay_strings_1 if we already
3321 have overlay strings loaded, because doing so
3322 will load them again and push the iterator state
3323 onto the stack one more time, which is not
3324 expected by the rest of the code that processes
3325 overlay strings. */
3326 || (it->current.overlay_string_index < 0
3327 ? !get_overlay_strings_1 (it, 0, 0)
3328 : 0))
3330 if (it->ellipsis_p)
3331 setup_for_ellipsis (it, 0);
3332 /* When handling a display spec, we might load an
3333 empty string. In that case, discard it here. We
3334 used to discard it in handle_single_display_spec,
3335 but that causes get_overlay_strings_1, above, to
3336 ignore overlay strings that we must check. */
3337 if (STRINGP (it->string) && !SCHARS (it->string))
3338 pop_it (it);
3339 return;
3341 else if (STRINGP (it->string) && !SCHARS (it->string))
3342 pop_it (it);
3343 else
3345 it->ignore_overlay_strings_at_pos_p = 1;
3346 it->string_from_display_prop_p = 0;
3347 it->from_disp_prop_p = 0;
3348 handle_overlay_change_p = 0;
3350 handled = HANDLED_RECOMPUTE_PROPS;
3351 break;
3353 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
3354 handle_overlay_change_p = 0;
3357 if (handled != HANDLED_RECOMPUTE_PROPS)
3359 /* Don't check for overlay strings below when set to deliver
3360 characters from a display vector. */
3361 if (it->method == GET_FROM_DISPLAY_VECTOR)
3362 handle_overlay_change_p = 0;
3364 /* Handle overlay changes.
3365 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
3366 if it finds overlays. */
3367 if (handle_overlay_change_p)
3368 handled = handle_overlay_change (it);
3371 if (it->ellipsis_p)
3373 setup_for_ellipsis (it, 0);
3374 break;
3377 while (handled == HANDLED_RECOMPUTE_PROPS);
3379 /* Determine where to stop next. */
3380 if (handled == HANDLED_NORMALLY)
3381 compute_stop_pos (it);
3385 /* Compute IT->stop_charpos from text property and overlay change
3386 information for IT's current position. */
3388 static void
3389 compute_stop_pos (struct it *it)
3391 register INTERVAL iv, next_iv;
3392 Lisp_Object object, limit, position;
3393 ptrdiff_t charpos, bytepos;
3395 if (STRINGP (it->string))
3397 /* Strings are usually short, so don't limit the search for
3398 properties. */
3399 it->stop_charpos = it->end_charpos;
3400 object = it->string;
3401 limit = Qnil;
3402 charpos = IT_STRING_CHARPOS (*it);
3403 bytepos = IT_STRING_BYTEPOS (*it);
3405 else
3407 ptrdiff_t pos;
3409 /* If end_charpos is out of range for some reason, such as a
3410 misbehaving display function, rationalize it (Bug#5984). */
3411 if (it->end_charpos > ZV)
3412 it->end_charpos = ZV;
3413 it->stop_charpos = it->end_charpos;
3415 /* If next overlay change is in front of the current stop pos
3416 (which is IT->end_charpos), stop there. Note: value of
3417 next_overlay_change is point-max if no overlay change
3418 follows. */
3419 charpos = IT_CHARPOS (*it);
3420 bytepos = IT_BYTEPOS (*it);
3421 pos = next_overlay_change (charpos);
3422 if (pos < it->stop_charpos)
3423 it->stop_charpos = pos;
3425 /* If showing the region, we have to stop at the region
3426 start or end because the face might change there. */
3427 if (it->region_beg_charpos > 0)
3429 if (IT_CHARPOS (*it) < it->region_beg_charpos)
3430 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
3431 else if (IT_CHARPOS (*it) < it->region_end_charpos)
3432 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
3435 /* Set up variables for computing the stop position from text
3436 property changes. */
3437 XSETBUFFER (object, current_buffer);
3438 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3441 /* Get the interval containing IT's position. Value is a null
3442 interval if there isn't such an interval. */
3443 position = make_number (charpos);
3444 iv = validate_interval_range (object, &position, &position, 0);
3445 if (iv)
3447 Lisp_Object values_here[LAST_PROP_IDX];
3448 struct props *p;
3450 /* Get properties here. */
3451 for (p = it_props; p->handler; ++p)
3452 values_here[p->idx] = textget (iv->plist, *p->name);
3454 /* Look for an interval following iv that has different
3455 properties. */
3456 for (next_iv = next_interval (iv);
3457 (next_iv
3458 && (NILP (limit)
3459 || XFASTINT (limit) > next_iv->position));
3460 next_iv = next_interval (next_iv))
3462 for (p = it_props; p->handler; ++p)
3464 Lisp_Object new_value;
3466 new_value = textget (next_iv->plist, *p->name);
3467 if (!EQ (values_here[p->idx], new_value))
3468 break;
3471 if (p->handler)
3472 break;
3475 if (next_iv)
3477 if (INTEGERP (limit)
3478 && next_iv->position >= XFASTINT (limit))
3479 /* No text property change up to limit. */
3480 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3481 else
3482 /* Text properties change in next_iv. */
3483 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3487 if (it->cmp_it.id < 0)
3489 ptrdiff_t stoppos = it->end_charpos;
3491 if (it->bidi_p && it->bidi_it.scan_dir < 0)
3492 stoppos = -1;
3493 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
3494 stoppos, it->string);
3497 eassert (STRINGP (it->string)
3498 || (it->stop_charpos >= BEGV
3499 && it->stop_charpos >= IT_CHARPOS (*it)));
3503 /* Return the position of the next overlay change after POS in
3504 current_buffer. Value is point-max if no overlay change
3505 follows. This is like `next-overlay-change' but doesn't use
3506 xmalloc. */
3508 static ptrdiff_t
3509 next_overlay_change (ptrdiff_t pos)
3511 ptrdiff_t i, noverlays;
3512 ptrdiff_t endpos;
3513 Lisp_Object *overlays;
3515 /* Get all overlays at the given position. */
3516 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
3518 /* If any of these overlays ends before endpos,
3519 use its ending point instead. */
3520 for (i = 0; i < noverlays; ++i)
3522 Lisp_Object oend;
3523 ptrdiff_t oendpos;
3525 oend = OVERLAY_END (overlays[i]);
3526 oendpos = OVERLAY_POSITION (oend);
3527 endpos = min (endpos, oendpos);
3530 return endpos;
3533 /* How many characters forward to search for a display property or
3534 display string. Searching too far forward makes the bidi display
3535 sluggish, especially in small windows. */
3536 #define MAX_DISP_SCAN 250
3538 /* Return the character position of a display string at or after
3539 position specified by POSITION. If no display string exists at or
3540 after POSITION, return ZV. A display string is either an overlay
3541 with `display' property whose value is a string, or a `display'
3542 text property whose value is a string. STRING is data about the
3543 string to iterate; if STRING->lstring is nil, we are iterating a
3544 buffer. FRAME_WINDOW_P is non-zero when we are displaying a window
3545 on a GUI frame. DISP_PROP is set to zero if we searched
3546 MAX_DISP_SCAN characters forward without finding any display
3547 strings, non-zero otherwise. It is set to 2 if the display string
3548 uses any kind of `(space ...)' spec that will produce a stretch of
3549 white space in the text area. */
3550 ptrdiff_t
3551 compute_display_string_pos (struct text_pos *position,
3552 struct bidi_string_data *string,
3553 struct window *w,
3554 int frame_window_p, int *disp_prop)
3556 /* OBJECT = nil means current buffer. */
3557 Lisp_Object object, object1;
3558 Lisp_Object pos, spec, limpos;
3559 int string_p = (string && (STRINGP (string->lstring) || string->s));
3560 ptrdiff_t eob = string_p ? string->schars : ZV;
3561 ptrdiff_t begb = string_p ? 0 : BEGV;
3562 ptrdiff_t bufpos, charpos = CHARPOS (*position);
3563 ptrdiff_t lim =
3564 (charpos < eob - MAX_DISP_SCAN) ? charpos + MAX_DISP_SCAN : eob;
3565 struct text_pos tpos;
3566 int rv = 0;
3568 if (string && STRINGP (string->lstring))
3569 object1 = object = string->lstring;
3570 else if (w && !string_p)
3572 XSETWINDOW (object, w);
3573 object1 = Qnil;
3575 else
3576 object1 = object = Qnil;
3578 *disp_prop = 1;
3580 if (charpos >= eob
3581 /* We don't support display properties whose values are strings
3582 that have display string properties. */
3583 || string->from_disp_str
3584 /* C strings cannot have display properties. */
3585 || (string->s && !STRINGP (object)))
3587 *disp_prop = 0;
3588 return eob;
3591 /* If the character at CHARPOS is where the display string begins,
3592 return CHARPOS. */
3593 pos = make_number (charpos);
3594 if (STRINGP (object))
3595 bufpos = string->bufpos;
3596 else
3597 bufpos = charpos;
3598 tpos = *position;
3599 if (!NILP (spec = Fget_char_property (pos, Qdisplay, object))
3600 && (charpos <= begb
3601 || !EQ (Fget_char_property (make_number (charpos - 1), Qdisplay,
3602 object),
3603 spec))
3604 && (rv = handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
3605 frame_window_p)))
3607 if (rv == 2)
3608 *disp_prop = 2;
3609 return charpos;
3612 /* Look forward for the first character with a `display' property
3613 that will replace the underlying text when displayed. */
3614 limpos = make_number (lim);
3615 do {
3616 pos = Fnext_single_char_property_change (pos, Qdisplay, object1, limpos);
3617 CHARPOS (tpos) = XFASTINT (pos);
3618 if (CHARPOS (tpos) >= lim)
3620 *disp_prop = 0;
3621 break;
3623 if (STRINGP (object))
3624 BYTEPOS (tpos) = string_char_to_byte (object, CHARPOS (tpos));
3625 else
3626 BYTEPOS (tpos) = CHAR_TO_BYTE (CHARPOS (tpos));
3627 spec = Fget_char_property (pos, Qdisplay, object);
3628 if (!STRINGP (object))
3629 bufpos = CHARPOS (tpos);
3630 } while (NILP (spec)
3631 || !(rv = handle_display_spec (NULL, spec, object, Qnil, &tpos,
3632 bufpos, frame_window_p)));
3633 if (rv == 2)
3634 *disp_prop = 2;
3636 return CHARPOS (tpos);
3639 /* Return the character position of the end of the display string that
3640 started at CHARPOS. If there's no display string at CHARPOS,
3641 return -1. A display string is either an overlay with `display'
3642 property whose value is a string or a `display' text property whose
3643 value is a string. */
3644 ptrdiff_t
3645 compute_display_string_end (ptrdiff_t charpos, struct bidi_string_data *string)
3647 /* OBJECT = nil means current buffer. */
3648 Lisp_Object object =
3649 (string && STRINGP (string->lstring)) ? string->lstring : Qnil;
3650 Lisp_Object pos = make_number (charpos);
3651 ptrdiff_t eob =
3652 (STRINGP (object) || (string && string->s)) ? string->schars : ZV;
3654 if (charpos >= eob || (string->s && !STRINGP (object)))
3655 return eob;
3657 /* It could happen that the display property or overlay was removed
3658 since we found it in compute_display_string_pos above. One way
3659 this can happen is if JIT font-lock was called (through
3660 handle_fontified_prop), and jit-lock-functions remove text
3661 properties or overlays from the portion of buffer that includes
3662 CHARPOS. Muse mode is known to do that, for example. In this
3663 case, we return -1 to the caller, to signal that no display
3664 string is actually present at CHARPOS. See bidi_fetch_char for
3665 how this is handled.
3667 An alternative would be to never look for display properties past
3668 it->stop_charpos. But neither compute_display_string_pos nor
3669 bidi_fetch_char that calls it know or care where the next
3670 stop_charpos is. */
3671 if (NILP (Fget_char_property (pos, Qdisplay, object)))
3672 return -1;
3674 /* Look forward for the first character where the `display' property
3675 changes. */
3676 pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil);
3678 return XFASTINT (pos);
3683 /***********************************************************************
3684 Fontification
3685 ***********************************************************************/
3687 /* Handle changes in the `fontified' property of the current buffer by
3688 calling hook functions from Qfontification_functions to fontify
3689 regions of text. */
3691 static enum prop_handled
3692 handle_fontified_prop (struct it *it)
3694 Lisp_Object prop, pos;
3695 enum prop_handled handled = HANDLED_NORMALLY;
3697 if (!NILP (Vmemory_full))
3698 return handled;
3700 /* Get the value of the `fontified' property at IT's current buffer
3701 position. (The `fontified' property doesn't have a special
3702 meaning in strings.) If the value is nil, call functions from
3703 Qfontification_functions. */
3704 if (!STRINGP (it->string)
3705 && it->s == NULL
3706 && !NILP (Vfontification_functions)
3707 && !NILP (Vrun_hooks)
3708 && (pos = make_number (IT_CHARPOS (*it)),
3709 prop = Fget_char_property (pos, Qfontified, Qnil),
3710 /* Ignore the special cased nil value always present at EOB since
3711 no amount of fontifying will be able to change it. */
3712 NILP (prop) && IT_CHARPOS (*it) < Z))
3714 ptrdiff_t count = SPECPDL_INDEX ();
3715 Lisp_Object val;
3716 struct buffer *obuf = current_buffer;
3717 int begv = BEGV, zv = ZV;
3718 int old_clip_changed = current_buffer->clip_changed;
3720 val = Vfontification_functions;
3721 specbind (Qfontification_functions, Qnil);
3723 eassert (it->end_charpos == ZV);
3725 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3726 safe_call1 (val, pos);
3727 else
3729 Lisp_Object fns, fn;
3730 struct gcpro gcpro1, gcpro2;
3732 fns = Qnil;
3733 GCPRO2 (val, fns);
3735 for (; CONSP (val); val = XCDR (val))
3737 fn = XCAR (val);
3739 if (EQ (fn, Qt))
3741 /* A value of t indicates this hook has a local
3742 binding; it means to run the global binding too.
3743 In a global value, t should not occur. If it
3744 does, we must ignore it to avoid an endless
3745 loop. */
3746 for (fns = Fdefault_value (Qfontification_functions);
3747 CONSP (fns);
3748 fns = XCDR (fns))
3750 fn = XCAR (fns);
3751 if (!EQ (fn, Qt))
3752 safe_call1 (fn, pos);
3755 else
3756 safe_call1 (fn, pos);
3759 UNGCPRO;
3762 unbind_to (count, Qnil);
3764 /* Fontification functions routinely call `save-restriction'.
3765 Normally, this tags clip_changed, which can confuse redisplay
3766 (see discussion in Bug#6671). Since we don't perform any
3767 special handling of fontification changes in the case where
3768 `save-restriction' isn't called, there's no point doing so in
3769 this case either. So, if the buffer's restrictions are
3770 actually left unchanged, reset clip_changed. */
3771 if (obuf == current_buffer)
3773 if (begv == BEGV && zv == ZV)
3774 current_buffer->clip_changed = old_clip_changed;
3776 /* There isn't much we can reasonably do to protect against
3777 misbehaving fontification, but here's a fig leaf. */
3778 else if (BUFFER_LIVE_P (obuf))
3779 set_buffer_internal_1 (obuf);
3781 /* The fontification code may have added/removed text.
3782 It could do even a lot worse, but let's at least protect against
3783 the most obvious case where only the text past `pos' gets changed',
3784 as is/was done in grep.el where some escapes sequences are turned
3785 into face properties (bug#7876). */
3786 it->end_charpos = ZV;
3788 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3789 something. This avoids an endless loop if they failed to
3790 fontify the text for which reason ever. */
3791 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3792 handled = HANDLED_RECOMPUTE_PROPS;
3795 return handled;
3800 /***********************************************************************
3801 Faces
3802 ***********************************************************************/
3804 /* Set up iterator IT from face properties at its current position.
3805 Called from handle_stop. */
3807 static enum prop_handled
3808 handle_face_prop (struct it *it)
3810 int new_face_id;
3811 ptrdiff_t next_stop;
3813 if (!STRINGP (it->string))
3815 new_face_id
3816 = face_at_buffer_position (it->w,
3817 IT_CHARPOS (*it),
3818 it->region_beg_charpos,
3819 it->region_end_charpos,
3820 &next_stop,
3821 (IT_CHARPOS (*it)
3822 + TEXT_PROP_DISTANCE_LIMIT),
3823 0, it->base_face_id);
3825 /* Is this a start of a run of characters with box face?
3826 Caveat: this can be called for a freshly initialized
3827 iterator; face_id is -1 in this case. We know that the new
3828 face will not change until limit, i.e. if the new face has a
3829 box, all characters up to limit will have one. But, as
3830 usual, we don't know whether limit is really the end. */
3831 if (new_face_id != it->face_id)
3833 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3834 /* If it->face_id is -1, old_face below will be NULL, see
3835 the definition of FACE_FROM_ID. This will happen if this
3836 is the initial call that gets the face. */
3837 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3839 /* If the value of face_id of the iterator is -1, we have to
3840 look in front of IT's position and see whether there is a
3841 face there that's different from new_face_id. */
3842 if (!old_face && IT_CHARPOS (*it) > BEG)
3844 int prev_face_id = face_before_it_pos (it);
3846 old_face = FACE_FROM_ID (it->f, prev_face_id);
3849 /* If the new face has a box, but the old face does not,
3850 this is the start of a run of characters with box face,
3851 i.e. this character has a shadow on the left side. */
3852 it->start_of_box_run_p = (new_face->box != FACE_NO_BOX
3853 && (old_face == NULL || !old_face->box));
3854 it->face_box_p = new_face->box != FACE_NO_BOX;
3857 else
3859 int base_face_id;
3860 ptrdiff_t bufpos;
3861 int i;
3862 Lisp_Object from_overlay
3863 = (it->current.overlay_string_index >= 0
3864 ? it->string_overlays[it->current.overlay_string_index
3865 % OVERLAY_STRING_CHUNK_SIZE]
3866 : Qnil);
3868 /* See if we got to this string directly or indirectly from
3869 an overlay property. That includes the before-string or
3870 after-string of an overlay, strings in display properties
3871 provided by an overlay, their text properties, etc.
3873 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
3874 if (! NILP (from_overlay))
3875 for (i = it->sp - 1; i >= 0; i--)
3877 if (it->stack[i].current.overlay_string_index >= 0)
3878 from_overlay
3879 = it->string_overlays[it->stack[i].current.overlay_string_index
3880 % OVERLAY_STRING_CHUNK_SIZE];
3881 else if (! NILP (it->stack[i].from_overlay))
3882 from_overlay = it->stack[i].from_overlay;
3884 if (!NILP (from_overlay))
3885 break;
3888 if (! NILP (from_overlay))
3890 bufpos = IT_CHARPOS (*it);
3891 /* For a string from an overlay, the base face depends
3892 only on text properties and ignores overlays. */
3893 base_face_id
3894 = face_for_overlay_string (it->w,
3895 IT_CHARPOS (*it),
3896 it->region_beg_charpos,
3897 it->region_end_charpos,
3898 &next_stop,
3899 (IT_CHARPOS (*it)
3900 + TEXT_PROP_DISTANCE_LIMIT),
3902 from_overlay);
3904 else
3906 bufpos = 0;
3908 /* For strings from a `display' property, use the face at
3909 IT's current buffer position as the base face to merge
3910 with, so that overlay strings appear in the same face as
3911 surrounding text, unless they specify their own
3912 faces. */
3913 base_face_id = it->string_from_prefix_prop_p
3914 ? DEFAULT_FACE_ID
3915 : underlying_face_id (it);
3918 new_face_id = face_at_string_position (it->w,
3919 it->string,
3920 IT_STRING_CHARPOS (*it),
3921 bufpos,
3922 it->region_beg_charpos,
3923 it->region_end_charpos,
3924 &next_stop,
3925 base_face_id, 0);
3927 /* Is this a start of a run of characters with box? Caveat:
3928 this can be called for a freshly allocated iterator; face_id
3929 is -1 is this case. We know that the new face will not
3930 change until the next check pos, i.e. if the new face has a
3931 box, all characters up to that position will have a
3932 box. But, as usual, we don't know whether that position
3933 is really the end. */
3934 if (new_face_id != it->face_id)
3936 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3937 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3939 /* If new face has a box but old face hasn't, this is the
3940 start of a run of characters with box, i.e. it has a
3941 shadow on the left side. */
3942 it->start_of_box_run_p
3943 = new_face->box && (old_face == NULL || !old_face->box);
3944 it->face_box_p = new_face->box != FACE_NO_BOX;
3948 it->face_id = new_face_id;
3949 return HANDLED_NORMALLY;
3953 /* Return the ID of the face ``underlying'' IT's current position,
3954 which is in a string. If the iterator is associated with a
3955 buffer, return the face at IT's current buffer position.
3956 Otherwise, use the iterator's base_face_id. */
3958 static int
3959 underlying_face_id (struct it *it)
3961 int face_id = it->base_face_id, i;
3963 eassert (STRINGP (it->string));
3965 for (i = it->sp - 1; i >= 0; --i)
3966 if (NILP (it->stack[i].string))
3967 face_id = it->stack[i].face_id;
3969 return face_id;
3973 /* Compute the face one character before or after the current position
3974 of IT, in the visual order. BEFORE_P non-zero means get the face
3975 in front (to the left in L2R paragraphs, to the right in R2L
3976 paragraphs) of IT's screen position. Value is the ID of the face. */
3978 static int
3979 face_before_or_after_it_pos (struct it *it, int before_p)
3981 int face_id, limit;
3982 ptrdiff_t next_check_charpos;
3983 struct it it_copy;
3984 void *it_copy_data = NULL;
3986 eassert (it->s == NULL);
3988 if (STRINGP (it->string))
3990 ptrdiff_t bufpos, charpos;
3991 int base_face_id;
3993 /* No face change past the end of the string (for the case
3994 we are padding with spaces). No face change before the
3995 string start. */
3996 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
3997 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
3998 return it->face_id;
4000 if (!it->bidi_p)
4002 /* Set charpos to the position before or after IT's current
4003 position, in the logical order, which in the non-bidi
4004 case is the same as the visual order. */
4005 if (before_p)
4006 charpos = IT_STRING_CHARPOS (*it) - 1;
4007 else if (it->what == IT_COMPOSITION)
4008 /* For composition, we must check the character after the
4009 composition. */
4010 charpos = IT_STRING_CHARPOS (*it) + it->cmp_it.nchars;
4011 else
4012 charpos = IT_STRING_CHARPOS (*it) + 1;
4014 else
4016 if (before_p)
4018 /* With bidi iteration, the character before the current
4019 in the visual order cannot be found by simple
4020 iteration, because "reverse" reordering is not
4021 supported. Instead, we need to use the move_it_*
4022 family of functions. */
4023 /* Ignore face changes before the first visible
4024 character on this display line. */
4025 if (it->current_x <= it->first_visible_x)
4026 return it->face_id;
4027 SAVE_IT (it_copy, *it, it_copy_data);
4028 /* Implementation note: Since move_it_in_display_line
4029 works in the iterator geometry, and thinks the first
4030 character is always the leftmost, even in R2L lines,
4031 we don't need to distinguish between the R2L and L2R
4032 cases here. */
4033 move_it_in_display_line (&it_copy, SCHARS (it_copy.string),
4034 it_copy.current_x - 1, MOVE_TO_X);
4035 charpos = IT_STRING_CHARPOS (it_copy);
4036 RESTORE_IT (it, it, it_copy_data);
4038 else
4040 /* Set charpos to the string position of the character
4041 that comes after IT's current position in the visual
4042 order. */
4043 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
4045 it_copy = *it;
4046 while (n--)
4047 bidi_move_to_visually_next (&it_copy.bidi_it);
4049 charpos = it_copy.bidi_it.charpos;
4052 eassert (0 <= charpos && charpos <= SCHARS (it->string));
4054 if (it->current.overlay_string_index >= 0)
4055 bufpos = IT_CHARPOS (*it);
4056 else
4057 bufpos = 0;
4059 base_face_id = underlying_face_id (it);
4061 /* Get the face for ASCII, or unibyte. */
4062 face_id = face_at_string_position (it->w,
4063 it->string,
4064 charpos,
4065 bufpos,
4066 it->region_beg_charpos,
4067 it->region_end_charpos,
4068 &next_check_charpos,
4069 base_face_id, 0);
4071 /* Correct the face for charsets different from ASCII. Do it
4072 for the multibyte case only. The face returned above is
4073 suitable for unibyte text if IT->string is unibyte. */
4074 if (STRING_MULTIBYTE (it->string))
4076 struct text_pos pos1 = string_pos (charpos, it->string);
4077 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos1);
4078 int c, len;
4079 struct face *face = FACE_FROM_ID (it->f, face_id);
4081 c = string_char_and_length (p, &len);
4082 face_id = FACE_FOR_CHAR (it->f, face, c, charpos, it->string);
4085 else
4087 struct text_pos pos;
4089 if ((IT_CHARPOS (*it) >= ZV && !before_p)
4090 || (IT_CHARPOS (*it) <= BEGV && before_p))
4091 return it->face_id;
4093 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
4094 pos = it->current.pos;
4096 if (!it->bidi_p)
4098 if (before_p)
4099 DEC_TEXT_POS (pos, it->multibyte_p);
4100 else
4102 if (it->what == IT_COMPOSITION)
4104 /* For composition, we must check the position after
4105 the composition. */
4106 pos.charpos += it->cmp_it.nchars;
4107 pos.bytepos += it->len;
4109 else
4110 INC_TEXT_POS (pos, it->multibyte_p);
4113 else
4115 if (before_p)
4117 /* With bidi iteration, the character before the current
4118 in the visual order cannot be found by simple
4119 iteration, because "reverse" reordering is not
4120 supported. Instead, we need to use the move_it_*
4121 family of functions. */
4122 /* Ignore face changes before the first visible
4123 character on this display line. */
4124 if (it->current_x <= it->first_visible_x)
4125 return it->face_id;
4126 SAVE_IT (it_copy, *it, it_copy_data);
4127 /* Implementation note: Since move_it_in_display_line
4128 works in the iterator geometry, and thinks the first
4129 character is always the leftmost, even in R2L lines,
4130 we don't need to distinguish between the R2L and L2R
4131 cases here. */
4132 move_it_in_display_line (&it_copy, ZV,
4133 it_copy.current_x - 1, MOVE_TO_X);
4134 pos = it_copy.current.pos;
4135 RESTORE_IT (it, it, it_copy_data);
4137 else
4139 /* Set charpos to the buffer position of the character
4140 that comes after IT's current position in the visual
4141 order. */
4142 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
4144 it_copy = *it;
4145 while (n--)
4146 bidi_move_to_visually_next (&it_copy.bidi_it);
4148 SET_TEXT_POS (pos,
4149 it_copy.bidi_it.charpos, it_copy.bidi_it.bytepos);
4152 eassert (BEGV <= CHARPOS (pos) && CHARPOS (pos) <= ZV);
4154 /* Determine face for CHARSET_ASCII, or unibyte. */
4155 face_id = face_at_buffer_position (it->w,
4156 CHARPOS (pos),
4157 it->region_beg_charpos,
4158 it->region_end_charpos,
4159 &next_check_charpos,
4160 limit, 0, -1);
4162 /* Correct the face for charsets different from ASCII. Do it
4163 for the multibyte case only. The face returned above is
4164 suitable for unibyte text if current_buffer is unibyte. */
4165 if (it->multibyte_p)
4167 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
4168 struct face *face = FACE_FROM_ID (it->f, face_id);
4169 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
4173 return face_id;
4178 /***********************************************************************
4179 Invisible text
4180 ***********************************************************************/
4182 /* Set up iterator IT from invisible properties at its current
4183 position. Called from handle_stop. */
4185 static enum prop_handled
4186 handle_invisible_prop (struct it *it)
4188 enum prop_handled handled = HANDLED_NORMALLY;
4189 int invis_p;
4190 Lisp_Object prop;
4192 if (STRINGP (it->string))
4194 Lisp_Object end_charpos, limit, charpos;
4196 /* Get the value of the invisible text property at the
4197 current position. Value will be nil if there is no such
4198 property. */
4199 charpos = make_number (IT_STRING_CHARPOS (*it));
4200 prop = Fget_text_property (charpos, Qinvisible, it->string);
4201 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4203 if (invis_p && IT_STRING_CHARPOS (*it) < it->end_charpos)
4205 /* Record whether we have to display an ellipsis for the
4206 invisible text. */
4207 int display_ellipsis_p = (invis_p == 2);
4208 ptrdiff_t len, endpos;
4210 handled = HANDLED_RECOMPUTE_PROPS;
4212 /* Get the position at which the next visible text can be
4213 found in IT->string, if any. */
4214 endpos = len = SCHARS (it->string);
4215 XSETINT (limit, len);
4218 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
4219 it->string, limit);
4220 if (INTEGERP (end_charpos))
4222 endpos = XFASTINT (end_charpos);
4223 prop = Fget_text_property (end_charpos, Qinvisible, it->string);
4224 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4225 if (invis_p == 2)
4226 display_ellipsis_p = 1;
4229 while (invis_p && endpos < len);
4231 if (display_ellipsis_p)
4232 it->ellipsis_p = 1;
4234 if (endpos < len)
4236 /* Text at END_CHARPOS is visible. Move IT there. */
4237 struct text_pos old;
4238 ptrdiff_t oldpos;
4240 old = it->current.string_pos;
4241 oldpos = CHARPOS (old);
4242 if (it->bidi_p)
4244 if (it->bidi_it.first_elt
4245 && it->bidi_it.charpos < SCHARS (it->string))
4246 bidi_paragraph_init (it->paragraph_embedding,
4247 &it->bidi_it, 1);
4248 /* Bidi-iterate out of the invisible text. */
4251 bidi_move_to_visually_next (&it->bidi_it);
4253 while (oldpos <= it->bidi_it.charpos
4254 && it->bidi_it.charpos < endpos);
4256 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
4257 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
4258 if (IT_CHARPOS (*it) >= endpos)
4259 it->prev_stop = endpos;
4261 else
4263 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
4264 compute_string_pos (&it->current.string_pos, old, it->string);
4267 else
4269 /* The rest of the string is invisible. If this is an
4270 overlay string, proceed with the next overlay string
4271 or whatever comes and return a character from there. */
4272 if (it->current.overlay_string_index >= 0
4273 && !display_ellipsis_p)
4275 next_overlay_string (it);
4276 /* Don't check for overlay strings when we just
4277 finished processing them. */
4278 handled = HANDLED_OVERLAY_STRING_CONSUMED;
4280 else
4282 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
4283 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
4288 else
4290 ptrdiff_t newpos, next_stop, start_charpos, tem;
4291 Lisp_Object pos, overlay;
4293 /* First of all, is there invisible text at this position? */
4294 tem = start_charpos = IT_CHARPOS (*it);
4295 pos = make_number (tem);
4296 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
4297 &overlay);
4298 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4300 /* If we are on invisible text, skip over it. */
4301 if (invis_p && start_charpos < it->end_charpos)
4303 /* Record whether we have to display an ellipsis for the
4304 invisible text. */
4305 int display_ellipsis_p = invis_p == 2;
4307 handled = HANDLED_RECOMPUTE_PROPS;
4309 /* Loop skipping over invisible text. The loop is left at
4310 ZV or with IT on the first char being visible again. */
4313 /* Try to skip some invisible text. Return value is the
4314 position reached which can be equal to where we start
4315 if there is nothing invisible there. This skips both
4316 over invisible text properties and overlays with
4317 invisible property. */
4318 newpos = skip_invisible (tem, &next_stop, ZV, it->window);
4320 /* If we skipped nothing at all we weren't at invisible
4321 text in the first place. If everything to the end of
4322 the buffer was skipped, end the loop. */
4323 if (newpos == tem || newpos >= ZV)
4324 invis_p = 0;
4325 else
4327 /* We skipped some characters but not necessarily
4328 all there are. Check if we ended up on visible
4329 text. Fget_char_property returns the property of
4330 the char before the given position, i.e. if we
4331 get invis_p = 0, this means that the char at
4332 newpos is visible. */
4333 pos = make_number (newpos);
4334 prop = Fget_char_property (pos, Qinvisible, it->window);
4335 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4338 /* If we ended up on invisible text, proceed to
4339 skip starting with next_stop. */
4340 if (invis_p)
4341 tem = next_stop;
4343 /* If there are adjacent invisible texts, don't lose the
4344 second one's ellipsis. */
4345 if (invis_p == 2)
4346 display_ellipsis_p = 1;
4348 while (invis_p);
4350 /* The position newpos is now either ZV or on visible text. */
4351 if (it->bidi_p)
4353 ptrdiff_t bpos = CHAR_TO_BYTE (newpos);
4354 int on_newline =
4355 bpos == ZV_BYTE || FETCH_BYTE (bpos) == '\n';
4356 int after_newline =
4357 newpos <= BEGV || FETCH_BYTE (bpos - 1) == '\n';
4359 /* If the invisible text ends on a newline or on a
4360 character after a newline, we can avoid the costly,
4361 character by character, bidi iteration to NEWPOS, and
4362 instead simply reseat the iterator there. That's
4363 because all bidi reordering information is tossed at
4364 the newline. This is a big win for modes that hide
4365 complete lines, like Outline, Org, etc. */
4366 if (on_newline || after_newline)
4368 struct text_pos tpos;
4369 bidi_dir_t pdir = it->bidi_it.paragraph_dir;
4371 SET_TEXT_POS (tpos, newpos, bpos);
4372 reseat_1 (it, tpos, 0);
4373 /* If we reseat on a newline/ZV, we need to prep the
4374 bidi iterator for advancing to the next character
4375 after the newline/EOB, keeping the current paragraph
4376 direction (so that PRODUCE_GLYPHS does TRT wrt
4377 prepending/appending glyphs to a glyph row). */
4378 if (on_newline)
4380 it->bidi_it.first_elt = 0;
4381 it->bidi_it.paragraph_dir = pdir;
4382 it->bidi_it.ch = (bpos == ZV_BYTE) ? -1 : '\n';
4383 it->bidi_it.nchars = 1;
4384 it->bidi_it.ch_len = 1;
4387 else /* Must use the slow method. */
4389 /* With bidi iteration, the region of invisible text
4390 could start and/or end in the middle of a
4391 non-base embedding level. Therefore, we need to
4392 skip invisible text using the bidi iterator,
4393 starting at IT's current position, until we find
4394 ourselves outside of the invisible text.
4395 Skipping invisible text _after_ bidi iteration
4396 avoids affecting the visual order of the
4397 displayed text when invisible properties are
4398 added or removed. */
4399 if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV)
4401 /* If we were `reseat'ed to a new paragraph,
4402 determine the paragraph base direction. We
4403 need to do it now because
4404 next_element_from_buffer may not have a
4405 chance to do it, if we are going to skip any
4406 text at the beginning, which resets the
4407 FIRST_ELT flag. */
4408 bidi_paragraph_init (it->paragraph_embedding,
4409 &it->bidi_it, 1);
4413 bidi_move_to_visually_next (&it->bidi_it);
4415 while (it->stop_charpos <= it->bidi_it.charpos
4416 && it->bidi_it.charpos < newpos);
4417 IT_CHARPOS (*it) = it->bidi_it.charpos;
4418 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
4419 /* If we overstepped NEWPOS, record its position in
4420 the iterator, so that we skip invisible text if
4421 later the bidi iteration lands us in the
4422 invisible region again. */
4423 if (IT_CHARPOS (*it) >= newpos)
4424 it->prev_stop = newpos;
4427 else
4429 IT_CHARPOS (*it) = newpos;
4430 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
4433 /* If there are before-strings at the start of invisible
4434 text, and the text is invisible because of a text
4435 property, arrange to show before-strings because 20.x did
4436 it that way. (If the text is invisible because of an
4437 overlay property instead of a text property, this is
4438 already handled in the overlay code.) */
4439 if (NILP (overlay)
4440 && get_overlay_strings (it, it->stop_charpos))
4442 handled = HANDLED_RECOMPUTE_PROPS;
4443 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
4445 else if (display_ellipsis_p)
4447 /* Make sure that the glyphs of the ellipsis will get
4448 correct `charpos' values. If we would not update
4449 it->position here, the glyphs would belong to the
4450 last visible character _before_ the invisible
4451 text, which confuses `set_cursor_from_row'.
4453 We use the last invisible position instead of the
4454 first because this way the cursor is always drawn on
4455 the first "." of the ellipsis, whenever PT is inside
4456 the invisible text. Otherwise the cursor would be
4457 placed _after_ the ellipsis when the point is after the
4458 first invisible character. */
4459 if (!STRINGP (it->object))
4461 it->position.charpos = newpos - 1;
4462 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
4464 it->ellipsis_p = 1;
4465 /* Let the ellipsis display before
4466 considering any properties of the following char.
4467 Fixes jasonr@gnu.org 01 Oct 07 bug. */
4468 handled = HANDLED_RETURN;
4473 return handled;
4477 /* Make iterator IT return `...' next.
4478 Replaces LEN characters from buffer. */
4480 static void
4481 setup_for_ellipsis (struct it *it, int len)
4483 /* Use the display table definition for `...'. Invalid glyphs
4484 will be handled by the method returning elements from dpvec. */
4485 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
4487 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
4488 it->dpvec = v->contents;
4489 it->dpend = v->contents + v->header.size;
4491 else
4493 /* Default `...'. */
4494 it->dpvec = default_invis_vector;
4495 it->dpend = default_invis_vector + 3;
4498 it->dpvec_char_len = len;
4499 it->current.dpvec_index = 0;
4500 it->dpvec_face_id = -1;
4502 /* Remember the current face id in case glyphs specify faces.
4503 IT's face is restored in set_iterator_to_next.
4504 saved_face_id was set to preceding char's face in handle_stop. */
4505 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
4506 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
4508 it->method = GET_FROM_DISPLAY_VECTOR;
4509 it->ellipsis_p = 1;
4514 /***********************************************************************
4515 'display' property
4516 ***********************************************************************/
4518 /* Set up iterator IT from `display' property at its current position.
4519 Called from handle_stop.
4520 We return HANDLED_RETURN if some part of the display property
4521 overrides the display of the buffer text itself.
4522 Otherwise we return HANDLED_NORMALLY. */
4524 static enum prop_handled
4525 handle_display_prop (struct it *it)
4527 Lisp_Object propval, object, overlay;
4528 struct text_pos *position;
4529 ptrdiff_t bufpos;
4530 /* Nonzero if some property replaces the display of the text itself. */
4531 int display_replaced_p = 0;
4533 if (STRINGP (it->string))
4535 object = it->string;
4536 position = &it->current.string_pos;
4537 bufpos = CHARPOS (it->current.pos);
4539 else
4541 XSETWINDOW (object, it->w);
4542 position = &it->current.pos;
4543 bufpos = CHARPOS (*position);
4546 /* Reset those iterator values set from display property values. */
4547 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
4548 it->space_width = Qnil;
4549 it->font_height = Qnil;
4550 it->voffset = 0;
4552 /* We don't support recursive `display' properties, i.e. string
4553 values that have a string `display' property, that have a string
4554 `display' property etc. */
4555 if (!it->string_from_display_prop_p)
4556 it->area = TEXT_AREA;
4558 propval = get_char_property_and_overlay (make_number (position->charpos),
4559 Qdisplay, object, &overlay);
4560 if (NILP (propval))
4561 return HANDLED_NORMALLY;
4562 /* Now OVERLAY is the overlay that gave us this property, or nil
4563 if it was a text property. */
4565 if (!STRINGP (it->string))
4566 object = it->w->contents;
4568 display_replaced_p = handle_display_spec (it, propval, object, overlay,
4569 position, bufpos,
4570 FRAME_WINDOW_P (it->f));
4572 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
4575 /* Subroutine of handle_display_prop. Returns non-zero if the display
4576 specification in SPEC is a replacing specification, i.e. it would
4577 replace the text covered by `display' property with something else,
4578 such as an image or a display string. If SPEC includes any kind or
4579 `(space ...) specification, the value is 2; this is used by
4580 compute_display_string_pos, which see.
4582 See handle_single_display_spec for documentation of arguments.
4583 frame_window_p is non-zero if the window being redisplayed is on a
4584 GUI frame; this argument is used only if IT is NULL, see below.
4586 IT can be NULL, if this is called by the bidi reordering code
4587 through compute_display_string_pos, which see. In that case, this
4588 function only examines SPEC, but does not otherwise "handle" it, in
4589 the sense that it doesn't set up members of IT from the display
4590 spec. */
4591 static int
4592 handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4593 Lisp_Object overlay, struct text_pos *position,
4594 ptrdiff_t bufpos, int frame_window_p)
4596 int replacing_p = 0;
4597 int rv;
4599 if (CONSP (spec)
4600 /* Simple specifications. */
4601 && !EQ (XCAR (spec), Qimage)
4602 && !EQ (XCAR (spec), Qspace)
4603 && !EQ (XCAR (spec), Qwhen)
4604 && !EQ (XCAR (spec), Qslice)
4605 && !EQ (XCAR (spec), Qspace_width)
4606 && !EQ (XCAR (spec), Qheight)
4607 && !EQ (XCAR (spec), Qraise)
4608 /* Marginal area specifications. */
4609 && !(CONSP (XCAR (spec)) && EQ (XCAR (XCAR (spec)), Qmargin))
4610 && !EQ (XCAR (spec), Qleft_fringe)
4611 && !EQ (XCAR (spec), Qright_fringe)
4612 && !NILP (XCAR (spec)))
4614 for (; CONSP (spec); spec = XCDR (spec))
4616 if ((rv = handle_single_display_spec (it, XCAR (spec), object,
4617 overlay, position, bufpos,
4618 replacing_p, frame_window_p)))
4620 replacing_p = rv;
4621 /* If some text in a string is replaced, `position' no
4622 longer points to the position of `object'. */
4623 if (!it || STRINGP (object))
4624 break;
4628 else if (VECTORP (spec))
4630 ptrdiff_t i;
4631 for (i = 0; i < ASIZE (spec); ++i)
4632 if ((rv = handle_single_display_spec (it, AREF (spec, i), object,
4633 overlay, position, bufpos,
4634 replacing_p, frame_window_p)))
4636 replacing_p = rv;
4637 /* If some text in a string is replaced, `position' no
4638 longer points to the position of `object'. */
4639 if (!it || STRINGP (object))
4640 break;
4643 else
4645 if ((rv = handle_single_display_spec (it, spec, object, overlay,
4646 position, bufpos, 0,
4647 frame_window_p)))
4648 replacing_p = rv;
4651 return replacing_p;
4654 /* Value is the position of the end of the `display' property starting
4655 at START_POS in OBJECT. */
4657 static struct text_pos
4658 display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
4660 Lisp_Object end;
4661 struct text_pos end_pos;
4663 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
4664 Qdisplay, object, Qnil);
4665 CHARPOS (end_pos) = XFASTINT (end);
4666 if (STRINGP (object))
4667 compute_string_pos (&end_pos, start_pos, it->string);
4668 else
4669 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
4671 return end_pos;
4675 /* Set up IT from a single `display' property specification SPEC. OBJECT
4676 is the object in which the `display' property was found. *POSITION
4677 is the position in OBJECT at which the `display' property was found.
4678 BUFPOS is the buffer position of OBJECT (different from POSITION if
4679 OBJECT is not a buffer). DISPLAY_REPLACED_P non-zero means that we
4680 previously saw a display specification which already replaced text
4681 display with something else, for example an image; we ignore such
4682 properties after the first one has been processed.
4684 OVERLAY is the overlay this `display' property came from,
4685 or nil if it was a text property.
4687 If SPEC is a `space' or `image' specification, and in some other
4688 cases too, set *POSITION to the position where the `display'
4689 property ends.
4691 If IT is NULL, only examine the property specification in SPEC, but
4692 don't set up IT. In that case, FRAME_WINDOW_P non-zero means SPEC
4693 is intended to be displayed in a window on a GUI frame.
4695 Value is non-zero if something was found which replaces the display
4696 of buffer or string text. */
4698 static int
4699 handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4700 Lisp_Object overlay, struct text_pos *position,
4701 ptrdiff_t bufpos, int display_replaced_p,
4702 int frame_window_p)
4704 Lisp_Object form;
4705 Lisp_Object location, value;
4706 struct text_pos start_pos = *position;
4707 int valid_p;
4709 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4710 If the result is non-nil, use VALUE instead of SPEC. */
4711 form = Qt;
4712 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
4714 spec = XCDR (spec);
4715 if (!CONSP (spec))
4716 return 0;
4717 form = XCAR (spec);
4718 spec = XCDR (spec);
4721 if (!NILP (form) && !EQ (form, Qt))
4723 ptrdiff_t count = SPECPDL_INDEX ();
4724 struct gcpro gcpro1;
4726 /* Bind `object' to the object having the `display' property, a
4727 buffer or string. Bind `position' to the position in the
4728 object where the property was found, and `buffer-position'
4729 to the current position in the buffer. */
4731 if (NILP (object))
4732 XSETBUFFER (object, current_buffer);
4733 specbind (Qobject, object);
4734 specbind (Qposition, make_number (CHARPOS (*position)));
4735 specbind (Qbuffer_position, make_number (bufpos));
4736 GCPRO1 (form);
4737 form = safe_eval (form);
4738 UNGCPRO;
4739 unbind_to (count, Qnil);
4742 if (NILP (form))
4743 return 0;
4745 /* Handle `(height HEIGHT)' specifications. */
4746 if (CONSP (spec)
4747 && EQ (XCAR (spec), Qheight)
4748 && CONSP (XCDR (spec)))
4750 if (it)
4752 if (!FRAME_WINDOW_P (it->f))
4753 return 0;
4755 it->font_height = XCAR (XCDR (spec));
4756 if (!NILP (it->font_height))
4758 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4759 int new_height = -1;
4761 if (CONSP (it->font_height)
4762 && (EQ (XCAR (it->font_height), Qplus)
4763 || EQ (XCAR (it->font_height), Qminus))
4764 && CONSP (XCDR (it->font_height))
4765 && RANGED_INTEGERP (0, XCAR (XCDR (it->font_height)), INT_MAX))
4767 /* `(+ N)' or `(- N)' where N is an integer. */
4768 int steps = XINT (XCAR (XCDR (it->font_height)));
4769 if (EQ (XCAR (it->font_height), Qplus))
4770 steps = - steps;
4771 it->face_id = smaller_face (it->f, it->face_id, steps);
4773 else if (FUNCTIONP (it->font_height))
4775 /* Call function with current height as argument.
4776 Value is the new height. */
4777 Lisp_Object height;
4778 height = safe_call1 (it->font_height,
4779 face->lface[LFACE_HEIGHT_INDEX]);
4780 if (NUMBERP (height))
4781 new_height = XFLOATINT (height);
4783 else if (NUMBERP (it->font_height))
4785 /* Value is a multiple of the canonical char height. */
4786 struct face *f;
4788 f = FACE_FROM_ID (it->f,
4789 lookup_basic_face (it->f, DEFAULT_FACE_ID));
4790 new_height = (XFLOATINT (it->font_height)
4791 * XINT (f->lface[LFACE_HEIGHT_INDEX]));
4793 else
4795 /* Evaluate IT->font_height with `height' bound to the
4796 current specified height to get the new height. */
4797 ptrdiff_t count = SPECPDL_INDEX ();
4799 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
4800 value = safe_eval (it->font_height);
4801 unbind_to (count, Qnil);
4803 if (NUMBERP (value))
4804 new_height = XFLOATINT (value);
4807 if (new_height > 0)
4808 it->face_id = face_with_height (it->f, it->face_id, new_height);
4812 return 0;
4815 /* Handle `(space-width WIDTH)'. */
4816 if (CONSP (spec)
4817 && EQ (XCAR (spec), Qspace_width)
4818 && CONSP (XCDR (spec)))
4820 if (it)
4822 if (!FRAME_WINDOW_P (it->f))
4823 return 0;
4825 value = XCAR (XCDR (spec));
4826 if (NUMBERP (value) && XFLOATINT (value) > 0)
4827 it->space_width = value;
4830 return 0;
4833 /* Handle `(slice X Y WIDTH HEIGHT)'. */
4834 if (CONSP (spec)
4835 && EQ (XCAR (spec), Qslice))
4837 Lisp_Object tem;
4839 if (it)
4841 if (!FRAME_WINDOW_P (it->f))
4842 return 0;
4844 if (tem = XCDR (spec), CONSP (tem))
4846 it->slice.x = XCAR (tem);
4847 if (tem = XCDR (tem), CONSP (tem))
4849 it->slice.y = XCAR (tem);
4850 if (tem = XCDR (tem), CONSP (tem))
4852 it->slice.width = XCAR (tem);
4853 if (tem = XCDR (tem), CONSP (tem))
4854 it->slice.height = XCAR (tem);
4860 return 0;
4863 /* Handle `(raise FACTOR)'. */
4864 if (CONSP (spec)
4865 && EQ (XCAR (spec), Qraise)
4866 && CONSP (XCDR (spec)))
4868 if (it)
4870 if (!FRAME_WINDOW_P (it->f))
4871 return 0;
4873 #ifdef HAVE_WINDOW_SYSTEM
4874 value = XCAR (XCDR (spec));
4875 if (NUMBERP (value))
4877 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4878 it->voffset = - (XFLOATINT (value)
4879 * (FONT_HEIGHT (face->font)));
4881 #endif /* HAVE_WINDOW_SYSTEM */
4884 return 0;
4887 /* Don't handle the other kinds of display specifications
4888 inside a string that we got from a `display' property. */
4889 if (it && it->string_from_display_prop_p)
4890 return 0;
4892 /* Characters having this form of property are not displayed, so
4893 we have to find the end of the property. */
4894 if (it)
4896 start_pos = *position;
4897 *position = display_prop_end (it, object, start_pos);
4899 value = Qnil;
4901 /* Stop the scan at that end position--we assume that all
4902 text properties change there. */
4903 if (it)
4904 it->stop_charpos = position->charpos;
4906 /* Handle `(left-fringe BITMAP [FACE])'
4907 and `(right-fringe BITMAP [FACE])'. */
4908 if (CONSP (spec)
4909 && (EQ (XCAR (spec), Qleft_fringe)
4910 || EQ (XCAR (spec), Qright_fringe))
4911 && CONSP (XCDR (spec)))
4913 int fringe_bitmap;
4915 if (it)
4917 if (!FRAME_WINDOW_P (it->f))
4918 /* If we return here, POSITION has been advanced
4919 across the text with this property. */
4921 /* Synchronize the bidi iterator with POSITION. This is
4922 needed because we are not going to push the iterator
4923 on behalf of this display property, so there will be
4924 no pop_it call to do this synchronization for us. */
4925 if (it->bidi_p)
4927 it->position = *position;
4928 iterate_out_of_display_property (it);
4929 *position = it->position;
4931 return 1;
4934 else if (!frame_window_p)
4935 return 1;
4937 #ifdef HAVE_WINDOW_SYSTEM
4938 value = XCAR (XCDR (spec));
4939 if (!SYMBOLP (value)
4940 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
4941 /* If we return here, POSITION has been advanced
4942 across the text with this property. */
4944 if (it && it->bidi_p)
4946 it->position = *position;
4947 iterate_out_of_display_property (it);
4948 *position = it->position;
4950 return 1;
4953 if (it)
4955 int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);;
4957 if (CONSP (XCDR (XCDR (spec))))
4959 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
4960 int face_id2 = lookup_derived_face (it->f, face_name,
4961 FRINGE_FACE_ID, 0);
4962 if (face_id2 >= 0)
4963 face_id = face_id2;
4966 /* Save current settings of IT so that we can restore them
4967 when we are finished with the glyph property value. */
4968 push_it (it, position);
4970 it->area = TEXT_AREA;
4971 it->what = IT_IMAGE;
4972 it->image_id = -1; /* no image */
4973 it->position = start_pos;
4974 it->object = NILP (object) ? it->w->contents : object;
4975 it->method = GET_FROM_IMAGE;
4976 it->from_overlay = Qnil;
4977 it->face_id = face_id;
4978 it->from_disp_prop_p = 1;
4980 /* Say that we haven't consumed the characters with
4981 `display' property yet. The call to pop_it in
4982 set_iterator_to_next will clean this up. */
4983 *position = start_pos;
4985 if (EQ (XCAR (spec), Qleft_fringe))
4987 it->left_user_fringe_bitmap = fringe_bitmap;
4988 it->left_user_fringe_face_id = face_id;
4990 else
4992 it->right_user_fringe_bitmap = fringe_bitmap;
4993 it->right_user_fringe_face_id = face_id;
4996 #endif /* HAVE_WINDOW_SYSTEM */
4997 return 1;
5000 /* Prepare to handle `((margin left-margin) ...)',
5001 `((margin right-margin) ...)' and `((margin nil) ...)'
5002 prefixes for display specifications. */
5003 location = Qunbound;
5004 if (CONSP (spec) && CONSP (XCAR (spec)))
5006 Lisp_Object tem;
5008 value = XCDR (spec);
5009 if (CONSP (value))
5010 value = XCAR (value);
5012 tem = XCAR (spec);
5013 if (EQ (XCAR (tem), Qmargin)
5014 && (tem = XCDR (tem),
5015 tem = CONSP (tem) ? XCAR (tem) : Qnil,
5016 (NILP (tem)
5017 || EQ (tem, Qleft_margin)
5018 || EQ (tem, Qright_margin))))
5019 location = tem;
5022 if (EQ (location, Qunbound))
5024 location = Qnil;
5025 value = spec;
5028 /* After this point, VALUE is the property after any
5029 margin prefix has been stripped. It must be a string,
5030 an image specification, or `(space ...)'.
5032 LOCATION specifies where to display: `left-margin',
5033 `right-margin' or nil. */
5035 valid_p = (STRINGP (value)
5036 #ifdef HAVE_WINDOW_SYSTEM
5037 || ((it ? FRAME_WINDOW_P (it->f) : frame_window_p)
5038 && valid_image_p (value))
5039 #endif /* not HAVE_WINDOW_SYSTEM */
5040 || (CONSP (value) && EQ (XCAR (value), Qspace)));
5042 if (valid_p && !display_replaced_p)
5044 int retval = 1;
5046 if (!it)
5048 /* Callers need to know whether the display spec is any kind
5049 of `(space ...)' spec that is about to affect text-area
5050 display. */
5051 if (CONSP (value) && EQ (XCAR (value), Qspace) && NILP (location))
5052 retval = 2;
5053 return retval;
5056 /* Save current settings of IT so that we can restore them
5057 when we are finished with the glyph property value. */
5058 push_it (it, position);
5059 it->from_overlay = overlay;
5060 it->from_disp_prop_p = 1;
5062 if (NILP (location))
5063 it->area = TEXT_AREA;
5064 else if (EQ (location, Qleft_margin))
5065 it->area = LEFT_MARGIN_AREA;
5066 else
5067 it->area = RIGHT_MARGIN_AREA;
5069 if (STRINGP (value))
5071 it->string = value;
5072 it->multibyte_p = STRING_MULTIBYTE (it->string);
5073 it->current.overlay_string_index = -1;
5074 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5075 it->end_charpos = it->string_nchars = SCHARS (it->string);
5076 it->method = GET_FROM_STRING;
5077 it->stop_charpos = 0;
5078 it->prev_stop = 0;
5079 it->base_level_stop = 0;
5080 it->string_from_display_prop_p = 1;
5081 /* Say that we haven't consumed the characters with
5082 `display' property yet. The call to pop_it in
5083 set_iterator_to_next will clean this up. */
5084 if (BUFFERP (object))
5085 *position = start_pos;
5087 /* Force paragraph direction to be that of the parent
5088 object. If the parent object's paragraph direction is
5089 not yet determined, default to L2R. */
5090 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
5091 it->paragraph_embedding = it->bidi_it.paragraph_dir;
5092 else
5093 it->paragraph_embedding = L2R;
5095 /* Set up the bidi iterator for this display string. */
5096 if (it->bidi_p)
5098 it->bidi_it.string.lstring = it->string;
5099 it->bidi_it.string.s = NULL;
5100 it->bidi_it.string.schars = it->end_charpos;
5101 it->bidi_it.string.bufpos = bufpos;
5102 it->bidi_it.string.from_disp_str = 1;
5103 it->bidi_it.string.unibyte = !it->multibyte_p;
5104 it->bidi_it.w = it->w;
5105 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5108 else if (CONSP (value) && EQ (XCAR (value), Qspace))
5110 it->method = GET_FROM_STRETCH;
5111 it->object = value;
5112 *position = it->position = start_pos;
5113 retval = 1 + (it->area == TEXT_AREA);
5115 #ifdef HAVE_WINDOW_SYSTEM
5116 else
5118 it->what = IT_IMAGE;
5119 it->image_id = lookup_image (it->f, value);
5120 it->position = start_pos;
5121 it->object = NILP (object) ? it->w->contents : object;
5122 it->method = GET_FROM_IMAGE;
5124 /* Say that we haven't consumed the characters with
5125 `display' property yet. The call to pop_it in
5126 set_iterator_to_next will clean this up. */
5127 *position = start_pos;
5129 #endif /* HAVE_WINDOW_SYSTEM */
5131 return retval;
5134 /* Invalid property or property not supported. Restore
5135 POSITION to what it was before. */
5136 *position = start_pos;
5137 return 0;
5140 /* Check if PROP is a display property value whose text should be
5141 treated as intangible. OVERLAY is the overlay from which PROP
5142 came, or nil if it came from a text property. CHARPOS and BYTEPOS
5143 specify the buffer position covered by PROP. */
5146 display_prop_intangible_p (Lisp_Object prop, Lisp_Object overlay,
5147 ptrdiff_t charpos, ptrdiff_t bytepos)
5149 int frame_window_p = FRAME_WINDOW_P (XFRAME (selected_frame));
5150 struct text_pos position;
5152 SET_TEXT_POS (position, charpos, bytepos);
5153 return handle_display_spec (NULL, prop, Qnil, overlay,
5154 &position, charpos, frame_window_p);
5158 /* Return 1 if PROP is a display sub-property value containing STRING.
5160 Implementation note: this and the following function are really
5161 special cases of handle_display_spec and
5162 handle_single_display_spec, and should ideally use the same code.
5163 Until they do, these two pairs must be consistent and must be
5164 modified in sync. */
5166 static int
5167 single_display_spec_string_p (Lisp_Object prop, Lisp_Object string)
5169 if (EQ (string, prop))
5170 return 1;
5172 /* Skip over `when FORM'. */
5173 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
5175 prop = XCDR (prop);
5176 if (!CONSP (prop))
5177 return 0;
5178 /* Actually, the condition following `when' should be eval'ed,
5179 like handle_single_display_spec does, and we should return
5180 zero if it evaluates to nil. However, this function is
5181 called only when the buffer was already displayed and some
5182 glyph in the glyph matrix was found to come from a display
5183 string. Therefore, the condition was already evaluated, and
5184 the result was non-nil, otherwise the display string wouldn't
5185 have been displayed and we would have never been called for
5186 this property. Thus, we can skip the evaluation and assume
5187 its result is non-nil. */
5188 prop = XCDR (prop);
5191 if (CONSP (prop))
5192 /* Skip over `margin LOCATION'. */
5193 if (EQ (XCAR (prop), Qmargin))
5195 prop = XCDR (prop);
5196 if (!CONSP (prop))
5197 return 0;
5199 prop = XCDR (prop);
5200 if (!CONSP (prop))
5201 return 0;
5204 return EQ (prop, string) || (CONSP (prop) && EQ (XCAR (prop), string));
5208 /* Return 1 if STRING appears in the `display' property PROP. */
5210 static int
5211 display_prop_string_p (Lisp_Object prop, Lisp_Object string)
5213 if (CONSP (prop)
5214 && !EQ (XCAR (prop), Qwhen)
5215 && !(CONSP (XCAR (prop)) && EQ (Qmargin, XCAR (XCAR (prop)))))
5217 /* A list of sub-properties. */
5218 while (CONSP (prop))
5220 if (single_display_spec_string_p (XCAR (prop), string))
5221 return 1;
5222 prop = XCDR (prop);
5225 else if (VECTORP (prop))
5227 /* A vector of sub-properties. */
5228 ptrdiff_t i;
5229 for (i = 0; i < ASIZE (prop); ++i)
5230 if (single_display_spec_string_p (AREF (prop, i), string))
5231 return 1;
5233 else
5234 return single_display_spec_string_p (prop, string);
5236 return 0;
5239 /* Look for STRING in overlays and text properties in the current
5240 buffer, between character positions FROM and TO (excluding TO).
5241 BACK_P non-zero means look back (in this case, TO is supposed to be
5242 less than FROM).
5243 Value is the first character position where STRING was found, or
5244 zero if it wasn't found before hitting TO.
5246 This function may only use code that doesn't eval because it is
5247 called asynchronously from note_mouse_highlight. */
5249 static ptrdiff_t
5250 string_buffer_position_lim (Lisp_Object string,
5251 ptrdiff_t from, ptrdiff_t to, int back_p)
5253 Lisp_Object limit, prop, pos;
5254 int found = 0;
5256 pos = make_number (max (from, BEGV));
5258 if (!back_p) /* looking forward */
5260 limit = make_number (min (to, ZV));
5261 while (!found && !EQ (pos, limit))
5263 prop = Fget_char_property (pos, Qdisplay, Qnil);
5264 if (!NILP (prop) && display_prop_string_p (prop, string))
5265 found = 1;
5266 else
5267 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil,
5268 limit);
5271 else /* looking back */
5273 limit = make_number (max (to, BEGV));
5274 while (!found && !EQ (pos, limit))
5276 prop = Fget_char_property (pos, Qdisplay, Qnil);
5277 if (!NILP (prop) && display_prop_string_p (prop, string))
5278 found = 1;
5279 else
5280 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
5281 limit);
5285 return found ? XINT (pos) : 0;
5288 /* Determine which buffer position in current buffer STRING comes from.
5289 AROUND_CHARPOS is an approximate position where it could come from.
5290 Value is the buffer position or 0 if it couldn't be determined.
5292 This function is necessary because we don't record buffer positions
5293 in glyphs generated from strings (to keep struct glyph small).
5294 This function may only use code that doesn't eval because it is
5295 called asynchronously from note_mouse_highlight. */
5297 static ptrdiff_t
5298 string_buffer_position (Lisp_Object string, ptrdiff_t around_charpos)
5300 const int MAX_DISTANCE = 1000;
5301 ptrdiff_t found = string_buffer_position_lim (string, around_charpos,
5302 around_charpos + MAX_DISTANCE,
5305 if (!found)
5306 found = string_buffer_position_lim (string, around_charpos,
5307 around_charpos - MAX_DISTANCE, 1);
5308 return found;
5313 /***********************************************************************
5314 `composition' property
5315 ***********************************************************************/
5317 /* Set up iterator IT from `composition' property at its current
5318 position. Called from handle_stop. */
5320 static enum prop_handled
5321 handle_composition_prop (struct it *it)
5323 Lisp_Object prop, string;
5324 ptrdiff_t pos, pos_byte, start, end;
5326 if (STRINGP (it->string))
5328 unsigned char *s;
5330 pos = IT_STRING_CHARPOS (*it);
5331 pos_byte = IT_STRING_BYTEPOS (*it);
5332 string = it->string;
5333 s = SDATA (string) + pos_byte;
5334 it->c = STRING_CHAR (s);
5336 else
5338 pos = IT_CHARPOS (*it);
5339 pos_byte = IT_BYTEPOS (*it);
5340 string = Qnil;
5341 it->c = FETCH_CHAR (pos_byte);
5344 /* If there's a valid composition and point is not inside of the
5345 composition (in the case that the composition is from the current
5346 buffer), draw a glyph composed from the composition components. */
5347 if (find_composition (pos, -1, &start, &end, &prop, string)
5348 && composition_valid_p (start, end, prop)
5349 && (STRINGP (it->string) || (PT <= start || PT >= end)))
5351 if (start < pos)
5352 /* As we can't handle this situation (perhaps font-lock added
5353 a new composition), we just return here hoping that next
5354 redisplay will detect this composition much earlier. */
5355 return HANDLED_NORMALLY;
5356 if (start != pos)
5358 if (STRINGP (it->string))
5359 pos_byte = string_char_to_byte (it->string, start);
5360 else
5361 pos_byte = CHAR_TO_BYTE (start);
5363 it->cmp_it.id = get_composition_id (start, pos_byte, end - start,
5364 prop, string);
5366 if (it->cmp_it.id >= 0)
5368 it->cmp_it.ch = -1;
5369 it->cmp_it.nchars = COMPOSITION_LENGTH (prop);
5370 it->cmp_it.nglyphs = -1;
5374 return HANDLED_NORMALLY;
5379 /***********************************************************************
5380 Overlay strings
5381 ***********************************************************************/
5383 /* The following structure is used to record overlay strings for
5384 later sorting in load_overlay_strings. */
5386 struct overlay_entry
5388 Lisp_Object overlay;
5389 Lisp_Object string;
5390 EMACS_INT priority;
5391 int after_string_p;
5395 /* Set up iterator IT from overlay strings at its current position.
5396 Called from handle_stop. */
5398 static enum prop_handled
5399 handle_overlay_change (struct it *it)
5401 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
5402 return HANDLED_RECOMPUTE_PROPS;
5403 else
5404 return HANDLED_NORMALLY;
5408 /* Set up the next overlay string for delivery by IT, if there is an
5409 overlay string to deliver. Called by set_iterator_to_next when the
5410 end of the current overlay string is reached. If there are more
5411 overlay strings to display, IT->string and
5412 IT->current.overlay_string_index are set appropriately here.
5413 Otherwise IT->string is set to nil. */
5415 static void
5416 next_overlay_string (struct it *it)
5418 ++it->current.overlay_string_index;
5419 if (it->current.overlay_string_index == it->n_overlay_strings)
5421 /* No more overlay strings. Restore IT's settings to what
5422 they were before overlay strings were processed, and
5423 continue to deliver from current_buffer. */
5425 it->ellipsis_p = (it->stack[it->sp - 1].display_ellipsis_p != 0);
5426 pop_it (it);
5427 eassert (it->sp > 0
5428 || (NILP (it->string)
5429 && it->method == GET_FROM_BUFFER
5430 && it->stop_charpos >= BEGV
5431 && it->stop_charpos <= it->end_charpos));
5432 it->current.overlay_string_index = -1;
5433 it->n_overlay_strings = 0;
5434 it->overlay_strings_charpos = -1;
5435 /* If there's an empty display string on the stack, pop the
5436 stack, to resync the bidi iterator with IT's position. Such
5437 empty strings are pushed onto the stack in
5438 get_overlay_strings_1. */
5439 if (it->sp > 0 && STRINGP (it->string) && !SCHARS (it->string))
5440 pop_it (it);
5442 /* If we're at the end of the buffer, record that we have
5443 processed the overlay strings there already, so that
5444 next_element_from_buffer doesn't try it again. */
5445 if (NILP (it->string) && IT_CHARPOS (*it) >= it->end_charpos)
5446 it->overlay_strings_at_end_processed_p = 1;
5448 else
5450 /* There are more overlay strings to process. If
5451 IT->current.overlay_string_index has advanced to a position
5452 where we must load IT->overlay_strings with more strings, do
5453 it. We must load at the IT->overlay_strings_charpos where
5454 IT->n_overlay_strings was originally computed; when invisible
5455 text is present, this might not be IT_CHARPOS (Bug#7016). */
5456 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
5458 if (it->current.overlay_string_index && i == 0)
5459 load_overlay_strings (it, it->overlay_strings_charpos);
5461 /* Initialize IT to deliver display elements from the overlay
5462 string. */
5463 it->string = it->overlay_strings[i];
5464 it->multibyte_p = STRING_MULTIBYTE (it->string);
5465 SET_TEXT_POS (it->current.string_pos, 0, 0);
5466 it->method = GET_FROM_STRING;
5467 it->stop_charpos = 0;
5468 it->end_charpos = SCHARS (it->string);
5469 if (it->cmp_it.stop_pos >= 0)
5470 it->cmp_it.stop_pos = 0;
5471 it->prev_stop = 0;
5472 it->base_level_stop = 0;
5474 /* Set up the bidi iterator for this overlay string. */
5475 if (it->bidi_p)
5477 it->bidi_it.string.lstring = it->string;
5478 it->bidi_it.string.s = NULL;
5479 it->bidi_it.string.schars = SCHARS (it->string);
5480 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
5481 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5482 it->bidi_it.string.unibyte = !it->multibyte_p;
5483 it->bidi_it.w = it->w;
5484 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5488 CHECK_IT (it);
5492 /* Compare two overlay_entry structures E1 and E2. Used as a
5493 comparison function for qsort in load_overlay_strings. Overlay
5494 strings for the same position are sorted so that
5496 1. All after-strings come in front of before-strings, except
5497 when they come from the same overlay.
5499 2. Within after-strings, strings are sorted so that overlay strings
5500 from overlays with higher priorities come first.
5502 2. Within before-strings, strings are sorted so that overlay
5503 strings from overlays with higher priorities come last.
5505 Value is analogous to strcmp. */
5508 static int
5509 compare_overlay_entries (const void *e1, const void *e2)
5511 struct overlay_entry const *entry1 = e1;
5512 struct overlay_entry const *entry2 = e2;
5513 int result;
5515 if (entry1->after_string_p != entry2->after_string_p)
5517 /* Let after-strings appear in front of before-strings if
5518 they come from different overlays. */
5519 if (EQ (entry1->overlay, entry2->overlay))
5520 result = entry1->after_string_p ? 1 : -1;
5521 else
5522 result = entry1->after_string_p ? -1 : 1;
5524 else if (entry1->priority != entry2->priority)
5526 if (entry1->after_string_p)
5527 /* After-strings sorted in order of decreasing priority. */
5528 result = entry2->priority < entry1->priority ? -1 : 1;
5529 else
5530 /* Before-strings sorted in order of increasing priority. */
5531 result = entry1->priority < entry2->priority ? -1 : 1;
5533 else
5534 result = 0;
5536 return result;
5540 /* Load the vector IT->overlay_strings with overlay strings from IT's
5541 current buffer position, or from CHARPOS if that is > 0. Set
5542 IT->n_overlays to the total number of overlay strings found.
5544 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
5545 a time. On entry into load_overlay_strings,
5546 IT->current.overlay_string_index gives the number of overlay
5547 strings that have already been loaded by previous calls to this
5548 function.
5550 IT->add_overlay_start contains an additional overlay start
5551 position to consider for taking overlay strings from, if non-zero.
5552 This position comes into play when the overlay has an `invisible'
5553 property, and both before and after-strings. When we've skipped to
5554 the end of the overlay, because of its `invisible' property, we
5555 nevertheless want its before-string to appear.
5556 IT->add_overlay_start will contain the overlay start position
5557 in this case.
5559 Overlay strings are sorted so that after-string strings come in
5560 front of before-string strings. Within before and after-strings,
5561 strings are sorted by overlay priority. See also function
5562 compare_overlay_entries. */
5564 static void
5565 load_overlay_strings (struct it *it, ptrdiff_t charpos)
5567 Lisp_Object overlay, window, str, invisible;
5568 struct Lisp_Overlay *ov;
5569 ptrdiff_t start, end;
5570 ptrdiff_t size = 20;
5571 ptrdiff_t n = 0, i, j;
5572 int invis_p;
5573 struct overlay_entry *entries = alloca (size * sizeof *entries);
5574 USE_SAFE_ALLOCA;
5576 if (charpos <= 0)
5577 charpos = IT_CHARPOS (*it);
5579 /* Append the overlay string STRING of overlay OVERLAY to vector
5580 `entries' which has size `size' and currently contains `n'
5581 elements. AFTER_P non-zero means STRING is an after-string of
5582 OVERLAY. */
5583 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
5584 do \
5586 Lisp_Object priority; \
5588 if (n == size) \
5590 struct overlay_entry *old = entries; \
5591 SAFE_NALLOCA (entries, 2, size); \
5592 memcpy (entries, old, size * sizeof *entries); \
5593 size *= 2; \
5596 entries[n].string = (STRING); \
5597 entries[n].overlay = (OVERLAY); \
5598 priority = Foverlay_get ((OVERLAY), Qpriority); \
5599 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
5600 entries[n].after_string_p = (AFTER_P); \
5601 ++n; \
5603 while (0)
5605 /* Process overlay before the overlay center. */
5606 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
5608 XSETMISC (overlay, ov);
5609 eassert (OVERLAYP (overlay));
5610 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5611 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5613 if (end < charpos)
5614 break;
5616 /* Skip this overlay if it doesn't start or end at IT's current
5617 position. */
5618 if (end != charpos && start != charpos)
5619 continue;
5621 /* Skip this overlay if it doesn't apply to IT->w. */
5622 window = Foverlay_get (overlay, Qwindow);
5623 if (WINDOWP (window) && XWINDOW (window) != it->w)
5624 continue;
5626 /* If the text ``under'' the overlay is invisible, both before-
5627 and after-strings from this overlay are visible; start and
5628 end position are indistinguishable. */
5629 invisible = Foverlay_get (overlay, Qinvisible);
5630 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5632 /* If overlay has a non-empty before-string, record it. */
5633 if ((start == charpos || (end == charpos && invis_p))
5634 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5635 && SCHARS (str))
5636 RECORD_OVERLAY_STRING (overlay, str, 0);
5638 /* If overlay has a non-empty after-string, record it. */
5639 if ((end == charpos || (start == charpos && invis_p))
5640 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5641 && SCHARS (str))
5642 RECORD_OVERLAY_STRING (overlay, str, 1);
5645 /* Process overlays after the overlay center. */
5646 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
5648 XSETMISC (overlay, ov);
5649 eassert (OVERLAYP (overlay));
5650 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5651 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5653 if (start > charpos)
5654 break;
5656 /* Skip this overlay if it doesn't start or end at IT's current
5657 position. */
5658 if (end != charpos && start != charpos)
5659 continue;
5661 /* Skip this overlay if it doesn't apply to IT->w. */
5662 window = Foverlay_get (overlay, Qwindow);
5663 if (WINDOWP (window) && XWINDOW (window) != it->w)
5664 continue;
5666 /* If the text ``under'' the overlay is invisible, it has a zero
5667 dimension, and both before- and after-strings apply. */
5668 invisible = Foverlay_get (overlay, Qinvisible);
5669 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5671 /* If overlay has a non-empty before-string, record it. */
5672 if ((start == charpos || (end == charpos && invis_p))
5673 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5674 && SCHARS (str))
5675 RECORD_OVERLAY_STRING (overlay, str, 0);
5677 /* If overlay has a non-empty after-string, record it. */
5678 if ((end == charpos || (start == charpos && invis_p))
5679 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5680 && SCHARS (str))
5681 RECORD_OVERLAY_STRING (overlay, str, 1);
5684 #undef RECORD_OVERLAY_STRING
5686 /* Sort entries. */
5687 if (n > 1)
5688 qsort (entries, n, sizeof *entries, compare_overlay_entries);
5690 /* Record number of overlay strings, and where we computed it. */
5691 it->n_overlay_strings = n;
5692 it->overlay_strings_charpos = charpos;
5694 /* IT->current.overlay_string_index is the number of overlay strings
5695 that have already been consumed by IT. Copy some of the
5696 remaining overlay strings to IT->overlay_strings. */
5697 i = 0;
5698 j = it->current.overlay_string_index;
5699 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
5701 it->overlay_strings[i] = entries[j].string;
5702 it->string_overlays[i++] = entries[j++].overlay;
5705 CHECK_IT (it);
5706 SAFE_FREE ();
5710 /* Get the first chunk of overlay strings at IT's current buffer
5711 position, or at CHARPOS if that is > 0. Value is non-zero if at
5712 least one overlay string was found. */
5714 static int
5715 get_overlay_strings_1 (struct it *it, ptrdiff_t charpos, int compute_stop_p)
5717 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
5718 process. This fills IT->overlay_strings with strings, and sets
5719 IT->n_overlay_strings to the total number of strings to process.
5720 IT->pos.overlay_string_index has to be set temporarily to zero
5721 because load_overlay_strings needs this; it must be set to -1
5722 when no overlay strings are found because a zero value would
5723 indicate a position in the first overlay string. */
5724 it->current.overlay_string_index = 0;
5725 load_overlay_strings (it, charpos);
5727 /* If we found overlay strings, set up IT to deliver display
5728 elements from the first one. Otherwise set up IT to deliver
5729 from current_buffer. */
5730 if (it->n_overlay_strings)
5732 /* Make sure we know settings in current_buffer, so that we can
5733 restore meaningful values when we're done with the overlay
5734 strings. */
5735 if (compute_stop_p)
5736 compute_stop_pos (it);
5737 eassert (it->face_id >= 0);
5739 /* Save IT's settings. They are restored after all overlay
5740 strings have been processed. */
5741 eassert (!compute_stop_p || it->sp == 0);
5743 /* When called from handle_stop, there might be an empty display
5744 string loaded. In that case, don't bother saving it. But
5745 don't use this optimization with the bidi iterator, since we
5746 need the corresponding pop_it call to resync the bidi
5747 iterator's position with IT's position, after we are done
5748 with the overlay strings. (The corresponding call to pop_it
5749 in case of an empty display string is in
5750 next_overlay_string.) */
5751 if (!(!it->bidi_p
5752 && STRINGP (it->string) && !SCHARS (it->string)))
5753 push_it (it, NULL);
5755 /* Set up IT to deliver display elements from the first overlay
5756 string. */
5757 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5758 it->string = it->overlay_strings[0];
5759 it->from_overlay = Qnil;
5760 it->stop_charpos = 0;
5761 eassert (STRINGP (it->string));
5762 it->end_charpos = SCHARS (it->string);
5763 it->prev_stop = 0;
5764 it->base_level_stop = 0;
5765 it->multibyte_p = STRING_MULTIBYTE (it->string);
5766 it->method = GET_FROM_STRING;
5767 it->from_disp_prop_p = 0;
5769 /* Force paragraph direction to be that of the parent
5770 buffer. */
5771 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
5772 it->paragraph_embedding = it->bidi_it.paragraph_dir;
5773 else
5774 it->paragraph_embedding = L2R;
5776 /* Set up the bidi iterator for this overlay string. */
5777 if (it->bidi_p)
5779 ptrdiff_t pos = (charpos > 0 ? charpos : IT_CHARPOS (*it));
5781 it->bidi_it.string.lstring = it->string;
5782 it->bidi_it.string.s = NULL;
5783 it->bidi_it.string.schars = SCHARS (it->string);
5784 it->bidi_it.string.bufpos = pos;
5785 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5786 it->bidi_it.string.unibyte = !it->multibyte_p;
5787 it->bidi_it.w = it->w;
5788 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5790 return 1;
5793 it->current.overlay_string_index = -1;
5794 return 0;
5797 static int
5798 get_overlay_strings (struct it *it, ptrdiff_t charpos)
5800 it->string = Qnil;
5801 it->method = GET_FROM_BUFFER;
5803 (void) get_overlay_strings_1 (it, charpos, 1);
5805 CHECK_IT (it);
5807 /* Value is non-zero if we found at least one overlay string. */
5808 return STRINGP (it->string);
5813 /***********************************************************************
5814 Saving and restoring state
5815 ***********************************************************************/
5817 /* Save current settings of IT on IT->stack. Called, for example,
5818 before setting up IT for an overlay string, to be able to restore
5819 IT's settings to what they were after the overlay string has been
5820 processed. If POSITION is non-NULL, it is the position to save on
5821 the stack instead of IT->position. */
5823 static void
5824 push_it (struct it *it, struct text_pos *position)
5826 struct iterator_stack_entry *p;
5828 eassert (it->sp < IT_STACK_SIZE);
5829 p = it->stack + it->sp;
5831 p->stop_charpos = it->stop_charpos;
5832 p->prev_stop = it->prev_stop;
5833 p->base_level_stop = it->base_level_stop;
5834 p->cmp_it = it->cmp_it;
5835 eassert (it->face_id >= 0);
5836 p->face_id = it->face_id;
5837 p->string = it->string;
5838 p->method = it->method;
5839 p->from_overlay = it->from_overlay;
5840 switch (p->method)
5842 case GET_FROM_IMAGE:
5843 p->u.image.object = it->object;
5844 p->u.image.image_id = it->image_id;
5845 p->u.image.slice = it->slice;
5846 break;
5847 case GET_FROM_STRETCH:
5848 p->u.stretch.object = it->object;
5849 break;
5851 p->position = position ? *position : it->position;
5852 p->current = it->current;
5853 p->end_charpos = it->end_charpos;
5854 p->string_nchars = it->string_nchars;
5855 p->area = it->area;
5856 p->multibyte_p = it->multibyte_p;
5857 p->avoid_cursor_p = it->avoid_cursor_p;
5858 p->space_width = it->space_width;
5859 p->font_height = it->font_height;
5860 p->voffset = it->voffset;
5861 p->string_from_display_prop_p = it->string_from_display_prop_p;
5862 p->string_from_prefix_prop_p = it->string_from_prefix_prop_p;
5863 p->display_ellipsis_p = 0;
5864 p->line_wrap = it->line_wrap;
5865 p->bidi_p = it->bidi_p;
5866 p->paragraph_embedding = it->paragraph_embedding;
5867 p->from_disp_prop_p = it->from_disp_prop_p;
5868 ++it->sp;
5870 /* Save the state of the bidi iterator as well. */
5871 if (it->bidi_p)
5872 bidi_push_it (&it->bidi_it);
5875 static void
5876 iterate_out_of_display_property (struct it *it)
5878 int buffer_p = !STRINGP (it->string);
5879 ptrdiff_t eob = (buffer_p ? ZV : it->end_charpos);
5880 ptrdiff_t bob = (buffer_p ? BEGV : 0);
5882 eassert (eob >= CHARPOS (it->position) && CHARPOS (it->position) >= bob);
5884 /* Maybe initialize paragraph direction. If we are at the beginning
5885 of a new paragraph, next_element_from_buffer may not have a
5886 chance to do that. */
5887 if (it->bidi_it.first_elt && it->bidi_it.charpos < eob)
5888 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
5889 /* prev_stop can be zero, so check against BEGV as well. */
5890 while (it->bidi_it.charpos >= bob
5891 && it->prev_stop <= it->bidi_it.charpos
5892 && it->bidi_it.charpos < CHARPOS (it->position)
5893 && it->bidi_it.charpos < eob)
5894 bidi_move_to_visually_next (&it->bidi_it);
5895 /* Record the stop_pos we just crossed, for when we cross it
5896 back, maybe. */
5897 if (it->bidi_it.charpos > CHARPOS (it->position))
5898 it->prev_stop = CHARPOS (it->position);
5899 /* If we ended up not where pop_it put us, resync IT's
5900 positional members with the bidi iterator. */
5901 if (it->bidi_it.charpos != CHARPOS (it->position))
5902 SET_TEXT_POS (it->position, it->bidi_it.charpos, it->bidi_it.bytepos);
5903 if (buffer_p)
5904 it->current.pos = it->position;
5905 else
5906 it->current.string_pos = it->position;
5909 /* Restore IT's settings from IT->stack. Called, for example, when no
5910 more overlay strings must be processed, and we return to delivering
5911 display elements from a buffer, or when the end of a string from a
5912 `display' property is reached and we return to delivering display
5913 elements from an overlay string, or from a buffer. */
5915 static void
5916 pop_it (struct it *it)
5918 struct iterator_stack_entry *p;
5919 int from_display_prop = it->from_disp_prop_p;
5921 eassert (it->sp > 0);
5922 --it->sp;
5923 p = it->stack + it->sp;
5924 it->stop_charpos = p->stop_charpos;
5925 it->prev_stop = p->prev_stop;
5926 it->base_level_stop = p->base_level_stop;
5927 it->cmp_it = p->cmp_it;
5928 it->face_id = p->face_id;
5929 it->current = p->current;
5930 it->position = p->position;
5931 it->string = p->string;
5932 it->from_overlay = p->from_overlay;
5933 if (NILP (it->string))
5934 SET_TEXT_POS (it->current.string_pos, -1, -1);
5935 it->method = p->method;
5936 switch (it->method)
5938 case GET_FROM_IMAGE:
5939 it->image_id = p->u.image.image_id;
5940 it->object = p->u.image.object;
5941 it->slice = p->u.image.slice;
5942 break;
5943 case GET_FROM_STRETCH:
5944 it->object = p->u.stretch.object;
5945 break;
5946 case GET_FROM_BUFFER:
5947 it->object = it->w->contents;
5948 break;
5949 case GET_FROM_STRING:
5950 it->object = it->string;
5951 break;
5952 case GET_FROM_DISPLAY_VECTOR:
5953 if (it->s)
5954 it->method = GET_FROM_C_STRING;
5955 else if (STRINGP (it->string))
5956 it->method = GET_FROM_STRING;
5957 else
5959 it->method = GET_FROM_BUFFER;
5960 it->object = it->w->contents;
5963 it->end_charpos = p->end_charpos;
5964 it->string_nchars = p->string_nchars;
5965 it->area = p->area;
5966 it->multibyte_p = p->multibyte_p;
5967 it->avoid_cursor_p = p->avoid_cursor_p;
5968 it->space_width = p->space_width;
5969 it->font_height = p->font_height;
5970 it->voffset = p->voffset;
5971 it->string_from_display_prop_p = p->string_from_display_prop_p;
5972 it->string_from_prefix_prop_p = p->string_from_prefix_prop_p;
5973 it->line_wrap = p->line_wrap;
5974 it->bidi_p = p->bidi_p;
5975 it->paragraph_embedding = p->paragraph_embedding;
5976 it->from_disp_prop_p = p->from_disp_prop_p;
5977 if (it->bidi_p)
5979 bidi_pop_it (&it->bidi_it);
5980 /* Bidi-iterate until we get out of the portion of text, if any,
5981 covered by a `display' text property or by an overlay with
5982 `display' property. (We cannot just jump there, because the
5983 internal coherency of the bidi iterator state can not be
5984 preserved across such jumps.) We also must determine the
5985 paragraph base direction if the overlay we just processed is
5986 at the beginning of a new paragraph. */
5987 if (from_display_prop
5988 && (it->method == GET_FROM_BUFFER || it->method == GET_FROM_STRING))
5989 iterate_out_of_display_property (it);
5991 eassert ((BUFFERP (it->object)
5992 && IT_CHARPOS (*it) == it->bidi_it.charpos
5993 && IT_BYTEPOS (*it) == it->bidi_it.bytepos)
5994 || (STRINGP (it->object)
5995 && IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
5996 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos)
5997 || (CONSP (it->object) && it->method == GET_FROM_STRETCH));
6003 /***********************************************************************
6004 Moving over lines
6005 ***********************************************************************/
6007 /* Set IT's current position to the previous line start. */
6009 static void
6010 back_to_previous_line_start (struct it *it)
6012 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
6014 DEC_BOTH (cp, bp);
6015 IT_CHARPOS (*it) = find_newline_no_quit (cp, bp, -1, &IT_BYTEPOS (*it));
6019 /* Move IT to the next line start.
6021 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
6022 we skipped over part of the text (as opposed to moving the iterator
6023 continuously over the text). Otherwise, don't change the value
6024 of *SKIPPED_P.
6026 If BIDI_IT_PREV is non-NULL, store into it the state of the bidi
6027 iterator on the newline, if it was found.
6029 Newlines may come from buffer text, overlay strings, or strings
6030 displayed via the `display' property. That's the reason we can't
6031 simply use find_newline_no_quit.
6033 Note that this function may not skip over invisible text that is so
6034 because of text properties and immediately follows a newline. If
6035 it would, function reseat_at_next_visible_line_start, when called
6036 from set_iterator_to_next, would effectively make invisible
6037 characters following a newline part of the wrong glyph row, which
6038 leads to wrong cursor motion. */
6040 static int
6041 forward_to_next_line_start (struct it *it, int *skipped_p,
6042 struct bidi_it *bidi_it_prev)
6044 ptrdiff_t old_selective;
6045 int newline_found_p, n;
6046 const int MAX_NEWLINE_DISTANCE = 500;
6048 /* If already on a newline, just consume it to avoid unintended
6049 skipping over invisible text below. */
6050 if (it->what == IT_CHARACTER
6051 && it->c == '\n'
6052 && CHARPOS (it->position) == IT_CHARPOS (*it))
6054 if (it->bidi_p && bidi_it_prev)
6055 *bidi_it_prev = it->bidi_it;
6056 set_iterator_to_next (it, 0);
6057 it->c = 0;
6058 return 1;
6061 /* Don't handle selective display in the following. It's (a)
6062 unnecessary because it's done by the caller, and (b) leads to an
6063 infinite recursion because next_element_from_ellipsis indirectly
6064 calls this function. */
6065 old_selective = it->selective;
6066 it->selective = 0;
6068 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
6069 from buffer text. */
6070 for (n = newline_found_p = 0;
6071 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
6072 n += STRINGP (it->string) ? 0 : 1)
6074 if (!get_next_display_element (it))
6075 return 0;
6076 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
6077 if (newline_found_p && it->bidi_p && bidi_it_prev)
6078 *bidi_it_prev = it->bidi_it;
6079 set_iterator_to_next (it, 0);
6082 /* If we didn't find a newline near enough, see if we can use a
6083 short-cut. */
6084 if (!newline_found_p)
6086 ptrdiff_t bytepos, start = IT_CHARPOS (*it);
6087 ptrdiff_t limit = find_newline_no_quit (start, IT_BYTEPOS (*it),
6088 1, &bytepos);
6089 Lisp_Object pos;
6091 eassert (!STRINGP (it->string));
6093 /* If there isn't any `display' property in sight, and no
6094 overlays, we can just use the position of the newline in
6095 buffer text. */
6096 if (it->stop_charpos >= limit
6097 || ((pos = Fnext_single_property_change (make_number (start),
6098 Qdisplay, Qnil,
6099 make_number (limit)),
6100 NILP (pos))
6101 && next_overlay_change (start) == ZV))
6103 if (!it->bidi_p)
6105 IT_CHARPOS (*it) = limit;
6106 IT_BYTEPOS (*it) = bytepos;
6108 else
6110 struct bidi_it bprev;
6112 /* Help bidi.c avoid expensive searches for display
6113 properties and overlays, by telling it that there are
6114 none up to `limit'. */
6115 if (it->bidi_it.disp_pos < limit)
6117 it->bidi_it.disp_pos = limit;
6118 it->bidi_it.disp_prop = 0;
6120 do {
6121 bprev = it->bidi_it;
6122 bidi_move_to_visually_next (&it->bidi_it);
6123 } while (it->bidi_it.charpos != limit);
6124 IT_CHARPOS (*it) = limit;
6125 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6126 if (bidi_it_prev)
6127 *bidi_it_prev = bprev;
6129 *skipped_p = newline_found_p = 1;
6131 else
6133 while (get_next_display_element (it)
6134 && !newline_found_p)
6136 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
6137 if (newline_found_p && it->bidi_p && bidi_it_prev)
6138 *bidi_it_prev = it->bidi_it;
6139 set_iterator_to_next (it, 0);
6144 it->selective = old_selective;
6145 return newline_found_p;
6149 /* Set IT's current position to the previous visible line start. Skip
6150 invisible text that is so either due to text properties or due to
6151 selective display. Caution: this does not change IT->current_x and
6152 IT->hpos. */
6154 static void
6155 back_to_previous_visible_line_start (struct it *it)
6157 while (IT_CHARPOS (*it) > BEGV)
6159 back_to_previous_line_start (it);
6161 if (IT_CHARPOS (*it) <= BEGV)
6162 break;
6164 /* If selective > 0, then lines indented more than its value are
6165 invisible. */
6166 if (it->selective > 0
6167 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6168 it->selective))
6169 continue;
6171 /* Check the newline before point for invisibility. */
6173 Lisp_Object prop;
6174 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
6175 Qinvisible, it->window);
6176 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6177 continue;
6180 if (IT_CHARPOS (*it) <= BEGV)
6181 break;
6184 struct it it2;
6185 void *it2data = NULL;
6186 ptrdiff_t pos;
6187 ptrdiff_t beg, end;
6188 Lisp_Object val, overlay;
6190 SAVE_IT (it2, *it, it2data);
6192 /* If newline is part of a composition, continue from start of composition */
6193 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
6194 && beg < IT_CHARPOS (*it))
6195 goto replaced;
6197 /* If newline is replaced by a display property, find start of overlay
6198 or interval and continue search from that point. */
6199 pos = --IT_CHARPOS (it2);
6200 --IT_BYTEPOS (it2);
6201 it2.sp = 0;
6202 bidi_unshelve_cache (NULL, 0);
6203 it2.string_from_display_prop_p = 0;
6204 it2.from_disp_prop_p = 0;
6205 if (handle_display_prop (&it2) == HANDLED_RETURN
6206 && !NILP (val = get_char_property_and_overlay
6207 (make_number (pos), Qdisplay, Qnil, &overlay))
6208 && (OVERLAYP (overlay)
6209 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
6210 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
6212 RESTORE_IT (it, it, it2data);
6213 goto replaced;
6216 /* Newline is not replaced by anything -- so we are done. */
6217 RESTORE_IT (it, it, it2data);
6218 break;
6220 replaced:
6221 if (beg < BEGV)
6222 beg = BEGV;
6223 IT_CHARPOS (*it) = beg;
6224 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
6228 it->continuation_lines_width = 0;
6230 eassert (IT_CHARPOS (*it) >= BEGV);
6231 eassert (IT_CHARPOS (*it) == BEGV
6232 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6233 CHECK_IT (it);
6237 /* Reseat iterator IT at the previous visible line start. Skip
6238 invisible text that is so either due to text properties or due to
6239 selective display. At the end, update IT's overlay information,
6240 face information etc. */
6242 void
6243 reseat_at_previous_visible_line_start (struct it *it)
6245 back_to_previous_visible_line_start (it);
6246 reseat (it, it->current.pos, 1);
6247 CHECK_IT (it);
6251 /* Reseat iterator IT on the next visible line start in the current
6252 buffer. ON_NEWLINE_P non-zero means position IT on the newline
6253 preceding the line start. Skip over invisible text that is so
6254 because of selective display. Compute faces, overlays etc at the
6255 new position. Note that this function does not skip over text that
6256 is invisible because of text properties. */
6258 static void
6259 reseat_at_next_visible_line_start (struct it *it, int on_newline_p)
6261 int newline_found_p, skipped_p = 0;
6262 struct bidi_it bidi_it_prev;
6264 newline_found_p = forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6266 /* Skip over lines that are invisible because they are indented
6267 more than the value of IT->selective. */
6268 if (it->selective > 0)
6269 while (IT_CHARPOS (*it) < ZV
6270 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6271 it->selective))
6273 eassert (IT_BYTEPOS (*it) == BEGV
6274 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6275 newline_found_p =
6276 forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6279 /* Position on the newline if that's what's requested. */
6280 if (on_newline_p && newline_found_p)
6282 if (STRINGP (it->string))
6284 if (IT_STRING_CHARPOS (*it) > 0)
6286 if (!it->bidi_p)
6288 --IT_STRING_CHARPOS (*it);
6289 --IT_STRING_BYTEPOS (*it);
6291 else
6293 /* We need to restore the bidi iterator to the state
6294 it had on the newline, and resync the IT's
6295 position with that. */
6296 it->bidi_it = bidi_it_prev;
6297 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
6298 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
6302 else if (IT_CHARPOS (*it) > BEGV)
6304 if (!it->bidi_p)
6306 --IT_CHARPOS (*it);
6307 --IT_BYTEPOS (*it);
6309 else
6311 /* We need to restore the bidi iterator to the state it
6312 had on the newline and resync IT with that. */
6313 it->bidi_it = bidi_it_prev;
6314 IT_CHARPOS (*it) = it->bidi_it.charpos;
6315 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6317 reseat (it, it->current.pos, 0);
6320 else if (skipped_p)
6321 reseat (it, it->current.pos, 0);
6323 CHECK_IT (it);
6328 /***********************************************************************
6329 Changing an iterator's position
6330 ***********************************************************************/
6332 /* Change IT's current position to POS in current_buffer. If FORCE_P
6333 is non-zero, always check for text properties at the new position.
6334 Otherwise, text properties are only looked up if POS >=
6335 IT->check_charpos of a property. */
6337 static void
6338 reseat (struct it *it, struct text_pos pos, int force_p)
6340 ptrdiff_t original_pos = IT_CHARPOS (*it);
6342 reseat_1 (it, pos, 0);
6344 /* Determine where to check text properties. Avoid doing it
6345 where possible because text property lookup is very expensive. */
6346 if (force_p
6347 || CHARPOS (pos) > it->stop_charpos
6348 || CHARPOS (pos) < original_pos)
6350 if (it->bidi_p)
6352 /* For bidi iteration, we need to prime prev_stop and
6353 base_level_stop with our best estimations. */
6354 /* Implementation note: Of course, POS is not necessarily a
6355 stop position, so assigning prev_pos to it is a lie; we
6356 should have called compute_stop_backwards. However, if
6357 the current buffer does not include any R2L characters,
6358 that call would be a waste of cycles, because the
6359 iterator will never move back, and thus never cross this
6360 "fake" stop position. So we delay that backward search
6361 until the time we really need it, in next_element_from_buffer. */
6362 if (CHARPOS (pos) != it->prev_stop)
6363 it->prev_stop = CHARPOS (pos);
6364 if (CHARPOS (pos) < it->base_level_stop)
6365 it->base_level_stop = 0; /* meaning it's unknown */
6366 handle_stop (it);
6368 else
6370 handle_stop (it);
6371 it->prev_stop = it->base_level_stop = 0;
6376 CHECK_IT (it);
6380 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
6381 IT->stop_pos to POS, also. */
6383 static void
6384 reseat_1 (struct it *it, struct text_pos pos, int set_stop_p)
6386 /* Don't call this function when scanning a C string. */
6387 eassert (it->s == NULL);
6389 /* POS must be a reasonable value. */
6390 eassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
6392 it->current.pos = it->position = pos;
6393 it->end_charpos = ZV;
6394 it->dpvec = NULL;
6395 it->current.dpvec_index = -1;
6396 it->current.overlay_string_index = -1;
6397 IT_STRING_CHARPOS (*it) = -1;
6398 IT_STRING_BYTEPOS (*it) = -1;
6399 it->string = Qnil;
6400 it->method = GET_FROM_BUFFER;
6401 it->object = it->w->contents;
6402 it->area = TEXT_AREA;
6403 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
6404 it->sp = 0;
6405 it->string_from_display_prop_p = 0;
6406 it->string_from_prefix_prop_p = 0;
6408 it->from_disp_prop_p = 0;
6409 it->face_before_selective_p = 0;
6410 if (it->bidi_p)
6412 bidi_init_it (IT_CHARPOS (*it), IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6413 &it->bidi_it);
6414 bidi_unshelve_cache (NULL, 0);
6415 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6416 it->bidi_it.string.s = NULL;
6417 it->bidi_it.string.lstring = Qnil;
6418 it->bidi_it.string.bufpos = 0;
6419 it->bidi_it.string.unibyte = 0;
6420 it->bidi_it.w = it->w;
6423 if (set_stop_p)
6425 it->stop_charpos = CHARPOS (pos);
6426 it->base_level_stop = CHARPOS (pos);
6428 /* This make the information stored in it->cmp_it invalidate. */
6429 it->cmp_it.id = -1;
6433 /* Set up IT for displaying a string, starting at CHARPOS in window W.
6434 If S is non-null, it is a C string to iterate over. Otherwise,
6435 STRING gives a Lisp string to iterate over.
6437 If PRECISION > 0, don't return more then PRECISION number of
6438 characters from the string.
6440 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
6441 characters have been returned. FIELD_WIDTH < 0 means an infinite
6442 field width.
6444 MULTIBYTE = 0 means disable processing of multibyte characters,
6445 MULTIBYTE > 0 means enable it,
6446 MULTIBYTE < 0 means use IT->multibyte_p.
6448 IT must be initialized via a prior call to init_iterator before
6449 calling this function. */
6451 static void
6452 reseat_to_string (struct it *it, const char *s, Lisp_Object string,
6453 ptrdiff_t charpos, ptrdiff_t precision, int field_width,
6454 int multibyte)
6456 /* No region in strings. */
6457 it->region_beg_charpos = it->region_end_charpos = -1;
6459 /* No text property checks performed by default, but see below. */
6460 it->stop_charpos = -1;
6462 /* Set iterator position and end position. */
6463 memset (&it->current, 0, sizeof it->current);
6464 it->current.overlay_string_index = -1;
6465 it->current.dpvec_index = -1;
6466 eassert (charpos >= 0);
6468 /* If STRING is specified, use its multibyteness, otherwise use the
6469 setting of MULTIBYTE, if specified. */
6470 if (multibyte >= 0)
6471 it->multibyte_p = multibyte > 0;
6473 /* Bidirectional reordering of strings is controlled by the default
6474 value of bidi-display-reordering. Don't try to reorder while
6475 loading loadup.el, as the necessary character property tables are
6476 not yet available. */
6477 it->bidi_p =
6478 NILP (Vpurify_flag)
6479 && !NILP (BVAR (&buffer_defaults, bidi_display_reordering));
6481 if (s == NULL)
6483 eassert (STRINGP (string));
6484 it->string = string;
6485 it->s = NULL;
6486 it->end_charpos = it->string_nchars = SCHARS (string);
6487 it->method = GET_FROM_STRING;
6488 it->current.string_pos = string_pos (charpos, string);
6490 if (it->bidi_p)
6492 it->bidi_it.string.lstring = string;
6493 it->bidi_it.string.s = NULL;
6494 it->bidi_it.string.schars = it->end_charpos;
6495 it->bidi_it.string.bufpos = 0;
6496 it->bidi_it.string.from_disp_str = 0;
6497 it->bidi_it.string.unibyte = !it->multibyte_p;
6498 it->bidi_it.w = it->w;
6499 bidi_init_it (charpos, IT_STRING_BYTEPOS (*it),
6500 FRAME_WINDOW_P (it->f), &it->bidi_it);
6503 else
6505 it->s = (const unsigned char *) s;
6506 it->string = Qnil;
6508 /* Note that we use IT->current.pos, not it->current.string_pos,
6509 for displaying C strings. */
6510 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
6511 if (it->multibyte_p)
6513 it->current.pos = c_string_pos (charpos, s, 1);
6514 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
6516 else
6518 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
6519 it->end_charpos = it->string_nchars = strlen (s);
6522 if (it->bidi_p)
6524 it->bidi_it.string.lstring = Qnil;
6525 it->bidi_it.string.s = (const unsigned char *) s;
6526 it->bidi_it.string.schars = it->end_charpos;
6527 it->bidi_it.string.bufpos = 0;
6528 it->bidi_it.string.from_disp_str = 0;
6529 it->bidi_it.string.unibyte = !it->multibyte_p;
6530 it->bidi_it.w = it->w;
6531 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6532 &it->bidi_it);
6534 it->method = GET_FROM_C_STRING;
6537 /* PRECISION > 0 means don't return more than PRECISION characters
6538 from the string. */
6539 if (precision > 0 && it->end_charpos - charpos > precision)
6541 it->end_charpos = it->string_nchars = charpos + precision;
6542 if (it->bidi_p)
6543 it->bidi_it.string.schars = it->end_charpos;
6546 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
6547 characters have been returned. FIELD_WIDTH == 0 means don't pad,
6548 FIELD_WIDTH < 0 means infinite field width. This is useful for
6549 padding with `-' at the end of a mode line. */
6550 if (field_width < 0)
6551 field_width = INFINITY;
6552 /* Implementation note: We deliberately don't enlarge
6553 it->bidi_it.string.schars here to fit it->end_charpos, because
6554 the bidi iterator cannot produce characters out of thin air. */
6555 if (field_width > it->end_charpos - charpos)
6556 it->end_charpos = charpos + field_width;
6558 /* Use the standard display table for displaying strings. */
6559 if (DISP_TABLE_P (Vstandard_display_table))
6560 it->dp = XCHAR_TABLE (Vstandard_display_table);
6562 it->stop_charpos = charpos;
6563 it->prev_stop = charpos;
6564 it->base_level_stop = 0;
6565 if (it->bidi_p)
6567 it->bidi_it.first_elt = 1;
6568 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6569 it->bidi_it.disp_pos = -1;
6571 if (s == NULL && it->multibyte_p)
6573 ptrdiff_t endpos = SCHARS (it->string);
6574 if (endpos > it->end_charpos)
6575 endpos = it->end_charpos;
6576 composition_compute_stop_pos (&it->cmp_it, charpos, -1, endpos,
6577 it->string);
6579 CHECK_IT (it);
6584 /***********************************************************************
6585 Iteration
6586 ***********************************************************************/
6588 /* Map enum it_method value to corresponding next_element_from_* function. */
6590 static int (* get_next_element[NUM_IT_METHODS]) (struct it *it) =
6592 next_element_from_buffer,
6593 next_element_from_display_vector,
6594 next_element_from_string,
6595 next_element_from_c_string,
6596 next_element_from_image,
6597 next_element_from_stretch
6600 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
6603 /* Return 1 iff a character at CHARPOS (and BYTEPOS) is composed
6604 (possibly with the following characters). */
6606 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS) \
6607 ((IT)->cmp_it.id >= 0 \
6608 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
6609 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
6610 END_CHARPOS, (IT)->w, \
6611 FACE_FROM_ID ((IT)->f, (IT)->face_id), \
6612 (IT)->string)))
6615 /* Lookup the char-table Vglyphless_char_display for character C (-1
6616 if we want information for no-font case), and return the display
6617 method symbol. By side-effect, update it->what and
6618 it->glyphless_method. This function is called from
6619 get_next_display_element for each character element, and from
6620 x_produce_glyphs when no suitable font was found. */
6622 Lisp_Object
6623 lookup_glyphless_char_display (int c, struct it *it)
6625 Lisp_Object glyphless_method = Qnil;
6627 if (CHAR_TABLE_P (Vglyphless_char_display)
6628 && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display)) >= 1)
6630 if (c >= 0)
6632 glyphless_method = CHAR_TABLE_REF (Vglyphless_char_display, c);
6633 if (CONSP (glyphless_method))
6634 glyphless_method = FRAME_WINDOW_P (it->f)
6635 ? XCAR (glyphless_method)
6636 : XCDR (glyphless_method);
6638 else
6639 glyphless_method = XCHAR_TABLE (Vglyphless_char_display)->extras[0];
6642 retry:
6643 if (NILP (glyphless_method))
6645 if (c >= 0)
6646 /* The default is to display the character by a proper font. */
6647 return Qnil;
6648 /* The default for the no-font case is to display an empty box. */
6649 glyphless_method = Qempty_box;
6651 if (EQ (glyphless_method, Qzero_width))
6653 if (c >= 0)
6654 return glyphless_method;
6655 /* This method can't be used for the no-font case. */
6656 glyphless_method = Qempty_box;
6658 if (EQ (glyphless_method, Qthin_space))
6659 it->glyphless_method = GLYPHLESS_DISPLAY_THIN_SPACE;
6660 else if (EQ (glyphless_method, Qempty_box))
6661 it->glyphless_method = GLYPHLESS_DISPLAY_EMPTY_BOX;
6662 else if (EQ (glyphless_method, Qhex_code))
6663 it->glyphless_method = GLYPHLESS_DISPLAY_HEX_CODE;
6664 else if (STRINGP (glyphless_method))
6665 it->glyphless_method = GLYPHLESS_DISPLAY_ACRONYM;
6666 else
6668 /* Invalid value. We use the default method. */
6669 glyphless_method = Qnil;
6670 goto retry;
6672 it->what = IT_GLYPHLESS;
6673 return glyphless_method;
6676 /* Load IT's display element fields with information about the next
6677 display element from the current position of IT. Value is zero if
6678 end of buffer (or C string) is reached. */
6680 static struct frame *last_escape_glyph_frame = NULL;
6681 static int last_escape_glyph_face_id = (1 << FACE_ID_BITS);
6682 static int last_escape_glyph_merged_face_id = 0;
6684 struct frame *last_glyphless_glyph_frame = NULL;
6685 int last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
6686 int last_glyphless_glyph_merged_face_id = 0;
6688 static int
6689 get_next_display_element (struct it *it)
6691 /* Non-zero means that we found a display element. Zero means that
6692 we hit the end of what we iterate over. Performance note: the
6693 function pointer `method' used here turns out to be faster than
6694 using a sequence of if-statements. */
6695 int success_p;
6697 get_next:
6698 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
6700 if (it->what == IT_CHARACTER)
6702 /* UAX#9, L4: "A character is depicted by a mirrored glyph if
6703 and only if (a) the resolved directionality of that character
6704 is R..." */
6705 /* FIXME: Do we need an exception for characters from display
6706 tables? */
6707 if (it->bidi_p && it->bidi_it.type == STRONG_R)
6708 it->c = bidi_mirror_char (it->c);
6709 /* Map via display table or translate control characters.
6710 IT->c, IT->len etc. have been set to the next character by
6711 the function call above. If we have a display table, and it
6712 contains an entry for IT->c, translate it. Don't do this if
6713 IT->c itself comes from a display table, otherwise we could
6714 end up in an infinite recursion. (An alternative could be to
6715 count the recursion depth of this function and signal an
6716 error when a certain maximum depth is reached.) Is it worth
6717 it? */
6718 if (success_p && it->dpvec == NULL)
6720 Lisp_Object dv;
6721 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
6722 int nonascii_space_p = 0;
6723 int nonascii_hyphen_p = 0;
6724 int c = it->c; /* This is the character to display. */
6726 if (! it->multibyte_p && ! ASCII_CHAR_P (c))
6728 eassert (SINGLE_BYTE_CHAR_P (c));
6729 if (unibyte_display_via_language_environment)
6731 c = DECODE_CHAR (unibyte, c);
6732 if (c < 0)
6733 c = BYTE8_TO_CHAR (it->c);
6735 else
6736 c = BYTE8_TO_CHAR (it->c);
6739 if (it->dp
6740 && (dv = DISP_CHAR_VECTOR (it->dp, c),
6741 VECTORP (dv)))
6743 struct Lisp_Vector *v = XVECTOR (dv);
6745 /* Return the first character from the display table
6746 entry, if not empty. If empty, don't display the
6747 current character. */
6748 if (v->header.size)
6750 it->dpvec_char_len = it->len;
6751 it->dpvec = v->contents;
6752 it->dpend = v->contents + v->header.size;
6753 it->current.dpvec_index = 0;
6754 it->dpvec_face_id = -1;
6755 it->saved_face_id = it->face_id;
6756 it->method = GET_FROM_DISPLAY_VECTOR;
6757 it->ellipsis_p = 0;
6759 else
6761 set_iterator_to_next (it, 0);
6763 goto get_next;
6766 if (! NILP (lookup_glyphless_char_display (c, it)))
6768 if (it->what == IT_GLYPHLESS)
6769 goto done;
6770 /* Don't display this character. */
6771 set_iterator_to_next (it, 0);
6772 goto get_next;
6775 /* If `nobreak-char-display' is non-nil, we display
6776 non-ASCII spaces and hyphens specially. */
6777 if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
6779 if (c == 0xA0)
6780 nonascii_space_p = 1;
6781 else if (c == 0xAD || c == 0x2010 || c == 0x2011)
6782 nonascii_hyphen_p = 1;
6785 /* Translate control characters into `\003' or `^C' form.
6786 Control characters coming from a display table entry are
6787 currently not translated because we use IT->dpvec to hold
6788 the translation. This could easily be changed but I
6789 don't believe that it is worth doing.
6791 The characters handled by `nobreak-char-display' must be
6792 translated too.
6794 Non-printable characters and raw-byte characters are also
6795 translated to octal form. */
6796 if (((c < ' ' || c == 127) /* ASCII control chars */
6797 ? (it->area != TEXT_AREA
6798 /* In mode line, treat \n, \t like other crl chars. */
6799 || (c != '\t'
6800 && it->glyph_row
6801 && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
6802 || (c != '\n' && c != '\t'))
6803 : (nonascii_space_p
6804 || nonascii_hyphen_p
6805 || CHAR_BYTE8_P (c)
6806 || ! CHAR_PRINTABLE_P (c))))
6808 /* C is a control character, non-ASCII space/hyphen,
6809 raw-byte, or a non-printable character which must be
6810 displayed either as '\003' or as `^C' where the '\\'
6811 and '^' can be defined in the display table. Fill
6812 IT->ctl_chars with glyphs for what we have to
6813 display. Then, set IT->dpvec to these glyphs. */
6814 Lisp_Object gc;
6815 int ctl_len;
6816 int face_id;
6817 int lface_id = 0;
6818 int escape_glyph;
6820 /* Handle control characters with ^. */
6822 if (ASCII_CHAR_P (c) && it->ctl_arrow_p)
6824 int g;
6826 g = '^'; /* default glyph for Control */
6827 /* Set IT->ctl_chars[0] to the glyph for `^'. */
6828 if (it->dp
6829 && (gc = DISP_CTRL_GLYPH (it->dp), GLYPH_CODE_P (gc)))
6831 g = GLYPH_CODE_CHAR (gc);
6832 lface_id = GLYPH_CODE_FACE (gc);
6834 if (lface_id)
6836 face_id = merge_faces (it->f, Qt, lface_id, it->face_id);
6838 else if (it->f == last_escape_glyph_frame
6839 && it->face_id == last_escape_glyph_face_id)
6841 face_id = last_escape_glyph_merged_face_id;
6843 else
6845 /* Merge the escape-glyph face into the current face. */
6846 face_id = merge_faces (it->f, Qescape_glyph, 0,
6847 it->face_id);
6848 last_escape_glyph_frame = it->f;
6849 last_escape_glyph_face_id = it->face_id;
6850 last_escape_glyph_merged_face_id = face_id;
6853 XSETINT (it->ctl_chars[0], g);
6854 XSETINT (it->ctl_chars[1], c ^ 0100);
6855 ctl_len = 2;
6856 goto display_control;
6859 /* Handle non-ascii space in the mode where it only gets
6860 highlighting. */
6862 if (nonascii_space_p && EQ (Vnobreak_char_display, Qt))
6864 /* Merge `nobreak-space' into the current face. */
6865 face_id = merge_faces (it->f, Qnobreak_space, 0,
6866 it->face_id);
6867 XSETINT (it->ctl_chars[0], ' ');
6868 ctl_len = 1;
6869 goto display_control;
6872 /* Handle sequences that start with the "escape glyph". */
6874 /* the default escape glyph is \. */
6875 escape_glyph = '\\';
6877 if (it->dp
6878 && (gc = DISP_ESCAPE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
6880 escape_glyph = GLYPH_CODE_CHAR (gc);
6881 lface_id = GLYPH_CODE_FACE (gc);
6883 if (lface_id)
6885 /* The display table specified a face.
6886 Merge it into face_id and also into escape_glyph. */
6887 face_id = merge_faces (it->f, Qt, lface_id,
6888 it->face_id);
6890 else if (it->f == last_escape_glyph_frame
6891 && it->face_id == last_escape_glyph_face_id)
6893 face_id = last_escape_glyph_merged_face_id;
6895 else
6897 /* Merge the escape-glyph face into the current face. */
6898 face_id = merge_faces (it->f, Qescape_glyph, 0,
6899 it->face_id);
6900 last_escape_glyph_frame = it->f;
6901 last_escape_glyph_face_id = it->face_id;
6902 last_escape_glyph_merged_face_id = face_id;
6905 /* Draw non-ASCII hyphen with just highlighting: */
6907 if (nonascii_hyphen_p && EQ (Vnobreak_char_display, Qt))
6909 XSETINT (it->ctl_chars[0], '-');
6910 ctl_len = 1;
6911 goto display_control;
6914 /* Draw non-ASCII space/hyphen with escape glyph: */
6916 if (nonascii_space_p || nonascii_hyphen_p)
6918 XSETINT (it->ctl_chars[0], escape_glyph);
6919 XSETINT (it->ctl_chars[1], nonascii_space_p ? ' ' : '-');
6920 ctl_len = 2;
6921 goto display_control;
6925 char str[10];
6926 int len, i;
6928 if (CHAR_BYTE8_P (c))
6929 /* Display \200 instead of \17777600. */
6930 c = CHAR_TO_BYTE8 (c);
6931 len = sprintf (str, "%03o", c);
6933 XSETINT (it->ctl_chars[0], escape_glyph);
6934 for (i = 0; i < len; i++)
6935 XSETINT (it->ctl_chars[i + 1], str[i]);
6936 ctl_len = len + 1;
6939 display_control:
6940 /* Set up IT->dpvec and return first character from it. */
6941 it->dpvec_char_len = it->len;
6942 it->dpvec = it->ctl_chars;
6943 it->dpend = it->dpvec + ctl_len;
6944 it->current.dpvec_index = 0;
6945 it->dpvec_face_id = face_id;
6946 it->saved_face_id = it->face_id;
6947 it->method = GET_FROM_DISPLAY_VECTOR;
6948 it->ellipsis_p = 0;
6949 goto get_next;
6951 it->char_to_display = c;
6953 else if (success_p)
6955 it->char_to_display = it->c;
6959 /* Adjust face id for a multibyte character. There are no multibyte
6960 character in unibyte text. */
6961 if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
6962 && it->multibyte_p
6963 && success_p
6964 && FRAME_WINDOW_P (it->f))
6966 struct face *face = FACE_FROM_ID (it->f, it->face_id);
6968 if (it->what == IT_COMPOSITION && it->cmp_it.ch >= 0)
6970 /* Automatic composition with glyph-string. */
6971 Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id);
6973 it->face_id = face_for_font (it->f, LGSTRING_FONT (gstring), face);
6975 else
6977 ptrdiff_t pos = (it->s ? -1
6978 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
6979 : IT_CHARPOS (*it));
6980 int c;
6982 if (it->what == IT_CHARACTER)
6983 c = it->char_to_display;
6984 else
6986 struct composition *cmp = composition_table[it->cmp_it.id];
6987 int i;
6989 c = ' ';
6990 for (i = 0; i < cmp->glyph_len; i++)
6991 /* TAB in a composition means display glyphs with
6992 padding space on the left or right. */
6993 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
6994 break;
6996 it->face_id = FACE_FOR_CHAR (it->f, face, c, pos, it->string);
7000 done:
7001 /* Is this character the last one of a run of characters with
7002 box? If yes, set IT->end_of_box_run_p to 1. */
7003 if (it->face_box_p
7004 && it->s == NULL)
7006 if (it->method == GET_FROM_STRING && it->sp)
7008 int face_id = underlying_face_id (it);
7009 struct face *face = FACE_FROM_ID (it->f, face_id);
7011 if (face)
7013 if (face->box == FACE_NO_BOX)
7015 /* If the box comes from face properties in a
7016 display string, check faces in that string. */
7017 int string_face_id = face_after_it_pos (it);
7018 it->end_of_box_run_p
7019 = (FACE_FROM_ID (it->f, string_face_id)->box
7020 == FACE_NO_BOX);
7022 /* Otherwise, the box comes from the underlying face.
7023 If this is the last string character displayed, check
7024 the next buffer location. */
7025 else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1)
7026 && (it->current.overlay_string_index
7027 == it->n_overlay_strings - 1))
7029 ptrdiff_t ignore;
7030 int next_face_id;
7031 struct text_pos pos = it->current.pos;
7032 INC_TEXT_POS (pos, it->multibyte_p);
7034 next_face_id = face_at_buffer_position
7035 (it->w, CHARPOS (pos), it->region_beg_charpos,
7036 it->region_end_charpos, &ignore,
7037 (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT), 0,
7038 -1);
7039 it->end_of_box_run_p
7040 = (FACE_FROM_ID (it->f, next_face_id)->box
7041 == FACE_NO_BOX);
7045 else
7047 int face_id = face_after_it_pos (it);
7048 it->end_of_box_run_p
7049 = (face_id != it->face_id
7050 && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX);
7053 /* If we reached the end of the object we've been iterating (e.g., a
7054 display string or an overlay string), and there's something on
7055 IT->stack, proceed with what's on the stack. It doesn't make
7056 sense to return zero if there's unprocessed stuff on the stack,
7057 because otherwise that stuff will never be displayed. */
7058 if (!success_p && it->sp > 0)
7060 set_iterator_to_next (it, 0);
7061 success_p = get_next_display_element (it);
7064 /* Value is 0 if end of buffer or string reached. */
7065 return success_p;
7069 /* Move IT to the next display element.
7071 RESEAT_P non-zero means if called on a newline in buffer text,
7072 skip to the next visible line start.
7074 Functions get_next_display_element and set_iterator_to_next are
7075 separate because I find this arrangement easier to handle than a
7076 get_next_display_element function that also increments IT's
7077 position. The way it is we can first look at an iterator's current
7078 display element, decide whether it fits on a line, and if it does,
7079 increment the iterator position. The other way around we probably
7080 would either need a flag indicating whether the iterator has to be
7081 incremented the next time, or we would have to implement a
7082 decrement position function which would not be easy to write. */
7084 void
7085 set_iterator_to_next (struct it *it, int reseat_p)
7087 /* Reset flags indicating start and end of a sequence of characters
7088 with box. Reset them at the start of this function because
7089 moving the iterator to a new position might set them. */
7090 it->start_of_box_run_p = it->end_of_box_run_p = 0;
7092 switch (it->method)
7094 case GET_FROM_BUFFER:
7095 /* The current display element of IT is a character from
7096 current_buffer. Advance in the buffer, and maybe skip over
7097 invisible lines that are so because of selective display. */
7098 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
7099 reseat_at_next_visible_line_start (it, 0);
7100 else if (it->cmp_it.id >= 0)
7102 /* We are currently getting glyphs from a composition. */
7103 int i;
7105 if (! it->bidi_p)
7107 IT_CHARPOS (*it) += it->cmp_it.nchars;
7108 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
7109 if (it->cmp_it.to < it->cmp_it.nglyphs)
7111 it->cmp_it.from = it->cmp_it.to;
7113 else
7115 it->cmp_it.id = -1;
7116 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7117 IT_BYTEPOS (*it),
7118 it->end_charpos, Qnil);
7121 else if (! it->cmp_it.reversed_p)
7123 /* Composition created while scanning forward. */
7124 /* Update IT's char/byte positions to point to the first
7125 character of the next grapheme cluster, or to the
7126 character visually after the current composition. */
7127 for (i = 0; i < it->cmp_it.nchars; i++)
7128 bidi_move_to_visually_next (&it->bidi_it);
7129 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7130 IT_CHARPOS (*it) = it->bidi_it.charpos;
7132 if (it->cmp_it.to < it->cmp_it.nglyphs)
7134 /* Proceed to the next grapheme cluster. */
7135 it->cmp_it.from = it->cmp_it.to;
7137 else
7139 /* No more grapheme clusters in this composition.
7140 Find the next stop position. */
7141 ptrdiff_t stop = it->end_charpos;
7142 if (it->bidi_it.scan_dir < 0)
7143 /* Now we are scanning backward and don't know
7144 where to stop. */
7145 stop = -1;
7146 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7147 IT_BYTEPOS (*it), stop, Qnil);
7150 else
7152 /* Composition created while scanning backward. */
7153 /* Update IT's char/byte positions to point to the last
7154 character of the previous grapheme cluster, or the
7155 character visually after the current composition. */
7156 for (i = 0; i < it->cmp_it.nchars; i++)
7157 bidi_move_to_visually_next (&it->bidi_it);
7158 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7159 IT_CHARPOS (*it) = it->bidi_it.charpos;
7160 if (it->cmp_it.from > 0)
7162 /* Proceed to the previous grapheme cluster. */
7163 it->cmp_it.to = it->cmp_it.from;
7165 else
7167 /* No more grapheme clusters in this composition.
7168 Find the next stop position. */
7169 ptrdiff_t stop = it->end_charpos;
7170 if (it->bidi_it.scan_dir < 0)
7171 /* Now we are scanning backward and don't know
7172 where to stop. */
7173 stop = -1;
7174 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7175 IT_BYTEPOS (*it), stop, Qnil);
7179 else
7181 eassert (it->len != 0);
7183 if (!it->bidi_p)
7185 IT_BYTEPOS (*it) += it->len;
7186 IT_CHARPOS (*it) += 1;
7188 else
7190 int prev_scan_dir = it->bidi_it.scan_dir;
7191 /* If this is a new paragraph, determine its base
7192 direction (a.k.a. its base embedding level). */
7193 if (it->bidi_it.new_paragraph)
7194 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
7195 bidi_move_to_visually_next (&it->bidi_it);
7196 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7197 IT_CHARPOS (*it) = it->bidi_it.charpos;
7198 if (prev_scan_dir != it->bidi_it.scan_dir)
7200 /* As the scan direction was changed, we must
7201 re-compute the stop position for composition. */
7202 ptrdiff_t stop = it->end_charpos;
7203 if (it->bidi_it.scan_dir < 0)
7204 stop = -1;
7205 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7206 IT_BYTEPOS (*it), stop, Qnil);
7209 eassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
7211 break;
7213 case GET_FROM_C_STRING:
7214 /* Current display element of IT is from a C string. */
7215 if (!it->bidi_p
7216 /* If the string position is beyond string's end, it means
7217 next_element_from_c_string is padding the string with
7218 blanks, in which case we bypass the bidi iterator,
7219 because it cannot deal with such virtual characters. */
7220 || IT_CHARPOS (*it) >= it->bidi_it.string.schars)
7222 IT_BYTEPOS (*it) += it->len;
7223 IT_CHARPOS (*it) += 1;
7225 else
7227 bidi_move_to_visually_next (&it->bidi_it);
7228 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7229 IT_CHARPOS (*it) = it->bidi_it.charpos;
7231 break;
7233 case GET_FROM_DISPLAY_VECTOR:
7234 /* Current display element of IT is from a display table entry.
7235 Advance in the display table definition. Reset it to null if
7236 end reached, and continue with characters from buffers/
7237 strings. */
7238 ++it->current.dpvec_index;
7240 /* Restore face of the iterator to what they were before the
7241 display vector entry (these entries may contain faces). */
7242 it->face_id = it->saved_face_id;
7244 if (it->dpvec + it->current.dpvec_index >= it->dpend)
7246 int recheck_faces = it->ellipsis_p;
7248 if (it->s)
7249 it->method = GET_FROM_C_STRING;
7250 else if (STRINGP (it->string))
7251 it->method = GET_FROM_STRING;
7252 else
7254 it->method = GET_FROM_BUFFER;
7255 it->object = it->w->contents;
7258 it->dpvec = NULL;
7259 it->current.dpvec_index = -1;
7261 /* Skip over characters which were displayed via IT->dpvec. */
7262 if (it->dpvec_char_len < 0)
7263 reseat_at_next_visible_line_start (it, 1);
7264 else if (it->dpvec_char_len > 0)
7266 if (it->method == GET_FROM_STRING
7267 && it->current.overlay_string_index >= 0
7268 && it->n_overlay_strings > 0)
7269 it->ignore_overlay_strings_at_pos_p = 1;
7270 it->len = it->dpvec_char_len;
7271 set_iterator_to_next (it, reseat_p);
7274 /* Maybe recheck faces after display vector */
7275 if (recheck_faces)
7276 it->stop_charpos = IT_CHARPOS (*it);
7278 break;
7280 case GET_FROM_STRING:
7281 /* Current display element is a character from a Lisp string. */
7282 eassert (it->s == NULL && STRINGP (it->string));
7283 /* Don't advance past string end. These conditions are true
7284 when set_iterator_to_next is called at the end of
7285 get_next_display_element, in which case the Lisp string is
7286 already exhausted, and all we want is pop the iterator
7287 stack. */
7288 if (it->current.overlay_string_index >= 0)
7290 /* This is an overlay string, so there's no padding with
7291 spaces, and the number of characters in the string is
7292 where the string ends. */
7293 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7294 goto consider_string_end;
7296 else
7298 /* Not an overlay string. There could be padding, so test
7299 against it->end_charpos . */
7300 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7301 goto consider_string_end;
7303 if (it->cmp_it.id >= 0)
7305 int i;
7307 if (! it->bidi_p)
7309 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
7310 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
7311 if (it->cmp_it.to < it->cmp_it.nglyphs)
7312 it->cmp_it.from = it->cmp_it.to;
7313 else
7315 it->cmp_it.id = -1;
7316 composition_compute_stop_pos (&it->cmp_it,
7317 IT_STRING_CHARPOS (*it),
7318 IT_STRING_BYTEPOS (*it),
7319 it->end_charpos, it->string);
7322 else if (! it->cmp_it.reversed_p)
7324 for (i = 0; i < it->cmp_it.nchars; i++)
7325 bidi_move_to_visually_next (&it->bidi_it);
7326 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7327 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7329 if (it->cmp_it.to < it->cmp_it.nglyphs)
7330 it->cmp_it.from = it->cmp_it.to;
7331 else
7333 ptrdiff_t stop = it->end_charpos;
7334 if (it->bidi_it.scan_dir < 0)
7335 stop = -1;
7336 composition_compute_stop_pos (&it->cmp_it,
7337 IT_STRING_CHARPOS (*it),
7338 IT_STRING_BYTEPOS (*it), stop,
7339 it->string);
7342 else
7344 for (i = 0; i < it->cmp_it.nchars; i++)
7345 bidi_move_to_visually_next (&it->bidi_it);
7346 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7347 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7348 if (it->cmp_it.from > 0)
7349 it->cmp_it.to = it->cmp_it.from;
7350 else
7352 ptrdiff_t stop = it->end_charpos;
7353 if (it->bidi_it.scan_dir < 0)
7354 stop = -1;
7355 composition_compute_stop_pos (&it->cmp_it,
7356 IT_STRING_CHARPOS (*it),
7357 IT_STRING_BYTEPOS (*it), stop,
7358 it->string);
7362 else
7364 if (!it->bidi_p
7365 /* If the string position is beyond string's end, it
7366 means next_element_from_string is padding the string
7367 with blanks, in which case we bypass the bidi
7368 iterator, because it cannot deal with such virtual
7369 characters. */
7370 || IT_STRING_CHARPOS (*it) >= it->bidi_it.string.schars)
7372 IT_STRING_BYTEPOS (*it) += it->len;
7373 IT_STRING_CHARPOS (*it) += 1;
7375 else
7377 int prev_scan_dir = it->bidi_it.scan_dir;
7379 bidi_move_to_visually_next (&it->bidi_it);
7380 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7381 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7382 if (prev_scan_dir != it->bidi_it.scan_dir)
7384 ptrdiff_t stop = it->end_charpos;
7386 if (it->bidi_it.scan_dir < 0)
7387 stop = -1;
7388 composition_compute_stop_pos (&it->cmp_it,
7389 IT_STRING_CHARPOS (*it),
7390 IT_STRING_BYTEPOS (*it), stop,
7391 it->string);
7396 consider_string_end:
7398 if (it->current.overlay_string_index >= 0)
7400 /* IT->string is an overlay string. Advance to the
7401 next, if there is one. */
7402 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7404 it->ellipsis_p = 0;
7405 next_overlay_string (it);
7406 if (it->ellipsis_p)
7407 setup_for_ellipsis (it, 0);
7410 else
7412 /* IT->string is not an overlay string. If we reached
7413 its end, and there is something on IT->stack, proceed
7414 with what is on the stack. This can be either another
7415 string, this time an overlay string, or a buffer. */
7416 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
7417 && it->sp > 0)
7419 pop_it (it);
7420 if (it->method == GET_FROM_STRING)
7421 goto consider_string_end;
7424 break;
7426 case GET_FROM_IMAGE:
7427 case GET_FROM_STRETCH:
7428 /* The position etc with which we have to proceed are on
7429 the stack. The position may be at the end of a string,
7430 if the `display' property takes up the whole string. */
7431 eassert (it->sp > 0);
7432 pop_it (it);
7433 if (it->method == GET_FROM_STRING)
7434 goto consider_string_end;
7435 break;
7437 default:
7438 /* There are no other methods defined, so this should be a bug. */
7439 emacs_abort ();
7442 eassert (it->method != GET_FROM_STRING
7443 || (STRINGP (it->string)
7444 && IT_STRING_CHARPOS (*it) >= 0));
7447 /* Load IT's display element fields with information about the next
7448 display element which comes from a display table entry or from the
7449 result of translating a control character to one of the forms `^C'
7450 or `\003'.
7452 IT->dpvec holds the glyphs to return as characters.
7453 IT->saved_face_id holds the face id before the display vector--it
7454 is restored into IT->face_id in set_iterator_to_next. */
7456 static int
7457 next_element_from_display_vector (struct it *it)
7459 Lisp_Object gc;
7461 /* Precondition. */
7462 eassert (it->dpvec && it->current.dpvec_index >= 0);
7464 it->face_id = it->saved_face_id;
7466 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
7467 That seemed totally bogus - so I changed it... */
7468 gc = it->dpvec[it->current.dpvec_index];
7470 if (GLYPH_CODE_P (gc))
7472 it->c = GLYPH_CODE_CHAR (gc);
7473 it->len = CHAR_BYTES (it->c);
7475 /* The entry may contain a face id to use. Such a face id is
7476 the id of a Lisp face, not a realized face. A face id of
7477 zero means no face is specified. */
7478 if (it->dpvec_face_id >= 0)
7479 it->face_id = it->dpvec_face_id;
7480 else
7482 int lface_id = GLYPH_CODE_FACE (gc);
7483 if (lface_id > 0)
7484 it->face_id = merge_faces (it->f, Qt, lface_id,
7485 it->saved_face_id);
7488 else
7489 /* Display table entry is invalid. Return a space. */
7490 it->c = ' ', it->len = 1;
7492 /* Don't change position and object of the iterator here. They are
7493 still the values of the character that had this display table
7494 entry or was translated, and that's what we want. */
7495 it->what = IT_CHARACTER;
7496 return 1;
7499 /* Get the first element of string/buffer in the visual order, after
7500 being reseated to a new position in a string or a buffer. */
7501 static void
7502 get_visually_first_element (struct it *it)
7504 int string_p = STRINGP (it->string) || it->s;
7505 ptrdiff_t eob = (string_p ? it->bidi_it.string.schars : ZV);
7506 ptrdiff_t bob = (string_p ? 0 : BEGV);
7508 if (STRINGP (it->string))
7510 it->bidi_it.charpos = IT_STRING_CHARPOS (*it);
7511 it->bidi_it.bytepos = IT_STRING_BYTEPOS (*it);
7513 else
7515 it->bidi_it.charpos = IT_CHARPOS (*it);
7516 it->bidi_it.bytepos = IT_BYTEPOS (*it);
7519 if (it->bidi_it.charpos == eob)
7521 /* Nothing to do, but reset the FIRST_ELT flag, like
7522 bidi_paragraph_init does, because we are not going to
7523 call it. */
7524 it->bidi_it.first_elt = 0;
7526 else if (it->bidi_it.charpos == bob
7527 || (!string_p
7528 && (FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n'
7529 || FETCH_CHAR (it->bidi_it.bytepos) == '\n')))
7531 /* If we are at the beginning of a line/string, we can produce
7532 the next element right away. */
7533 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
7534 bidi_move_to_visually_next (&it->bidi_it);
7536 else
7538 ptrdiff_t orig_bytepos = it->bidi_it.bytepos;
7540 /* We need to prime the bidi iterator starting at the line's or
7541 string's beginning, before we will be able to produce the
7542 next element. */
7543 if (string_p)
7544 it->bidi_it.charpos = it->bidi_it.bytepos = 0;
7545 else
7546 it->bidi_it.charpos = find_newline_no_quit (IT_CHARPOS (*it),
7547 IT_BYTEPOS (*it), -1,
7548 &it->bidi_it.bytepos);
7549 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
7552 /* Now return to buffer/string position where we were asked
7553 to get the next display element, and produce that. */
7554 bidi_move_to_visually_next (&it->bidi_it);
7556 while (it->bidi_it.bytepos != orig_bytepos
7557 && it->bidi_it.charpos < eob);
7560 /* Adjust IT's position information to where we ended up. */
7561 if (STRINGP (it->string))
7563 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7564 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7566 else
7568 IT_CHARPOS (*it) = it->bidi_it.charpos;
7569 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7572 if (STRINGP (it->string) || !it->s)
7574 ptrdiff_t stop, charpos, bytepos;
7576 if (STRINGP (it->string))
7578 eassert (!it->s);
7579 stop = SCHARS (it->string);
7580 if (stop > it->end_charpos)
7581 stop = it->end_charpos;
7582 charpos = IT_STRING_CHARPOS (*it);
7583 bytepos = IT_STRING_BYTEPOS (*it);
7585 else
7587 stop = it->end_charpos;
7588 charpos = IT_CHARPOS (*it);
7589 bytepos = IT_BYTEPOS (*it);
7591 if (it->bidi_it.scan_dir < 0)
7592 stop = -1;
7593 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos, stop,
7594 it->string);
7598 /* Load IT with the next display element from Lisp string IT->string.
7599 IT->current.string_pos is the current position within the string.
7600 If IT->current.overlay_string_index >= 0, the Lisp string is an
7601 overlay string. */
7603 static int
7604 next_element_from_string (struct it *it)
7606 struct text_pos position;
7608 eassert (STRINGP (it->string));
7609 eassert (!it->bidi_p || EQ (it->string, it->bidi_it.string.lstring));
7610 eassert (IT_STRING_CHARPOS (*it) >= 0);
7611 position = it->current.string_pos;
7613 /* With bidi reordering, the character to display might not be the
7614 character at IT_STRING_CHARPOS. BIDI_IT.FIRST_ELT non-zero means
7615 that we were reseat()ed to a new string, whose paragraph
7616 direction is not known. */
7617 if (it->bidi_p && it->bidi_it.first_elt)
7619 get_visually_first_element (it);
7620 SET_TEXT_POS (position, IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it));
7623 /* Time to check for invisible text? */
7624 if (IT_STRING_CHARPOS (*it) < it->end_charpos)
7626 if (IT_STRING_CHARPOS (*it) >= it->stop_charpos)
7628 if (!(!it->bidi_p
7629 || BIDI_AT_BASE_LEVEL (it->bidi_it)
7630 || IT_STRING_CHARPOS (*it) == it->stop_charpos))
7632 /* With bidi non-linear iteration, we could find
7633 ourselves far beyond the last computed stop_charpos,
7634 with several other stop positions in between that we
7635 missed. Scan them all now, in buffer's logical
7636 order, until we find and handle the last stop_charpos
7637 that precedes our current position. */
7638 handle_stop_backwards (it, it->stop_charpos);
7639 return GET_NEXT_DISPLAY_ELEMENT (it);
7641 else
7643 if (it->bidi_p)
7645 /* Take note of the stop position we just moved
7646 across, for when we will move back across it. */
7647 it->prev_stop = it->stop_charpos;
7648 /* If we are at base paragraph embedding level, take
7649 note of the last stop position seen at this
7650 level. */
7651 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
7652 it->base_level_stop = it->stop_charpos;
7654 handle_stop (it);
7656 /* Since a handler may have changed IT->method, we must
7657 recurse here. */
7658 return GET_NEXT_DISPLAY_ELEMENT (it);
7661 else if (it->bidi_p
7662 /* If we are before prev_stop, we may have overstepped
7663 on our way backwards a stop_pos, and if so, we need
7664 to handle that stop_pos. */
7665 && IT_STRING_CHARPOS (*it) < it->prev_stop
7666 /* We can sometimes back up for reasons that have nothing
7667 to do with bidi reordering. E.g., compositions. The
7668 code below is only needed when we are above the base
7669 embedding level, so test for that explicitly. */
7670 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
7672 /* If we lost track of base_level_stop, we have no better
7673 place for handle_stop_backwards to start from than string
7674 beginning. This happens, e.g., when we were reseated to
7675 the previous screenful of text by vertical-motion. */
7676 if (it->base_level_stop <= 0
7677 || IT_STRING_CHARPOS (*it) < it->base_level_stop)
7678 it->base_level_stop = 0;
7679 handle_stop_backwards (it, it->base_level_stop);
7680 return GET_NEXT_DISPLAY_ELEMENT (it);
7684 if (it->current.overlay_string_index >= 0)
7686 /* Get the next character from an overlay string. In overlay
7687 strings, there is no field width or padding with spaces to
7688 do. */
7689 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7691 it->what = IT_EOB;
7692 return 0;
7694 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
7695 IT_STRING_BYTEPOS (*it),
7696 it->bidi_it.scan_dir < 0
7697 ? -1
7698 : SCHARS (it->string))
7699 && next_element_from_composition (it))
7701 return 1;
7703 else if (STRING_MULTIBYTE (it->string))
7705 const unsigned char *s = (SDATA (it->string)
7706 + IT_STRING_BYTEPOS (*it));
7707 it->c = string_char_and_length (s, &it->len);
7709 else
7711 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
7712 it->len = 1;
7715 else
7717 /* Get the next character from a Lisp string that is not an
7718 overlay string. Such strings come from the mode line, for
7719 example. We may have to pad with spaces, or truncate the
7720 string. See also next_element_from_c_string. */
7721 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7723 it->what = IT_EOB;
7724 return 0;
7726 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
7728 /* Pad with spaces. */
7729 it->c = ' ', it->len = 1;
7730 CHARPOS (position) = BYTEPOS (position) = -1;
7732 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
7733 IT_STRING_BYTEPOS (*it),
7734 it->bidi_it.scan_dir < 0
7735 ? -1
7736 : it->string_nchars)
7737 && next_element_from_composition (it))
7739 return 1;
7741 else if (STRING_MULTIBYTE (it->string))
7743 const unsigned char *s = (SDATA (it->string)
7744 + IT_STRING_BYTEPOS (*it));
7745 it->c = string_char_and_length (s, &it->len);
7747 else
7749 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
7750 it->len = 1;
7754 /* Record what we have and where it came from. */
7755 it->what = IT_CHARACTER;
7756 it->object = it->string;
7757 it->position = position;
7758 return 1;
7762 /* Load IT with next display element from C string IT->s.
7763 IT->string_nchars is the maximum number of characters to return
7764 from the string. IT->end_charpos may be greater than
7765 IT->string_nchars when this function is called, in which case we
7766 may have to return padding spaces. Value is zero if end of string
7767 reached, including padding spaces. */
7769 static int
7770 next_element_from_c_string (struct it *it)
7772 int success_p = 1;
7774 eassert (it->s);
7775 eassert (!it->bidi_p || it->s == it->bidi_it.string.s);
7776 it->what = IT_CHARACTER;
7777 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
7778 it->object = Qnil;
7780 /* With bidi reordering, the character to display might not be the
7781 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
7782 we were reseated to a new string, whose paragraph direction is
7783 not known. */
7784 if (it->bidi_p && it->bidi_it.first_elt)
7785 get_visually_first_element (it);
7787 /* IT's position can be greater than IT->string_nchars in case a
7788 field width or precision has been specified when the iterator was
7789 initialized. */
7790 if (IT_CHARPOS (*it) >= it->end_charpos)
7792 /* End of the game. */
7793 it->what = IT_EOB;
7794 success_p = 0;
7796 else if (IT_CHARPOS (*it) >= it->string_nchars)
7798 /* Pad with spaces. */
7799 it->c = ' ', it->len = 1;
7800 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
7802 else if (it->multibyte_p)
7803 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), &it->len);
7804 else
7805 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
7807 return success_p;
7811 /* Set up IT to return characters from an ellipsis, if appropriate.
7812 The definition of the ellipsis glyphs may come from a display table
7813 entry. This function fills IT with the first glyph from the
7814 ellipsis if an ellipsis is to be displayed. */
7816 static int
7817 next_element_from_ellipsis (struct it *it)
7819 if (it->selective_display_ellipsis_p)
7820 setup_for_ellipsis (it, it->len);
7821 else
7823 /* The face at the current position may be different from the
7824 face we find after the invisible text. Remember what it
7825 was in IT->saved_face_id, and signal that it's there by
7826 setting face_before_selective_p. */
7827 it->saved_face_id = it->face_id;
7828 it->method = GET_FROM_BUFFER;
7829 it->object = it->w->contents;
7830 reseat_at_next_visible_line_start (it, 1);
7831 it->face_before_selective_p = 1;
7834 return GET_NEXT_DISPLAY_ELEMENT (it);
7838 /* Deliver an image display element. The iterator IT is already
7839 filled with image information (done in handle_display_prop). Value
7840 is always 1. */
7843 static int
7844 next_element_from_image (struct it *it)
7846 it->what = IT_IMAGE;
7847 it->ignore_overlay_strings_at_pos_p = 0;
7848 return 1;
7852 /* Fill iterator IT with next display element from a stretch glyph
7853 property. IT->object is the value of the text property. Value is
7854 always 1. */
7856 static int
7857 next_element_from_stretch (struct it *it)
7859 it->what = IT_STRETCH;
7860 return 1;
7863 /* Scan backwards from IT's current position until we find a stop
7864 position, or until BEGV. This is called when we find ourself
7865 before both the last known prev_stop and base_level_stop while
7866 reordering bidirectional text. */
7868 static void
7869 compute_stop_pos_backwards (struct it *it)
7871 const int SCAN_BACK_LIMIT = 1000;
7872 struct text_pos pos;
7873 struct display_pos save_current = it->current;
7874 struct text_pos save_position = it->position;
7875 ptrdiff_t charpos = IT_CHARPOS (*it);
7876 ptrdiff_t where_we_are = charpos;
7877 ptrdiff_t save_stop_pos = it->stop_charpos;
7878 ptrdiff_t save_end_pos = it->end_charpos;
7880 eassert (NILP (it->string) && !it->s);
7881 eassert (it->bidi_p);
7882 it->bidi_p = 0;
7885 it->end_charpos = min (charpos + 1, ZV);
7886 charpos = max (charpos - SCAN_BACK_LIMIT, BEGV);
7887 SET_TEXT_POS (pos, charpos, CHAR_TO_BYTE (charpos));
7888 reseat_1 (it, pos, 0);
7889 compute_stop_pos (it);
7890 /* We must advance forward, right? */
7891 if (it->stop_charpos <= charpos)
7892 emacs_abort ();
7894 while (charpos > BEGV && it->stop_charpos >= it->end_charpos);
7896 if (it->stop_charpos <= where_we_are)
7897 it->prev_stop = it->stop_charpos;
7898 else
7899 it->prev_stop = BEGV;
7900 it->bidi_p = 1;
7901 it->current = save_current;
7902 it->position = save_position;
7903 it->stop_charpos = save_stop_pos;
7904 it->end_charpos = save_end_pos;
7907 /* Scan forward from CHARPOS in the current buffer/string, until we
7908 find a stop position > current IT's position. Then handle the stop
7909 position before that. This is called when we bump into a stop
7910 position while reordering bidirectional text. CHARPOS should be
7911 the last previously processed stop_pos (or BEGV/0, if none were
7912 processed yet) whose position is less that IT's current
7913 position. */
7915 static void
7916 handle_stop_backwards (struct it *it, ptrdiff_t charpos)
7918 int bufp = !STRINGP (it->string);
7919 ptrdiff_t where_we_are = (bufp ? IT_CHARPOS (*it) : IT_STRING_CHARPOS (*it));
7920 struct display_pos save_current = it->current;
7921 struct text_pos save_position = it->position;
7922 struct text_pos pos1;
7923 ptrdiff_t next_stop;
7925 /* Scan in strict logical order. */
7926 eassert (it->bidi_p);
7927 it->bidi_p = 0;
7930 it->prev_stop = charpos;
7931 if (bufp)
7933 SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos));
7934 reseat_1 (it, pos1, 0);
7936 else
7937 it->current.string_pos = string_pos (charpos, it->string);
7938 compute_stop_pos (it);
7939 /* We must advance forward, right? */
7940 if (it->stop_charpos <= it->prev_stop)
7941 emacs_abort ();
7942 charpos = it->stop_charpos;
7944 while (charpos <= where_we_are);
7946 it->bidi_p = 1;
7947 it->current = save_current;
7948 it->position = save_position;
7949 next_stop = it->stop_charpos;
7950 it->stop_charpos = it->prev_stop;
7951 handle_stop (it);
7952 it->stop_charpos = next_stop;
7955 /* Load IT with the next display element from current_buffer. Value
7956 is zero if end of buffer reached. IT->stop_charpos is the next
7957 position at which to stop and check for text properties or buffer
7958 end. */
7960 static int
7961 next_element_from_buffer (struct it *it)
7963 int success_p = 1;
7965 eassert (IT_CHARPOS (*it) >= BEGV);
7966 eassert (NILP (it->string) && !it->s);
7967 eassert (!it->bidi_p
7968 || (EQ (it->bidi_it.string.lstring, Qnil)
7969 && it->bidi_it.string.s == NULL));
7971 /* With bidi reordering, the character to display might not be the
7972 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
7973 we were reseat()ed to a new buffer position, which is potentially
7974 a different paragraph. */
7975 if (it->bidi_p && it->bidi_it.first_elt)
7977 get_visually_first_element (it);
7978 SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it));
7981 if (IT_CHARPOS (*it) >= it->stop_charpos)
7983 if (IT_CHARPOS (*it) >= it->end_charpos)
7985 int overlay_strings_follow_p;
7987 /* End of the game, except when overlay strings follow that
7988 haven't been returned yet. */
7989 if (it->overlay_strings_at_end_processed_p)
7990 overlay_strings_follow_p = 0;
7991 else
7993 it->overlay_strings_at_end_processed_p = 1;
7994 overlay_strings_follow_p = get_overlay_strings (it, 0);
7997 if (overlay_strings_follow_p)
7998 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
7999 else
8001 it->what = IT_EOB;
8002 it->position = it->current.pos;
8003 success_p = 0;
8006 else if (!(!it->bidi_p
8007 || BIDI_AT_BASE_LEVEL (it->bidi_it)
8008 || IT_CHARPOS (*it) == it->stop_charpos))
8010 /* With bidi non-linear iteration, we could find ourselves
8011 far beyond the last computed stop_charpos, with several
8012 other stop positions in between that we missed. Scan
8013 them all now, in buffer's logical order, until we find
8014 and handle the last stop_charpos that precedes our
8015 current position. */
8016 handle_stop_backwards (it, it->stop_charpos);
8017 return GET_NEXT_DISPLAY_ELEMENT (it);
8019 else
8021 if (it->bidi_p)
8023 /* Take note of the stop position we just moved across,
8024 for when we will move back across it. */
8025 it->prev_stop = it->stop_charpos;
8026 /* If we are at base paragraph embedding level, take
8027 note of the last stop position seen at this
8028 level. */
8029 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
8030 it->base_level_stop = it->stop_charpos;
8032 handle_stop (it);
8033 return GET_NEXT_DISPLAY_ELEMENT (it);
8036 else if (it->bidi_p
8037 /* If we are before prev_stop, we may have overstepped on
8038 our way backwards a stop_pos, and if so, we need to
8039 handle that stop_pos. */
8040 && IT_CHARPOS (*it) < it->prev_stop
8041 /* We can sometimes back up for reasons that have nothing
8042 to do with bidi reordering. E.g., compositions. The
8043 code below is only needed when we are above the base
8044 embedding level, so test for that explicitly. */
8045 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
8047 if (it->base_level_stop <= 0
8048 || IT_CHARPOS (*it) < it->base_level_stop)
8050 /* If we lost track of base_level_stop, we need to find
8051 prev_stop by looking backwards. This happens, e.g., when
8052 we were reseated to the previous screenful of text by
8053 vertical-motion. */
8054 it->base_level_stop = BEGV;
8055 compute_stop_pos_backwards (it);
8056 handle_stop_backwards (it, it->prev_stop);
8058 else
8059 handle_stop_backwards (it, it->base_level_stop);
8060 return GET_NEXT_DISPLAY_ELEMENT (it);
8062 else
8064 /* No face changes, overlays etc. in sight, so just return a
8065 character from current_buffer. */
8066 unsigned char *p;
8067 ptrdiff_t stop;
8069 /* Maybe run the redisplay end trigger hook. Performance note:
8070 This doesn't seem to cost measurable time. */
8071 if (it->redisplay_end_trigger_charpos
8072 && it->glyph_row
8073 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
8074 run_redisplay_end_trigger_hook (it);
8076 stop = it->bidi_it.scan_dir < 0 ? -1 : it->end_charpos;
8077 if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it),
8078 stop)
8079 && next_element_from_composition (it))
8081 return 1;
8084 /* Get the next character, maybe multibyte. */
8085 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
8086 if (it->multibyte_p && !ASCII_BYTE_P (*p))
8087 it->c = STRING_CHAR_AND_LENGTH (p, it->len);
8088 else
8089 it->c = *p, it->len = 1;
8091 /* Record what we have and where it came from. */
8092 it->what = IT_CHARACTER;
8093 it->object = it->w->contents;
8094 it->position = it->current.pos;
8096 /* Normally we return the character found above, except when we
8097 really want to return an ellipsis for selective display. */
8098 if (it->selective)
8100 if (it->c == '\n')
8102 /* A value of selective > 0 means hide lines indented more
8103 than that number of columns. */
8104 if (it->selective > 0
8105 && IT_CHARPOS (*it) + 1 < ZV
8106 && indented_beyond_p (IT_CHARPOS (*it) + 1,
8107 IT_BYTEPOS (*it) + 1,
8108 it->selective))
8110 success_p = next_element_from_ellipsis (it);
8111 it->dpvec_char_len = -1;
8114 else if (it->c == '\r' && it->selective == -1)
8116 /* A value of selective == -1 means that everything from the
8117 CR to the end of the line is invisible, with maybe an
8118 ellipsis displayed for it. */
8119 success_p = next_element_from_ellipsis (it);
8120 it->dpvec_char_len = -1;
8125 /* Value is zero if end of buffer reached. */
8126 eassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
8127 return success_p;
8131 /* Run the redisplay end trigger hook for IT. */
8133 static void
8134 run_redisplay_end_trigger_hook (struct it *it)
8136 Lisp_Object args[3];
8138 /* IT->glyph_row should be non-null, i.e. we should be actually
8139 displaying something, or otherwise we should not run the hook. */
8140 eassert (it->glyph_row);
8142 /* Set up hook arguments. */
8143 args[0] = Qredisplay_end_trigger_functions;
8144 args[1] = it->window;
8145 XSETINT (args[2], it->redisplay_end_trigger_charpos);
8146 it->redisplay_end_trigger_charpos = 0;
8148 /* Since we are *trying* to run these functions, don't try to run
8149 them again, even if they get an error. */
8150 wset_redisplay_end_trigger (it->w, Qnil);
8151 Frun_hook_with_args (3, args);
8153 /* Notice if it changed the face of the character we are on. */
8154 handle_face_prop (it);
8158 /* Deliver a composition display element. Unlike the other
8159 next_element_from_XXX, this function is not registered in the array
8160 get_next_element[]. It is called from next_element_from_buffer and
8161 next_element_from_string when necessary. */
8163 static int
8164 next_element_from_composition (struct it *it)
8166 it->what = IT_COMPOSITION;
8167 it->len = it->cmp_it.nbytes;
8168 if (STRINGP (it->string))
8170 if (it->c < 0)
8172 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
8173 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
8174 return 0;
8176 it->position = it->current.string_pos;
8177 it->object = it->string;
8178 it->c = composition_update_it (&it->cmp_it, IT_STRING_CHARPOS (*it),
8179 IT_STRING_BYTEPOS (*it), it->string);
8181 else
8183 if (it->c < 0)
8185 IT_CHARPOS (*it) += it->cmp_it.nchars;
8186 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
8187 if (it->bidi_p)
8189 if (it->bidi_it.new_paragraph)
8190 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
8191 /* Resync the bidi iterator with IT's new position.
8192 FIXME: this doesn't support bidirectional text. */
8193 while (it->bidi_it.charpos < IT_CHARPOS (*it))
8194 bidi_move_to_visually_next (&it->bidi_it);
8196 return 0;
8198 it->position = it->current.pos;
8199 it->object = it->w->contents;
8200 it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
8201 IT_BYTEPOS (*it), Qnil);
8203 return 1;
8208 /***********************************************************************
8209 Moving an iterator without producing glyphs
8210 ***********************************************************************/
8212 /* Check if iterator is at a position corresponding to a valid buffer
8213 position after some move_it_ call. */
8215 #define IT_POS_VALID_AFTER_MOVE_P(it) \
8216 ((it)->method == GET_FROM_STRING \
8217 ? IT_STRING_CHARPOS (*it) == 0 \
8218 : 1)
8221 /* Move iterator IT to a specified buffer or X position within one
8222 line on the display without producing glyphs.
8224 OP should be a bit mask including some or all of these bits:
8225 MOVE_TO_X: Stop upon reaching x-position TO_X.
8226 MOVE_TO_POS: Stop upon reaching buffer or string position TO_CHARPOS.
8227 Regardless of OP's value, stop upon reaching the end of the display line.
8229 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
8230 This means, in particular, that TO_X includes window's horizontal
8231 scroll amount.
8233 The return value has several possible values that
8234 say what condition caused the scan to stop:
8236 MOVE_POS_MATCH_OR_ZV
8237 - when TO_POS or ZV was reached.
8239 MOVE_X_REACHED
8240 -when TO_X was reached before TO_POS or ZV were reached.
8242 MOVE_LINE_CONTINUED
8243 - when we reached the end of the display area and the line must
8244 be continued.
8246 MOVE_LINE_TRUNCATED
8247 - when we reached the end of the display area and the line is
8248 truncated.
8250 MOVE_NEWLINE_OR_CR
8251 - when we stopped at a line end, i.e. a newline or a CR and selective
8252 display is on. */
8254 static enum move_it_result
8255 move_it_in_display_line_to (struct it *it,
8256 ptrdiff_t to_charpos, int to_x,
8257 enum move_operation_enum op)
8259 enum move_it_result result = MOVE_UNDEFINED;
8260 struct glyph_row *saved_glyph_row;
8261 struct it wrap_it, atpos_it, atx_it, ppos_it;
8262 void *wrap_data = NULL, *atpos_data = NULL, *atx_data = NULL;
8263 void *ppos_data = NULL;
8264 int may_wrap = 0;
8265 enum it_method prev_method = it->method;
8266 ptrdiff_t prev_pos = IT_CHARPOS (*it);
8267 int saw_smaller_pos = prev_pos < to_charpos;
8269 /* Don't produce glyphs in produce_glyphs. */
8270 saved_glyph_row = it->glyph_row;
8271 it->glyph_row = NULL;
8273 /* Use wrap_it to save a copy of IT wherever a word wrap could
8274 occur. Use atpos_it to save a copy of IT at the desired buffer
8275 position, if found, so that we can scan ahead and check if the
8276 word later overshoots the window edge. Use atx_it similarly, for
8277 pixel positions. */
8278 wrap_it.sp = -1;
8279 atpos_it.sp = -1;
8280 atx_it.sp = -1;
8282 /* Use ppos_it under bidi reordering to save a copy of IT for the
8283 position > CHARPOS that is the closest to CHARPOS. We restore
8284 that position in IT when we have scanned the entire display line
8285 without finding a match for CHARPOS and all the character
8286 positions are greater than CHARPOS. */
8287 if (it->bidi_p)
8289 SAVE_IT (ppos_it, *it, ppos_data);
8290 SET_TEXT_POS (ppos_it.current.pos, ZV, ZV_BYTE);
8291 if ((op & MOVE_TO_POS) && IT_CHARPOS (*it) >= to_charpos)
8292 SAVE_IT (ppos_it, *it, ppos_data);
8295 #define BUFFER_POS_REACHED_P() \
8296 ((op & MOVE_TO_POS) != 0 \
8297 && BUFFERP (it->object) \
8298 && (IT_CHARPOS (*it) == to_charpos \
8299 || ((!it->bidi_p \
8300 || BIDI_AT_BASE_LEVEL (it->bidi_it)) \
8301 && IT_CHARPOS (*it) > to_charpos) \
8302 || (it->what == IT_COMPOSITION \
8303 && ((IT_CHARPOS (*it) > to_charpos \
8304 && to_charpos >= it->cmp_it.charpos) \
8305 || (IT_CHARPOS (*it) < to_charpos \
8306 && to_charpos <= it->cmp_it.charpos)))) \
8307 && (it->method == GET_FROM_BUFFER \
8308 || (it->method == GET_FROM_DISPLAY_VECTOR \
8309 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
8311 /* If there's a line-/wrap-prefix, handle it. */
8312 if (it->hpos == 0 && it->method == GET_FROM_BUFFER
8313 && it->current_y < it->last_visible_y)
8314 handle_line_prefix (it);
8316 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8317 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8319 while (1)
8321 int x, i, ascent = 0, descent = 0;
8323 /* Utility macro to reset an iterator with x, ascent, and descent. */
8324 #define IT_RESET_X_ASCENT_DESCENT(IT) \
8325 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
8326 (IT)->max_descent = descent)
8328 /* Stop if we move beyond TO_CHARPOS (after an image or a
8329 display string or stretch glyph). */
8330 if ((op & MOVE_TO_POS) != 0
8331 && BUFFERP (it->object)
8332 && it->method == GET_FROM_BUFFER
8333 && (((!it->bidi_p
8334 /* When the iterator is at base embedding level, we
8335 are guaranteed that characters are delivered for
8336 display in strictly increasing order of their
8337 buffer positions. */
8338 || BIDI_AT_BASE_LEVEL (it->bidi_it))
8339 && IT_CHARPOS (*it) > to_charpos)
8340 || (it->bidi_p
8341 && (prev_method == GET_FROM_IMAGE
8342 || prev_method == GET_FROM_STRETCH
8343 || prev_method == GET_FROM_STRING)
8344 /* Passed TO_CHARPOS from left to right. */
8345 && ((prev_pos < to_charpos
8346 && IT_CHARPOS (*it) > to_charpos)
8347 /* Passed TO_CHARPOS from right to left. */
8348 || (prev_pos > to_charpos
8349 && IT_CHARPOS (*it) < to_charpos)))))
8351 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8353 result = MOVE_POS_MATCH_OR_ZV;
8354 break;
8356 else if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8357 /* If wrap_it is valid, the current position might be in a
8358 word that is wrapped. So, save the iterator in
8359 atpos_it and continue to see if wrapping happens. */
8360 SAVE_IT (atpos_it, *it, atpos_data);
8363 /* Stop when ZV reached.
8364 We used to stop here when TO_CHARPOS reached as well, but that is
8365 too soon if this glyph does not fit on this line. So we handle it
8366 explicitly below. */
8367 if (!get_next_display_element (it))
8369 result = MOVE_POS_MATCH_OR_ZV;
8370 break;
8373 if (it->line_wrap == TRUNCATE)
8375 if (BUFFER_POS_REACHED_P ())
8377 result = MOVE_POS_MATCH_OR_ZV;
8378 break;
8381 else
8383 if (it->line_wrap == WORD_WRAP)
8385 if (IT_DISPLAYING_WHITESPACE (it))
8386 may_wrap = 1;
8387 else if (may_wrap)
8389 /* We have reached a glyph that follows one or more
8390 whitespace characters. If the position is
8391 already found, we are done. */
8392 if (atpos_it.sp >= 0)
8394 RESTORE_IT (it, &atpos_it, atpos_data);
8395 result = MOVE_POS_MATCH_OR_ZV;
8396 goto done;
8398 if (atx_it.sp >= 0)
8400 RESTORE_IT (it, &atx_it, atx_data);
8401 result = MOVE_X_REACHED;
8402 goto done;
8404 /* Otherwise, we can wrap here. */
8405 SAVE_IT (wrap_it, *it, wrap_data);
8406 may_wrap = 0;
8411 /* Remember the line height for the current line, in case
8412 the next element doesn't fit on the line. */
8413 ascent = it->max_ascent;
8414 descent = it->max_descent;
8416 /* The call to produce_glyphs will get the metrics of the
8417 display element IT is loaded with. Record the x-position
8418 before this display element, in case it doesn't fit on the
8419 line. */
8420 x = it->current_x;
8422 PRODUCE_GLYPHS (it);
8424 if (it->area != TEXT_AREA)
8426 prev_method = it->method;
8427 if (it->method == GET_FROM_BUFFER)
8428 prev_pos = IT_CHARPOS (*it);
8429 set_iterator_to_next (it, 1);
8430 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8431 SET_TEXT_POS (this_line_min_pos,
8432 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8433 if (it->bidi_p
8434 && (op & MOVE_TO_POS)
8435 && IT_CHARPOS (*it) > to_charpos
8436 && IT_CHARPOS (*it) < IT_CHARPOS (ppos_it))
8437 SAVE_IT (ppos_it, *it, ppos_data);
8438 continue;
8441 /* The number of glyphs we get back in IT->nglyphs will normally
8442 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
8443 character on a terminal frame, or (iii) a line end. For the
8444 second case, IT->nglyphs - 1 padding glyphs will be present.
8445 (On X frames, there is only one glyph produced for a
8446 composite character.)
8448 The behavior implemented below means, for continuation lines,
8449 that as many spaces of a TAB as fit on the current line are
8450 displayed there. For terminal frames, as many glyphs of a
8451 multi-glyph character are displayed in the current line, too.
8452 This is what the old redisplay code did, and we keep it that
8453 way. Under X, the whole shape of a complex character must
8454 fit on the line or it will be completely displayed in the
8455 next line.
8457 Note that both for tabs and padding glyphs, all glyphs have
8458 the same width. */
8459 if (it->nglyphs)
8461 /* More than one glyph or glyph doesn't fit on line. All
8462 glyphs have the same width. */
8463 int single_glyph_width = it->pixel_width / it->nglyphs;
8464 int new_x;
8465 int x_before_this_char = x;
8466 int hpos_before_this_char = it->hpos;
8468 for (i = 0; i < it->nglyphs; ++i, x = new_x)
8470 new_x = x + single_glyph_width;
8472 /* We want to leave anything reaching TO_X to the caller. */
8473 if ((op & MOVE_TO_X) && new_x > to_x)
8475 if (BUFFER_POS_REACHED_P ())
8477 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8478 goto buffer_pos_reached;
8479 if (atpos_it.sp < 0)
8481 SAVE_IT (atpos_it, *it, atpos_data);
8482 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8485 else
8487 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8489 it->current_x = x;
8490 result = MOVE_X_REACHED;
8491 break;
8493 if (atx_it.sp < 0)
8495 SAVE_IT (atx_it, *it, atx_data);
8496 IT_RESET_X_ASCENT_DESCENT (&atx_it);
8501 if (/* Lines are continued. */
8502 it->line_wrap != TRUNCATE
8503 && (/* And glyph doesn't fit on the line. */
8504 new_x > it->last_visible_x
8505 /* Or it fits exactly and we're on a window
8506 system frame. */
8507 || (new_x == it->last_visible_x
8508 && FRAME_WINDOW_P (it->f)
8509 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
8510 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8511 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
8513 if (/* IT->hpos == 0 means the very first glyph
8514 doesn't fit on the line, e.g. a wide image. */
8515 it->hpos == 0
8516 || (new_x == it->last_visible_x
8517 && FRAME_WINDOW_P (it->f)))
8519 ++it->hpos;
8520 it->current_x = new_x;
8522 /* The character's last glyph just barely fits
8523 in this row. */
8524 if (i == it->nglyphs - 1)
8526 /* If this is the destination position,
8527 return a position *before* it in this row,
8528 now that we know it fits in this row. */
8529 if (BUFFER_POS_REACHED_P ())
8531 if (it->line_wrap != WORD_WRAP
8532 || wrap_it.sp < 0)
8534 it->hpos = hpos_before_this_char;
8535 it->current_x = x_before_this_char;
8536 result = MOVE_POS_MATCH_OR_ZV;
8537 break;
8539 if (it->line_wrap == WORD_WRAP
8540 && atpos_it.sp < 0)
8542 SAVE_IT (atpos_it, *it, atpos_data);
8543 atpos_it.current_x = x_before_this_char;
8544 atpos_it.hpos = hpos_before_this_char;
8548 prev_method = it->method;
8549 if (it->method == GET_FROM_BUFFER)
8550 prev_pos = IT_CHARPOS (*it);
8551 set_iterator_to_next (it, 1);
8552 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8553 SET_TEXT_POS (this_line_min_pos,
8554 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8555 /* On graphical terminals, newlines may
8556 "overflow" into the fringe if
8557 overflow-newline-into-fringe is non-nil.
8558 On text terminals, and on graphical
8559 terminals with no right margin, newlines
8560 may overflow into the last glyph on the
8561 display line.*/
8562 if (!FRAME_WINDOW_P (it->f)
8563 || ((it->bidi_p
8564 && it->bidi_it.paragraph_dir == R2L)
8565 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8566 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
8567 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8569 if (!get_next_display_element (it))
8571 result = MOVE_POS_MATCH_OR_ZV;
8572 break;
8574 if (BUFFER_POS_REACHED_P ())
8576 if (ITERATOR_AT_END_OF_LINE_P (it))
8577 result = MOVE_POS_MATCH_OR_ZV;
8578 else
8579 result = MOVE_LINE_CONTINUED;
8580 break;
8582 if (ITERATOR_AT_END_OF_LINE_P (it)
8583 && (it->line_wrap != WORD_WRAP
8584 || wrap_it.sp < 0))
8586 result = MOVE_NEWLINE_OR_CR;
8587 break;
8592 else
8593 IT_RESET_X_ASCENT_DESCENT (it);
8595 if (wrap_it.sp >= 0)
8597 RESTORE_IT (it, &wrap_it, wrap_data);
8598 atpos_it.sp = -1;
8599 atx_it.sp = -1;
8602 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
8603 IT_CHARPOS (*it)));
8604 result = MOVE_LINE_CONTINUED;
8605 break;
8608 if (BUFFER_POS_REACHED_P ())
8610 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8611 goto buffer_pos_reached;
8612 if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8614 SAVE_IT (atpos_it, *it, atpos_data);
8615 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8619 if (new_x > it->first_visible_x)
8621 /* Glyph is visible. Increment number of glyphs that
8622 would be displayed. */
8623 ++it->hpos;
8627 if (result != MOVE_UNDEFINED)
8628 break;
8630 else if (BUFFER_POS_REACHED_P ())
8632 buffer_pos_reached:
8633 IT_RESET_X_ASCENT_DESCENT (it);
8634 result = MOVE_POS_MATCH_OR_ZV;
8635 break;
8637 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
8639 /* Stop when TO_X specified and reached. This check is
8640 necessary here because of lines consisting of a line end,
8641 only. The line end will not produce any glyphs and we
8642 would never get MOVE_X_REACHED. */
8643 eassert (it->nglyphs == 0);
8644 result = MOVE_X_REACHED;
8645 break;
8648 /* Is this a line end? If yes, we're done. */
8649 if (ITERATOR_AT_END_OF_LINE_P (it))
8651 /* If we are past TO_CHARPOS, but never saw any character
8652 positions smaller than TO_CHARPOS, return
8653 MOVE_POS_MATCH_OR_ZV, like the unidirectional display
8654 did. */
8655 if (it->bidi_p && (op & MOVE_TO_POS) != 0)
8657 if (!saw_smaller_pos && IT_CHARPOS (*it) > to_charpos)
8659 if (IT_CHARPOS (ppos_it) < ZV)
8661 RESTORE_IT (it, &ppos_it, ppos_data);
8662 result = MOVE_POS_MATCH_OR_ZV;
8664 else
8665 goto buffer_pos_reached;
8667 else if (it->line_wrap == WORD_WRAP && atpos_it.sp >= 0
8668 && IT_CHARPOS (*it) > to_charpos)
8669 goto buffer_pos_reached;
8670 else
8671 result = MOVE_NEWLINE_OR_CR;
8673 else
8674 result = MOVE_NEWLINE_OR_CR;
8675 break;
8678 prev_method = it->method;
8679 if (it->method == GET_FROM_BUFFER)
8680 prev_pos = IT_CHARPOS (*it);
8681 /* The current display element has been consumed. Advance
8682 to the next. */
8683 set_iterator_to_next (it, 1);
8684 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8685 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8686 if (IT_CHARPOS (*it) < to_charpos)
8687 saw_smaller_pos = 1;
8688 if (it->bidi_p
8689 && (op & MOVE_TO_POS)
8690 && IT_CHARPOS (*it) >= to_charpos
8691 && IT_CHARPOS (*it) < IT_CHARPOS (ppos_it))
8692 SAVE_IT (ppos_it, *it, ppos_data);
8694 /* Stop if lines are truncated and IT's current x-position is
8695 past the right edge of the window now. */
8696 if (it->line_wrap == TRUNCATE
8697 && it->current_x >= it->last_visible_x)
8699 if (!FRAME_WINDOW_P (it->f)
8700 || ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
8701 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8702 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
8703 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8705 int at_eob_p = 0;
8707 if ((at_eob_p = !get_next_display_element (it))
8708 || BUFFER_POS_REACHED_P ()
8709 /* If we are past TO_CHARPOS, but never saw any
8710 character positions smaller than TO_CHARPOS,
8711 return MOVE_POS_MATCH_OR_ZV, like the
8712 unidirectional display did. */
8713 || (it->bidi_p && (op & MOVE_TO_POS) != 0
8714 && !saw_smaller_pos
8715 && IT_CHARPOS (*it) > to_charpos))
8717 if (it->bidi_p
8718 && !at_eob_p && IT_CHARPOS (ppos_it) < ZV)
8719 RESTORE_IT (it, &ppos_it, ppos_data);
8720 result = MOVE_POS_MATCH_OR_ZV;
8721 break;
8723 if (ITERATOR_AT_END_OF_LINE_P (it))
8725 result = MOVE_NEWLINE_OR_CR;
8726 break;
8729 else if (it->bidi_p && (op & MOVE_TO_POS) != 0
8730 && !saw_smaller_pos
8731 && IT_CHARPOS (*it) > to_charpos)
8733 if (IT_CHARPOS (ppos_it) < ZV)
8734 RESTORE_IT (it, &ppos_it, ppos_data);
8735 result = MOVE_POS_MATCH_OR_ZV;
8736 break;
8738 result = MOVE_LINE_TRUNCATED;
8739 break;
8741 #undef IT_RESET_X_ASCENT_DESCENT
8744 #undef BUFFER_POS_REACHED_P
8746 /* If we scanned beyond to_pos and didn't find a point to wrap at,
8747 restore the saved iterator. */
8748 if (atpos_it.sp >= 0)
8749 RESTORE_IT (it, &atpos_it, atpos_data);
8750 else if (atx_it.sp >= 0)
8751 RESTORE_IT (it, &atx_it, atx_data);
8753 done:
8755 if (atpos_data)
8756 bidi_unshelve_cache (atpos_data, 1);
8757 if (atx_data)
8758 bidi_unshelve_cache (atx_data, 1);
8759 if (wrap_data)
8760 bidi_unshelve_cache (wrap_data, 1);
8761 if (ppos_data)
8762 bidi_unshelve_cache (ppos_data, 1);
8764 /* Restore the iterator settings altered at the beginning of this
8765 function. */
8766 it->glyph_row = saved_glyph_row;
8767 return result;
8770 /* For external use. */
8771 void
8772 move_it_in_display_line (struct it *it,
8773 ptrdiff_t to_charpos, int to_x,
8774 enum move_operation_enum op)
8776 if (it->line_wrap == WORD_WRAP
8777 && (op & MOVE_TO_X))
8779 struct it save_it;
8780 void *save_data = NULL;
8781 int skip;
8783 SAVE_IT (save_it, *it, save_data);
8784 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
8785 /* When word-wrap is on, TO_X may lie past the end
8786 of a wrapped line. Then it->current is the
8787 character on the next line, so backtrack to the
8788 space before the wrap point. */
8789 if (skip == MOVE_LINE_CONTINUED)
8791 int prev_x = max (it->current_x - 1, 0);
8792 RESTORE_IT (it, &save_it, save_data);
8793 move_it_in_display_line_to
8794 (it, -1, prev_x, MOVE_TO_X);
8796 else
8797 bidi_unshelve_cache (save_data, 1);
8799 else
8800 move_it_in_display_line_to (it, to_charpos, to_x, op);
8804 /* Move IT forward until it satisfies one or more of the criteria in
8805 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
8807 OP is a bit-mask that specifies where to stop, and in particular,
8808 which of those four position arguments makes a difference. See the
8809 description of enum move_operation_enum.
8811 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
8812 screen line, this function will set IT to the next position that is
8813 displayed to the right of TO_CHARPOS on the screen. */
8815 void
8816 move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos, int op)
8818 enum move_it_result skip, skip2 = MOVE_X_REACHED;
8819 int line_height, line_start_x = 0, reached = 0;
8820 void *backup_data = NULL;
8822 for (;;)
8824 if (op & MOVE_TO_VPOS)
8826 /* If no TO_CHARPOS and no TO_X specified, stop at the
8827 start of the line TO_VPOS. */
8828 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
8830 if (it->vpos == to_vpos)
8832 reached = 1;
8833 break;
8835 else
8836 skip = move_it_in_display_line_to (it, -1, -1, 0);
8838 else
8840 /* TO_VPOS >= 0 means stop at TO_X in the line at
8841 TO_VPOS, or at TO_POS, whichever comes first. */
8842 if (it->vpos == to_vpos)
8844 reached = 2;
8845 break;
8848 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
8850 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
8852 reached = 3;
8853 break;
8855 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
8857 /* We have reached TO_X but not in the line we want. */
8858 skip = move_it_in_display_line_to (it, to_charpos,
8859 -1, MOVE_TO_POS);
8860 if (skip == MOVE_POS_MATCH_OR_ZV)
8862 reached = 4;
8863 break;
8868 else if (op & MOVE_TO_Y)
8870 struct it it_backup;
8872 if (it->line_wrap == WORD_WRAP)
8873 SAVE_IT (it_backup, *it, backup_data);
8875 /* TO_Y specified means stop at TO_X in the line containing
8876 TO_Y---or at TO_CHARPOS if this is reached first. The
8877 problem is that we can't really tell whether the line
8878 contains TO_Y before we have completely scanned it, and
8879 this may skip past TO_X. What we do is to first scan to
8880 TO_X.
8882 If TO_X is not specified, use a TO_X of zero. The reason
8883 is to make the outcome of this function more predictable.
8884 If we didn't use TO_X == 0, we would stop at the end of
8885 the line which is probably not what a caller would expect
8886 to happen. */
8887 skip = move_it_in_display_line_to
8888 (it, to_charpos, ((op & MOVE_TO_X) ? to_x : 0),
8889 (MOVE_TO_X | (op & MOVE_TO_POS)));
8891 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
8892 if (skip == MOVE_POS_MATCH_OR_ZV)
8893 reached = 5;
8894 else if (skip == MOVE_X_REACHED)
8896 /* If TO_X was reached, we want to know whether TO_Y is
8897 in the line. We know this is the case if the already
8898 scanned glyphs make the line tall enough. Otherwise,
8899 we must check by scanning the rest of the line. */
8900 line_height = it->max_ascent + it->max_descent;
8901 if (to_y >= it->current_y
8902 && to_y < it->current_y + line_height)
8904 reached = 6;
8905 break;
8907 SAVE_IT (it_backup, *it, backup_data);
8908 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
8909 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
8910 op & MOVE_TO_POS);
8911 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
8912 line_height = it->max_ascent + it->max_descent;
8913 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
8915 if (to_y >= it->current_y
8916 && to_y < it->current_y + line_height)
8918 /* If TO_Y is in this line and TO_X was reached
8919 above, we scanned too far. We have to restore
8920 IT's settings to the ones before skipping. But
8921 keep the more accurate values of max_ascent and
8922 max_descent we've found while skipping the rest
8923 of the line, for the sake of callers, such as
8924 pos_visible_p, that need to know the line
8925 height. */
8926 int max_ascent = it->max_ascent;
8927 int max_descent = it->max_descent;
8929 RESTORE_IT (it, &it_backup, backup_data);
8930 it->max_ascent = max_ascent;
8931 it->max_descent = max_descent;
8932 reached = 6;
8934 else
8936 skip = skip2;
8937 if (skip == MOVE_POS_MATCH_OR_ZV)
8938 reached = 7;
8941 else
8943 /* Check whether TO_Y is in this line. */
8944 line_height = it->max_ascent + it->max_descent;
8945 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
8947 if (to_y >= it->current_y
8948 && to_y < it->current_y + line_height)
8950 /* When word-wrap is on, TO_X may lie past the end
8951 of a wrapped line. Then it->current is the
8952 character on the next line, so backtrack to the
8953 space before the wrap point. */
8954 if (skip == MOVE_LINE_CONTINUED
8955 && it->line_wrap == WORD_WRAP)
8957 int prev_x = max (it->current_x - 1, 0);
8958 RESTORE_IT (it, &it_backup, backup_data);
8959 skip = move_it_in_display_line_to
8960 (it, -1, prev_x, MOVE_TO_X);
8962 reached = 6;
8966 if (reached)
8967 break;
8969 else if (BUFFERP (it->object)
8970 && (it->method == GET_FROM_BUFFER
8971 || it->method == GET_FROM_STRETCH)
8972 && IT_CHARPOS (*it) >= to_charpos
8973 /* Under bidi iteration, a call to set_iterator_to_next
8974 can scan far beyond to_charpos if the initial
8975 portion of the next line needs to be reordered. In
8976 that case, give move_it_in_display_line_to another
8977 chance below. */
8978 && !(it->bidi_p
8979 && it->bidi_it.scan_dir == -1))
8980 skip = MOVE_POS_MATCH_OR_ZV;
8981 else
8982 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
8984 switch (skip)
8986 case MOVE_POS_MATCH_OR_ZV:
8987 reached = 8;
8988 goto out;
8990 case MOVE_NEWLINE_OR_CR:
8991 set_iterator_to_next (it, 1);
8992 it->continuation_lines_width = 0;
8993 break;
8995 case MOVE_LINE_TRUNCATED:
8996 it->continuation_lines_width = 0;
8997 reseat_at_next_visible_line_start (it, 0);
8998 if ((op & MOVE_TO_POS) != 0
8999 && IT_CHARPOS (*it) > to_charpos)
9001 reached = 9;
9002 goto out;
9004 break;
9006 case MOVE_LINE_CONTINUED:
9007 /* For continued lines ending in a tab, some of the glyphs
9008 associated with the tab are displayed on the current
9009 line. Since it->current_x does not include these glyphs,
9010 we use it->last_visible_x instead. */
9011 if (it->c == '\t')
9013 it->continuation_lines_width += it->last_visible_x;
9014 /* When moving by vpos, ensure that the iterator really
9015 advances to the next line (bug#847, bug#969). Fixme:
9016 do we need to do this in other circumstances? */
9017 if (it->current_x != it->last_visible_x
9018 && (op & MOVE_TO_VPOS)
9019 && !(op & (MOVE_TO_X | MOVE_TO_POS)))
9021 line_start_x = it->current_x + it->pixel_width
9022 - it->last_visible_x;
9023 set_iterator_to_next (it, 0);
9026 else
9027 it->continuation_lines_width += it->current_x;
9028 break;
9030 default:
9031 emacs_abort ();
9034 /* Reset/increment for the next run. */
9035 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
9036 it->current_x = line_start_x;
9037 line_start_x = 0;
9038 it->hpos = 0;
9039 it->current_y += it->max_ascent + it->max_descent;
9040 ++it->vpos;
9041 last_height = it->max_ascent + it->max_descent;
9042 it->max_ascent = it->max_descent = 0;
9045 out:
9047 /* On text terminals, we may stop at the end of a line in the middle
9048 of a multi-character glyph. If the glyph itself is continued,
9049 i.e. it is actually displayed on the next line, don't treat this
9050 stopping point as valid; move to the next line instead (unless
9051 that brings us offscreen). */
9052 if (!FRAME_WINDOW_P (it->f)
9053 && op & MOVE_TO_POS
9054 && IT_CHARPOS (*it) == to_charpos
9055 && it->what == IT_CHARACTER
9056 && it->nglyphs > 1
9057 && it->line_wrap == WINDOW_WRAP
9058 && it->current_x == it->last_visible_x - 1
9059 && it->c != '\n'
9060 && it->c != '\t'
9061 && it->vpos < XFASTINT (it->w->window_end_vpos))
9063 it->continuation_lines_width += it->current_x;
9064 it->current_x = it->hpos = it->max_ascent = it->max_descent = 0;
9065 it->current_y += it->max_ascent + it->max_descent;
9066 ++it->vpos;
9067 last_height = it->max_ascent + it->max_descent;
9070 if (backup_data)
9071 bidi_unshelve_cache (backup_data, 1);
9073 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
9077 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
9079 If DY > 0, move IT backward at least that many pixels. DY = 0
9080 means move IT backward to the preceding line start or BEGV. This
9081 function may move over more than DY pixels if IT->current_y - DY
9082 ends up in the middle of a line; in this case IT->current_y will be
9083 set to the top of the line moved to. */
9085 void
9086 move_it_vertically_backward (struct it *it, int dy)
9088 int nlines, h;
9089 struct it it2, it3;
9090 void *it2data = NULL, *it3data = NULL;
9091 ptrdiff_t start_pos;
9092 int nchars_per_row
9093 = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
9094 ptrdiff_t pos_limit;
9096 move_further_back:
9097 eassert (dy >= 0);
9099 start_pos = IT_CHARPOS (*it);
9101 /* Estimate how many newlines we must move back. */
9102 nlines = max (1, dy / default_line_pixel_height (it->w));
9103 if (it->line_wrap == TRUNCATE)
9104 pos_limit = BEGV;
9105 else
9106 pos_limit = max (start_pos - nlines * nchars_per_row, BEGV);
9108 /* Set the iterator's position that many lines back. But don't go
9109 back more than NLINES full screen lines -- this wins a day with
9110 buffers which have very long lines. */
9111 while (nlines-- && IT_CHARPOS (*it) > pos_limit)
9112 back_to_previous_visible_line_start (it);
9114 /* Reseat the iterator here. When moving backward, we don't want
9115 reseat to skip forward over invisible text, set up the iterator
9116 to deliver from overlay strings at the new position etc. So,
9117 use reseat_1 here. */
9118 reseat_1 (it, it->current.pos, 1);
9120 /* We are now surely at a line start. */
9121 it->current_x = it->hpos = 0; /* FIXME: this is incorrect when bidi
9122 reordering is in effect. */
9123 it->continuation_lines_width = 0;
9125 /* Move forward and see what y-distance we moved. First move to the
9126 start of the next line so that we get its height. We need this
9127 height to be able to tell whether we reached the specified
9128 y-distance. */
9129 SAVE_IT (it2, *it, it2data);
9130 it2.max_ascent = it2.max_descent = 0;
9133 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
9134 MOVE_TO_POS | MOVE_TO_VPOS);
9136 while (!(IT_POS_VALID_AFTER_MOVE_P (&it2)
9137 /* If we are in a display string which starts at START_POS,
9138 and that display string includes a newline, and we are
9139 right after that newline (i.e. at the beginning of a
9140 display line), exit the loop, because otherwise we will
9141 infloop, since move_it_to will see that it is already at
9142 START_POS and will not move. */
9143 || (it2.method == GET_FROM_STRING
9144 && IT_CHARPOS (it2) == start_pos
9145 && SREF (it2.string, IT_STRING_BYTEPOS (it2) - 1) == '\n')));
9146 eassert (IT_CHARPOS (*it) >= BEGV);
9147 SAVE_IT (it3, it2, it3data);
9149 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
9150 eassert (IT_CHARPOS (*it) >= BEGV);
9151 /* H is the actual vertical distance from the position in *IT
9152 and the starting position. */
9153 h = it2.current_y - it->current_y;
9154 /* NLINES is the distance in number of lines. */
9155 nlines = it2.vpos - it->vpos;
9157 /* Correct IT's y and vpos position
9158 so that they are relative to the starting point. */
9159 it->vpos -= nlines;
9160 it->current_y -= h;
9162 if (dy == 0)
9164 /* DY == 0 means move to the start of the screen line. The
9165 value of nlines is > 0 if continuation lines were involved,
9166 or if the original IT position was at start of a line. */
9167 RESTORE_IT (it, it, it2data);
9168 if (nlines > 0)
9169 move_it_by_lines (it, nlines);
9170 /* The above code moves us to some position NLINES down,
9171 usually to its first glyph (leftmost in an L2R line), but
9172 that's not necessarily the start of the line, under bidi
9173 reordering. We want to get to the character position
9174 that is immediately after the newline of the previous
9175 line. */
9176 if (it->bidi_p
9177 && !it->continuation_lines_width
9178 && !STRINGP (it->string)
9179 && IT_CHARPOS (*it) > BEGV
9180 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9182 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
9184 DEC_BOTH (cp, bp);
9185 cp = find_newline_no_quit (cp, bp, -1, NULL);
9186 move_it_to (it, cp, -1, -1, -1, MOVE_TO_POS);
9188 bidi_unshelve_cache (it3data, 1);
9190 else
9192 /* The y-position we try to reach, relative to *IT.
9193 Note that H has been subtracted in front of the if-statement. */
9194 int target_y = it->current_y + h - dy;
9195 int y0 = it3.current_y;
9196 int y1;
9197 int line_height;
9199 RESTORE_IT (&it3, &it3, it3data);
9200 y1 = line_bottom_y (&it3);
9201 line_height = y1 - y0;
9202 RESTORE_IT (it, it, it2data);
9203 /* If we did not reach target_y, try to move further backward if
9204 we can. If we moved too far backward, try to move forward. */
9205 if (target_y < it->current_y
9206 /* This is heuristic. In a window that's 3 lines high, with
9207 a line height of 13 pixels each, recentering with point
9208 on the bottom line will try to move -39/2 = 19 pixels
9209 backward. Try to avoid moving into the first line. */
9210 && (it->current_y - target_y
9211 > min (window_box_height (it->w), line_height * 2 / 3))
9212 && IT_CHARPOS (*it) > BEGV)
9214 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
9215 target_y - it->current_y));
9216 dy = it->current_y - target_y;
9217 goto move_further_back;
9219 else if (target_y >= it->current_y + line_height
9220 && IT_CHARPOS (*it) < ZV)
9222 /* Should move forward by at least one line, maybe more.
9224 Note: Calling move_it_by_lines can be expensive on
9225 terminal frames, where compute_motion is used (via
9226 vmotion) to do the job, when there are very long lines
9227 and truncate-lines is nil. That's the reason for
9228 treating terminal frames specially here. */
9230 if (!FRAME_WINDOW_P (it->f))
9231 move_it_vertically (it, target_y - (it->current_y + line_height));
9232 else
9236 move_it_by_lines (it, 1);
9238 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
9245 /* Move IT by a specified amount of pixel lines DY. DY negative means
9246 move backwards. DY = 0 means move to start of screen line. At the
9247 end, IT will be on the start of a screen line. */
9249 void
9250 move_it_vertically (struct it *it, int dy)
9252 if (dy <= 0)
9253 move_it_vertically_backward (it, -dy);
9254 else
9256 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
9257 move_it_to (it, ZV, -1, it->current_y + dy, -1,
9258 MOVE_TO_POS | MOVE_TO_Y);
9259 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
9261 /* If buffer ends in ZV without a newline, move to the start of
9262 the line to satisfy the post-condition. */
9263 if (IT_CHARPOS (*it) == ZV
9264 && ZV > BEGV
9265 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9266 move_it_by_lines (it, 0);
9271 /* Move iterator IT past the end of the text line it is in. */
9273 void
9274 move_it_past_eol (struct it *it)
9276 enum move_it_result rc;
9278 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
9279 if (rc == MOVE_NEWLINE_OR_CR)
9280 set_iterator_to_next (it, 0);
9284 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
9285 negative means move up. DVPOS == 0 means move to the start of the
9286 screen line.
9288 Optimization idea: If we would know that IT->f doesn't use
9289 a face with proportional font, we could be faster for
9290 truncate-lines nil. */
9292 void
9293 move_it_by_lines (struct it *it, ptrdiff_t dvpos)
9296 /* The commented-out optimization uses vmotion on terminals. This
9297 gives bad results, because elements like it->what, on which
9298 callers such as pos_visible_p rely, aren't updated. */
9299 /* struct position pos;
9300 if (!FRAME_WINDOW_P (it->f))
9302 struct text_pos textpos;
9304 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
9305 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
9306 reseat (it, textpos, 1);
9307 it->vpos += pos.vpos;
9308 it->current_y += pos.vpos;
9310 else */
9312 if (dvpos == 0)
9314 /* DVPOS == 0 means move to the start of the screen line. */
9315 move_it_vertically_backward (it, 0);
9316 /* Let next call to line_bottom_y calculate real line height */
9317 last_height = 0;
9319 else if (dvpos > 0)
9321 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
9322 if (!IT_POS_VALID_AFTER_MOVE_P (it))
9324 /* Only move to the next buffer position if we ended up in a
9325 string from display property, not in an overlay string
9326 (before-string or after-string). That is because the
9327 latter don't conceal the underlying buffer position, so
9328 we can ask to move the iterator to the exact position we
9329 are interested in. Note that, even if we are already at
9330 IT_CHARPOS (*it), the call below is not a no-op, as it
9331 will detect that we are at the end of the string, pop the
9332 iterator, and compute it->current_x and it->hpos
9333 correctly. */
9334 move_it_to (it, IT_CHARPOS (*it) + it->string_from_display_prop_p,
9335 -1, -1, -1, MOVE_TO_POS);
9338 else
9340 struct it it2;
9341 void *it2data = NULL;
9342 ptrdiff_t start_charpos, i;
9343 int nchars_per_row
9344 = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
9345 ptrdiff_t pos_limit;
9347 /* Start at the beginning of the screen line containing IT's
9348 position. This may actually move vertically backwards,
9349 in case of overlays, so adjust dvpos accordingly. */
9350 dvpos += it->vpos;
9351 move_it_vertically_backward (it, 0);
9352 dvpos -= it->vpos;
9354 /* Go back -DVPOS buffer lines, but no farther than -DVPOS full
9355 screen lines, and reseat the iterator there. */
9356 start_charpos = IT_CHARPOS (*it);
9357 if (it->line_wrap == TRUNCATE)
9358 pos_limit = BEGV;
9359 else
9360 pos_limit = max (start_charpos + dvpos * nchars_per_row, BEGV);
9361 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > pos_limit; --i)
9362 back_to_previous_visible_line_start (it);
9363 reseat (it, it->current.pos, 1);
9365 /* Move further back if we end up in a string or an image. */
9366 while (!IT_POS_VALID_AFTER_MOVE_P (it))
9368 /* First try to move to start of display line. */
9369 dvpos += it->vpos;
9370 move_it_vertically_backward (it, 0);
9371 dvpos -= it->vpos;
9372 if (IT_POS_VALID_AFTER_MOVE_P (it))
9373 break;
9374 /* If start of line is still in string or image,
9375 move further back. */
9376 back_to_previous_visible_line_start (it);
9377 reseat (it, it->current.pos, 1);
9378 dvpos--;
9381 it->current_x = it->hpos = 0;
9383 /* Above call may have moved too far if continuation lines
9384 are involved. Scan forward and see if it did. */
9385 SAVE_IT (it2, *it, it2data);
9386 it2.vpos = it2.current_y = 0;
9387 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
9388 it->vpos -= it2.vpos;
9389 it->current_y -= it2.current_y;
9390 it->current_x = it->hpos = 0;
9392 /* If we moved too far back, move IT some lines forward. */
9393 if (it2.vpos > -dvpos)
9395 int delta = it2.vpos + dvpos;
9397 RESTORE_IT (&it2, &it2, it2data);
9398 SAVE_IT (it2, *it, it2data);
9399 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
9400 /* Move back again if we got too far ahead. */
9401 if (IT_CHARPOS (*it) >= start_charpos)
9402 RESTORE_IT (it, &it2, it2data);
9403 else
9404 bidi_unshelve_cache (it2data, 1);
9406 else
9407 RESTORE_IT (it, it, it2data);
9411 /* Return 1 if IT points into the middle of a display vector. */
9414 in_display_vector_p (struct it *it)
9416 return (it->method == GET_FROM_DISPLAY_VECTOR
9417 && it->current.dpvec_index > 0
9418 && it->dpvec + it->current.dpvec_index != it->dpend);
9422 /***********************************************************************
9423 Messages
9424 ***********************************************************************/
9427 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
9428 to *Messages*. */
9430 void
9431 add_to_log (const char *format, Lisp_Object arg1, Lisp_Object arg2)
9433 Lisp_Object args[3];
9434 Lisp_Object msg, fmt;
9435 char *buffer;
9436 ptrdiff_t len;
9437 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
9438 USE_SAFE_ALLOCA;
9440 fmt = msg = Qnil;
9441 GCPRO4 (fmt, msg, arg1, arg2);
9443 args[0] = fmt = build_string (format);
9444 args[1] = arg1;
9445 args[2] = arg2;
9446 msg = Fformat (3, args);
9448 len = SBYTES (msg) + 1;
9449 buffer = SAFE_ALLOCA (len);
9450 memcpy (buffer, SDATA (msg), len);
9452 message_dolog (buffer, len - 1, 1, 0);
9453 SAFE_FREE ();
9455 UNGCPRO;
9459 /* Output a newline in the *Messages* buffer if "needs" one. */
9461 void
9462 message_log_maybe_newline (void)
9464 if (message_log_need_newline)
9465 message_dolog ("", 0, 1, 0);
9469 /* Add a string M of length NBYTES to the message log, optionally
9470 terminated with a newline when NLFLAG is true. MULTIBYTE, if
9471 true, means interpret the contents of M as multibyte. This
9472 function calls low-level routines in order to bypass text property
9473 hooks, etc. which might not be safe to run.
9475 This may GC (insert may run before/after change hooks),
9476 so the buffer M must NOT point to a Lisp string. */
9478 void
9479 message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte)
9481 const unsigned char *msg = (const unsigned char *) m;
9483 if (!NILP (Vmemory_full))
9484 return;
9486 if (!NILP (Vmessage_log_max))
9488 struct buffer *oldbuf;
9489 Lisp_Object oldpoint, oldbegv, oldzv;
9490 int old_windows_or_buffers_changed = windows_or_buffers_changed;
9491 ptrdiff_t point_at_end = 0;
9492 ptrdiff_t zv_at_end = 0;
9493 Lisp_Object old_deactivate_mark;
9494 bool shown;
9495 struct gcpro gcpro1;
9497 old_deactivate_mark = Vdeactivate_mark;
9498 oldbuf = current_buffer;
9499 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
9500 bset_undo_list (current_buffer, Qt);
9502 oldpoint = message_dolog_marker1;
9503 set_marker_restricted_both (oldpoint, Qnil, PT, PT_BYTE);
9504 oldbegv = message_dolog_marker2;
9505 set_marker_restricted_both (oldbegv, Qnil, BEGV, BEGV_BYTE);
9506 oldzv = message_dolog_marker3;
9507 set_marker_restricted_both (oldzv, Qnil, ZV, ZV_BYTE);
9508 GCPRO1 (old_deactivate_mark);
9510 if (PT == Z)
9511 point_at_end = 1;
9512 if (ZV == Z)
9513 zv_at_end = 1;
9515 BEGV = BEG;
9516 BEGV_BYTE = BEG_BYTE;
9517 ZV = Z;
9518 ZV_BYTE = Z_BYTE;
9519 TEMP_SET_PT_BOTH (Z, Z_BYTE);
9521 /* Insert the string--maybe converting multibyte to single byte
9522 or vice versa, so that all the text fits the buffer. */
9523 if (multibyte
9524 && NILP (BVAR (current_buffer, enable_multibyte_characters)))
9526 ptrdiff_t i;
9527 int c, char_bytes;
9528 char work[1];
9530 /* Convert a multibyte string to single-byte
9531 for the *Message* buffer. */
9532 for (i = 0; i < nbytes; i += char_bytes)
9534 c = string_char_and_length (msg + i, &char_bytes);
9535 work[0] = (ASCII_CHAR_P (c)
9537 : multibyte_char_to_unibyte (c));
9538 insert_1_both (work, 1, 1, 1, 0, 0);
9541 else if (! multibyte
9542 && ! NILP (BVAR (current_buffer, enable_multibyte_characters)))
9544 ptrdiff_t i;
9545 int c, char_bytes;
9546 unsigned char str[MAX_MULTIBYTE_LENGTH];
9547 /* Convert a single-byte string to multibyte
9548 for the *Message* buffer. */
9549 for (i = 0; i < nbytes; i++)
9551 c = msg[i];
9552 MAKE_CHAR_MULTIBYTE (c);
9553 char_bytes = CHAR_STRING (c, str);
9554 insert_1_both ((char *) str, 1, char_bytes, 1, 0, 0);
9557 else if (nbytes)
9558 insert_1_both (m, chars_in_text (msg, nbytes), nbytes, 1, 0, 0);
9560 if (nlflag)
9562 ptrdiff_t this_bol, this_bol_byte, prev_bol, prev_bol_byte;
9563 printmax_t dups;
9565 insert_1_both ("\n", 1, 1, 1, 0, 0);
9567 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
9568 this_bol = PT;
9569 this_bol_byte = PT_BYTE;
9571 /* See if this line duplicates the previous one.
9572 If so, combine duplicates. */
9573 if (this_bol > BEG)
9575 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
9576 prev_bol = PT;
9577 prev_bol_byte = PT_BYTE;
9579 dups = message_log_check_duplicate (prev_bol_byte,
9580 this_bol_byte);
9581 if (dups)
9583 del_range_both (prev_bol, prev_bol_byte,
9584 this_bol, this_bol_byte, 0);
9585 if (dups > 1)
9587 char dupstr[sizeof " [ times]"
9588 + INT_STRLEN_BOUND (printmax_t)];
9590 /* If you change this format, don't forget to also
9591 change message_log_check_duplicate. */
9592 int duplen = sprintf (dupstr, " [%"pMd" times]", dups);
9593 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
9594 insert_1_both (dupstr, duplen, duplen, 1, 0, 1);
9599 /* If we have more than the desired maximum number of lines
9600 in the *Messages* buffer now, delete the oldest ones.
9601 This is safe because we don't have undo in this buffer. */
9603 if (NATNUMP (Vmessage_log_max))
9605 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
9606 -XFASTINT (Vmessage_log_max) - 1, 0);
9607 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
9610 BEGV = marker_position (oldbegv);
9611 BEGV_BYTE = marker_byte_position (oldbegv);
9613 if (zv_at_end)
9615 ZV = Z;
9616 ZV_BYTE = Z_BYTE;
9618 else
9620 ZV = marker_position (oldzv);
9621 ZV_BYTE = marker_byte_position (oldzv);
9624 if (point_at_end)
9625 TEMP_SET_PT_BOTH (Z, Z_BYTE);
9626 else
9627 /* We can't do Fgoto_char (oldpoint) because it will run some
9628 Lisp code. */
9629 TEMP_SET_PT_BOTH (marker_position (oldpoint),
9630 marker_byte_position (oldpoint));
9632 UNGCPRO;
9633 unchain_marker (XMARKER (oldpoint));
9634 unchain_marker (XMARKER (oldbegv));
9635 unchain_marker (XMARKER (oldzv));
9637 shown = buffer_window_count (current_buffer) > 0;
9638 set_buffer_internal (oldbuf);
9639 /* We called insert_1_both above with its 5th argument (PREPARE)
9640 zero, which prevents insert_1_both from calling
9641 prepare_to_modify_buffer, which in turns prevents us from
9642 incrementing windows_or_buffers_changed even if *Messages* is
9643 shown in some window. So we must manually incrementing
9644 windows_or_buffers_changed here to make up for that. */
9645 if (shown)
9646 windows_or_buffers_changed++;
9647 else
9648 windows_or_buffers_changed = old_windows_or_buffers_changed;
9649 message_log_need_newline = !nlflag;
9650 Vdeactivate_mark = old_deactivate_mark;
9655 /* We are at the end of the buffer after just having inserted a newline.
9656 (Note: We depend on the fact we won't be crossing the gap.)
9657 Check to see if the most recent message looks a lot like the previous one.
9658 Return 0 if different, 1 if the new one should just replace it, or a
9659 value N > 1 if we should also append " [N times]". */
9661 static intmax_t
9662 message_log_check_duplicate (ptrdiff_t prev_bol_byte, ptrdiff_t this_bol_byte)
9664 ptrdiff_t i;
9665 ptrdiff_t len = Z_BYTE - 1 - this_bol_byte;
9666 int seen_dots = 0;
9667 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
9668 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
9670 for (i = 0; i < len; i++)
9672 if (i >= 3 && p1[i - 3] == '.' && p1[i - 2] == '.' && p1[i - 1] == '.')
9673 seen_dots = 1;
9674 if (p1[i] != p2[i])
9675 return seen_dots;
9677 p1 += len;
9678 if (*p1 == '\n')
9679 return 2;
9680 if (*p1++ == ' ' && *p1++ == '[')
9682 char *pend;
9683 intmax_t n = strtoimax ((char *) p1, &pend, 10);
9684 if (0 < n && n < INTMAX_MAX && strncmp (pend, " times]\n", 8) == 0)
9685 return n + 1;
9687 return 0;
9691 /* Display an echo area message M with a specified length of NBYTES
9692 bytes. The string may include null characters. If M is not a
9693 string, clear out any existing message, and let the mini-buffer
9694 text show through.
9696 This function cancels echoing. */
9698 void
9699 message3 (Lisp_Object m)
9701 struct gcpro gcpro1;
9703 GCPRO1 (m);
9704 clear_message (1,1);
9705 cancel_echoing ();
9707 /* First flush out any partial line written with print. */
9708 message_log_maybe_newline ();
9709 if (STRINGP (m))
9711 ptrdiff_t nbytes = SBYTES (m);
9712 bool multibyte = STRING_MULTIBYTE (m);
9713 USE_SAFE_ALLOCA;
9714 char *buffer = SAFE_ALLOCA (nbytes);
9715 memcpy (buffer, SDATA (m), nbytes);
9716 message_dolog (buffer, nbytes, 1, multibyte);
9717 SAFE_FREE ();
9719 message3_nolog (m);
9721 UNGCPRO;
9725 /* The non-logging version of message3.
9726 This does not cancel echoing, because it is used for echoing.
9727 Perhaps we need to make a separate function for echoing
9728 and make this cancel echoing. */
9730 void
9731 message3_nolog (Lisp_Object m)
9733 struct frame *sf = SELECTED_FRAME ();
9735 if (FRAME_INITIAL_P (sf))
9737 if (noninteractive_need_newline)
9738 putc ('\n', stderr);
9739 noninteractive_need_newline = 0;
9740 if (STRINGP (m))
9741 fwrite (SDATA (m), SBYTES (m), 1, stderr);
9742 if (cursor_in_echo_area == 0)
9743 fprintf (stderr, "\n");
9744 fflush (stderr);
9746 /* Error messages get reported properly by cmd_error, so this must be just an
9747 informative message; if the frame hasn't really been initialized yet, just
9748 toss it. */
9749 else if (INTERACTIVE && sf->glyphs_initialized_p)
9751 /* Get the frame containing the mini-buffer
9752 that the selected frame is using. */
9753 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
9754 Lisp_Object frame = XWINDOW (mini_window)->frame;
9755 struct frame *f = XFRAME (frame);
9757 if (FRAME_VISIBLE_P (sf) && !FRAME_VISIBLE_P (f))
9758 Fmake_frame_visible (frame);
9760 if (STRINGP (m) && SCHARS (m) > 0)
9762 set_message (m);
9763 if (minibuffer_auto_raise)
9764 Fraise_frame (frame);
9765 /* Assume we are not echoing.
9766 (If we are, echo_now will override this.) */
9767 echo_message_buffer = Qnil;
9769 else
9770 clear_message (1, 1);
9772 do_pending_window_change (0);
9773 echo_area_display (1);
9774 do_pending_window_change (0);
9775 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
9776 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
9781 /* Display a null-terminated echo area message M. If M is 0, clear
9782 out any existing message, and let the mini-buffer text show through.
9784 The buffer M must continue to exist until after the echo area gets
9785 cleared or some other message gets displayed there. Do not pass
9786 text that is stored in a Lisp string. Do not pass text in a buffer
9787 that was alloca'd. */
9789 void
9790 message1 (const char *m)
9792 message3 (m ? build_unibyte_string (m) : Qnil);
9796 /* The non-logging counterpart of message1. */
9798 void
9799 message1_nolog (const char *m)
9801 message3_nolog (m ? build_unibyte_string (m) : Qnil);
9804 /* Display a message M which contains a single %s
9805 which gets replaced with STRING. */
9807 void
9808 message_with_string (const char *m, Lisp_Object string, int log)
9810 CHECK_STRING (string);
9812 if (noninteractive)
9814 if (m)
9816 if (noninteractive_need_newline)
9817 putc ('\n', stderr);
9818 noninteractive_need_newline = 0;
9819 fprintf (stderr, m, SDATA (string));
9820 if (!cursor_in_echo_area)
9821 fprintf (stderr, "\n");
9822 fflush (stderr);
9825 else if (INTERACTIVE)
9827 /* The frame whose minibuffer we're going to display the message on.
9828 It may be larger than the selected frame, so we need
9829 to use its buffer, not the selected frame's buffer. */
9830 Lisp_Object mini_window;
9831 struct frame *f, *sf = SELECTED_FRAME ();
9833 /* Get the frame containing the minibuffer
9834 that the selected frame is using. */
9835 mini_window = FRAME_MINIBUF_WINDOW (sf);
9836 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
9838 /* Error messages get reported properly by cmd_error, so this must be
9839 just an informative message; if the frame hasn't really been
9840 initialized yet, just toss it. */
9841 if (f->glyphs_initialized_p)
9843 Lisp_Object args[2], msg;
9844 struct gcpro gcpro1, gcpro2;
9846 args[0] = build_string (m);
9847 args[1] = msg = string;
9848 GCPRO2 (args[0], msg);
9849 gcpro1.nvars = 2;
9851 msg = Fformat (2, args);
9853 if (log)
9854 message3 (msg);
9855 else
9856 message3_nolog (msg);
9858 UNGCPRO;
9860 /* Print should start at the beginning of the message
9861 buffer next time. */
9862 message_buf_print = 0;
9868 /* Dump an informative message to the minibuf. If M is 0, clear out
9869 any existing message, and let the mini-buffer text show through. */
9871 static void
9872 vmessage (const char *m, va_list ap)
9874 if (noninteractive)
9876 if (m)
9878 if (noninteractive_need_newline)
9879 putc ('\n', stderr);
9880 noninteractive_need_newline = 0;
9881 vfprintf (stderr, m, ap);
9882 if (cursor_in_echo_area == 0)
9883 fprintf (stderr, "\n");
9884 fflush (stderr);
9887 else if (INTERACTIVE)
9889 /* The frame whose mini-buffer we're going to display the message
9890 on. It may be larger than the selected frame, so we need to
9891 use its buffer, not the selected frame's buffer. */
9892 Lisp_Object mini_window;
9893 struct frame *f, *sf = SELECTED_FRAME ();
9895 /* Get the frame containing the mini-buffer
9896 that the selected frame is using. */
9897 mini_window = FRAME_MINIBUF_WINDOW (sf);
9898 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
9900 /* Error messages get reported properly by cmd_error, so this must be
9901 just an informative message; if the frame hasn't really been
9902 initialized yet, just toss it. */
9903 if (f->glyphs_initialized_p)
9905 if (m)
9907 ptrdiff_t len;
9908 ptrdiff_t maxsize = FRAME_MESSAGE_BUF_SIZE (f);
9909 char *message_buf = alloca (maxsize + 1);
9911 len = doprnt (message_buf, maxsize, m, 0, ap);
9913 message3 (make_string (message_buf, len));
9915 else
9916 message1 (0);
9918 /* Print should start at the beginning of the message
9919 buffer next time. */
9920 message_buf_print = 0;
9925 void
9926 message (const char *m, ...)
9928 va_list ap;
9929 va_start (ap, m);
9930 vmessage (m, ap);
9931 va_end (ap);
9935 #if 0
9936 /* The non-logging version of message. */
9938 void
9939 message_nolog (const char *m, ...)
9941 Lisp_Object old_log_max;
9942 va_list ap;
9943 va_start (ap, m);
9944 old_log_max = Vmessage_log_max;
9945 Vmessage_log_max = Qnil;
9946 vmessage (m, ap);
9947 Vmessage_log_max = old_log_max;
9948 va_end (ap);
9950 #endif
9953 /* Display the current message in the current mini-buffer. This is
9954 only called from error handlers in process.c, and is not time
9955 critical. */
9957 void
9958 update_echo_area (void)
9960 if (!NILP (echo_area_buffer[0]))
9962 Lisp_Object string;
9963 string = Fcurrent_message ();
9964 message3 (string);
9969 /* Make sure echo area buffers in `echo_buffers' are live.
9970 If they aren't, make new ones. */
9972 static void
9973 ensure_echo_area_buffers (void)
9975 int i;
9977 for (i = 0; i < 2; ++i)
9978 if (!BUFFERP (echo_buffer[i])
9979 || !BUFFER_LIVE_P (XBUFFER (echo_buffer[i])))
9981 char name[30];
9982 Lisp_Object old_buffer;
9983 int j;
9985 old_buffer = echo_buffer[i];
9986 echo_buffer[i] = Fget_buffer_create
9987 (make_formatted_string (name, " *Echo Area %d*", i));
9988 bset_truncate_lines (XBUFFER (echo_buffer[i]), Qnil);
9989 /* to force word wrap in echo area -
9990 it was decided to postpone this*/
9991 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
9993 for (j = 0; j < 2; ++j)
9994 if (EQ (old_buffer, echo_area_buffer[j]))
9995 echo_area_buffer[j] = echo_buffer[i];
10000 /* Call FN with args A1..A2 with either the current or last displayed
10001 echo_area_buffer as current buffer.
10003 WHICH zero means use the current message buffer
10004 echo_area_buffer[0]. If that is nil, choose a suitable buffer
10005 from echo_buffer[] and clear it.
10007 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
10008 suitable buffer from echo_buffer[] and clear it.
10010 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
10011 that the current message becomes the last displayed one, make
10012 choose a suitable buffer for echo_area_buffer[0], and clear it.
10014 Value is what FN returns. */
10016 static int
10017 with_echo_area_buffer (struct window *w, int which,
10018 int (*fn) (ptrdiff_t, Lisp_Object),
10019 ptrdiff_t a1, Lisp_Object a2)
10021 Lisp_Object buffer;
10022 int this_one, the_other, clear_buffer_p, rc;
10023 ptrdiff_t count = SPECPDL_INDEX ();
10025 /* If buffers aren't live, make new ones. */
10026 ensure_echo_area_buffers ();
10028 clear_buffer_p = 0;
10030 if (which == 0)
10031 this_one = 0, the_other = 1;
10032 else if (which > 0)
10033 this_one = 1, the_other = 0;
10034 else
10036 this_one = 0, the_other = 1;
10037 clear_buffer_p = 1;
10039 /* We need a fresh one in case the current echo buffer equals
10040 the one containing the last displayed echo area message. */
10041 if (!NILP (echo_area_buffer[this_one])
10042 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
10043 echo_area_buffer[this_one] = Qnil;
10046 /* Choose a suitable buffer from echo_buffer[] is we don't
10047 have one. */
10048 if (NILP (echo_area_buffer[this_one]))
10050 echo_area_buffer[this_one]
10051 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
10052 ? echo_buffer[the_other]
10053 : echo_buffer[this_one]);
10054 clear_buffer_p = 1;
10057 buffer = echo_area_buffer[this_one];
10059 /* Don't get confused by reusing the buffer used for echoing
10060 for a different purpose. */
10061 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
10062 cancel_echoing ();
10064 record_unwind_protect (unwind_with_echo_area_buffer,
10065 with_echo_area_buffer_unwind_data (w));
10067 /* Make the echo area buffer current. Note that for display
10068 purposes, it is not necessary that the displayed window's buffer
10069 == current_buffer, except for text property lookup. So, let's
10070 only set that buffer temporarily here without doing a full
10071 Fset_window_buffer. We must also change w->pointm, though,
10072 because otherwise an assertions in unshow_buffer fails, and Emacs
10073 aborts. */
10074 set_buffer_internal_1 (XBUFFER (buffer));
10075 if (w)
10077 wset_buffer (w, buffer);
10078 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
10081 bset_undo_list (current_buffer, Qt);
10082 bset_read_only (current_buffer, Qnil);
10083 specbind (Qinhibit_read_only, Qt);
10084 specbind (Qinhibit_modification_hooks, Qt);
10086 if (clear_buffer_p && Z > BEG)
10087 del_range (BEG, Z);
10089 eassert (BEGV >= BEG);
10090 eassert (ZV <= Z && ZV >= BEGV);
10092 rc = fn (a1, a2);
10094 eassert (BEGV >= BEG);
10095 eassert (ZV <= Z && ZV >= BEGV);
10097 unbind_to (count, Qnil);
10098 return rc;
10102 /* Save state that should be preserved around the call to the function
10103 FN called in with_echo_area_buffer. */
10105 static Lisp_Object
10106 with_echo_area_buffer_unwind_data (struct window *w)
10108 int i = 0;
10109 Lisp_Object vector, tmp;
10111 /* Reduce consing by keeping one vector in
10112 Vwith_echo_area_save_vector. */
10113 vector = Vwith_echo_area_save_vector;
10114 Vwith_echo_area_save_vector = Qnil;
10116 if (NILP (vector))
10117 vector = Fmake_vector (make_number (9), Qnil);
10119 XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
10120 ASET (vector, i, Vdeactivate_mark); ++i;
10121 ASET (vector, i, make_number (windows_or_buffers_changed)); ++i;
10123 if (w)
10125 XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i;
10126 ASET (vector, i, w->contents); ++i;
10127 ASET (vector, i, make_number (marker_position (w->pointm))); ++i;
10128 ASET (vector, i, make_number (marker_byte_position (w->pointm))); ++i;
10129 ASET (vector, i, make_number (marker_position (w->start))); ++i;
10130 ASET (vector, i, make_number (marker_byte_position (w->start))); ++i;
10132 else
10134 int end = i + 6;
10135 for (; i < end; ++i)
10136 ASET (vector, i, Qnil);
10139 eassert (i == ASIZE (vector));
10140 return vector;
10144 /* Restore global state from VECTOR which was created by
10145 with_echo_area_buffer_unwind_data. */
10147 static void
10148 unwind_with_echo_area_buffer (Lisp_Object vector)
10150 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
10151 Vdeactivate_mark = AREF (vector, 1);
10152 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
10154 if (WINDOWP (AREF (vector, 3)))
10156 struct window *w;
10157 Lisp_Object buffer;
10159 w = XWINDOW (AREF (vector, 3));
10160 buffer = AREF (vector, 4);
10162 wset_buffer (w, buffer);
10163 set_marker_both (w->pointm, buffer,
10164 XFASTINT (AREF (vector, 5)),
10165 XFASTINT (AREF (vector, 6)));
10166 set_marker_both (w->start, buffer,
10167 XFASTINT (AREF (vector, 7)),
10168 XFASTINT (AREF (vector, 8)));
10171 Vwith_echo_area_save_vector = vector;
10175 /* Set up the echo area for use by print functions. MULTIBYTE_P
10176 non-zero means we will print multibyte. */
10178 void
10179 setup_echo_area_for_printing (int multibyte_p)
10181 /* If we can't find an echo area any more, exit. */
10182 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
10183 Fkill_emacs (Qnil);
10185 ensure_echo_area_buffers ();
10187 if (!message_buf_print)
10189 /* A message has been output since the last time we printed.
10190 Choose a fresh echo area buffer. */
10191 if (EQ (echo_area_buffer[1], echo_buffer[0]))
10192 echo_area_buffer[0] = echo_buffer[1];
10193 else
10194 echo_area_buffer[0] = echo_buffer[0];
10196 /* Switch to that buffer and clear it. */
10197 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
10198 bset_truncate_lines (current_buffer, Qnil);
10200 if (Z > BEG)
10202 ptrdiff_t count = SPECPDL_INDEX ();
10203 specbind (Qinhibit_read_only, Qt);
10204 /* Note that undo recording is always disabled. */
10205 del_range (BEG, Z);
10206 unbind_to (count, Qnil);
10208 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
10210 /* Set up the buffer for the multibyteness we need. */
10211 if (multibyte_p
10212 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
10213 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
10215 /* Raise the frame containing the echo area. */
10216 if (minibuffer_auto_raise)
10218 struct frame *sf = SELECTED_FRAME ();
10219 Lisp_Object mini_window;
10220 mini_window = FRAME_MINIBUF_WINDOW (sf);
10221 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
10224 message_log_maybe_newline ();
10225 message_buf_print = 1;
10227 else
10229 if (NILP (echo_area_buffer[0]))
10231 if (EQ (echo_area_buffer[1], echo_buffer[0]))
10232 echo_area_buffer[0] = echo_buffer[1];
10233 else
10234 echo_area_buffer[0] = echo_buffer[0];
10237 if (current_buffer != XBUFFER (echo_area_buffer[0]))
10239 /* Someone switched buffers between print requests. */
10240 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
10241 bset_truncate_lines (current_buffer, Qnil);
10247 /* Display an echo area message in window W. Value is non-zero if W's
10248 height is changed. If display_last_displayed_message_p is
10249 non-zero, display the message that was last displayed, otherwise
10250 display the current message. */
10252 static int
10253 display_echo_area (struct window *w)
10255 int i, no_message_p, window_height_changed_p;
10257 /* Temporarily disable garbage collections while displaying the echo
10258 area. This is done because a GC can print a message itself.
10259 That message would modify the echo area buffer's contents while a
10260 redisplay of the buffer is going on, and seriously confuse
10261 redisplay. */
10262 ptrdiff_t count = inhibit_garbage_collection ();
10264 /* If there is no message, we must call display_echo_area_1
10265 nevertheless because it resizes the window. But we will have to
10266 reset the echo_area_buffer in question to nil at the end because
10267 with_echo_area_buffer will sets it to an empty buffer. */
10268 i = display_last_displayed_message_p ? 1 : 0;
10269 no_message_p = NILP (echo_area_buffer[i]);
10271 window_height_changed_p
10272 = with_echo_area_buffer (w, display_last_displayed_message_p,
10273 display_echo_area_1,
10274 (intptr_t) w, Qnil);
10276 if (no_message_p)
10277 echo_area_buffer[i] = Qnil;
10279 unbind_to (count, Qnil);
10280 return window_height_changed_p;
10284 /* Helper for display_echo_area. Display the current buffer which
10285 contains the current echo area message in window W, a mini-window,
10286 a pointer to which is passed in A1. A2..A4 are currently not used.
10287 Change the height of W so that all of the message is displayed.
10288 Value is non-zero if height of W was changed. */
10290 static int
10291 display_echo_area_1 (ptrdiff_t a1, Lisp_Object a2)
10293 intptr_t i1 = a1;
10294 struct window *w = (struct window *) i1;
10295 Lisp_Object window;
10296 struct text_pos start;
10297 int window_height_changed_p = 0;
10299 /* Do this before displaying, so that we have a large enough glyph
10300 matrix for the display. If we can't get enough space for the
10301 whole text, display the last N lines. That works by setting w->start. */
10302 window_height_changed_p = resize_mini_window (w, 0);
10304 /* Use the starting position chosen by resize_mini_window. */
10305 SET_TEXT_POS_FROM_MARKER (start, w->start);
10307 /* Display. */
10308 clear_glyph_matrix (w->desired_matrix);
10309 XSETWINDOW (window, w);
10310 try_window (window, start, 0);
10312 return window_height_changed_p;
10316 /* Resize the echo area window to exactly the size needed for the
10317 currently displayed message, if there is one. If a mini-buffer
10318 is active, don't shrink it. */
10320 void
10321 resize_echo_area_exactly (void)
10323 if (BUFFERP (echo_area_buffer[0])
10324 && WINDOWP (echo_area_window))
10326 struct window *w = XWINDOW (echo_area_window);
10327 int resized_p;
10328 Lisp_Object resize_exactly;
10330 if (minibuf_level == 0)
10331 resize_exactly = Qt;
10332 else
10333 resize_exactly = Qnil;
10335 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
10336 (intptr_t) w, resize_exactly);
10337 if (resized_p)
10339 ++windows_or_buffers_changed;
10340 ++update_mode_lines;
10341 redisplay_internal ();
10347 /* Callback function for with_echo_area_buffer, when used from
10348 resize_echo_area_exactly. A1 contains a pointer to the window to
10349 resize, EXACTLY non-nil means resize the mini-window exactly to the
10350 size of the text displayed. A3 and A4 are not used. Value is what
10351 resize_mini_window returns. */
10353 static int
10354 resize_mini_window_1 (ptrdiff_t a1, Lisp_Object exactly)
10356 intptr_t i1 = a1;
10357 return resize_mini_window ((struct window *) i1, !NILP (exactly));
10361 /* Resize mini-window W to fit the size of its contents. EXACT_P
10362 means size the window exactly to the size needed. Otherwise, it's
10363 only enlarged until W's buffer is empty.
10365 Set W->start to the right place to begin display. If the whole
10366 contents fit, start at the beginning. Otherwise, start so as
10367 to make the end of the contents appear. This is particularly
10368 important for y-or-n-p, but seems desirable generally.
10370 Value is non-zero if the window height has been changed. */
10373 resize_mini_window (struct window *w, int exact_p)
10375 struct frame *f = XFRAME (w->frame);
10376 int window_height_changed_p = 0;
10378 eassert (MINI_WINDOW_P (w));
10380 /* By default, start display at the beginning. */
10381 set_marker_both (w->start, w->contents,
10382 BUF_BEGV (XBUFFER (w->contents)),
10383 BUF_BEGV_BYTE (XBUFFER (w->contents)));
10385 /* Don't resize windows while redisplaying a window; it would
10386 confuse redisplay functions when the size of the window they are
10387 displaying changes from under them. Such a resizing can happen,
10388 for instance, when which-func prints a long message while
10389 we are running fontification-functions. We're running these
10390 functions with safe_call which binds inhibit-redisplay to t. */
10391 if (!NILP (Vinhibit_redisplay))
10392 return 0;
10394 /* Nil means don't try to resize. */
10395 if (NILP (Vresize_mini_windows)
10396 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
10397 return 0;
10399 if (!FRAME_MINIBUF_ONLY_P (f))
10401 struct it it;
10402 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
10403 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
10404 int height;
10405 EMACS_INT max_height;
10406 int unit = FRAME_LINE_HEIGHT (f);
10407 struct text_pos start;
10408 struct buffer *old_current_buffer = NULL;
10410 if (current_buffer != XBUFFER (w->contents))
10412 old_current_buffer = current_buffer;
10413 set_buffer_internal (XBUFFER (w->contents));
10416 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
10418 /* Compute the max. number of lines specified by the user. */
10419 if (FLOATP (Vmax_mini_window_height))
10420 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
10421 else if (INTEGERP (Vmax_mini_window_height))
10422 max_height = XINT (Vmax_mini_window_height);
10423 else
10424 max_height = total_height / 4;
10426 /* Correct that max. height if it's bogus. */
10427 max_height = clip_to_bounds (1, max_height, total_height);
10429 /* Find out the height of the text in the window. */
10430 if (it.line_wrap == TRUNCATE)
10431 height = 1;
10432 else
10434 last_height = 0;
10435 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
10436 if (it.max_ascent == 0 && it.max_descent == 0)
10437 height = it.current_y + last_height;
10438 else
10439 height = it.current_y + it.max_ascent + it.max_descent;
10440 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
10441 height = (height + unit - 1) / unit;
10444 /* Compute a suitable window start. */
10445 if (height > max_height)
10447 height = max_height;
10448 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
10449 move_it_vertically_backward (&it, (height - 1) * unit);
10450 start = it.current.pos;
10452 else
10453 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
10454 SET_MARKER_FROM_TEXT_POS (w->start, start);
10456 if (EQ (Vresize_mini_windows, Qgrow_only))
10458 /* Let it grow only, until we display an empty message, in which
10459 case the window shrinks again. */
10460 if (height > WINDOW_TOTAL_LINES (w))
10462 int old_height = WINDOW_TOTAL_LINES (w);
10464 FRAME_WINDOWS_FROZEN (f) = 1;
10465 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10466 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10468 else if (height < WINDOW_TOTAL_LINES (w)
10469 && (exact_p || BEGV == ZV))
10471 int old_height = WINDOW_TOTAL_LINES (w);
10473 FRAME_WINDOWS_FROZEN (f) = 0;
10474 shrink_mini_window (w);
10475 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10478 else
10480 /* Always resize to exact size needed. */
10481 if (height > WINDOW_TOTAL_LINES (w))
10483 int old_height = WINDOW_TOTAL_LINES (w);
10485 FRAME_WINDOWS_FROZEN (f) = 1;
10486 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10487 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10489 else if (height < WINDOW_TOTAL_LINES (w))
10491 int old_height = WINDOW_TOTAL_LINES (w);
10493 FRAME_WINDOWS_FROZEN (f) = 0;
10494 shrink_mini_window (w);
10496 if (height)
10498 FRAME_WINDOWS_FROZEN (f) = 1;
10499 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10502 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10506 if (old_current_buffer)
10507 set_buffer_internal (old_current_buffer);
10510 return window_height_changed_p;
10514 /* Value is the current message, a string, or nil if there is no
10515 current message. */
10517 Lisp_Object
10518 current_message (void)
10520 Lisp_Object msg;
10522 if (!BUFFERP (echo_area_buffer[0]))
10523 msg = Qnil;
10524 else
10526 with_echo_area_buffer (0, 0, current_message_1,
10527 (intptr_t) &msg, Qnil);
10528 if (NILP (msg))
10529 echo_area_buffer[0] = Qnil;
10532 return msg;
10536 static int
10537 current_message_1 (ptrdiff_t a1, Lisp_Object a2)
10539 intptr_t i1 = a1;
10540 Lisp_Object *msg = (Lisp_Object *) i1;
10542 if (Z > BEG)
10543 *msg = make_buffer_string (BEG, Z, 1);
10544 else
10545 *msg = Qnil;
10546 return 0;
10550 /* Push the current message on Vmessage_stack for later restoration
10551 by restore_message. Value is non-zero if the current message isn't
10552 empty. This is a relatively infrequent operation, so it's not
10553 worth optimizing. */
10555 bool
10556 push_message (void)
10558 Lisp_Object msg = current_message ();
10559 Vmessage_stack = Fcons (msg, Vmessage_stack);
10560 return STRINGP (msg);
10564 /* Restore message display from the top of Vmessage_stack. */
10566 void
10567 restore_message (void)
10569 eassert (CONSP (Vmessage_stack));
10570 message3_nolog (XCAR (Vmessage_stack));
10574 /* Handler for unwind-protect calling pop_message. */
10576 void
10577 pop_message_unwind (void)
10579 /* Pop the top-most entry off Vmessage_stack. */
10580 eassert (CONSP (Vmessage_stack));
10581 Vmessage_stack = XCDR (Vmessage_stack);
10585 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
10586 exits. If the stack is not empty, we have a missing pop_message
10587 somewhere. */
10589 void
10590 check_message_stack (void)
10592 if (!NILP (Vmessage_stack))
10593 emacs_abort ();
10597 /* Truncate to NCHARS what will be displayed in the echo area the next
10598 time we display it---but don't redisplay it now. */
10600 void
10601 truncate_echo_area (ptrdiff_t nchars)
10603 if (nchars == 0)
10604 echo_area_buffer[0] = Qnil;
10605 else if (!noninteractive
10606 && INTERACTIVE
10607 && !NILP (echo_area_buffer[0]))
10609 struct frame *sf = SELECTED_FRAME ();
10610 /* Error messages get reported properly by cmd_error, so this must be
10611 just an informative message; if the frame hasn't really been
10612 initialized yet, just toss it. */
10613 if (sf->glyphs_initialized_p)
10614 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil);
10619 /* Helper function for truncate_echo_area. Truncate the current
10620 message to at most NCHARS characters. */
10622 static int
10623 truncate_message_1 (ptrdiff_t nchars, Lisp_Object a2)
10625 if (BEG + nchars < Z)
10626 del_range (BEG + nchars, Z);
10627 if (Z == BEG)
10628 echo_area_buffer[0] = Qnil;
10629 return 0;
10632 /* Set the current message to STRING. */
10634 static void
10635 set_message (Lisp_Object string)
10637 eassert (STRINGP (string));
10639 message_enable_multibyte = STRING_MULTIBYTE (string);
10641 with_echo_area_buffer (0, -1, set_message_1, 0, string);
10642 message_buf_print = 0;
10643 help_echo_showing_p = 0;
10645 if (STRINGP (Vdebug_on_message)
10646 && STRINGP (string)
10647 && fast_string_match (Vdebug_on_message, string) >= 0)
10648 call_debugger (list2 (Qerror, string));
10652 /* Helper function for set_message. First argument is ignored and second
10653 argument has the same meaning as for set_message.
10654 This function is called with the echo area buffer being current. */
10656 static int
10657 set_message_1 (ptrdiff_t a1, Lisp_Object string)
10659 eassert (STRINGP (string));
10661 /* Change multibyteness of the echo buffer appropriately. */
10662 if (message_enable_multibyte
10663 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
10664 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
10666 bset_truncate_lines (current_buffer, message_truncate_lines ? Qt : Qnil);
10667 if (!NILP (BVAR (current_buffer, bidi_display_reordering)))
10668 bset_bidi_paragraph_direction (current_buffer, Qleft_to_right);
10670 /* Insert new message at BEG. */
10671 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
10673 /* This function takes care of single/multibyte conversion.
10674 We just have to ensure that the echo area buffer has the right
10675 setting of enable_multibyte_characters. */
10676 insert_from_string (string, 0, 0, SCHARS (string), SBYTES (string), 1);
10678 return 0;
10682 /* Clear messages. CURRENT_P non-zero means clear the current
10683 message. LAST_DISPLAYED_P non-zero means clear the message
10684 last displayed. */
10686 void
10687 clear_message (int current_p, int last_displayed_p)
10689 if (current_p)
10691 echo_area_buffer[0] = Qnil;
10692 message_cleared_p = 1;
10695 if (last_displayed_p)
10696 echo_area_buffer[1] = Qnil;
10698 message_buf_print = 0;
10701 /* Clear garbaged frames.
10703 This function is used where the old redisplay called
10704 redraw_garbaged_frames which in turn called redraw_frame which in
10705 turn called clear_frame. The call to clear_frame was a source of
10706 flickering. I believe a clear_frame is not necessary. It should
10707 suffice in the new redisplay to invalidate all current matrices,
10708 and ensure a complete redisplay of all windows. */
10710 static void
10711 clear_garbaged_frames (void)
10713 if (frame_garbaged)
10715 Lisp_Object tail, frame;
10716 int changed_count = 0;
10718 FOR_EACH_FRAME (tail, frame)
10720 struct frame *f = XFRAME (frame);
10722 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
10724 if (f->resized_p)
10726 redraw_frame (f);
10727 f->force_flush_display_p = 1;
10729 clear_current_matrices (f);
10730 changed_count++;
10731 f->garbaged = 0;
10732 f->resized_p = 0;
10736 frame_garbaged = 0;
10737 if (changed_count)
10738 ++windows_or_buffers_changed;
10743 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
10744 is non-zero update selected_frame. Value is non-zero if the
10745 mini-windows height has been changed. */
10747 static int
10748 echo_area_display (int update_frame_p)
10750 Lisp_Object mini_window;
10751 struct window *w;
10752 struct frame *f;
10753 int window_height_changed_p = 0;
10754 struct frame *sf = SELECTED_FRAME ();
10756 mini_window = FRAME_MINIBUF_WINDOW (sf);
10757 w = XWINDOW (mini_window);
10758 f = XFRAME (WINDOW_FRAME (w));
10760 /* Don't display if frame is invisible or not yet initialized. */
10761 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
10762 return 0;
10764 #ifdef HAVE_WINDOW_SYSTEM
10765 /* When Emacs starts, selected_frame may be the initial terminal
10766 frame. If we let this through, a message would be displayed on
10767 the terminal. */
10768 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
10769 return 0;
10770 #endif /* HAVE_WINDOW_SYSTEM */
10772 /* Redraw garbaged frames. */
10773 clear_garbaged_frames ();
10775 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
10777 echo_area_window = mini_window;
10778 window_height_changed_p = display_echo_area (w);
10779 w->must_be_updated_p = 1;
10781 /* Update the display, unless called from redisplay_internal.
10782 Also don't update the screen during redisplay itself. The
10783 update will happen at the end of redisplay, and an update
10784 here could cause confusion. */
10785 if (update_frame_p && !redisplaying_p)
10787 int n = 0;
10789 /* If the display update has been interrupted by pending
10790 input, update mode lines in the frame. Due to the
10791 pending input, it might have been that redisplay hasn't
10792 been called, so that mode lines above the echo area are
10793 garbaged. This looks odd, so we prevent it here. */
10794 if (!display_completed)
10795 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
10797 if (window_height_changed_p
10798 /* Don't do this if Emacs is shutting down. Redisplay
10799 needs to run hooks. */
10800 && !NILP (Vrun_hooks))
10802 /* Must update other windows. Likewise as in other
10803 cases, don't let this update be interrupted by
10804 pending input. */
10805 ptrdiff_t count = SPECPDL_INDEX ();
10806 specbind (Qredisplay_dont_pause, Qt);
10807 windows_or_buffers_changed = 1;
10808 redisplay_internal ();
10809 unbind_to (count, Qnil);
10811 else if (FRAME_WINDOW_P (f) && n == 0)
10813 /* Window configuration is the same as before.
10814 Can do with a display update of the echo area,
10815 unless we displayed some mode lines. */
10816 update_single_window (w, 1);
10817 FRAME_RIF (f)->flush_display (f);
10819 else
10820 update_frame (f, 1, 1);
10822 /* If cursor is in the echo area, make sure that the next
10823 redisplay displays the minibuffer, so that the cursor will
10824 be replaced with what the minibuffer wants. */
10825 if (cursor_in_echo_area)
10826 ++windows_or_buffers_changed;
10829 else if (!EQ (mini_window, selected_window))
10830 windows_or_buffers_changed++;
10832 /* Last displayed message is now the current message. */
10833 echo_area_buffer[1] = echo_area_buffer[0];
10834 /* Inform read_char that we're not echoing. */
10835 echo_message_buffer = Qnil;
10837 /* Prevent redisplay optimization in redisplay_internal by resetting
10838 this_line_start_pos. This is done because the mini-buffer now
10839 displays the message instead of its buffer text. */
10840 if (EQ (mini_window, selected_window))
10841 CHARPOS (this_line_start_pos) = 0;
10843 return window_height_changed_p;
10846 /* Nonzero if the current window's buffer is shown in more than one
10847 window and was modified since last redisplay. */
10849 static int
10850 buffer_shared_and_changed (void)
10852 return (buffer_window_count (current_buffer) > 1
10853 && UNCHANGED_MODIFIED < MODIFF);
10856 /* Nonzero if W's buffer was changed but not saved or Transient Mark mode
10857 is enabled and mark of W's buffer was changed since last W's update. */
10859 static int
10860 window_buffer_changed (struct window *w)
10862 struct buffer *b = XBUFFER (w->contents);
10864 eassert (BUFFER_LIVE_P (b));
10866 return (((BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) != w->last_had_star)
10867 || ((!NILP (Vtransient_mark_mode) && !NILP (BVAR (b, mark_active)))
10868 != (w->region_showing != 0)));
10871 /* Nonzero if W has %c in its mode line and mode line should be updated. */
10873 static int
10874 mode_line_update_needed (struct window *w)
10876 return (w->column_number_displayed != -1
10877 && !(PT == w->last_point && !window_outdated (w))
10878 && (w->column_number_displayed != current_column ()));
10881 /* Nonzero if window start of W is frozen and may not be changed during
10882 redisplay. */
10884 static bool
10885 window_frozen_p (struct window *w)
10887 if (FRAME_WINDOWS_FROZEN (XFRAME (WINDOW_FRAME (w))))
10889 Lisp_Object window;
10891 XSETWINDOW (window, w);
10892 if (MINI_WINDOW_P (w))
10893 return 0;
10894 else if (EQ (window, selected_window))
10895 return 0;
10896 else if (MINI_WINDOW_P (XWINDOW (selected_window))
10897 && EQ (window, Vminibuf_scroll_window))
10898 /* This special window can't be frozen too. */
10899 return 0;
10900 else
10901 return 1;
10903 return 0;
10906 /***********************************************************************
10907 Mode Lines and Frame Titles
10908 ***********************************************************************/
10910 /* A buffer for constructing non-propertized mode-line strings and
10911 frame titles in it; allocated from the heap in init_xdisp and
10912 resized as needed in store_mode_line_noprop_char. */
10914 static char *mode_line_noprop_buf;
10916 /* The buffer's end, and a current output position in it. */
10918 static char *mode_line_noprop_buf_end;
10919 static char *mode_line_noprop_ptr;
10921 #define MODE_LINE_NOPROP_LEN(start) \
10922 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
10924 static enum {
10925 MODE_LINE_DISPLAY = 0,
10926 MODE_LINE_TITLE,
10927 MODE_LINE_NOPROP,
10928 MODE_LINE_STRING
10929 } mode_line_target;
10931 /* Alist that caches the results of :propertize.
10932 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
10933 static Lisp_Object mode_line_proptrans_alist;
10935 /* List of strings making up the mode-line. */
10936 static Lisp_Object mode_line_string_list;
10938 /* Base face property when building propertized mode line string. */
10939 static Lisp_Object mode_line_string_face;
10940 static Lisp_Object mode_line_string_face_prop;
10943 /* Unwind data for mode line strings */
10945 static Lisp_Object Vmode_line_unwind_vector;
10947 static Lisp_Object
10948 format_mode_line_unwind_data (struct frame *target_frame,
10949 struct buffer *obuf,
10950 Lisp_Object owin,
10951 int save_proptrans)
10953 Lisp_Object vector, tmp;
10955 /* Reduce consing by keeping one vector in
10956 Vwith_echo_area_save_vector. */
10957 vector = Vmode_line_unwind_vector;
10958 Vmode_line_unwind_vector = Qnil;
10960 if (NILP (vector))
10961 vector = Fmake_vector (make_number (10), Qnil);
10963 ASET (vector, 0, make_number (mode_line_target));
10964 ASET (vector, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
10965 ASET (vector, 2, mode_line_string_list);
10966 ASET (vector, 3, save_proptrans ? mode_line_proptrans_alist : Qt);
10967 ASET (vector, 4, mode_line_string_face);
10968 ASET (vector, 5, mode_line_string_face_prop);
10970 if (obuf)
10971 XSETBUFFER (tmp, obuf);
10972 else
10973 tmp = Qnil;
10974 ASET (vector, 6, tmp);
10975 ASET (vector, 7, owin);
10976 if (target_frame)
10978 /* Similarly to `with-selected-window', if the operation selects
10979 a window on another frame, we must restore that frame's
10980 selected window, and (for a tty) the top-frame. */
10981 ASET (vector, 8, target_frame->selected_window);
10982 if (FRAME_TERMCAP_P (target_frame))
10983 ASET (vector, 9, FRAME_TTY (target_frame)->top_frame);
10986 return vector;
10989 static void
10990 unwind_format_mode_line (Lisp_Object vector)
10992 Lisp_Object old_window = AREF (vector, 7);
10993 Lisp_Object target_frame_window = AREF (vector, 8);
10994 Lisp_Object old_top_frame = AREF (vector, 9);
10996 mode_line_target = XINT (AREF (vector, 0));
10997 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
10998 mode_line_string_list = AREF (vector, 2);
10999 if (! EQ (AREF (vector, 3), Qt))
11000 mode_line_proptrans_alist = AREF (vector, 3);
11001 mode_line_string_face = AREF (vector, 4);
11002 mode_line_string_face_prop = AREF (vector, 5);
11004 /* Select window before buffer, since it may change the buffer. */
11005 if (!NILP (old_window))
11007 /* If the operation that we are unwinding had selected a window
11008 on a different frame, reset its frame-selected-window. For a
11009 text terminal, reset its top-frame if necessary. */
11010 if (!NILP (target_frame_window))
11012 Lisp_Object frame
11013 = WINDOW_FRAME (XWINDOW (target_frame_window));
11015 if (!EQ (frame, WINDOW_FRAME (XWINDOW (old_window))))
11016 Fselect_window (target_frame_window, Qt);
11018 if (!NILP (old_top_frame) && !EQ (old_top_frame, frame))
11019 Fselect_frame (old_top_frame, Qt);
11022 Fselect_window (old_window, Qt);
11025 if (!NILP (AREF (vector, 6)))
11027 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
11028 ASET (vector, 6, Qnil);
11031 Vmode_line_unwind_vector = vector;
11035 /* Store a single character C for the frame title in mode_line_noprop_buf.
11036 Re-allocate mode_line_noprop_buf if necessary. */
11038 static void
11039 store_mode_line_noprop_char (char c)
11041 /* If output position has reached the end of the allocated buffer,
11042 increase the buffer's size. */
11043 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
11045 ptrdiff_t len = MODE_LINE_NOPROP_LEN (0);
11046 ptrdiff_t size = len;
11047 mode_line_noprop_buf =
11048 xpalloc (mode_line_noprop_buf, &size, 1, STRING_BYTES_BOUND, 1);
11049 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
11050 mode_line_noprop_ptr = mode_line_noprop_buf + len;
11053 *mode_line_noprop_ptr++ = c;
11057 /* Store part of a frame title in mode_line_noprop_buf, beginning at
11058 mode_line_noprop_ptr. STRING is the string to store. Do not copy
11059 characters that yield more columns than PRECISION; PRECISION <= 0
11060 means copy the whole string. Pad with spaces until FIELD_WIDTH
11061 number of characters have been copied; FIELD_WIDTH <= 0 means don't
11062 pad. Called from display_mode_element when it is used to build a
11063 frame title. */
11065 static int
11066 store_mode_line_noprop (const char *string, int field_width, int precision)
11068 const unsigned char *str = (const unsigned char *) string;
11069 int n = 0;
11070 ptrdiff_t dummy, nbytes;
11072 /* Copy at most PRECISION chars from STR. */
11073 nbytes = strlen (string);
11074 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
11075 while (nbytes--)
11076 store_mode_line_noprop_char (*str++);
11078 /* Fill up with spaces until FIELD_WIDTH reached. */
11079 while (field_width > 0
11080 && n < field_width)
11082 store_mode_line_noprop_char (' ');
11083 ++n;
11086 return n;
11089 /***********************************************************************
11090 Frame Titles
11091 ***********************************************************************/
11093 #ifdef HAVE_WINDOW_SYSTEM
11095 /* Set the title of FRAME, if it has changed. The title format is
11096 Vicon_title_format if FRAME is iconified, otherwise it is
11097 frame_title_format. */
11099 static void
11100 x_consider_frame_title (Lisp_Object frame)
11102 struct frame *f = XFRAME (frame);
11104 if (FRAME_WINDOW_P (f)
11105 || FRAME_MINIBUF_ONLY_P (f)
11106 || f->explicit_name)
11108 /* Do we have more than one visible frame on this X display? */
11109 Lisp_Object tail, other_frame, fmt;
11110 ptrdiff_t title_start;
11111 char *title;
11112 ptrdiff_t len;
11113 struct it it;
11114 ptrdiff_t count = SPECPDL_INDEX ();
11116 FOR_EACH_FRAME (tail, other_frame)
11118 struct frame *tf = XFRAME (other_frame);
11120 if (tf != f
11121 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
11122 && !FRAME_MINIBUF_ONLY_P (tf)
11123 && !EQ (other_frame, tip_frame)
11124 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
11125 break;
11128 /* Set global variable indicating that multiple frames exist. */
11129 multiple_frames = CONSP (tail);
11131 /* Switch to the buffer of selected window of the frame. Set up
11132 mode_line_target so that display_mode_element will output into
11133 mode_line_noprop_buf; then display the title. */
11134 record_unwind_protect (unwind_format_mode_line,
11135 format_mode_line_unwind_data
11136 (f, current_buffer, selected_window, 0));
11138 Fselect_window (f->selected_window, Qt);
11139 set_buffer_internal_1
11140 (XBUFFER (XWINDOW (f->selected_window)->contents));
11141 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
11143 mode_line_target = MODE_LINE_TITLE;
11144 title_start = MODE_LINE_NOPROP_LEN (0);
11145 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
11146 NULL, DEFAULT_FACE_ID);
11147 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
11148 len = MODE_LINE_NOPROP_LEN (title_start);
11149 title = mode_line_noprop_buf + title_start;
11150 unbind_to (count, Qnil);
11152 /* Set the title only if it's changed. This avoids consing in
11153 the common case where it hasn't. (If it turns out that we've
11154 already wasted too much time by walking through the list with
11155 display_mode_element, then we might need to optimize at a
11156 higher level than this.) */
11157 if (! STRINGP (f->name)
11158 || SBYTES (f->name) != len
11159 || memcmp (title, SDATA (f->name), len) != 0)
11160 x_implicitly_set_name (f, make_string (title, len), Qnil);
11164 #endif /* not HAVE_WINDOW_SYSTEM */
11167 /***********************************************************************
11168 Menu Bars
11169 ***********************************************************************/
11172 /* Prepare for redisplay by updating menu-bar item lists when
11173 appropriate. This can call eval. */
11175 void
11176 prepare_menu_bars (void)
11178 int all_windows;
11179 struct gcpro gcpro1, gcpro2;
11180 struct frame *f;
11181 Lisp_Object tooltip_frame;
11183 #ifdef HAVE_WINDOW_SYSTEM
11184 tooltip_frame = tip_frame;
11185 #else
11186 tooltip_frame = Qnil;
11187 #endif
11189 /* Update all frame titles based on their buffer names, etc. We do
11190 this before the menu bars so that the buffer-menu will show the
11191 up-to-date frame titles. */
11192 #ifdef HAVE_WINDOW_SYSTEM
11193 if (windows_or_buffers_changed || update_mode_lines)
11195 Lisp_Object tail, frame;
11197 FOR_EACH_FRAME (tail, frame)
11199 f = XFRAME (frame);
11200 if (!EQ (frame, tooltip_frame)
11201 && (FRAME_ICONIFIED_P (f)
11202 || FRAME_VISIBLE_P (f) == 1
11203 /* Exclude TTY frames that are obscured because they
11204 are not the top frame on their console. This is
11205 because x_consider_frame_title actually switches
11206 to the frame, which for TTY frames means it is
11207 marked as garbaged, and will be completely
11208 redrawn on the next redisplay cycle. This causes
11209 TTY frames to be completely redrawn, when there
11210 are more than one of them, even though nothing
11211 should be changed on display. */
11212 || (FRAME_VISIBLE_P (f) == 2 && FRAME_WINDOW_P (f))))
11213 x_consider_frame_title (frame);
11216 #endif /* HAVE_WINDOW_SYSTEM */
11218 /* Update the menu bar item lists, if appropriate. This has to be
11219 done before any actual redisplay or generation of display lines. */
11220 all_windows = (update_mode_lines
11221 || buffer_shared_and_changed ()
11222 || windows_or_buffers_changed);
11223 if (all_windows)
11225 Lisp_Object tail, frame;
11226 ptrdiff_t count = SPECPDL_INDEX ();
11227 /* 1 means that update_menu_bar has run its hooks
11228 so any further calls to update_menu_bar shouldn't do so again. */
11229 int menu_bar_hooks_run = 0;
11231 record_unwind_save_match_data ();
11233 FOR_EACH_FRAME (tail, frame)
11235 f = XFRAME (frame);
11237 /* Ignore tooltip frame. */
11238 if (EQ (frame, tooltip_frame))
11239 continue;
11241 /* If a window on this frame changed size, report that to
11242 the user and clear the size-change flag. */
11243 if (FRAME_WINDOW_SIZES_CHANGED (f))
11245 Lisp_Object functions;
11247 /* Clear flag first in case we get an error below. */
11248 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
11249 functions = Vwindow_size_change_functions;
11250 GCPRO2 (tail, functions);
11252 while (CONSP (functions))
11254 if (!EQ (XCAR (functions), Qt))
11255 call1 (XCAR (functions), frame);
11256 functions = XCDR (functions);
11258 UNGCPRO;
11261 GCPRO1 (tail);
11262 menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
11263 #ifdef HAVE_WINDOW_SYSTEM
11264 update_tool_bar (f, 0);
11265 #endif
11266 #ifdef HAVE_NS
11267 if (windows_or_buffers_changed
11268 && FRAME_NS_P (f))
11269 ns_set_doc_edited
11270 (f, Fbuffer_modified_p (XWINDOW (f->selected_window)->contents));
11271 #endif
11272 UNGCPRO;
11275 unbind_to (count, Qnil);
11277 else
11279 struct frame *sf = SELECTED_FRAME ();
11280 update_menu_bar (sf, 1, 0);
11281 #ifdef HAVE_WINDOW_SYSTEM
11282 update_tool_bar (sf, 1);
11283 #endif
11288 /* Update the menu bar item list for frame F. This has to be done
11289 before we start to fill in any display lines, because it can call
11290 eval.
11292 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
11294 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
11295 already ran the menu bar hooks for this redisplay, so there
11296 is no need to run them again. The return value is the
11297 updated value of this flag, to pass to the next call. */
11299 static int
11300 update_menu_bar (struct frame *f, int save_match_data, int hooks_run)
11302 Lisp_Object window;
11303 register struct window *w;
11305 /* If called recursively during a menu update, do nothing. This can
11306 happen when, for instance, an activate-menubar-hook causes a
11307 redisplay. */
11308 if (inhibit_menubar_update)
11309 return hooks_run;
11311 window = FRAME_SELECTED_WINDOW (f);
11312 w = XWINDOW (window);
11314 if (FRAME_WINDOW_P (f)
11316 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11317 || defined (HAVE_NS) || defined (USE_GTK)
11318 FRAME_EXTERNAL_MENU_BAR (f)
11319 #else
11320 FRAME_MENU_BAR_LINES (f) > 0
11321 #endif
11322 : FRAME_MENU_BAR_LINES (f) > 0)
11324 /* If the user has switched buffers or windows, we need to
11325 recompute to reflect the new bindings. But we'll
11326 recompute when update_mode_lines is set too; that means
11327 that people can use force-mode-line-update to request
11328 that the menu bar be recomputed. The adverse effect on
11329 the rest of the redisplay algorithm is about the same as
11330 windows_or_buffers_changed anyway. */
11331 if (windows_or_buffers_changed
11332 /* This used to test w->update_mode_line, but we believe
11333 there is no need to recompute the menu in that case. */
11334 || update_mode_lines
11335 || window_buffer_changed (w))
11337 struct buffer *prev = current_buffer;
11338 ptrdiff_t count = SPECPDL_INDEX ();
11340 specbind (Qinhibit_menubar_update, Qt);
11342 set_buffer_internal_1 (XBUFFER (w->contents));
11343 if (save_match_data)
11344 record_unwind_save_match_data ();
11345 if (NILP (Voverriding_local_map_menu_flag))
11347 specbind (Qoverriding_terminal_local_map, Qnil);
11348 specbind (Qoverriding_local_map, Qnil);
11351 if (!hooks_run)
11353 /* Run the Lucid hook. */
11354 safe_run_hooks (Qactivate_menubar_hook);
11356 /* If it has changed current-menubar from previous value,
11357 really recompute the menu-bar from the value. */
11358 if (! NILP (Vlucid_menu_bar_dirty_flag))
11359 call0 (Qrecompute_lucid_menubar);
11361 safe_run_hooks (Qmenu_bar_update_hook);
11363 hooks_run = 1;
11366 XSETFRAME (Vmenu_updating_frame, f);
11367 fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f)));
11369 /* Redisplay the menu bar in case we changed it. */
11370 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11371 || defined (HAVE_NS) || defined (USE_GTK)
11372 if (FRAME_WINDOW_P (f))
11374 #if defined (HAVE_NS)
11375 /* All frames on Mac OS share the same menubar. So only
11376 the selected frame should be allowed to set it. */
11377 if (f == SELECTED_FRAME ())
11378 #endif
11379 set_frame_menubar (f, 0, 0);
11381 else
11382 /* On a terminal screen, the menu bar is an ordinary screen
11383 line, and this makes it get updated. */
11384 w->update_mode_line = 1;
11385 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11386 /* In the non-toolkit version, the menu bar is an ordinary screen
11387 line, and this makes it get updated. */
11388 w->update_mode_line = 1;
11389 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11391 unbind_to (count, Qnil);
11392 set_buffer_internal_1 (prev);
11396 return hooks_run;
11401 /***********************************************************************
11402 Output Cursor
11403 ***********************************************************************/
11405 #ifdef HAVE_WINDOW_SYSTEM
11407 /* EXPORT:
11408 Nominal cursor position -- where to draw output.
11409 HPOS and VPOS are window relative glyph matrix coordinates.
11410 X and Y are window relative pixel coordinates. */
11412 struct cursor_pos output_cursor;
11415 /* EXPORT:
11416 Set the global variable output_cursor to CURSOR. All cursor
11417 positions are relative to currently updated window. */
11419 void
11420 set_output_cursor (struct cursor_pos *cursor)
11422 output_cursor.hpos = cursor->hpos;
11423 output_cursor.vpos = cursor->vpos;
11424 output_cursor.x = cursor->x;
11425 output_cursor.y = cursor->y;
11429 /* EXPORT for RIF:
11430 Set a nominal cursor position.
11432 HPOS and VPOS are column/row positions in a window glyph matrix.
11433 X and Y are window text area relative pixel positions.
11435 This is always done during window update, so the position is the
11436 future output cursor position for currently updated window W.
11437 NOTE: W is used only to check whether this function is called
11438 in a consistent manner via the redisplay interface. */
11440 void
11441 x_cursor_to (struct window *w, int vpos, int hpos, int y, int x)
11443 eassert (w);
11445 /* Set the output cursor. */
11446 output_cursor.hpos = hpos;
11447 output_cursor.vpos = vpos;
11448 output_cursor.x = x;
11449 output_cursor.y = y;
11452 #endif /* HAVE_WINDOW_SYSTEM */
11455 /***********************************************************************
11456 Tool-bars
11457 ***********************************************************************/
11459 #ifdef HAVE_WINDOW_SYSTEM
11461 /* Where the mouse was last time we reported a mouse event. */
11463 struct frame *last_mouse_frame;
11465 /* Tool-bar item index of the item on which a mouse button was pressed
11466 or -1. */
11468 int last_tool_bar_item;
11470 /* Select `frame' temporarily without running all the code in
11471 do_switch_frame.
11472 FIXME: Maybe do_switch_frame should be trimmed down similarly
11473 when `norecord' is set. */
11474 static void
11475 fast_set_selected_frame (Lisp_Object frame)
11477 if (!EQ (selected_frame, frame))
11479 selected_frame = frame;
11480 selected_window = XFRAME (frame)->selected_window;
11484 /* Update the tool-bar item list for frame F. This has to be done
11485 before we start to fill in any display lines. Called from
11486 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
11487 and restore it here. */
11489 static void
11490 update_tool_bar (struct frame *f, int save_match_data)
11492 #if defined (USE_GTK) || defined (HAVE_NS)
11493 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
11494 #else
11495 int do_update = WINDOWP (f->tool_bar_window)
11496 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
11497 #endif
11499 if (do_update)
11501 Lisp_Object window;
11502 struct window *w;
11504 window = FRAME_SELECTED_WINDOW (f);
11505 w = XWINDOW (window);
11507 /* If the user has switched buffers or windows, we need to
11508 recompute to reflect the new bindings. But we'll
11509 recompute when update_mode_lines is set too; that means
11510 that people can use force-mode-line-update to request
11511 that the menu bar be recomputed. The adverse effect on
11512 the rest of the redisplay algorithm is about the same as
11513 windows_or_buffers_changed anyway. */
11514 if (windows_or_buffers_changed
11515 || w->update_mode_line
11516 || update_mode_lines
11517 || window_buffer_changed (w))
11519 struct buffer *prev = current_buffer;
11520 ptrdiff_t count = SPECPDL_INDEX ();
11521 Lisp_Object frame, new_tool_bar;
11522 int new_n_tool_bar;
11523 struct gcpro gcpro1;
11525 /* Set current_buffer to the buffer of the selected
11526 window of the frame, so that we get the right local
11527 keymaps. */
11528 set_buffer_internal_1 (XBUFFER (w->contents));
11530 /* Save match data, if we must. */
11531 if (save_match_data)
11532 record_unwind_save_match_data ();
11534 /* Make sure that we don't accidentally use bogus keymaps. */
11535 if (NILP (Voverriding_local_map_menu_flag))
11537 specbind (Qoverriding_terminal_local_map, Qnil);
11538 specbind (Qoverriding_local_map, Qnil);
11541 GCPRO1 (new_tool_bar);
11543 /* We must temporarily set the selected frame to this frame
11544 before calling tool_bar_items, because the calculation of
11545 the tool-bar keymap uses the selected frame (see
11546 `tool-bar-make-keymap' in tool-bar.el). */
11547 eassert (EQ (selected_window,
11548 /* Since we only explicitly preserve selected_frame,
11549 check that selected_window would be redundant. */
11550 XFRAME (selected_frame)->selected_window));
11551 record_unwind_protect (fast_set_selected_frame, selected_frame);
11552 XSETFRAME (frame, f);
11553 fast_set_selected_frame (frame);
11555 /* Build desired tool-bar items from keymaps. */
11556 new_tool_bar
11557 = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
11558 &new_n_tool_bar);
11560 /* Redisplay the tool-bar if we changed it. */
11561 if (new_n_tool_bar != f->n_tool_bar_items
11562 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
11564 /* Redisplay that happens asynchronously due to an expose event
11565 may access f->tool_bar_items. Make sure we update both
11566 variables within BLOCK_INPUT so no such event interrupts. */
11567 block_input ();
11568 fset_tool_bar_items (f, new_tool_bar);
11569 f->n_tool_bar_items = new_n_tool_bar;
11570 w->update_mode_line = 1;
11571 unblock_input ();
11574 UNGCPRO;
11576 unbind_to (count, Qnil);
11577 set_buffer_internal_1 (prev);
11583 /* Set F->desired_tool_bar_string to a Lisp string representing frame
11584 F's desired tool-bar contents. F->tool_bar_items must have
11585 been set up previously by calling prepare_menu_bars. */
11587 static void
11588 build_desired_tool_bar_string (struct frame *f)
11590 int i, size, size_needed;
11591 struct gcpro gcpro1, gcpro2, gcpro3;
11592 Lisp_Object image, plist, props;
11594 image = plist = props = Qnil;
11595 GCPRO3 (image, plist, props);
11597 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
11598 Otherwise, make a new string. */
11600 /* The size of the string we might be able to reuse. */
11601 size = (STRINGP (f->desired_tool_bar_string)
11602 ? SCHARS (f->desired_tool_bar_string)
11603 : 0);
11605 /* We need one space in the string for each image. */
11606 size_needed = f->n_tool_bar_items;
11608 /* Reuse f->desired_tool_bar_string, if possible. */
11609 if (size < size_needed || NILP (f->desired_tool_bar_string))
11610 fset_desired_tool_bar_string
11611 (f, Fmake_string (make_number (size_needed), make_number (' ')));
11612 else
11614 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
11615 Fremove_text_properties (make_number (0), make_number (size),
11616 props, f->desired_tool_bar_string);
11619 /* Put a `display' property on the string for the images to display,
11620 put a `menu_item' property on tool-bar items with a value that
11621 is the index of the item in F's tool-bar item vector. */
11622 for (i = 0; i < f->n_tool_bar_items; ++i)
11624 #define PROP(IDX) \
11625 AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
11627 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
11628 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
11629 int hmargin, vmargin, relief, idx, end;
11631 /* If image is a vector, choose the image according to the
11632 button state. */
11633 image = PROP (TOOL_BAR_ITEM_IMAGES);
11634 if (VECTORP (image))
11636 if (enabled_p)
11637 idx = (selected_p
11638 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
11639 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
11640 else
11641 idx = (selected_p
11642 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
11643 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
11645 eassert (ASIZE (image) >= idx);
11646 image = AREF (image, idx);
11648 else
11649 idx = -1;
11651 /* Ignore invalid image specifications. */
11652 if (!valid_image_p (image))
11653 continue;
11655 /* Display the tool-bar button pressed, or depressed. */
11656 plist = Fcopy_sequence (XCDR (image));
11658 /* Compute margin and relief to draw. */
11659 relief = (tool_bar_button_relief >= 0
11660 ? tool_bar_button_relief
11661 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
11662 hmargin = vmargin = relief;
11664 if (RANGED_INTEGERP (1, Vtool_bar_button_margin,
11665 INT_MAX - max (hmargin, vmargin)))
11667 hmargin += XFASTINT (Vtool_bar_button_margin);
11668 vmargin += XFASTINT (Vtool_bar_button_margin);
11670 else if (CONSP (Vtool_bar_button_margin))
11672 if (RANGED_INTEGERP (1, XCAR (Vtool_bar_button_margin),
11673 INT_MAX - hmargin))
11674 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
11676 if (RANGED_INTEGERP (1, XCDR (Vtool_bar_button_margin),
11677 INT_MAX - vmargin))
11678 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
11681 if (auto_raise_tool_bar_buttons_p)
11683 /* Add a `:relief' property to the image spec if the item is
11684 selected. */
11685 if (selected_p)
11687 plist = Fplist_put (plist, QCrelief, make_number (-relief));
11688 hmargin -= relief;
11689 vmargin -= relief;
11692 else
11694 /* If image is selected, display it pressed, i.e. with a
11695 negative relief. If it's not selected, display it with a
11696 raised relief. */
11697 plist = Fplist_put (plist, QCrelief,
11698 (selected_p
11699 ? make_number (-relief)
11700 : make_number (relief)));
11701 hmargin -= relief;
11702 vmargin -= relief;
11705 /* Put a margin around the image. */
11706 if (hmargin || vmargin)
11708 if (hmargin == vmargin)
11709 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
11710 else
11711 plist = Fplist_put (plist, QCmargin,
11712 Fcons (make_number (hmargin),
11713 make_number (vmargin)));
11716 /* If button is not enabled, and we don't have special images
11717 for the disabled state, make the image appear disabled by
11718 applying an appropriate algorithm to it. */
11719 if (!enabled_p && idx < 0)
11720 plist = Fplist_put (plist, QCconversion, Qdisabled);
11722 /* Put a `display' text property on the string for the image to
11723 display. Put a `menu-item' property on the string that gives
11724 the start of this item's properties in the tool-bar items
11725 vector. */
11726 image = Fcons (Qimage, plist);
11727 props = list4 (Qdisplay, image,
11728 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
11730 /* Let the last image hide all remaining spaces in the tool bar
11731 string. The string can be longer than needed when we reuse a
11732 previous string. */
11733 if (i + 1 == f->n_tool_bar_items)
11734 end = SCHARS (f->desired_tool_bar_string);
11735 else
11736 end = i + 1;
11737 Fadd_text_properties (make_number (i), make_number (end),
11738 props, f->desired_tool_bar_string);
11739 #undef PROP
11742 UNGCPRO;
11746 /* Display one line of the tool-bar of frame IT->f.
11748 HEIGHT specifies the desired height of the tool-bar line.
11749 If the actual height of the glyph row is less than HEIGHT, the
11750 row's height is increased to HEIGHT, and the icons are centered
11751 vertically in the new height.
11753 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
11754 count a final empty row in case the tool-bar width exactly matches
11755 the window width.
11758 static void
11759 display_tool_bar_line (struct it *it, int height)
11761 struct glyph_row *row = it->glyph_row;
11762 int max_x = it->last_visible_x;
11763 struct glyph *last;
11765 prepare_desired_row (row);
11766 row->y = it->current_y;
11768 /* Note that this isn't made use of if the face hasn't a box,
11769 so there's no need to check the face here. */
11770 it->start_of_box_run_p = 1;
11772 while (it->current_x < max_x)
11774 int x, n_glyphs_before, i, nglyphs;
11775 struct it it_before;
11777 /* Get the next display element. */
11778 if (!get_next_display_element (it))
11780 /* Don't count empty row if we are counting needed tool-bar lines. */
11781 if (height < 0 && !it->hpos)
11782 return;
11783 break;
11786 /* Produce glyphs. */
11787 n_glyphs_before = row->used[TEXT_AREA];
11788 it_before = *it;
11790 PRODUCE_GLYPHS (it);
11792 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
11793 i = 0;
11794 x = it_before.current_x;
11795 while (i < nglyphs)
11797 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
11799 if (x + glyph->pixel_width > max_x)
11801 /* Glyph doesn't fit on line. Backtrack. */
11802 row->used[TEXT_AREA] = n_glyphs_before;
11803 *it = it_before;
11804 /* If this is the only glyph on this line, it will never fit on the
11805 tool-bar, so skip it. But ensure there is at least one glyph,
11806 so we don't accidentally disable the tool-bar. */
11807 if (n_glyphs_before == 0
11808 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
11809 break;
11810 goto out;
11813 ++it->hpos;
11814 x += glyph->pixel_width;
11815 ++i;
11818 /* Stop at line end. */
11819 if (ITERATOR_AT_END_OF_LINE_P (it))
11820 break;
11822 set_iterator_to_next (it, 1);
11825 out:;
11827 row->displays_text_p = row->used[TEXT_AREA] != 0;
11829 /* Use default face for the border below the tool bar.
11831 FIXME: When auto-resize-tool-bars is grow-only, there is
11832 no additional border below the possibly empty tool-bar lines.
11833 So to make the extra empty lines look "normal", we have to
11834 use the tool-bar face for the border too. */
11835 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
11836 && !EQ (Vauto_resize_tool_bars, Qgrow_only))
11837 it->face_id = DEFAULT_FACE_ID;
11839 extend_face_to_end_of_line (it);
11840 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
11841 last->right_box_line_p = 1;
11842 if (last == row->glyphs[TEXT_AREA])
11843 last->left_box_line_p = 1;
11845 /* Make line the desired height and center it vertically. */
11846 if ((height -= it->max_ascent + it->max_descent) > 0)
11848 /* Don't add more than one line height. */
11849 height %= FRAME_LINE_HEIGHT (it->f);
11850 it->max_ascent += height / 2;
11851 it->max_descent += (height + 1) / 2;
11854 compute_line_metrics (it);
11856 /* If line is empty, make it occupy the rest of the tool-bar. */
11857 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row))
11859 row->height = row->phys_height = it->last_visible_y - row->y;
11860 row->visible_height = row->height;
11861 row->ascent = row->phys_ascent = 0;
11862 row->extra_line_spacing = 0;
11865 row->full_width_p = 1;
11866 row->continued_p = 0;
11867 row->truncated_on_left_p = 0;
11868 row->truncated_on_right_p = 0;
11870 it->current_x = it->hpos = 0;
11871 it->current_y += row->height;
11872 ++it->vpos;
11873 ++it->glyph_row;
11877 /* Max tool-bar height. */
11879 #define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
11880 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
11882 /* Value is the number of screen lines needed to make all tool-bar
11883 items of frame F visible. The number of actual rows needed is
11884 returned in *N_ROWS if non-NULL. */
11886 static int
11887 tool_bar_lines_needed (struct frame *f, int *n_rows)
11889 struct window *w = XWINDOW (f->tool_bar_window);
11890 struct it it;
11891 /* tool_bar_lines_needed is called from redisplay_tool_bar after building
11892 the desired matrix, so use (unused) mode-line row as temporary row to
11893 avoid destroying the first tool-bar row. */
11894 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
11896 /* Initialize an iterator for iteration over
11897 F->desired_tool_bar_string in the tool-bar window of frame F. */
11898 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
11899 it.first_visible_x = 0;
11900 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
11901 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
11902 it.paragraph_embedding = L2R;
11904 while (!ITERATOR_AT_END_P (&it))
11906 clear_glyph_row (temp_row);
11907 it.glyph_row = temp_row;
11908 display_tool_bar_line (&it, -1);
11910 clear_glyph_row (temp_row);
11912 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
11913 if (n_rows)
11914 *n_rows = it.vpos > 0 ? it.vpos : -1;
11916 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
11920 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
11921 0, 1, 0,
11922 doc: /* Return the number of lines occupied by the tool bar of FRAME.
11923 If FRAME is nil or omitted, use the selected frame. */)
11924 (Lisp_Object frame)
11926 struct frame *f = decode_any_frame (frame);
11927 struct window *w;
11928 int nlines = 0;
11930 if (WINDOWP (f->tool_bar_window)
11931 && (w = XWINDOW (f->tool_bar_window),
11932 WINDOW_TOTAL_LINES (w) > 0))
11934 update_tool_bar (f, 1);
11935 if (f->n_tool_bar_items)
11937 build_desired_tool_bar_string (f);
11938 nlines = tool_bar_lines_needed (f, NULL);
11942 return make_number (nlines);
11946 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
11947 height should be changed. */
11949 static int
11950 redisplay_tool_bar (struct frame *f)
11952 struct window *w;
11953 struct it it;
11954 struct glyph_row *row;
11956 #if defined (USE_GTK) || defined (HAVE_NS)
11957 if (FRAME_EXTERNAL_TOOL_BAR (f))
11958 update_frame_tool_bar (f);
11959 return 0;
11960 #endif
11962 /* If frame hasn't a tool-bar window or if it is zero-height, don't
11963 do anything. This means you must start with tool-bar-lines
11964 non-zero to get the auto-sizing effect. Or in other words, you
11965 can turn off tool-bars by specifying tool-bar-lines zero. */
11966 if (!WINDOWP (f->tool_bar_window)
11967 || (w = XWINDOW (f->tool_bar_window),
11968 WINDOW_TOTAL_LINES (w) == 0))
11969 return 0;
11971 /* Set up an iterator for the tool-bar window. */
11972 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
11973 it.first_visible_x = 0;
11974 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
11975 row = it.glyph_row;
11977 /* Build a string that represents the contents of the tool-bar. */
11978 build_desired_tool_bar_string (f);
11979 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
11980 /* FIXME: This should be controlled by a user option. But it
11981 doesn't make sense to have an R2L tool bar if the menu bar cannot
11982 be drawn also R2L, and making the menu bar R2L is tricky due
11983 toolkit-specific code that implements it. If an R2L tool bar is
11984 ever supported, display_tool_bar_line should also be augmented to
11985 call unproduce_glyphs like display_line and display_string
11986 do. */
11987 it.paragraph_embedding = L2R;
11989 if (f->n_tool_bar_rows == 0)
11991 int nlines;
11993 if ((nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
11994 nlines != WINDOW_TOTAL_LINES (w)))
11996 Lisp_Object frame;
11997 int old_height = WINDOW_TOTAL_LINES (w);
11999 XSETFRAME (frame, f);
12000 Fmodify_frame_parameters (frame,
12001 list1 (Fcons (Qtool_bar_lines,
12002 make_number (nlines))));
12003 if (WINDOW_TOTAL_LINES (w) != old_height)
12005 clear_glyph_matrix (w->desired_matrix);
12006 fonts_changed_p = 1;
12007 return 1;
12012 /* Display as many lines as needed to display all tool-bar items. */
12014 if (f->n_tool_bar_rows > 0)
12016 int border, rows, height, extra;
12018 if (TYPE_RANGED_INTEGERP (int, Vtool_bar_border))
12019 border = XINT (Vtool_bar_border);
12020 else if (EQ (Vtool_bar_border, Qinternal_border_width))
12021 border = FRAME_INTERNAL_BORDER_WIDTH (f);
12022 else if (EQ (Vtool_bar_border, Qborder_width))
12023 border = f->border_width;
12024 else
12025 border = 0;
12026 if (border < 0)
12027 border = 0;
12029 rows = f->n_tool_bar_rows;
12030 height = max (1, (it.last_visible_y - border) / rows);
12031 extra = it.last_visible_y - border - height * rows;
12033 while (it.current_y < it.last_visible_y)
12035 int h = 0;
12036 if (extra > 0 && rows-- > 0)
12038 h = (extra + rows - 1) / rows;
12039 extra -= h;
12041 display_tool_bar_line (&it, height + h);
12044 else
12046 while (it.current_y < it.last_visible_y)
12047 display_tool_bar_line (&it, 0);
12050 /* It doesn't make much sense to try scrolling in the tool-bar
12051 window, so don't do it. */
12052 w->desired_matrix->no_scrolling_p = 1;
12053 w->must_be_updated_p = 1;
12055 if (!NILP (Vauto_resize_tool_bars))
12057 int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
12058 int change_height_p = 0;
12060 /* If we couldn't display everything, change the tool-bar's
12061 height if there is room for more. */
12062 if (IT_STRING_CHARPOS (it) < it.end_charpos
12063 && it.current_y < max_tool_bar_height)
12064 change_height_p = 1;
12066 row = it.glyph_row - 1;
12068 /* If there are blank lines at the end, except for a partially
12069 visible blank line at the end that is smaller than
12070 FRAME_LINE_HEIGHT, change the tool-bar's height. */
12071 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
12072 && row->height >= FRAME_LINE_HEIGHT (f))
12073 change_height_p = 1;
12075 /* If row displays tool-bar items, but is partially visible,
12076 change the tool-bar's height. */
12077 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12078 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y
12079 && MATRIX_ROW_BOTTOM_Y (row) < max_tool_bar_height)
12080 change_height_p = 1;
12082 /* Resize windows as needed by changing the `tool-bar-lines'
12083 frame parameter. */
12084 if (change_height_p)
12086 Lisp_Object frame;
12087 int old_height = WINDOW_TOTAL_LINES (w);
12088 int nrows;
12089 int nlines = tool_bar_lines_needed (f, &nrows);
12091 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
12092 && !f->minimize_tool_bar_window_p)
12093 ? (nlines > old_height)
12094 : (nlines != old_height));
12095 f->minimize_tool_bar_window_p = 0;
12097 if (change_height_p)
12099 XSETFRAME (frame, f);
12100 Fmodify_frame_parameters (frame,
12101 list1 (Fcons (Qtool_bar_lines,
12102 make_number (nlines))));
12103 if (WINDOW_TOTAL_LINES (w) != old_height)
12105 clear_glyph_matrix (w->desired_matrix);
12106 f->n_tool_bar_rows = nrows;
12107 fonts_changed_p = 1;
12108 return 1;
12114 f->minimize_tool_bar_window_p = 0;
12115 return 0;
12119 /* Get information about the tool-bar item which is displayed in GLYPH
12120 on frame F. Return in *PROP_IDX the index where tool-bar item
12121 properties start in F->tool_bar_items. Value is zero if
12122 GLYPH doesn't display a tool-bar item. */
12124 static int
12125 tool_bar_item_info (struct frame *f, struct glyph *glyph, int *prop_idx)
12127 Lisp_Object prop;
12128 int success_p;
12129 int charpos;
12131 /* This function can be called asynchronously, which means we must
12132 exclude any possibility that Fget_text_property signals an
12133 error. */
12134 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
12135 charpos = max (0, charpos);
12137 /* Get the text property `menu-item' at pos. The value of that
12138 property is the start index of this item's properties in
12139 F->tool_bar_items. */
12140 prop = Fget_text_property (make_number (charpos),
12141 Qmenu_item, f->current_tool_bar_string);
12142 if (INTEGERP (prop))
12144 *prop_idx = XINT (prop);
12145 success_p = 1;
12147 else
12148 success_p = 0;
12150 return success_p;
12154 /* Get information about the tool-bar item at position X/Y on frame F.
12155 Return in *GLYPH a pointer to the glyph of the tool-bar item in
12156 the current matrix of the tool-bar window of F, or NULL if not
12157 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
12158 item in F->tool_bar_items. Value is
12160 -1 if X/Y is not on a tool-bar item
12161 0 if X/Y is on the same item that was highlighted before.
12162 1 otherwise. */
12164 static int
12165 get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
12166 int *hpos, int *vpos, int *prop_idx)
12168 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12169 struct window *w = XWINDOW (f->tool_bar_window);
12170 int area;
12172 /* Find the glyph under X/Y. */
12173 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
12174 if (*glyph == NULL)
12175 return -1;
12177 /* Get the start of this tool-bar item's properties in
12178 f->tool_bar_items. */
12179 if (!tool_bar_item_info (f, *glyph, prop_idx))
12180 return -1;
12182 /* Is mouse on the highlighted item? */
12183 if (EQ (f->tool_bar_window, hlinfo->mouse_face_window)
12184 && *vpos >= hlinfo->mouse_face_beg_row
12185 && *vpos <= hlinfo->mouse_face_end_row
12186 && (*vpos > hlinfo->mouse_face_beg_row
12187 || *hpos >= hlinfo->mouse_face_beg_col)
12188 && (*vpos < hlinfo->mouse_face_end_row
12189 || *hpos < hlinfo->mouse_face_end_col
12190 || hlinfo->mouse_face_past_end))
12191 return 0;
12193 return 1;
12197 /* EXPORT:
12198 Handle mouse button event on the tool-bar of frame F, at
12199 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
12200 0 for button release. MODIFIERS is event modifiers for button
12201 release. */
12203 void
12204 handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
12205 int modifiers)
12207 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12208 struct window *w = XWINDOW (f->tool_bar_window);
12209 int hpos, vpos, prop_idx;
12210 struct glyph *glyph;
12211 Lisp_Object enabled_p;
12212 int ts;
12214 /* If not on the highlighted tool-bar item, and mouse-highlight is
12215 non-nil, return. This is so we generate the tool-bar button
12216 click only when the mouse button is released on the same item as
12217 where it was pressed. However, when mouse-highlight is disabled,
12218 generate the click when the button is released regardless of the
12219 highlight, since tool-bar items are not highlighted in that
12220 case. */
12221 frame_to_window_pixel_xy (w, &x, &y);
12222 ts = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
12223 if (ts == -1
12224 || (ts != 0 && !NILP (Vmouse_highlight)))
12225 return;
12227 /* When mouse-highlight is off, generate the click for the item
12228 where the button was pressed, disregarding where it was
12229 released. */
12230 if (NILP (Vmouse_highlight) && !down_p)
12231 prop_idx = last_tool_bar_item;
12233 /* If item is disabled, do nothing. */
12234 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
12235 if (NILP (enabled_p))
12236 return;
12238 if (down_p)
12240 /* Show item in pressed state. */
12241 if (!NILP (Vmouse_highlight))
12242 show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN);
12243 last_tool_bar_item = prop_idx;
12245 else
12247 Lisp_Object key, frame;
12248 struct input_event event;
12249 EVENT_INIT (event);
12251 /* Show item in released state. */
12252 if (!NILP (Vmouse_highlight))
12253 show_mouse_face (hlinfo, DRAW_IMAGE_RAISED);
12255 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
12257 XSETFRAME (frame, f);
12258 event.kind = TOOL_BAR_EVENT;
12259 event.frame_or_window = frame;
12260 event.arg = frame;
12261 kbd_buffer_store_event (&event);
12263 event.kind = TOOL_BAR_EVENT;
12264 event.frame_or_window = frame;
12265 event.arg = key;
12266 event.modifiers = modifiers;
12267 kbd_buffer_store_event (&event);
12268 last_tool_bar_item = -1;
12273 /* Possibly highlight a tool-bar item on frame F when mouse moves to
12274 tool-bar window-relative coordinates X/Y. Called from
12275 note_mouse_highlight. */
12277 static void
12278 note_tool_bar_highlight (struct frame *f, int x, int y)
12280 Lisp_Object window = f->tool_bar_window;
12281 struct window *w = XWINDOW (window);
12282 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
12283 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12284 int hpos, vpos;
12285 struct glyph *glyph;
12286 struct glyph_row *row;
12287 int i;
12288 Lisp_Object enabled_p;
12289 int prop_idx;
12290 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
12291 int mouse_down_p, rc;
12293 /* Function note_mouse_highlight is called with negative X/Y
12294 values when mouse moves outside of the frame. */
12295 if (x <= 0 || y <= 0)
12297 clear_mouse_face (hlinfo);
12298 return;
12301 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
12302 if (rc < 0)
12304 /* Not on tool-bar item. */
12305 clear_mouse_face (hlinfo);
12306 return;
12308 else if (rc == 0)
12309 /* On same tool-bar item as before. */
12310 goto set_help_echo;
12312 clear_mouse_face (hlinfo);
12314 /* Mouse is down, but on different tool-bar item? */
12315 mouse_down_p = (dpyinfo->grabbed
12316 && f == last_mouse_frame
12317 && FRAME_LIVE_P (f));
12318 if (mouse_down_p
12319 && last_tool_bar_item != prop_idx)
12320 return;
12322 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
12324 /* If tool-bar item is not enabled, don't highlight it. */
12325 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
12326 if (!NILP (enabled_p) && !NILP (Vmouse_highlight))
12328 /* Compute the x-position of the glyph. In front and past the
12329 image is a space. We include this in the highlighted area. */
12330 row = MATRIX_ROW (w->current_matrix, vpos);
12331 for (i = x = 0; i < hpos; ++i)
12332 x += row->glyphs[TEXT_AREA][i].pixel_width;
12334 /* Record this as the current active region. */
12335 hlinfo->mouse_face_beg_col = hpos;
12336 hlinfo->mouse_face_beg_row = vpos;
12337 hlinfo->mouse_face_beg_x = x;
12338 hlinfo->mouse_face_beg_y = row->y;
12339 hlinfo->mouse_face_past_end = 0;
12341 hlinfo->mouse_face_end_col = hpos + 1;
12342 hlinfo->mouse_face_end_row = vpos;
12343 hlinfo->mouse_face_end_x = x + glyph->pixel_width;
12344 hlinfo->mouse_face_end_y = row->y;
12345 hlinfo->mouse_face_window = window;
12346 hlinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
12348 /* Display it as active. */
12349 show_mouse_face (hlinfo, draw);
12352 set_help_echo:
12354 /* Set help_echo_string to a help string to display for this tool-bar item.
12355 XTread_socket does the rest. */
12356 help_echo_object = help_echo_window = Qnil;
12357 help_echo_pos = -1;
12358 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
12359 if (NILP (help_echo_string))
12360 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
12363 #endif /* HAVE_WINDOW_SYSTEM */
12367 /************************************************************************
12368 Horizontal scrolling
12369 ************************************************************************/
12371 static int hscroll_window_tree (Lisp_Object);
12372 static int hscroll_windows (Lisp_Object);
12374 /* For all leaf windows in the window tree rooted at WINDOW, set their
12375 hscroll value so that PT is (i) visible in the window, and (ii) so
12376 that it is not within a certain margin at the window's left and
12377 right border. Value is non-zero if any window's hscroll has been
12378 changed. */
12380 static int
12381 hscroll_window_tree (Lisp_Object window)
12383 int hscrolled_p = 0;
12384 int hscroll_relative_p = FLOATP (Vhscroll_step);
12385 int hscroll_step_abs = 0;
12386 double hscroll_step_rel = 0;
12388 if (hscroll_relative_p)
12390 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
12391 if (hscroll_step_rel < 0)
12393 hscroll_relative_p = 0;
12394 hscroll_step_abs = 0;
12397 else if (TYPE_RANGED_INTEGERP (int, Vhscroll_step))
12399 hscroll_step_abs = XINT (Vhscroll_step);
12400 if (hscroll_step_abs < 0)
12401 hscroll_step_abs = 0;
12403 else
12404 hscroll_step_abs = 0;
12406 while (WINDOWP (window))
12408 struct window *w = XWINDOW (window);
12410 if (WINDOWP (w->contents))
12411 hscrolled_p |= hscroll_window_tree (w->contents);
12412 else if (w->cursor.vpos >= 0)
12414 int h_margin;
12415 int text_area_width;
12416 struct glyph_row *current_cursor_row
12417 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
12418 struct glyph_row *desired_cursor_row
12419 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
12420 struct glyph_row *cursor_row
12421 = (desired_cursor_row->enabled_p
12422 ? desired_cursor_row
12423 : current_cursor_row);
12424 int row_r2l_p = cursor_row->reversed_p;
12426 text_area_width = window_box_width (w, TEXT_AREA);
12428 /* Scroll when cursor is inside this scroll margin. */
12429 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
12431 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->contents))
12432 /* For left-to-right rows, hscroll when cursor is either
12433 (i) inside the right hscroll margin, or (ii) if it is
12434 inside the left margin and the window is already
12435 hscrolled. */
12436 && ((!row_r2l_p
12437 && ((w->hscroll
12438 && w->cursor.x <= h_margin)
12439 || (cursor_row->enabled_p
12440 && cursor_row->truncated_on_right_p
12441 && (w->cursor.x >= text_area_width - h_margin))))
12442 /* For right-to-left rows, the logic is similar,
12443 except that rules for scrolling to left and right
12444 are reversed. E.g., if cursor.x <= h_margin, we
12445 need to hscroll "to the right" unconditionally,
12446 and that will scroll the screen to the left so as
12447 to reveal the next portion of the row. */
12448 || (row_r2l_p
12449 && ((cursor_row->enabled_p
12450 /* FIXME: It is confusing to set the
12451 truncated_on_right_p flag when R2L rows
12452 are actually truncated on the left. */
12453 && cursor_row->truncated_on_right_p
12454 && w->cursor.x <= h_margin)
12455 || (w->hscroll
12456 && (w->cursor.x >= text_area_width - h_margin))))))
12458 struct it it;
12459 ptrdiff_t hscroll;
12460 struct buffer *saved_current_buffer;
12461 ptrdiff_t pt;
12462 int wanted_x;
12464 /* Find point in a display of infinite width. */
12465 saved_current_buffer = current_buffer;
12466 current_buffer = XBUFFER (w->contents);
12468 if (w == XWINDOW (selected_window))
12469 pt = PT;
12470 else
12471 pt = clip_to_bounds (BEGV, marker_position (w->pointm), ZV);
12473 /* Move iterator to pt starting at cursor_row->start in
12474 a line with infinite width. */
12475 init_to_row_start (&it, w, cursor_row);
12476 it.last_visible_x = INFINITY;
12477 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
12478 current_buffer = saved_current_buffer;
12480 /* Position cursor in window. */
12481 if (!hscroll_relative_p && hscroll_step_abs == 0)
12482 hscroll = max (0, (it.current_x
12483 - (ITERATOR_AT_END_OF_LINE_P (&it)
12484 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
12485 : (text_area_width / 2))))
12486 / FRAME_COLUMN_WIDTH (it.f);
12487 else if ((!row_r2l_p
12488 && w->cursor.x >= text_area_width - h_margin)
12489 || (row_r2l_p && w->cursor.x <= h_margin))
12491 if (hscroll_relative_p)
12492 wanted_x = text_area_width * (1 - hscroll_step_rel)
12493 - h_margin;
12494 else
12495 wanted_x = text_area_width
12496 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
12497 - h_margin;
12498 hscroll
12499 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
12501 else
12503 if (hscroll_relative_p)
12504 wanted_x = text_area_width * hscroll_step_rel
12505 + h_margin;
12506 else
12507 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
12508 + h_margin;
12509 hscroll
12510 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
12512 hscroll = max (hscroll, w->min_hscroll);
12514 /* Don't prevent redisplay optimizations if hscroll
12515 hasn't changed, as it will unnecessarily slow down
12516 redisplay. */
12517 if (w->hscroll != hscroll)
12519 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
12520 w->hscroll = hscroll;
12521 hscrolled_p = 1;
12526 window = w->next;
12529 /* Value is non-zero if hscroll of any leaf window has been changed. */
12530 return hscrolled_p;
12534 /* Set hscroll so that cursor is visible and not inside horizontal
12535 scroll margins for all windows in the tree rooted at WINDOW. See
12536 also hscroll_window_tree above. Value is non-zero if any window's
12537 hscroll has been changed. If it has, desired matrices on the frame
12538 of WINDOW are cleared. */
12540 static int
12541 hscroll_windows (Lisp_Object window)
12543 int hscrolled_p = hscroll_window_tree (window);
12544 if (hscrolled_p)
12545 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
12546 return hscrolled_p;
12551 /************************************************************************
12552 Redisplay
12553 ************************************************************************/
12555 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
12556 to a non-zero value. This is sometimes handy to have in a debugger
12557 session. */
12559 #ifdef GLYPH_DEBUG
12561 /* First and last unchanged row for try_window_id. */
12563 static int debug_first_unchanged_at_end_vpos;
12564 static int debug_last_unchanged_at_beg_vpos;
12566 /* Delta vpos and y. */
12568 static int debug_dvpos, debug_dy;
12570 /* Delta in characters and bytes for try_window_id. */
12572 static ptrdiff_t debug_delta, debug_delta_bytes;
12574 /* Values of window_end_pos and window_end_vpos at the end of
12575 try_window_id. */
12577 static ptrdiff_t debug_end_vpos;
12579 /* Append a string to W->desired_matrix->method. FMT is a printf
12580 format string. If trace_redisplay_p is non-zero also printf the
12581 resulting string to stderr. */
12583 static void debug_method_add (struct window *, char const *, ...)
12584 ATTRIBUTE_FORMAT_PRINTF (2, 3);
12586 static void
12587 debug_method_add (struct window *w, char const *fmt, ...)
12589 void *ptr = w;
12590 char *method = w->desired_matrix->method;
12591 int len = strlen (method);
12592 int size = sizeof w->desired_matrix->method;
12593 int remaining = size - len - 1;
12594 va_list ap;
12596 if (len && remaining)
12598 method[len] = '|';
12599 --remaining, ++len;
12602 va_start (ap, fmt);
12603 vsnprintf (method + len, remaining + 1, fmt, ap);
12604 va_end (ap);
12606 if (trace_redisplay_p)
12607 fprintf (stderr, "%p (%s): %s\n",
12608 ptr,
12609 ((BUFFERP (w->contents)
12610 && STRINGP (BVAR (XBUFFER (w->contents), name)))
12611 ? SSDATA (BVAR (XBUFFER (w->contents), name))
12612 : "no buffer"),
12613 method + len);
12616 #endif /* GLYPH_DEBUG */
12619 /* Value is non-zero if all changes in window W, which displays
12620 current_buffer, are in the text between START and END. START is a
12621 buffer position, END is given as a distance from Z. Used in
12622 redisplay_internal for display optimization. */
12624 static int
12625 text_outside_line_unchanged_p (struct window *w,
12626 ptrdiff_t start, ptrdiff_t end)
12628 int unchanged_p = 1;
12630 /* If text or overlays have changed, see where. */
12631 if (window_outdated (w))
12633 /* Gap in the line? */
12634 if (GPT < start || Z - GPT < end)
12635 unchanged_p = 0;
12637 /* Changes start in front of the line, or end after it? */
12638 if (unchanged_p
12639 && (BEG_UNCHANGED < start - 1
12640 || END_UNCHANGED < end))
12641 unchanged_p = 0;
12643 /* If selective display, can't optimize if changes start at the
12644 beginning of the line. */
12645 if (unchanged_p
12646 && INTEGERP (BVAR (current_buffer, selective_display))
12647 && XINT (BVAR (current_buffer, selective_display)) > 0
12648 && (BEG_UNCHANGED < start || GPT <= start))
12649 unchanged_p = 0;
12651 /* If there are overlays at the start or end of the line, these
12652 may have overlay strings with newlines in them. A change at
12653 START, for instance, may actually concern the display of such
12654 overlay strings as well, and they are displayed on different
12655 lines. So, quickly rule out this case. (For the future, it
12656 might be desirable to implement something more telling than
12657 just BEG/END_UNCHANGED.) */
12658 if (unchanged_p)
12660 if (BEG + BEG_UNCHANGED == start
12661 && overlay_touches_p (start))
12662 unchanged_p = 0;
12663 if (END_UNCHANGED == end
12664 && overlay_touches_p (Z - end))
12665 unchanged_p = 0;
12668 /* Under bidi reordering, adding or deleting a character in the
12669 beginning of a paragraph, before the first strong directional
12670 character, can change the base direction of the paragraph (unless
12671 the buffer specifies a fixed paragraph direction), which will
12672 require to redisplay the whole paragraph. It might be worthwhile
12673 to find the paragraph limits and widen the range of redisplayed
12674 lines to that, but for now just give up this optimization. */
12675 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
12676 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
12677 unchanged_p = 0;
12680 return unchanged_p;
12684 /* Do a frame update, taking possible shortcuts into account. This is
12685 the main external entry point for redisplay.
12687 If the last redisplay displayed an echo area message and that message
12688 is no longer requested, we clear the echo area or bring back the
12689 mini-buffer if that is in use. */
12691 void
12692 redisplay (void)
12694 redisplay_internal ();
12698 static Lisp_Object
12699 overlay_arrow_string_or_property (Lisp_Object var)
12701 Lisp_Object val;
12703 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
12704 return val;
12706 return Voverlay_arrow_string;
12709 /* Return 1 if there are any overlay-arrows in current_buffer. */
12710 static int
12711 overlay_arrow_in_current_buffer_p (void)
12713 Lisp_Object vlist;
12715 for (vlist = Voverlay_arrow_variable_list;
12716 CONSP (vlist);
12717 vlist = XCDR (vlist))
12719 Lisp_Object var = XCAR (vlist);
12720 Lisp_Object val;
12722 if (!SYMBOLP (var))
12723 continue;
12724 val = find_symbol_value (var);
12725 if (MARKERP (val)
12726 && current_buffer == XMARKER (val)->buffer)
12727 return 1;
12729 return 0;
12733 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
12734 has changed. */
12736 static int
12737 overlay_arrows_changed_p (void)
12739 Lisp_Object vlist;
12741 for (vlist = Voverlay_arrow_variable_list;
12742 CONSP (vlist);
12743 vlist = XCDR (vlist))
12745 Lisp_Object var = XCAR (vlist);
12746 Lisp_Object val, pstr;
12748 if (!SYMBOLP (var))
12749 continue;
12750 val = find_symbol_value (var);
12751 if (!MARKERP (val))
12752 continue;
12753 if (! EQ (COERCE_MARKER (val),
12754 Fget (var, Qlast_arrow_position))
12755 || ! (pstr = overlay_arrow_string_or_property (var),
12756 EQ (pstr, Fget (var, Qlast_arrow_string))))
12757 return 1;
12759 return 0;
12762 /* Mark overlay arrows to be updated on next redisplay. */
12764 static void
12765 update_overlay_arrows (int up_to_date)
12767 Lisp_Object vlist;
12769 for (vlist = Voverlay_arrow_variable_list;
12770 CONSP (vlist);
12771 vlist = XCDR (vlist))
12773 Lisp_Object var = XCAR (vlist);
12775 if (!SYMBOLP (var))
12776 continue;
12778 if (up_to_date > 0)
12780 Lisp_Object val = find_symbol_value (var);
12781 Fput (var, Qlast_arrow_position,
12782 COERCE_MARKER (val));
12783 Fput (var, Qlast_arrow_string,
12784 overlay_arrow_string_or_property (var));
12786 else if (up_to_date < 0
12787 || !NILP (Fget (var, Qlast_arrow_position)))
12789 Fput (var, Qlast_arrow_position, Qt);
12790 Fput (var, Qlast_arrow_string, Qt);
12796 /* Return overlay arrow string to display at row.
12797 Return integer (bitmap number) for arrow bitmap in left fringe.
12798 Return nil if no overlay arrow. */
12800 static Lisp_Object
12801 overlay_arrow_at_row (struct it *it, struct glyph_row *row)
12803 Lisp_Object vlist;
12805 for (vlist = Voverlay_arrow_variable_list;
12806 CONSP (vlist);
12807 vlist = XCDR (vlist))
12809 Lisp_Object var = XCAR (vlist);
12810 Lisp_Object val;
12812 if (!SYMBOLP (var))
12813 continue;
12815 val = find_symbol_value (var);
12817 if (MARKERP (val)
12818 && current_buffer == XMARKER (val)->buffer
12819 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
12821 if (FRAME_WINDOW_P (it->f)
12822 /* FIXME: if ROW->reversed_p is set, this should test
12823 the right fringe, not the left one. */
12824 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
12826 #ifdef HAVE_WINDOW_SYSTEM
12827 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
12829 int fringe_bitmap;
12830 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
12831 return make_number (fringe_bitmap);
12833 #endif
12834 return make_number (-1); /* Use default arrow bitmap. */
12836 return overlay_arrow_string_or_property (var);
12840 return Qnil;
12843 /* Return 1 if point moved out of or into a composition. Otherwise
12844 return 0. PREV_BUF and PREV_PT are the last point buffer and
12845 position. BUF and PT are the current point buffer and position. */
12847 static int
12848 check_point_in_composition (struct buffer *prev_buf, ptrdiff_t prev_pt,
12849 struct buffer *buf, ptrdiff_t pt)
12851 ptrdiff_t start, end;
12852 Lisp_Object prop;
12853 Lisp_Object buffer;
12855 XSETBUFFER (buffer, buf);
12856 /* Check a composition at the last point if point moved within the
12857 same buffer. */
12858 if (prev_buf == buf)
12860 if (prev_pt == pt)
12861 /* Point didn't move. */
12862 return 0;
12864 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
12865 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
12866 && composition_valid_p (start, end, prop)
12867 && start < prev_pt && end > prev_pt)
12868 /* The last point was within the composition. Return 1 iff
12869 point moved out of the composition. */
12870 return (pt <= start || pt >= end);
12873 /* Check a composition at the current point. */
12874 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
12875 && find_composition (pt, -1, &start, &end, &prop, buffer)
12876 && composition_valid_p (start, end, prop)
12877 && start < pt && end > pt);
12880 /* Reconsider the clip changes of buffer which is displayed in W. */
12882 static void
12883 reconsider_clip_changes (struct window *w)
12885 struct buffer *b = XBUFFER (w->contents);
12887 if (b->clip_changed
12888 && w->window_end_valid
12889 && w->current_matrix->buffer == b
12890 && w->current_matrix->zv == BUF_ZV (b)
12891 && w->current_matrix->begv == BUF_BEGV (b))
12892 b->clip_changed = 0;
12894 /* If display wasn't paused, and W is not a tool bar window, see if
12895 point has been moved into or out of a composition. In that case,
12896 we set b->clip_changed to 1 to force updating the screen. If
12897 b->clip_changed has already been set to 1, we can skip this
12898 check. */
12899 if (!b->clip_changed && w->window_end_valid)
12901 ptrdiff_t pt = (w == XWINDOW (selected_window)
12902 ? PT : marker_position (w->pointm));
12904 if ((w->current_matrix->buffer != b || pt != w->last_point)
12905 && check_point_in_composition (w->current_matrix->buffer,
12906 w->last_point, b, pt))
12907 b->clip_changed = 1;
12911 #define STOP_POLLING \
12912 do { if (! polling_stopped_here) stop_polling (); \
12913 polling_stopped_here = 1; } while (0)
12915 #define RESUME_POLLING \
12916 do { if (polling_stopped_here) start_polling (); \
12917 polling_stopped_here = 0; } while (0)
12920 /* Perhaps in the future avoid recentering windows if it
12921 is not necessary; currently that causes some problems. */
12923 static void
12924 redisplay_internal (void)
12926 struct window *w = XWINDOW (selected_window);
12927 struct window *sw;
12928 struct frame *fr;
12929 int pending;
12930 bool must_finish = 0, match_p;
12931 struct text_pos tlbufpos, tlendpos;
12932 int number_of_visible_frames;
12933 ptrdiff_t count;
12934 struct frame *sf;
12935 int polling_stopped_here = 0;
12936 Lisp_Object tail, frame;
12938 /* Non-zero means redisplay has to consider all windows on all
12939 frames. Zero means, only selected_window is considered. */
12940 int consider_all_windows_p;
12942 /* Non-zero means redisplay has to redisplay the miniwindow. */
12943 int update_miniwindow_p = 0;
12945 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
12947 /* No redisplay if running in batch mode or frame is not yet fully
12948 initialized, or redisplay is explicitly turned off by setting
12949 Vinhibit_redisplay. */
12950 if (FRAME_INITIAL_P (SELECTED_FRAME ())
12951 || !NILP (Vinhibit_redisplay))
12952 return;
12954 /* Don't examine these until after testing Vinhibit_redisplay.
12955 When Emacs is shutting down, perhaps because its connection to
12956 X has dropped, we should not look at them at all. */
12957 fr = XFRAME (w->frame);
12958 sf = SELECTED_FRAME ();
12960 if (!fr->glyphs_initialized_p)
12961 return;
12963 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
12964 if (popup_activated ())
12965 return;
12966 #endif
12968 /* I don't think this happens but let's be paranoid. */
12969 if (redisplaying_p)
12970 return;
12972 /* Record a function that clears redisplaying_p
12973 when we leave this function. */
12974 count = SPECPDL_INDEX ();
12975 record_unwind_protect_void (unwind_redisplay);
12976 redisplaying_p = 1;
12977 specbind (Qinhibit_free_realized_faces, Qnil);
12979 /* Record this function, so it appears on the profiler's backtraces. */
12980 record_in_backtrace (Qredisplay_internal, &Qnil, 0);
12982 FOR_EACH_FRAME (tail, frame)
12983 XFRAME (frame)->already_hscrolled_p = 0;
12985 retry:
12986 /* Remember the currently selected window. */
12987 sw = w;
12989 pending = 0;
12990 last_escape_glyph_frame = NULL;
12991 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
12992 last_glyphless_glyph_frame = NULL;
12993 last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
12995 /* If new fonts have been loaded that make a glyph matrix adjustment
12996 necessary, do it. */
12997 if (fonts_changed_p)
12999 adjust_glyphs (NULL);
13000 ++windows_or_buffers_changed;
13001 fonts_changed_p = 0;
13004 /* If face_change_count is non-zero, init_iterator will free all
13005 realized faces, which includes the faces referenced from current
13006 matrices. So, we can't reuse current matrices in this case. */
13007 if (face_change_count)
13008 ++windows_or_buffers_changed;
13010 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
13011 && FRAME_TTY (sf)->previous_frame != sf)
13013 /* Since frames on a single ASCII terminal share the same
13014 display area, displaying a different frame means redisplay
13015 the whole thing. */
13016 windows_or_buffers_changed++;
13017 SET_FRAME_GARBAGED (sf);
13018 #ifndef DOS_NT
13019 set_tty_color_mode (FRAME_TTY (sf), sf);
13020 #endif
13021 FRAME_TTY (sf)->previous_frame = sf;
13024 /* Set the visible flags for all frames. Do this before checking for
13025 resized or garbaged frames; they want to know if their frames are
13026 visible. See the comment in frame.h for FRAME_SAMPLE_VISIBILITY. */
13027 number_of_visible_frames = 0;
13029 FOR_EACH_FRAME (tail, frame)
13031 struct frame *f = XFRAME (frame);
13033 if (FRAME_VISIBLE_P (f))
13034 ++number_of_visible_frames;
13035 clear_desired_matrices (f);
13038 /* Notice any pending interrupt request to change frame size. */
13039 do_pending_window_change (1);
13041 /* do_pending_window_change could change the selected_window due to
13042 frame resizing which makes the selected window too small. */
13043 if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw)
13044 sw = w;
13046 /* Clear frames marked as garbaged. */
13047 clear_garbaged_frames ();
13049 /* Build menubar and tool-bar items. */
13050 if (NILP (Vmemory_full))
13051 prepare_menu_bars ();
13053 if (windows_or_buffers_changed)
13054 update_mode_lines++;
13056 reconsider_clip_changes (w);
13058 /* In most cases selected window displays current buffer. */
13059 match_p = XBUFFER (w->contents) == current_buffer;
13060 if (match_p)
13062 ptrdiff_t count1;
13064 /* Detect case that we need to write or remove a star in the mode line. */
13065 if ((SAVE_MODIFF < MODIFF) != w->last_had_star)
13067 w->update_mode_line = 1;
13068 if (buffer_shared_and_changed ())
13069 update_mode_lines++;
13072 /* Avoid invocation of point motion hooks by `current_column' below. */
13073 count1 = SPECPDL_INDEX ();
13074 specbind (Qinhibit_point_motion_hooks, Qt);
13076 if (mode_line_update_needed (w))
13077 w->update_mode_line = 1;
13079 unbind_to (count1, Qnil);
13082 consider_all_windows_p = (update_mode_lines
13083 || buffer_shared_and_changed ()
13084 || cursor_type_changed);
13086 /* If specs for an arrow have changed, do thorough redisplay
13087 to ensure we remove any arrow that should no longer exist. */
13088 if (overlay_arrows_changed_p ())
13089 consider_all_windows_p = windows_or_buffers_changed = 1;
13091 /* Normally the message* functions will have already displayed and
13092 updated the echo area, but the frame may have been trashed, or
13093 the update may have been preempted, so display the echo area
13094 again here. Checking message_cleared_p captures the case that
13095 the echo area should be cleared. */
13096 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
13097 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
13098 || (message_cleared_p
13099 && minibuf_level == 0
13100 /* If the mini-window is currently selected, this means the
13101 echo-area doesn't show through. */
13102 && !MINI_WINDOW_P (XWINDOW (selected_window))))
13104 int window_height_changed_p = echo_area_display (0);
13106 if (message_cleared_p)
13107 update_miniwindow_p = 1;
13109 must_finish = 1;
13111 /* If we don't display the current message, don't clear the
13112 message_cleared_p flag, because, if we did, we wouldn't clear
13113 the echo area in the next redisplay which doesn't preserve
13114 the echo area. */
13115 if (!display_last_displayed_message_p)
13116 message_cleared_p = 0;
13118 if (fonts_changed_p)
13119 goto retry;
13120 else if (window_height_changed_p)
13122 consider_all_windows_p = 1;
13123 ++update_mode_lines;
13124 ++windows_or_buffers_changed;
13126 /* If window configuration was changed, frames may have been
13127 marked garbaged. Clear them or we will experience
13128 surprises wrt scrolling. */
13129 clear_garbaged_frames ();
13132 else if (EQ (selected_window, minibuf_window)
13133 && (current_buffer->clip_changed || window_outdated (w))
13134 && resize_mini_window (w, 0))
13136 /* Resized active mini-window to fit the size of what it is
13137 showing if its contents might have changed. */
13138 must_finish = 1;
13139 /* FIXME: this causes all frames to be updated, which seems unnecessary
13140 since only the current frame needs to be considered. This function
13141 needs to be rewritten with two variables, consider_all_windows and
13142 consider_all_frames. */
13143 consider_all_windows_p = 1;
13144 ++windows_or_buffers_changed;
13145 ++update_mode_lines;
13147 /* If window configuration was changed, frames may have been
13148 marked garbaged. Clear them or we will experience
13149 surprises wrt scrolling. */
13150 clear_garbaged_frames ();
13153 /* If showing the region, and mark has changed, we must redisplay
13154 the whole window. The assignment to this_line_start_pos prevents
13155 the optimization directly below this if-statement. */
13156 if (((!NILP (Vtransient_mark_mode)
13157 && !NILP (BVAR (XBUFFER (w->contents), mark_active)))
13158 != (w->region_showing > 0))
13159 || (w->region_showing
13160 && w->region_showing
13161 != XINT (Fmarker_position (BVAR (XBUFFER (w->contents), mark)))))
13162 CHARPOS (this_line_start_pos) = 0;
13164 /* Optimize the case that only the line containing the cursor in the
13165 selected window has changed. Variables starting with this_ are
13166 set in display_line and record information about the line
13167 containing the cursor. */
13168 tlbufpos = this_line_start_pos;
13169 tlendpos = this_line_end_pos;
13170 if (!consider_all_windows_p
13171 && CHARPOS (tlbufpos) > 0
13172 && !w->update_mode_line
13173 && !current_buffer->clip_changed
13174 && !current_buffer->prevent_redisplay_optimizations_p
13175 && FRAME_VISIBLE_P (XFRAME (w->frame))
13176 && !FRAME_OBSCURED_P (XFRAME (w->frame))
13177 /* Make sure recorded data applies to current buffer, etc. */
13178 && this_line_buffer == current_buffer
13179 && match_p
13180 && !w->force_start
13181 && !w->optional_new_start
13182 /* Point must be on the line that we have info recorded about. */
13183 && PT >= CHARPOS (tlbufpos)
13184 && PT <= Z - CHARPOS (tlendpos)
13185 /* All text outside that line, including its final newline,
13186 must be unchanged. */
13187 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
13188 CHARPOS (tlendpos)))
13190 if (CHARPOS (tlbufpos) > BEGV
13191 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
13192 && (CHARPOS (tlbufpos) == ZV
13193 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
13194 /* Former continuation line has disappeared by becoming empty. */
13195 goto cancel;
13196 else if (window_outdated (w) || MINI_WINDOW_P (w))
13198 /* We have to handle the case of continuation around a
13199 wide-column character (see the comment in indent.c around
13200 line 1340).
13202 For instance, in the following case:
13204 -------- Insert --------
13205 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
13206 J_I_ ==> J_I_ `^^' are cursors.
13207 ^^ ^^
13208 -------- --------
13210 As we have to redraw the line above, we cannot use this
13211 optimization. */
13213 struct it it;
13214 int line_height_before = this_line_pixel_height;
13216 /* Note that start_display will handle the case that the
13217 line starting at tlbufpos is a continuation line. */
13218 start_display (&it, w, tlbufpos);
13220 /* Implementation note: It this still necessary? */
13221 if (it.current_x != this_line_start_x)
13222 goto cancel;
13224 TRACE ((stderr, "trying display optimization 1\n"));
13225 w->cursor.vpos = -1;
13226 overlay_arrow_seen = 0;
13227 it.vpos = this_line_vpos;
13228 it.current_y = this_line_y;
13229 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
13230 display_line (&it);
13232 /* If line contains point, is not continued,
13233 and ends at same distance from eob as before, we win. */
13234 if (w->cursor.vpos >= 0
13235 /* Line is not continued, otherwise this_line_start_pos
13236 would have been set to 0 in display_line. */
13237 && CHARPOS (this_line_start_pos)
13238 /* Line ends as before. */
13239 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
13240 /* Line has same height as before. Otherwise other lines
13241 would have to be shifted up or down. */
13242 && this_line_pixel_height == line_height_before)
13244 /* If this is not the window's last line, we must adjust
13245 the charstarts of the lines below. */
13246 if (it.current_y < it.last_visible_y)
13248 struct glyph_row *row
13249 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
13250 ptrdiff_t delta, delta_bytes;
13252 /* We used to distinguish between two cases here,
13253 conditioned by Z - CHARPOS (tlendpos) == ZV, for
13254 when the line ends in a newline or the end of the
13255 buffer's accessible portion. But both cases did
13256 the same, so they were collapsed. */
13257 delta = (Z
13258 - CHARPOS (tlendpos)
13259 - MATRIX_ROW_START_CHARPOS (row));
13260 delta_bytes = (Z_BYTE
13261 - BYTEPOS (tlendpos)
13262 - MATRIX_ROW_START_BYTEPOS (row));
13264 increment_matrix_positions (w->current_matrix,
13265 this_line_vpos + 1,
13266 w->current_matrix->nrows,
13267 delta, delta_bytes);
13270 /* If this row displays text now but previously didn't,
13271 or vice versa, w->window_end_vpos may have to be
13272 adjusted. */
13273 if (MATRIX_ROW_DISPLAYS_TEXT_P (it.glyph_row - 1))
13275 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
13276 wset_window_end_vpos (w, make_number (this_line_vpos));
13278 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
13279 && this_line_vpos > 0)
13280 wset_window_end_vpos (w, make_number (this_line_vpos - 1));
13281 w->window_end_valid = 0;
13283 /* Update hint: No need to try to scroll in update_window. */
13284 w->desired_matrix->no_scrolling_p = 1;
13286 #ifdef GLYPH_DEBUG
13287 *w->desired_matrix->method = 0;
13288 debug_method_add (w, "optimization 1");
13289 #endif
13290 #ifdef HAVE_WINDOW_SYSTEM
13291 update_window_fringes (w, 0);
13292 #endif
13293 goto update;
13295 else
13296 goto cancel;
13298 else if (/* Cursor position hasn't changed. */
13299 PT == w->last_point
13300 /* Make sure the cursor was last displayed
13301 in this window. Otherwise we have to reposition it. */
13302 && 0 <= w->cursor.vpos
13303 && w->cursor.vpos < WINDOW_TOTAL_LINES (w))
13305 if (!must_finish)
13307 do_pending_window_change (1);
13308 /* If selected_window changed, redisplay again. */
13309 if (WINDOWP (selected_window)
13310 && (w = XWINDOW (selected_window)) != sw)
13311 goto retry;
13313 /* We used to always goto end_of_redisplay here, but this
13314 isn't enough if we have a blinking cursor. */
13315 if (w->cursor_off_p == w->last_cursor_off_p)
13316 goto end_of_redisplay;
13318 goto update;
13320 /* If highlighting the region, or if the cursor is in the echo area,
13321 then we can't just move the cursor. */
13322 else if (! (!NILP (Vtransient_mark_mode)
13323 && !NILP (BVAR (current_buffer, mark_active)))
13324 && (EQ (selected_window,
13325 BVAR (current_buffer, last_selected_window))
13326 || highlight_nonselected_windows)
13327 && !w->region_showing
13328 && NILP (Vshow_trailing_whitespace)
13329 && !cursor_in_echo_area)
13331 struct it it;
13332 struct glyph_row *row;
13334 /* Skip from tlbufpos to PT and see where it is. Note that
13335 PT may be in invisible text. If so, we will end at the
13336 next visible position. */
13337 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
13338 NULL, DEFAULT_FACE_ID);
13339 it.current_x = this_line_start_x;
13340 it.current_y = this_line_y;
13341 it.vpos = this_line_vpos;
13343 /* The call to move_it_to stops in front of PT, but
13344 moves over before-strings. */
13345 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
13347 if (it.vpos == this_line_vpos
13348 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
13349 row->enabled_p))
13351 eassert (this_line_vpos == it.vpos);
13352 eassert (this_line_y == it.current_y);
13353 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13354 #ifdef GLYPH_DEBUG
13355 *w->desired_matrix->method = 0;
13356 debug_method_add (w, "optimization 3");
13357 #endif
13358 goto update;
13360 else
13361 goto cancel;
13364 cancel:
13365 /* Text changed drastically or point moved off of line. */
13366 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
13369 CHARPOS (this_line_start_pos) = 0;
13370 consider_all_windows_p |= buffer_shared_and_changed ();
13371 ++clear_face_cache_count;
13372 #ifdef HAVE_WINDOW_SYSTEM
13373 ++clear_image_cache_count;
13374 #endif
13376 /* Build desired matrices, and update the display. If
13377 consider_all_windows_p is non-zero, do it for all windows on all
13378 frames. Otherwise do it for selected_window, only. */
13380 if (consider_all_windows_p)
13382 FOR_EACH_FRAME (tail, frame)
13383 XFRAME (frame)->updated_p = 0;
13385 FOR_EACH_FRAME (tail, frame)
13387 struct frame *f = XFRAME (frame);
13389 /* We don't have to do anything for unselected terminal
13390 frames. */
13391 if ((FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
13392 && !EQ (FRAME_TTY (f)->top_frame, frame))
13393 continue;
13395 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
13397 /* Mark all the scroll bars to be removed; we'll redeem
13398 the ones we want when we redisplay their windows. */
13399 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
13400 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
13402 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
13403 redisplay_windows (FRAME_ROOT_WINDOW (f));
13405 /* The X error handler may have deleted that frame. */
13406 if (!FRAME_LIVE_P (f))
13407 continue;
13409 /* Any scroll bars which redisplay_windows should have
13410 nuked should now go away. */
13411 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
13412 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
13414 /* If fonts changed, display again. */
13415 /* ??? rms: I suspect it is a mistake to jump all the way
13416 back to retry here. It should just retry this frame. */
13417 if (fonts_changed_p)
13418 goto retry;
13420 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
13422 /* See if we have to hscroll. */
13423 if (!f->already_hscrolled_p)
13425 f->already_hscrolled_p = 1;
13426 if (hscroll_windows (f->root_window))
13427 goto retry;
13430 /* Prevent various kinds of signals during display
13431 update. stdio is not robust about handling
13432 signals, which can cause an apparent I/O
13433 error. */
13434 if (interrupt_input)
13435 unrequest_sigio ();
13436 STOP_POLLING;
13438 /* Update the display. */
13439 set_window_update_flags (XWINDOW (f->root_window), 1);
13440 pending |= update_frame (f, 0, 0);
13441 f->updated_p = 1;
13446 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
13448 if (!pending)
13450 /* Do the mark_window_display_accurate after all windows have
13451 been redisplayed because this call resets flags in buffers
13452 which are needed for proper redisplay. */
13453 FOR_EACH_FRAME (tail, frame)
13455 struct frame *f = XFRAME (frame);
13456 if (f->updated_p)
13458 mark_window_display_accurate (f->root_window, 1);
13459 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
13460 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
13465 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
13467 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
13468 struct frame *mini_frame;
13470 displayed_buffer = XBUFFER (XWINDOW (selected_window)->contents);
13471 /* Use list_of_error, not Qerror, so that
13472 we catch only errors and don't run the debugger. */
13473 internal_condition_case_1 (redisplay_window_1, selected_window,
13474 list_of_error,
13475 redisplay_window_error);
13476 if (update_miniwindow_p)
13477 internal_condition_case_1 (redisplay_window_1, mini_window,
13478 list_of_error,
13479 redisplay_window_error);
13481 /* Compare desired and current matrices, perform output. */
13483 update:
13484 /* If fonts changed, display again. */
13485 if (fonts_changed_p)
13486 goto retry;
13488 /* Prevent various kinds of signals during display update.
13489 stdio is not robust about handling signals,
13490 which can cause an apparent I/O error. */
13491 if (interrupt_input)
13492 unrequest_sigio ();
13493 STOP_POLLING;
13495 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
13497 if (hscroll_windows (selected_window))
13498 goto retry;
13500 XWINDOW (selected_window)->must_be_updated_p = 1;
13501 pending = update_frame (sf, 0, 0);
13504 /* We may have called echo_area_display at the top of this
13505 function. If the echo area is on another frame, that may
13506 have put text on a frame other than the selected one, so the
13507 above call to update_frame would not have caught it. Catch
13508 it here. */
13509 mini_window = FRAME_MINIBUF_WINDOW (sf);
13510 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
13512 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
13514 XWINDOW (mini_window)->must_be_updated_p = 1;
13515 pending |= update_frame (mini_frame, 0, 0);
13516 if (!pending && hscroll_windows (mini_window))
13517 goto retry;
13521 /* If display was paused because of pending input, make sure we do a
13522 thorough update the next time. */
13523 if (pending)
13525 /* Prevent the optimization at the beginning of
13526 redisplay_internal that tries a single-line update of the
13527 line containing the cursor in the selected window. */
13528 CHARPOS (this_line_start_pos) = 0;
13530 /* Let the overlay arrow be updated the next time. */
13531 update_overlay_arrows (0);
13533 /* If we pause after scrolling, some rows in the current
13534 matrices of some windows are not valid. */
13535 if (!WINDOW_FULL_WIDTH_P (w)
13536 && !FRAME_WINDOW_P (XFRAME (w->frame)))
13537 update_mode_lines = 1;
13539 else
13541 if (!consider_all_windows_p)
13543 /* This has already been done above if
13544 consider_all_windows_p is set. */
13545 mark_window_display_accurate_1 (w, 1);
13547 /* Say overlay arrows are up to date. */
13548 update_overlay_arrows (1);
13550 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
13551 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
13554 update_mode_lines = 0;
13555 windows_or_buffers_changed = 0;
13556 cursor_type_changed = 0;
13559 /* Start SIGIO interrupts coming again. Having them off during the
13560 code above makes it less likely one will discard output, but not
13561 impossible, since there might be stuff in the system buffer here.
13562 But it is much hairier to try to do anything about that. */
13563 if (interrupt_input)
13564 request_sigio ();
13565 RESUME_POLLING;
13567 /* If a frame has become visible which was not before, redisplay
13568 again, so that we display it. Expose events for such a frame
13569 (which it gets when becoming visible) don't call the parts of
13570 redisplay constructing glyphs, so simply exposing a frame won't
13571 display anything in this case. So, we have to display these
13572 frames here explicitly. */
13573 if (!pending)
13575 int new_count = 0;
13577 FOR_EACH_FRAME (tail, frame)
13579 int this_is_visible = 0;
13581 if (XFRAME (frame)->visible)
13582 this_is_visible = 1;
13584 if (this_is_visible)
13585 new_count++;
13588 if (new_count != number_of_visible_frames)
13589 windows_or_buffers_changed++;
13592 /* Change frame size now if a change is pending. */
13593 do_pending_window_change (1);
13595 /* If we just did a pending size change, or have additional
13596 visible frames, or selected_window changed, redisplay again. */
13597 if ((windows_or_buffers_changed && !pending)
13598 || (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw))
13599 goto retry;
13601 /* Clear the face and image caches.
13603 We used to do this only if consider_all_windows_p. But the cache
13604 needs to be cleared if a timer creates images in the current
13605 buffer (e.g. the test case in Bug#6230). */
13607 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
13609 clear_face_cache (0);
13610 clear_face_cache_count = 0;
13613 #ifdef HAVE_WINDOW_SYSTEM
13614 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
13616 clear_image_caches (Qnil);
13617 clear_image_cache_count = 0;
13619 #endif /* HAVE_WINDOW_SYSTEM */
13621 end_of_redisplay:
13622 unbind_to (count, Qnil);
13623 RESUME_POLLING;
13627 /* Redisplay, but leave alone any recent echo area message unless
13628 another message has been requested in its place.
13630 This is useful in situations where you need to redisplay but no
13631 user action has occurred, making it inappropriate for the message
13632 area to be cleared. See tracking_off and
13633 wait_reading_process_output for examples of these situations.
13635 FROM_WHERE is an integer saying from where this function was
13636 called. This is useful for debugging. */
13638 void
13639 redisplay_preserve_echo_area (int from_where)
13641 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
13643 if (!NILP (echo_area_buffer[1]))
13645 /* We have a previously displayed message, but no current
13646 message. Redisplay the previous message. */
13647 display_last_displayed_message_p = 1;
13648 redisplay_internal ();
13649 display_last_displayed_message_p = 0;
13651 else
13652 redisplay_internal ();
13654 if (FRAME_RIF (SELECTED_FRAME ()) != NULL
13655 && FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
13656 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (NULL);
13660 /* Function registered with record_unwind_protect in redisplay_internal. */
13662 static void
13663 unwind_redisplay (void)
13665 redisplaying_p = 0;
13669 /* Mark the display of leaf window W as accurate or inaccurate.
13670 If ACCURATE_P is non-zero mark display of W as accurate. If
13671 ACCURATE_P is zero, arrange for W to be redisplayed the next
13672 time redisplay_internal is called. */
13674 static void
13675 mark_window_display_accurate_1 (struct window *w, int accurate_p)
13677 struct buffer *b = XBUFFER (w->contents);
13679 w->last_modified = accurate_p ? BUF_MODIFF (b) : 0;
13680 w->last_overlay_modified = accurate_p ? BUF_OVERLAY_MODIFF (b) : 0;
13681 w->last_had_star = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b);
13683 if (accurate_p)
13685 b->clip_changed = 0;
13686 b->prevent_redisplay_optimizations_p = 0;
13688 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
13689 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
13690 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
13691 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
13693 w->current_matrix->buffer = b;
13694 w->current_matrix->begv = BUF_BEGV (b);
13695 w->current_matrix->zv = BUF_ZV (b);
13697 w->last_cursor = w->cursor;
13698 w->last_cursor_off_p = w->cursor_off_p;
13700 if (w == XWINDOW (selected_window))
13701 w->last_point = BUF_PT (b);
13702 else
13703 w->last_point = marker_position (w->pointm);
13705 w->window_end_valid = 1;
13706 w->update_mode_line = 0;
13711 /* Mark the display of windows in the window tree rooted at WINDOW as
13712 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
13713 windows as accurate. If ACCURATE_P is zero, arrange for windows to
13714 be redisplayed the next time redisplay_internal is called. */
13716 void
13717 mark_window_display_accurate (Lisp_Object window, int accurate_p)
13719 struct window *w;
13721 for (; !NILP (window); window = w->next)
13723 w = XWINDOW (window);
13724 if (WINDOWP (w->contents))
13725 mark_window_display_accurate (w->contents, accurate_p);
13726 else
13727 mark_window_display_accurate_1 (w, accurate_p);
13730 if (accurate_p)
13731 update_overlay_arrows (1);
13732 else
13733 /* Force a thorough redisplay the next time by setting
13734 last_arrow_position and last_arrow_string to t, which is
13735 unequal to any useful value of Voverlay_arrow_... */
13736 update_overlay_arrows (-1);
13740 /* Return value in display table DP (Lisp_Char_Table *) for character
13741 C. Since a display table doesn't have any parent, we don't have to
13742 follow parent. Do not call this function directly but use the
13743 macro DISP_CHAR_VECTOR. */
13745 Lisp_Object
13746 disp_char_vector (struct Lisp_Char_Table *dp, int c)
13748 Lisp_Object val;
13750 if (ASCII_CHAR_P (c))
13752 val = dp->ascii;
13753 if (SUB_CHAR_TABLE_P (val))
13754 val = XSUB_CHAR_TABLE (val)->contents[c];
13756 else
13758 Lisp_Object table;
13760 XSETCHAR_TABLE (table, dp);
13761 val = char_table_ref (table, c);
13763 if (NILP (val))
13764 val = dp->defalt;
13765 return val;
13770 /***********************************************************************
13771 Window Redisplay
13772 ***********************************************************************/
13774 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
13776 static void
13777 redisplay_windows (Lisp_Object window)
13779 while (!NILP (window))
13781 struct window *w = XWINDOW (window);
13783 if (WINDOWP (w->contents))
13784 redisplay_windows (w->contents);
13785 else if (BUFFERP (w->contents))
13787 displayed_buffer = XBUFFER (w->contents);
13788 /* Use list_of_error, not Qerror, so that
13789 we catch only errors and don't run the debugger. */
13790 internal_condition_case_1 (redisplay_window_0, window,
13791 list_of_error,
13792 redisplay_window_error);
13795 window = w->next;
13799 static Lisp_Object
13800 redisplay_window_error (Lisp_Object ignore)
13802 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
13803 return Qnil;
13806 static Lisp_Object
13807 redisplay_window_0 (Lisp_Object window)
13809 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
13810 redisplay_window (window, 0);
13811 return Qnil;
13814 static Lisp_Object
13815 redisplay_window_1 (Lisp_Object window)
13817 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
13818 redisplay_window (window, 1);
13819 return Qnil;
13823 /* Set cursor position of W. PT is assumed to be displayed in ROW.
13824 DELTA and DELTA_BYTES are the numbers of characters and bytes by
13825 which positions recorded in ROW differ from current buffer
13826 positions.
13828 Return 0 if cursor is not on this row, 1 otherwise. */
13830 static int
13831 set_cursor_from_row (struct window *w, struct glyph_row *row,
13832 struct glyph_matrix *matrix,
13833 ptrdiff_t delta, ptrdiff_t delta_bytes,
13834 int dy, int dvpos)
13836 struct glyph *glyph = row->glyphs[TEXT_AREA];
13837 struct glyph *end = glyph + row->used[TEXT_AREA];
13838 struct glyph *cursor = NULL;
13839 /* The last known character position in row. */
13840 ptrdiff_t last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
13841 int x = row->x;
13842 ptrdiff_t pt_old = PT - delta;
13843 ptrdiff_t pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
13844 ptrdiff_t pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
13845 struct glyph *glyph_before = glyph - 1, *glyph_after = end;
13846 /* A glyph beyond the edge of TEXT_AREA which we should never
13847 touch. */
13848 struct glyph *glyphs_end = end;
13849 /* Non-zero means we've found a match for cursor position, but that
13850 glyph has the avoid_cursor_p flag set. */
13851 int match_with_avoid_cursor = 0;
13852 /* Non-zero means we've seen at least one glyph that came from a
13853 display string. */
13854 int string_seen = 0;
13855 /* Largest and smallest buffer positions seen so far during scan of
13856 glyph row. */
13857 ptrdiff_t bpos_max = pos_before;
13858 ptrdiff_t bpos_min = pos_after;
13859 /* Last buffer position covered by an overlay string with an integer
13860 `cursor' property. */
13861 ptrdiff_t bpos_covered = 0;
13862 /* Non-zero means the display string on which to display the cursor
13863 comes from a text property, not from an overlay. */
13864 int string_from_text_prop = 0;
13866 /* Don't even try doing anything if called for a mode-line or
13867 header-line row, since the rest of the code isn't prepared to
13868 deal with such calamities. */
13869 eassert (!row->mode_line_p);
13870 if (row->mode_line_p)
13871 return 0;
13873 /* Skip over glyphs not having an object at the start and the end of
13874 the row. These are special glyphs like truncation marks on
13875 terminal frames. */
13876 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
13878 if (!row->reversed_p)
13880 while (glyph < end
13881 && INTEGERP (glyph->object)
13882 && glyph->charpos < 0)
13884 x += glyph->pixel_width;
13885 ++glyph;
13887 while (end > glyph
13888 && INTEGERP ((end - 1)->object)
13889 /* CHARPOS is zero for blanks and stretch glyphs
13890 inserted by extend_face_to_end_of_line. */
13891 && (end - 1)->charpos <= 0)
13892 --end;
13893 glyph_before = glyph - 1;
13894 glyph_after = end;
13896 else
13898 struct glyph *g;
13900 /* If the glyph row is reversed, we need to process it from back
13901 to front, so swap the edge pointers. */
13902 glyphs_end = end = glyph - 1;
13903 glyph += row->used[TEXT_AREA] - 1;
13905 while (glyph > end + 1
13906 && INTEGERP (glyph->object)
13907 && glyph->charpos < 0)
13909 --glyph;
13910 x -= glyph->pixel_width;
13912 if (INTEGERP (glyph->object) && glyph->charpos < 0)
13913 --glyph;
13914 /* By default, in reversed rows we put the cursor on the
13915 rightmost (first in the reading order) glyph. */
13916 for (g = end + 1; g < glyph; g++)
13917 x += g->pixel_width;
13918 while (end < glyph
13919 && INTEGERP ((end + 1)->object)
13920 && (end + 1)->charpos <= 0)
13921 ++end;
13922 glyph_before = glyph + 1;
13923 glyph_after = end;
13926 else if (row->reversed_p)
13928 /* In R2L rows that don't display text, put the cursor on the
13929 rightmost glyph. Case in point: an empty last line that is
13930 part of an R2L paragraph. */
13931 cursor = end - 1;
13932 /* Avoid placing the cursor on the last glyph of the row, where
13933 on terminal frames we hold the vertical border between
13934 adjacent windows. */
13935 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w))
13936 && !WINDOW_RIGHTMOST_P (w)
13937 && cursor == row->glyphs[LAST_AREA] - 1)
13938 cursor--;
13939 x = -1; /* will be computed below, at label compute_x */
13942 /* Step 1: Try to find the glyph whose character position
13943 corresponds to point. If that's not possible, find 2 glyphs
13944 whose character positions are the closest to point, one before
13945 point, the other after it. */
13946 if (!row->reversed_p)
13947 while (/* not marched to end of glyph row */
13948 glyph < end
13949 /* glyph was not inserted by redisplay for internal purposes */
13950 && !INTEGERP (glyph->object))
13952 if (BUFFERP (glyph->object))
13954 ptrdiff_t dpos = glyph->charpos - pt_old;
13956 if (glyph->charpos > bpos_max)
13957 bpos_max = glyph->charpos;
13958 if (glyph->charpos < bpos_min)
13959 bpos_min = glyph->charpos;
13960 if (!glyph->avoid_cursor_p)
13962 /* If we hit point, we've found the glyph on which to
13963 display the cursor. */
13964 if (dpos == 0)
13966 match_with_avoid_cursor = 0;
13967 break;
13969 /* See if we've found a better approximation to
13970 POS_BEFORE or to POS_AFTER. */
13971 if (0 > dpos && dpos > pos_before - pt_old)
13973 pos_before = glyph->charpos;
13974 glyph_before = glyph;
13976 else if (0 < dpos && dpos < pos_after - pt_old)
13978 pos_after = glyph->charpos;
13979 glyph_after = glyph;
13982 else if (dpos == 0)
13983 match_with_avoid_cursor = 1;
13985 else if (STRINGP (glyph->object))
13987 Lisp_Object chprop;
13988 ptrdiff_t glyph_pos = glyph->charpos;
13990 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
13991 glyph->object);
13992 if (!NILP (chprop))
13994 /* If the string came from a `display' text property,
13995 look up the buffer position of that property and
13996 use that position to update bpos_max, as if we
13997 actually saw such a position in one of the row's
13998 glyphs. This helps with supporting integer values
13999 of `cursor' property on the display string in
14000 situations where most or all of the row's buffer
14001 text is completely covered by display properties,
14002 so that no glyph with valid buffer positions is
14003 ever seen in the row. */
14004 ptrdiff_t prop_pos =
14005 string_buffer_position_lim (glyph->object, pos_before,
14006 pos_after, 0);
14008 if (prop_pos >= pos_before)
14009 bpos_max = prop_pos - 1;
14011 if (INTEGERP (chprop))
14013 bpos_covered = bpos_max + XINT (chprop);
14014 /* If the `cursor' property covers buffer positions up
14015 to and including point, we should display cursor on
14016 this glyph. Note that, if a `cursor' property on one
14017 of the string's characters has an integer value, we
14018 will break out of the loop below _before_ we get to
14019 the position match above. IOW, integer values of
14020 the `cursor' property override the "exact match for
14021 point" strategy of positioning the cursor. */
14022 /* Implementation note: bpos_max == pt_old when, e.g.,
14023 we are in an empty line, where bpos_max is set to
14024 MATRIX_ROW_START_CHARPOS, see above. */
14025 if (bpos_max <= pt_old && bpos_covered >= pt_old)
14027 cursor = glyph;
14028 break;
14032 string_seen = 1;
14034 x += glyph->pixel_width;
14035 ++glyph;
14037 else if (glyph > end) /* row is reversed */
14038 while (!INTEGERP (glyph->object))
14040 if (BUFFERP (glyph->object))
14042 ptrdiff_t dpos = glyph->charpos - pt_old;
14044 if (glyph->charpos > bpos_max)
14045 bpos_max = glyph->charpos;
14046 if (glyph->charpos < bpos_min)
14047 bpos_min = glyph->charpos;
14048 if (!glyph->avoid_cursor_p)
14050 if (dpos == 0)
14052 match_with_avoid_cursor = 0;
14053 break;
14055 if (0 > dpos && dpos > pos_before - pt_old)
14057 pos_before = glyph->charpos;
14058 glyph_before = glyph;
14060 else if (0 < dpos && dpos < pos_after - pt_old)
14062 pos_after = glyph->charpos;
14063 glyph_after = glyph;
14066 else if (dpos == 0)
14067 match_with_avoid_cursor = 1;
14069 else if (STRINGP (glyph->object))
14071 Lisp_Object chprop;
14072 ptrdiff_t glyph_pos = glyph->charpos;
14074 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
14075 glyph->object);
14076 if (!NILP (chprop))
14078 ptrdiff_t prop_pos =
14079 string_buffer_position_lim (glyph->object, pos_before,
14080 pos_after, 0);
14082 if (prop_pos >= pos_before)
14083 bpos_max = prop_pos - 1;
14085 if (INTEGERP (chprop))
14087 bpos_covered = bpos_max + XINT (chprop);
14088 /* If the `cursor' property covers buffer positions up
14089 to and including point, we should display cursor on
14090 this glyph. */
14091 if (bpos_max <= pt_old && bpos_covered >= pt_old)
14093 cursor = glyph;
14094 break;
14097 string_seen = 1;
14099 --glyph;
14100 if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
14102 x--; /* can't use any pixel_width */
14103 break;
14105 x -= glyph->pixel_width;
14108 /* Step 2: If we didn't find an exact match for point, we need to
14109 look for a proper place to put the cursor among glyphs between
14110 GLYPH_BEFORE and GLYPH_AFTER. */
14111 if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
14112 && BUFFERP (glyph->object) && glyph->charpos == pt_old)
14113 && !(bpos_max < pt_old && pt_old <= bpos_covered))
14115 /* An empty line has a single glyph whose OBJECT is zero and
14116 whose CHARPOS is the position of a newline on that line.
14117 Note that on a TTY, there are more glyphs after that, which
14118 were produced by extend_face_to_end_of_line, but their
14119 CHARPOS is zero or negative. */
14120 int empty_line_p =
14121 (row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
14122 && INTEGERP (glyph->object) && glyph->charpos > 0
14123 /* On a TTY, continued and truncated rows also have a glyph at
14124 their end whose OBJECT is zero and whose CHARPOS is
14125 positive (the continuation and truncation glyphs), but such
14126 rows are obviously not "empty". */
14127 && !(row->continued_p || row->truncated_on_right_p);
14129 if (row->ends_in_ellipsis_p && pos_after == last_pos)
14131 ptrdiff_t ellipsis_pos;
14133 /* Scan back over the ellipsis glyphs. */
14134 if (!row->reversed_p)
14136 ellipsis_pos = (glyph - 1)->charpos;
14137 while (glyph > row->glyphs[TEXT_AREA]
14138 && (glyph - 1)->charpos == ellipsis_pos)
14139 glyph--, x -= glyph->pixel_width;
14140 /* That loop always goes one position too far, including
14141 the glyph before the ellipsis. So scan forward over
14142 that one. */
14143 x += glyph->pixel_width;
14144 glyph++;
14146 else /* row is reversed */
14148 ellipsis_pos = (glyph + 1)->charpos;
14149 while (glyph < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14150 && (glyph + 1)->charpos == ellipsis_pos)
14151 glyph++, x += glyph->pixel_width;
14152 x -= glyph->pixel_width;
14153 glyph--;
14156 else if (match_with_avoid_cursor)
14158 cursor = glyph_after;
14159 x = -1;
14161 else if (string_seen)
14163 int incr = row->reversed_p ? -1 : +1;
14165 /* Need to find the glyph that came out of a string which is
14166 present at point. That glyph is somewhere between
14167 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
14168 positioned between POS_BEFORE and POS_AFTER in the
14169 buffer. */
14170 struct glyph *start, *stop;
14171 ptrdiff_t pos = pos_before;
14173 x = -1;
14175 /* If the row ends in a newline from a display string,
14176 reordering could have moved the glyphs belonging to the
14177 string out of the [GLYPH_BEFORE..GLYPH_AFTER] range. So
14178 in this case we extend the search to the last glyph in
14179 the row that was not inserted by redisplay. */
14180 if (row->ends_in_newline_from_string_p)
14182 glyph_after = end;
14183 pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
14186 /* GLYPH_BEFORE and GLYPH_AFTER are the glyphs that
14187 correspond to POS_BEFORE and POS_AFTER, respectively. We
14188 need START and STOP in the order that corresponds to the
14189 row's direction as given by its reversed_p flag. If the
14190 directionality of characters between POS_BEFORE and
14191 POS_AFTER is the opposite of the row's base direction,
14192 these characters will have been reordered for display,
14193 and we need to reverse START and STOP. */
14194 if (!row->reversed_p)
14196 start = min (glyph_before, glyph_after);
14197 stop = max (glyph_before, glyph_after);
14199 else
14201 start = max (glyph_before, glyph_after);
14202 stop = min (glyph_before, glyph_after);
14204 for (glyph = start + incr;
14205 row->reversed_p ? glyph > stop : glyph < stop; )
14208 /* Any glyphs that come from the buffer are here because
14209 of bidi reordering. Skip them, and only pay
14210 attention to glyphs that came from some string. */
14211 if (STRINGP (glyph->object))
14213 Lisp_Object str;
14214 ptrdiff_t tem;
14215 /* If the display property covers the newline, we
14216 need to search for it one position farther. */
14217 ptrdiff_t lim = pos_after
14218 + (pos_after == MATRIX_ROW_END_CHARPOS (row) + delta);
14220 string_from_text_prop = 0;
14221 str = glyph->object;
14222 tem = string_buffer_position_lim (str, pos, lim, 0);
14223 if (tem == 0 /* from overlay */
14224 || pos <= tem)
14226 /* If the string from which this glyph came is
14227 found in the buffer at point, or at position
14228 that is closer to point than pos_after, then
14229 we've found the glyph we've been looking for.
14230 If it comes from an overlay (tem == 0), and
14231 it has the `cursor' property on one of its
14232 glyphs, record that glyph as a candidate for
14233 displaying the cursor. (As in the
14234 unidirectional version, we will display the
14235 cursor on the last candidate we find.) */
14236 if (tem == 0
14237 || tem == pt_old
14238 || (tem - pt_old > 0 && tem < pos_after))
14240 /* The glyphs from this string could have
14241 been reordered. Find the one with the
14242 smallest string position. Or there could
14243 be a character in the string with the
14244 `cursor' property, which means display
14245 cursor on that character's glyph. */
14246 ptrdiff_t strpos = glyph->charpos;
14248 if (tem)
14250 cursor = glyph;
14251 string_from_text_prop = 1;
14253 for ( ;
14254 (row->reversed_p ? glyph > stop : glyph < stop)
14255 && EQ (glyph->object, str);
14256 glyph += incr)
14258 Lisp_Object cprop;
14259 ptrdiff_t gpos = glyph->charpos;
14261 cprop = Fget_char_property (make_number (gpos),
14262 Qcursor,
14263 glyph->object);
14264 if (!NILP (cprop))
14266 cursor = glyph;
14267 break;
14269 if (tem && glyph->charpos < strpos)
14271 strpos = glyph->charpos;
14272 cursor = glyph;
14276 if (tem == pt_old
14277 || (tem - pt_old > 0 && tem < pos_after))
14278 goto compute_x;
14280 if (tem)
14281 pos = tem + 1; /* don't find previous instances */
14283 /* This string is not what we want; skip all of the
14284 glyphs that came from it. */
14285 while ((row->reversed_p ? glyph > stop : glyph < stop)
14286 && EQ (glyph->object, str))
14287 glyph += incr;
14289 else
14290 glyph += incr;
14293 /* If we reached the end of the line, and END was from a string,
14294 the cursor is not on this line. */
14295 if (cursor == NULL
14296 && (row->reversed_p ? glyph <= end : glyph >= end)
14297 && (row->reversed_p ? end > glyphs_end : end < glyphs_end)
14298 && STRINGP (end->object)
14299 && row->continued_p)
14300 return 0;
14302 /* A truncated row may not include PT among its character positions.
14303 Setting the cursor inside the scroll margin will trigger
14304 recalculation of hscroll in hscroll_window_tree. But if a
14305 display string covers point, defer to the string-handling
14306 code below to figure this out. */
14307 else if (row->truncated_on_left_p && pt_old < bpos_min)
14309 cursor = glyph_before;
14310 x = -1;
14312 else if ((row->truncated_on_right_p && pt_old > bpos_max)
14313 /* Zero-width characters produce no glyphs. */
14314 || (!empty_line_p
14315 && (row->reversed_p
14316 ? glyph_after > glyphs_end
14317 : glyph_after < glyphs_end)))
14319 cursor = glyph_after;
14320 x = -1;
14324 compute_x:
14325 if (cursor != NULL)
14326 glyph = cursor;
14327 else if (glyph == glyphs_end
14328 && pos_before == pos_after
14329 && STRINGP ((row->reversed_p
14330 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14331 : row->glyphs[TEXT_AREA])->object))
14333 /* If all the glyphs of this row came from strings, put the
14334 cursor on the first glyph of the row. This avoids having the
14335 cursor outside of the text area in this very rare and hard
14336 use case. */
14337 glyph =
14338 row->reversed_p
14339 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14340 : row->glyphs[TEXT_AREA];
14342 if (x < 0)
14344 struct glyph *g;
14346 /* Need to compute x that corresponds to GLYPH. */
14347 for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++)
14349 if (g >= row->glyphs[TEXT_AREA] + row->used[TEXT_AREA])
14350 emacs_abort ();
14351 x += g->pixel_width;
14355 /* ROW could be part of a continued line, which, under bidi
14356 reordering, might have other rows whose start and end charpos
14357 occlude point. Only set w->cursor if we found a better
14358 approximation to the cursor position than we have from previously
14359 examined candidate rows belonging to the same continued line. */
14360 if (/* we already have a candidate row */
14361 w->cursor.vpos >= 0
14362 /* that candidate is not the row we are processing */
14363 && MATRIX_ROW (matrix, w->cursor.vpos) != row
14364 /* Make sure cursor.vpos specifies a row whose start and end
14365 charpos occlude point, and it is valid candidate for being a
14366 cursor-row. This is because some callers of this function
14367 leave cursor.vpos at the row where the cursor was displayed
14368 during the last redisplay cycle. */
14369 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old
14370 && pt_old <= MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14371 && cursor_row_p (MATRIX_ROW (matrix, w->cursor.vpos)))
14373 struct glyph *g1 =
14374 MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
14376 /* Don't consider glyphs that are outside TEXT_AREA. */
14377 if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
14378 return 0;
14379 /* Keep the candidate whose buffer position is the closest to
14380 point or has the `cursor' property. */
14381 if (/* previous candidate is a glyph in TEXT_AREA of that row */
14382 w->cursor.hpos >= 0
14383 && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
14384 && ((BUFFERP (g1->object)
14385 && (g1->charpos == pt_old /* an exact match always wins */
14386 || (BUFFERP (glyph->object)
14387 && eabs (g1->charpos - pt_old)
14388 < eabs (glyph->charpos - pt_old))))
14389 /* previous candidate is a glyph from a string that has
14390 a non-nil `cursor' property */
14391 || (STRINGP (g1->object)
14392 && (!NILP (Fget_char_property (make_number (g1->charpos),
14393 Qcursor, g1->object))
14394 /* previous candidate is from the same display
14395 string as this one, and the display string
14396 came from a text property */
14397 || (EQ (g1->object, glyph->object)
14398 && string_from_text_prop)
14399 /* this candidate is from newline and its
14400 position is not an exact match */
14401 || (INTEGERP (glyph->object)
14402 && glyph->charpos != pt_old)))))
14403 return 0;
14404 /* If this candidate gives an exact match, use that. */
14405 if (!((BUFFERP (glyph->object) && glyph->charpos == pt_old)
14406 /* If this candidate is a glyph created for the
14407 terminating newline of a line, and point is on that
14408 newline, it wins because it's an exact match. */
14409 || (!row->continued_p
14410 && INTEGERP (glyph->object)
14411 && glyph->charpos == 0
14412 && pt_old == MATRIX_ROW_END_CHARPOS (row) - 1))
14413 /* Otherwise, keep the candidate that comes from a row
14414 spanning less buffer positions. This may win when one or
14415 both candidate positions are on glyphs that came from
14416 display strings, for which we cannot compare buffer
14417 positions. */
14418 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14419 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14420 < MATRIX_ROW_END_CHARPOS (row) - MATRIX_ROW_START_CHARPOS (row))
14421 return 0;
14423 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
14424 w->cursor.x = x;
14425 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
14426 w->cursor.y = row->y + dy;
14428 if (w == XWINDOW (selected_window))
14430 if (!row->continued_p
14431 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
14432 && row->x == 0)
14434 this_line_buffer = XBUFFER (w->contents);
14436 CHARPOS (this_line_start_pos)
14437 = MATRIX_ROW_START_CHARPOS (row) + delta;
14438 BYTEPOS (this_line_start_pos)
14439 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
14441 CHARPOS (this_line_end_pos)
14442 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
14443 BYTEPOS (this_line_end_pos)
14444 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
14446 this_line_y = w->cursor.y;
14447 this_line_pixel_height = row->height;
14448 this_line_vpos = w->cursor.vpos;
14449 this_line_start_x = row->x;
14451 else
14452 CHARPOS (this_line_start_pos) = 0;
14455 return 1;
14459 /* Run window scroll functions, if any, for WINDOW with new window
14460 start STARTP. Sets the window start of WINDOW to that position.
14462 We assume that the window's buffer is really current. */
14464 static struct text_pos
14465 run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
14467 struct window *w = XWINDOW (window);
14468 SET_MARKER_FROM_TEXT_POS (w->start, startp);
14470 eassert (current_buffer == XBUFFER (w->contents));
14472 if (!NILP (Vwindow_scroll_functions))
14474 run_hook_with_args_2 (Qwindow_scroll_functions, window,
14475 make_number (CHARPOS (startp)));
14476 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14477 /* In case the hook functions switch buffers. */
14478 set_buffer_internal (XBUFFER (w->contents));
14481 return startp;
14485 /* Make sure the line containing the cursor is fully visible.
14486 A value of 1 means there is nothing to be done.
14487 (Either the line is fully visible, or it cannot be made so,
14488 or we cannot tell.)
14490 If FORCE_P is non-zero, return 0 even if partial visible cursor row
14491 is higher than window.
14493 A value of 0 means the caller should do scrolling
14494 as if point had gone off the screen. */
14496 static int
14497 cursor_row_fully_visible_p (struct window *w, int force_p, int current_matrix_p)
14499 struct glyph_matrix *matrix;
14500 struct glyph_row *row;
14501 int window_height;
14503 if (!make_cursor_line_fully_visible_p)
14504 return 1;
14506 /* It's not always possible to find the cursor, e.g, when a window
14507 is full of overlay strings. Don't do anything in that case. */
14508 if (w->cursor.vpos < 0)
14509 return 1;
14511 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
14512 row = MATRIX_ROW (matrix, w->cursor.vpos);
14514 /* If the cursor row is not partially visible, there's nothing to do. */
14515 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
14516 return 1;
14518 /* If the row the cursor is in is taller than the window's height,
14519 it's not clear what to do, so do nothing. */
14520 window_height = window_box_height (w);
14521 if (row->height >= window_height)
14523 if (!force_p || MINI_WINDOW_P (w)
14524 || w->vscroll || w->cursor.vpos == 0)
14525 return 1;
14527 return 0;
14531 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
14532 non-zero means only WINDOW is redisplayed in redisplay_internal.
14533 TEMP_SCROLL_STEP has the same meaning as emacs_scroll_step, and is used
14534 in redisplay_window to bring a partially visible line into view in
14535 the case that only the cursor has moved.
14537 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
14538 last screen line's vertical height extends past the end of the screen.
14540 Value is
14542 1 if scrolling succeeded
14544 0 if scrolling didn't find point.
14546 -1 if new fonts have been loaded so that we must interrupt
14547 redisplay, adjust glyph matrices, and try again. */
14549 enum
14551 SCROLLING_SUCCESS,
14552 SCROLLING_FAILED,
14553 SCROLLING_NEED_LARGER_MATRICES
14556 /* If scroll-conservatively is more than this, never recenter.
14558 If you change this, don't forget to update the doc string of
14559 `scroll-conservatively' and the Emacs manual. */
14560 #define SCROLL_LIMIT 100
14562 static int
14563 try_scrolling (Lisp_Object window, int just_this_one_p,
14564 ptrdiff_t arg_scroll_conservatively, ptrdiff_t scroll_step,
14565 int temp_scroll_step, int last_line_misfit)
14567 struct window *w = XWINDOW (window);
14568 struct frame *f = XFRAME (w->frame);
14569 struct text_pos pos, startp;
14570 struct it it;
14571 int this_scroll_margin, scroll_max, rc, height;
14572 int dy = 0, amount_to_scroll = 0, scroll_down_p = 0;
14573 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
14574 Lisp_Object aggressive;
14575 /* We will never try scrolling more than this number of lines. */
14576 int scroll_limit = SCROLL_LIMIT;
14577 int frame_line_height = default_line_pixel_height (w);
14578 int window_total_lines
14579 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
14581 #ifdef GLYPH_DEBUG
14582 debug_method_add (w, "try_scrolling");
14583 #endif
14585 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14587 /* Compute scroll margin height in pixels. We scroll when point is
14588 within this distance from the top or bottom of the window. */
14589 if (scroll_margin > 0)
14590 this_scroll_margin = min (scroll_margin, window_total_lines / 4)
14591 * frame_line_height;
14592 else
14593 this_scroll_margin = 0;
14595 /* Force arg_scroll_conservatively to have a reasonable value, to
14596 avoid scrolling too far away with slow move_it_* functions. Note
14597 that the user can supply scroll-conservatively equal to
14598 `most-positive-fixnum', which can be larger than INT_MAX. */
14599 if (arg_scroll_conservatively > scroll_limit)
14601 arg_scroll_conservatively = scroll_limit + 1;
14602 scroll_max = scroll_limit * frame_line_height;
14604 else if (scroll_step || arg_scroll_conservatively || temp_scroll_step)
14605 /* Compute how much we should try to scroll maximally to bring
14606 point into view. */
14607 scroll_max = (max (scroll_step,
14608 max (arg_scroll_conservatively, temp_scroll_step))
14609 * frame_line_height);
14610 else if (NUMBERP (BVAR (current_buffer, scroll_down_aggressively))
14611 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively)))
14612 /* We're trying to scroll because of aggressive scrolling but no
14613 scroll_step is set. Choose an arbitrary one. */
14614 scroll_max = 10 * frame_line_height;
14615 else
14616 scroll_max = 0;
14618 too_near_end:
14620 /* Decide whether to scroll down. */
14621 if (PT > CHARPOS (startp))
14623 int scroll_margin_y;
14625 /* Compute the pixel ypos of the scroll margin, then move IT to
14626 either that ypos or PT, whichever comes first. */
14627 start_display (&it, w, startp);
14628 scroll_margin_y = it.last_visible_y - this_scroll_margin
14629 - frame_line_height * extra_scroll_margin_lines;
14630 move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
14631 (MOVE_TO_POS | MOVE_TO_Y));
14633 if (PT > CHARPOS (it.current.pos))
14635 int y0 = line_bottom_y (&it);
14636 /* Compute how many pixels below window bottom to stop searching
14637 for PT. This avoids costly search for PT that is far away if
14638 the user limited scrolling by a small number of lines, but
14639 always finds PT if scroll_conservatively is set to a large
14640 number, such as most-positive-fixnum. */
14641 int slack = max (scroll_max, 10 * frame_line_height);
14642 int y_to_move = it.last_visible_y + slack;
14644 /* Compute the distance from the scroll margin to PT or to
14645 the scroll limit, whichever comes first. This should
14646 include the height of the cursor line, to make that line
14647 fully visible. */
14648 move_it_to (&it, PT, -1, y_to_move,
14649 -1, MOVE_TO_POS | MOVE_TO_Y);
14650 dy = line_bottom_y (&it) - y0;
14652 if (dy > scroll_max)
14653 return SCROLLING_FAILED;
14655 if (dy > 0)
14656 scroll_down_p = 1;
14660 if (scroll_down_p)
14662 /* Point is in or below the bottom scroll margin, so move the
14663 window start down. If scrolling conservatively, move it just
14664 enough down to make point visible. If scroll_step is set,
14665 move it down by scroll_step. */
14666 if (arg_scroll_conservatively)
14667 amount_to_scroll
14668 = min (max (dy, frame_line_height),
14669 frame_line_height * arg_scroll_conservatively);
14670 else if (scroll_step || temp_scroll_step)
14671 amount_to_scroll = scroll_max;
14672 else
14674 aggressive = BVAR (current_buffer, scroll_up_aggressively);
14675 height = WINDOW_BOX_TEXT_HEIGHT (w);
14676 if (NUMBERP (aggressive))
14678 double float_amount = XFLOATINT (aggressive) * height;
14679 int aggressive_scroll = float_amount;
14680 if (aggressive_scroll == 0 && float_amount > 0)
14681 aggressive_scroll = 1;
14682 /* Don't let point enter the scroll margin near top of
14683 the window. This could happen if the value of
14684 scroll_up_aggressively is too large and there are
14685 non-zero margins, because scroll_up_aggressively
14686 means put point that fraction of window height
14687 _from_the_bottom_margin_. */
14688 if (aggressive_scroll + 2*this_scroll_margin > height)
14689 aggressive_scroll = height - 2*this_scroll_margin;
14690 amount_to_scroll = dy + aggressive_scroll;
14694 if (amount_to_scroll <= 0)
14695 return SCROLLING_FAILED;
14697 start_display (&it, w, startp);
14698 if (arg_scroll_conservatively <= scroll_limit)
14699 move_it_vertically (&it, amount_to_scroll);
14700 else
14702 /* Extra precision for users who set scroll-conservatively
14703 to a large number: make sure the amount we scroll
14704 the window start is never less than amount_to_scroll,
14705 which was computed as distance from window bottom to
14706 point. This matters when lines at window top and lines
14707 below window bottom have different height. */
14708 struct it it1;
14709 void *it1data = NULL;
14710 /* We use a temporary it1 because line_bottom_y can modify
14711 its argument, if it moves one line down; see there. */
14712 int start_y;
14714 SAVE_IT (it1, it, it1data);
14715 start_y = line_bottom_y (&it1);
14716 do {
14717 RESTORE_IT (&it, &it, it1data);
14718 move_it_by_lines (&it, 1);
14719 SAVE_IT (it1, it, it1data);
14720 } while (line_bottom_y (&it1) - start_y < amount_to_scroll);
14723 /* If STARTP is unchanged, move it down another screen line. */
14724 if (CHARPOS (it.current.pos) == CHARPOS (startp))
14725 move_it_by_lines (&it, 1);
14726 startp = it.current.pos;
14728 else
14730 struct text_pos scroll_margin_pos = startp;
14731 int y_offset = 0;
14733 /* See if point is inside the scroll margin at the top of the
14734 window. */
14735 if (this_scroll_margin)
14737 int y_start;
14739 start_display (&it, w, startp);
14740 y_start = it.current_y;
14741 move_it_vertically (&it, this_scroll_margin);
14742 scroll_margin_pos = it.current.pos;
14743 /* If we didn't move enough before hitting ZV, request
14744 additional amount of scroll, to move point out of the
14745 scroll margin. */
14746 if (IT_CHARPOS (it) == ZV
14747 && it.current_y - y_start < this_scroll_margin)
14748 y_offset = this_scroll_margin - (it.current_y - y_start);
14751 if (PT < CHARPOS (scroll_margin_pos))
14753 /* Point is in the scroll margin at the top of the window or
14754 above what is displayed in the window. */
14755 int y0, y_to_move;
14757 /* Compute the vertical distance from PT to the scroll
14758 margin position. Move as far as scroll_max allows, or
14759 one screenful, or 10 screen lines, whichever is largest.
14760 Give up if distance is greater than scroll_max or if we
14761 didn't reach the scroll margin position. */
14762 SET_TEXT_POS (pos, PT, PT_BYTE);
14763 start_display (&it, w, pos);
14764 y0 = it.current_y;
14765 y_to_move = max (it.last_visible_y,
14766 max (scroll_max, 10 * frame_line_height));
14767 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
14768 y_to_move, -1,
14769 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
14770 dy = it.current_y - y0;
14771 if (dy > scroll_max
14772 || IT_CHARPOS (it) < CHARPOS (scroll_margin_pos))
14773 return SCROLLING_FAILED;
14775 /* Additional scroll for when ZV was too close to point. */
14776 dy += y_offset;
14778 /* Compute new window start. */
14779 start_display (&it, w, startp);
14781 if (arg_scroll_conservatively)
14782 amount_to_scroll = max (dy, frame_line_height *
14783 max (scroll_step, temp_scroll_step));
14784 else if (scroll_step || temp_scroll_step)
14785 amount_to_scroll = scroll_max;
14786 else
14788 aggressive = BVAR (current_buffer, scroll_down_aggressively);
14789 height = WINDOW_BOX_TEXT_HEIGHT (w);
14790 if (NUMBERP (aggressive))
14792 double float_amount = XFLOATINT (aggressive) * height;
14793 int aggressive_scroll = float_amount;
14794 if (aggressive_scroll == 0 && float_amount > 0)
14795 aggressive_scroll = 1;
14796 /* Don't let point enter the scroll margin near
14797 bottom of the window, if the value of
14798 scroll_down_aggressively happens to be too
14799 large. */
14800 if (aggressive_scroll + 2*this_scroll_margin > height)
14801 aggressive_scroll = height - 2*this_scroll_margin;
14802 amount_to_scroll = dy + aggressive_scroll;
14806 if (amount_to_scroll <= 0)
14807 return SCROLLING_FAILED;
14809 move_it_vertically_backward (&it, amount_to_scroll);
14810 startp = it.current.pos;
14814 /* Run window scroll functions. */
14815 startp = run_window_scroll_functions (window, startp);
14817 /* Display the window. Give up if new fonts are loaded, or if point
14818 doesn't appear. */
14819 if (!try_window (window, startp, 0))
14820 rc = SCROLLING_NEED_LARGER_MATRICES;
14821 else if (w->cursor.vpos < 0)
14823 clear_glyph_matrix (w->desired_matrix);
14824 rc = SCROLLING_FAILED;
14826 else
14828 /* Maybe forget recorded base line for line number display. */
14829 if (!just_this_one_p
14830 || current_buffer->clip_changed
14831 || BEG_UNCHANGED < CHARPOS (startp))
14832 w->base_line_number = 0;
14834 /* If cursor ends up on a partially visible line,
14835 treat that as being off the bottom of the screen. */
14836 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0)
14837 /* It's possible that the cursor is on the first line of the
14838 buffer, which is partially obscured due to a vscroll
14839 (Bug#7537). In that case, avoid looping forever . */
14840 && extra_scroll_margin_lines < w->desired_matrix->nrows - 1)
14842 clear_glyph_matrix (w->desired_matrix);
14843 ++extra_scroll_margin_lines;
14844 goto too_near_end;
14846 rc = SCROLLING_SUCCESS;
14849 return rc;
14853 /* Compute a suitable window start for window W if display of W starts
14854 on a continuation line. Value is non-zero if a new window start
14855 was computed.
14857 The new window start will be computed, based on W's width, starting
14858 from the start of the continued line. It is the start of the
14859 screen line with the minimum distance from the old start W->start. */
14861 static int
14862 compute_window_start_on_continuation_line (struct window *w)
14864 struct text_pos pos, start_pos;
14865 int window_start_changed_p = 0;
14867 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
14869 /* If window start is on a continuation line... Window start may be
14870 < BEGV in case there's invisible text at the start of the
14871 buffer (M-x rmail, for example). */
14872 if (CHARPOS (start_pos) > BEGV
14873 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
14875 struct it it;
14876 struct glyph_row *row;
14878 /* Handle the case that the window start is out of range. */
14879 if (CHARPOS (start_pos) < BEGV)
14880 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
14881 else if (CHARPOS (start_pos) > ZV)
14882 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
14884 /* Find the start of the continued line. This should be fast
14885 because find_newline is fast (newline cache). */
14886 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
14887 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
14888 row, DEFAULT_FACE_ID);
14889 reseat_at_previous_visible_line_start (&it);
14891 /* If the line start is "too far" away from the window start,
14892 say it takes too much time to compute a new window start. */
14893 if (CHARPOS (start_pos) - IT_CHARPOS (it)
14894 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
14896 int min_distance, distance;
14898 /* Move forward by display lines to find the new window
14899 start. If window width was enlarged, the new start can
14900 be expected to be > the old start. If window width was
14901 decreased, the new window start will be < the old start.
14902 So, we're looking for the display line start with the
14903 minimum distance from the old window start. */
14904 pos = it.current.pos;
14905 min_distance = INFINITY;
14906 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
14907 distance < min_distance)
14909 min_distance = distance;
14910 pos = it.current.pos;
14911 move_it_by_lines (&it, 1);
14914 /* Set the window start there. */
14915 SET_MARKER_FROM_TEXT_POS (w->start, pos);
14916 window_start_changed_p = 1;
14920 return window_start_changed_p;
14924 /* Try cursor movement in case text has not changed in window WINDOW,
14925 with window start STARTP. Value is
14927 CURSOR_MOVEMENT_SUCCESS if successful
14929 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
14931 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
14932 display. *SCROLL_STEP is set to 1, under certain circumstances, if
14933 we want to scroll as if scroll-step were set to 1. See the code.
14935 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
14936 which case we have to abort this redisplay, and adjust matrices
14937 first. */
14939 enum
14941 CURSOR_MOVEMENT_SUCCESS,
14942 CURSOR_MOVEMENT_CANNOT_BE_USED,
14943 CURSOR_MOVEMENT_MUST_SCROLL,
14944 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
14947 static int
14948 try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_step)
14950 struct window *w = XWINDOW (window);
14951 struct frame *f = XFRAME (w->frame);
14952 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
14954 #ifdef GLYPH_DEBUG
14955 if (inhibit_try_cursor_movement)
14956 return rc;
14957 #endif
14959 /* Previously, there was a check for Lisp integer in the
14960 if-statement below. Now, this field is converted to
14961 ptrdiff_t, thus zero means invalid position in a buffer. */
14962 eassert (w->last_point > 0);
14964 /* Handle case where text has not changed, only point, and it has
14965 not moved off the frame. */
14966 if (/* Point may be in this window. */
14967 PT >= CHARPOS (startp)
14968 /* Selective display hasn't changed. */
14969 && !current_buffer->clip_changed
14970 /* Function force-mode-line-update is used to force a thorough
14971 redisplay. It sets either windows_or_buffers_changed or
14972 update_mode_lines. So don't take a shortcut here for these
14973 cases. */
14974 && !update_mode_lines
14975 && !windows_or_buffers_changed
14976 && !cursor_type_changed
14977 /* Can't use this case if highlighting a region. When a
14978 region exists, cursor movement has to do more than just
14979 set the cursor. */
14980 && markpos_of_region () < 0
14981 && !w->region_showing
14982 && NILP (Vshow_trailing_whitespace)
14983 /* This code is not used for mini-buffer for the sake of the case
14984 of redisplaying to replace an echo area message; since in
14985 that case the mini-buffer contents per se are usually
14986 unchanged. This code is of no real use in the mini-buffer
14987 since the handling of this_line_start_pos, etc., in redisplay
14988 handles the same cases. */
14989 && !EQ (window, minibuf_window)
14990 /* When splitting windows or for new windows, it happens that
14991 redisplay is called with a nil window_end_vpos or one being
14992 larger than the window. This should really be fixed in
14993 window.c. I don't have this on my list, now, so we do
14994 approximately the same as the old redisplay code. --gerd. */
14995 && INTEGERP (w->window_end_vpos)
14996 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
14997 && (FRAME_WINDOW_P (f)
14998 || !overlay_arrow_in_current_buffer_p ()))
15000 int this_scroll_margin, top_scroll_margin;
15001 struct glyph_row *row = NULL;
15002 int frame_line_height = default_line_pixel_height (w);
15003 int window_total_lines
15004 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
15006 #ifdef GLYPH_DEBUG
15007 debug_method_add (w, "cursor movement");
15008 #endif
15010 /* Scroll if point within this distance from the top or bottom
15011 of the window. This is a pixel value. */
15012 if (scroll_margin > 0)
15014 this_scroll_margin = min (scroll_margin, window_total_lines / 4);
15015 this_scroll_margin *= frame_line_height;
15017 else
15018 this_scroll_margin = 0;
15020 top_scroll_margin = this_scroll_margin;
15021 if (WINDOW_WANTS_HEADER_LINE_P (w))
15022 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
15024 /* Start with the row the cursor was displayed during the last
15025 not paused redisplay. Give up if that row is not valid. */
15026 if (w->last_cursor.vpos < 0
15027 || w->last_cursor.vpos >= w->current_matrix->nrows)
15028 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15029 else
15031 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
15032 if (row->mode_line_p)
15033 ++row;
15034 if (!row->enabled_p)
15035 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15038 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
15040 int scroll_p = 0, must_scroll = 0;
15041 int last_y = window_text_bottom_y (w) - this_scroll_margin;
15043 if (PT > w->last_point)
15045 /* Point has moved forward. */
15046 while (MATRIX_ROW_END_CHARPOS (row) < PT
15047 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
15049 eassert (row->enabled_p);
15050 ++row;
15053 /* If the end position of a row equals the start
15054 position of the next row, and PT is at that position,
15055 we would rather display cursor in the next line. */
15056 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15057 && MATRIX_ROW_END_CHARPOS (row) == PT
15058 && row < MATRIX_MODE_LINE_ROW (w->current_matrix)
15059 && MATRIX_ROW_START_CHARPOS (row+1) == PT
15060 && !cursor_row_p (row))
15061 ++row;
15063 /* If within the scroll margin, scroll. Note that
15064 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
15065 the next line would be drawn, and that
15066 this_scroll_margin can be zero. */
15067 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
15068 || PT > MATRIX_ROW_END_CHARPOS (row)
15069 /* Line is completely visible last line in window
15070 and PT is to be set in the next line. */
15071 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
15072 && PT == MATRIX_ROW_END_CHARPOS (row)
15073 && !row->ends_at_zv_p
15074 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
15075 scroll_p = 1;
15077 else if (PT < w->last_point)
15079 /* Cursor has to be moved backward. Note that PT >=
15080 CHARPOS (startp) because of the outer if-statement. */
15081 while (!row->mode_line_p
15082 && (MATRIX_ROW_START_CHARPOS (row) > PT
15083 || (MATRIX_ROW_START_CHARPOS (row) == PT
15084 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
15085 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
15086 row > w->current_matrix->rows
15087 && (row-1)->ends_in_newline_from_string_p))))
15088 && (row->y > top_scroll_margin
15089 || CHARPOS (startp) == BEGV))
15091 eassert (row->enabled_p);
15092 --row;
15095 /* Consider the following case: Window starts at BEGV,
15096 there is invisible, intangible text at BEGV, so that
15097 display starts at some point START > BEGV. It can
15098 happen that we are called with PT somewhere between
15099 BEGV and START. Try to handle that case. */
15100 if (row < w->current_matrix->rows
15101 || row->mode_line_p)
15103 row = w->current_matrix->rows;
15104 if (row->mode_line_p)
15105 ++row;
15108 /* Due to newlines in overlay strings, we may have to
15109 skip forward over overlay strings. */
15110 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15111 && MATRIX_ROW_END_CHARPOS (row) == PT
15112 && !cursor_row_p (row))
15113 ++row;
15115 /* If within the scroll margin, scroll. */
15116 if (row->y < top_scroll_margin
15117 && CHARPOS (startp) != BEGV)
15118 scroll_p = 1;
15120 else
15122 /* Cursor did not move. So don't scroll even if cursor line
15123 is partially visible, as it was so before. */
15124 rc = CURSOR_MOVEMENT_SUCCESS;
15127 if (PT < MATRIX_ROW_START_CHARPOS (row)
15128 || PT > MATRIX_ROW_END_CHARPOS (row))
15130 /* if PT is not in the glyph row, give up. */
15131 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15132 must_scroll = 1;
15134 else if (rc != CURSOR_MOVEMENT_SUCCESS
15135 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
15137 struct glyph_row *row1;
15139 /* If rows are bidi-reordered and point moved, back up
15140 until we find a row that does not belong to a
15141 continuation line. This is because we must consider
15142 all rows of a continued line as candidates for the
15143 new cursor positioning, since row start and end
15144 positions change non-linearly with vertical position
15145 in such rows. */
15146 /* FIXME: Revisit this when glyph ``spilling'' in
15147 continuation lines' rows is implemented for
15148 bidi-reordered rows. */
15149 for (row1 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
15150 MATRIX_ROW_CONTINUATION_LINE_P (row);
15151 --row)
15153 /* If we hit the beginning of the displayed portion
15154 without finding the first row of a continued
15155 line, give up. */
15156 if (row <= row1)
15158 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15159 break;
15161 eassert (row->enabled_p);
15164 if (must_scroll)
15166 else if (rc != CURSOR_MOVEMENT_SUCCESS
15167 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
15168 /* Make sure this isn't a header line by any chance, since
15169 then MATRIX_ROW_PARTIALLY_VISIBLE_P might yield non-zero. */
15170 && !row->mode_line_p
15171 && make_cursor_line_fully_visible_p)
15173 if (PT == MATRIX_ROW_END_CHARPOS (row)
15174 && !row->ends_at_zv_p
15175 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
15176 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15177 else if (row->height > window_box_height (w))
15179 /* If we end up in a partially visible line, let's
15180 make it fully visible, except when it's taller
15181 than the window, in which case we can't do much
15182 about it. */
15183 *scroll_step = 1;
15184 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15186 else
15188 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
15189 if (!cursor_row_fully_visible_p (w, 0, 1))
15190 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15191 else
15192 rc = CURSOR_MOVEMENT_SUCCESS;
15195 else if (scroll_p)
15196 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15197 else if (rc != CURSOR_MOVEMENT_SUCCESS
15198 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
15200 /* With bidi-reordered rows, there could be more than
15201 one candidate row whose start and end positions
15202 occlude point. We need to let set_cursor_from_row
15203 find the best candidate. */
15204 /* FIXME: Revisit this when glyph ``spilling'' in
15205 continuation lines' rows is implemented for
15206 bidi-reordered rows. */
15207 int rv = 0;
15211 int at_zv_p = 0, exact_match_p = 0;
15213 if (MATRIX_ROW_START_CHARPOS (row) <= PT
15214 && PT <= MATRIX_ROW_END_CHARPOS (row)
15215 && cursor_row_p (row))
15216 rv |= set_cursor_from_row (w, row, w->current_matrix,
15217 0, 0, 0, 0);
15218 /* As soon as we've found the exact match for point,
15219 or the first suitable row whose ends_at_zv_p flag
15220 is set, we are done. */
15221 at_zv_p =
15222 MATRIX_ROW (w->current_matrix, w->cursor.vpos)->ends_at_zv_p;
15223 if (rv && !at_zv_p
15224 && w->cursor.hpos >= 0
15225 && w->cursor.hpos < MATRIX_ROW_USED (w->current_matrix,
15226 w->cursor.vpos))
15228 struct glyph_row *candidate =
15229 MATRIX_ROW (w->current_matrix, w->cursor.vpos);
15230 struct glyph *g =
15231 candidate->glyphs[TEXT_AREA] + w->cursor.hpos;
15232 ptrdiff_t endpos = MATRIX_ROW_END_CHARPOS (candidate);
15234 exact_match_p =
15235 (BUFFERP (g->object) && g->charpos == PT)
15236 || (INTEGERP (g->object)
15237 && (g->charpos == PT
15238 || (g->charpos == 0 && endpos - 1 == PT)));
15240 if (rv && (at_zv_p || exact_match_p))
15242 rc = CURSOR_MOVEMENT_SUCCESS;
15243 break;
15245 if (MATRIX_ROW_BOTTOM_Y (row) == last_y)
15246 break;
15247 ++row;
15249 while (((MATRIX_ROW_CONTINUATION_LINE_P (row)
15250 || row->continued_p)
15251 && MATRIX_ROW_BOTTOM_Y (row) <= last_y)
15252 || (MATRIX_ROW_START_CHARPOS (row) == PT
15253 && MATRIX_ROW_BOTTOM_Y (row) < last_y));
15254 /* If we didn't find any candidate rows, or exited the
15255 loop before all the candidates were examined, signal
15256 to the caller that this method failed. */
15257 if (rc != CURSOR_MOVEMENT_SUCCESS
15258 && !(rv
15259 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
15260 && !row->continued_p))
15261 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15262 else if (rv)
15263 rc = CURSOR_MOVEMENT_SUCCESS;
15265 else
15269 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
15271 rc = CURSOR_MOVEMENT_SUCCESS;
15272 break;
15274 ++row;
15276 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15277 && MATRIX_ROW_START_CHARPOS (row) == PT
15278 && cursor_row_p (row));
15283 return rc;
15286 #if !defined USE_TOOLKIT_SCROLL_BARS || defined USE_GTK
15287 static
15288 #endif
15289 void
15290 set_vertical_scroll_bar (struct window *w)
15292 ptrdiff_t start, end, whole;
15294 /* Calculate the start and end positions for the current window.
15295 At some point, it would be nice to choose between scrollbars
15296 which reflect the whole buffer size, with special markers
15297 indicating narrowing, and scrollbars which reflect only the
15298 visible region.
15300 Note that mini-buffers sometimes aren't displaying any text. */
15301 if (!MINI_WINDOW_P (w)
15302 || (w == XWINDOW (minibuf_window)
15303 && NILP (echo_area_buffer[0])))
15305 struct buffer *buf = XBUFFER (w->contents);
15306 whole = BUF_ZV (buf) - BUF_BEGV (buf);
15307 start = marker_position (w->start) - BUF_BEGV (buf);
15308 /* I don't think this is guaranteed to be right. For the
15309 moment, we'll pretend it is. */
15310 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
15312 if (end < start)
15313 end = start;
15314 if (whole < (end - start))
15315 whole = end - start;
15317 else
15318 start = end = whole = 0;
15320 /* Indicate what this scroll bar ought to be displaying now. */
15321 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
15322 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
15323 (w, end - start, whole, start);
15327 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
15328 selected_window is redisplayed.
15330 We can return without actually redisplaying the window if
15331 fonts_changed_p. In that case, redisplay_internal will
15332 retry. */
15334 static void
15335 redisplay_window (Lisp_Object window, int just_this_one_p)
15337 struct window *w = XWINDOW (window);
15338 struct frame *f = XFRAME (w->frame);
15339 struct buffer *buffer = XBUFFER (w->contents);
15340 struct buffer *old = current_buffer;
15341 struct text_pos lpoint, opoint, startp;
15342 int update_mode_line;
15343 int tem;
15344 struct it it;
15345 /* Record it now because it's overwritten. */
15346 int current_matrix_up_to_date_p = 0;
15347 int used_current_matrix_p = 0;
15348 /* This is less strict than current_matrix_up_to_date_p.
15349 It indicates that the buffer contents and narrowing are unchanged. */
15350 int buffer_unchanged_p = 0;
15351 int temp_scroll_step = 0;
15352 ptrdiff_t count = SPECPDL_INDEX ();
15353 int rc;
15354 int centering_position = -1;
15355 int last_line_misfit = 0;
15356 ptrdiff_t beg_unchanged, end_unchanged;
15357 int frame_line_height;
15359 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15360 opoint = lpoint;
15362 #ifdef GLYPH_DEBUG
15363 *w->desired_matrix->method = 0;
15364 #endif
15366 /* Make sure that both W's markers are valid. */
15367 eassert (XMARKER (w->start)->buffer == buffer);
15368 eassert (XMARKER (w->pointm)->buffer == buffer);
15370 restart:
15371 reconsider_clip_changes (w);
15372 frame_line_height = default_line_pixel_height (w);
15374 /* Has the mode line to be updated? */
15375 update_mode_line = (w->update_mode_line
15376 || update_mode_lines
15377 || buffer->clip_changed
15378 || buffer->prevent_redisplay_optimizations_p);
15380 if (MINI_WINDOW_P (w))
15382 if (w == XWINDOW (echo_area_window)
15383 && !NILP (echo_area_buffer[0]))
15385 if (update_mode_line)
15386 /* We may have to update a tty frame's menu bar or a
15387 tool-bar. Example `M-x C-h C-h C-g'. */
15388 goto finish_menu_bars;
15389 else
15390 /* We've already displayed the echo area glyphs in this window. */
15391 goto finish_scroll_bars;
15393 else if ((w != XWINDOW (minibuf_window)
15394 || minibuf_level == 0)
15395 /* When buffer is nonempty, redisplay window normally. */
15396 && BUF_Z (XBUFFER (w->contents)) == BUF_BEG (XBUFFER (w->contents))
15397 /* Quail displays non-mini buffers in minibuffer window.
15398 In that case, redisplay the window normally. */
15399 && !NILP (Fmemq (w->contents, Vminibuffer_list)))
15401 /* W is a mini-buffer window, but it's not active, so clear
15402 it. */
15403 int yb = window_text_bottom_y (w);
15404 struct glyph_row *row;
15405 int y;
15407 for (y = 0, row = w->desired_matrix->rows;
15408 y < yb;
15409 y += row->height, ++row)
15410 blank_row (w, row, y);
15411 goto finish_scroll_bars;
15414 clear_glyph_matrix (w->desired_matrix);
15417 /* Otherwise set up data on this window; select its buffer and point
15418 value. */
15419 /* Really select the buffer, for the sake of buffer-local
15420 variables. */
15421 set_buffer_internal_1 (XBUFFER (w->contents));
15423 current_matrix_up_to_date_p
15424 = (w->window_end_valid
15425 && !current_buffer->clip_changed
15426 && !current_buffer->prevent_redisplay_optimizations_p
15427 && !window_outdated (w));
15429 /* Run the window-bottom-change-functions
15430 if it is possible that the text on the screen has changed
15431 (either due to modification of the text, or any other reason). */
15432 if (!current_matrix_up_to_date_p
15433 && !NILP (Vwindow_text_change_functions))
15435 safe_run_hooks (Qwindow_text_change_functions);
15436 goto restart;
15439 beg_unchanged = BEG_UNCHANGED;
15440 end_unchanged = END_UNCHANGED;
15442 SET_TEXT_POS (opoint, PT, PT_BYTE);
15444 specbind (Qinhibit_point_motion_hooks, Qt);
15446 buffer_unchanged_p
15447 = (w->window_end_valid
15448 && !current_buffer->clip_changed
15449 && !window_outdated (w));
15451 /* When windows_or_buffers_changed is non-zero, we can't rely on
15452 the window end being valid, so set it to nil there. */
15453 if (windows_or_buffers_changed)
15455 /* If window starts on a continuation line, maybe adjust the
15456 window start in case the window's width changed. */
15457 if (XMARKER (w->start)->buffer == current_buffer)
15458 compute_window_start_on_continuation_line (w);
15460 w->window_end_valid = 0;
15463 /* Some sanity checks. */
15464 CHECK_WINDOW_END (w);
15465 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
15466 emacs_abort ();
15467 if (BYTEPOS (opoint) < CHARPOS (opoint))
15468 emacs_abort ();
15470 if (mode_line_update_needed (w))
15471 update_mode_line = 1;
15473 /* Point refers normally to the selected window. For any other
15474 window, set up appropriate value. */
15475 if (!EQ (window, selected_window))
15477 ptrdiff_t new_pt = marker_position (w->pointm);
15478 ptrdiff_t new_pt_byte = marker_byte_position (w->pointm);
15479 if (new_pt < BEGV)
15481 new_pt = BEGV;
15482 new_pt_byte = BEGV_BYTE;
15483 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
15485 else if (new_pt > (ZV - 1))
15487 new_pt = ZV;
15488 new_pt_byte = ZV_BYTE;
15489 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
15492 /* We don't use SET_PT so that the point-motion hooks don't run. */
15493 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
15496 /* If any of the character widths specified in the display table
15497 have changed, invalidate the width run cache. It's true that
15498 this may be a bit late to catch such changes, but the rest of
15499 redisplay goes (non-fatally) haywire when the display table is
15500 changed, so why should we worry about doing any better? */
15501 if (current_buffer->width_run_cache)
15503 struct Lisp_Char_Table *disptab = buffer_display_table ();
15505 if (! disptab_matches_widthtab
15506 (disptab, XVECTOR (BVAR (current_buffer, width_table))))
15508 invalidate_region_cache (current_buffer,
15509 current_buffer->width_run_cache,
15510 BEG, Z);
15511 recompute_width_table (current_buffer, disptab);
15515 /* If window-start is screwed up, choose a new one. */
15516 if (XMARKER (w->start)->buffer != current_buffer)
15517 goto recenter;
15519 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15521 /* If someone specified a new starting point but did not insist,
15522 check whether it can be used. */
15523 if (w->optional_new_start
15524 && CHARPOS (startp) >= BEGV
15525 && CHARPOS (startp) <= ZV)
15527 w->optional_new_start = 0;
15528 start_display (&it, w, startp);
15529 move_it_to (&it, PT, 0, it.last_visible_y, -1,
15530 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
15531 if (IT_CHARPOS (it) == PT)
15532 w->force_start = 1;
15533 /* IT may overshoot PT if text at PT is invisible. */
15534 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
15535 w->force_start = 1;
15538 force_start:
15540 /* Handle case where place to start displaying has been specified,
15541 unless the specified location is outside the accessible range. */
15542 if (w->force_start || window_frozen_p (w))
15544 /* We set this later on if we have to adjust point. */
15545 int new_vpos = -1;
15547 w->force_start = 0;
15548 w->vscroll = 0;
15549 w->window_end_valid = 0;
15551 /* Forget any recorded base line for line number display. */
15552 if (!buffer_unchanged_p)
15553 w->base_line_number = 0;
15555 /* Redisplay the mode line. Select the buffer properly for that.
15556 Also, run the hook window-scroll-functions
15557 because we have scrolled. */
15558 /* Note, we do this after clearing force_start because
15559 if there's an error, it is better to forget about force_start
15560 than to get into an infinite loop calling the hook functions
15561 and having them get more errors. */
15562 if (!update_mode_line
15563 || ! NILP (Vwindow_scroll_functions))
15565 update_mode_line = 1;
15566 w->update_mode_line = 1;
15567 startp = run_window_scroll_functions (window, startp);
15570 if (CHARPOS (startp) < BEGV)
15571 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
15572 else if (CHARPOS (startp) > ZV)
15573 SET_TEXT_POS (startp, ZV, ZV_BYTE);
15575 /* Redisplay, then check if cursor has been set during the
15576 redisplay. Give up if new fonts were loaded. */
15577 /* We used to issue a CHECK_MARGINS argument to try_window here,
15578 but this causes scrolling to fail when point begins inside
15579 the scroll margin (bug#148) -- cyd */
15580 if (!try_window (window, startp, 0))
15582 w->force_start = 1;
15583 clear_glyph_matrix (w->desired_matrix);
15584 goto need_larger_matrices;
15587 if (w->cursor.vpos < 0 && !window_frozen_p (w))
15589 /* If point does not appear, try to move point so it does
15590 appear. The desired matrix has been built above, so we
15591 can use it here. */
15592 new_vpos = window_box_height (w) / 2;
15595 if (!cursor_row_fully_visible_p (w, 0, 0))
15597 /* Point does appear, but on a line partly visible at end of window.
15598 Move it back to a fully-visible line. */
15599 new_vpos = window_box_height (w);
15601 else if (w->cursor.vpos >=0)
15603 /* Some people insist on not letting point enter the scroll
15604 margin, even though this part handles windows that didn't
15605 scroll at all. */
15606 int window_total_lines
15607 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
15608 int margin = min (scroll_margin, window_total_lines / 4);
15609 int pixel_margin = margin * frame_line_height;
15610 bool header_line = WINDOW_WANTS_HEADER_LINE_P (w);
15612 /* Note: We add an extra FRAME_LINE_HEIGHT, because the loop
15613 below, which finds the row to move point to, advances by
15614 the Y coordinate of the _next_ row, see the definition of
15615 MATRIX_ROW_BOTTOM_Y. */
15616 if (w->cursor.vpos < margin + header_line)
15618 w->cursor.vpos = -1;
15619 clear_glyph_matrix (w->desired_matrix);
15620 goto try_to_scroll;
15622 else
15624 int window_height = window_box_height (w);
15626 if (header_line)
15627 window_height += CURRENT_HEADER_LINE_HEIGHT (w);
15628 if (w->cursor.y >= window_height - pixel_margin)
15630 w->cursor.vpos = -1;
15631 clear_glyph_matrix (w->desired_matrix);
15632 goto try_to_scroll;
15637 /* If we need to move point for either of the above reasons,
15638 now actually do it. */
15639 if (new_vpos >= 0)
15641 struct glyph_row *row;
15643 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
15644 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
15645 ++row;
15647 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
15648 MATRIX_ROW_START_BYTEPOS (row));
15650 if (w != XWINDOW (selected_window))
15651 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
15652 else if (current_buffer == old)
15653 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15655 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
15657 /* If we are highlighting the region, then we just changed
15658 the region, so redisplay to show it. */
15659 if (markpos_of_region () >= 0)
15661 clear_glyph_matrix (w->desired_matrix);
15662 if (!try_window (window, startp, 0))
15663 goto need_larger_matrices;
15667 #ifdef GLYPH_DEBUG
15668 debug_method_add (w, "forced window start");
15669 #endif
15670 goto done;
15673 /* Handle case where text has not changed, only point, and it has
15674 not moved off the frame, and we are not retrying after hscroll.
15675 (current_matrix_up_to_date_p is nonzero when retrying.) */
15676 if (current_matrix_up_to_date_p
15677 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
15678 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
15680 switch (rc)
15682 case CURSOR_MOVEMENT_SUCCESS:
15683 used_current_matrix_p = 1;
15684 goto done;
15686 case CURSOR_MOVEMENT_MUST_SCROLL:
15687 goto try_to_scroll;
15689 default:
15690 emacs_abort ();
15693 /* If current starting point was originally the beginning of a line
15694 but no longer is, find a new starting point. */
15695 else if (w->start_at_line_beg
15696 && !(CHARPOS (startp) <= BEGV
15697 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
15699 #ifdef GLYPH_DEBUG
15700 debug_method_add (w, "recenter 1");
15701 #endif
15702 goto recenter;
15705 /* Try scrolling with try_window_id. Value is > 0 if update has
15706 been done, it is -1 if we know that the same window start will
15707 not work. It is 0 if unsuccessful for some other reason. */
15708 else if ((tem = try_window_id (w)) != 0)
15710 #ifdef GLYPH_DEBUG
15711 debug_method_add (w, "try_window_id %d", tem);
15712 #endif
15714 if (fonts_changed_p)
15715 goto need_larger_matrices;
15716 if (tem > 0)
15717 goto done;
15719 /* Otherwise try_window_id has returned -1 which means that we
15720 don't want the alternative below this comment to execute. */
15722 else if (CHARPOS (startp) >= BEGV
15723 && CHARPOS (startp) <= ZV
15724 && PT >= CHARPOS (startp)
15725 && (CHARPOS (startp) < ZV
15726 /* Avoid starting at end of buffer. */
15727 || CHARPOS (startp) == BEGV
15728 || !window_outdated (w)))
15730 int d1, d2, d3, d4, d5, d6;
15732 /* If first window line is a continuation line, and window start
15733 is inside the modified region, but the first change is before
15734 current window start, we must select a new window start.
15736 However, if this is the result of a down-mouse event (e.g. by
15737 extending the mouse-drag-overlay), we don't want to select a
15738 new window start, since that would change the position under
15739 the mouse, resulting in an unwanted mouse-movement rather
15740 than a simple mouse-click. */
15741 if (!w->start_at_line_beg
15742 && NILP (do_mouse_tracking)
15743 && CHARPOS (startp) > BEGV
15744 && CHARPOS (startp) > BEG + beg_unchanged
15745 && CHARPOS (startp) <= Z - end_unchanged
15746 /* Even if w->start_at_line_beg is nil, a new window may
15747 start at a line_beg, since that's how set_buffer_window
15748 sets it. So, we need to check the return value of
15749 compute_window_start_on_continuation_line. (See also
15750 bug#197). */
15751 && XMARKER (w->start)->buffer == current_buffer
15752 && compute_window_start_on_continuation_line (w)
15753 /* It doesn't make sense to force the window start like we
15754 do at label force_start if it is already known that point
15755 will not be visible in the resulting window, because
15756 doing so will move point from its correct position
15757 instead of scrolling the window to bring point into view.
15758 See bug#9324. */
15759 && pos_visible_p (w, PT, &d1, &d2, &d3, &d4, &d5, &d6))
15761 w->force_start = 1;
15762 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15763 goto force_start;
15766 #ifdef GLYPH_DEBUG
15767 debug_method_add (w, "same window start");
15768 #endif
15770 /* Try to redisplay starting at same place as before.
15771 If point has not moved off frame, accept the results. */
15772 if (!current_matrix_up_to_date_p
15773 /* Don't use try_window_reusing_current_matrix in this case
15774 because a window scroll function can have changed the
15775 buffer. */
15776 || !NILP (Vwindow_scroll_functions)
15777 || MINI_WINDOW_P (w)
15778 || !(used_current_matrix_p
15779 = try_window_reusing_current_matrix (w)))
15781 IF_DEBUG (debug_method_add (w, "1"));
15782 if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
15783 /* -1 means we need to scroll.
15784 0 means we need new matrices, but fonts_changed_p
15785 is set in that case, so we will detect it below. */
15786 goto try_to_scroll;
15789 if (fonts_changed_p)
15790 goto need_larger_matrices;
15792 if (w->cursor.vpos >= 0)
15794 if (!just_this_one_p
15795 || current_buffer->clip_changed
15796 || BEG_UNCHANGED < CHARPOS (startp))
15797 /* Forget any recorded base line for line number display. */
15798 w->base_line_number = 0;
15800 if (!cursor_row_fully_visible_p (w, 1, 0))
15802 clear_glyph_matrix (w->desired_matrix);
15803 last_line_misfit = 1;
15805 /* Drop through and scroll. */
15806 else
15807 goto done;
15809 else
15810 clear_glyph_matrix (w->desired_matrix);
15813 try_to_scroll:
15815 /* Redisplay the mode line. Select the buffer properly for that. */
15816 if (!update_mode_line)
15818 update_mode_line = 1;
15819 w->update_mode_line = 1;
15822 /* Try to scroll by specified few lines. */
15823 if ((scroll_conservatively
15824 || emacs_scroll_step
15825 || temp_scroll_step
15826 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively))
15827 || NUMBERP (BVAR (current_buffer, scroll_down_aggressively)))
15828 && CHARPOS (startp) >= BEGV
15829 && CHARPOS (startp) <= ZV)
15831 /* The function returns -1 if new fonts were loaded, 1 if
15832 successful, 0 if not successful. */
15833 int ss = try_scrolling (window, just_this_one_p,
15834 scroll_conservatively,
15835 emacs_scroll_step,
15836 temp_scroll_step, last_line_misfit);
15837 switch (ss)
15839 case SCROLLING_SUCCESS:
15840 goto done;
15842 case SCROLLING_NEED_LARGER_MATRICES:
15843 goto need_larger_matrices;
15845 case SCROLLING_FAILED:
15846 break;
15848 default:
15849 emacs_abort ();
15853 /* Finally, just choose a place to start which positions point
15854 according to user preferences. */
15856 recenter:
15858 #ifdef GLYPH_DEBUG
15859 debug_method_add (w, "recenter");
15860 #endif
15862 /* Forget any previously recorded base line for line number display. */
15863 if (!buffer_unchanged_p)
15864 w->base_line_number = 0;
15866 /* Determine the window start relative to point. */
15867 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
15868 it.current_y = it.last_visible_y;
15869 if (centering_position < 0)
15871 int window_total_lines
15872 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
15873 int margin =
15874 scroll_margin > 0
15875 ? min (scroll_margin, window_total_lines / 4)
15876 : 0;
15877 ptrdiff_t margin_pos = CHARPOS (startp);
15878 Lisp_Object aggressive;
15879 int scrolling_up;
15881 /* If there is a scroll margin at the top of the window, find
15882 its character position. */
15883 if (margin
15884 /* Cannot call start_display if startp is not in the
15885 accessible region of the buffer. This can happen when we
15886 have just switched to a different buffer and/or changed
15887 its restriction. In that case, startp is initialized to
15888 the character position 1 (BEGV) because we did not yet
15889 have chance to display the buffer even once. */
15890 && BEGV <= CHARPOS (startp) && CHARPOS (startp) <= ZV)
15892 struct it it1;
15893 void *it1data = NULL;
15895 SAVE_IT (it1, it, it1data);
15896 start_display (&it1, w, startp);
15897 move_it_vertically (&it1, margin * frame_line_height);
15898 margin_pos = IT_CHARPOS (it1);
15899 RESTORE_IT (&it, &it, it1data);
15901 scrolling_up = PT > margin_pos;
15902 aggressive =
15903 scrolling_up
15904 ? BVAR (current_buffer, scroll_up_aggressively)
15905 : BVAR (current_buffer, scroll_down_aggressively);
15907 if (!MINI_WINDOW_P (w)
15908 && (scroll_conservatively > SCROLL_LIMIT || NUMBERP (aggressive)))
15910 int pt_offset = 0;
15912 /* Setting scroll-conservatively overrides
15913 scroll-*-aggressively. */
15914 if (!scroll_conservatively && NUMBERP (aggressive))
15916 double float_amount = XFLOATINT (aggressive);
15918 pt_offset = float_amount * WINDOW_BOX_TEXT_HEIGHT (w);
15919 if (pt_offset == 0 && float_amount > 0)
15920 pt_offset = 1;
15921 if (pt_offset && margin > 0)
15922 margin -= 1;
15924 /* Compute how much to move the window start backward from
15925 point so that point will be displayed where the user
15926 wants it. */
15927 if (scrolling_up)
15929 centering_position = it.last_visible_y;
15930 if (pt_offset)
15931 centering_position -= pt_offset;
15932 centering_position -=
15933 frame_line_height * (1 + margin + (last_line_misfit != 0))
15934 + WINDOW_HEADER_LINE_HEIGHT (w);
15935 /* Don't let point enter the scroll margin near top of
15936 the window. */
15937 if (centering_position < margin * frame_line_height)
15938 centering_position = margin * frame_line_height;
15940 else
15941 centering_position = margin * frame_line_height + pt_offset;
15943 else
15944 /* Set the window start half the height of the window backward
15945 from point. */
15946 centering_position = window_box_height (w) / 2;
15948 move_it_vertically_backward (&it, centering_position);
15950 eassert (IT_CHARPOS (it) >= BEGV);
15952 /* The function move_it_vertically_backward may move over more
15953 than the specified y-distance. If it->w is small, e.g. a
15954 mini-buffer window, we may end up in front of the window's
15955 display area. Start displaying at the start of the line
15956 containing PT in this case. */
15957 if (it.current_y <= 0)
15959 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
15960 move_it_vertically_backward (&it, 0);
15961 it.current_y = 0;
15964 it.current_x = it.hpos = 0;
15966 /* Set the window start position here explicitly, to avoid an
15967 infinite loop in case the functions in window-scroll-functions
15968 get errors. */
15969 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
15971 /* Run scroll hooks. */
15972 startp = run_window_scroll_functions (window, it.current.pos);
15974 /* Redisplay the window. */
15975 if (!current_matrix_up_to_date_p
15976 || windows_or_buffers_changed
15977 || cursor_type_changed
15978 /* Don't use try_window_reusing_current_matrix in this case
15979 because it can have changed the buffer. */
15980 || !NILP (Vwindow_scroll_functions)
15981 || !just_this_one_p
15982 || MINI_WINDOW_P (w)
15983 || !(used_current_matrix_p
15984 = try_window_reusing_current_matrix (w)))
15985 try_window (window, startp, 0);
15987 /* If new fonts have been loaded (due to fontsets), give up. We
15988 have to start a new redisplay since we need to re-adjust glyph
15989 matrices. */
15990 if (fonts_changed_p)
15991 goto need_larger_matrices;
15993 /* If cursor did not appear assume that the middle of the window is
15994 in the first line of the window. Do it again with the next line.
15995 (Imagine a window of height 100, displaying two lines of height
15996 60. Moving back 50 from it->last_visible_y will end in the first
15997 line.) */
15998 if (w->cursor.vpos < 0)
16000 if (w->window_end_valid && PT >= Z - XFASTINT (w->window_end_pos))
16002 clear_glyph_matrix (w->desired_matrix);
16003 move_it_by_lines (&it, 1);
16004 try_window (window, it.current.pos, 0);
16006 else if (PT < IT_CHARPOS (it))
16008 clear_glyph_matrix (w->desired_matrix);
16009 move_it_by_lines (&it, -1);
16010 try_window (window, it.current.pos, 0);
16012 else
16014 /* Not much we can do about it. */
16018 /* Consider the following case: Window starts at BEGV, there is
16019 invisible, intangible text at BEGV, so that display starts at
16020 some point START > BEGV. It can happen that we are called with
16021 PT somewhere between BEGV and START. Try to handle that case. */
16022 if (w->cursor.vpos < 0)
16024 struct glyph_row *row = w->current_matrix->rows;
16025 if (row->mode_line_p)
16026 ++row;
16027 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
16030 if (!cursor_row_fully_visible_p (w, 0, 0))
16032 /* If vscroll is enabled, disable it and try again. */
16033 if (w->vscroll)
16035 w->vscroll = 0;
16036 clear_glyph_matrix (w->desired_matrix);
16037 goto recenter;
16040 /* Users who set scroll-conservatively to a large number want
16041 point just above/below the scroll margin. If we ended up
16042 with point's row partially visible, move the window start to
16043 make that row fully visible and out of the margin. */
16044 if (scroll_conservatively > SCROLL_LIMIT)
16046 int window_total_lines
16047 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) * frame_line_height;
16048 int margin =
16049 scroll_margin > 0
16050 ? min (scroll_margin, window_total_lines / 4)
16051 : 0;
16052 int move_down = w->cursor.vpos >= window_total_lines / 2;
16054 move_it_by_lines (&it, move_down ? margin + 1 : -(margin + 1));
16055 clear_glyph_matrix (w->desired_matrix);
16056 if (1 == try_window (window, it.current.pos,
16057 TRY_WINDOW_CHECK_MARGINS))
16058 goto done;
16061 /* If centering point failed to make the whole line visible,
16062 put point at the top instead. That has to make the whole line
16063 visible, if it can be done. */
16064 if (centering_position == 0)
16065 goto done;
16067 clear_glyph_matrix (w->desired_matrix);
16068 centering_position = 0;
16069 goto recenter;
16072 done:
16074 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16075 w->start_at_line_beg = (CHARPOS (startp) == BEGV
16076 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n');
16078 /* Display the mode line, if we must. */
16079 if ((update_mode_line
16080 /* If window not full width, must redo its mode line
16081 if (a) the window to its side is being redone and
16082 (b) we do a frame-based redisplay. This is a consequence
16083 of how inverted lines are drawn in frame-based redisplay. */
16084 || (!just_this_one_p
16085 && !FRAME_WINDOW_P (f)
16086 && !WINDOW_FULL_WIDTH_P (w))
16087 /* Line number to display. */
16088 || w->base_line_pos > 0
16089 /* Column number is displayed and different from the one displayed. */
16090 || (w->column_number_displayed != -1
16091 && (w->column_number_displayed != current_column ())))
16092 /* This means that the window has a mode line. */
16093 && (WINDOW_WANTS_MODELINE_P (w)
16094 || WINDOW_WANTS_HEADER_LINE_P (w)))
16096 display_mode_lines (w);
16098 /* If mode line height has changed, arrange for a thorough
16099 immediate redisplay using the correct mode line height. */
16100 if (WINDOW_WANTS_MODELINE_P (w)
16101 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
16103 fonts_changed_p = 1;
16104 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
16105 = DESIRED_MODE_LINE_HEIGHT (w);
16108 /* If header line height has changed, arrange for a thorough
16109 immediate redisplay using the correct header line height. */
16110 if (WINDOW_WANTS_HEADER_LINE_P (w)
16111 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
16113 fonts_changed_p = 1;
16114 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
16115 = DESIRED_HEADER_LINE_HEIGHT (w);
16118 if (fonts_changed_p)
16119 goto need_larger_matrices;
16122 if (!line_number_displayed && w->base_line_pos != -1)
16124 w->base_line_pos = 0;
16125 w->base_line_number = 0;
16128 finish_menu_bars:
16130 /* When we reach a frame's selected window, redo the frame's menu bar. */
16131 if (update_mode_line
16132 && EQ (FRAME_SELECTED_WINDOW (f), window))
16134 int redisplay_menu_p = 0;
16136 if (FRAME_WINDOW_P (f))
16138 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
16139 || defined (HAVE_NS) || defined (USE_GTK)
16140 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
16141 #else
16142 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
16143 #endif
16145 else
16146 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
16148 if (redisplay_menu_p)
16149 display_menu_bar (w);
16151 #ifdef HAVE_WINDOW_SYSTEM
16152 if (FRAME_WINDOW_P (f))
16154 #if defined (USE_GTK) || defined (HAVE_NS)
16155 if (FRAME_EXTERNAL_TOOL_BAR (f))
16156 redisplay_tool_bar (f);
16157 #else
16158 if (WINDOWP (f->tool_bar_window)
16159 && (FRAME_TOOL_BAR_LINES (f) > 0
16160 || !NILP (Vauto_resize_tool_bars))
16161 && redisplay_tool_bar (f))
16162 ignore_mouse_drag_p = 1;
16163 #endif
16165 #endif
16168 #ifdef HAVE_WINDOW_SYSTEM
16169 if (FRAME_WINDOW_P (f)
16170 && update_window_fringes (w, (just_this_one_p
16171 || (!used_current_matrix_p && !overlay_arrow_seen)
16172 || w->pseudo_window_p)))
16174 update_begin (f);
16175 block_input ();
16176 if (draw_window_fringes (w, 1))
16177 x_draw_vertical_border (w);
16178 unblock_input ();
16179 update_end (f);
16181 #endif /* HAVE_WINDOW_SYSTEM */
16183 /* We go to this label, with fonts_changed_p set,
16184 if it is necessary to try again using larger glyph matrices.
16185 We have to redeem the scroll bar even in this case,
16186 because the loop in redisplay_internal expects that. */
16187 need_larger_matrices:
16189 finish_scroll_bars:
16191 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
16193 /* Set the thumb's position and size. */
16194 set_vertical_scroll_bar (w);
16196 /* Note that we actually used the scroll bar attached to this
16197 window, so it shouldn't be deleted at the end of redisplay. */
16198 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
16199 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
16202 /* Restore current_buffer and value of point in it. The window
16203 update may have changed the buffer, so first make sure `opoint'
16204 is still valid (Bug#6177). */
16205 if (CHARPOS (opoint) < BEGV)
16206 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
16207 else if (CHARPOS (opoint) > ZV)
16208 TEMP_SET_PT_BOTH (Z, Z_BYTE);
16209 else
16210 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
16212 set_buffer_internal_1 (old);
16213 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
16214 shorter. This can be caused by log truncation in *Messages*. */
16215 if (CHARPOS (lpoint) <= ZV)
16216 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
16218 unbind_to (count, Qnil);
16222 /* Build the complete desired matrix of WINDOW with a window start
16223 buffer position POS.
16225 Value is 1 if successful. It is zero if fonts were loaded during
16226 redisplay which makes re-adjusting glyph matrices necessary, and -1
16227 if point would appear in the scroll margins.
16228 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
16229 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
16230 set in FLAGS.) */
16233 try_window (Lisp_Object window, struct text_pos pos, int flags)
16235 struct window *w = XWINDOW (window);
16236 struct it it;
16237 struct glyph_row *last_text_row = NULL;
16238 struct frame *f = XFRAME (w->frame);
16239 int frame_line_height = default_line_pixel_height (w);
16241 /* Make POS the new window start. */
16242 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
16244 /* Mark cursor position as unknown. No overlay arrow seen. */
16245 w->cursor.vpos = -1;
16246 overlay_arrow_seen = 0;
16248 /* Initialize iterator and info to start at POS. */
16249 start_display (&it, w, pos);
16251 /* Display all lines of W. */
16252 while (it.current_y < it.last_visible_y)
16254 if (display_line (&it))
16255 last_text_row = it.glyph_row - 1;
16256 if (fonts_changed_p && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
16257 return 0;
16260 /* Don't let the cursor end in the scroll margins. */
16261 if ((flags & TRY_WINDOW_CHECK_MARGINS)
16262 && !MINI_WINDOW_P (w))
16264 int this_scroll_margin;
16265 int window_total_lines
16266 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
16268 if (scroll_margin > 0)
16270 this_scroll_margin = min (scroll_margin, window_total_lines / 4);
16271 this_scroll_margin *= frame_line_height;
16273 else
16274 this_scroll_margin = 0;
16276 if ((w->cursor.y >= 0 /* not vscrolled */
16277 && w->cursor.y < this_scroll_margin
16278 && CHARPOS (pos) > BEGV
16279 && IT_CHARPOS (it) < ZV)
16280 /* rms: considering make_cursor_line_fully_visible_p here
16281 seems to give wrong results. We don't want to recenter
16282 when the last line is partly visible, we want to allow
16283 that case to be handled in the usual way. */
16284 || w->cursor.y > it.last_visible_y - this_scroll_margin - 1)
16286 w->cursor.vpos = -1;
16287 clear_glyph_matrix (w->desired_matrix);
16288 return -1;
16292 /* If bottom moved off end of frame, change mode line percentage. */
16293 if (XFASTINT (w->window_end_pos) <= 0
16294 && Z != IT_CHARPOS (it))
16295 w->update_mode_line = 1;
16297 /* Set window_end_pos to the offset of the last character displayed
16298 on the window from the end of current_buffer. Set
16299 window_end_vpos to its row number. */
16300 if (last_text_row)
16302 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
16303 w->window_end_bytepos
16304 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16305 wset_window_end_pos
16306 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
16307 wset_window_end_vpos
16308 (w, make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix)));
16309 eassert
16310 (MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->desired_matrix,
16311 XFASTINT (w->window_end_vpos))));
16313 else
16315 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
16316 wset_window_end_pos (w, make_number (Z - ZV));
16317 wset_window_end_vpos (w, make_number (0));
16320 /* But that is not valid info until redisplay finishes. */
16321 w->window_end_valid = 0;
16322 return 1;
16327 /************************************************************************
16328 Window redisplay reusing current matrix when buffer has not changed
16329 ************************************************************************/
16331 /* Try redisplay of window W showing an unchanged buffer with a
16332 different window start than the last time it was displayed by
16333 reusing its current matrix. Value is non-zero if successful.
16334 W->start is the new window start. */
16336 static int
16337 try_window_reusing_current_matrix (struct window *w)
16339 struct frame *f = XFRAME (w->frame);
16340 struct glyph_row *bottom_row;
16341 struct it it;
16342 struct run run;
16343 struct text_pos start, new_start;
16344 int nrows_scrolled, i;
16345 struct glyph_row *last_text_row;
16346 struct glyph_row *last_reused_text_row;
16347 struct glyph_row *start_row;
16348 int start_vpos, min_y, max_y;
16350 #ifdef GLYPH_DEBUG
16351 if (inhibit_try_window_reusing)
16352 return 0;
16353 #endif
16355 if (/* This function doesn't handle terminal frames. */
16356 !FRAME_WINDOW_P (f)
16357 /* Don't try to reuse the display if windows have been split
16358 or such. */
16359 || windows_or_buffers_changed
16360 || cursor_type_changed)
16361 return 0;
16363 /* Can't do this if region may have changed. */
16364 if (markpos_of_region () >= 0
16365 || w->region_showing
16366 || !NILP (Vshow_trailing_whitespace))
16367 return 0;
16369 /* If top-line visibility has changed, give up. */
16370 if (WINDOW_WANTS_HEADER_LINE_P (w)
16371 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
16372 return 0;
16374 /* Give up if old or new display is scrolled vertically. We could
16375 make this function handle this, but right now it doesn't. */
16376 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16377 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
16378 return 0;
16380 /* The variable new_start now holds the new window start. The old
16381 start `start' can be determined from the current matrix. */
16382 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
16383 start = start_row->minpos;
16384 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
16386 /* Clear the desired matrix for the display below. */
16387 clear_glyph_matrix (w->desired_matrix);
16389 if (CHARPOS (new_start) <= CHARPOS (start))
16391 /* Don't use this method if the display starts with an ellipsis
16392 displayed for invisible text. It's not easy to handle that case
16393 below, and it's certainly not worth the effort since this is
16394 not a frequent case. */
16395 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
16396 return 0;
16398 IF_DEBUG (debug_method_add (w, "twu1"));
16400 /* Display up to a row that can be reused. The variable
16401 last_text_row is set to the last row displayed that displays
16402 text. Note that it.vpos == 0 if or if not there is a
16403 header-line; it's not the same as the MATRIX_ROW_VPOS! */
16404 start_display (&it, w, new_start);
16405 w->cursor.vpos = -1;
16406 last_text_row = last_reused_text_row = NULL;
16408 while (it.current_y < it.last_visible_y
16409 && !fonts_changed_p)
16411 /* If we have reached into the characters in the START row,
16412 that means the line boundaries have changed. So we
16413 can't start copying with the row START. Maybe it will
16414 work to start copying with the following row. */
16415 while (IT_CHARPOS (it) > CHARPOS (start))
16417 /* Advance to the next row as the "start". */
16418 start_row++;
16419 start = start_row->minpos;
16420 /* If there are no more rows to try, or just one, give up. */
16421 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
16422 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
16423 || CHARPOS (start) == ZV)
16425 clear_glyph_matrix (w->desired_matrix);
16426 return 0;
16429 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
16431 /* If we have reached alignment, we can copy the rest of the
16432 rows. */
16433 if (IT_CHARPOS (it) == CHARPOS (start)
16434 /* Don't accept "alignment" inside a display vector,
16435 since start_row could have started in the middle of
16436 that same display vector (thus their character
16437 positions match), and we have no way of telling if
16438 that is the case. */
16439 && it.current.dpvec_index < 0)
16440 break;
16442 if (display_line (&it))
16443 last_text_row = it.glyph_row - 1;
16447 /* A value of current_y < last_visible_y means that we stopped
16448 at the previous window start, which in turn means that we
16449 have at least one reusable row. */
16450 if (it.current_y < it.last_visible_y)
16452 struct glyph_row *row;
16454 /* IT.vpos always starts from 0; it counts text lines. */
16455 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
16457 /* Find PT if not already found in the lines displayed. */
16458 if (w->cursor.vpos < 0)
16460 int dy = it.current_y - start_row->y;
16462 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16463 row = row_containing_pos (w, PT, row, NULL, dy);
16464 if (row)
16465 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
16466 dy, nrows_scrolled);
16467 else
16469 clear_glyph_matrix (w->desired_matrix);
16470 return 0;
16474 /* Scroll the display. Do it before the current matrix is
16475 changed. The problem here is that update has not yet
16476 run, i.e. part of the current matrix is not up to date.
16477 scroll_run_hook will clear the cursor, and use the
16478 current matrix to get the height of the row the cursor is
16479 in. */
16480 run.current_y = start_row->y;
16481 run.desired_y = it.current_y;
16482 run.height = it.last_visible_y - it.current_y;
16484 if (run.height > 0 && run.current_y != run.desired_y)
16486 update_begin (f);
16487 FRAME_RIF (f)->update_window_begin_hook (w);
16488 FRAME_RIF (f)->clear_window_mouse_face (w);
16489 FRAME_RIF (f)->scroll_run_hook (w, &run);
16490 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
16491 update_end (f);
16494 /* Shift current matrix down by nrows_scrolled lines. */
16495 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
16496 rotate_matrix (w->current_matrix,
16497 start_vpos,
16498 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
16499 nrows_scrolled);
16501 /* Disable lines that must be updated. */
16502 for (i = 0; i < nrows_scrolled; ++i)
16503 (start_row + i)->enabled_p = 0;
16505 /* Re-compute Y positions. */
16506 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
16507 max_y = it.last_visible_y;
16508 for (row = start_row + nrows_scrolled;
16509 row < bottom_row;
16510 ++row)
16512 row->y = it.current_y;
16513 row->visible_height = row->height;
16515 if (row->y < min_y)
16516 row->visible_height -= min_y - row->y;
16517 if (row->y + row->height > max_y)
16518 row->visible_height -= row->y + row->height - max_y;
16519 if (row->fringe_bitmap_periodic_p)
16520 row->redraw_fringe_bitmaps_p = 1;
16522 it.current_y += row->height;
16524 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16525 last_reused_text_row = row;
16526 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
16527 break;
16530 /* Disable lines in the current matrix which are now
16531 below the window. */
16532 for (++row; row < bottom_row; ++row)
16533 row->enabled_p = row->mode_line_p = 0;
16536 /* Update window_end_pos etc.; last_reused_text_row is the last
16537 reused row from the current matrix containing text, if any.
16538 The value of last_text_row is the last displayed line
16539 containing text. */
16540 if (last_reused_text_row)
16542 w->window_end_bytepos
16543 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
16544 wset_window_end_pos
16545 (w, make_number (Z
16546 - MATRIX_ROW_END_CHARPOS (last_reused_text_row)));
16547 wset_window_end_vpos
16548 (w, make_number (MATRIX_ROW_VPOS (last_reused_text_row,
16549 w->current_matrix)));
16551 else if (last_text_row)
16553 w->window_end_bytepos
16554 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16555 wset_window_end_pos
16556 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
16557 wset_window_end_vpos
16558 (w, make_number (MATRIX_ROW_VPOS (last_text_row,
16559 w->desired_matrix)));
16561 else
16563 /* This window must be completely empty. */
16564 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
16565 wset_window_end_pos (w, make_number (Z - ZV));
16566 wset_window_end_vpos (w, make_number (0));
16568 w->window_end_valid = 0;
16570 /* Update hint: don't try scrolling again in update_window. */
16571 w->desired_matrix->no_scrolling_p = 1;
16573 #ifdef GLYPH_DEBUG
16574 debug_method_add (w, "try_window_reusing_current_matrix 1");
16575 #endif
16576 return 1;
16578 else if (CHARPOS (new_start) > CHARPOS (start))
16580 struct glyph_row *pt_row, *row;
16581 struct glyph_row *first_reusable_row;
16582 struct glyph_row *first_row_to_display;
16583 int dy;
16584 int yb = window_text_bottom_y (w);
16586 /* Find the row starting at new_start, if there is one. Don't
16587 reuse a partially visible line at the end. */
16588 first_reusable_row = start_row;
16589 while (first_reusable_row->enabled_p
16590 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
16591 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
16592 < CHARPOS (new_start)))
16593 ++first_reusable_row;
16595 /* Give up if there is no row to reuse. */
16596 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
16597 || !first_reusable_row->enabled_p
16598 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
16599 != CHARPOS (new_start)))
16600 return 0;
16602 /* We can reuse fully visible rows beginning with
16603 first_reusable_row to the end of the window. Set
16604 first_row_to_display to the first row that cannot be reused.
16605 Set pt_row to the row containing point, if there is any. */
16606 pt_row = NULL;
16607 for (first_row_to_display = first_reusable_row;
16608 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
16609 ++first_row_to_display)
16611 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
16612 && (PT < MATRIX_ROW_END_CHARPOS (first_row_to_display)
16613 || (PT == MATRIX_ROW_END_CHARPOS (first_row_to_display)
16614 && first_row_to_display->ends_at_zv_p
16615 && pt_row == NULL)))
16616 pt_row = first_row_to_display;
16619 /* Start displaying at the start of first_row_to_display. */
16620 eassert (first_row_to_display->y < yb);
16621 init_to_row_start (&it, w, first_row_to_display);
16623 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
16624 - start_vpos);
16625 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
16626 - nrows_scrolled);
16627 it.current_y = (first_row_to_display->y - first_reusable_row->y
16628 + WINDOW_HEADER_LINE_HEIGHT (w));
16630 /* Display lines beginning with first_row_to_display in the
16631 desired matrix. Set last_text_row to the last row displayed
16632 that displays text. */
16633 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
16634 if (pt_row == NULL)
16635 w->cursor.vpos = -1;
16636 last_text_row = NULL;
16637 while (it.current_y < it.last_visible_y && !fonts_changed_p)
16638 if (display_line (&it))
16639 last_text_row = it.glyph_row - 1;
16641 /* If point is in a reused row, adjust y and vpos of the cursor
16642 position. */
16643 if (pt_row)
16645 w->cursor.vpos -= nrows_scrolled;
16646 w->cursor.y -= first_reusable_row->y - start_row->y;
16649 /* Give up if point isn't in a row displayed or reused. (This
16650 also handles the case where w->cursor.vpos < nrows_scrolled
16651 after the calls to display_line, which can happen with scroll
16652 margins. See bug#1295.) */
16653 if (w->cursor.vpos < 0)
16655 clear_glyph_matrix (w->desired_matrix);
16656 return 0;
16659 /* Scroll the display. */
16660 run.current_y = first_reusable_row->y;
16661 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
16662 run.height = it.last_visible_y - run.current_y;
16663 dy = run.current_y - run.desired_y;
16665 if (run.height)
16667 update_begin (f);
16668 FRAME_RIF (f)->update_window_begin_hook (w);
16669 FRAME_RIF (f)->clear_window_mouse_face (w);
16670 FRAME_RIF (f)->scroll_run_hook (w, &run);
16671 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
16672 update_end (f);
16675 /* Adjust Y positions of reused rows. */
16676 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
16677 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
16678 max_y = it.last_visible_y;
16679 for (row = first_reusable_row; row < first_row_to_display; ++row)
16681 row->y -= dy;
16682 row->visible_height = row->height;
16683 if (row->y < min_y)
16684 row->visible_height -= min_y - row->y;
16685 if (row->y + row->height > max_y)
16686 row->visible_height -= row->y + row->height - max_y;
16687 if (row->fringe_bitmap_periodic_p)
16688 row->redraw_fringe_bitmaps_p = 1;
16691 /* Scroll the current matrix. */
16692 eassert (nrows_scrolled > 0);
16693 rotate_matrix (w->current_matrix,
16694 start_vpos,
16695 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
16696 -nrows_scrolled);
16698 /* Disable rows not reused. */
16699 for (row -= nrows_scrolled; row < bottom_row; ++row)
16700 row->enabled_p = 0;
16702 /* Point may have moved to a different line, so we cannot assume that
16703 the previous cursor position is valid; locate the correct row. */
16704 if (pt_row)
16706 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
16707 row < bottom_row
16708 && PT >= MATRIX_ROW_END_CHARPOS (row)
16709 && !row->ends_at_zv_p;
16710 row++)
16712 w->cursor.vpos++;
16713 w->cursor.y = row->y;
16715 if (row < bottom_row)
16717 /* Can't simply scan the row for point with
16718 bidi-reordered glyph rows. Let set_cursor_from_row
16719 figure out where to put the cursor, and if it fails,
16720 give up. */
16721 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
16723 if (!set_cursor_from_row (w, row, w->current_matrix,
16724 0, 0, 0, 0))
16726 clear_glyph_matrix (w->desired_matrix);
16727 return 0;
16730 else
16732 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
16733 struct glyph *end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
16735 for (; glyph < end
16736 && (!BUFFERP (glyph->object)
16737 || glyph->charpos < PT);
16738 glyph++)
16740 w->cursor.hpos++;
16741 w->cursor.x += glyph->pixel_width;
16747 /* Adjust window end. A null value of last_text_row means that
16748 the window end is in reused rows which in turn means that
16749 only its vpos can have changed. */
16750 if (last_text_row)
16752 w->window_end_bytepos
16753 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16754 wset_window_end_pos
16755 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
16756 wset_window_end_vpos
16757 (w, make_number (MATRIX_ROW_VPOS (last_text_row,
16758 w->desired_matrix)));
16760 else
16762 wset_window_end_vpos
16763 (w, make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled));
16766 w->window_end_valid = 0;
16767 w->desired_matrix->no_scrolling_p = 1;
16769 #ifdef GLYPH_DEBUG
16770 debug_method_add (w, "try_window_reusing_current_matrix 2");
16771 #endif
16772 return 1;
16775 return 0;
16780 /************************************************************************
16781 Window redisplay reusing current matrix when buffer has changed
16782 ************************************************************************/
16784 static struct glyph_row *find_last_unchanged_at_beg_row (struct window *);
16785 static struct glyph_row *find_first_unchanged_at_end_row (struct window *,
16786 ptrdiff_t *, ptrdiff_t *);
16787 static struct glyph_row *
16788 find_last_row_displaying_text (struct glyph_matrix *, struct it *,
16789 struct glyph_row *);
16792 /* Return the last row in MATRIX displaying text. If row START is
16793 non-null, start searching with that row. IT gives the dimensions
16794 of the display. Value is null if matrix is empty; otherwise it is
16795 a pointer to the row found. */
16797 static struct glyph_row *
16798 find_last_row_displaying_text (struct glyph_matrix *matrix, struct it *it,
16799 struct glyph_row *start)
16801 struct glyph_row *row, *row_found;
16803 /* Set row_found to the last row in IT->w's current matrix
16804 displaying text. The loop looks funny but think of partially
16805 visible lines. */
16806 row_found = NULL;
16807 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
16808 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16810 eassert (row->enabled_p);
16811 row_found = row;
16812 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
16813 break;
16814 ++row;
16817 return row_found;
16821 /* Return the last row in the current matrix of W that is not affected
16822 by changes at the start of current_buffer that occurred since W's
16823 current matrix was built. Value is null if no such row exists.
16825 BEG_UNCHANGED us the number of characters unchanged at the start of
16826 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
16827 first changed character in current_buffer. Characters at positions <
16828 BEG + BEG_UNCHANGED are at the same buffer positions as they were
16829 when the current matrix was built. */
16831 static struct glyph_row *
16832 find_last_unchanged_at_beg_row (struct window *w)
16834 ptrdiff_t first_changed_pos = BEG + BEG_UNCHANGED;
16835 struct glyph_row *row;
16836 struct glyph_row *row_found = NULL;
16837 int yb = window_text_bottom_y (w);
16839 /* Find the last row displaying unchanged text. */
16840 for (row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16841 MATRIX_ROW_DISPLAYS_TEXT_P (row)
16842 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos;
16843 ++row)
16845 if (/* If row ends before first_changed_pos, it is unchanged,
16846 except in some case. */
16847 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
16848 /* When row ends in ZV and we write at ZV it is not
16849 unchanged. */
16850 && !row->ends_at_zv_p
16851 /* When first_changed_pos is the end of a continued line,
16852 row is not unchanged because it may be no longer
16853 continued. */
16854 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
16855 && (row->continued_p
16856 || row->exact_window_width_line_p))
16857 /* If ROW->end is beyond ZV, then ROW->end is outdated and
16858 needs to be recomputed, so don't consider this row as
16859 unchanged. This happens when the last line was
16860 bidi-reordered and was killed immediately before this
16861 redisplay cycle. In that case, ROW->end stores the
16862 buffer position of the first visual-order character of
16863 the killed text, which is now beyond ZV. */
16864 && CHARPOS (row->end.pos) <= ZV)
16865 row_found = row;
16867 /* Stop if last visible row. */
16868 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
16869 break;
16872 return row_found;
16876 /* Find the first glyph row in the current matrix of W that is not
16877 affected by changes at the end of current_buffer since the
16878 time W's current matrix was built.
16880 Return in *DELTA the number of chars by which buffer positions in
16881 unchanged text at the end of current_buffer must be adjusted.
16883 Return in *DELTA_BYTES the corresponding number of bytes.
16885 Value is null if no such row exists, i.e. all rows are affected by
16886 changes. */
16888 static struct glyph_row *
16889 find_first_unchanged_at_end_row (struct window *w,
16890 ptrdiff_t *delta, ptrdiff_t *delta_bytes)
16892 struct glyph_row *row;
16893 struct glyph_row *row_found = NULL;
16895 *delta = *delta_bytes = 0;
16897 /* Display must not have been paused, otherwise the current matrix
16898 is not up to date. */
16899 eassert (w->window_end_valid);
16901 /* A value of window_end_pos >= END_UNCHANGED means that the window
16902 end is in the range of changed text. If so, there is no
16903 unchanged row at the end of W's current matrix. */
16904 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
16905 return NULL;
16907 /* Set row to the last row in W's current matrix displaying text. */
16908 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
16910 /* If matrix is entirely empty, no unchanged row exists. */
16911 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16913 /* The value of row is the last glyph row in the matrix having a
16914 meaningful buffer position in it. The end position of row
16915 corresponds to window_end_pos. This allows us to translate
16916 buffer positions in the current matrix to current buffer
16917 positions for characters not in changed text. */
16918 ptrdiff_t Z_old =
16919 MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
16920 ptrdiff_t Z_BYTE_old =
16921 MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
16922 ptrdiff_t last_unchanged_pos, last_unchanged_pos_old;
16923 struct glyph_row *first_text_row
16924 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16926 *delta = Z - Z_old;
16927 *delta_bytes = Z_BYTE - Z_BYTE_old;
16929 /* Set last_unchanged_pos to the buffer position of the last
16930 character in the buffer that has not been changed. Z is the
16931 index + 1 of the last character in current_buffer, i.e. by
16932 subtracting END_UNCHANGED we get the index of the last
16933 unchanged character, and we have to add BEG to get its buffer
16934 position. */
16935 last_unchanged_pos = Z - END_UNCHANGED + BEG;
16936 last_unchanged_pos_old = last_unchanged_pos - *delta;
16938 /* Search backward from ROW for a row displaying a line that
16939 starts at a minimum position >= last_unchanged_pos_old. */
16940 for (; row > first_text_row; --row)
16942 /* This used to abort, but it can happen.
16943 It is ok to just stop the search instead here. KFS. */
16944 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
16945 break;
16947 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
16948 row_found = row;
16952 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
16954 return row_found;
16958 /* Make sure that glyph rows in the current matrix of window W
16959 reference the same glyph memory as corresponding rows in the
16960 frame's frame matrix. This function is called after scrolling W's
16961 current matrix on a terminal frame in try_window_id and
16962 try_window_reusing_current_matrix. */
16964 static void
16965 sync_frame_with_window_matrix_rows (struct window *w)
16967 struct frame *f = XFRAME (w->frame);
16968 struct glyph_row *window_row, *window_row_end, *frame_row;
16970 /* Preconditions: W must be a leaf window and full-width. Its frame
16971 must have a frame matrix. */
16972 eassert (BUFFERP (w->contents));
16973 eassert (WINDOW_FULL_WIDTH_P (w));
16974 eassert (!FRAME_WINDOW_P (f));
16976 /* If W is a full-width window, glyph pointers in W's current matrix
16977 have, by definition, to be the same as glyph pointers in the
16978 corresponding frame matrix. Note that frame matrices have no
16979 marginal areas (see build_frame_matrix). */
16980 window_row = w->current_matrix->rows;
16981 window_row_end = window_row + w->current_matrix->nrows;
16982 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
16983 while (window_row < window_row_end)
16985 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
16986 struct glyph *end = window_row->glyphs[LAST_AREA];
16988 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
16989 frame_row->glyphs[TEXT_AREA] = start;
16990 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
16991 frame_row->glyphs[LAST_AREA] = end;
16993 /* Disable frame rows whose corresponding window rows have
16994 been disabled in try_window_id. */
16995 if (!window_row->enabled_p)
16996 frame_row->enabled_p = 0;
16998 ++window_row, ++frame_row;
17003 /* Find the glyph row in window W containing CHARPOS. Consider all
17004 rows between START and END (not inclusive). END null means search
17005 all rows to the end of the display area of W. Value is the row
17006 containing CHARPOS or null. */
17008 struct glyph_row *
17009 row_containing_pos (struct window *w, ptrdiff_t charpos,
17010 struct glyph_row *start, struct glyph_row *end, int dy)
17012 struct glyph_row *row = start;
17013 struct glyph_row *best_row = NULL;
17014 ptrdiff_t mindif = BUF_ZV (XBUFFER (w->contents)) + 1;
17015 int last_y;
17017 /* If we happen to start on a header-line, skip that. */
17018 if (row->mode_line_p)
17019 ++row;
17021 if ((end && row >= end) || !row->enabled_p)
17022 return NULL;
17024 last_y = window_text_bottom_y (w) - dy;
17026 while (1)
17028 /* Give up if we have gone too far. */
17029 if (end && row >= end)
17030 return NULL;
17031 /* This formerly returned if they were equal.
17032 I think that both quantities are of a "last plus one" type;
17033 if so, when they are equal, the row is within the screen. -- rms. */
17034 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
17035 return NULL;
17037 /* If it is in this row, return this row. */
17038 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
17039 || (MATRIX_ROW_END_CHARPOS (row) == charpos
17040 /* The end position of a row equals the start
17041 position of the next row. If CHARPOS is there, we
17042 would rather consider it displayed in the next
17043 line, except when this line ends in ZV. */
17044 && !row_for_charpos_p (row, charpos)))
17045 && charpos >= MATRIX_ROW_START_CHARPOS (row))
17047 struct glyph *g;
17049 if (NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
17050 || (!best_row && !row->continued_p))
17051 return row;
17052 /* In bidi-reordered rows, there could be several rows whose
17053 edges surround CHARPOS, all of these rows belonging to
17054 the same continued line. We need to find the row which
17055 fits CHARPOS the best. */
17056 for (g = row->glyphs[TEXT_AREA];
17057 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
17058 g++)
17060 if (!STRINGP (g->object))
17062 if (g->charpos > 0 && eabs (g->charpos - charpos) < mindif)
17064 mindif = eabs (g->charpos - charpos);
17065 best_row = row;
17066 /* Exact match always wins. */
17067 if (mindif == 0)
17068 return best_row;
17073 else if (best_row && !row->continued_p)
17074 return best_row;
17075 ++row;
17080 /* Try to redisplay window W by reusing its existing display. W's
17081 current matrix must be up to date when this function is called,
17082 i.e. window_end_valid must be nonzero.
17084 Value is
17086 1 if display has been updated
17087 0 if otherwise unsuccessful
17088 -1 if redisplay with same window start is known not to succeed
17090 The following steps are performed:
17092 1. Find the last row in the current matrix of W that is not
17093 affected by changes at the start of current_buffer. If no such row
17094 is found, give up.
17096 2. Find the first row in W's current matrix that is not affected by
17097 changes at the end of current_buffer. Maybe there is no such row.
17099 3. Display lines beginning with the row + 1 found in step 1 to the
17100 row found in step 2 or, if step 2 didn't find a row, to the end of
17101 the window.
17103 4. If cursor is not known to appear on the window, give up.
17105 5. If display stopped at the row found in step 2, scroll the
17106 display and current matrix as needed.
17108 6. Maybe display some lines at the end of W, if we must. This can
17109 happen under various circumstances, like a partially visible line
17110 becoming fully visible, or because newly displayed lines are displayed
17111 in smaller font sizes.
17113 7. Update W's window end information. */
17115 static int
17116 try_window_id (struct window *w)
17118 struct frame *f = XFRAME (w->frame);
17119 struct glyph_matrix *current_matrix = w->current_matrix;
17120 struct glyph_matrix *desired_matrix = w->desired_matrix;
17121 struct glyph_row *last_unchanged_at_beg_row;
17122 struct glyph_row *first_unchanged_at_end_row;
17123 struct glyph_row *row;
17124 struct glyph_row *bottom_row;
17125 int bottom_vpos;
17126 struct it it;
17127 ptrdiff_t delta = 0, delta_bytes = 0, stop_pos;
17128 int dvpos, dy;
17129 struct text_pos start_pos;
17130 struct run run;
17131 int first_unchanged_at_end_vpos = 0;
17132 struct glyph_row *last_text_row, *last_text_row_at_end;
17133 struct text_pos start;
17134 ptrdiff_t first_changed_charpos, last_changed_charpos;
17136 #ifdef GLYPH_DEBUG
17137 if (inhibit_try_window_id)
17138 return 0;
17139 #endif
17141 /* This is handy for debugging. */
17142 #if 0
17143 #define GIVE_UP(X) \
17144 do { \
17145 fprintf (stderr, "try_window_id give up %d\n", (X)); \
17146 return 0; \
17147 } while (0)
17148 #else
17149 #define GIVE_UP(X) return 0
17150 #endif
17152 SET_TEXT_POS_FROM_MARKER (start, w->start);
17154 /* Don't use this for mini-windows because these can show
17155 messages and mini-buffers, and we don't handle that here. */
17156 if (MINI_WINDOW_P (w))
17157 GIVE_UP (1);
17159 /* This flag is used to prevent redisplay optimizations. */
17160 if (windows_or_buffers_changed || cursor_type_changed)
17161 GIVE_UP (2);
17163 /* Verify that narrowing has not changed.
17164 Also verify that we were not told to prevent redisplay optimizations.
17165 It would be nice to further
17166 reduce the number of cases where this prevents try_window_id. */
17167 if (current_buffer->clip_changed
17168 || current_buffer->prevent_redisplay_optimizations_p)
17169 GIVE_UP (3);
17171 /* Window must either use window-based redisplay or be full width. */
17172 if (!FRAME_WINDOW_P (f)
17173 && (!FRAME_LINE_INS_DEL_OK (f)
17174 || !WINDOW_FULL_WIDTH_P (w)))
17175 GIVE_UP (4);
17177 /* Give up if point is known NOT to appear in W. */
17178 if (PT < CHARPOS (start))
17179 GIVE_UP (5);
17181 /* Another way to prevent redisplay optimizations. */
17182 if (w->last_modified == 0)
17183 GIVE_UP (6);
17185 /* Verify that window is not hscrolled. */
17186 if (w->hscroll != 0)
17187 GIVE_UP (7);
17189 /* Verify that display wasn't paused. */
17190 if (!w->window_end_valid)
17191 GIVE_UP (8);
17193 /* Can't use this if highlighting a region because a cursor movement
17194 will do more than just set the cursor. */
17195 if (markpos_of_region () >= 0)
17196 GIVE_UP (9);
17198 /* Likewise if highlighting trailing whitespace. */
17199 if (!NILP (Vshow_trailing_whitespace))
17200 GIVE_UP (11);
17202 /* Likewise if showing a region. */
17203 if (w->region_showing)
17204 GIVE_UP (10);
17206 /* Can't use this if overlay arrow position and/or string have
17207 changed. */
17208 if (overlay_arrows_changed_p ())
17209 GIVE_UP (12);
17211 /* When word-wrap is on, adding a space to the first word of a
17212 wrapped line can change the wrap position, altering the line
17213 above it. It might be worthwhile to handle this more
17214 intelligently, but for now just redisplay from scratch. */
17215 if (!NILP (BVAR (XBUFFER (w->contents), word_wrap)))
17216 GIVE_UP (21);
17218 /* Under bidi reordering, adding or deleting a character in the
17219 beginning of a paragraph, before the first strong directional
17220 character, can change the base direction of the paragraph (unless
17221 the buffer specifies a fixed paragraph direction), which will
17222 require to redisplay the whole paragraph. It might be worthwhile
17223 to find the paragraph limits and widen the range of redisplayed
17224 lines to that, but for now just give up this optimization and
17225 redisplay from scratch. */
17226 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
17227 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
17228 GIVE_UP (22);
17230 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
17231 only if buffer has really changed. The reason is that the gap is
17232 initially at Z for freshly visited files. The code below would
17233 set end_unchanged to 0 in that case. */
17234 if (MODIFF > SAVE_MODIFF
17235 /* This seems to happen sometimes after saving a buffer. */
17236 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
17238 if (GPT - BEG < BEG_UNCHANGED)
17239 BEG_UNCHANGED = GPT - BEG;
17240 if (Z - GPT < END_UNCHANGED)
17241 END_UNCHANGED = Z - GPT;
17244 /* The position of the first and last character that has been changed. */
17245 first_changed_charpos = BEG + BEG_UNCHANGED;
17246 last_changed_charpos = Z - END_UNCHANGED;
17248 /* If window starts after a line end, and the last change is in
17249 front of that newline, then changes don't affect the display.
17250 This case happens with stealth-fontification. Note that although
17251 the display is unchanged, glyph positions in the matrix have to
17252 be adjusted, of course. */
17253 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
17254 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
17255 && ((last_changed_charpos < CHARPOS (start)
17256 && CHARPOS (start) == BEGV)
17257 || (last_changed_charpos < CHARPOS (start) - 1
17258 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
17260 ptrdiff_t Z_old, Z_delta, Z_BYTE_old, Z_delta_bytes;
17261 struct glyph_row *r0;
17263 /* Compute how many chars/bytes have been added to or removed
17264 from the buffer. */
17265 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
17266 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
17267 Z_delta = Z - Z_old;
17268 Z_delta_bytes = Z_BYTE - Z_BYTE_old;
17270 /* Give up if PT is not in the window. Note that it already has
17271 been checked at the start of try_window_id that PT is not in
17272 front of the window start. */
17273 if (PT >= MATRIX_ROW_END_CHARPOS (row) + Z_delta)
17274 GIVE_UP (13);
17276 /* If window start is unchanged, we can reuse the whole matrix
17277 as is, after adjusting glyph positions. No need to compute
17278 the window end again, since its offset from Z hasn't changed. */
17279 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
17280 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + Z_delta
17281 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + Z_delta_bytes
17282 /* PT must not be in a partially visible line. */
17283 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + Z_delta
17284 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
17286 /* Adjust positions in the glyph matrix. */
17287 if (Z_delta || Z_delta_bytes)
17289 struct glyph_row *r1
17290 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
17291 increment_matrix_positions (w->current_matrix,
17292 MATRIX_ROW_VPOS (r0, current_matrix),
17293 MATRIX_ROW_VPOS (r1, current_matrix),
17294 Z_delta, Z_delta_bytes);
17297 /* Set the cursor. */
17298 row = row_containing_pos (w, PT, r0, NULL, 0);
17299 if (row)
17300 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
17301 else
17302 emacs_abort ();
17303 return 1;
17307 /* Handle the case that changes are all below what is displayed in
17308 the window, and that PT is in the window. This shortcut cannot
17309 be taken if ZV is visible in the window, and text has been added
17310 there that is visible in the window. */
17311 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
17312 /* ZV is not visible in the window, or there are no
17313 changes at ZV, actually. */
17314 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
17315 || first_changed_charpos == last_changed_charpos))
17317 struct glyph_row *r0;
17319 /* Give up if PT is not in the window. Note that it already has
17320 been checked at the start of try_window_id that PT is not in
17321 front of the window start. */
17322 if (PT >= MATRIX_ROW_END_CHARPOS (row))
17323 GIVE_UP (14);
17325 /* If window start is unchanged, we can reuse the whole matrix
17326 as is, without changing glyph positions since no text has
17327 been added/removed in front of the window end. */
17328 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
17329 if (TEXT_POS_EQUAL_P (start, r0->minpos)
17330 /* PT must not be in a partially visible line. */
17331 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
17332 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
17334 /* We have to compute the window end anew since text
17335 could have been added/removed after it. */
17336 wset_window_end_pos
17337 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row)));
17338 w->window_end_bytepos
17339 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17341 /* Set the cursor. */
17342 row = row_containing_pos (w, PT, r0, NULL, 0);
17343 if (row)
17344 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
17345 else
17346 emacs_abort ();
17347 return 2;
17351 /* Give up if window start is in the changed area.
17353 The condition used to read
17355 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
17357 but why that was tested escapes me at the moment. */
17358 if (CHARPOS (start) >= first_changed_charpos
17359 && CHARPOS (start) <= last_changed_charpos)
17360 GIVE_UP (15);
17362 /* Check that window start agrees with the start of the first glyph
17363 row in its current matrix. Check this after we know the window
17364 start is not in changed text, otherwise positions would not be
17365 comparable. */
17366 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
17367 if (!TEXT_POS_EQUAL_P (start, row->minpos))
17368 GIVE_UP (16);
17370 /* Give up if the window ends in strings. Overlay strings
17371 at the end are difficult to handle, so don't try. */
17372 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
17373 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
17374 GIVE_UP (20);
17376 /* Compute the position at which we have to start displaying new
17377 lines. Some of the lines at the top of the window might be
17378 reusable because they are not displaying changed text. Find the
17379 last row in W's current matrix not affected by changes at the
17380 start of current_buffer. Value is null if changes start in the
17381 first line of window. */
17382 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
17383 if (last_unchanged_at_beg_row)
17385 /* Avoid starting to display in the middle of a character, a TAB
17386 for instance. This is easier than to set up the iterator
17387 exactly, and it's not a frequent case, so the additional
17388 effort wouldn't really pay off. */
17389 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
17390 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
17391 && last_unchanged_at_beg_row > w->current_matrix->rows)
17392 --last_unchanged_at_beg_row;
17394 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
17395 GIVE_UP (17);
17397 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
17398 GIVE_UP (18);
17399 start_pos = it.current.pos;
17401 /* Start displaying new lines in the desired matrix at the same
17402 vpos we would use in the current matrix, i.e. below
17403 last_unchanged_at_beg_row. */
17404 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
17405 current_matrix);
17406 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
17407 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
17409 eassert (it.hpos == 0 && it.current_x == 0);
17411 else
17413 /* There are no reusable lines at the start of the window.
17414 Start displaying in the first text line. */
17415 start_display (&it, w, start);
17416 it.vpos = it.first_vpos;
17417 start_pos = it.current.pos;
17420 /* Find the first row that is not affected by changes at the end of
17421 the buffer. Value will be null if there is no unchanged row, in
17422 which case we must redisplay to the end of the window. delta
17423 will be set to the value by which buffer positions beginning with
17424 first_unchanged_at_end_row have to be adjusted due to text
17425 changes. */
17426 first_unchanged_at_end_row
17427 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
17428 IF_DEBUG (debug_delta = delta);
17429 IF_DEBUG (debug_delta_bytes = delta_bytes);
17431 /* Set stop_pos to the buffer position up to which we will have to
17432 display new lines. If first_unchanged_at_end_row != NULL, this
17433 is the buffer position of the start of the line displayed in that
17434 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
17435 that we don't stop at a buffer position. */
17436 stop_pos = 0;
17437 if (first_unchanged_at_end_row)
17439 eassert (last_unchanged_at_beg_row == NULL
17440 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
17442 /* If this is a continuation line, move forward to the next one
17443 that isn't. Changes in lines above affect this line.
17444 Caution: this may move first_unchanged_at_end_row to a row
17445 not displaying text. */
17446 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
17447 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
17448 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
17449 < it.last_visible_y))
17450 ++first_unchanged_at_end_row;
17452 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
17453 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
17454 >= it.last_visible_y))
17455 first_unchanged_at_end_row = NULL;
17456 else
17458 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
17459 + delta);
17460 first_unchanged_at_end_vpos
17461 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
17462 eassert (stop_pos >= Z - END_UNCHANGED);
17465 else if (last_unchanged_at_beg_row == NULL)
17466 GIVE_UP (19);
17469 #ifdef GLYPH_DEBUG
17471 /* Either there is no unchanged row at the end, or the one we have
17472 now displays text. This is a necessary condition for the window
17473 end pos calculation at the end of this function. */
17474 eassert (first_unchanged_at_end_row == NULL
17475 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
17477 debug_last_unchanged_at_beg_vpos
17478 = (last_unchanged_at_beg_row
17479 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
17480 : -1);
17481 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
17483 #endif /* GLYPH_DEBUG */
17486 /* Display new lines. Set last_text_row to the last new line
17487 displayed which has text on it, i.e. might end up as being the
17488 line where the window_end_vpos is. */
17489 w->cursor.vpos = -1;
17490 last_text_row = NULL;
17491 overlay_arrow_seen = 0;
17492 while (it.current_y < it.last_visible_y
17493 && !fonts_changed_p
17494 && (first_unchanged_at_end_row == NULL
17495 || IT_CHARPOS (it) < stop_pos))
17497 if (display_line (&it))
17498 last_text_row = it.glyph_row - 1;
17501 if (fonts_changed_p)
17502 return -1;
17505 /* Compute differences in buffer positions, y-positions etc. for
17506 lines reused at the bottom of the window. Compute what we can
17507 scroll. */
17508 if (first_unchanged_at_end_row
17509 /* No lines reused because we displayed everything up to the
17510 bottom of the window. */
17511 && it.current_y < it.last_visible_y)
17513 dvpos = (it.vpos
17514 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
17515 current_matrix));
17516 dy = it.current_y - first_unchanged_at_end_row->y;
17517 run.current_y = first_unchanged_at_end_row->y;
17518 run.desired_y = run.current_y + dy;
17519 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
17521 else
17523 delta = delta_bytes = dvpos = dy
17524 = run.current_y = run.desired_y = run.height = 0;
17525 first_unchanged_at_end_row = NULL;
17527 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
17530 /* Find the cursor if not already found. We have to decide whether
17531 PT will appear on this window (it sometimes doesn't, but this is
17532 not a very frequent case.) This decision has to be made before
17533 the current matrix is altered. A value of cursor.vpos < 0 means
17534 that PT is either in one of the lines beginning at
17535 first_unchanged_at_end_row or below the window. Don't care for
17536 lines that might be displayed later at the window end; as
17537 mentioned, this is not a frequent case. */
17538 if (w->cursor.vpos < 0)
17540 /* Cursor in unchanged rows at the top? */
17541 if (PT < CHARPOS (start_pos)
17542 && last_unchanged_at_beg_row)
17544 row = row_containing_pos (w, PT,
17545 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
17546 last_unchanged_at_beg_row + 1, 0);
17547 if (row)
17548 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
17551 /* Start from first_unchanged_at_end_row looking for PT. */
17552 else if (first_unchanged_at_end_row)
17554 row = row_containing_pos (w, PT - delta,
17555 first_unchanged_at_end_row, NULL, 0);
17556 if (row)
17557 set_cursor_from_row (w, row, w->current_matrix, delta,
17558 delta_bytes, dy, dvpos);
17561 /* Give up if cursor was not found. */
17562 if (w->cursor.vpos < 0)
17564 clear_glyph_matrix (w->desired_matrix);
17565 return -1;
17569 /* Don't let the cursor end in the scroll margins. */
17571 int this_scroll_margin, cursor_height;
17572 int frame_line_height = default_line_pixel_height (w);
17573 int window_total_lines
17574 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (it.f) / frame_line_height;
17576 this_scroll_margin =
17577 max (0, min (scroll_margin, window_total_lines / 4));
17578 this_scroll_margin *= frame_line_height;
17579 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
17581 if ((w->cursor.y < this_scroll_margin
17582 && CHARPOS (start) > BEGV)
17583 /* Old redisplay didn't take scroll margin into account at the bottom,
17584 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
17585 || (w->cursor.y + (make_cursor_line_fully_visible_p
17586 ? cursor_height + this_scroll_margin
17587 : 1)) > it.last_visible_y)
17589 w->cursor.vpos = -1;
17590 clear_glyph_matrix (w->desired_matrix);
17591 return -1;
17595 /* Scroll the display. Do it before changing the current matrix so
17596 that xterm.c doesn't get confused about where the cursor glyph is
17597 found. */
17598 if (dy && run.height)
17600 update_begin (f);
17602 if (FRAME_WINDOW_P (f))
17604 FRAME_RIF (f)->update_window_begin_hook (w);
17605 FRAME_RIF (f)->clear_window_mouse_face (w);
17606 FRAME_RIF (f)->scroll_run_hook (w, &run);
17607 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
17609 else
17611 /* Terminal frame. In this case, dvpos gives the number of
17612 lines to scroll by; dvpos < 0 means scroll up. */
17613 int from_vpos
17614 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
17615 int from = WINDOW_TOP_EDGE_LINE (w) + from_vpos;
17616 int end = (WINDOW_TOP_EDGE_LINE (w)
17617 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
17618 + window_internal_height (w));
17620 #if defined (HAVE_GPM) || defined (MSDOS)
17621 x_clear_window_mouse_face (w);
17622 #endif
17623 /* Perform the operation on the screen. */
17624 if (dvpos > 0)
17626 /* Scroll last_unchanged_at_beg_row to the end of the
17627 window down dvpos lines. */
17628 set_terminal_window (f, end);
17630 /* On dumb terminals delete dvpos lines at the end
17631 before inserting dvpos empty lines. */
17632 if (!FRAME_SCROLL_REGION_OK (f))
17633 ins_del_lines (f, end - dvpos, -dvpos);
17635 /* Insert dvpos empty lines in front of
17636 last_unchanged_at_beg_row. */
17637 ins_del_lines (f, from, dvpos);
17639 else if (dvpos < 0)
17641 /* Scroll up last_unchanged_at_beg_vpos to the end of
17642 the window to last_unchanged_at_beg_vpos - |dvpos|. */
17643 set_terminal_window (f, end);
17645 /* Delete dvpos lines in front of
17646 last_unchanged_at_beg_vpos. ins_del_lines will set
17647 the cursor to the given vpos and emit |dvpos| delete
17648 line sequences. */
17649 ins_del_lines (f, from + dvpos, dvpos);
17651 /* On a dumb terminal insert dvpos empty lines at the
17652 end. */
17653 if (!FRAME_SCROLL_REGION_OK (f))
17654 ins_del_lines (f, end + dvpos, -dvpos);
17657 set_terminal_window (f, 0);
17660 update_end (f);
17663 /* Shift reused rows of the current matrix to the right position.
17664 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
17665 text. */
17666 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
17667 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
17668 if (dvpos < 0)
17670 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
17671 bottom_vpos, dvpos);
17672 clear_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
17673 bottom_vpos);
17675 else if (dvpos > 0)
17677 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
17678 bottom_vpos, dvpos);
17679 clear_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
17680 first_unchanged_at_end_vpos + dvpos);
17683 /* For frame-based redisplay, make sure that current frame and window
17684 matrix are in sync with respect to glyph memory. */
17685 if (!FRAME_WINDOW_P (f))
17686 sync_frame_with_window_matrix_rows (w);
17688 /* Adjust buffer positions in reused rows. */
17689 if (delta || delta_bytes)
17690 increment_matrix_positions (current_matrix,
17691 first_unchanged_at_end_vpos + dvpos,
17692 bottom_vpos, delta, delta_bytes);
17694 /* Adjust Y positions. */
17695 if (dy)
17696 shift_glyph_matrix (w, current_matrix,
17697 first_unchanged_at_end_vpos + dvpos,
17698 bottom_vpos, dy);
17700 if (first_unchanged_at_end_row)
17702 first_unchanged_at_end_row += dvpos;
17703 if (first_unchanged_at_end_row->y >= it.last_visible_y
17704 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
17705 first_unchanged_at_end_row = NULL;
17708 /* If scrolling up, there may be some lines to display at the end of
17709 the window. */
17710 last_text_row_at_end = NULL;
17711 if (dy < 0)
17713 /* Scrolling up can leave for example a partially visible line
17714 at the end of the window to be redisplayed. */
17715 /* Set last_row to the glyph row in the current matrix where the
17716 window end line is found. It has been moved up or down in
17717 the matrix by dvpos. */
17718 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
17719 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
17721 /* If last_row is the window end line, it should display text. */
17722 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_row));
17724 /* If window end line was partially visible before, begin
17725 displaying at that line. Otherwise begin displaying with the
17726 line following it. */
17727 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
17729 init_to_row_start (&it, w, last_row);
17730 it.vpos = last_vpos;
17731 it.current_y = last_row->y;
17733 else
17735 init_to_row_end (&it, w, last_row);
17736 it.vpos = 1 + last_vpos;
17737 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
17738 ++last_row;
17741 /* We may start in a continuation line. If so, we have to
17742 get the right continuation_lines_width and current_x. */
17743 it.continuation_lines_width = last_row->continuation_lines_width;
17744 it.hpos = it.current_x = 0;
17746 /* Display the rest of the lines at the window end. */
17747 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
17748 while (it.current_y < it.last_visible_y
17749 && !fonts_changed_p)
17751 /* Is it always sure that the display agrees with lines in
17752 the current matrix? I don't think so, so we mark rows
17753 displayed invalid in the current matrix by setting their
17754 enabled_p flag to zero. */
17755 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
17756 if (display_line (&it))
17757 last_text_row_at_end = it.glyph_row - 1;
17761 /* Update window_end_pos and window_end_vpos. */
17762 if (first_unchanged_at_end_row
17763 && !last_text_row_at_end)
17765 /* Window end line if one of the preserved rows from the current
17766 matrix. Set row to the last row displaying text in current
17767 matrix starting at first_unchanged_at_end_row, after
17768 scrolling. */
17769 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
17770 row = find_last_row_displaying_text (w->current_matrix, &it,
17771 first_unchanged_at_end_row);
17772 eassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
17774 wset_window_end_pos (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row)));
17775 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17776 wset_window_end_vpos
17777 (w, make_number (MATRIX_ROW_VPOS (row, w->current_matrix)));
17778 eassert (w->window_end_bytepos >= 0);
17779 IF_DEBUG (debug_method_add (w, "A"));
17781 else if (last_text_row_at_end)
17783 wset_window_end_pos
17784 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end)));
17785 w->window_end_bytepos
17786 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
17787 wset_window_end_vpos
17788 (w, make_number (MATRIX_ROW_VPOS (last_text_row_at_end,
17789 desired_matrix)));
17790 eassert (w->window_end_bytepos >= 0);
17791 IF_DEBUG (debug_method_add (w, "B"));
17793 else if (last_text_row)
17795 /* We have displayed either to the end of the window or at the
17796 end of the window, i.e. the last row with text is to be found
17797 in the desired matrix. */
17798 wset_window_end_pos
17799 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
17800 w->window_end_bytepos
17801 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
17802 wset_window_end_vpos
17803 (w, make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix)));
17804 eassert (w->window_end_bytepos >= 0);
17806 else if (first_unchanged_at_end_row == NULL
17807 && last_text_row == NULL
17808 && last_text_row_at_end == NULL)
17810 /* Displayed to end of window, but no line containing text was
17811 displayed. Lines were deleted at the end of the window. */
17812 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
17813 int vpos = XFASTINT (w->window_end_vpos);
17814 struct glyph_row *current_row = current_matrix->rows + vpos;
17815 struct glyph_row *desired_row = desired_matrix->rows + vpos;
17817 for (row = NULL;
17818 row == NULL && vpos >= first_vpos;
17819 --vpos, --current_row, --desired_row)
17821 if (desired_row->enabled_p)
17823 if (MATRIX_ROW_DISPLAYS_TEXT_P (desired_row))
17824 row = desired_row;
17826 else if (MATRIX_ROW_DISPLAYS_TEXT_P (current_row))
17827 row = current_row;
17830 eassert (row != NULL);
17831 wset_window_end_vpos (w, make_number (vpos + 1));
17832 wset_window_end_pos (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row)));
17833 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17834 eassert (w->window_end_bytepos >= 0);
17835 IF_DEBUG (debug_method_add (w, "C"));
17837 else
17838 emacs_abort ();
17840 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
17841 debug_end_vpos = XFASTINT (w->window_end_vpos));
17843 /* Record that display has not been completed. */
17844 w->window_end_valid = 0;
17845 w->desired_matrix->no_scrolling_p = 1;
17846 return 3;
17848 #undef GIVE_UP
17853 /***********************************************************************
17854 More debugging support
17855 ***********************************************************************/
17857 #ifdef GLYPH_DEBUG
17859 void dump_glyph_row (struct glyph_row *, int, int) EXTERNALLY_VISIBLE;
17860 void dump_glyph_matrix (struct glyph_matrix *, int) EXTERNALLY_VISIBLE;
17861 void dump_glyph (struct glyph_row *, struct glyph *, int) EXTERNALLY_VISIBLE;
17864 /* Dump the contents of glyph matrix MATRIX on stderr.
17866 GLYPHS 0 means don't show glyph contents.
17867 GLYPHS 1 means show glyphs in short form
17868 GLYPHS > 1 means show glyphs in long form. */
17870 void
17871 dump_glyph_matrix (struct glyph_matrix *matrix, int glyphs)
17873 int i;
17874 for (i = 0; i < matrix->nrows; ++i)
17875 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
17879 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
17880 the glyph row and area where the glyph comes from. */
17882 void
17883 dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
17885 if (glyph->type == CHAR_GLYPH
17886 || glyph->type == GLYPHLESS_GLYPH)
17888 fprintf (stderr,
17889 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
17890 glyph - row->glyphs[TEXT_AREA],
17891 (glyph->type == CHAR_GLYPH
17892 ? 'C'
17893 : 'G'),
17894 glyph->charpos,
17895 (BUFFERP (glyph->object)
17896 ? 'B'
17897 : (STRINGP (glyph->object)
17898 ? 'S'
17899 : (INTEGERP (glyph->object)
17900 ? '0'
17901 : '-'))),
17902 glyph->pixel_width,
17903 glyph->u.ch,
17904 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
17905 ? glyph->u.ch
17906 : '.'),
17907 glyph->face_id,
17908 glyph->left_box_line_p,
17909 glyph->right_box_line_p);
17911 else if (glyph->type == STRETCH_GLYPH)
17913 fprintf (stderr,
17914 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
17915 glyph - row->glyphs[TEXT_AREA],
17916 'S',
17917 glyph->charpos,
17918 (BUFFERP (glyph->object)
17919 ? 'B'
17920 : (STRINGP (glyph->object)
17921 ? 'S'
17922 : (INTEGERP (glyph->object)
17923 ? '0'
17924 : '-'))),
17925 glyph->pixel_width,
17927 ' ',
17928 glyph->face_id,
17929 glyph->left_box_line_p,
17930 glyph->right_box_line_p);
17932 else if (glyph->type == IMAGE_GLYPH)
17934 fprintf (stderr,
17935 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
17936 glyph - row->glyphs[TEXT_AREA],
17937 'I',
17938 glyph->charpos,
17939 (BUFFERP (glyph->object)
17940 ? 'B'
17941 : (STRINGP (glyph->object)
17942 ? 'S'
17943 : (INTEGERP (glyph->object)
17944 ? '0'
17945 : '-'))),
17946 glyph->pixel_width,
17947 glyph->u.img_id,
17948 '.',
17949 glyph->face_id,
17950 glyph->left_box_line_p,
17951 glyph->right_box_line_p);
17953 else if (glyph->type == COMPOSITE_GLYPH)
17955 fprintf (stderr,
17956 " %5"pD"d %c %9"pI"d %c %3d 0x%06x",
17957 glyph - row->glyphs[TEXT_AREA],
17958 '+',
17959 glyph->charpos,
17960 (BUFFERP (glyph->object)
17961 ? 'B'
17962 : (STRINGP (glyph->object)
17963 ? 'S'
17964 : (INTEGERP (glyph->object)
17965 ? '0'
17966 : '-'))),
17967 glyph->pixel_width,
17968 glyph->u.cmp.id);
17969 if (glyph->u.cmp.automatic)
17970 fprintf (stderr,
17971 "[%d-%d]",
17972 glyph->slice.cmp.from, glyph->slice.cmp.to);
17973 fprintf (stderr, " . %4d %1.1d%1.1d\n",
17974 glyph->face_id,
17975 glyph->left_box_line_p,
17976 glyph->right_box_line_p);
17981 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
17982 GLYPHS 0 means don't show glyph contents.
17983 GLYPHS 1 means show glyphs in short form
17984 GLYPHS > 1 means show glyphs in long form. */
17986 void
17987 dump_glyph_row (struct glyph_row *row, int vpos, int glyphs)
17989 if (glyphs != 1)
17991 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
17992 fprintf (stderr, "==============================================================================\n");
17994 fprintf (stderr, "%3d %9"pI"d %9"pI"d %4d %1.1d%1.1d%1.1d%1.1d\
17995 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
17996 vpos,
17997 MATRIX_ROW_START_CHARPOS (row),
17998 MATRIX_ROW_END_CHARPOS (row),
17999 row->used[TEXT_AREA],
18000 row->contains_overlapping_glyphs_p,
18001 row->enabled_p,
18002 row->truncated_on_left_p,
18003 row->truncated_on_right_p,
18004 row->continued_p,
18005 MATRIX_ROW_CONTINUATION_LINE_P (row),
18006 MATRIX_ROW_DISPLAYS_TEXT_P (row),
18007 row->ends_at_zv_p,
18008 row->fill_line_p,
18009 row->ends_in_middle_of_char_p,
18010 row->starts_in_middle_of_char_p,
18011 row->mouse_face_p,
18012 row->x,
18013 row->y,
18014 row->pixel_width,
18015 row->height,
18016 row->visible_height,
18017 row->ascent,
18018 row->phys_ascent);
18019 /* The next 3 lines should align to "Start" in the header. */
18020 fprintf (stderr, " %9"pD"d %9"pD"d\t%5d\n", row->start.overlay_string_index,
18021 row->end.overlay_string_index,
18022 row->continuation_lines_width);
18023 fprintf (stderr, " %9"pI"d %9"pI"d\n",
18024 CHARPOS (row->start.string_pos),
18025 CHARPOS (row->end.string_pos));
18026 fprintf (stderr, " %9d %9d\n", row->start.dpvec_index,
18027 row->end.dpvec_index);
18030 if (glyphs > 1)
18032 int area;
18034 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18036 struct glyph *glyph = row->glyphs[area];
18037 struct glyph *glyph_end = glyph + row->used[area];
18039 /* Glyph for a line end in text. */
18040 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
18041 ++glyph_end;
18043 if (glyph < glyph_end)
18044 fprintf (stderr, " Glyph# Type Pos O W Code C Face LR\n");
18046 for (; glyph < glyph_end; ++glyph)
18047 dump_glyph (row, glyph, area);
18050 else if (glyphs == 1)
18052 int area;
18054 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18056 char *s = alloca (row->used[area] + 4);
18057 int i;
18059 for (i = 0; i < row->used[area]; ++i)
18061 struct glyph *glyph = row->glyphs[area] + i;
18062 if (i == row->used[area] - 1
18063 && area == TEXT_AREA
18064 && INTEGERP (glyph->object)
18065 && glyph->type == CHAR_GLYPH
18066 && glyph->u.ch == ' ')
18068 strcpy (&s[i], "[\\n]");
18069 i += 4;
18071 else if (glyph->type == CHAR_GLYPH
18072 && glyph->u.ch < 0x80
18073 && glyph->u.ch >= ' ')
18074 s[i] = glyph->u.ch;
18075 else
18076 s[i] = '.';
18079 s[i] = '\0';
18080 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
18086 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
18087 Sdump_glyph_matrix, 0, 1, "p",
18088 doc: /* Dump the current matrix of the selected window to stderr.
18089 Shows contents of glyph row structures. With non-nil
18090 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
18091 glyphs in short form, otherwise show glyphs in long form. */)
18092 (Lisp_Object glyphs)
18094 struct window *w = XWINDOW (selected_window);
18095 struct buffer *buffer = XBUFFER (w->contents);
18097 fprintf (stderr, "PT = %"pI"d, BEGV = %"pI"d. ZV = %"pI"d\n",
18098 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
18099 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
18100 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
18101 fprintf (stderr, "=============================================\n");
18102 dump_glyph_matrix (w->current_matrix,
18103 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 0);
18104 return Qnil;
18108 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
18109 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
18110 (void)
18112 struct frame *f = XFRAME (selected_frame);
18113 dump_glyph_matrix (f->current_matrix, 1);
18114 return Qnil;
18118 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
18119 doc: /* Dump glyph row ROW to stderr.
18120 GLYPH 0 means don't dump glyphs.
18121 GLYPH 1 means dump glyphs in short form.
18122 GLYPH > 1 or omitted means dump glyphs in long form. */)
18123 (Lisp_Object row, Lisp_Object glyphs)
18125 struct glyph_matrix *matrix;
18126 EMACS_INT vpos;
18128 CHECK_NUMBER (row);
18129 matrix = XWINDOW (selected_window)->current_matrix;
18130 vpos = XINT (row);
18131 if (vpos >= 0 && vpos < matrix->nrows)
18132 dump_glyph_row (MATRIX_ROW (matrix, vpos),
18133 vpos,
18134 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
18135 return Qnil;
18139 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
18140 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
18141 GLYPH 0 means don't dump glyphs.
18142 GLYPH 1 means dump glyphs in short form.
18143 GLYPH > 1 or omitted means dump glyphs in long form. */)
18144 (Lisp_Object row, Lisp_Object glyphs)
18146 struct frame *sf = SELECTED_FRAME ();
18147 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
18148 EMACS_INT vpos;
18150 CHECK_NUMBER (row);
18151 vpos = XINT (row);
18152 if (vpos >= 0 && vpos < m->nrows)
18153 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
18154 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
18155 return Qnil;
18159 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
18160 doc: /* Toggle tracing of redisplay.
18161 With ARG, turn tracing on if and only if ARG is positive. */)
18162 (Lisp_Object arg)
18164 if (NILP (arg))
18165 trace_redisplay_p = !trace_redisplay_p;
18166 else
18168 arg = Fprefix_numeric_value (arg);
18169 trace_redisplay_p = XINT (arg) > 0;
18172 return Qnil;
18176 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
18177 doc: /* Like `format', but print result to stderr.
18178 usage: (trace-to-stderr STRING &rest OBJECTS) */)
18179 (ptrdiff_t nargs, Lisp_Object *args)
18181 Lisp_Object s = Fformat (nargs, args);
18182 fprintf (stderr, "%s", SDATA (s));
18183 return Qnil;
18186 #endif /* GLYPH_DEBUG */
18190 /***********************************************************************
18191 Building Desired Matrix Rows
18192 ***********************************************************************/
18194 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
18195 Used for non-window-redisplay windows, and for windows w/o left fringe. */
18197 static struct glyph_row *
18198 get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
18200 struct frame *f = XFRAME (WINDOW_FRAME (w));
18201 struct buffer *buffer = XBUFFER (w->contents);
18202 struct buffer *old = current_buffer;
18203 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
18204 int arrow_len = SCHARS (overlay_arrow_string);
18205 const unsigned char *arrow_end = arrow_string + arrow_len;
18206 const unsigned char *p;
18207 struct it it;
18208 bool multibyte_p;
18209 int n_glyphs_before;
18211 set_buffer_temp (buffer);
18212 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
18213 it.glyph_row->used[TEXT_AREA] = 0;
18214 SET_TEXT_POS (it.position, 0, 0);
18216 multibyte_p = !NILP (BVAR (buffer, enable_multibyte_characters));
18217 p = arrow_string;
18218 while (p < arrow_end)
18220 Lisp_Object face, ilisp;
18222 /* Get the next character. */
18223 if (multibyte_p)
18224 it.c = it.char_to_display = string_char_and_length (p, &it.len);
18225 else
18227 it.c = it.char_to_display = *p, it.len = 1;
18228 if (! ASCII_CHAR_P (it.c))
18229 it.char_to_display = BYTE8_TO_CHAR (it.c);
18231 p += it.len;
18233 /* Get its face. */
18234 ilisp = make_number (p - arrow_string);
18235 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
18236 it.face_id = compute_char_face (f, it.char_to_display, face);
18238 /* Compute its width, get its glyphs. */
18239 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
18240 SET_TEXT_POS (it.position, -1, -1);
18241 PRODUCE_GLYPHS (&it);
18243 /* If this character doesn't fit any more in the line, we have
18244 to remove some glyphs. */
18245 if (it.current_x > it.last_visible_x)
18247 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
18248 break;
18252 set_buffer_temp (old);
18253 return it.glyph_row;
18257 /* Insert truncation glyphs at the start of IT->glyph_row. Which
18258 glyphs to insert is determined by produce_special_glyphs. */
18260 static void
18261 insert_left_trunc_glyphs (struct it *it)
18263 struct it truncate_it;
18264 struct glyph *from, *end, *to, *toend;
18266 eassert (!FRAME_WINDOW_P (it->f)
18267 || (!it->glyph_row->reversed_p
18268 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)
18269 || (it->glyph_row->reversed_p
18270 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0));
18272 /* Get the truncation glyphs. */
18273 truncate_it = *it;
18274 truncate_it.current_x = 0;
18275 truncate_it.face_id = DEFAULT_FACE_ID;
18276 truncate_it.glyph_row = &scratch_glyph_row;
18277 truncate_it.glyph_row->used[TEXT_AREA] = 0;
18278 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
18279 truncate_it.object = make_number (0);
18280 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
18282 /* Overwrite glyphs from IT with truncation glyphs. */
18283 if (!it->glyph_row->reversed_p)
18285 short tused = truncate_it.glyph_row->used[TEXT_AREA];
18287 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
18288 end = from + tused;
18289 to = it->glyph_row->glyphs[TEXT_AREA];
18290 toend = to + it->glyph_row->used[TEXT_AREA];
18291 if (FRAME_WINDOW_P (it->f))
18293 /* On GUI frames, when variable-size fonts are displayed,
18294 the truncation glyphs may need more pixels than the row's
18295 glyphs they overwrite. We overwrite more glyphs to free
18296 enough screen real estate, and enlarge the stretch glyph
18297 on the right (see display_line), if there is one, to
18298 preserve the screen position of the truncation glyphs on
18299 the right. */
18300 int w = 0;
18301 struct glyph *g = to;
18302 short used;
18304 /* The first glyph could be partially visible, in which case
18305 it->glyph_row->x will be negative. But we want the left
18306 truncation glyphs to be aligned at the left margin of the
18307 window, so we override the x coordinate at which the row
18308 will begin. */
18309 it->glyph_row->x = 0;
18310 while (g < toend && w < it->truncation_pixel_width)
18312 w += g->pixel_width;
18313 ++g;
18315 if (g - to - tused > 0)
18317 memmove (to + tused, g, (toend - g) * sizeof(*g));
18318 it->glyph_row->used[TEXT_AREA] -= g - to - tused;
18320 used = it->glyph_row->used[TEXT_AREA];
18321 if (it->glyph_row->truncated_on_right_p
18322 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
18323 && it->glyph_row->glyphs[TEXT_AREA][used - 2].type
18324 == STRETCH_GLYPH)
18326 int extra = w - it->truncation_pixel_width;
18328 it->glyph_row->glyphs[TEXT_AREA][used - 2].pixel_width += extra;
18332 while (from < end)
18333 *to++ = *from++;
18335 /* There may be padding glyphs left over. Overwrite them too. */
18336 if (!FRAME_WINDOW_P (it->f))
18338 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
18340 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
18341 while (from < end)
18342 *to++ = *from++;
18346 if (to > toend)
18347 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
18349 else
18351 short tused = truncate_it.glyph_row->used[TEXT_AREA];
18353 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
18354 that back to front. */
18355 end = truncate_it.glyph_row->glyphs[TEXT_AREA];
18356 from = end + truncate_it.glyph_row->used[TEXT_AREA] - 1;
18357 toend = it->glyph_row->glyphs[TEXT_AREA];
18358 to = toend + it->glyph_row->used[TEXT_AREA] - 1;
18359 if (FRAME_WINDOW_P (it->f))
18361 int w = 0;
18362 struct glyph *g = to;
18364 while (g >= toend && w < it->truncation_pixel_width)
18366 w += g->pixel_width;
18367 --g;
18369 if (to - g - tused > 0)
18370 to = g + tused;
18371 if (it->glyph_row->truncated_on_right_p
18372 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0
18373 && it->glyph_row->glyphs[TEXT_AREA][1].type == STRETCH_GLYPH)
18375 int extra = w - it->truncation_pixel_width;
18377 it->glyph_row->glyphs[TEXT_AREA][1].pixel_width += extra;
18381 while (from >= end && to >= toend)
18382 *to-- = *from--;
18383 if (!FRAME_WINDOW_P (it->f))
18385 while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
18387 from =
18388 truncate_it.glyph_row->glyphs[TEXT_AREA]
18389 + truncate_it.glyph_row->used[TEXT_AREA] - 1;
18390 while (from >= end && to >= toend)
18391 *to-- = *from--;
18394 if (from >= end)
18396 /* Need to free some room before prepending additional
18397 glyphs. */
18398 int move_by = from - end + 1;
18399 struct glyph *g0 = it->glyph_row->glyphs[TEXT_AREA];
18400 struct glyph *g = g0 + it->glyph_row->used[TEXT_AREA] - 1;
18402 for ( ; g >= g0; g--)
18403 g[move_by] = *g;
18404 while (from >= end)
18405 *to-- = *from--;
18406 it->glyph_row->used[TEXT_AREA] += move_by;
18411 /* Compute the hash code for ROW. */
18412 unsigned
18413 row_hash (struct glyph_row *row)
18415 int area, k;
18416 unsigned hashval = 0;
18418 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18419 for (k = 0; k < row->used[area]; ++k)
18420 hashval = ((((hashval << 4) + (hashval >> 24)) & 0x0fffffff)
18421 + row->glyphs[area][k].u.val
18422 + row->glyphs[area][k].face_id
18423 + row->glyphs[area][k].padding_p
18424 + (row->glyphs[area][k].type << 2));
18426 return hashval;
18429 /* Compute the pixel height and width of IT->glyph_row.
18431 Most of the time, ascent and height of a display line will be equal
18432 to the max_ascent and max_height values of the display iterator
18433 structure. This is not the case if
18435 1. We hit ZV without displaying anything. In this case, max_ascent
18436 and max_height will be zero.
18438 2. We have some glyphs that don't contribute to the line height.
18439 (The glyph row flag contributes_to_line_height_p is for future
18440 pixmap extensions).
18442 The first case is easily covered by using default values because in
18443 these cases, the line height does not really matter, except that it
18444 must not be zero. */
18446 static void
18447 compute_line_metrics (struct it *it)
18449 struct glyph_row *row = it->glyph_row;
18451 if (FRAME_WINDOW_P (it->f))
18453 int i, min_y, max_y;
18455 /* The line may consist of one space only, that was added to
18456 place the cursor on it. If so, the row's height hasn't been
18457 computed yet. */
18458 if (row->height == 0)
18460 if (it->max_ascent + it->max_descent == 0)
18461 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
18462 row->ascent = it->max_ascent;
18463 row->height = it->max_ascent + it->max_descent;
18464 row->phys_ascent = it->max_phys_ascent;
18465 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
18466 row->extra_line_spacing = it->max_extra_line_spacing;
18469 /* Compute the width of this line. */
18470 row->pixel_width = row->x;
18471 for (i = 0; i < row->used[TEXT_AREA]; ++i)
18472 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
18474 eassert (row->pixel_width >= 0);
18475 eassert (row->ascent >= 0 && row->height > 0);
18477 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
18478 || MATRIX_ROW_OVERLAPS_PRED_P (row));
18480 /* If first line's physical ascent is larger than its logical
18481 ascent, use the physical ascent, and make the row taller.
18482 This makes accented characters fully visible. */
18483 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
18484 && row->phys_ascent > row->ascent)
18486 row->height += row->phys_ascent - row->ascent;
18487 row->ascent = row->phys_ascent;
18490 /* Compute how much of the line is visible. */
18491 row->visible_height = row->height;
18493 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
18494 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
18496 if (row->y < min_y)
18497 row->visible_height -= min_y - row->y;
18498 if (row->y + row->height > max_y)
18499 row->visible_height -= row->y + row->height - max_y;
18501 else
18503 row->pixel_width = row->used[TEXT_AREA];
18504 if (row->continued_p)
18505 row->pixel_width -= it->continuation_pixel_width;
18506 else if (row->truncated_on_right_p)
18507 row->pixel_width -= it->truncation_pixel_width;
18508 row->ascent = row->phys_ascent = 0;
18509 row->height = row->phys_height = row->visible_height = 1;
18510 row->extra_line_spacing = 0;
18513 /* Compute a hash code for this row. */
18514 row->hash = row_hash (row);
18516 it->max_ascent = it->max_descent = 0;
18517 it->max_phys_ascent = it->max_phys_descent = 0;
18521 /* Append one space to the glyph row of iterator IT if doing a
18522 window-based redisplay. The space has the same face as
18523 IT->face_id. Value is non-zero if a space was added.
18525 This function is called to make sure that there is always one glyph
18526 at the end of a glyph row that the cursor can be set on under
18527 window-systems. (If there weren't such a glyph we would not know
18528 how wide and tall a box cursor should be displayed).
18530 At the same time this space let's a nicely handle clearing to the
18531 end of the line if the row ends in italic text. */
18533 static int
18534 append_space_for_newline (struct it *it, int default_face_p)
18536 if (FRAME_WINDOW_P (it->f))
18538 int n = it->glyph_row->used[TEXT_AREA];
18540 if (it->glyph_row->glyphs[TEXT_AREA] + n
18541 < it->glyph_row->glyphs[1 + TEXT_AREA])
18543 /* Save some values that must not be changed.
18544 Must save IT->c and IT->len because otherwise
18545 ITERATOR_AT_END_P wouldn't work anymore after
18546 append_space_for_newline has been called. */
18547 enum display_element_type saved_what = it->what;
18548 int saved_c = it->c, saved_len = it->len;
18549 int saved_char_to_display = it->char_to_display;
18550 int saved_x = it->current_x;
18551 int saved_face_id = it->face_id;
18552 int saved_box_end = it->end_of_box_run_p;
18553 struct text_pos saved_pos;
18554 Lisp_Object saved_object;
18555 struct face *face;
18557 saved_object = it->object;
18558 saved_pos = it->position;
18560 it->what = IT_CHARACTER;
18561 memset (&it->position, 0, sizeof it->position);
18562 it->object = make_number (0);
18563 it->c = it->char_to_display = ' ';
18564 it->len = 1;
18566 /* If the default face was remapped, be sure to use the
18567 remapped face for the appended newline. */
18568 if (default_face_p)
18569 it->face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
18570 else if (it->face_before_selective_p)
18571 it->face_id = it->saved_face_id;
18572 face = FACE_FROM_ID (it->f, it->face_id);
18573 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
18574 /* In R2L rows, we will prepend a stretch glyph that will
18575 have the end_of_box_run_p flag set for it, so there's no
18576 need for the appended newline glyph to have that flag
18577 set. */
18578 if (it->glyph_row->reversed_p
18579 /* But if the appended newline glyph goes all the way to
18580 the end of the row, there will be no stretch glyph,
18581 so leave the box flag set. */
18582 && saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x)
18583 it->end_of_box_run_p = 0;
18585 PRODUCE_GLYPHS (it);
18587 it->override_ascent = -1;
18588 it->constrain_row_ascent_descent_p = 0;
18589 it->current_x = saved_x;
18590 it->object = saved_object;
18591 it->position = saved_pos;
18592 it->what = saved_what;
18593 it->face_id = saved_face_id;
18594 it->len = saved_len;
18595 it->c = saved_c;
18596 it->char_to_display = saved_char_to_display;
18597 it->end_of_box_run_p = saved_box_end;
18598 return 1;
18602 return 0;
18606 /* Extend the face of the last glyph in the text area of IT->glyph_row
18607 to the end of the display line. Called from display_line. If the
18608 glyph row is empty, add a space glyph to it so that we know the
18609 face to draw. Set the glyph row flag fill_line_p. If the glyph
18610 row is R2L, prepend a stretch glyph to cover the empty space to the
18611 left of the leftmost glyph. */
18613 static void
18614 extend_face_to_end_of_line (struct it *it)
18616 struct face *face, *default_face;
18617 struct frame *f = it->f;
18619 /* If line is already filled, do nothing. Non window-system frames
18620 get a grace of one more ``pixel'' because their characters are
18621 1-``pixel'' wide, so they hit the equality too early. This grace
18622 is needed only for R2L rows that are not continued, to produce
18623 one extra blank where we could display the cursor. */
18624 if (it->current_x >= it->last_visible_x
18625 + (!FRAME_WINDOW_P (f)
18626 && it->glyph_row->reversed_p
18627 && !it->glyph_row->continued_p))
18628 return;
18630 /* The default face, possibly remapped. */
18631 default_face = FACE_FROM_ID (f, lookup_basic_face (f, DEFAULT_FACE_ID));
18633 /* Face extension extends the background and box of IT->face_id
18634 to the end of the line. If the background equals the background
18635 of the frame, we don't have to do anything. */
18636 if (it->face_before_selective_p)
18637 face = FACE_FROM_ID (f, it->saved_face_id);
18638 else
18639 face = FACE_FROM_ID (f, it->face_id);
18641 if (FRAME_WINDOW_P (f)
18642 && MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row)
18643 && face->box == FACE_NO_BOX
18644 && face->background == FRAME_BACKGROUND_PIXEL (f)
18645 && !face->stipple
18646 && !it->glyph_row->reversed_p)
18647 return;
18649 /* Set the glyph row flag indicating that the face of the last glyph
18650 in the text area has to be drawn to the end of the text area. */
18651 it->glyph_row->fill_line_p = 1;
18653 /* If current character of IT is not ASCII, make sure we have the
18654 ASCII face. This will be automatically undone the next time
18655 get_next_display_element returns a multibyte character. Note
18656 that the character will always be single byte in unibyte
18657 text. */
18658 if (!ASCII_CHAR_P (it->c))
18660 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
18663 if (FRAME_WINDOW_P (f))
18665 /* If the row is empty, add a space with the current face of IT,
18666 so that we know which face to draw. */
18667 if (it->glyph_row->used[TEXT_AREA] == 0)
18669 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
18670 it->glyph_row->glyphs[TEXT_AREA][0].face_id = face->id;
18671 it->glyph_row->used[TEXT_AREA] = 1;
18673 #ifdef HAVE_WINDOW_SYSTEM
18674 if (it->glyph_row->reversed_p)
18676 /* Prepend a stretch glyph to the row, such that the
18677 rightmost glyph will be drawn flushed all the way to the
18678 right margin of the window. The stretch glyph that will
18679 occupy the empty space, if any, to the left of the
18680 glyphs. */
18681 struct font *font = face->font ? face->font : FRAME_FONT (f);
18682 struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA];
18683 struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA];
18684 struct glyph *g;
18685 int row_width, stretch_ascent, stretch_width;
18686 struct text_pos saved_pos;
18687 int saved_face_id, saved_avoid_cursor, saved_box_start;
18689 for (row_width = 0, g = row_start; g < row_end; g++)
18690 row_width += g->pixel_width;
18691 stretch_width = window_box_width (it->w, TEXT_AREA) - row_width;
18692 if (stretch_width > 0)
18694 stretch_ascent =
18695 (((it->ascent + it->descent)
18696 * FONT_BASE (font)) / FONT_HEIGHT (font));
18697 saved_pos = it->position;
18698 memset (&it->position, 0, sizeof it->position);
18699 saved_avoid_cursor = it->avoid_cursor_p;
18700 it->avoid_cursor_p = 1;
18701 saved_face_id = it->face_id;
18702 saved_box_start = it->start_of_box_run_p;
18703 /* The last row's stretch glyph should get the default
18704 face, to avoid painting the rest of the window with
18705 the region face, if the region ends at ZV. */
18706 if (it->glyph_row->ends_at_zv_p)
18707 it->face_id = default_face->id;
18708 else
18709 it->face_id = face->id;
18710 it->start_of_box_run_p = 0;
18711 append_stretch_glyph (it, make_number (0), stretch_width,
18712 it->ascent + it->descent, stretch_ascent);
18713 it->position = saved_pos;
18714 it->avoid_cursor_p = saved_avoid_cursor;
18715 it->face_id = saved_face_id;
18716 it->start_of_box_run_p = saved_box_start;
18719 #endif /* HAVE_WINDOW_SYSTEM */
18721 else
18723 /* Save some values that must not be changed. */
18724 int saved_x = it->current_x;
18725 struct text_pos saved_pos;
18726 Lisp_Object saved_object;
18727 enum display_element_type saved_what = it->what;
18728 int saved_face_id = it->face_id;
18730 saved_object = it->object;
18731 saved_pos = it->position;
18733 it->what = IT_CHARACTER;
18734 memset (&it->position, 0, sizeof it->position);
18735 it->object = make_number (0);
18736 it->c = it->char_to_display = ' ';
18737 it->len = 1;
18738 /* The last row's blank glyphs should get the default face, to
18739 avoid painting the rest of the window with the region face,
18740 if the region ends at ZV. */
18741 if (it->glyph_row->ends_at_zv_p)
18742 it->face_id = default_face->id;
18743 else
18744 it->face_id = face->id;
18746 PRODUCE_GLYPHS (it);
18748 while (it->current_x <= it->last_visible_x)
18749 PRODUCE_GLYPHS (it);
18751 /* Don't count these blanks really. It would let us insert a left
18752 truncation glyph below and make us set the cursor on them, maybe. */
18753 it->current_x = saved_x;
18754 it->object = saved_object;
18755 it->position = saved_pos;
18756 it->what = saved_what;
18757 it->face_id = saved_face_id;
18762 /* Value is non-zero if text starting at CHARPOS in current_buffer is
18763 trailing whitespace. */
18765 static int
18766 trailing_whitespace_p (ptrdiff_t charpos)
18768 ptrdiff_t bytepos = CHAR_TO_BYTE (charpos);
18769 int c = 0;
18771 while (bytepos < ZV_BYTE
18772 && (c = FETCH_CHAR (bytepos),
18773 c == ' ' || c == '\t'))
18774 ++bytepos;
18776 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
18778 if (bytepos != PT_BYTE)
18779 return 1;
18781 return 0;
18785 /* Highlight trailing whitespace, if any, in ROW. */
18787 static void
18788 highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
18790 int used = row->used[TEXT_AREA];
18792 if (used)
18794 struct glyph *start = row->glyphs[TEXT_AREA];
18795 struct glyph *glyph = start + used - 1;
18797 if (row->reversed_p)
18799 /* Right-to-left rows need to be processed in the opposite
18800 direction, so swap the edge pointers. */
18801 glyph = start;
18802 start = row->glyphs[TEXT_AREA] + used - 1;
18805 /* Skip over glyphs inserted to display the cursor at the
18806 end of a line, for extending the face of the last glyph
18807 to the end of the line on terminals, and for truncation
18808 and continuation glyphs. */
18809 if (!row->reversed_p)
18811 while (glyph >= start
18812 && glyph->type == CHAR_GLYPH
18813 && INTEGERP (glyph->object))
18814 --glyph;
18816 else
18818 while (glyph <= start
18819 && glyph->type == CHAR_GLYPH
18820 && INTEGERP (glyph->object))
18821 ++glyph;
18824 /* If last glyph is a space or stretch, and it's trailing
18825 whitespace, set the face of all trailing whitespace glyphs in
18826 IT->glyph_row to `trailing-whitespace'. */
18827 if ((row->reversed_p ? glyph <= start : glyph >= start)
18828 && BUFFERP (glyph->object)
18829 && (glyph->type == STRETCH_GLYPH
18830 || (glyph->type == CHAR_GLYPH
18831 && glyph->u.ch == ' '))
18832 && trailing_whitespace_p (glyph->charpos))
18834 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
18835 if (face_id < 0)
18836 return;
18838 if (!row->reversed_p)
18840 while (glyph >= start
18841 && BUFFERP (glyph->object)
18842 && (glyph->type == STRETCH_GLYPH
18843 || (glyph->type == CHAR_GLYPH
18844 && glyph->u.ch == ' ')))
18845 (glyph--)->face_id = face_id;
18847 else
18849 while (glyph <= start
18850 && BUFFERP (glyph->object)
18851 && (glyph->type == STRETCH_GLYPH
18852 || (glyph->type == CHAR_GLYPH
18853 && glyph->u.ch == ' ')))
18854 (glyph++)->face_id = face_id;
18861 /* Value is non-zero if glyph row ROW should be
18862 considered to hold the buffer position CHARPOS. */
18864 static int
18865 row_for_charpos_p (struct glyph_row *row, ptrdiff_t charpos)
18867 int result = 1;
18869 if (charpos == CHARPOS (row->end.pos)
18870 || charpos == MATRIX_ROW_END_CHARPOS (row))
18872 /* Suppose the row ends on a string.
18873 Unless the row is continued, that means it ends on a newline
18874 in the string. If it's anything other than a display string
18875 (e.g., a before-string from an overlay), we don't want the
18876 cursor there. (This heuristic seems to give the optimal
18877 behavior for the various types of multi-line strings.)
18878 One exception: if the string has `cursor' property on one of
18879 its characters, we _do_ want the cursor there. */
18880 if (CHARPOS (row->end.string_pos) >= 0)
18882 if (row->continued_p)
18883 result = 1;
18884 else
18886 /* Check for `display' property. */
18887 struct glyph *beg = row->glyphs[TEXT_AREA];
18888 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
18889 struct glyph *glyph;
18891 result = 0;
18892 for (glyph = end; glyph >= beg; --glyph)
18893 if (STRINGP (glyph->object))
18895 Lisp_Object prop
18896 = Fget_char_property (make_number (charpos),
18897 Qdisplay, Qnil);
18898 result =
18899 (!NILP (prop)
18900 && display_prop_string_p (prop, glyph->object));
18901 /* If there's a `cursor' property on one of the
18902 string's characters, this row is a cursor row,
18903 even though this is not a display string. */
18904 if (!result)
18906 Lisp_Object s = glyph->object;
18908 for ( ; glyph >= beg && EQ (glyph->object, s); --glyph)
18910 ptrdiff_t gpos = glyph->charpos;
18912 if (!NILP (Fget_char_property (make_number (gpos),
18913 Qcursor, s)))
18915 result = 1;
18916 break;
18920 break;
18924 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
18926 /* If the row ends in middle of a real character,
18927 and the line is continued, we want the cursor here.
18928 That's because CHARPOS (ROW->end.pos) would equal
18929 PT if PT is before the character. */
18930 if (!row->ends_in_ellipsis_p)
18931 result = row->continued_p;
18932 else
18933 /* If the row ends in an ellipsis, then
18934 CHARPOS (ROW->end.pos) will equal point after the
18935 invisible text. We want that position to be displayed
18936 after the ellipsis. */
18937 result = 0;
18939 /* If the row ends at ZV, display the cursor at the end of that
18940 row instead of at the start of the row below. */
18941 else if (row->ends_at_zv_p)
18942 result = 1;
18943 else
18944 result = 0;
18947 return result;
18950 /* Value is non-zero if glyph row ROW should be
18951 used to hold the cursor. */
18953 static int
18954 cursor_row_p (struct glyph_row *row)
18956 return row_for_charpos_p (row, PT);
18961 /* Push the property PROP so that it will be rendered at the current
18962 position in IT. Return 1 if PROP was successfully pushed, 0
18963 otherwise. Called from handle_line_prefix to handle the
18964 `line-prefix' and `wrap-prefix' properties. */
18966 static int
18967 push_prefix_prop (struct it *it, Lisp_Object prop)
18969 struct text_pos pos =
18970 STRINGP (it->string) ? it->current.string_pos : it->current.pos;
18972 eassert (it->method == GET_FROM_BUFFER
18973 || it->method == GET_FROM_DISPLAY_VECTOR
18974 || it->method == GET_FROM_STRING);
18976 /* We need to save the current buffer/string position, so it will be
18977 restored by pop_it, because iterate_out_of_display_property
18978 depends on that being set correctly, but some situations leave
18979 it->position not yet set when this function is called. */
18980 push_it (it, &pos);
18982 if (STRINGP (prop))
18984 if (SCHARS (prop) == 0)
18986 pop_it (it);
18987 return 0;
18990 it->string = prop;
18991 it->string_from_prefix_prop_p = 1;
18992 it->multibyte_p = STRING_MULTIBYTE (it->string);
18993 it->current.overlay_string_index = -1;
18994 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
18995 it->end_charpos = it->string_nchars = SCHARS (it->string);
18996 it->method = GET_FROM_STRING;
18997 it->stop_charpos = 0;
18998 it->prev_stop = 0;
18999 it->base_level_stop = 0;
19001 /* Force paragraph direction to be that of the parent
19002 buffer/string. */
19003 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
19004 it->paragraph_embedding = it->bidi_it.paragraph_dir;
19005 else
19006 it->paragraph_embedding = L2R;
19008 /* Set up the bidi iterator for this display string. */
19009 if (it->bidi_p)
19011 it->bidi_it.string.lstring = it->string;
19012 it->bidi_it.string.s = NULL;
19013 it->bidi_it.string.schars = it->end_charpos;
19014 it->bidi_it.string.bufpos = IT_CHARPOS (*it);
19015 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
19016 it->bidi_it.string.unibyte = !it->multibyte_p;
19017 it->bidi_it.w = it->w;
19018 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
19021 else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
19023 it->method = GET_FROM_STRETCH;
19024 it->object = prop;
19026 #ifdef HAVE_WINDOW_SYSTEM
19027 else if (IMAGEP (prop))
19029 it->what = IT_IMAGE;
19030 it->image_id = lookup_image (it->f, prop);
19031 it->method = GET_FROM_IMAGE;
19033 #endif /* HAVE_WINDOW_SYSTEM */
19034 else
19036 pop_it (it); /* bogus display property, give up */
19037 return 0;
19040 return 1;
19043 /* Return the character-property PROP at the current position in IT. */
19045 static Lisp_Object
19046 get_it_property (struct it *it, Lisp_Object prop)
19048 Lisp_Object position, object = it->object;
19050 if (STRINGP (object))
19051 position = make_number (IT_STRING_CHARPOS (*it));
19052 else if (BUFFERP (object))
19054 position = make_number (IT_CHARPOS (*it));
19055 object = it->window;
19057 else
19058 return Qnil;
19060 return Fget_char_property (position, prop, object);
19063 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
19065 static void
19066 handle_line_prefix (struct it *it)
19068 Lisp_Object prefix;
19070 if (it->continuation_lines_width > 0)
19072 prefix = get_it_property (it, Qwrap_prefix);
19073 if (NILP (prefix))
19074 prefix = Vwrap_prefix;
19076 else
19078 prefix = get_it_property (it, Qline_prefix);
19079 if (NILP (prefix))
19080 prefix = Vline_prefix;
19082 if (! NILP (prefix) && push_prefix_prop (it, prefix))
19084 /* If the prefix is wider than the window, and we try to wrap
19085 it, it would acquire its own wrap prefix, and so on till the
19086 iterator stack overflows. So, don't wrap the prefix. */
19087 it->line_wrap = TRUNCATE;
19088 it->avoid_cursor_p = 1;
19094 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
19095 only for R2L lines from display_line and display_string, when they
19096 decide that too many glyphs were produced by PRODUCE_GLYPHS, and
19097 the line/string needs to be continued on the next glyph row. */
19098 static void
19099 unproduce_glyphs (struct it *it, int n)
19101 struct glyph *glyph, *end;
19103 eassert (it->glyph_row);
19104 eassert (it->glyph_row->reversed_p);
19105 eassert (it->area == TEXT_AREA);
19106 eassert (n <= it->glyph_row->used[TEXT_AREA]);
19108 if (n > it->glyph_row->used[TEXT_AREA])
19109 n = it->glyph_row->used[TEXT_AREA];
19110 glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
19111 end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
19112 for ( ; glyph < end; glyph++)
19113 glyph[-n] = *glyph;
19116 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
19117 and ROW->maxpos. */
19118 static void
19119 find_row_edges (struct it *it, struct glyph_row *row,
19120 ptrdiff_t min_pos, ptrdiff_t min_bpos,
19121 ptrdiff_t max_pos, ptrdiff_t max_bpos)
19123 /* FIXME: Revisit this when glyph ``spilling'' in continuation
19124 lines' rows is implemented for bidi-reordered rows. */
19126 /* ROW->minpos is the value of min_pos, the minimal buffer position
19127 we have in ROW, or ROW->start.pos if that is smaller. */
19128 if (min_pos <= ZV && min_pos < row->start.pos.charpos)
19129 SET_TEXT_POS (row->minpos, min_pos, min_bpos);
19130 else
19131 /* We didn't find buffer positions smaller than ROW->start, or
19132 didn't find _any_ valid buffer positions in any of the glyphs,
19133 so we must trust the iterator's computed positions. */
19134 row->minpos = row->start.pos;
19135 if (max_pos <= 0)
19137 max_pos = CHARPOS (it->current.pos);
19138 max_bpos = BYTEPOS (it->current.pos);
19141 /* Here are the various use-cases for ending the row, and the
19142 corresponding values for ROW->maxpos:
19144 Line ends in a newline from buffer eol_pos + 1
19145 Line is continued from buffer max_pos + 1
19146 Line is truncated on right it->current.pos
19147 Line ends in a newline from string max_pos + 1(*)
19148 (*) + 1 only when line ends in a forward scan
19149 Line is continued from string max_pos
19150 Line is continued from display vector max_pos
19151 Line is entirely from a string min_pos == max_pos
19152 Line is entirely from a display vector min_pos == max_pos
19153 Line that ends at ZV ZV
19155 If you discover other use-cases, please add them here as
19156 appropriate. */
19157 if (row->ends_at_zv_p)
19158 row->maxpos = it->current.pos;
19159 else if (row->used[TEXT_AREA])
19161 int seen_this_string = 0;
19162 struct glyph_row *r1 = row - 1;
19164 /* Did we see the same display string on the previous row? */
19165 if (STRINGP (it->object)
19166 /* this is not the first row */
19167 && row > it->w->desired_matrix->rows
19168 /* previous row is not the header line */
19169 && !r1->mode_line_p
19170 /* previous row also ends in a newline from a string */
19171 && r1->ends_in_newline_from_string_p)
19173 struct glyph *start, *end;
19175 /* Search for the last glyph of the previous row that came
19176 from buffer or string. Depending on whether the row is
19177 L2R or R2L, we need to process it front to back or the
19178 other way round. */
19179 if (!r1->reversed_p)
19181 start = r1->glyphs[TEXT_AREA];
19182 end = start + r1->used[TEXT_AREA];
19183 /* Glyphs inserted by redisplay have an integer (zero)
19184 as their object. */
19185 while (end > start
19186 && INTEGERP ((end - 1)->object)
19187 && (end - 1)->charpos <= 0)
19188 --end;
19189 if (end > start)
19191 if (EQ ((end - 1)->object, it->object))
19192 seen_this_string = 1;
19194 else
19195 /* If all the glyphs of the previous row were inserted
19196 by redisplay, it means the previous row was
19197 produced from a single newline, which is only
19198 possible if that newline came from the same string
19199 as the one which produced this ROW. */
19200 seen_this_string = 1;
19202 else
19204 end = r1->glyphs[TEXT_AREA] - 1;
19205 start = end + r1->used[TEXT_AREA];
19206 while (end < start
19207 && INTEGERP ((end + 1)->object)
19208 && (end + 1)->charpos <= 0)
19209 ++end;
19210 if (end < start)
19212 if (EQ ((end + 1)->object, it->object))
19213 seen_this_string = 1;
19215 else
19216 seen_this_string = 1;
19219 /* Take note of each display string that covers a newline only
19220 once, the first time we see it. This is for when a display
19221 string includes more than one newline in it. */
19222 if (row->ends_in_newline_from_string_p && !seen_this_string)
19224 /* If we were scanning the buffer forward when we displayed
19225 the string, we want to account for at least one buffer
19226 position that belongs to this row (position covered by
19227 the display string), so that cursor positioning will
19228 consider this row as a candidate when point is at the end
19229 of the visual line represented by this row. This is not
19230 required when scanning back, because max_pos will already
19231 have a much larger value. */
19232 if (CHARPOS (row->end.pos) > max_pos)
19233 INC_BOTH (max_pos, max_bpos);
19234 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19236 else if (CHARPOS (it->eol_pos) > 0)
19237 SET_TEXT_POS (row->maxpos,
19238 CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
19239 else if (row->continued_p)
19241 /* If max_pos is different from IT's current position, it
19242 means IT->method does not belong to the display element
19243 at max_pos. However, it also means that the display
19244 element at max_pos was displayed in its entirety on this
19245 line, which is equivalent to saying that the next line
19246 starts at the next buffer position. */
19247 if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
19248 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19249 else
19251 INC_BOTH (max_pos, max_bpos);
19252 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19255 else if (row->truncated_on_right_p)
19256 /* display_line already called reseat_at_next_visible_line_start,
19257 which puts the iterator at the beginning of the next line, in
19258 the logical order. */
19259 row->maxpos = it->current.pos;
19260 else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
19261 /* A line that is entirely from a string/image/stretch... */
19262 row->maxpos = row->minpos;
19263 else
19264 emacs_abort ();
19266 else
19267 row->maxpos = it->current.pos;
19270 /* Construct the glyph row IT->glyph_row in the desired matrix of
19271 IT->w from text at the current position of IT. See dispextern.h
19272 for an overview of struct it. Value is non-zero if
19273 IT->glyph_row displays text, as opposed to a line displaying ZV
19274 only. */
19276 static int
19277 display_line (struct it *it)
19279 struct glyph_row *row = it->glyph_row;
19280 Lisp_Object overlay_arrow_string;
19281 struct it wrap_it;
19282 void *wrap_data = NULL;
19283 int may_wrap = 0, wrap_x IF_LINT (= 0);
19284 int wrap_row_used = -1;
19285 int wrap_row_ascent IF_LINT (= 0), wrap_row_height IF_LINT (= 0);
19286 int wrap_row_phys_ascent IF_LINT (= 0), wrap_row_phys_height IF_LINT (= 0);
19287 int wrap_row_extra_line_spacing IF_LINT (= 0);
19288 ptrdiff_t wrap_row_min_pos IF_LINT (= 0), wrap_row_min_bpos IF_LINT (= 0);
19289 ptrdiff_t wrap_row_max_pos IF_LINT (= 0), wrap_row_max_bpos IF_LINT (= 0);
19290 int cvpos;
19291 ptrdiff_t min_pos = ZV + 1, max_pos = 0;
19292 ptrdiff_t min_bpos IF_LINT (= 0), max_bpos IF_LINT (= 0);
19294 /* We always start displaying at hpos zero even if hscrolled. */
19295 eassert (it->hpos == 0 && it->current_x == 0);
19297 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
19298 >= it->w->desired_matrix->nrows)
19300 it->w->nrows_scale_factor++;
19301 fonts_changed_p = 1;
19302 return 0;
19305 /* Is IT->w showing the region? */
19306 it->w->region_showing = it->region_beg_charpos > 0 ? it->region_beg_charpos : 0;
19308 /* Clear the result glyph row and enable it. */
19309 prepare_desired_row (row);
19311 row->y = it->current_y;
19312 row->start = it->start;
19313 row->continuation_lines_width = it->continuation_lines_width;
19314 row->displays_text_p = 1;
19315 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
19316 it->starts_in_middle_of_char_p = 0;
19318 /* Arrange the overlays nicely for our purposes. Usually, we call
19319 display_line on only one line at a time, in which case this
19320 can't really hurt too much, or we call it on lines which appear
19321 one after another in the buffer, in which case all calls to
19322 recenter_overlay_lists but the first will be pretty cheap. */
19323 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
19325 /* Move over display elements that are not visible because we are
19326 hscrolled. This may stop at an x-position < IT->first_visible_x
19327 if the first glyph is partially visible or if we hit a line end. */
19328 if (it->current_x < it->first_visible_x)
19330 enum move_it_result move_result;
19332 this_line_min_pos = row->start.pos;
19333 move_result = move_it_in_display_line_to (it, ZV, it->first_visible_x,
19334 MOVE_TO_POS | MOVE_TO_X);
19335 /* If we are under a large hscroll, move_it_in_display_line_to
19336 could hit the end of the line without reaching
19337 it->first_visible_x. Pretend that we did reach it. This is
19338 especially important on a TTY, where we will call
19339 extend_face_to_end_of_line, which needs to know how many
19340 blank glyphs to produce. */
19341 if (it->current_x < it->first_visible_x
19342 && (move_result == MOVE_NEWLINE_OR_CR
19343 || move_result == MOVE_POS_MATCH_OR_ZV))
19344 it->current_x = it->first_visible_x;
19346 /* Record the smallest positions seen while we moved over
19347 display elements that are not visible. This is needed by
19348 redisplay_internal for optimizing the case where the cursor
19349 stays inside the same line. The rest of this function only
19350 considers positions that are actually displayed, so
19351 RECORD_MAX_MIN_POS will not otherwise record positions that
19352 are hscrolled to the left of the left edge of the window. */
19353 min_pos = CHARPOS (this_line_min_pos);
19354 min_bpos = BYTEPOS (this_line_min_pos);
19356 else
19358 /* We only do this when not calling `move_it_in_display_line_to'
19359 above, because move_it_in_display_line_to calls
19360 handle_line_prefix itself. */
19361 handle_line_prefix (it);
19364 /* Get the initial row height. This is either the height of the
19365 text hscrolled, if there is any, or zero. */
19366 row->ascent = it->max_ascent;
19367 row->height = it->max_ascent + it->max_descent;
19368 row->phys_ascent = it->max_phys_ascent;
19369 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
19370 row->extra_line_spacing = it->max_extra_line_spacing;
19372 /* Utility macro to record max and min buffer positions seen until now. */
19373 #define RECORD_MAX_MIN_POS(IT) \
19374 do \
19376 int composition_p = !STRINGP ((IT)->string) \
19377 && ((IT)->what == IT_COMPOSITION); \
19378 ptrdiff_t current_pos = \
19379 composition_p ? (IT)->cmp_it.charpos \
19380 : IT_CHARPOS (*(IT)); \
19381 ptrdiff_t current_bpos = \
19382 composition_p ? CHAR_TO_BYTE (current_pos) \
19383 : IT_BYTEPOS (*(IT)); \
19384 if (current_pos < min_pos) \
19386 min_pos = current_pos; \
19387 min_bpos = current_bpos; \
19389 if (IT_CHARPOS (*it) > max_pos) \
19391 max_pos = IT_CHARPOS (*it); \
19392 max_bpos = IT_BYTEPOS (*it); \
19395 while (0)
19397 /* Loop generating characters. The loop is left with IT on the next
19398 character to display. */
19399 while (1)
19401 int n_glyphs_before, hpos_before, x_before;
19402 int x, nglyphs;
19403 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
19405 /* Retrieve the next thing to display. Value is zero if end of
19406 buffer reached. */
19407 if (!get_next_display_element (it))
19409 /* Maybe add a space at the end of this line that is used to
19410 display the cursor there under X. Set the charpos of the
19411 first glyph of blank lines not corresponding to any text
19412 to -1. */
19413 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19414 row->exact_window_width_line_p = 1;
19415 else if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
19416 || row->used[TEXT_AREA] == 0)
19418 row->glyphs[TEXT_AREA]->charpos = -1;
19419 row->displays_text_p = 0;
19421 if (!NILP (BVAR (XBUFFER (it->w->contents), indicate_empty_lines))
19422 && (!MINI_WINDOW_P (it->w)
19423 || (minibuf_level && EQ (it->window, minibuf_window))))
19424 row->indicate_empty_line_p = 1;
19427 it->continuation_lines_width = 0;
19428 row->ends_at_zv_p = 1;
19429 /* A row that displays right-to-left text must always have
19430 its last face extended all the way to the end of line,
19431 even if this row ends in ZV, because we still write to
19432 the screen left to right. We also need to extend the
19433 last face if the default face is remapped to some
19434 different face, otherwise the functions that clear
19435 portions of the screen will clear with the default face's
19436 background color. */
19437 if (row->reversed_p
19438 || lookup_basic_face (it->f, DEFAULT_FACE_ID) != DEFAULT_FACE_ID)
19439 extend_face_to_end_of_line (it);
19440 break;
19443 /* Now, get the metrics of what we want to display. This also
19444 generates glyphs in `row' (which is IT->glyph_row). */
19445 n_glyphs_before = row->used[TEXT_AREA];
19446 x = it->current_x;
19448 /* Remember the line height so far in case the next element doesn't
19449 fit on the line. */
19450 if (it->line_wrap != TRUNCATE)
19452 ascent = it->max_ascent;
19453 descent = it->max_descent;
19454 phys_ascent = it->max_phys_ascent;
19455 phys_descent = it->max_phys_descent;
19457 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
19459 if (IT_DISPLAYING_WHITESPACE (it))
19460 may_wrap = 1;
19461 else if (may_wrap)
19463 SAVE_IT (wrap_it, *it, wrap_data);
19464 wrap_x = x;
19465 wrap_row_used = row->used[TEXT_AREA];
19466 wrap_row_ascent = row->ascent;
19467 wrap_row_height = row->height;
19468 wrap_row_phys_ascent = row->phys_ascent;
19469 wrap_row_phys_height = row->phys_height;
19470 wrap_row_extra_line_spacing = row->extra_line_spacing;
19471 wrap_row_min_pos = min_pos;
19472 wrap_row_min_bpos = min_bpos;
19473 wrap_row_max_pos = max_pos;
19474 wrap_row_max_bpos = max_bpos;
19475 may_wrap = 0;
19480 PRODUCE_GLYPHS (it);
19482 /* If this display element was in marginal areas, continue with
19483 the next one. */
19484 if (it->area != TEXT_AREA)
19486 row->ascent = max (row->ascent, it->max_ascent);
19487 row->height = max (row->height, it->max_ascent + it->max_descent);
19488 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19489 row->phys_height = max (row->phys_height,
19490 it->max_phys_ascent + it->max_phys_descent);
19491 row->extra_line_spacing = max (row->extra_line_spacing,
19492 it->max_extra_line_spacing);
19493 set_iterator_to_next (it, 1);
19494 continue;
19497 /* Does the display element fit on the line? If we truncate
19498 lines, we should draw past the right edge of the window. If
19499 we don't truncate, we want to stop so that we can display the
19500 continuation glyph before the right margin. If lines are
19501 continued, there are two possible strategies for characters
19502 resulting in more than 1 glyph (e.g. tabs): Display as many
19503 glyphs as possible in this line and leave the rest for the
19504 continuation line, or display the whole element in the next
19505 line. Original redisplay did the former, so we do it also. */
19506 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
19507 hpos_before = it->hpos;
19508 x_before = x;
19510 if (/* Not a newline. */
19511 nglyphs > 0
19512 /* Glyphs produced fit entirely in the line. */
19513 && it->current_x < it->last_visible_x)
19515 it->hpos += nglyphs;
19516 row->ascent = max (row->ascent, it->max_ascent);
19517 row->height = max (row->height, it->max_ascent + it->max_descent);
19518 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19519 row->phys_height = max (row->phys_height,
19520 it->max_phys_ascent + it->max_phys_descent);
19521 row->extra_line_spacing = max (row->extra_line_spacing,
19522 it->max_extra_line_spacing);
19523 if (it->current_x - it->pixel_width < it->first_visible_x)
19524 row->x = x - it->first_visible_x;
19525 /* Record the maximum and minimum buffer positions seen so
19526 far in glyphs that will be displayed by this row. */
19527 if (it->bidi_p)
19528 RECORD_MAX_MIN_POS (it);
19530 else
19532 int i, new_x;
19533 struct glyph *glyph;
19535 for (i = 0; i < nglyphs; ++i, x = new_x)
19537 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
19538 new_x = x + glyph->pixel_width;
19540 if (/* Lines are continued. */
19541 it->line_wrap != TRUNCATE
19542 && (/* Glyph doesn't fit on the line. */
19543 new_x > it->last_visible_x
19544 /* Or it fits exactly on a window system frame. */
19545 || (new_x == it->last_visible_x
19546 && FRAME_WINDOW_P (it->f)
19547 && (row->reversed_p
19548 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19549 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
19551 /* End of a continued line. */
19553 if (it->hpos == 0
19554 || (new_x == it->last_visible_x
19555 && FRAME_WINDOW_P (it->f)
19556 && (row->reversed_p
19557 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19558 : WINDOW_RIGHT_FRINGE_WIDTH (it->w))))
19560 /* Current glyph is the only one on the line or
19561 fits exactly on the line. We must continue
19562 the line because we can't draw the cursor
19563 after the glyph. */
19564 row->continued_p = 1;
19565 it->current_x = new_x;
19566 it->continuation_lines_width += new_x;
19567 ++it->hpos;
19568 if (i == nglyphs - 1)
19570 /* If line-wrap is on, check if a previous
19571 wrap point was found. */
19572 if (wrap_row_used > 0
19573 /* Even if there is a previous wrap
19574 point, continue the line here as
19575 usual, if (i) the previous character
19576 was a space or tab AND (ii) the
19577 current character is not. */
19578 && (!may_wrap
19579 || IT_DISPLAYING_WHITESPACE (it)))
19580 goto back_to_wrap;
19582 /* Record the maximum and minimum buffer
19583 positions seen so far in glyphs that will be
19584 displayed by this row. */
19585 if (it->bidi_p)
19586 RECORD_MAX_MIN_POS (it);
19587 set_iterator_to_next (it, 1);
19588 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19590 if (!get_next_display_element (it))
19592 row->exact_window_width_line_p = 1;
19593 it->continuation_lines_width = 0;
19594 row->continued_p = 0;
19595 row->ends_at_zv_p = 1;
19597 else if (ITERATOR_AT_END_OF_LINE_P (it))
19599 row->continued_p = 0;
19600 row->exact_window_width_line_p = 1;
19604 else if (it->bidi_p)
19605 RECORD_MAX_MIN_POS (it);
19607 else if (CHAR_GLYPH_PADDING_P (*glyph)
19608 && !FRAME_WINDOW_P (it->f))
19610 /* A padding glyph that doesn't fit on this line.
19611 This means the whole character doesn't fit
19612 on the line. */
19613 if (row->reversed_p)
19614 unproduce_glyphs (it, row->used[TEXT_AREA]
19615 - n_glyphs_before);
19616 row->used[TEXT_AREA] = n_glyphs_before;
19618 /* Fill the rest of the row with continuation
19619 glyphs like in 20.x. */
19620 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
19621 < row->glyphs[1 + TEXT_AREA])
19622 produce_special_glyphs (it, IT_CONTINUATION);
19624 row->continued_p = 1;
19625 it->current_x = x_before;
19626 it->continuation_lines_width += x_before;
19628 /* Restore the height to what it was before the
19629 element not fitting on the line. */
19630 it->max_ascent = ascent;
19631 it->max_descent = descent;
19632 it->max_phys_ascent = phys_ascent;
19633 it->max_phys_descent = phys_descent;
19635 else if (wrap_row_used > 0)
19637 back_to_wrap:
19638 if (row->reversed_p)
19639 unproduce_glyphs (it,
19640 row->used[TEXT_AREA] - wrap_row_used);
19641 RESTORE_IT (it, &wrap_it, wrap_data);
19642 it->continuation_lines_width += wrap_x;
19643 row->used[TEXT_AREA] = wrap_row_used;
19644 row->ascent = wrap_row_ascent;
19645 row->height = wrap_row_height;
19646 row->phys_ascent = wrap_row_phys_ascent;
19647 row->phys_height = wrap_row_phys_height;
19648 row->extra_line_spacing = wrap_row_extra_line_spacing;
19649 min_pos = wrap_row_min_pos;
19650 min_bpos = wrap_row_min_bpos;
19651 max_pos = wrap_row_max_pos;
19652 max_bpos = wrap_row_max_bpos;
19653 row->continued_p = 1;
19654 row->ends_at_zv_p = 0;
19655 row->exact_window_width_line_p = 0;
19656 it->continuation_lines_width += x;
19658 /* Make sure that a non-default face is extended
19659 up to the right margin of the window. */
19660 extend_face_to_end_of_line (it);
19662 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
19664 /* A TAB that extends past the right edge of the
19665 window. This produces a single glyph on
19666 window system frames. We leave the glyph in
19667 this row and let it fill the row, but don't
19668 consume the TAB. */
19669 if ((row->reversed_p
19670 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19671 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
19672 produce_special_glyphs (it, IT_CONTINUATION);
19673 it->continuation_lines_width += it->last_visible_x;
19674 row->ends_in_middle_of_char_p = 1;
19675 row->continued_p = 1;
19676 glyph->pixel_width = it->last_visible_x - x;
19677 it->starts_in_middle_of_char_p = 1;
19679 else
19681 /* Something other than a TAB that draws past
19682 the right edge of the window. Restore
19683 positions to values before the element. */
19684 if (row->reversed_p)
19685 unproduce_glyphs (it, row->used[TEXT_AREA]
19686 - (n_glyphs_before + i));
19687 row->used[TEXT_AREA] = n_glyphs_before + i;
19689 /* Display continuation glyphs. */
19690 it->current_x = x_before;
19691 it->continuation_lines_width += x;
19692 if (!FRAME_WINDOW_P (it->f)
19693 || (row->reversed_p
19694 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19695 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
19696 produce_special_glyphs (it, IT_CONTINUATION);
19697 row->continued_p = 1;
19699 extend_face_to_end_of_line (it);
19701 if (nglyphs > 1 && i > 0)
19703 row->ends_in_middle_of_char_p = 1;
19704 it->starts_in_middle_of_char_p = 1;
19707 /* Restore the height to what it was before the
19708 element not fitting on the line. */
19709 it->max_ascent = ascent;
19710 it->max_descent = descent;
19711 it->max_phys_ascent = phys_ascent;
19712 it->max_phys_descent = phys_descent;
19715 break;
19717 else if (new_x > it->first_visible_x)
19719 /* Increment number of glyphs actually displayed. */
19720 ++it->hpos;
19722 /* Record the maximum and minimum buffer positions
19723 seen so far in glyphs that will be displayed by
19724 this row. */
19725 if (it->bidi_p)
19726 RECORD_MAX_MIN_POS (it);
19728 if (x < it->first_visible_x)
19729 /* Glyph is partially visible, i.e. row starts at
19730 negative X position. */
19731 row->x = x - it->first_visible_x;
19733 else
19735 /* Glyph is completely off the left margin of the
19736 window. This should not happen because of the
19737 move_it_in_display_line at the start of this
19738 function, unless the text display area of the
19739 window is empty. */
19740 eassert (it->first_visible_x <= it->last_visible_x);
19743 /* Even if this display element produced no glyphs at all,
19744 we want to record its position. */
19745 if (it->bidi_p && nglyphs == 0)
19746 RECORD_MAX_MIN_POS (it);
19748 row->ascent = max (row->ascent, it->max_ascent);
19749 row->height = max (row->height, it->max_ascent + it->max_descent);
19750 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19751 row->phys_height = max (row->phys_height,
19752 it->max_phys_ascent + it->max_phys_descent);
19753 row->extra_line_spacing = max (row->extra_line_spacing,
19754 it->max_extra_line_spacing);
19756 /* End of this display line if row is continued. */
19757 if (row->continued_p || row->ends_at_zv_p)
19758 break;
19761 at_end_of_line:
19762 /* Is this a line end? If yes, we're also done, after making
19763 sure that a non-default face is extended up to the right
19764 margin of the window. */
19765 if (ITERATOR_AT_END_OF_LINE_P (it))
19767 int used_before = row->used[TEXT_AREA];
19769 row->ends_in_newline_from_string_p = STRINGP (it->object);
19771 /* Add a space at the end of the line that is used to
19772 display the cursor there. */
19773 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19774 append_space_for_newline (it, 0);
19776 /* Extend the face to the end of the line. */
19777 extend_face_to_end_of_line (it);
19779 /* Make sure we have the position. */
19780 if (used_before == 0)
19781 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
19783 /* Record the position of the newline, for use in
19784 find_row_edges. */
19785 it->eol_pos = it->current.pos;
19787 /* Consume the line end. This skips over invisible lines. */
19788 set_iterator_to_next (it, 1);
19789 it->continuation_lines_width = 0;
19790 break;
19793 /* Proceed with next display element. Note that this skips
19794 over lines invisible because of selective display. */
19795 set_iterator_to_next (it, 1);
19797 /* If we truncate lines, we are done when the last displayed
19798 glyphs reach past the right margin of the window. */
19799 if (it->line_wrap == TRUNCATE
19800 && (FRAME_WINDOW_P (it->f) && WINDOW_RIGHT_FRINGE_WIDTH (it->w)
19801 ? (it->current_x >= it->last_visible_x)
19802 : (it->current_x > it->last_visible_x)))
19804 /* Maybe add truncation glyphs. */
19805 if (!FRAME_WINDOW_P (it->f)
19806 || (row->reversed_p
19807 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19808 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
19810 int i, n;
19812 if (!row->reversed_p)
19814 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
19815 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
19816 break;
19818 else
19820 for (i = 0; i < row->used[TEXT_AREA]; i++)
19821 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
19822 break;
19823 /* Remove any padding glyphs at the front of ROW, to
19824 make room for the truncation glyphs we will be
19825 adding below. The loop below always inserts at
19826 least one truncation glyph, so also remove the
19827 last glyph added to ROW. */
19828 unproduce_glyphs (it, i + 1);
19829 /* Adjust i for the loop below. */
19830 i = row->used[TEXT_AREA] - (i + 1);
19833 it->current_x = x_before;
19834 if (!FRAME_WINDOW_P (it->f))
19836 for (n = row->used[TEXT_AREA]; i < n; ++i)
19838 row->used[TEXT_AREA] = i;
19839 produce_special_glyphs (it, IT_TRUNCATION);
19842 else
19844 row->used[TEXT_AREA] = i;
19845 produce_special_glyphs (it, IT_TRUNCATION);
19848 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19850 /* Don't truncate if we can overflow newline into fringe. */
19851 if (!get_next_display_element (it))
19853 it->continuation_lines_width = 0;
19854 row->ends_at_zv_p = 1;
19855 row->exact_window_width_line_p = 1;
19856 break;
19858 if (ITERATOR_AT_END_OF_LINE_P (it))
19860 row->exact_window_width_line_p = 1;
19861 goto at_end_of_line;
19863 it->current_x = x_before;
19866 row->truncated_on_right_p = 1;
19867 it->continuation_lines_width = 0;
19868 reseat_at_next_visible_line_start (it, 0);
19869 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
19870 it->hpos = hpos_before;
19871 break;
19875 if (wrap_data)
19876 bidi_unshelve_cache (wrap_data, 1);
19878 /* If line is not empty and hscrolled, maybe insert truncation glyphs
19879 at the left window margin. */
19880 if (it->first_visible_x
19881 && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
19883 if (!FRAME_WINDOW_P (it->f)
19884 || (row->reversed_p
19885 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
19886 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
19887 insert_left_trunc_glyphs (it);
19888 row->truncated_on_left_p = 1;
19891 /* Remember the position at which this line ends.
19893 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
19894 cannot be before the call to find_row_edges below, since that is
19895 where these positions are determined. */
19896 row->end = it->current;
19897 if (!it->bidi_p)
19899 row->minpos = row->start.pos;
19900 row->maxpos = row->end.pos;
19902 else
19904 /* ROW->minpos and ROW->maxpos must be the smallest and
19905 `1 + the largest' buffer positions in ROW. But if ROW was
19906 bidi-reordered, these two positions can be anywhere in the
19907 row, so we must determine them now. */
19908 find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
19911 /* If the start of this line is the overlay arrow-position, then
19912 mark this glyph row as the one containing the overlay arrow.
19913 This is clearly a mess with variable size fonts. It would be
19914 better to let it be displayed like cursors under X. */
19915 if ((MATRIX_ROW_DISPLAYS_TEXT_P (row) || !overlay_arrow_seen)
19916 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
19917 !NILP (overlay_arrow_string)))
19919 /* Overlay arrow in window redisplay is a fringe bitmap. */
19920 if (STRINGP (overlay_arrow_string))
19922 struct glyph_row *arrow_row
19923 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
19924 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
19925 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
19926 struct glyph *p = row->glyphs[TEXT_AREA];
19927 struct glyph *p2, *end;
19929 /* Copy the arrow glyphs. */
19930 while (glyph < arrow_end)
19931 *p++ = *glyph++;
19933 /* Throw away padding glyphs. */
19934 p2 = p;
19935 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
19936 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
19937 ++p2;
19938 if (p2 > p)
19940 while (p2 < end)
19941 *p++ = *p2++;
19942 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
19945 else
19947 eassert (INTEGERP (overlay_arrow_string));
19948 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
19950 overlay_arrow_seen = 1;
19953 /* Highlight trailing whitespace. */
19954 if (!NILP (Vshow_trailing_whitespace))
19955 highlight_trailing_whitespace (it->f, it->glyph_row);
19957 /* Compute pixel dimensions of this line. */
19958 compute_line_metrics (it);
19960 /* Implementation note: No changes in the glyphs of ROW or in their
19961 faces can be done past this point, because compute_line_metrics
19962 computes ROW's hash value and stores it within the glyph_row
19963 structure. */
19965 /* Record whether this row ends inside an ellipsis. */
19966 row->ends_in_ellipsis_p
19967 = (it->method == GET_FROM_DISPLAY_VECTOR
19968 && it->ellipsis_p);
19970 /* Save fringe bitmaps in this row. */
19971 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
19972 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
19973 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
19974 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
19976 it->left_user_fringe_bitmap = 0;
19977 it->left_user_fringe_face_id = 0;
19978 it->right_user_fringe_bitmap = 0;
19979 it->right_user_fringe_face_id = 0;
19981 /* Maybe set the cursor. */
19982 cvpos = it->w->cursor.vpos;
19983 if ((cvpos < 0
19984 /* In bidi-reordered rows, keep checking for proper cursor
19985 position even if one has been found already, because buffer
19986 positions in such rows change non-linearly with ROW->VPOS,
19987 when a line is continued. One exception: when we are at ZV,
19988 display cursor on the first suitable glyph row, since all
19989 the empty rows after that also have their position set to ZV. */
19990 /* FIXME: Revisit this when glyph ``spilling'' in continuation
19991 lines' rows is implemented for bidi-reordered rows. */
19992 || (it->bidi_p
19993 && !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
19994 && PT >= MATRIX_ROW_START_CHARPOS (row)
19995 && PT <= MATRIX_ROW_END_CHARPOS (row)
19996 && cursor_row_p (row))
19997 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
19999 /* Prepare for the next line. This line starts horizontally at (X
20000 HPOS) = (0 0). Vertical positions are incremented. As a
20001 convenience for the caller, IT->glyph_row is set to the next
20002 row to be used. */
20003 it->current_x = it->hpos = 0;
20004 it->current_y += row->height;
20005 SET_TEXT_POS (it->eol_pos, 0, 0);
20006 ++it->vpos;
20007 ++it->glyph_row;
20008 /* The next row should by default use the same value of the
20009 reversed_p flag as this one. set_iterator_to_next decides when
20010 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
20011 the flag accordingly. */
20012 if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
20013 it->glyph_row->reversed_p = row->reversed_p;
20014 it->start = row->end;
20015 return MATRIX_ROW_DISPLAYS_TEXT_P (row);
20017 #undef RECORD_MAX_MIN_POS
20020 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,
20021 Scurrent_bidi_paragraph_direction, 0, 1, 0,
20022 doc: /* Return paragraph direction at point in BUFFER.
20023 Value is either `left-to-right' or `right-to-left'.
20024 If BUFFER is omitted or nil, it defaults to the current buffer.
20026 Paragraph direction determines how the text in the paragraph is displayed.
20027 In left-to-right paragraphs, text begins at the left margin of the window
20028 and the reading direction is generally left to right. In right-to-left
20029 paragraphs, text begins at the right margin and is read from right to left.
20031 See also `bidi-paragraph-direction'. */)
20032 (Lisp_Object buffer)
20034 struct buffer *buf = current_buffer;
20035 struct buffer *old = buf;
20037 if (! NILP (buffer))
20039 CHECK_BUFFER (buffer);
20040 buf = XBUFFER (buffer);
20043 if (NILP (BVAR (buf, bidi_display_reordering))
20044 || NILP (BVAR (buf, enable_multibyte_characters))
20045 /* When we are loading loadup.el, the character property tables
20046 needed for bidi iteration are not yet available. */
20047 || !NILP (Vpurify_flag))
20048 return Qleft_to_right;
20049 else if (!NILP (BVAR (buf, bidi_paragraph_direction)))
20050 return BVAR (buf, bidi_paragraph_direction);
20051 else
20053 /* Determine the direction from buffer text. We could try to
20054 use current_matrix if it is up to date, but this seems fast
20055 enough as it is. */
20056 struct bidi_it itb;
20057 ptrdiff_t pos = BUF_PT (buf);
20058 ptrdiff_t bytepos = BUF_PT_BYTE (buf);
20059 int c;
20060 void *itb_data = bidi_shelve_cache ();
20062 set_buffer_temp (buf);
20063 /* bidi_paragraph_init finds the base direction of the paragraph
20064 by searching forward from paragraph start. We need the base
20065 direction of the current or _previous_ paragraph, so we need
20066 to make sure we are within that paragraph. To that end, find
20067 the previous non-empty line. */
20068 if (pos >= ZV && pos > BEGV)
20069 DEC_BOTH (pos, bytepos);
20070 if (fast_looking_at (build_string ("[\f\t ]*\n"),
20071 pos, bytepos, ZV, ZV_BYTE, Qnil) > 0)
20073 while ((c = FETCH_BYTE (bytepos)) == '\n'
20074 || c == ' ' || c == '\t' || c == '\f')
20076 if (bytepos <= BEGV_BYTE)
20077 break;
20078 bytepos--;
20079 pos--;
20081 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos)))
20082 bytepos--;
20084 bidi_init_it (pos, bytepos, FRAME_WINDOW_P (SELECTED_FRAME ()), &itb);
20085 itb.paragraph_dir = NEUTRAL_DIR;
20086 itb.string.s = NULL;
20087 itb.string.lstring = Qnil;
20088 itb.string.bufpos = 0;
20089 itb.string.unibyte = 0;
20090 /* We have no window to use here for ignoring window-specific
20091 overlays. Using NULL for window pointer will cause
20092 compute_display_string_pos to use the current buffer. */
20093 itb.w = NULL;
20094 bidi_paragraph_init (NEUTRAL_DIR, &itb, 1);
20095 bidi_unshelve_cache (itb_data, 0);
20096 set_buffer_temp (old);
20097 switch (itb.paragraph_dir)
20099 case L2R:
20100 return Qleft_to_right;
20101 break;
20102 case R2L:
20103 return Qright_to_left;
20104 break;
20105 default:
20106 emacs_abort ();
20111 DEFUN ("move-point-visually", Fmove_point_visually,
20112 Smove_point_visually, 1, 1, 0,
20113 doc: /* Move point in the visual order in the specified DIRECTION.
20114 DIRECTION can be 1, meaning move to the right, or -1, which moves to the
20115 left.
20117 Value is the new character position of point. */)
20118 (Lisp_Object direction)
20120 struct window *w = XWINDOW (selected_window);
20121 struct buffer *b = XBUFFER (w->contents);
20122 struct glyph_row *row;
20123 int dir;
20124 Lisp_Object paragraph_dir;
20126 #define ROW_GLYPH_NEWLINE_P(ROW,GLYPH) \
20127 (!(ROW)->continued_p \
20128 && INTEGERP ((GLYPH)->object) \
20129 && (GLYPH)->type == CHAR_GLYPH \
20130 && (GLYPH)->u.ch == ' ' \
20131 && (GLYPH)->charpos >= 0 \
20132 && !(GLYPH)->avoid_cursor_p)
20134 CHECK_NUMBER (direction);
20135 dir = XINT (direction);
20136 if (dir > 0)
20137 dir = 1;
20138 else
20139 dir = -1;
20141 /* If current matrix is up-to-date, we can use the information
20142 recorded in the glyphs, at least as long as the goal is on the
20143 screen. */
20144 if (w->window_end_valid
20145 && !windows_or_buffers_changed
20146 && b
20147 && !b->clip_changed
20148 && !b->prevent_redisplay_optimizations_p
20149 && !window_outdated (w)
20150 && w->cursor.vpos >= 0
20151 && w->cursor.vpos < w->current_matrix->nrows
20152 && (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos))->enabled_p)
20154 struct glyph *g = row->glyphs[TEXT_AREA];
20155 struct glyph *e = dir > 0 ? g + row->used[TEXT_AREA] : g - 1;
20156 struct glyph *gpt = g + w->cursor.hpos;
20158 for (g = gpt + dir; (dir > 0 ? g < e : g > e); g += dir)
20160 if (BUFFERP (g->object) && g->charpos != PT)
20162 SET_PT (g->charpos);
20163 w->cursor.vpos = -1;
20164 return make_number (PT);
20166 else if (!INTEGERP (g->object) && !EQ (g->object, gpt->object))
20168 ptrdiff_t new_pos;
20170 if (BUFFERP (gpt->object))
20172 new_pos = PT;
20173 if ((gpt->resolved_level - row->reversed_p) % 2 == 0)
20174 new_pos += (row->reversed_p ? -dir : dir);
20175 else
20176 new_pos -= (row->reversed_p ? -dir : dir);;
20178 else if (BUFFERP (g->object))
20179 new_pos = g->charpos;
20180 else
20181 break;
20182 SET_PT (new_pos);
20183 w->cursor.vpos = -1;
20184 return make_number (PT);
20186 else if (ROW_GLYPH_NEWLINE_P (row, g))
20188 /* Glyphs inserted at the end of a non-empty line for
20189 positioning the cursor have zero charpos, so we must
20190 deduce the value of point by other means. */
20191 if (g->charpos > 0)
20192 SET_PT (g->charpos);
20193 else if (row->ends_at_zv_p && PT != ZV)
20194 SET_PT (ZV);
20195 else if (PT != MATRIX_ROW_END_CHARPOS (row) - 1)
20196 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
20197 else
20198 break;
20199 w->cursor.vpos = -1;
20200 return make_number (PT);
20203 if (g == e || INTEGERP (g->object))
20205 if (row->truncated_on_left_p || row->truncated_on_right_p)
20206 goto simulate_display;
20207 if (!row->reversed_p)
20208 row += dir;
20209 else
20210 row -= dir;
20211 if (row < MATRIX_FIRST_TEXT_ROW (w->current_matrix)
20212 || row > MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
20213 goto simulate_display;
20215 if (dir > 0)
20217 if (row->reversed_p && !row->continued_p)
20219 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
20220 w->cursor.vpos = -1;
20221 return make_number (PT);
20223 g = row->glyphs[TEXT_AREA];
20224 e = g + row->used[TEXT_AREA];
20225 for ( ; g < e; g++)
20227 if (BUFFERP (g->object)
20228 /* Empty lines have only one glyph, which stands
20229 for the newline, and whose charpos is the
20230 buffer position of the newline. */
20231 || ROW_GLYPH_NEWLINE_P (row, g)
20232 /* When the buffer ends in a newline, the line at
20233 EOB also has one glyph, but its charpos is -1. */
20234 || (row->ends_at_zv_p
20235 && !row->reversed_p
20236 && INTEGERP (g->object)
20237 && g->type == CHAR_GLYPH
20238 && g->u.ch == ' '))
20240 if (g->charpos > 0)
20241 SET_PT (g->charpos);
20242 else if (!row->reversed_p
20243 && row->ends_at_zv_p
20244 && PT != ZV)
20245 SET_PT (ZV);
20246 else
20247 continue;
20248 w->cursor.vpos = -1;
20249 return make_number (PT);
20253 else
20255 if (!row->reversed_p && !row->continued_p)
20257 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
20258 w->cursor.vpos = -1;
20259 return make_number (PT);
20261 e = row->glyphs[TEXT_AREA];
20262 g = e + row->used[TEXT_AREA] - 1;
20263 for ( ; g >= e; g--)
20265 if (BUFFERP (g->object)
20266 || (ROW_GLYPH_NEWLINE_P (row, g)
20267 && g->charpos > 0)
20268 /* Empty R2L lines on GUI frames have the buffer
20269 position of the newline stored in the stretch
20270 glyph. */
20271 || g->type == STRETCH_GLYPH
20272 || (row->ends_at_zv_p
20273 && row->reversed_p
20274 && INTEGERP (g->object)
20275 && g->type == CHAR_GLYPH
20276 && g->u.ch == ' '))
20278 if (g->charpos > 0)
20279 SET_PT (g->charpos);
20280 else if (row->reversed_p
20281 && row->ends_at_zv_p
20282 && PT != ZV)
20283 SET_PT (ZV);
20284 else
20285 continue;
20286 w->cursor.vpos = -1;
20287 return make_number (PT);
20294 simulate_display:
20296 /* If we wind up here, we failed to move by using the glyphs, so we
20297 need to simulate display instead. */
20299 if (b)
20300 paragraph_dir = Fcurrent_bidi_paragraph_direction (w->contents);
20301 else
20302 paragraph_dir = Qleft_to_right;
20303 if (EQ (paragraph_dir, Qright_to_left))
20304 dir = -dir;
20305 if (PT <= BEGV && dir < 0)
20306 xsignal0 (Qbeginning_of_buffer);
20307 else if (PT >= ZV && dir > 0)
20308 xsignal0 (Qend_of_buffer);
20309 else
20311 struct text_pos pt;
20312 struct it it;
20313 int pt_x, target_x, pixel_width, pt_vpos;
20314 bool at_eol_p;
20315 bool overshoot_expected = false;
20316 bool target_is_eol_p = false;
20318 /* Setup the arena. */
20319 SET_TEXT_POS (pt, PT, PT_BYTE);
20320 start_display (&it, w, pt);
20322 if (it.cmp_it.id < 0
20323 && it.method == GET_FROM_STRING
20324 && it.area == TEXT_AREA
20325 && it.string_from_display_prop_p
20326 && (it.sp > 0 && it.stack[it.sp - 1].method == GET_FROM_BUFFER))
20327 overshoot_expected = true;
20329 /* Find the X coordinate of point. We start from the beginning
20330 of this or previous line to make sure we are before point in
20331 the logical order (since the move_it_* functions can only
20332 move forward). */
20333 reseat_at_previous_visible_line_start (&it);
20334 it.current_x = it.hpos = it.current_y = it.vpos = 0;
20335 if (IT_CHARPOS (it) != PT)
20336 move_it_to (&it, overshoot_expected ? PT - 1 : PT,
20337 -1, -1, -1, MOVE_TO_POS);
20338 pt_x = it.current_x;
20339 pt_vpos = it.vpos;
20340 if (dir > 0 || overshoot_expected)
20342 struct glyph_row *row = it.glyph_row;
20344 /* When point is at beginning of line, we don't have
20345 information about the glyph there loaded into struct
20346 it. Calling get_next_display_element fixes that. */
20347 if (pt_x == 0)
20348 get_next_display_element (&it);
20349 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
20350 it.glyph_row = NULL;
20351 PRODUCE_GLYPHS (&it); /* compute it.pixel_width */
20352 it.glyph_row = row;
20353 /* PRODUCE_GLYPHS advances it.current_x, so we must restore
20354 it, lest it will become out of sync with it's buffer
20355 position. */
20356 it.current_x = pt_x;
20358 else
20359 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
20360 pixel_width = it.pixel_width;
20361 if (overshoot_expected && at_eol_p)
20362 pixel_width = 0;
20363 else if (pixel_width <= 0)
20364 pixel_width = 1;
20366 /* If there's a display string at point, we are actually at the
20367 glyph to the left of point, so we need to correct the X
20368 coordinate. */
20369 if (overshoot_expected)
20370 pt_x += pixel_width;
20372 /* Compute target X coordinate, either to the left or to the
20373 right of point. On TTY frames, all characters have the same
20374 pixel width of 1, so we can use that. On GUI frames we don't
20375 have an easy way of getting at the pixel width of the
20376 character to the left of point, so we use a different method
20377 of getting to that place. */
20378 if (dir > 0)
20379 target_x = pt_x + pixel_width;
20380 else
20381 target_x = pt_x - (!FRAME_WINDOW_P (it.f)) * pixel_width;
20383 /* Target X coordinate could be one line above or below the line
20384 of point, in which case we need to adjust the target X
20385 coordinate. Also, if moving to the left, we need to begin at
20386 the left edge of the point's screen line. */
20387 if (dir < 0)
20389 if (pt_x > 0)
20391 start_display (&it, w, pt);
20392 reseat_at_previous_visible_line_start (&it);
20393 it.current_x = it.current_y = it.hpos = 0;
20394 if (pt_vpos != 0)
20395 move_it_by_lines (&it, pt_vpos);
20397 else
20399 move_it_by_lines (&it, -1);
20400 target_x = it.last_visible_x - !FRAME_WINDOW_P (it.f);
20401 target_is_eol_p = true;
20404 else
20406 if (at_eol_p
20407 || (target_x >= it.last_visible_x
20408 && it.line_wrap != TRUNCATE))
20410 if (pt_x > 0)
20411 move_it_by_lines (&it, 0);
20412 move_it_by_lines (&it, 1);
20413 target_x = 0;
20417 /* Move to the target X coordinate. */
20418 #ifdef HAVE_WINDOW_SYSTEM
20419 /* On GUI frames, as we don't know the X coordinate of the
20420 character to the left of point, moving point to the left
20421 requires walking, one grapheme cluster at a time, until we
20422 find ourself at a place immediately to the left of the
20423 character at point. */
20424 if (FRAME_WINDOW_P (it.f) && dir < 0)
20426 struct text_pos new_pos = it.current.pos;
20427 enum move_it_result rc = MOVE_X_REACHED;
20429 while (it.current_x + it.pixel_width <= target_x
20430 && rc == MOVE_X_REACHED)
20432 int new_x = it.current_x + it.pixel_width;
20434 new_pos = it.current.pos;
20435 if (new_x == it.current_x)
20436 new_x++;
20437 rc = move_it_in_display_line_to (&it, ZV, new_x,
20438 MOVE_TO_POS | MOVE_TO_X);
20439 if (ITERATOR_AT_END_OF_LINE_P (&it) && !target_is_eol_p)
20440 break;
20442 /* If we ended up on a composed character inside
20443 bidi-reordered text (e.g., Hebrew text with diacritics),
20444 the iterator gives us the buffer position of the last (in
20445 logical order) character of the composed grapheme cluster,
20446 which is not what we want. So we cheat: we compute the
20447 character position of the character that follows (in the
20448 logical order) the one where the above loop stopped. That
20449 character will appear on display to the left of point. */
20450 if (it.bidi_p
20451 && it.bidi_it.scan_dir == -1
20452 && new_pos.charpos - IT_CHARPOS (it) > 1)
20454 new_pos.charpos = IT_CHARPOS (it) + 1;
20455 new_pos.bytepos = CHAR_TO_BYTE (new_pos.charpos);
20457 it.current.pos = new_pos;
20459 else
20460 #endif
20461 if (it.current_x != target_x)
20462 move_it_in_display_line_to (&it, ZV, target_x, MOVE_TO_POS | MOVE_TO_X);
20464 /* When lines are truncated, the above loop will stop at the
20465 window edge. But we want to get to the end of line, even if
20466 it is beyond the window edge; automatic hscroll will then
20467 scroll the window to show point as appropriate. */
20468 if (target_is_eol_p && it.line_wrap == TRUNCATE
20469 && get_next_display_element (&it))
20471 struct text_pos new_pos = it.current.pos;
20473 while (!ITERATOR_AT_END_OF_LINE_P (&it))
20475 set_iterator_to_next (&it, 0);
20476 if (it.method == GET_FROM_BUFFER)
20477 new_pos = it.current.pos;
20478 if (!get_next_display_element (&it))
20479 break;
20482 it.current.pos = new_pos;
20485 /* If we ended up in a display string that covers point, move to
20486 buffer position to the right in the visual order. */
20487 if (dir > 0)
20489 while (IT_CHARPOS (it) == PT)
20491 set_iterator_to_next (&it, 0);
20492 if (!get_next_display_element (&it))
20493 break;
20497 /* Move point to that position. */
20498 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
20501 return make_number (PT);
20503 #undef ROW_GLYPH_NEWLINE_P
20507 /***********************************************************************
20508 Menu Bar
20509 ***********************************************************************/
20511 /* Redisplay the menu bar in the frame for window W.
20513 The menu bar of X frames that don't have X toolkit support is
20514 displayed in a special window W->frame->menu_bar_window.
20516 The menu bar of terminal frames is treated specially as far as
20517 glyph matrices are concerned. Menu bar lines are not part of
20518 windows, so the update is done directly on the frame matrix rows
20519 for the menu bar. */
20521 static void
20522 display_menu_bar (struct window *w)
20524 struct frame *f = XFRAME (WINDOW_FRAME (w));
20525 struct it it;
20526 Lisp_Object items;
20527 int i;
20529 /* Don't do all this for graphical frames. */
20530 #ifdef HAVE_NTGUI
20531 if (FRAME_W32_P (f))
20532 return;
20533 #endif
20534 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
20535 if (FRAME_X_P (f))
20536 return;
20537 #endif
20539 #ifdef HAVE_NS
20540 if (FRAME_NS_P (f))
20541 return;
20542 #endif /* HAVE_NS */
20544 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
20545 eassert (!FRAME_WINDOW_P (f));
20546 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
20547 it.first_visible_x = 0;
20548 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
20549 #elif defined (HAVE_X_WINDOWS) /* X without toolkit. */
20550 if (FRAME_WINDOW_P (f))
20552 /* Menu bar lines are displayed in the desired matrix of the
20553 dummy window menu_bar_window. */
20554 struct window *menu_w;
20555 menu_w = XWINDOW (f->menu_bar_window);
20556 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
20557 MENU_FACE_ID);
20558 it.first_visible_x = 0;
20559 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
20561 else
20562 #endif /* not USE_X_TOOLKIT and not USE_GTK */
20564 /* This is a TTY frame, i.e. character hpos/vpos are used as
20565 pixel x/y. */
20566 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
20567 MENU_FACE_ID);
20568 it.first_visible_x = 0;
20569 it.last_visible_x = FRAME_COLS (f);
20572 /* FIXME: This should be controlled by a user option. See the
20573 comments in redisplay_tool_bar and display_mode_line about
20574 this. */
20575 it.paragraph_embedding = L2R;
20577 /* Clear all rows of the menu bar. */
20578 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
20580 struct glyph_row *row = it.glyph_row + i;
20581 clear_glyph_row (row);
20582 row->enabled_p = 1;
20583 row->full_width_p = 1;
20586 /* Display all items of the menu bar. */
20587 items = FRAME_MENU_BAR_ITEMS (it.f);
20588 for (i = 0; i < ASIZE (items); i += 4)
20590 Lisp_Object string;
20592 /* Stop at nil string. */
20593 string = AREF (items, i + 1);
20594 if (NILP (string))
20595 break;
20597 /* Remember where item was displayed. */
20598 ASET (items, i + 3, make_number (it.hpos));
20600 /* Display the item, pad with one space. */
20601 if (it.current_x < it.last_visible_x)
20602 display_string (NULL, string, Qnil, 0, 0, &it,
20603 SCHARS (string) + 1, 0, 0, -1);
20606 /* Fill out the line with spaces. */
20607 if (it.current_x < it.last_visible_x)
20608 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
20610 /* Compute the total height of the lines. */
20611 compute_line_metrics (&it);
20616 /***********************************************************************
20617 Mode Line
20618 ***********************************************************************/
20620 /* Redisplay mode lines in the window tree whose root is WINDOW. If
20621 FORCE is non-zero, redisplay mode lines unconditionally.
20622 Otherwise, redisplay only mode lines that are garbaged. Value is
20623 the number of windows whose mode lines were redisplayed. */
20625 static int
20626 redisplay_mode_lines (Lisp_Object window, int force)
20628 int nwindows = 0;
20630 while (!NILP (window))
20632 struct window *w = XWINDOW (window);
20634 if (WINDOWP (w->contents))
20635 nwindows += redisplay_mode_lines (w->contents, force);
20636 else if (force
20637 || FRAME_GARBAGED_P (XFRAME (w->frame))
20638 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
20640 struct text_pos lpoint;
20641 struct buffer *old = current_buffer;
20643 /* Set the window's buffer for the mode line display. */
20644 SET_TEXT_POS (lpoint, PT, PT_BYTE);
20645 set_buffer_internal_1 (XBUFFER (w->contents));
20647 /* Point refers normally to the selected window. For any
20648 other window, set up appropriate value. */
20649 if (!EQ (window, selected_window))
20651 struct text_pos pt;
20653 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
20654 if (CHARPOS (pt) < BEGV)
20655 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
20656 else if (CHARPOS (pt) > (ZV - 1))
20657 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
20658 else
20659 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
20662 /* Display mode lines. */
20663 clear_glyph_matrix (w->desired_matrix);
20664 if (display_mode_lines (w))
20666 ++nwindows;
20667 w->must_be_updated_p = 1;
20670 /* Restore old settings. */
20671 set_buffer_internal_1 (old);
20672 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
20675 window = w->next;
20678 return nwindows;
20682 /* Display the mode and/or header line of window W. Value is the
20683 sum number of mode lines and header lines displayed. */
20685 static int
20686 display_mode_lines (struct window *w)
20688 Lisp_Object old_selected_window = selected_window;
20689 Lisp_Object old_selected_frame = selected_frame;
20690 Lisp_Object new_frame = w->frame;
20691 Lisp_Object old_frame_selected_window = XFRAME (new_frame)->selected_window;
20692 int n = 0;
20694 selected_frame = new_frame;
20695 /* FIXME: If we were to allow the mode-line's computation changing the buffer
20696 or window's point, then we'd need select_window_1 here as well. */
20697 XSETWINDOW (selected_window, w);
20698 XFRAME (new_frame)->selected_window = selected_window;
20700 /* These will be set while the mode line specs are processed. */
20701 line_number_displayed = 0;
20702 w->column_number_displayed = -1;
20704 if (WINDOW_WANTS_MODELINE_P (w))
20706 struct window *sel_w = XWINDOW (old_selected_window);
20708 /* Select mode line face based on the real selected window. */
20709 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
20710 BVAR (current_buffer, mode_line_format));
20711 ++n;
20714 if (WINDOW_WANTS_HEADER_LINE_P (w))
20716 display_mode_line (w, HEADER_LINE_FACE_ID,
20717 BVAR (current_buffer, header_line_format));
20718 ++n;
20721 XFRAME (new_frame)->selected_window = old_frame_selected_window;
20722 selected_frame = old_selected_frame;
20723 selected_window = old_selected_window;
20724 return n;
20728 /* Display mode or header line of window W. FACE_ID specifies which
20729 line to display; it is either MODE_LINE_FACE_ID or
20730 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
20731 display. Value is the pixel height of the mode/header line
20732 displayed. */
20734 static int
20735 display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
20737 struct it it;
20738 struct face *face;
20739 ptrdiff_t count = SPECPDL_INDEX ();
20741 init_iterator (&it, w, -1, -1, NULL, face_id);
20742 /* Don't extend on a previously drawn mode-line.
20743 This may happen if called from pos_visible_p. */
20744 it.glyph_row->enabled_p = 0;
20745 prepare_desired_row (it.glyph_row);
20747 it.glyph_row->mode_line_p = 1;
20749 /* FIXME: This should be controlled by a user option. But
20750 supporting such an option is not trivial, since the mode line is
20751 made up of many separate strings. */
20752 it.paragraph_embedding = L2R;
20754 record_unwind_protect (unwind_format_mode_line,
20755 format_mode_line_unwind_data (NULL, NULL, Qnil, 0));
20757 mode_line_target = MODE_LINE_DISPLAY;
20759 /* Temporarily make frame's keyboard the current kboard so that
20760 kboard-local variables in the mode_line_format will get the right
20761 values. */
20762 push_kboard (FRAME_KBOARD (it.f));
20763 record_unwind_save_match_data ();
20764 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
20765 pop_kboard ();
20767 unbind_to (count, Qnil);
20769 /* Fill up with spaces. */
20770 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
20772 compute_line_metrics (&it);
20773 it.glyph_row->full_width_p = 1;
20774 it.glyph_row->continued_p = 0;
20775 it.glyph_row->truncated_on_left_p = 0;
20776 it.glyph_row->truncated_on_right_p = 0;
20778 /* Make a 3D mode-line have a shadow at its right end. */
20779 face = FACE_FROM_ID (it.f, face_id);
20780 extend_face_to_end_of_line (&it);
20781 if (face->box != FACE_NO_BOX)
20783 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
20784 + it.glyph_row->used[TEXT_AREA] - 1);
20785 last->right_box_line_p = 1;
20788 return it.glyph_row->height;
20791 /* Move element ELT in LIST to the front of LIST.
20792 Return the updated list. */
20794 static Lisp_Object
20795 move_elt_to_front (Lisp_Object elt, Lisp_Object list)
20797 register Lisp_Object tail, prev;
20798 register Lisp_Object tem;
20800 tail = list;
20801 prev = Qnil;
20802 while (CONSP (tail))
20804 tem = XCAR (tail);
20806 if (EQ (elt, tem))
20808 /* Splice out the link TAIL. */
20809 if (NILP (prev))
20810 list = XCDR (tail);
20811 else
20812 Fsetcdr (prev, XCDR (tail));
20814 /* Now make it the first. */
20815 Fsetcdr (tail, list);
20816 return tail;
20818 else
20819 prev = tail;
20820 tail = XCDR (tail);
20821 QUIT;
20824 /* Not found--return unchanged LIST. */
20825 return list;
20828 /* Contribute ELT to the mode line for window IT->w. How it
20829 translates into text depends on its data type.
20831 IT describes the display environment in which we display, as usual.
20833 DEPTH is the depth in recursion. It is used to prevent
20834 infinite recursion here.
20836 FIELD_WIDTH is the number of characters the display of ELT should
20837 occupy in the mode line, and PRECISION is the maximum number of
20838 characters to display from ELT's representation. See
20839 display_string for details.
20841 Returns the hpos of the end of the text generated by ELT.
20843 PROPS is a property list to add to any string we encounter.
20845 If RISKY is nonzero, remove (disregard) any properties in any string
20846 we encounter, and ignore :eval and :propertize.
20848 The global variable `mode_line_target' determines whether the
20849 output is passed to `store_mode_line_noprop',
20850 `store_mode_line_string', or `display_string'. */
20852 static int
20853 display_mode_element (struct it *it, int depth, int field_width, int precision,
20854 Lisp_Object elt, Lisp_Object props, int risky)
20856 int n = 0, field, prec;
20857 int literal = 0;
20859 tail_recurse:
20860 if (depth > 100)
20861 elt = build_string ("*too-deep*");
20863 depth++;
20865 switch (XTYPE (elt))
20867 case Lisp_String:
20869 /* A string: output it and check for %-constructs within it. */
20870 unsigned char c;
20871 ptrdiff_t offset = 0;
20873 if (SCHARS (elt) > 0
20874 && (!NILP (props) || risky))
20876 Lisp_Object oprops, aelt;
20877 oprops = Ftext_properties_at (make_number (0), elt);
20879 /* If the starting string's properties are not what
20880 we want, translate the string. Also, if the string
20881 is risky, do that anyway. */
20883 if (NILP (Fequal (props, oprops)) || risky)
20885 /* If the starting string has properties,
20886 merge the specified ones onto the existing ones. */
20887 if (! NILP (oprops) && !risky)
20889 Lisp_Object tem;
20891 oprops = Fcopy_sequence (oprops);
20892 tem = props;
20893 while (CONSP (tem))
20895 oprops = Fplist_put (oprops, XCAR (tem),
20896 XCAR (XCDR (tem)));
20897 tem = XCDR (XCDR (tem));
20899 props = oprops;
20902 aelt = Fassoc (elt, mode_line_proptrans_alist);
20903 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
20905 /* AELT is what we want. Move it to the front
20906 without consing. */
20907 elt = XCAR (aelt);
20908 mode_line_proptrans_alist
20909 = move_elt_to_front (aelt, mode_line_proptrans_alist);
20911 else
20913 Lisp_Object tem;
20915 /* If AELT has the wrong props, it is useless.
20916 so get rid of it. */
20917 if (! NILP (aelt))
20918 mode_line_proptrans_alist
20919 = Fdelq (aelt, mode_line_proptrans_alist);
20921 elt = Fcopy_sequence (elt);
20922 Fset_text_properties (make_number (0), Flength (elt),
20923 props, elt);
20924 /* Add this item to mode_line_proptrans_alist. */
20925 mode_line_proptrans_alist
20926 = Fcons (Fcons (elt, props),
20927 mode_line_proptrans_alist);
20928 /* Truncate mode_line_proptrans_alist
20929 to at most 50 elements. */
20930 tem = Fnthcdr (make_number (50),
20931 mode_line_proptrans_alist);
20932 if (! NILP (tem))
20933 XSETCDR (tem, Qnil);
20938 offset = 0;
20940 if (literal)
20942 prec = precision - n;
20943 switch (mode_line_target)
20945 case MODE_LINE_NOPROP:
20946 case MODE_LINE_TITLE:
20947 n += store_mode_line_noprop (SSDATA (elt), -1, prec);
20948 break;
20949 case MODE_LINE_STRING:
20950 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
20951 break;
20952 case MODE_LINE_DISPLAY:
20953 n += display_string (NULL, elt, Qnil, 0, 0, it,
20954 0, prec, 0, STRING_MULTIBYTE (elt));
20955 break;
20958 break;
20961 /* Handle the non-literal case. */
20963 while ((precision <= 0 || n < precision)
20964 && SREF (elt, offset) != 0
20965 && (mode_line_target != MODE_LINE_DISPLAY
20966 || it->current_x < it->last_visible_x))
20968 ptrdiff_t last_offset = offset;
20970 /* Advance to end of string or next format specifier. */
20971 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
20974 if (offset - 1 != last_offset)
20976 ptrdiff_t nchars, nbytes;
20978 /* Output to end of string or up to '%'. Field width
20979 is length of string. Don't output more than
20980 PRECISION allows us. */
20981 offset--;
20983 prec = c_string_width (SDATA (elt) + last_offset,
20984 offset - last_offset, precision - n,
20985 &nchars, &nbytes);
20987 switch (mode_line_target)
20989 case MODE_LINE_NOPROP:
20990 case MODE_LINE_TITLE:
20991 n += store_mode_line_noprop (SSDATA (elt) + last_offset, 0, prec);
20992 break;
20993 case MODE_LINE_STRING:
20995 ptrdiff_t bytepos = last_offset;
20996 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
20997 ptrdiff_t endpos = (precision <= 0
20998 ? string_byte_to_char (elt, offset)
20999 : charpos + nchars);
21001 n += store_mode_line_string (NULL,
21002 Fsubstring (elt, make_number (charpos),
21003 make_number (endpos)),
21004 0, 0, 0, Qnil);
21006 break;
21007 case MODE_LINE_DISPLAY:
21009 ptrdiff_t bytepos = last_offset;
21010 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
21012 if (precision <= 0)
21013 nchars = string_byte_to_char (elt, offset) - charpos;
21014 n += display_string (NULL, elt, Qnil, 0, charpos,
21015 it, 0, nchars, 0,
21016 STRING_MULTIBYTE (elt));
21018 break;
21021 else /* c == '%' */
21023 ptrdiff_t percent_position = offset;
21025 /* Get the specified minimum width. Zero means
21026 don't pad. */
21027 field = 0;
21028 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
21029 field = field * 10 + c - '0';
21031 /* Don't pad beyond the total padding allowed. */
21032 if (field_width - n > 0 && field > field_width - n)
21033 field = field_width - n;
21035 /* Note that either PRECISION <= 0 or N < PRECISION. */
21036 prec = precision - n;
21038 if (c == 'M')
21039 n += display_mode_element (it, depth, field, prec,
21040 Vglobal_mode_string, props,
21041 risky);
21042 else if (c != 0)
21044 bool multibyte;
21045 ptrdiff_t bytepos, charpos;
21046 const char *spec;
21047 Lisp_Object string;
21049 bytepos = percent_position;
21050 charpos = (STRING_MULTIBYTE (elt)
21051 ? string_byte_to_char (elt, bytepos)
21052 : bytepos);
21053 spec = decode_mode_spec (it->w, c, field, &string);
21054 multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
21056 switch (mode_line_target)
21058 case MODE_LINE_NOPROP:
21059 case MODE_LINE_TITLE:
21060 n += store_mode_line_noprop (spec, field, prec);
21061 break;
21062 case MODE_LINE_STRING:
21064 Lisp_Object tem = build_string (spec);
21065 props = Ftext_properties_at (make_number (charpos), elt);
21066 /* Should only keep face property in props */
21067 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
21069 break;
21070 case MODE_LINE_DISPLAY:
21072 int nglyphs_before, nwritten;
21074 nglyphs_before = it->glyph_row->used[TEXT_AREA];
21075 nwritten = display_string (spec, string, elt,
21076 charpos, 0, it,
21077 field, prec, 0,
21078 multibyte);
21080 /* Assign to the glyphs written above the
21081 string where the `%x' came from, position
21082 of the `%'. */
21083 if (nwritten > 0)
21085 struct glyph *glyph
21086 = (it->glyph_row->glyphs[TEXT_AREA]
21087 + nglyphs_before);
21088 int i;
21090 for (i = 0; i < nwritten; ++i)
21092 glyph[i].object = elt;
21093 glyph[i].charpos = charpos;
21096 n += nwritten;
21099 break;
21102 else /* c == 0 */
21103 break;
21107 break;
21109 case Lisp_Symbol:
21110 /* A symbol: process the value of the symbol recursively
21111 as if it appeared here directly. Avoid error if symbol void.
21112 Special case: if value of symbol is a string, output the string
21113 literally. */
21115 register Lisp_Object tem;
21117 /* If the variable is not marked as risky to set
21118 then its contents are risky to use. */
21119 if (NILP (Fget (elt, Qrisky_local_variable)))
21120 risky = 1;
21122 tem = Fboundp (elt);
21123 if (!NILP (tem))
21125 tem = Fsymbol_value (elt);
21126 /* If value is a string, output that string literally:
21127 don't check for % within it. */
21128 if (STRINGP (tem))
21129 literal = 1;
21131 if (!EQ (tem, elt))
21133 /* Give up right away for nil or t. */
21134 elt = tem;
21135 goto tail_recurse;
21139 break;
21141 case Lisp_Cons:
21143 register Lisp_Object car, tem;
21145 /* A cons cell: five distinct cases.
21146 If first element is :eval or :propertize, do something special.
21147 If first element is a string or a cons, process all the elements
21148 and effectively concatenate them.
21149 If first element is a negative number, truncate displaying cdr to
21150 at most that many characters. If positive, pad (with spaces)
21151 to at least that many characters.
21152 If first element is a symbol, process the cadr or caddr recursively
21153 according to whether the symbol's value is non-nil or nil. */
21154 car = XCAR (elt);
21155 if (EQ (car, QCeval))
21157 /* An element of the form (:eval FORM) means evaluate FORM
21158 and use the result as mode line elements. */
21160 if (risky)
21161 break;
21163 if (CONSP (XCDR (elt)))
21165 Lisp_Object spec;
21166 spec = safe_eval (XCAR (XCDR (elt)));
21167 n += display_mode_element (it, depth, field_width - n,
21168 precision - n, spec, props,
21169 risky);
21172 else if (EQ (car, QCpropertize))
21174 /* An element of the form (:propertize ELT PROPS...)
21175 means display ELT but applying properties PROPS. */
21177 if (risky)
21178 break;
21180 if (CONSP (XCDR (elt)))
21181 n += display_mode_element (it, depth, field_width - n,
21182 precision - n, XCAR (XCDR (elt)),
21183 XCDR (XCDR (elt)), risky);
21185 else if (SYMBOLP (car))
21187 tem = Fboundp (car);
21188 elt = XCDR (elt);
21189 if (!CONSP (elt))
21190 goto invalid;
21191 /* elt is now the cdr, and we know it is a cons cell.
21192 Use its car if CAR has a non-nil value. */
21193 if (!NILP (tem))
21195 tem = Fsymbol_value (car);
21196 if (!NILP (tem))
21198 elt = XCAR (elt);
21199 goto tail_recurse;
21202 /* Symbol's value is nil (or symbol is unbound)
21203 Get the cddr of the original list
21204 and if possible find the caddr and use that. */
21205 elt = XCDR (elt);
21206 if (NILP (elt))
21207 break;
21208 else if (!CONSP (elt))
21209 goto invalid;
21210 elt = XCAR (elt);
21211 goto tail_recurse;
21213 else if (INTEGERP (car))
21215 register int lim = XINT (car);
21216 elt = XCDR (elt);
21217 if (lim < 0)
21219 /* Negative int means reduce maximum width. */
21220 if (precision <= 0)
21221 precision = -lim;
21222 else
21223 precision = min (precision, -lim);
21225 else if (lim > 0)
21227 /* Padding specified. Don't let it be more than
21228 current maximum. */
21229 if (precision > 0)
21230 lim = min (precision, lim);
21232 /* If that's more padding than already wanted, queue it.
21233 But don't reduce padding already specified even if
21234 that is beyond the current truncation point. */
21235 field_width = max (lim, field_width);
21237 goto tail_recurse;
21239 else if (STRINGP (car) || CONSP (car))
21241 Lisp_Object halftail = elt;
21242 int len = 0;
21244 while (CONSP (elt)
21245 && (precision <= 0 || n < precision))
21247 n += display_mode_element (it, depth,
21248 /* Do padding only after the last
21249 element in the list. */
21250 (! CONSP (XCDR (elt))
21251 ? field_width - n
21252 : 0),
21253 precision - n, XCAR (elt),
21254 props, risky);
21255 elt = XCDR (elt);
21256 len++;
21257 if ((len & 1) == 0)
21258 halftail = XCDR (halftail);
21259 /* Check for cycle. */
21260 if (EQ (halftail, elt))
21261 break;
21265 break;
21267 default:
21268 invalid:
21269 elt = build_string ("*invalid*");
21270 goto tail_recurse;
21273 /* Pad to FIELD_WIDTH. */
21274 if (field_width > 0 && n < field_width)
21276 switch (mode_line_target)
21278 case MODE_LINE_NOPROP:
21279 case MODE_LINE_TITLE:
21280 n += store_mode_line_noprop ("", field_width - n, 0);
21281 break;
21282 case MODE_LINE_STRING:
21283 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
21284 break;
21285 case MODE_LINE_DISPLAY:
21286 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
21287 0, 0, 0);
21288 break;
21292 return n;
21295 /* Store a mode-line string element in mode_line_string_list.
21297 If STRING is non-null, display that C string. Otherwise, the Lisp
21298 string LISP_STRING is displayed.
21300 FIELD_WIDTH is the minimum number of output glyphs to produce.
21301 If STRING has fewer characters than FIELD_WIDTH, pad to the right
21302 with spaces. FIELD_WIDTH <= 0 means don't pad.
21304 PRECISION is the maximum number of characters to output from
21305 STRING. PRECISION <= 0 means don't truncate the string.
21307 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
21308 properties to the string.
21310 PROPS are the properties to add to the string.
21311 The mode_line_string_face face property is always added to the string.
21314 static int
21315 store_mode_line_string (const char *string, Lisp_Object lisp_string, int copy_string,
21316 int field_width, int precision, Lisp_Object props)
21318 ptrdiff_t len;
21319 int n = 0;
21321 if (string != NULL)
21323 len = strlen (string);
21324 if (precision > 0 && len > precision)
21325 len = precision;
21326 lisp_string = make_string (string, len);
21327 if (NILP (props))
21328 props = mode_line_string_face_prop;
21329 else if (!NILP (mode_line_string_face))
21331 Lisp_Object face = Fplist_get (props, Qface);
21332 props = Fcopy_sequence (props);
21333 if (NILP (face))
21334 face = mode_line_string_face;
21335 else
21336 face = list2 (face, mode_line_string_face);
21337 props = Fplist_put (props, Qface, face);
21339 Fadd_text_properties (make_number (0), make_number (len),
21340 props, lisp_string);
21342 else
21344 len = XFASTINT (Flength (lisp_string));
21345 if (precision > 0 && len > precision)
21347 len = precision;
21348 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
21349 precision = -1;
21351 if (!NILP (mode_line_string_face))
21353 Lisp_Object face;
21354 if (NILP (props))
21355 props = Ftext_properties_at (make_number (0), lisp_string);
21356 face = Fplist_get (props, Qface);
21357 if (NILP (face))
21358 face = mode_line_string_face;
21359 else
21360 face = list2 (face, mode_line_string_face);
21361 props = list2 (Qface, face);
21362 if (copy_string)
21363 lisp_string = Fcopy_sequence (lisp_string);
21365 if (!NILP (props))
21366 Fadd_text_properties (make_number (0), make_number (len),
21367 props, lisp_string);
21370 if (len > 0)
21372 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
21373 n += len;
21376 if (field_width > len)
21378 field_width -= len;
21379 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
21380 if (!NILP (props))
21381 Fadd_text_properties (make_number (0), make_number (field_width),
21382 props, lisp_string);
21383 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
21384 n += field_width;
21387 return n;
21391 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
21392 1, 4, 0,
21393 doc: /* Format a string out of a mode line format specification.
21394 First arg FORMAT specifies the mode line format (see `mode-line-format'
21395 for details) to use.
21397 By default, the format is evaluated for the currently selected window.
21399 Optional second arg FACE specifies the face property to put on all
21400 characters for which no face is specified. The value nil means the
21401 default face. The value t means whatever face the window's mode line
21402 currently uses (either `mode-line' or `mode-line-inactive',
21403 depending on whether the window is the selected window or not).
21404 An integer value means the value string has no text
21405 properties.
21407 Optional third and fourth args WINDOW and BUFFER specify the window
21408 and buffer to use as the context for the formatting (defaults
21409 are the selected window and the WINDOW's buffer). */)
21410 (Lisp_Object format, Lisp_Object face,
21411 Lisp_Object window, Lisp_Object buffer)
21413 struct it it;
21414 int len;
21415 struct window *w;
21416 struct buffer *old_buffer = NULL;
21417 int face_id;
21418 int no_props = INTEGERP (face);
21419 ptrdiff_t count = SPECPDL_INDEX ();
21420 Lisp_Object str;
21421 int string_start = 0;
21423 w = decode_any_window (window);
21424 XSETWINDOW (window, w);
21426 if (NILP (buffer))
21427 buffer = w->contents;
21428 CHECK_BUFFER (buffer);
21430 /* Make formatting the modeline a non-op when noninteractive, otherwise
21431 there will be problems later caused by a partially initialized frame. */
21432 if (NILP (format) || noninteractive)
21433 return empty_unibyte_string;
21435 if (no_props)
21436 face = Qnil;
21438 face_id = (NILP (face) || EQ (face, Qdefault)) ? DEFAULT_FACE_ID
21439 : EQ (face, Qt) ? (EQ (window, selected_window)
21440 ? MODE_LINE_FACE_ID : MODE_LINE_INACTIVE_FACE_ID)
21441 : EQ (face, Qmode_line) ? MODE_LINE_FACE_ID
21442 : EQ (face, Qmode_line_inactive) ? MODE_LINE_INACTIVE_FACE_ID
21443 : EQ (face, Qheader_line) ? HEADER_LINE_FACE_ID
21444 : EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID
21445 : DEFAULT_FACE_ID;
21447 old_buffer = current_buffer;
21449 /* Save things including mode_line_proptrans_alist,
21450 and set that to nil so that we don't alter the outer value. */
21451 record_unwind_protect (unwind_format_mode_line,
21452 format_mode_line_unwind_data
21453 (XFRAME (WINDOW_FRAME (w)),
21454 old_buffer, selected_window, 1));
21455 mode_line_proptrans_alist = Qnil;
21457 Fselect_window (window, Qt);
21458 set_buffer_internal_1 (XBUFFER (buffer));
21460 init_iterator (&it, w, -1, -1, NULL, face_id);
21462 if (no_props)
21464 mode_line_target = MODE_LINE_NOPROP;
21465 mode_line_string_face_prop = Qnil;
21466 mode_line_string_list = Qnil;
21467 string_start = MODE_LINE_NOPROP_LEN (0);
21469 else
21471 mode_line_target = MODE_LINE_STRING;
21472 mode_line_string_list = Qnil;
21473 mode_line_string_face = face;
21474 mode_line_string_face_prop
21475 = NILP (face) ? Qnil : list2 (Qface, face);
21478 push_kboard (FRAME_KBOARD (it.f));
21479 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
21480 pop_kboard ();
21482 if (no_props)
21484 len = MODE_LINE_NOPROP_LEN (string_start);
21485 str = make_string (mode_line_noprop_buf + string_start, len);
21487 else
21489 mode_line_string_list = Fnreverse (mode_line_string_list);
21490 str = Fmapconcat (intern ("identity"), mode_line_string_list,
21491 empty_unibyte_string);
21494 unbind_to (count, Qnil);
21495 return str;
21498 /* Write a null-terminated, right justified decimal representation of
21499 the positive integer D to BUF using a minimal field width WIDTH. */
21501 static void
21502 pint2str (register char *buf, register int width, register ptrdiff_t d)
21504 register char *p = buf;
21506 if (d <= 0)
21507 *p++ = '0';
21508 else
21510 while (d > 0)
21512 *p++ = d % 10 + '0';
21513 d /= 10;
21517 for (width -= (int) (p - buf); width > 0; --width)
21518 *p++ = ' ';
21519 *p-- = '\0';
21520 while (p > buf)
21522 d = *buf;
21523 *buf++ = *p;
21524 *p-- = d;
21528 /* Write a null-terminated, right justified decimal and "human
21529 readable" representation of the nonnegative integer D to BUF using
21530 a minimal field width WIDTH. D should be smaller than 999.5e24. */
21532 static const char power_letter[] =
21534 0, /* no letter */
21535 'k', /* kilo */
21536 'M', /* mega */
21537 'G', /* giga */
21538 'T', /* tera */
21539 'P', /* peta */
21540 'E', /* exa */
21541 'Z', /* zetta */
21542 'Y' /* yotta */
21545 static void
21546 pint2hrstr (char *buf, int width, ptrdiff_t d)
21548 /* We aim to represent the nonnegative integer D as
21549 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
21550 ptrdiff_t quotient = d;
21551 int remainder = 0;
21552 /* -1 means: do not use TENTHS. */
21553 int tenths = -1;
21554 int exponent = 0;
21556 /* Length of QUOTIENT.TENTHS as a string. */
21557 int length;
21559 char * psuffix;
21560 char * p;
21562 if (quotient >= 1000)
21564 /* Scale to the appropriate EXPONENT. */
21567 remainder = quotient % 1000;
21568 quotient /= 1000;
21569 exponent++;
21571 while (quotient >= 1000);
21573 /* Round to nearest and decide whether to use TENTHS or not. */
21574 if (quotient <= 9)
21576 tenths = remainder / 100;
21577 if (remainder % 100 >= 50)
21579 if (tenths < 9)
21580 tenths++;
21581 else
21583 quotient++;
21584 if (quotient == 10)
21585 tenths = -1;
21586 else
21587 tenths = 0;
21591 else
21592 if (remainder >= 500)
21594 if (quotient < 999)
21595 quotient++;
21596 else
21598 quotient = 1;
21599 exponent++;
21600 tenths = 0;
21605 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
21606 if (tenths == -1 && quotient <= 99)
21607 if (quotient <= 9)
21608 length = 1;
21609 else
21610 length = 2;
21611 else
21612 length = 3;
21613 p = psuffix = buf + max (width, length);
21615 /* Print EXPONENT. */
21616 *psuffix++ = power_letter[exponent];
21617 *psuffix = '\0';
21619 /* Print TENTHS. */
21620 if (tenths >= 0)
21622 *--p = '0' + tenths;
21623 *--p = '.';
21626 /* Print QUOTIENT. */
21629 int digit = quotient % 10;
21630 *--p = '0' + digit;
21632 while ((quotient /= 10) != 0);
21634 /* Print leading spaces. */
21635 while (buf < p)
21636 *--p = ' ';
21639 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
21640 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
21641 type of CODING_SYSTEM. Return updated pointer into BUF. */
21643 static unsigned char invalid_eol_type[] = "(*invalid*)";
21645 static char *
21646 decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_flag)
21648 Lisp_Object val;
21649 bool multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
21650 const unsigned char *eol_str;
21651 int eol_str_len;
21652 /* The EOL conversion we are using. */
21653 Lisp_Object eoltype;
21655 val = CODING_SYSTEM_SPEC (coding_system);
21656 eoltype = Qnil;
21658 if (!VECTORP (val)) /* Not yet decided. */
21660 *buf++ = multibyte ? '-' : ' ';
21661 if (eol_flag)
21662 eoltype = eol_mnemonic_undecided;
21663 /* Don't mention EOL conversion if it isn't decided. */
21665 else
21667 Lisp_Object attrs;
21668 Lisp_Object eolvalue;
21670 attrs = AREF (val, 0);
21671 eolvalue = AREF (val, 2);
21673 *buf++ = multibyte
21674 ? XFASTINT (CODING_ATTR_MNEMONIC (attrs))
21675 : ' ';
21677 if (eol_flag)
21679 /* The EOL conversion that is normal on this system. */
21681 if (NILP (eolvalue)) /* Not yet decided. */
21682 eoltype = eol_mnemonic_undecided;
21683 else if (VECTORP (eolvalue)) /* Not yet decided. */
21684 eoltype = eol_mnemonic_undecided;
21685 else /* eolvalue is Qunix, Qdos, or Qmac. */
21686 eoltype = (EQ (eolvalue, Qunix)
21687 ? eol_mnemonic_unix
21688 : (EQ (eolvalue, Qdos) == 1
21689 ? eol_mnemonic_dos : eol_mnemonic_mac));
21693 if (eol_flag)
21695 /* Mention the EOL conversion if it is not the usual one. */
21696 if (STRINGP (eoltype))
21698 eol_str = SDATA (eoltype);
21699 eol_str_len = SBYTES (eoltype);
21701 else if (CHARACTERP (eoltype))
21703 unsigned char *tmp = alloca (MAX_MULTIBYTE_LENGTH);
21704 int c = XFASTINT (eoltype);
21705 eol_str_len = CHAR_STRING (c, tmp);
21706 eol_str = tmp;
21708 else
21710 eol_str = invalid_eol_type;
21711 eol_str_len = sizeof (invalid_eol_type) - 1;
21713 memcpy (buf, eol_str, eol_str_len);
21714 buf += eol_str_len;
21717 return buf;
21720 /* Return a string for the output of a mode line %-spec for window W,
21721 generated by character C. FIELD_WIDTH > 0 means pad the string
21722 returned with spaces to that value. Return a Lisp string in
21723 *STRING if the resulting string is taken from that Lisp string.
21725 Note we operate on the current buffer for most purposes. */
21727 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
21729 static const char *
21730 decode_mode_spec (struct window *w, register int c, int field_width,
21731 Lisp_Object *string)
21733 Lisp_Object obj;
21734 struct frame *f = XFRAME (WINDOW_FRAME (w));
21735 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
21736 /* We are going to use f->decode_mode_spec_buffer as the buffer to
21737 produce strings from numerical values, so limit preposterously
21738 large values of FIELD_WIDTH to avoid overrunning the buffer's
21739 end. The size of the buffer is enough for FRAME_MESSAGE_BUF_SIZE
21740 bytes plus the terminating null. */
21741 int width = min (field_width, FRAME_MESSAGE_BUF_SIZE (f));
21742 struct buffer *b = current_buffer;
21744 obj = Qnil;
21745 *string = Qnil;
21747 switch (c)
21749 case '*':
21750 if (!NILP (BVAR (b, read_only)))
21751 return "%";
21752 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21753 return "*";
21754 return "-";
21756 case '+':
21757 /* This differs from %* only for a modified read-only buffer. */
21758 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21759 return "*";
21760 if (!NILP (BVAR (b, read_only)))
21761 return "%";
21762 return "-";
21764 case '&':
21765 /* This differs from %* in ignoring read-only-ness. */
21766 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21767 return "*";
21768 return "-";
21770 case '%':
21771 return "%";
21773 case '[':
21775 int i;
21776 char *p;
21778 if (command_loop_level > 5)
21779 return "[[[... ";
21780 p = decode_mode_spec_buf;
21781 for (i = 0; i < command_loop_level; i++)
21782 *p++ = '[';
21783 *p = 0;
21784 return decode_mode_spec_buf;
21787 case ']':
21789 int i;
21790 char *p;
21792 if (command_loop_level > 5)
21793 return " ...]]]";
21794 p = decode_mode_spec_buf;
21795 for (i = 0; i < command_loop_level; i++)
21796 *p++ = ']';
21797 *p = 0;
21798 return decode_mode_spec_buf;
21801 case '-':
21803 register int i;
21805 /* Let lots_of_dashes be a string of infinite length. */
21806 if (mode_line_target == MODE_LINE_NOPROP
21807 || mode_line_target == MODE_LINE_STRING)
21808 return "--";
21809 if (field_width <= 0
21810 || field_width > sizeof (lots_of_dashes))
21812 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
21813 decode_mode_spec_buf[i] = '-';
21814 decode_mode_spec_buf[i] = '\0';
21815 return decode_mode_spec_buf;
21817 else
21818 return lots_of_dashes;
21821 case 'b':
21822 obj = BVAR (b, name);
21823 break;
21825 case 'c':
21826 /* %c and %l are ignored in `frame-title-format'.
21827 (In redisplay_internal, the frame title is drawn _before_ the
21828 windows are updated, so the stuff which depends on actual
21829 window contents (such as %l) may fail to render properly, or
21830 even crash emacs.) */
21831 if (mode_line_target == MODE_LINE_TITLE)
21832 return "";
21833 else
21835 ptrdiff_t col = current_column ();
21836 w->column_number_displayed = col;
21837 pint2str (decode_mode_spec_buf, width, col);
21838 return decode_mode_spec_buf;
21841 case 'e':
21842 #ifndef SYSTEM_MALLOC
21844 if (NILP (Vmemory_full))
21845 return "";
21846 else
21847 return "!MEM FULL! ";
21849 #else
21850 return "";
21851 #endif
21853 case 'F':
21854 /* %F displays the frame name. */
21855 if (!NILP (f->title))
21856 return SSDATA (f->title);
21857 if (f->explicit_name || ! FRAME_WINDOW_P (f))
21858 return SSDATA (f->name);
21859 return "Emacs";
21861 case 'f':
21862 obj = BVAR (b, filename);
21863 break;
21865 case 'i':
21867 ptrdiff_t size = ZV - BEGV;
21868 pint2str (decode_mode_spec_buf, width, size);
21869 return decode_mode_spec_buf;
21872 case 'I':
21874 ptrdiff_t size = ZV - BEGV;
21875 pint2hrstr (decode_mode_spec_buf, width, size);
21876 return decode_mode_spec_buf;
21879 case 'l':
21881 ptrdiff_t startpos, startpos_byte, line, linepos, linepos_byte;
21882 ptrdiff_t topline, nlines, height;
21883 ptrdiff_t junk;
21885 /* %c and %l are ignored in `frame-title-format'. */
21886 if (mode_line_target == MODE_LINE_TITLE)
21887 return "";
21889 startpos = marker_position (w->start);
21890 startpos_byte = marker_byte_position (w->start);
21891 height = WINDOW_TOTAL_LINES (w);
21893 /* If we decided that this buffer isn't suitable for line numbers,
21894 don't forget that too fast. */
21895 if (w->base_line_pos == -1)
21896 goto no_value;
21898 /* If the buffer is very big, don't waste time. */
21899 if (INTEGERP (Vline_number_display_limit)
21900 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
21902 w->base_line_pos = 0;
21903 w->base_line_number = 0;
21904 goto no_value;
21907 if (w->base_line_number > 0
21908 && w->base_line_pos > 0
21909 && w->base_line_pos <= startpos)
21911 line = w->base_line_number;
21912 linepos = w->base_line_pos;
21913 linepos_byte = buf_charpos_to_bytepos (b, linepos);
21915 else
21917 line = 1;
21918 linepos = BUF_BEGV (b);
21919 linepos_byte = BUF_BEGV_BYTE (b);
21922 /* Count lines from base line to window start position. */
21923 nlines = display_count_lines (linepos_byte,
21924 startpos_byte,
21925 startpos, &junk);
21927 topline = nlines + line;
21929 /* Determine a new base line, if the old one is too close
21930 or too far away, or if we did not have one.
21931 "Too close" means it's plausible a scroll-down would
21932 go back past it. */
21933 if (startpos == BUF_BEGV (b))
21935 w->base_line_number = topline;
21936 w->base_line_pos = BUF_BEGV (b);
21938 else if (nlines < height + 25 || nlines > height * 3 + 50
21939 || linepos == BUF_BEGV (b))
21941 ptrdiff_t limit = BUF_BEGV (b);
21942 ptrdiff_t limit_byte = BUF_BEGV_BYTE (b);
21943 ptrdiff_t position;
21944 ptrdiff_t distance =
21945 (height * 2 + 30) * line_number_display_limit_width;
21947 if (startpos - distance > limit)
21949 limit = startpos - distance;
21950 limit_byte = CHAR_TO_BYTE (limit);
21953 nlines = display_count_lines (startpos_byte,
21954 limit_byte,
21955 - (height * 2 + 30),
21956 &position);
21957 /* If we couldn't find the lines we wanted within
21958 line_number_display_limit_width chars per line,
21959 give up on line numbers for this window. */
21960 if (position == limit_byte && limit == startpos - distance)
21962 w->base_line_pos = -1;
21963 w->base_line_number = 0;
21964 goto no_value;
21967 w->base_line_number = topline - nlines;
21968 w->base_line_pos = BYTE_TO_CHAR (position);
21971 /* Now count lines from the start pos to point. */
21972 nlines = display_count_lines (startpos_byte,
21973 PT_BYTE, PT, &junk);
21975 /* Record that we did display the line number. */
21976 line_number_displayed = 1;
21978 /* Make the string to show. */
21979 pint2str (decode_mode_spec_buf, width, topline + nlines);
21980 return decode_mode_spec_buf;
21981 no_value:
21983 char* p = decode_mode_spec_buf;
21984 int pad = width - 2;
21985 while (pad-- > 0)
21986 *p++ = ' ';
21987 *p++ = '?';
21988 *p++ = '?';
21989 *p = '\0';
21990 return decode_mode_spec_buf;
21993 break;
21995 case 'm':
21996 obj = BVAR (b, mode_name);
21997 break;
21999 case 'n':
22000 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
22001 return " Narrow";
22002 break;
22004 case 'p':
22006 ptrdiff_t pos = marker_position (w->start);
22007 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
22009 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
22011 if (pos <= BUF_BEGV (b))
22012 return "All";
22013 else
22014 return "Bottom";
22016 else if (pos <= BUF_BEGV (b))
22017 return "Top";
22018 else
22020 if (total > 1000000)
22021 /* Do it differently for a large value, to avoid overflow. */
22022 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
22023 else
22024 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
22025 /* We can't normally display a 3-digit number,
22026 so get us a 2-digit number that is close. */
22027 if (total == 100)
22028 total = 99;
22029 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
22030 return decode_mode_spec_buf;
22034 /* Display percentage of size above the bottom of the screen. */
22035 case 'P':
22037 ptrdiff_t toppos = marker_position (w->start);
22038 ptrdiff_t botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
22039 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
22041 if (botpos >= BUF_ZV (b))
22043 if (toppos <= BUF_BEGV (b))
22044 return "All";
22045 else
22046 return "Bottom";
22048 else
22050 if (total > 1000000)
22051 /* Do it differently for a large value, to avoid overflow. */
22052 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
22053 else
22054 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
22055 /* We can't normally display a 3-digit number,
22056 so get us a 2-digit number that is close. */
22057 if (total == 100)
22058 total = 99;
22059 if (toppos <= BUF_BEGV (b))
22060 sprintf (decode_mode_spec_buf, "Top%2"pD"d%%", total);
22061 else
22062 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
22063 return decode_mode_spec_buf;
22067 case 's':
22068 /* status of process */
22069 obj = Fget_buffer_process (Fcurrent_buffer ());
22070 if (NILP (obj))
22071 return "no process";
22072 #ifndef MSDOS
22073 obj = Fsymbol_name (Fprocess_status (obj));
22074 #endif
22075 break;
22077 case '@':
22079 ptrdiff_t count = inhibit_garbage_collection ();
22080 Lisp_Object val = call1 (intern ("file-remote-p"),
22081 BVAR (current_buffer, directory));
22082 unbind_to (count, Qnil);
22084 if (NILP (val))
22085 return "-";
22086 else
22087 return "@";
22090 case 'z':
22091 /* coding-system (not including end-of-line format) */
22092 case 'Z':
22093 /* coding-system (including end-of-line type) */
22095 int eol_flag = (c == 'Z');
22096 char *p = decode_mode_spec_buf;
22098 if (! FRAME_WINDOW_P (f))
22100 /* No need to mention EOL here--the terminal never needs
22101 to do EOL conversion. */
22102 p = decode_mode_spec_coding (CODING_ID_NAME
22103 (FRAME_KEYBOARD_CODING (f)->id),
22104 p, 0);
22105 p = decode_mode_spec_coding (CODING_ID_NAME
22106 (FRAME_TERMINAL_CODING (f)->id),
22107 p, 0);
22109 p = decode_mode_spec_coding (BVAR (b, buffer_file_coding_system),
22110 p, eol_flag);
22112 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
22113 #ifdef subprocesses
22114 obj = Fget_buffer_process (Fcurrent_buffer ());
22115 if (PROCESSP (obj))
22117 p = decode_mode_spec_coding
22118 (XPROCESS (obj)->decode_coding_system, p, eol_flag);
22119 p = decode_mode_spec_coding
22120 (XPROCESS (obj)->encode_coding_system, p, eol_flag);
22122 #endif /* subprocesses */
22123 #endif /* 0 */
22124 *p = 0;
22125 return decode_mode_spec_buf;
22129 if (STRINGP (obj))
22131 *string = obj;
22132 return SSDATA (obj);
22134 else
22135 return "";
22139 /* Count up to COUNT lines starting from START_BYTE. COUNT negative
22140 means count lines back from START_BYTE. But don't go beyond
22141 LIMIT_BYTE. Return the number of lines thus found (always
22142 nonnegative).
22144 Set *BYTE_POS_PTR to the byte position where we stopped. This is
22145 either the position COUNT lines after/before START_BYTE, if we
22146 found COUNT lines, or LIMIT_BYTE if we hit the limit before finding
22147 COUNT lines. */
22149 static ptrdiff_t
22150 display_count_lines (ptrdiff_t start_byte,
22151 ptrdiff_t limit_byte, ptrdiff_t count,
22152 ptrdiff_t *byte_pos_ptr)
22154 register unsigned char *cursor;
22155 unsigned char *base;
22157 register ptrdiff_t ceiling;
22158 register unsigned char *ceiling_addr;
22159 ptrdiff_t orig_count = count;
22161 /* If we are not in selective display mode,
22162 check only for newlines. */
22163 int selective_display = (!NILP (BVAR (current_buffer, selective_display))
22164 && !INTEGERP (BVAR (current_buffer, selective_display)));
22166 if (count > 0)
22168 while (start_byte < limit_byte)
22170 ceiling = BUFFER_CEILING_OF (start_byte);
22171 ceiling = min (limit_byte - 1, ceiling);
22172 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
22173 base = (cursor = BYTE_POS_ADDR (start_byte));
22177 if (selective_display)
22179 while (*cursor != '\n' && *cursor != 015
22180 && ++cursor != ceiling_addr)
22181 continue;
22182 if (cursor == ceiling_addr)
22183 break;
22185 else
22187 cursor = memchr (cursor, '\n', ceiling_addr - cursor);
22188 if (! cursor)
22189 break;
22192 cursor++;
22194 if (--count == 0)
22196 start_byte += cursor - base;
22197 *byte_pos_ptr = start_byte;
22198 return orig_count;
22201 while (cursor < ceiling_addr);
22203 start_byte += ceiling_addr - base;
22206 else
22208 while (start_byte > limit_byte)
22210 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
22211 ceiling = max (limit_byte, ceiling);
22212 ceiling_addr = BYTE_POS_ADDR (ceiling);
22213 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
22214 while (1)
22216 if (selective_display)
22218 while (--cursor >= ceiling_addr
22219 && *cursor != '\n' && *cursor != 015)
22220 continue;
22221 if (cursor < ceiling_addr)
22222 break;
22224 else
22226 cursor = memrchr (ceiling_addr, '\n', cursor - ceiling_addr);
22227 if (! cursor)
22228 break;
22231 if (++count == 0)
22233 start_byte += cursor - base + 1;
22234 *byte_pos_ptr = start_byte;
22235 /* When scanning backwards, we should
22236 not count the newline posterior to which we stop. */
22237 return - orig_count - 1;
22240 start_byte += ceiling_addr - base;
22244 *byte_pos_ptr = limit_byte;
22246 if (count < 0)
22247 return - orig_count + count;
22248 return orig_count - count;
22254 /***********************************************************************
22255 Displaying strings
22256 ***********************************************************************/
22258 /* Display a NUL-terminated string, starting with index START.
22260 If STRING is non-null, display that C string. Otherwise, the Lisp
22261 string LISP_STRING is displayed. There's a case that STRING is
22262 non-null and LISP_STRING is not nil. It means STRING is a string
22263 data of LISP_STRING. In that case, we display LISP_STRING while
22264 ignoring its text properties.
22266 If FACE_STRING is not nil, FACE_STRING_POS is a position in
22267 FACE_STRING. Display STRING or LISP_STRING with the face at
22268 FACE_STRING_POS in FACE_STRING:
22270 Display the string in the environment given by IT, but use the
22271 standard display table, temporarily.
22273 FIELD_WIDTH is the minimum number of output glyphs to produce.
22274 If STRING has fewer characters than FIELD_WIDTH, pad to the right
22275 with spaces. If STRING has more characters, more than FIELD_WIDTH
22276 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
22278 PRECISION is the maximum number of characters to output from
22279 STRING. PRECISION < 0 means don't truncate the string.
22281 This is roughly equivalent to printf format specifiers:
22283 FIELD_WIDTH PRECISION PRINTF
22284 ----------------------------------------
22285 -1 -1 %s
22286 -1 10 %.10s
22287 10 -1 %10s
22288 20 10 %20.10s
22290 MULTIBYTE zero means do not display multibyte chars, > 0 means do
22291 display them, and < 0 means obey the current buffer's value of
22292 enable_multibyte_characters.
22294 Value is the number of columns displayed. */
22296 static int
22297 display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_string,
22298 ptrdiff_t face_string_pos, ptrdiff_t start, struct it *it,
22299 int field_width, int precision, int max_x, int multibyte)
22301 int hpos_at_start = it->hpos;
22302 int saved_face_id = it->face_id;
22303 struct glyph_row *row = it->glyph_row;
22304 ptrdiff_t it_charpos;
22306 /* Initialize the iterator IT for iteration over STRING beginning
22307 with index START. */
22308 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
22309 precision, field_width, multibyte);
22310 if (string && STRINGP (lisp_string))
22311 /* LISP_STRING is the one returned by decode_mode_spec. We should
22312 ignore its text properties. */
22313 it->stop_charpos = it->end_charpos;
22315 /* If displaying STRING, set up the face of the iterator from
22316 FACE_STRING, if that's given. */
22317 if (STRINGP (face_string))
22319 ptrdiff_t endptr;
22320 struct face *face;
22322 it->face_id
22323 = face_at_string_position (it->w, face_string, face_string_pos,
22324 0, it->region_beg_charpos,
22325 it->region_end_charpos,
22326 &endptr, it->base_face_id, 0);
22327 face = FACE_FROM_ID (it->f, it->face_id);
22328 it->face_box_p = face->box != FACE_NO_BOX;
22331 /* Set max_x to the maximum allowed X position. Don't let it go
22332 beyond the right edge of the window. */
22333 if (max_x <= 0)
22334 max_x = it->last_visible_x;
22335 else
22336 max_x = min (max_x, it->last_visible_x);
22338 /* Skip over display elements that are not visible. because IT->w is
22339 hscrolled. */
22340 if (it->current_x < it->first_visible_x)
22341 move_it_in_display_line_to (it, 100000, it->first_visible_x,
22342 MOVE_TO_POS | MOVE_TO_X);
22344 row->ascent = it->max_ascent;
22345 row->height = it->max_ascent + it->max_descent;
22346 row->phys_ascent = it->max_phys_ascent;
22347 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
22348 row->extra_line_spacing = it->max_extra_line_spacing;
22350 if (STRINGP (it->string))
22351 it_charpos = IT_STRING_CHARPOS (*it);
22352 else
22353 it_charpos = IT_CHARPOS (*it);
22355 /* This condition is for the case that we are called with current_x
22356 past last_visible_x. */
22357 while (it->current_x < max_x)
22359 int x_before, x, n_glyphs_before, i, nglyphs;
22361 /* Get the next display element. */
22362 if (!get_next_display_element (it))
22363 break;
22365 /* Produce glyphs. */
22366 x_before = it->current_x;
22367 n_glyphs_before = row->used[TEXT_AREA];
22368 PRODUCE_GLYPHS (it);
22370 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
22371 i = 0;
22372 x = x_before;
22373 while (i < nglyphs)
22375 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
22377 if (it->line_wrap != TRUNCATE
22378 && x + glyph->pixel_width > max_x)
22380 /* End of continued line or max_x reached. */
22381 if (CHAR_GLYPH_PADDING_P (*glyph))
22383 /* A wide character is unbreakable. */
22384 if (row->reversed_p)
22385 unproduce_glyphs (it, row->used[TEXT_AREA]
22386 - n_glyphs_before);
22387 row->used[TEXT_AREA] = n_glyphs_before;
22388 it->current_x = x_before;
22390 else
22392 if (row->reversed_p)
22393 unproduce_glyphs (it, row->used[TEXT_AREA]
22394 - (n_glyphs_before + i));
22395 row->used[TEXT_AREA] = n_glyphs_before + i;
22396 it->current_x = x;
22398 break;
22400 else if (x + glyph->pixel_width >= it->first_visible_x)
22402 /* Glyph is at least partially visible. */
22403 ++it->hpos;
22404 if (x < it->first_visible_x)
22405 row->x = x - it->first_visible_x;
22407 else
22409 /* Glyph is off the left margin of the display area.
22410 Should not happen. */
22411 emacs_abort ();
22414 row->ascent = max (row->ascent, it->max_ascent);
22415 row->height = max (row->height, it->max_ascent + it->max_descent);
22416 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
22417 row->phys_height = max (row->phys_height,
22418 it->max_phys_ascent + it->max_phys_descent);
22419 row->extra_line_spacing = max (row->extra_line_spacing,
22420 it->max_extra_line_spacing);
22421 x += glyph->pixel_width;
22422 ++i;
22425 /* Stop if max_x reached. */
22426 if (i < nglyphs)
22427 break;
22429 /* Stop at line ends. */
22430 if (ITERATOR_AT_END_OF_LINE_P (it))
22432 it->continuation_lines_width = 0;
22433 break;
22436 set_iterator_to_next (it, 1);
22437 if (STRINGP (it->string))
22438 it_charpos = IT_STRING_CHARPOS (*it);
22439 else
22440 it_charpos = IT_CHARPOS (*it);
22442 /* Stop if truncating at the right edge. */
22443 if (it->line_wrap == TRUNCATE
22444 && it->current_x >= it->last_visible_x)
22446 /* Add truncation mark, but don't do it if the line is
22447 truncated at a padding space. */
22448 if (it_charpos < it->string_nchars)
22450 if (!FRAME_WINDOW_P (it->f))
22452 int ii, n;
22454 if (it->current_x > it->last_visible_x)
22456 if (!row->reversed_p)
22458 for (ii = row->used[TEXT_AREA] - 1; ii > 0; --ii)
22459 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
22460 break;
22462 else
22464 for (ii = 0; ii < row->used[TEXT_AREA]; ii++)
22465 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
22466 break;
22467 unproduce_glyphs (it, ii + 1);
22468 ii = row->used[TEXT_AREA] - (ii + 1);
22470 for (n = row->used[TEXT_AREA]; ii < n; ++ii)
22472 row->used[TEXT_AREA] = ii;
22473 produce_special_glyphs (it, IT_TRUNCATION);
22476 produce_special_glyphs (it, IT_TRUNCATION);
22478 row->truncated_on_right_p = 1;
22480 break;
22484 /* Maybe insert a truncation at the left. */
22485 if (it->first_visible_x
22486 && it_charpos > 0)
22488 if (!FRAME_WINDOW_P (it->f)
22489 || (row->reversed_p
22490 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
22491 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
22492 insert_left_trunc_glyphs (it);
22493 row->truncated_on_left_p = 1;
22496 it->face_id = saved_face_id;
22498 /* Value is number of columns displayed. */
22499 return it->hpos - hpos_at_start;
22504 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
22505 appears as an element of LIST or as the car of an element of LIST.
22506 If PROPVAL is a list, compare each element against LIST in that
22507 way, and return 1/2 if any element of PROPVAL is found in LIST.
22508 Otherwise return 0. This function cannot quit.
22509 The return value is 2 if the text is invisible but with an ellipsis
22510 and 1 if it's invisible and without an ellipsis. */
22513 invisible_p (register Lisp_Object propval, Lisp_Object list)
22515 register Lisp_Object tail, proptail;
22517 for (tail = list; CONSP (tail); tail = XCDR (tail))
22519 register Lisp_Object tem;
22520 tem = XCAR (tail);
22521 if (EQ (propval, tem))
22522 return 1;
22523 if (CONSP (tem) && EQ (propval, XCAR (tem)))
22524 return NILP (XCDR (tem)) ? 1 : 2;
22527 if (CONSP (propval))
22529 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
22531 Lisp_Object propelt;
22532 propelt = XCAR (proptail);
22533 for (tail = list; CONSP (tail); tail = XCDR (tail))
22535 register Lisp_Object tem;
22536 tem = XCAR (tail);
22537 if (EQ (propelt, tem))
22538 return 1;
22539 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
22540 return NILP (XCDR (tem)) ? 1 : 2;
22545 return 0;
22548 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
22549 doc: /* Non-nil if the property makes the text invisible.
22550 POS-OR-PROP can be a marker or number, in which case it is taken to be
22551 a position in the current buffer and the value of the `invisible' property
22552 is checked; or it can be some other value, which is then presumed to be the
22553 value of the `invisible' property of the text of interest.
22554 The non-nil value returned can be t for truly invisible text or something
22555 else if the text is replaced by an ellipsis. */)
22556 (Lisp_Object pos_or_prop)
22558 Lisp_Object prop
22559 = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
22560 ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
22561 : pos_or_prop);
22562 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
22563 return (invis == 0 ? Qnil
22564 : invis == 1 ? Qt
22565 : make_number (invis));
22568 /* Calculate a width or height in pixels from a specification using
22569 the following elements:
22571 SPEC ::=
22572 NUM - a (fractional) multiple of the default font width/height
22573 (NUM) - specifies exactly NUM pixels
22574 UNIT - a fixed number of pixels, see below.
22575 ELEMENT - size of a display element in pixels, see below.
22576 (NUM . SPEC) - equals NUM * SPEC
22577 (+ SPEC SPEC ...) - add pixel values
22578 (- SPEC SPEC ...) - subtract pixel values
22579 (- SPEC) - negate pixel value
22581 NUM ::=
22582 INT or FLOAT - a number constant
22583 SYMBOL - use symbol's (buffer local) variable binding.
22585 UNIT ::=
22586 in - pixels per inch *)
22587 mm - pixels per 1/1000 meter *)
22588 cm - pixels per 1/100 meter *)
22589 width - width of current font in pixels.
22590 height - height of current font in pixels.
22592 *) using the ratio(s) defined in display-pixels-per-inch.
22594 ELEMENT ::=
22596 left-fringe - left fringe width in pixels
22597 right-fringe - right fringe width in pixels
22599 left-margin - left margin width in pixels
22600 right-margin - right margin width in pixels
22602 scroll-bar - scroll-bar area width in pixels
22604 Examples:
22606 Pixels corresponding to 5 inches:
22607 (5 . in)
22609 Total width of non-text areas on left side of window (if scroll-bar is on left):
22610 '(space :width (+ left-fringe left-margin scroll-bar))
22612 Align to first text column (in header line):
22613 '(space :align-to 0)
22615 Align to middle of text area minus half the width of variable `my-image'
22616 containing a loaded image:
22617 '(space :align-to (0.5 . (- text my-image)))
22619 Width of left margin minus width of 1 character in the default font:
22620 '(space :width (- left-margin 1))
22622 Width of left margin minus width of 2 characters in the current font:
22623 '(space :width (- left-margin (2 . width)))
22625 Center 1 character over left-margin (in header line):
22626 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
22628 Different ways to express width of left fringe plus left margin minus one pixel:
22629 '(space :width (- (+ left-fringe left-margin) (1)))
22630 '(space :width (+ left-fringe left-margin (- (1))))
22631 '(space :width (+ left-fringe left-margin (-1)))
22635 static int
22636 calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
22637 struct font *font, int width_p, int *align_to)
22639 double pixels;
22641 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
22642 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
22644 if (NILP (prop))
22645 return OK_PIXELS (0);
22647 eassert (FRAME_LIVE_P (it->f));
22649 if (SYMBOLP (prop))
22651 if (SCHARS (SYMBOL_NAME (prop)) == 2)
22653 char *unit = SSDATA (SYMBOL_NAME (prop));
22655 if (unit[0] == 'i' && unit[1] == 'n')
22656 pixels = 1.0;
22657 else if (unit[0] == 'm' && unit[1] == 'm')
22658 pixels = 25.4;
22659 else if (unit[0] == 'c' && unit[1] == 'm')
22660 pixels = 2.54;
22661 else
22662 pixels = 0;
22663 if (pixels > 0)
22665 double ppi = (width_p ? FRAME_RES_X (it->f)
22666 : FRAME_RES_Y (it->f));
22668 if (ppi > 0)
22669 return OK_PIXELS (ppi / pixels);
22670 return 0;
22674 #ifdef HAVE_WINDOW_SYSTEM
22675 if (EQ (prop, Qheight))
22676 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
22677 if (EQ (prop, Qwidth))
22678 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
22679 #else
22680 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
22681 return OK_PIXELS (1);
22682 #endif
22684 if (EQ (prop, Qtext))
22685 return OK_PIXELS (width_p
22686 ? window_box_width (it->w, TEXT_AREA)
22687 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
22689 if (align_to && *align_to < 0)
22691 *res = 0;
22692 if (EQ (prop, Qleft))
22693 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
22694 if (EQ (prop, Qright))
22695 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
22696 if (EQ (prop, Qcenter))
22697 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
22698 + window_box_width (it->w, TEXT_AREA) / 2);
22699 if (EQ (prop, Qleft_fringe))
22700 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22701 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
22702 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
22703 if (EQ (prop, Qright_fringe))
22704 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22705 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
22706 : window_box_right_offset (it->w, TEXT_AREA));
22707 if (EQ (prop, Qleft_margin))
22708 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
22709 if (EQ (prop, Qright_margin))
22710 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
22711 if (EQ (prop, Qscroll_bar))
22712 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
22714 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
22715 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22716 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
22717 : 0)));
22719 else
22721 if (EQ (prop, Qleft_fringe))
22722 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
22723 if (EQ (prop, Qright_fringe))
22724 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
22725 if (EQ (prop, Qleft_margin))
22726 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
22727 if (EQ (prop, Qright_margin))
22728 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
22729 if (EQ (prop, Qscroll_bar))
22730 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
22733 prop = buffer_local_value_1 (prop, it->w->contents);
22734 if (EQ (prop, Qunbound))
22735 prop = Qnil;
22738 if (INTEGERP (prop) || FLOATP (prop))
22740 int base_unit = (width_p
22741 ? FRAME_COLUMN_WIDTH (it->f)
22742 : FRAME_LINE_HEIGHT (it->f));
22743 return OK_PIXELS (XFLOATINT (prop) * base_unit);
22746 if (CONSP (prop))
22748 Lisp_Object car = XCAR (prop);
22749 Lisp_Object cdr = XCDR (prop);
22751 if (SYMBOLP (car))
22753 #ifdef HAVE_WINDOW_SYSTEM
22754 if (FRAME_WINDOW_P (it->f)
22755 && valid_image_p (prop))
22757 ptrdiff_t id = lookup_image (it->f, prop);
22758 struct image *img = IMAGE_FROM_ID (it->f, id);
22760 return OK_PIXELS (width_p ? img->width : img->height);
22762 #endif
22763 if (EQ (car, Qplus) || EQ (car, Qminus))
22765 int first = 1;
22766 double px;
22768 pixels = 0;
22769 while (CONSP (cdr))
22771 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
22772 font, width_p, align_to))
22773 return 0;
22774 if (first)
22775 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
22776 else
22777 pixels += px;
22778 cdr = XCDR (cdr);
22780 if (EQ (car, Qminus))
22781 pixels = -pixels;
22782 return OK_PIXELS (pixels);
22785 car = buffer_local_value_1 (car, it->w->contents);
22786 if (EQ (car, Qunbound))
22787 car = Qnil;
22790 if (INTEGERP (car) || FLOATP (car))
22792 double fact;
22793 pixels = XFLOATINT (car);
22794 if (NILP (cdr))
22795 return OK_PIXELS (pixels);
22796 if (calc_pixel_width_or_height (&fact, it, cdr,
22797 font, width_p, align_to))
22798 return OK_PIXELS (pixels * fact);
22799 return 0;
22802 return 0;
22805 return 0;
22809 /***********************************************************************
22810 Glyph Display
22811 ***********************************************************************/
22813 #ifdef HAVE_WINDOW_SYSTEM
22815 #ifdef GLYPH_DEBUG
22817 void
22818 dump_glyph_string (struct glyph_string *s)
22820 fprintf (stderr, "glyph string\n");
22821 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
22822 s->x, s->y, s->width, s->height);
22823 fprintf (stderr, " ybase = %d\n", s->ybase);
22824 fprintf (stderr, " hl = %d\n", s->hl);
22825 fprintf (stderr, " left overhang = %d, right = %d\n",
22826 s->left_overhang, s->right_overhang);
22827 fprintf (stderr, " nchars = %d\n", s->nchars);
22828 fprintf (stderr, " extends to end of line = %d\n",
22829 s->extends_to_end_of_line_p);
22830 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
22831 fprintf (stderr, " bg width = %d\n", s->background_width);
22834 #endif /* GLYPH_DEBUG */
22836 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
22837 of XChar2b structures for S; it can't be allocated in
22838 init_glyph_string because it must be allocated via `alloca'. W
22839 is the window on which S is drawn. ROW and AREA are the glyph row
22840 and area within the row from which S is constructed. START is the
22841 index of the first glyph structure covered by S. HL is a
22842 face-override for drawing S. */
22844 #ifdef HAVE_NTGUI
22845 #define OPTIONAL_HDC(hdc) HDC hdc,
22846 #define DECLARE_HDC(hdc) HDC hdc;
22847 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
22848 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
22849 #endif
22851 #ifndef OPTIONAL_HDC
22852 #define OPTIONAL_HDC(hdc)
22853 #define DECLARE_HDC(hdc)
22854 #define ALLOCATE_HDC(hdc, f)
22855 #define RELEASE_HDC(hdc, f)
22856 #endif
22858 static void
22859 init_glyph_string (struct glyph_string *s,
22860 OPTIONAL_HDC (hdc)
22861 XChar2b *char2b, struct window *w, struct glyph_row *row,
22862 enum glyph_row_area area, int start, enum draw_glyphs_face hl)
22864 memset (s, 0, sizeof *s);
22865 s->w = w;
22866 s->f = XFRAME (w->frame);
22867 #ifdef HAVE_NTGUI
22868 s->hdc = hdc;
22869 #endif
22870 s->display = FRAME_X_DISPLAY (s->f);
22871 s->window = FRAME_X_WINDOW (s->f);
22872 s->char2b = char2b;
22873 s->hl = hl;
22874 s->row = row;
22875 s->area = area;
22876 s->first_glyph = row->glyphs[area] + start;
22877 s->height = row->height;
22878 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
22879 s->ybase = s->y + row->ascent;
22883 /* Append the list of glyph strings with head H and tail T to the list
22884 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
22886 static void
22887 append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
22888 struct glyph_string *h, struct glyph_string *t)
22890 if (h)
22892 if (*head)
22893 (*tail)->next = h;
22894 else
22895 *head = h;
22896 h->prev = *tail;
22897 *tail = t;
22902 /* Prepend the list of glyph strings with head H and tail T to the
22903 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
22904 result. */
22906 static void
22907 prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
22908 struct glyph_string *h, struct glyph_string *t)
22910 if (h)
22912 if (*head)
22913 (*head)->prev = t;
22914 else
22915 *tail = t;
22916 t->next = *head;
22917 *head = h;
22922 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
22923 Set *HEAD and *TAIL to the resulting list. */
22925 static void
22926 append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
22927 struct glyph_string *s)
22929 s->next = s->prev = NULL;
22930 append_glyph_string_lists (head, tail, s, s);
22934 /* Get face and two-byte form of character C in face FACE_ID on frame F.
22935 The encoding of C is returned in *CHAR2B. DISPLAY_P non-zero means
22936 make sure that X resources for the face returned are allocated.
22937 Value is a pointer to a realized face that is ready for display if
22938 DISPLAY_P is non-zero. */
22940 static struct face *
22941 get_char_face_and_encoding (struct frame *f, int c, int face_id,
22942 XChar2b *char2b, int display_p)
22944 struct face *face = FACE_FROM_ID (f, face_id);
22945 unsigned code = 0;
22947 if (face->font)
22949 code = face->font->driver->encode_char (face->font, c);
22951 if (code == FONT_INVALID_CODE)
22952 code = 0;
22954 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
22956 /* Make sure X resources of the face are allocated. */
22957 #ifdef HAVE_X_WINDOWS
22958 if (display_p)
22959 #endif
22961 eassert (face != NULL);
22962 PREPARE_FACE_FOR_DISPLAY (f, face);
22965 return face;
22969 /* Get face and two-byte form of character glyph GLYPH on frame F.
22970 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
22971 a pointer to a realized face that is ready for display. */
22973 static struct face *
22974 get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
22975 XChar2b *char2b, int *two_byte_p)
22977 struct face *face;
22978 unsigned code = 0;
22980 eassert (glyph->type == CHAR_GLYPH);
22981 face = FACE_FROM_ID (f, glyph->face_id);
22983 /* Make sure X resources of the face are allocated. */
22984 eassert (face != NULL);
22985 PREPARE_FACE_FOR_DISPLAY (f, face);
22987 if (two_byte_p)
22988 *two_byte_p = 0;
22990 if (face->font)
22992 if (CHAR_BYTE8_P (glyph->u.ch))
22993 code = CHAR_TO_BYTE8 (glyph->u.ch);
22994 else
22995 code = face->font->driver->encode_char (face->font, glyph->u.ch);
22997 if (code == FONT_INVALID_CODE)
22998 code = 0;
23001 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
23002 return face;
23006 /* Get glyph code of character C in FONT in the two-byte form CHAR2B.
23007 Return 1 if FONT has a glyph for C, otherwise return 0. */
23009 static int
23010 get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
23012 unsigned code;
23014 if (CHAR_BYTE8_P (c))
23015 code = CHAR_TO_BYTE8 (c);
23016 else
23017 code = font->driver->encode_char (font, c);
23019 if (code == FONT_INVALID_CODE)
23020 return 0;
23021 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
23022 return 1;
23026 /* Fill glyph string S with composition components specified by S->cmp.
23028 BASE_FACE is the base face of the composition.
23029 S->cmp_from is the index of the first component for S.
23031 OVERLAPS non-zero means S should draw the foreground only, and use
23032 its physical height for clipping. See also draw_glyphs.
23034 Value is the index of a component not in S. */
23036 static int
23037 fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
23038 int overlaps)
23040 int i;
23041 /* For all glyphs of this composition, starting at the offset
23042 S->cmp_from, until we reach the end of the definition or encounter a
23043 glyph that requires the different face, add it to S. */
23044 struct face *face;
23046 eassert (s);
23048 s->for_overlaps = overlaps;
23049 s->face = NULL;
23050 s->font = NULL;
23051 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
23053 int c = COMPOSITION_GLYPH (s->cmp, i);
23055 /* TAB in a composition means display glyphs with padding space
23056 on the left or right. */
23057 if (c != '\t')
23059 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
23060 -1, Qnil);
23062 face = get_char_face_and_encoding (s->f, c, face_id,
23063 s->char2b + i, 1);
23064 if (face)
23066 if (! s->face)
23068 s->face = face;
23069 s->font = s->face->font;
23071 else if (s->face != face)
23072 break;
23075 ++s->nchars;
23077 s->cmp_to = i;
23079 if (s->face == NULL)
23081 s->face = base_face->ascii_face;
23082 s->font = s->face->font;
23085 /* All glyph strings for the same composition has the same width,
23086 i.e. the width set for the first component of the composition. */
23087 s->width = s->first_glyph->pixel_width;
23089 /* If the specified font could not be loaded, use the frame's
23090 default font, but record the fact that we couldn't load it in
23091 the glyph string so that we can draw rectangles for the
23092 characters of the glyph string. */
23093 if (s->font == NULL)
23095 s->font_not_found_p = 1;
23096 s->font = FRAME_FONT (s->f);
23099 /* Adjust base line for subscript/superscript text. */
23100 s->ybase += s->first_glyph->voffset;
23102 /* This glyph string must always be drawn with 16-bit functions. */
23103 s->two_byte_p = 1;
23105 return s->cmp_to;
23108 static int
23109 fill_gstring_glyph_string (struct glyph_string *s, int face_id,
23110 int start, int end, int overlaps)
23112 struct glyph *glyph, *last;
23113 Lisp_Object lgstring;
23114 int i;
23116 s->for_overlaps = overlaps;
23117 glyph = s->row->glyphs[s->area] + start;
23118 last = s->row->glyphs[s->area] + end;
23119 s->cmp_id = glyph->u.cmp.id;
23120 s->cmp_from = glyph->slice.cmp.from;
23121 s->cmp_to = glyph->slice.cmp.to + 1;
23122 s->face = FACE_FROM_ID (s->f, face_id);
23123 lgstring = composition_gstring_from_id (s->cmp_id);
23124 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
23125 glyph++;
23126 while (glyph < last
23127 && glyph->u.cmp.automatic
23128 && glyph->u.cmp.id == s->cmp_id
23129 && s->cmp_to == glyph->slice.cmp.from)
23130 s->cmp_to = (glyph++)->slice.cmp.to + 1;
23132 for (i = s->cmp_from; i < s->cmp_to; i++)
23134 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
23135 unsigned code = LGLYPH_CODE (lglyph);
23137 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
23139 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
23140 return glyph - s->row->glyphs[s->area];
23144 /* Fill glyph string S from a sequence glyphs for glyphless characters.
23145 See the comment of fill_glyph_string for arguments.
23146 Value is the index of the first glyph not in S. */
23149 static int
23150 fill_glyphless_glyph_string (struct glyph_string *s, int face_id,
23151 int start, int end, int overlaps)
23153 struct glyph *glyph, *last;
23154 int voffset;
23156 eassert (s->first_glyph->type == GLYPHLESS_GLYPH);
23157 s->for_overlaps = overlaps;
23158 glyph = s->row->glyphs[s->area] + start;
23159 last = s->row->glyphs[s->area] + end;
23160 voffset = glyph->voffset;
23161 s->face = FACE_FROM_ID (s->f, face_id);
23162 s->font = s->face->font ? s->face->font : FRAME_FONT (s->f);
23163 s->nchars = 1;
23164 s->width = glyph->pixel_width;
23165 glyph++;
23166 while (glyph < last
23167 && glyph->type == GLYPHLESS_GLYPH
23168 && glyph->voffset == voffset
23169 && glyph->face_id == face_id)
23171 s->nchars++;
23172 s->width += glyph->pixel_width;
23173 glyph++;
23175 s->ybase += voffset;
23176 return glyph - s->row->glyphs[s->area];
23180 /* Fill glyph string S from a sequence of character glyphs.
23182 FACE_ID is the face id of the string. START is the index of the
23183 first glyph to consider, END is the index of the last + 1.
23184 OVERLAPS non-zero means S should draw the foreground only, and use
23185 its physical height for clipping. See also draw_glyphs.
23187 Value is the index of the first glyph not in S. */
23189 static int
23190 fill_glyph_string (struct glyph_string *s, int face_id,
23191 int start, int end, int overlaps)
23193 struct glyph *glyph, *last;
23194 int voffset;
23195 int glyph_not_available_p;
23197 eassert (s->f == XFRAME (s->w->frame));
23198 eassert (s->nchars == 0);
23199 eassert (start >= 0 && end > start);
23201 s->for_overlaps = overlaps;
23202 glyph = s->row->glyphs[s->area] + start;
23203 last = s->row->glyphs[s->area] + end;
23204 voffset = glyph->voffset;
23205 s->padding_p = glyph->padding_p;
23206 glyph_not_available_p = glyph->glyph_not_available_p;
23208 while (glyph < last
23209 && glyph->type == CHAR_GLYPH
23210 && glyph->voffset == voffset
23211 /* Same face id implies same font, nowadays. */
23212 && glyph->face_id == face_id
23213 && glyph->glyph_not_available_p == glyph_not_available_p)
23215 int two_byte_p;
23217 s->face = get_glyph_face_and_encoding (s->f, glyph,
23218 s->char2b + s->nchars,
23219 &two_byte_p);
23220 s->two_byte_p = two_byte_p;
23221 ++s->nchars;
23222 eassert (s->nchars <= end - start);
23223 s->width += glyph->pixel_width;
23224 if (glyph++->padding_p != s->padding_p)
23225 break;
23228 s->font = s->face->font;
23230 /* If the specified font could not be loaded, use the frame's font,
23231 but record the fact that we couldn't load it in
23232 S->font_not_found_p so that we can draw rectangles for the
23233 characters of the glyph string. */
23234 if (s->font == NULL || glyph_not_available_p)
23236 s->font_not_found_p = 1;
23237 s->font = FRAME_FONT (s->f);
23240 /* Adjust base line for subscript/superscript text. */
23241 s->ybase += voffset;
23243 eassert (s->face && s->face->gc);
23244 return glyph - s->row->glyphs[s->area];
23248 /* Fill glyph string S from image glyph S->first_glyph. */
23250 static void
23251 fill_image_glyph_string (struct glyph_string *s)
23253 eassert (s->first_glyph->type == IMAGE_GLYPH);
23254 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
23255 eassert (s->img);
23256 s->slice = s->first_glyph->slice.img;
23257 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
23258 s->font = s->face->font;
23259 s->width = s->first_glyph->pixel_width;
23261 /* Adjust base line for subscript/superscript text. */
23262 s->ybase += s->first_glyph->voffset;
23266 /* Fill glyph string S from a sequence of stretch glyphs.
23268 START is the index of the first glyph to consider,
23269 END is the index of the last + 1.
23271 Value is the index of the first glyph not in S. */
23273 static int
23274 fill_stretch_glyph_string (struct glyph_string *s, int start, int end)
23276 struct glyph *glyph, *last;
23277 int voffset, face_id;
23279 eassert (s->first_glyph->type == STRETCH_GLYPH);
23281 glyph = s->row->glyphs[s->area] + start;
23282 last = s->row->glyphs[s->area] + end;
23283 face_id = glyph->face_id;
23284 s->face = FACE_FROM_ID (s->f, face_id);
23285 s->font = s->face->font;
23286 s->width = glyph->pixel_width;
23287 s->nchars = 1;
23288 voffset = glyph->voffset;
23290 for (++glyph;
23291 (glyph < last
23292 && glyph->type == STRETCH_GLYPH
23293 && glyph->voffset == voffset
23294 && glyph->face_id == face_id);
23295 ++glyph)
23296 s->width += glyph->pixel_width;
23298 /* Adjust base line for subscript/superscript text. */
23299 s->ybase += voffset;
23301 /* The case that face->gc == 0 is handled when drawing the glyph
23302 string by calling PREPARE_FACE_FOR_DISPLAY. */
23303 eassert (s->face);
23304 return glyph - s->row->glyphs[s->area];
23307 static struct font_metrics *
23308 get_per_char_metric (struct font *font, XChar2b *char2b)
23310 static struct font_metrics metrics;
23311 unsigned code;
23313 if (! font)
23314 return NULL;
23315 code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
23316 if (code == FONT_INVALID_CODE)
23317 return NULL;
23318 font->driver->text_extents (font, &code, 1, &metrics);
23319 return &metrics;
23322 /* EXPORT for RIF:
23323 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
23324 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
23325 assumed to be zero. */
23327 void
23328 x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *right)
23330 *left = *right = 0;
23332 if (glyph->type == CHAR_GLYPH)
23334 struct face *face;
23335 XChar2b char2b;
23336 struct font_metrics *pcm;
23338 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
23339 if (face->font && (pcm = get_per_char_metric (face->font, &char2b)))
23341 if (pcm->rbearing > pcm->width)
23342 *right = pcm->rbearing - pcm->width;
23343 if (pcm->lbearing < 0)
23344 *left = -pcm->lbearing;
23347 else if (glyph->type == COMPOSITE_GLYPH)
23349 if (! glyph->u.cmp.automatic)
23351 struct composition *cmp = composition_table[glyph->u.cmp.id];
23353 if (cmp->rbearing > cmp->pixel_width)
23354 *right = cmp->rbearing - cmp->pixel_width;
23355 if (cmp->lbearing < 0)
23356 *left = - cmp->lbearing;
23358 else
23360 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
23361 struct font_metrics metrics;
23363 composition_gstring_width (gstring, glyph->slice.cmp.from,
23364 glyph->slice.cmp.to + 1, &metrics);
23365 if (metrics.rbearing > metrics.width)
23366 *right = metrics.rbearing - metrics.width;
23367 if (metrics.lbearing < 0)
23368 *left = - metrics.lbearing;
23374 /* Return the index of the first glyph preceding glyph string S that
23375 is overwritten by S because of S's left overhang. Value is -1
23376 if no glyphs are overwritten. */
23378 static int
23379 left_overwritten (struct glyph_string *s)
23381 int k;
23383 if (s->left_overhang)
23385 int x = 0, i;
23386 struct glyph *glyphs = s->row->glyphs[s->area];
23387 int first = s->first_glyph - glyphs;
23389 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
23390 x -= glyphs[i].pixel_width;
23392 k = i + 1;
23394 else
23395 k = -1;
23397 return k;
23401 /* Return the index of the first glyph preceding glyph string S that
23402 is overwriting S because of its right overhang. Value is -1 if no
23403 glyph in front of S overwrites S. */
23405 static int
23406 left_overwriting (struct glyph_string *s)
23408 int i, k, x;
23409 struct glyph *glyphs = s->row->glyphs[s->area];
23410 int first = s->first_glyph - glyphs;
23412 k = -1;
23413 x = 0;
23414 for (i = first - 1; i >= 0; --i)
23416 int left, right;
23417 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
23418 if (x + right > 0)
23419 k = i;
23420 x -= glyphs[i].pixel_width;
23423 return k;
23427 /* Return the index of the last glyph following glyph string S that is
23428 overwritten by S because of S's right overhang. Value is -1 if
23429 no such glyph is found. */
23431 static int
23432 right_overwritten (struct glyph_string *s)
23434 int k = -1;
23436 if (s->right_overhang)
23438 int x = 0, i;
23439 struct glyph *glyphs = s->row->glyphs[s->area];
23440 int first = (s->first_glyph - glyphs
23441 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
23442 int end = s->row->used[s->area];
23444 for (i = first; i < end && s->right_overhang > x; ++i)
23445 x += glyphs[i].pixel_width;
23447 k = i;
23450 return k;
23454 /* Return the index of the last glyph following glyph string S that
23455 overwrites S because of its left overhang. Value is negative
23456 if no such glyph is found. */
23458 static int
23459 right_overwriting (struct glyph_string *s)
23461 int i, k, x;
23462 int end = s->row->used[s->area];
23463 struct glyph *glyphs = s->row->glyphs[s->area];
23464 int first = (s->first_glyph - glyphs
23465 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
23467 k = -1;
23468 x = 0;
23469 for (i = first; i < end; ++i)
23471 int left, right;
23472 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
23473 if (x - left < 0)
23474 k = i;
23475 x += glyphs[i].pixel_width;
23478 return k;
23482 /* Set background width of glyph string S. START is the index of the
23483 first glyph following S. LAST_X is the right-most x-position + 1
23484 in the drawing area. */
23486 static void
23487 set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
23489 /* If the face of this glyph string has to be drawn to the end of
23490 the drawing area, set S->extends_to_end_of_line_p. */
23492 if (start == s->row->used[s->area]
23493 && s->area == TEXT_AREA
23494 && ((s->row->fill_line_p
23495 && (s->hl == DRAW_NORMAL_TEXT
23496 || s->hl == DRAW_IMAGE_RAISED
23497 || s->hl == DRAW_IMAGE_SUNKEN))
23498 || s->hl == DRAW_MOUSE_FACE))
23499 s->extends_to_end_of_line_p = 1;
23501 /* If S extends its face to the end of the line, set its
23502 background_width to the distance to the right edge of the drawing
23503 area. */
23504 if (s->extends_to_end_of_line_p)
23505 s->background_width = last_x - s->x + 1;
23506 else
23507 s->background_width = s->width;
23511 /* Compute overhangs and x-positions for glyph string S and its
23512 predecessors, or successors. X is the starting x-position for S.
23513 BACKWARD_P non-zero means process predecessors. */
23515 static void
23516 compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
23518 if (backward_p)
23520 while (s)
23522 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
23523 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
23524 x -= s->width;
23525 s->x = x;
23526 s = s->prev;
23529 else
23531 while (s)
23533 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
23534 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
23535 s->x = x;
23536 x += s->width;
23537 s = s->next;
23544 /* The following macros are only called from draw_glyphs below.
23545 They reference the following parameters of that function directly:
23546 `w', `row', `area', and `overlap_p'
23547 as well as the following local variables:
23548 `s', `f', and `hdc' (in W32) */
23550 #ifdef HAVE_NTGUI
23551 /* On W32, silently add local `hdc' variable to argument list of
23552 init_glyph_string. */
23553 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
23554 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
23555 #else
23556 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
23557 init_glyph_string (s, char2b, w, row, area, start, hl)
23558 #endif
23560 /* Add a glyph string for a stretch glyph to the list of strings
23561 between HEAD and TAIL. START is the index of the stretch glyph in
23562 row area AREA of glyph row ROW. END is the index of the last glyph
23563 in that glyph row area. X is the current output position assigned
23564 to the new glyph string constructed. HL overrides that face of the
23565 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
23566 is the right-most x-position of the drawing area. */
23568 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
23569 and below -- keep them on one line. */
23570 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23571 do \
23573 s = alloca (sizeof *s); \
23574 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23575 START = fill_stretch_glyph_string (s, START, END); \
23576 append_glyph_string (&HEAD, &TAIL, s); \
23577 s->x = (X); \
23579 while (0)
23582 /* Add a glyph string for an image glyph to the list of strings
23583 between HEAD and TAIL. START is the index of the image glyph in
23584 row area AREA of glyph row ROW. END is the index of the last glyph
23585 in that glyph row area. X is the current output position assigned
23586 to the new glyph string constructed. HL overrides that face of the
23587 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
23588 is the right-most x-position of the drawing area. */
23590 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23591 do \
23593 s = alloca (sizeof *s); \
23594 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23595 fill_image_glyph_string (s); \
23596 append_glyph_string (&HEAD, &TAIL, s); \
23597 ++START; \
23598 s->x = (X); \
23600 while (0)
23603 /* Add a glyph string for a sequence of character glyphs to the list
23604 of strings between HEAD and TAIL. START is the index of the first
23605 glyph in row area AREA of glyph row ROW that is part of the new
23606 glyph string. END is the index of the last glyph in that glyph row
23607 area. X is the current output position assigned to the new glyph
23608 string constructed. HL overrides that face of the glyph; e.g. it
23609 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
23610 right-most x-position of the drawing area. */
23612 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
23613 do \
23615 int face_id; \
23616 XChar2b *char2b; \
23618 face_id = (row)->glyphs[area][START].face_id; \
23620 s = alloca (sizeof *s); \
23621 char2b = alloca ((END - START) * sizeof *char2b); \
23622 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23623 append_glyph_string (&HEAD, &TAIL, s); \
23624 s->x = (X); \
23625 START = fill_glyph_string (s, face_id, START, END, overlaps); \
23627 while (0)
23630 /* Add a glyph string for a composite sequence to the list of strings
23631 between HEAD and TAIL. START is the index of the first glyph in
23632 row area AREA of glyph row ROW that is part of the new glyph
23633 string. END is the index of the last glyph in that glyph row area.
23634 X is the current output position assigned to the new glyph string
23635 constructed. HL overrides that face of the glyph; e.g. it is
23636 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
23637 x-position of the drawing area. */
23639 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23640 do { \
23641 int face_id = (row)->glyphs[area][START].face_id; \
23642 struct face *base_face = FACE_FROM_ID (f, face_id); \
23643 ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \
23644 struct composition *cmp = composition_table[cmp_id]; \
23645 XChar2b *char2b; \
23646 struct glyph_string *first_s = NULL; \
23647 int n; \
23649 char2b = alloca (cmp->glyph_len * sizeof *char2b); \
23651 /* Make glyph_strings for each glyph sequence that is drawable by \
23652 the same face, and append them to HEAD/TAIL. */ \
23653 for (n = 0; n < cmp->glyph_len;) \
23655 s = alloca (sizeof *s); \
23656 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23657 append_glyph_string (&(HEAD), &(TAIL), s); \
23658 s->cmp = cmp; \
23659 s->cmp_from = n; \
23660 s->x = (X); \
23661 if (n == 0) \
23662 first_s = s; \
23663 n = fill_composite_glyph_string (s, base_face, overlaps); \
23666 ++START; \
23667 s = first_s; \
23668 } while (0)
23671 /* Add a glyph string for a glyph-string sequence to the list of strings
23672 between HEAD and TAIL. */
23674 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23675 do { \
23676 int face_id; \
23677 XChar2b *char2b; \
23678 Lisp_Object gstring; \
23680 face_id = (row)->glyphs[area][START].face_id; \
23681 gstring = (composition_gstring_from_id \
23682 ((row)->glyphs[area][START].u.cmp.id)); \
23683 s = alloca (sizeof *s); \
23684 char2b = alloca (LGSTRING_GLYPH_LEN (gstring) * sizeof *char2b); \
23685 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23686 append_glyph_string (&(HEAD), &(TAIL), s); \
23687 s->x = (X); \
23688 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
23689 } while (0)
23692 /* Add a glyph string for a sequence of glyphless character's glyphs
23693 to the list of strings between HEAD and TAIL. The meanings of
23694 arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */
23696 #define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23697 do \
23699 int face_id; \
23701 face_id = (row)->glyphs[area][START].face_id; \
23703 s = alloca (sizeof *s); \
23704 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23705 append_glyph_string (&HEAD, &TAIL, s); \
23706 s->x = (X); \
23707 START = fill_glyphless_glyph_string (s, face_id, START, END, \
23708 overlaps); \
23710 while (0)
23713 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
23714 of AREA of glyph row ROW on window W between indices START and END.
23715 HL overrides the face for drawing glyph strings, e.g. it is
23716 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
23717 x-positions of the drawing area.
23719 This is an ugly monster macro construct because we must use alloca
23720 to allocate glyph strings (because draw_glyphs can be called
23721 asynchronously). */
23723 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
23724 do \
23726 HEAD = TAIL = NULL; \
23727 while (START < END) \
23729 struct glyph *first_glyph = (row)->glyphs[area] + START; \
23730 switch (first_glyph->type) \
23732 case CHAR_GLYPH: \
23733 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
23734 HL, X, LAST_X); \
23735 break; \
23737 case COMPOSITE_GLYPH: \
23738 if (first_glyph->u.cmp.automatic) \
23739 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
23740 HL, X, LAST_X); \
23741 else \
23742 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
23743 HL, X, LAST_X); \
23744 break; \
23746 case STRETCH_GLYPH: \
23747 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
23748 HL, X, LAST_X); \
23749 break; \
23751 case IMAGE_GLYPH: \
23752 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
23753 HL, X, LAST_X); \
23754 break; \
23756 case GLYPHLESS_GLYPH: \
23757 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
23758 HL, X, LAST_X); \
23759 break; \
23761 default: \
23762 emacs_abort (); \
23765 if (s) \
23767 set_glyph_string_background_width (s, START, LAST_X); \
23768 (X) += s->width; \
23771 } while (0)
23774 /* Draw glyphs between START and END in AREA of ROW on window W,
23775 starting at x-position X. X is relative to AREA in W. HL is a
23776 face-override with the following meaning:
23778 DRAW_NORMAL_TEXT draw normally
23779 DRAW_CURSOR draw in cursor face
23780 DRAW_MOUSE_FACE draw in mouse face.
23781 DRAW_INVERSE_VIDEO draw in mode line face
23782 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
23783 DRAW_IMAGE_RAISED draw an image with a raised relief around it
23785 If OVERLAPS is non-zero, draw only the foreground of characters and
23786 clip to the physical height of ROW. Non-zero value also defines
23787 the overlapping part to be drawn:
23789 OVERLAPS_PRED overlap with preceding rows
23790 OVERLAPS_SUCC overlap with succeeding rows
23791 OVERLAPS_BOTH overlap with both preceding/succeeding rows
23792 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
23794 Value is the x-position reached, relative to AREA of W. */
23796 static int
23797 draw_glyphs (struct window *w, int x, struct glyph_row *row,
23798 enum glyph_row_area area, ptrdiff_t start, ptrdiff_t end,
23799 enum draw_glyphs_face hl, int overlaps)
23801 struct glyph_string *head, *tail;
23802 struct glyph_string *s;
23803 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
23804 int i, j, x_reached, last_x, area_left = 0;
23805 struct frame *f = XFRAME (WINDOW_FRAME (w));
23806 DECLARE_HDC (hdc);
23808 ALLOCATE_HDC (hdc, f);
23810 /* Let's rather be paranoid than getting a SEGV. */
23811 end = min (end, row->used[area]);
23812 start = clip_to_bounds (0, start, end);
23814 /* Translate X to frame coordinates. Set last_x to the right
23815 end of the drawing area. */
23816 if (row->full_width_p)
23818 /* X is relative to the left edge of W, without scroll bars
23819 or fringes. */
23820 area_left = WINDOW_LEFT_EDGE_X (w);
23821 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
23823 else
23825 area_left = window_box_left (w, area);
23826 last_x = area_left + window_box_width (w, area);
23828 x += area_left;
23830 /* Build a doubly-linked list of glyph_string structures between
23831 head and tail from what we have to draw. Note that the macro
23832 BUILD_GLYPH_STRINGS will modify its start parameter. That's
23833 the reason we use a separate variable `i'. */
23834 i = start;
23835 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
23836 if (tail)
23837 x_reached = tail->x + tail->background_width;
23838 else
23839 x_reached = x;
23841 /* If there are any glyphs with lbearing < 0 or rbearing > width in
23842 the row, redraw some glyphs in front or following the glyph
23843 strings built above. */
23844 if (head && !overlaps && row->contains_overlapping_glyphs_p)
23846 struct glyph_string *h, *t;
23847 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
23848 int mouse_beg_col IF_LINT (= 0), mouse_end_col IF_LINT (= 0);
23849 int check_mouse_face = 0;
23850 int dummy_x = 0;
23852 /* If mouse highlighting is on, we may need to draw adjacent
23853 glyphs using mouse-face highlighting. */
23854 if (area == TEXT_AREA && row->mouse_face_p
23855 && hlinfo->mouse_face_beg_row >= 0
23856 && hlinfo->mouse_face_end_row >= 0)
23858 ptrdiff_t row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
23860 if (row_vpos >= hlinfo->mouse_face_beg_row
23861 && row_vpos <= hlinfo->mouse_face_end_row)
23863 check_mouse_face = 1;
23864 mouse_beg_col = (row_vpos == hlinfo->mouse_face_beg_row)
23865 ? hlinfo->mouse_face_beg_col : 0;
23866 mouse_end_col = (row_vpos == hlinfo->mouse_face_end_row)
23867 ? hlinfo->mouse_face_end_col
23868 : row->used[TEXT_AREA];
23872 /* Compute overhangs for all glyph strings. */
23873 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
23874 for (s = head; s; s = s->next)
23875 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
23877 /* Prepend glyph strings for glyphs in front of the first glyph
23878 string that are overwritten because of the first glyph
23879 string's left overhang. The background of all strings
23880 prepended must be drawn because the first glyph string
23881 draws over it. */
23882 i = left_overwritten (head);
23883 if (i >= 0)
23885 enum draw_glyphs_face overlap_hl;
23887 /* If this row contains mouse highlighting, attempt to draw
23888 the overlapped glyphs with the correct highlight. This
23889 code fails if the overlap encompasses more than one glyph
23890 and mouse-highlight spans only some of these glyphs.
23891 However, making it work perfectly involves a lot more
23892 code, and I don't know if the pathological case occurs in
23893 practice, so we'll stick to this for now. --- cyd */
23894 if (check_mouse_face
23895 && mouse_beg_col < start && mouse_end_col > i)
23896 overlap_hl = DRAW_MOUSE_FACE;
23897 else
23898 overlap_hl = DRAW_NORMAL_TEXT;
23900 j = i;
23901 BUILD_GLYPH_STRINGS (j, start, h, t,
23902 overlap_hl, dummy_x, last_x);
23903 start = i;
23904 compute_overhangs_and_x (t, head->x, 1);
23905 prepend_glyph_string_lists (&head, &tail, h, t);
23906 clip_head = head;
23909 /* Prepend glyph strings for glyphs in front of the first glyph
23910 string that overwrite that glyph string because of their
23911 right overhang. For these strings, only the foreground must
23912 be drawn, because it draws over the glyph string at `head'.
23913 The background must not be drawn because this would overwrite
23914 right overhangs of preceding glyphs for which no glyph
23915 strings exist. */
23916 i = left_overwriting (head);
23917 if (i >= 0)
23919 enum draw_glyphs_face overlap_hl;
23921 if (check_mouse_face
23922 && mouse_beg_col < start && mouse_end_col > i)
23923 overlap_hl = DRAW_MOUSE_FACE;
23924 else
23925 overlap_hl = DRAW_NORMAL_TEXT;
23927 clip_head = head;
23928 BUILD_GLYPH_STRINGS (i, start, h, t,
23929 overlap_hl, dummy_x, last_x);
23930 for (s = h; s; s = s->next)
23931 s->background_filled_p = 1;
23932 compute_overhangs_and_x (t, head->x, 1);
23933 prepend_glyph_string_lists (&head, &tail, h, t);
23936 /* Append glyphs strings for glyphs following the last glyph
23937 string tail that are overwritten by tail. The background of
23938 these strings has to be drawn because tail's foreground draws
23939 over it. */
23940 i = right_overwritten (tail);
23941 if (i >= 0)
23943 enum draw_glyphs_face overlap_hl;
23945 if (check_mouse_face
23946 && mouse_beg_col < i && mouse_end_col > end)
23947 overlap_hl = DRAW_MOUSE_FACE;
23948 else
23949 overlap_hl = DRAW_NORMAL_TEXT;
23951 BUILD_GLYPH_STRINGS (end, i, h, t,
23952 overlap_hl, x, last_x);
23953 /* Because BUILD_GLYPH_STRINGS updates the first argument,
23954 we don't have `end = i;' here. */
23955 compute_overhangs_and_x (h, tail->x + tail->width, 0);
23956 append_glyph_string_lists (&head, &tail, h, t);
23957 clip_tail = tail;
23960 /* Append glyph strings for glyphs following the last glyph
23961 string tail that overwrite tail. The foreground of such
23962 glyphs has to be drawn because it writes into the background
23963 of tail. The background must not be drawn because it could
23964 paint over the foreground of following glyphs. */
23965 i = right_overwriting (tail);
23966 if (i >= 0)
23968 enum draw_glyphs_face overlap_hl;
23969 if (check_mouse_face
23970 && mouse_beg_col < i && mouse_end_col > end)
23971 overlap_hl = DRAW_MOUSE_FACE;
23972 else
23973 overlap_hl = DRAW_NORMAL_TEXT;
23975 clip_tail = tail;
23976 i++; /* We must include the Ith glyph. */
23977 BUILD_GLYPH_STRINGS (end, i, h, t,
23978 overlap_hl, x, last_x);
23979 for (s = h; s; s = s->next)
23980 s->background_filled_p = 1;
23981 compute_overhangs_and_x (h, tail->x + tail->width, 0);
23982 append_glyph_string_lists (&head, &tail, h, t);
23984 if (clip_head || clip_tail)
23985 for (s = head; s; s = s->next)
23987 s->clip_head = clip_head;
23988 s->clip_tail = clip_tail;
23992 /* Draw all strings. */
23993 for (s = head; s; s = s->next)
23994 FRAME_RIF (f)->draw_glyph_string (s);
23996 #ifndef HAVE_NS
23997 /* When focus a sole frame and move horizontally, this sets on_p to 0
23998 causing a failure to erase prev cursor position. */
23999 if (area == TEXT_AREA
24000 && !row->full_width_p
24001 /* When drawing overlapping rows, only the glyph strings'
24002 foreground is drawn, which doesn't erase a cursor
24003 completely. */
24004 && !overlaps)
24006 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
24007 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
24008 : (tail ? tail->x + tail->background_width : x));
24009 x0 -= area_left;
24010 x1 -= area_left;
24012 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
24013 row->y, MATRIX_ROW_BOTTOM_Y (row));
24015 #endif
24017 /* Value is the x-position up to which drawn, relative to AREA of W.
24018 This doesn't include parts drawn because of overhangs. */
24019 if (row->full_width_p)
24020 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
24021 else
24022 x_reached -= area_left;
24024 RELEASE_HDC (hdc, f);
24026 return x_reached;
24029 /* Expand row matrix if too narrow. Don't expand if area
24030 is not present. */
24032 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
24034 if (!fonts_changed_p \
24035 && (it->glyph_row->glyphs[area] \
24036 < it->glyph_row->glyphs[area + 1])) \
24038 it->w->ncols_scale_factor++; \
24039 fonts_changed_p = 1; \
24043 /* Store one glyph for IT->char_to_display in IT->glyph_row.
24044 Called from x_produce_glyphs when IT->glyph_row is non-null. */
24046 static void
24047 append_glyph (struct it *it)
24049 struct glyph *glyph;
24050 enum glyph_row_area area = it->area;
24052 eassert (it->glyph_row);
24053 eassert (it->char_to_display != '\n' && it->char_to_display != '\t');
24055 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24056 if (glyph < it->glyph_row->glyphs[area + 1])
24058 /* If the glyph row is reversed, we need to prepend the glyph
24059 rather than append it. */
24060 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24062 struct glyph *g;
24064 /* Make room for the additional glyph. */
24065 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
24066 g[1] = *g;
24067 glyph = it->glyph_row->glyphs[area];
24069 glyph->charpos = CHARPOS (it->position);
24070 glyph->object = it->object;
24071 if (it->pixel_width > 0)
24073 glyph->pixel_width = it->pixel_width;
24074 glyph->padding_p = 0;
24076 else
24078 /* Assure at least 1-pixel width. Otherwise, cursor can't
24079 be displayed correctly. */
24080 glyph->pixel_width = 1;
24081 glyph->padding_p = 1;
24083 glyph->ascent = it->ascent;
24084 glyph->descent = it->descent;
24085 glyph->voffset = it->voffset;
24086 glyph->type = CHAR_GLYPH;
24087 glyph->avoid_cursor_p = it->avoid_cursor_p;
24088 glyph->multibyte_p = it->multibyte_p;
24089 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24091 /* In R2L rows, the left and the right box edges need to be
24092 drawn in reverse direction. */
24093 glyph->right_box_line_p = it->start_of_box_run_p;
24094 glyph->left_box_line_p = it->end_of_box_run_p;
24096 else
24098 glyph->left_box_line_p = it->start_of_box_run_p;
24099 glyph->right_box_line_p = it->end_of_box_run_p;
24101 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
24102 || it->phys_descent > it->descent);
24103 glyph->glyph_not_available_p = it->glyph_not_available_p;
24104 glyph->face_id = it->face_id;
24105 glyph->u.ch = it->char_to_display;
24106 glyph->slice.img = null_glyph_slice;
24107 glyph->font_type = FONT_TYPE_UNKNOWN;
24108 if (it->bidi_p)
24110 glyph->resolved_level = it->bidi_it.resolved_level;
24111 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24112 emacs_abort ();
24113 glyph->bidi_type = it->bidi_it.type;
24115 else
24117 glyph->resolved_level = 0;
24118 glyph->bidi_type = UNKNOWN_BT;
24120 ++it->glyph_row->used[area];
24122 else
24123 IT_EXPAND_MATRIX_WIDTH (it, area);
24126 /* Store one glyph for the composition IT->cmp_it.id in
24127 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
24128 non-null. */
24130 static void
24131 append_composite_glyph (struct it *it)
24133 struct glyph *glyph;
24134 enum glyph_row_area area = it->area;
24136 eassert (it->glyph_row);
24138 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24139 if (glyph < it->glyph_row->glyphs[area + 1])
24141 /* If the glyph row is reversed, we need to prepend the glyph
24142 rather than append it. */
24143 if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
24145 struct glyph *g;
24147 /* Make room for the new glyph. */
24148 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
24149 g[1] = *g;
24150 glyph = it->glyph_row->glyphs[it->area];
24152 glyph->charpos = it->cmp_it.charpos;
24153 glyph->object = it->object;
24154 glyph->pixel_width = it->pixel_width;
24155 glyph->ascent = it->ascent;
24156 glyph->descent = it->descent;
24157 glyph->voffset = it->voffset;
24158 glyph->type = COMPOSITE_GLYPH;
24159 if (it->cmp_it.ch < 0)
24161 glyph->u.cmp.automatic = 0;
24162 glyph->u.cmp.id = it->cmp_it.id;
24163 glyph->slice.cmp.from = glyph->slice.cmp.to = 0;
24165 else
24167 glyph->u.cmp.automatic = 1;
24168 glyph->u.cmp.id = it->cmp_it.id;
24169 glyph->slice.cmp.from = it->cmp_it.from;
24170 glyph->slice.cmp.to = it->cmp_it.to - 1;
24172 glyph->avoid_cursor_p = it->avoid_cursor_p;
24173 glyph->multibyte_p = it->multibyte_p;
24174 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24176 /* In R2L rows, the left and the right box edges need to be
24177 drawn in reverse direction. */
24178 glyph->right_box_line_p = it->start_of_box_run_p;
24179 glyph->left_box_line_p = it->end_of_box_run_p;
24181 else
24183 glyph->left_box_line_p = it->start_of_box_run_p;
24184 glyph->right_box_line_p = it->end_of_box_run_p;
24186 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
24187 || it->phys_descent > it->descent);
24188 glyph->padding_p = 0;
24189 glyph->glyph_not_available_p = 0;
24190 glyph->face_id = it->face_id;
24191 glyph->font_type = FONT_TYPE_UNKNOWN;
24192 if (it->bidi_p)
24194 glyph->resolved_level = it->bidi_it.resolved_level;
24195 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24196 emacs_abort ();
24197 glyph->bidi_type = it->bidi_it.type;
24199 ++it->glyph_row->used[area];
24201 else
24202 IT_EXPAND_MATRIX_WIDTH (it, area);
24206 /* Change IT->ascent and IT->height according to the setting of
24207 IT->voffset. */
24209 static void
24210 take_vertical_position_into_account (struct it *it)
24212 if (it->voffset)
24214 if (it->voffset < 0)
24215 /* Increase the ascent so that we can display the text higher
24216 in the line. */
24217 it->ascent -= it->voffset;
24218 else
24219 /* Increase the descent so that we can display the text lower
24220 in the line. */
24221 it->descent += it->voffset;
24226 /* Produce glyphs/get display metrics for the image IT is loaded with.
24227 See the description of struct display_iterator in dispextern.h for
24228 an overview of struct display_iterator. */
24230 static void
24231 produce_image_glyph (struct it *it)
24233 struct image *img;
24234 struct face *face;
24235 int glyph_ascent, crop;
24236 struct glyph_slice slice;
24238 eassert (it->what == IT_IMAGE);
24240 face = FACE_FROM_ID (it->f, it->face_id);
24241 eassert (face);
24242 /* Make sure X resources of the face is loaded. */
24243 PREPARE_FACE_FOR_DISPLAY (it->f, face);
24245 if (it->image_id < 0)
24247 /* Fringe bitmap. */
24248 it->ascent = it->phys_ascent = 0;
24249 it->descent = it->phys_descent = 0;
24250 it->pixel_width = 0;
24251 it->nglyphs = 0;
24252 return;
24255 img = IMAGE_FROM_ID (it->f, it->image_id);
24256 eassert (img);
24257 /* Make sure X resources of the image is loaded. */
24258 prepare_image_for_display (it->f, img);
24260 slice.x = slice.y = 0;
24261 slice.width = img->width;
24262 slice.height = img->height;
24264 if (INTEGERP (it->slice.x))
24265 slice.x = XINT (it->slice.x);
24266 else if (FLOATP (it->slice.x))
24267 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
24269 if (INTEGERP (it->slice.y))
24270 slice.y = XINT (it->slice.y);
24271 else if (FLOATP (it->slice.y))
24272 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
24274 if (INTEGERP (it->slice.width))
24275 slice.width = XINT (it->slice.width);
24276 else if (FLOATP (it->slice.width))
24277 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
24279 if (INTEGERP (it->slice.height))
24280 slice.height = XINT (it->slice.height);
24281 else if (FLOATP (it->slice.height))
24282 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
24284 if (slice.x >= img->width)
24285 slice.x = img->width;
24286 if (slice.y >= img->height)
24287 slice.y = img->height;
24288 if (slice.x + slice.width >= img->width)
24289 slice.width = img->width - slice.x;
24290 if (slice.y + slice.height > img->height)
24291 slice.height = img->height - slice.y;
24293 if (slice.width == 0 || slice.height == 0)
24294 return;
24296 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
24298 it->descent = slice.height - glyph_ascent;
24299 if (slice.y == 0)
24300 it->descent += img->vmargin;
24301 if (slice.y + slice.height == img->height)
24302 it->descent += img->vmargin;
24303 it->phys_descent = it->descent;
24305 it->pixel_width = slice.width;
24306 if (slice.x == 0)
24307 it->pixel_width += img->hmargin;
24308 if (slice.x + slice.width == img->width)
24309 it->pixel_width += img->hmargin;
24311 /* It's quite possible for images to have an ascent greater than
24312 their height, so don't get confused in that case. */
24313 if (it->descent < 0)
24314 it->descent = 0;
24316 it->nglyphs = 1;
24318 if (face->box != FACE_NO_BOX)
24320 if (face->box_line_width > 0)
24322 if (slice.y == 0)
24323 it->ascent += face->box_line_width;
24324 if (slice.y + slice.height == img->height)
24325 it->descent += face->box_line_width;
24328 if (it->start_of_box_run_p && slice.x == 0)
24329 it->pixel_width += eabs (face->box_line_width);
24330 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
24331 it->pixel_width += eabs (face->box_line_width);
24334 take_vertical_position_into_account (it);
24336 /* Automatically crop wide image glyphs at right edge so we can
24337 draw the cursor on same display row. */
24338 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
24339 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
24341 it->pixel_width -= crop;
24342 slice.width -= crop;
24345 if (it->glyph_row)
24347 struct glyph *glyph;
24348 enum glyph_row_area area = it->area;
24350 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24351 if (glyph < it->glyph_row->glyphs[area + 1])
24353 glyph->charpos = CHARPOS (it->position);
24354 glyph->object = it->object;
24355 glyph->pixel_width = it->pixel_width;
24356 glyph->ascent = glyph_ascent;
24357 glyph->descent = it->descent;
24358 glyph->voffset = it->voffset;
24359 glyph->type = IMAGE_GLYPH;
24360 glyph->avoid_cursor_p = it->avoid_cursor_p;
24361 glyph->multibyte_p = it->multibyte_p;
24362 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24364 /* In R2L rows, the left and the right box edges need to be
24365 drawn in reverse direction. */
24366 glyph->right_box_line_p = it->start_of_box_run_p;
24367 glyph->left_box_line_p = it->end_of_box_run_p;
24369 else
24371 glyph->left_box_line_p = it->start_of_box_run_p;
24372 glyph->right_box_line_p = it->end_of_box_run_p;
24374 glyph->overlaps_vertically_p = 0;
24375 glyph->padding_p = 0;
24376 glyph->glyph_not_available_p = 0;
24377 glyph->face_id = it->face_id;
24378 glyph->u.img_id = img->id;
24379 glyph->slice.img = slice;
24380 glyph->font_type = FONT_TYPE_UNKNOWN;
24381 if (it->bidi_p)
24383 glyph->resolved_level = it->bidi_it.resolved_level;
24384 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24385 emacs_abort ();
24386 glyph->bidi_type = it->bidi_it.type;
24388 ++it->glyph_row->used[area];
24390 else
24391 IT_EXPAND_MATRIX_WIDTH (it, area);
24396 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
24397 of the glyph, WIDTH and HEIGHT are the width and height of the
24398 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
24400 static void
24401 append_stretch_glyph (struct it *it, Lisp_Object object,
24402 int width, int height, int ascent)
24404 struct glyph *glyph;
24405 enum glyph_row_area area = it->area;
24407 eassert (ascent >= 0 && ascent <= height);
24409 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24410 if (glyph < it->glyph_row->glyphs[area + 1])
24412 /* If the glyph row is reversed, we need to prepend the glyph
24413 rather than append it. */
24414 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24416 struct glyph *g;
24418 /* Make room for the additional glyph. */
24419 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
24420 g[1] = *g;
24421 glyph = it->glyph_row->glyphs[area];
24423 glyph->charpos = CHARPOS (it->position);
24424 glyph->object = object;
24425 glyph->pixel_width = width;
24426 glyph->ascent = ascent;
24427 glyph->descent = height - ascent;
24428 glyph->voffset = it->voffset;
24429 glyph->type = STRETCH_GLYPH;
24430 glyph->avoid_cursor_p = it->avoid_cursor_p;
24431 glyph->multibyte_p = it->multibyte_p;
24432 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24434 /* In R2L rows, the left and the right box edges need to be
24435 drawn in reverse direction. */
24436 glyph->right_box_line_p = it->start_of_box_run_p;
24437 glyph->left_box_line_p = it->end_of_box_run_p;
24439 else
24441 glyph->left_box_line_p = it->start_of_box_run_p;
24442 glyph->right_box_line_p = it->end_of_box_run_p;
24444 glyph->overlaps_vertically_p = 0;
24445 glyph->padding_p = 0;
24446 glyph->glyph_not_available_p = 0;
24447 glyph->face_id = it->face_id;
24448 glyph->u.stretch.ascent = ascent;
24449 glyph->u.stretch.height = height;
24450 glyph->slice.img = null_glyph_slice;
24451 glyph->font_type = FONT_TYPE_UNKNOWN;
24452 if (it->bidi_p)
24454 glyph->resolved_level = it->bidi_it.resolved_level;
24455 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24456 emacs_abort ();
24457 glyph->bidi_type = it->bidi_it.type;
24459 else
24461 glyph->resolved_level = 0;
24462 glyph->bidi_type = UNKNOWN_BT;
24464 ++it->glyph_row->used[area];
24466 else
24467 IT_EXPAND_MATRIX_WIDTH (it, area);
24470 #endif /* HAVE_WINDOW_SYSTEM */
24472 /* Produce a stretch glyph for iterator IT. IT->object is the value
24473 of the glyph property displayed. The value must be a list
24474 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
24475 being recognized:
24477 1. `:width WIDTH' specifies that the space should be WIDTH *
24478 canonical char width wide. WIDTH may be an integer or floating
24479 point number.
24481 2. `:relative-width FACTOR' specifies that the width of the stretch
24482 should be computed from the width of the first character having the
24483 `glyph' property, and should be FACTOR times that width.
24485 3. `:align-to HPOS' specifies that the space should be wide enough
24486 to reach HPOS, a value in canonical character units.
24488 Exactly one of the above pairs must be present.
24490 4. `:height HEIGHT' specifies that the height of the stretch produced
24491 should be HEIGHT, measured in canonical character units.
24493 5. `:relative-height FACTOR' specifies that the height of the
24494 stretch should be FACTOR times the height of the characters having
24495 the glyph property.
24497 Either none or exactly one of 4 or 5 must be present.
24499 6. `:ascent ASCENT' specifies that ASCENT percent of the height
24500 of the stretch should be used for the ascent of the stretch.
24501 ASCENT must be in the range 0 <= ASCENT <= 100. */
24503 void
24504 produce_stretch_glyph (struct it *it)
24506 /* (space :width WIDTH :height HEIGHT ...) */
24507 Lisp_Object prop, plist;
24508 int width = 0, height = 0, align_to = -1;
24509 int zero_width_ok_p = 0;
24510 double tem;
24511 struct font *font = NULL;
24513 #ifdef HAVE_WINDOW_SYSTEM
24514 int ascent = 0;
24515 int zero_height_ok_p = 0;
24517 if (FRAME_WINDOW_P (it->f))
24519 struct face *face = FACE_FROM_ID (it->f, it->face_id);
24520 font = face->font ? face->font : FRAME_FONT (it->f);
24521 PREPARE_FACE_FOR_DISPLAY (it->f, face);
24523 #endif
24525 /* List should start with `space'. */
24526 eassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
24527 plist = XCDR (it->object);
24529 /* Compute the width of the stretch. */
24530 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
24531 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
24533 /* Absolute width `:width WIDTH' specified and valid. */
24534 zero_width_ok_p = 1;
24535 width = (int)tem;
24537 #ifdef HAVE_WINDOW_SYSTEM
24538 else if (FRAME_WINDOW_P (it->f)
24539 && (prop = Fplist_get (plist, QCrelative_width), NUMVAL (prop) > 0))
24541 /* Relative width `:relative-width FACTOR' specified and valid.
24542 Compute the width of the characters having the `glyph'
24543 property. */
24544 struct it it2;
24545 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
24547 it2 = *it;
24548 if (it->multibyte_p)
24549 it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
24550 else
24552 it2.c = it2.char_to_display = *p, it2.len = 1;
24553 if (! ASCII_CHAR_P (it2.c))
24554 it2.char_to_display = BYTE8_TO_CHAR (it2.c);
24557 it2.glyph_row = NULL;
24558 it2.what = IT_CHARACTER;
24559 x_produce_glyphs (&it2);
24560 width = NUMVAL (prop) * it2.pixel_width;
24562 #endif /* HAVE_WINDOW_SYSTEM */
24563 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
24564 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
24566 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
24567 align_to = (align_to < 0
24569 : align_to - window_box_left_offset (it->w, TEXT_AREA));
24570 else if (align_to < 0)
24571 align_to = window_box_left_offset (it->w, TEXT_AREA);
24572 width = max (0, (int)tem + align_to - it->current_x);
24573 zero_width_ok_p = 1;
24575 else
24576 /* Nothing specified -> width defaults to canonical char width. */
24577 width = FRAME_COLUMN_WIDTH (it->f);
24579 if (width <= 0 && (width < 0 || !zero_width_ok_p))
24580 width = 1;
24582 #ifdef HAVE_WINDOW_SYSTEM
24583 /* Compute height. */
24584 if (FRAME_WINDOW_P (it->f))
24586 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
24587 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
24589 height = (int)tem;
24590 zero_height_ok_p = 1;
24592 else if (prop = Fplist_get (plist, QCrelative_height),
24593 NUMVAL (prop) > 0)
24594 height = FONT_HEIGHT (font) * NUMVAL (prop);
24595 else
24596 height = FONT_HEIGHT (font);
24598 if (height <= 0 && (height < 0 || !zero_height_ok_p))
24599 height = 1;
24601 /* Compute percentage of height used for ascent. If
24602 `:ascent ASCENT' is present and valid, use that. Otherwise,
24603 derive the ascent from the font in use. */
24604 if (prop = Fplist_get (plist, QCascent),
24605 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
24606 ascent = height * NUMVAL (prop) / 100.0;
24607 else if (!NILP (prop)
24608 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
24609 ascent = min (max (0, (int)tem), height);
24610 else
24611 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
24613 else
24614 #endif /* HAVE_WINDOW_SYSTEM */
24615 height = 1;
24617 if (width > 0 && it->line_wrap != TRUNCATE
24618 && it->current_x + width > it->last_visible_x)
24620 width = it->last_visible_x - it->current_x;
24621 #ifdef HAVE_WINDOW_SYSTEM
24622 /* Subtract one more pixel from the stretch width, but only on
24623 GUI frames, since on a TTY each glyph is one "pixel" wide. */
24624 width -= FRAME_WINDOW_P (it->f);
24625 #endif
24628 if (width > 0 && height > 0 && it->glyph_row)
24630 Lisp_Object o_object = it->object;
24631 Lisp_Object object = it->stack[it->sp - 1].string;
24632 int n = width;
24634 if (!STRINGP (object))
24635 object = it->w->contents;
24636 #ifdef HAVE_WINDOW_SYSTEM
24637 if (FRAME_WINDOW_P (it->f))
24638 append_stretch_glyph (it, object, width, height, ascent);
24639 else
24640 #endif
24642 it->object = object;
24643 it->char_to_display = ' ';
24644 it->pixel_width = it->len = 1;
24645 while (n--)
24646 tty_append_glyph (it);
24647 it->object = o_object;
24651 it->pixel_width = width;
24652 #ifdef HAVE_WINDOW_SYSTEM
24653 if (FRAME_WINDOW_P (it->f))
24655 it->ascent = it->phys_ascent = ascent;
24656 it->descent = it->phys_descent = height - it->ascent;
24657 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
24658 take_vertical_position_into_account (it);
24660 else
24661 #endif
24662 it->nglyphs = width;
24665 /* Get information about special display element WHAT in an
24666 environment described by IT. WHAT is one of IT_TRUNCATION or
24667 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
24668 non-null glyph_row member. This function ensures that fields like
24669 face_id, c, len of IT are left untouched. */
24671 static void
24672 produce_special_glyphs (struct it *it, enum display_element_type what)
24674 struct it temp_it;
24675 Lisp_Object gc;
24676 GLYPH glyph;
24678 temp_it = *it;
24679 temp_it.object = make_number (0);
24680 memset (&temp_it.current, 0, sizeof temp_it.current);
24682 if (what == IT_CONTINUATION)
24684 /* Continuation glyph. For R2L lines, we mirror it by hand. */
24685 if (it->bidi_it.paragraph_dir == R2L)
24686 SET_GLYPH_FROM_CHAR (glyph, '/');
24687 else
24688 SET_GLYPH_FROM_CHAR (glyph, '\\');
24689 if (it->dp
24690 && (gc = DISP_CONTINUE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
24692 /* FIXME: Should we mirror GC for R2L lines? */
24693 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
24694 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
24697 else if (what == IT_TRUNCATION)
24699 /* Truncation glyph. */
24700 SET_GLYPH_FROM_CHAR (glyph, '$');
24701 if (it->dp
24702 && (gc = DISP_TRUNC_GLYPH (it->dp), GLYPH_CODE_P (gc)))
24704 /* FIXME: Should we mirror GC for R2L lines? */
24705 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
24706 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
24709 else
24710 emacs_abort ();
24712 #ifdef HAVE_WINDOW_SYSTEM
24713 /* On a GUI frame, when the right fringe (left fringe for R2L rows)
24714 is turned off, we precede the truncation/continuation glyphs by a
24715 stretch glyph whose width is computed such that these special
24716 glyphs are aligned at the window margin, even when very different
24717 fonts are used in different glyph rows. */
24718 if (FRAME_WINDOW_P (temp_it.f)
24719 /* init_iterator calls this with it->glyph_row == NULL, and it
24720 wants only the pixel width of the truncation/continuation
24721 glyphs. */
24722 && temp_it.glyph_row
24723 /* insert_left_trunc_glyphs calls us at the beginning of the
24724 row, and it has its own calculation of the stretch glyph
24725 width. */
24726 && temp_it.glyph_row->used[TEXT_AREA] > 0
24727 && (temp_it.glyph_row->reversed_p
24728 ? WINDOW_LEFT_FRINGE_WIDTH (temp_it.w)
24729 : WINDOW_RIGHT_FRINGE_WIDTH (temp_it.w)) == 0)
24731 int stretch_width = temp_it.last_visible_x - temp_it.current_x;
24733 if (stretch_width > 0)
24735 struct face *face = FACE_FROM_ID (temp_it.f, temp_it.face_id);
24736 struct font *font =
24737 face->font ? face->font : FRAME_FONT (temp_it.f);
24738 int stretch_ascent =
24739 (((temp_it.ascent + temp_it.descent)
24740 * FONT_BASE (font)) / FONT_HEIGHT (font));
24742 append_stretch_glyph (&temp_it, make_number (0), stretch_width,
24743 temp_it.ascent + temp_it.descent,
24744 stretch_ascent);
24747 #endif
24749 temp_it.dp = NULL;
24750 temp_it.what = IT_CHARACTER;
24751 temp_it.len = 1;
24752 temp_it.c = temp_it.char_to_display = GLYPH_CHAR (glyph);
24753 temp_it.face_id = GLYPH_FACE (glyph);
24754 temp_it.len = CHAR_BYTES (temp_it.c);
24756 PRODUCE_GLYPHS (&temp_it);
24757 it->pixel_width = temp_it.pixel_width;
24758 it->nglyphs = temp_it.pixel_width;
24761 #ifdef HAVE_WINDOW_SYSTEM
24763 /* Calculate line-height and line-spacing properties.
24764 An integer value specifies explicit pixel value.
24765 A float value specifies relative value to current face height.
24766 A cons (float . face-name) specifies relative value to
24767 height of specified face font.
24769 Returns height in pixels, or nil. */
24772 static Lisp_Object
24773 calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
24774 int boff, int override)
24776 Lisp_Object face_name = Qnil;
24777 int ascent, descent, height;
24779 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
24780 return val;
24782 if (CONSP (val))
24784 face_name = XCAR (val);
24785 val = XCDR (val);
24786 if (!NUMBERP (val))
24787 val = make_number (1);
24788 if (NILP (face_name))
24790 height = it->ascent + it->descent;
24791 goto scale;
24795 if (NILP (face_name))
24797 font = FRAME_FONT (it->f);
24798 boff = FRAME_BASELINE_OFFSET (it->f);
24800 else if (EQ (face_name, Qt))
24802 override = 0;
24804 else
24806 int face_id;
24807 struct face *face;
24809 face_id = lookup_named_face (it->f, face_name, 0);
24810 if (face_id < 0)
24811 return make_number (-1);
24813 face = FACE_FROM_ID (it->f, face_id);
24814 font = face->font;
24815 if (font == NULL)
24816 return make_number (-1);
24817 boff = font->baseline_offset;
24818 if (font->vertical_centering)
24819 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
24822 ascent = FONT_BASE (font) + boff;
24823 descent = FONT_DESCENT (font) - boff;
24825 if (override)
24827 it->override_ascent = ascent;
24828 it->override_descent = descent;
24829 it->override_boff = boff;
24832 height = ascent + descent;
24834 scale:
24835 if (FLOATP (val))
24836 height = (int)(XFLOAT_DATA (val) * height);
24837 else if (INTEGERP (val))
24838 height *= XINT (val);
24840 return make_number (height);
24844 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
24845 is a face ID to be used for the glyph. FOR_NO_FONT is nonzero if
24846 and only if this is for a character for which no font was found.
24848 If the display method (it->glyphless_method) is
24849 GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
24850 length of the acronym or the hexadecimal string, UPPER_XOFF and
24851 UPPER_YOFF are pixel offsets for the upper part of the string,
24852 LOWER_XOFF and LOWER_YOFF are for the lower part.
24854 For the other display methods, LEN through LOWER_YOFF are zero. */
24856 static void
24857 append_glyphless_glyph (struct it *it, int face_id, int for_no_font, int len,
24858 short upper_xoff, short upper_yoff,
24859 short lower_xoff, short lower_yoff)
24861 struct glyph *glyph;
24862 enum glyph_row_area area = it->area;
24864 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24865 if (glyph < it->glyph_row->glyphs[area + 1])
24867 /* If the glyph row is reversed, we need to prepend the glyph
24868 rather than append it. */
24869 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24871 struct glyph *g;
24873 /* Make room for the additional glyph. */
24874 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
24875 g[1] = *g;
24876 glyph = it->glyph_row->glyphs[area];
24878 glyph->charpos = CHARPOS (it->position);
24879 glyph->object = it->object;
24880 glyph->pixel_width = it->pixel_width;
24881 glyph->ascent = it->ascent;
24882 glyph->descent = it->descent;
24883 glyph->voffset = it->voffset;
24884 glyph->type = GLYPHLESS_GLYPH;
24885 glyph->u.glyphless.method = it->glyphless_method;
24886 glyph->u.glyphless.for_no_font = for_no_font;
24887 glyph->u.glyphless.len = len;
24888 glyph->u.glyphless.ch = it->c;
24889 glyph->slice.glyphless.upper_xoff = upper_xoff;
24890 glyph->slice.glyphless.upper_yoff = upper_yoff;
24891 glyph->slice.glyphless.lower_xoff = lower_xoff;
24892 glyph->slice.glyphless.lower_yoff = lower_yoff;
24893 glyph->avoid_cursor_p = it->avoid_cursor_p;
24894 glyph->multibyte_p = it->multibyte_p;
24895 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24897 /* In R2L rows, the left and the right box edges need to be
24898 drawn in reverse direction. */
24899 glyph->right_box_line_p = it->start_of_box_run_p;
24900 glyph->left_box_line_p = it->end_of_box_run_p;
24902 else
24904 glyph->left_box_line_p = it->start_of_box_run_p;
24905 glyph->right_box_line_p = it->end_of_box_run_p;
24907 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
24908 || it->phys_descent > it->descent);
24909 glyph->padding_p = 0;
24910 glyph->glyph_not_available_p = 0;
24911 glyph->face_id = face_id;
24912 glyph->font_type = FONT_TYPE_UNKNOWN;
24913 if (it->bidi_p)
24915 glyph->resolved_level = it->bidi_it.resolved_level;
24916 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24917 emacs_abort ();
24918 glyph->bidi_type = it->bidi_it.type;
24920 ++it->glyph_row->used[area];
24922 else
24923 IT_EXPAND_MATRIX_WIDTH (it, area);
24927 /* Produce a glyph for a glyphless character for iterator IT.
24928 IT->glyphless_method specifies which method to use for displaying
24929 the character. See the description of enum
24930 glyphless_display_method in dispextern.h for the detail.
24932 FOR_NO_FONT is nonzero if and only if this is for a character for
24933 which no font was found. ACRONYM, if non-nil, is an acronym string
24934 for the character. */
24936 static void
24937 produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
24939 int face_id;
24940 struct face *face;
24941 struct font *font;
24942 int base_width, base_height, width, height;
24943 short upper_xoff, upper_yoff, lower_xoff, lower_yoff;
24944 int len;
24946 /* Get the metrics of the base font. We always refer to the current
24947 ASCII face. */
24948 face = FACE_FROM_ID (it->f, it->face_id)->ascii_face;
24949 font = face->font ? face->font : FRAME_FONT (it->f);
24950 it->ascent = FONT_BASE (font) + font->baseline_offset;
24951 it->descent = FONT_DESCENT (font) - font->baseline_offset;
24952 base_height = it->ascent + it->descent;
24953 base_width = font->average_width;
24955 /* Get a face ID for the glyph by utilizing a cache (the same way as
24956 done for `escape-glyph' in get_next_display_element). */
24957 if (it->f == last_glyphless_glyph_frame
24958 && it->face_id == last_glyphless_glyph_face_id)
24960 face_id = last_glyphless_glyph_merged_face_id;
24962 else
24964 /* Merge the `glyphless-char' face into the current face. */
24965 face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
24966 last_glyphless_glyph_frame = it->f;
24967 last_glyphless_glyph_face_id = it->face_id;
24968 last_glyphless_glyph_merged_face_id = face_id;
24971 if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
24973 it->pixel_width = THIN_SPACE_WIDTH;
24974 len = 0;
24975 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
24977 else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX)
24979 width = CHAR_WIDTH (it->c);
24980 if (width == 0)
24981 width = 1;
24982 else if (width > 4)
24983 width = 4;
24984 it->pixel_width = base_width * width;
24985 len = 0;
24986 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
24988 else
24990 char buf[7];
24991 const char *str;
24992 unsigned int code[6];
24993 int upper_len;
24994 int ascent, descent;
24995 struct font_metrics metrics_upper, metrics_lower;
24997 face = FACE_FROM_ID (it->f, face_id);
24998 font = face->font ? face->font : FRAME_FONT (it->f);
24999 PREPARE_FACE_FOR_DISPLAY (it->f, face);
25001 if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM)
25003 if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
25004 acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
25005 if (CONSP (acronym))
25006 acronym = XCAR (acronym);
25007 str = STRINGP (acronym) ? SSDATA (acronym) : "";
25009 else
25011 eassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
25012 sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c);
25013 str = buf;
25015 for (len = 0; str[len] && ASCII_BYTE_P (str[len]) && len < 6; len++)
25016 code[len] = font->driver->encode_char (font, str[len]);
25017 upper_len = (len + 1) / 2;
25018 font->driver->text_extents (font, code, upper_len,
25019 &metrics_upper);
25020 font->driver->text_extents (font, code + upper_len, len - upper_len,
25021 &metrics_lower);
25025 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
25026 width = max (metrics_upper.width, metrics_lower.width) + 4;
25027 upper_xoff = upper_yoff = 2; /* the typical case */
25028 if (base_width >= width)
25030 /* Align the upper to the left, the lower to the right. */
25031 it->pixel_width = base_width;
25032 lower_xoff = base_width - 2 - metrics_lower.width;
25034 else
25036 /* Center the shorter one. */
25037 it->pixel_width = width;
25038 if (metrics_upper.width >= metrics_lower.width)
25039 lower_xoff = (width - metrics_lower.width) / 2;
25040 else
25042 /* FIXME: This code doesn't look right. It formerly was
25043 missing the "lower_xoff = 0;", which couldn't have
25044 been right since it left lower_xoff uninitialized. */
25045 lower_xoff = 0;
25046 upper_xoff = (width - metrics_upper.width) / 2;
25050 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
25051 top, bottom, and between upper and lower strings. */
25052 height = (metrics_upper.ascent + metrics_upper.descent
25053 + metrics_lower.ascent + metrics_lower.descent) + 5;
25054 /* Center vertically.
25055 H:base_height, D:base_descent
25056 h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent
25058 ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up
25059 descent = D - H/2 + h/2;
25060 lower_yoff = descent - 2 - ld;
25061 upper_yoff = lower_yoff - la - 1 - ud; */
25062 ascent = - (it->descent - (base_height + height + 1) / 2);
25063 descent = it->descent - (base_height - height) / 2;
25064 lower_yoff = descent - 2 - metrics_lower.descent;
25065 upper_yoff = (lower_yoff - metrics_lower.ascent - 1
25066 - metrics_upper.descent);
25067 /* Don't make the height shorter than the base height. */
25068 if (height > base_height)
25070 it->ascent = ascent;
25071 it->descent = descent;
25075 it->phys_ascent = it->ascent;
25076 it->phys_descent = it->descent;
25077 if (it->glyph_row)
25078 append_glyphless_glyph (it, face_id, for_no_font, len,
25079 upper_xoff, upper_yoff,
25080 lower_xoff, lower_yoff);
25081 it->nglyphs = 1;
25082 take_vertical_position_into_account (it);
25086 /* RIF:
25087 Produce glyphs/get display metrics for the display element IT is
25088 loaded with. See the description of struct it in dispextern.h
25089 for an overview of struct it. */
25091 void
25092 x_produce_glyphs (struct it *it)
25094 int extra_line_spacing = it->extra_line_spacing;
25096 it->glyph_not_available_p = 0;
25098 if (it->what == IT_CHARACTER)
25100 XChar2b char2b;
25101 struct face *face = FACE_FROM_ID (it->f, it->face_id);
25102 struct font *font = face->font;
25103 struct font_metrics *pcm = NULL;
25104 int boff; /* baseline offset */
25106 if (font == NULL)
25108 /* When no suitable font is found, display this character by
25109 the method specified in the first extra slot of
25110 Vglyphless_char_display. */
25111 Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
25113 eassert (it->what == IT_GLYPHLESS);
25114 produce_glyphless_glyph (it, 1, STRINGP (acronym) ? acronym : Qnil);
25115 goto done;
25118 boff = font->baseline_offset;
25119 if (font->vertical_centering)
25120 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
25122 if (it->char_to_display != '\n' && it->char_to_display != '\t')
25124 int stretched_p;
25126 it->nglyphs = 1;
25128 if (it->override_ascent >= 0)
25130 it->ascent = it->override_ascent;
25131 it->descent = it->override_descent;
25132 boff = it->override_boff;
25134 else
25136 it->ascent = FONT_BASE (font) + boff;
25137 it->descent = FONT_DESCENT (font) - boff;
25140 if (get_char_glyph_code (it->char_to_display, font, &char2b))
25142 pcm = get_per_char_metric (font, &char2b);
25143 if (pcm->width == 0
25144 && pcm->rbearing == 0 && pcm->lbearing == 0)
25145 pcm = NULL;
25148 if (pcm)
25150 it->phys_ascent = pcm->ascent + boff;
25151 it->phys_descent = pcm->descent - boff;
25152 it->pixel_width = pcm->width;
25154 else
25156 it->glyph_not_available_p = 1;
25157 it->phys_ascent = it->ascent;
25158 it->phys_descent = it->descent;
25159 it->pixel_width = font->space_width;
25162 if (it->constrain_row_ascent_descent_p)
25164 if (it->descent > it->max_descent)
25166 it->ascent += it->descent - it->max_descent;
25167 it->descent = it->max_descent;
25169 if (it->ascent > it->max_ascent)
25171 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
25172 it->ascent = it->max_ascent;
25174 it->phys_ascent = min (it->phys_ascent, it->ascent);
25175 it->phys_descent = min (it->phys_descent, it->descent);
25176 extra_line_spacing = 0;
25179 /* If this is a space inside a region of text with
25180 `space-width' property, change its width. */
25181 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
25182 if (stretched_p)
25183 it->pixel_width *= XFLOATINT (it->space_width);
25185 /* If face has a box, add the box thickness to the character
25186 height. If character has a box line to the left and/or
25187 right, add the box line width to the character's width. */
25188 if (face->box != FACE_NO_BOX)
25190 int thick = face->box_line_width;
25192 if (thick > 0)
25194 it->ascent += thick;
25195 it->descent += thick;
25197 else
25198 thick = -thick;
25200 if (it->start_of_box_run_p)
25201 it->pixel_width += thick;
25202 if (it->end_of_box_run_p)
25203 it->pixel_width += thick;
25206 /* If face has an overline, add the height of the overline
25207 (1 pixel) and a 1 pixel margin to the character height. */
25208 if (face->overline_p)
25209 it->ascent += overline_margin;
25211 if (it->constrain_row_ascent_descent_p)
25213 if (it->ascent > it->max_ascent)
25214 it->ascent = it->max_ascent;
25215 if (it->descent > it->max_descent)
25216 it->descent = it->max_descent;
25219 take_vertical_position_into_account (it);
25221 /* If we have to actually produce glyphs, do it. */
25222 if (it->glyph_row)
25224 if (stretched_p)
25226 /* Translate a space with a `space-width' property
25227 into a stretch glyph. */
25228 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
25229 / FONT_HEIGHT (font));
25230 append_stretch_glyph (it, it->object, it->pixel_width,
25231 it->ascent + it->descent, ascent);
25233 else
25234 append_glyph (it);
25236 /* If characters with lbearing or rbearing are displayed
25237 in this line, record that fact in a flag of the
25238 glyph row. This is used to optimize X output code. */
25239 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
25240 it->glyph_row->contains_overlapping_glyphs_p = 1;
25242 if (! stretched_p && it->pixel_width == 0)
25243 /* We assure that all visible glyphs have at least 1-pixel
25244 width. */
25245 it->pixel_width = 1;
25247 else if (it->char_to_display == '\n')
25249 /* A newline has no width, but we need the height of the
25250 line. But if previous part of the line sets a height,
25251 don't increase that height */
25253 Lisp_Object height;
25254 Lisp_Object total_height = Qnil;
25256 it->override_ascent = -1;
25257 it->pixel_width = 0;
25258 it->nglyphs = 0;
25260 height = get_it_property (it, Qline_height);
25261 /* Split (line-height total-height) list */
25262 if (CONSP (height)
25263 && CONSP (XCDR (height))
25264 && NILP (XCDR (XCDR (height))))
25266 total_height = XCAR (XCDR (height));
25267 height = XCAR (height);
25269 height = calc_line_height_property (it, height, font, boff, 1);
25271 if (it->override_ascent >= 0)
25273 it->ascent = it->override_ascent;
25274 it->descent = it->override_descent;
25275 boff = it->override_boff;
25277 else
25279 it->ascent = FONT_BASE (font) + boff;
25280 it->descent = FONT_DESCENT (font) - boff;
25283 if (EQ (height, Qt))
25285 if (it->descent > it->max_descent)
25287 it->ascent += it->descent - it->max_descent;
25288 it->descent = it->max_descent;
25290 if (it->ascent > it->max_ascent)
25292 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
25293 it->ascent = it->max_ascent;
25295 it->phys_ascent = min (it->phys_ascent, it->ascent);
25296 it->phys_descent = min (it->phys_descent, it->descent);
25297 it->constrain_row_ascent_descent_p = 1;
25298 extra_line_spacing = 0;
25300 else
25302 Lisp_Object spacing;
25304 it->phys_ascent = it->ascent;
25305 it->phys_descent = it->descent;
25307 if ((it->max_ascent > 0 || it->max_descent > 0)
25308 && face->box != FACE_NO_BOX
25309 && face->box_line_width > 0)
25311 it->ascent += face->box_line_width;
25312 it->descent += face->box_line_width;
25314 if (!NILP (height)
25315 && XINT (height) > it->ascent + it->descent)
25316 it->ascent = XINT (height) - it->descent;
25318 if (!NILP (total_height))
25319 spacing = calc_line_height_property (it, total_height, font, boff, 0);
25320 else
25322 spacing = get_it_property (it, Qline_spacing);
25323 spacing = calc_line_height_property (it, spacing, font, boff, 0);
25325 if (INTEGERP (spacing))
25327 extra_line_spacing = XINT (spacing);
25328 if (!NILP (total_height))
25329 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
25333 else /* i.e. (it->char_to_display == '\t') */
25335 if (font->space_width > 0)
25337 int tab_width = it->tab_width * font->space_width;
25338 int x = it->current_x + it->continuation_lines_width;
25339 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
25341 /* If the distance from the current position to the next tab
25342 stop is less than a space character width, use the
25343 tab stop after that. */
25344 if (next_tab_x - x < font->space_width)
25345 next_tab_x += tab_width;
25347 it->pixel_width = next_tab_x - x;
25348 it->nglyphs = 1;
25349 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
25350 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
25352 if (it->glyph_row)
25354 append_stretch_glyph (it, it->object, it->pixel_width,
25355 it->ascent + it->descent, it->ascent);
25358 else
25360 it->pixel_width = 0;
25361 it->nglyphs = 1;
25365 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
25367 /* A static composition.
25369 Note: A composition is represented as one glyph in the
25370 glyph matrix. There are no padding glyphs.
25372 Important note: pixel_width, ascent, and descent are the
25373 values of what is drawn by draw_glyphs (i.e. the values of
25374 the overall glyphs composed). */
25375 struct face *face = FACE_FROM_ID (it->f, it->face_id);
25376 int boff; /* baseline offset */
25377 struct composition *cmp = composition_table[it->cmp_it.id];
25378 int glyph_len = cmp->glyph_len;
25379 struct font *font = face->font;
25381 it->nglyphs = 1;
25383 /* If we have not yet calculated pixel size data of glyphs of
25384 the composition for the current face font, calculate them
25385 now. Theoretically, we have to check all fonts for the
25386 glyphs, but that requires much time and memory space. So,
25387 here we check only the font of the first glyph. This may
25388 lead to incorrect display, but it's very rare, and C-l
25389 (recenter-top-bottom) can correct the display anyway. */
25390 if (! cmp->font || cmp->font != font)
25392 /* Ascent and descent of the font of the first character
25393 of this composition (adjusted by baseline offset).
25394 Ascent and descent of overall glyphs should not be less
25395 than these, respectively. */
25396 int font_ascent, font_descent, font_height;
25397 /* Bounding box of the overall glyphs. */
25398 int leftmost, rightmost, lowest, highest;
25399 int lbearing, rbearing;
25400 int i, width, ascent, descent;
25401 int left_padded = 0, right_padded = 0;
25402 int c IF_LINT (= 0); /* cmp->glyph_len can't be zero; see Bug#8512 */
25403 XChar2b char2b;
25404 struct font_metrics *pcm;
25405 int font_not_found_p;
25406 ptrdiff_t pos;
25408 for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
25409 if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
25410 break;
25411 if (glyph_len < cmp->glyph_len)
25412 right_padded = 1;
25413 for (i = 0; i < glyph_len; i++)
25415 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
25416 break;
25417 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
25419 if (i > 0)
25420 left_padded = 1;
25422 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
25423 : IT_CHARPOS (*it));
25424 /* If no suitable font is found, use the default font. */
25425 font_not_found_p = font == NULL;
25426 if (font_not_found_p)
25428 face = face->ascii_face;
25429 font = face->font;
25431 boff = font->baseline_offset;
25432 if (font->vertical_centering)
25433 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
25434 font_ascent = FONT_BASE (font) + boff;
25435 font_descent = FONT_DESCENT (font) - boff;
25436 font_height = FONT_HEIGHT (font);
25438 cmp->font = font;
25440 pcm = NULL;
25441 if (! font_not_found_p)
25443 get_char_face_and_encoding (it->f, c, it->face_id,
25444 &char2b, 0);
25445 pcm = get_per_char_metric (font, &char2b);
25448 /* Initialize the bounding box. */
25449 if (pcm)
25451 width = cmp->glyph_len > 0 ? pcm->width : 0;
25452 ascent = pcm->ascent;
25453 descent = pcm->descent;
25454 lbearing = pcm->lbearing;
25455 rbearing = pcm->rbearing;
25457 else
25459 width = cmp->glyph_len > 0 ? font->space_width : 0;
25460 ascent = FONT_BASE (font);
25461 descent = FONT_DESCENT (font);
25462 lbearing = 0;
25463 rbearing = width;
25466 rightmost = width;
25467 leftmost = 0;
25468 lowest = - descent + boff;
25469 highest = ascent + boff;
25471 if (! font_not_found_p
25472 && font->default_ascent
25473 && CHAR_TABLE_P (Vuse_default_ascent)
25474 && !NILP (Faref (Vuse_default_ascent,
25475 make_number (it->char_to_display))))
25476 highest = font->default_ascent + boff;
25478 /* Draw the first glyph at the normal position. It may be
25479 shifted to right later if some other glyphs are drawn
25480 at the left. */
25481 cmp->offsets[i * 2] = 0;
25482 cmp->offsets[i * 2 + 1] = boff;
25483 cmp->lbearing = lbearing;
25484 cmp->rbearing = rbearing;
25486 /* Set cmp->offsets for the remaining glyphs. */
25487 for (i++; i < glyph_len; i++)
25489 int left, right, btm, top;
25490 int ch = COMPOSITION_GLYPH (cmp, i);
25491 int face_id;
25492 struct face *this_face;
25494 if (ch == '\t')
25495 ch = ' ';
25496 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
25497 this_face = FACE_FROM_ID (it->f, face_id);
25498 font = this_face->font;
25500 if (font == NULL)
25501 pcm = NULL;
25502 else
25504 get_char_face_and_encoding (it->f, ch, face_id,
25505 &char2b, 0);
25506 pcm = get_per_char_metric (font, &char2b);
25508 if (! pcm)
25509 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
25510 else
25512 width = pcm->width;
25513 ascent = pcm->ascent;
25514 descent = pcm->descent;
25515 lbearing = pcm->lbearing;
25516 rbearing = pcm->rbearing;
25517 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
25519 /* Relative composition with or without
25520 alternate chars. */
25521 left = (leftmost + rightmost - width) / 2;
25522 btm = - descent + boff;
25523 if (font->relative_compose
25524 && (! CHAR_TABLE_P (Vignore_relative_composition)
25525 || NILP (Faref (Vignore_relative_composition,
25526 make_number (ch)))))
25529 if (- descent >= font->relative_compose)
25530 /* One extra pixel between two glyphs. */
25531 btm = highest + 1;
25532 else if (ascent <= 0)
25533 /* One extra pixel between two glyphs. */
25534 btm = lowest - 1 - ascent - descent;
25537 else
25539 /* A composition rule is specified by an integer
25540 value that encodes global and new reference
25541 points (GREF and NREF). GREF and NREF are
25542 specified by numbers as below:
25544 0---1---2 -- ascent
25548 9--10--11 -- center
25550 ---3---4---5--- baseline
25552 6---7---8 -- descent
25554 int rule = COMPOSITION_RULE (cmp, i);
25555 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
25557 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
25558 grefx = gref % 3, nrefx = nref % 3;
25559 grefy = gref / 3, nrefy = nref / 3;
25560 if (xoff)
25561 xoff = font_height * (xoff - 128) / 256;
25562 if (yoff)
25563 yoff = font_height * (yoff - 128) / 256;
25565 left = (leftmost
25566 + grefx * (rightmost - leftmost) / 2
25567 - nrefx * width / 2
25568 + xoff);
25570 btm = ((grefy == 0 ? highest
25571 : grefy == 1 ? 0
25572 : grefy == 2 ? lowest
25573 : (highest + lowest) / 2)
25574 - (nrefy == 0 ? ascent + descent
25575 : nrefy == 1 ? descent - boff
25576 : nrefy == 2 ? 0
25577 : (ascent + descent) / 2)
25578 + yoff);
25581 cmp->offsets[i * 2] = left;
25582 cmp->offsets[i * 2 + 1] = btm + descent;
25584 /* Update the bounding box of the overall glyphs. */
25585 if (width > 0)
25587 right = left + width;
25588 if (left < leftmost)
25589 leftmost = left;
25590 if (right > rightmost)
25591 rightmost = right;
25593 top = btm + descent + ascent;
25594 if (top > highest)
25595 highest = top;
25596 if (btm < lowest)
25597 lowest = btm;
25599 if (cmp->lbearing > left + lbearing)
25600 cmp->lbearing = left + lbearing;
25601 if (cmp->rbearing < left + rbearing)
25602 cmp->rbearing = left + rbearing;
25606 /* If there are glyphs whose x-offsets are negative,
25607 shift all glyphs to the right and make all x-offsets
25608 non-negative. */
25609 if (leftmost < 0)
25611 for (i = 0; i < cmp->glyph_len; i++)
25612 cmp->offsets[i * 2] -= leftmost;
25613 rightmost -= leftmost;
25614 cmp->lbearing -= leftmost;
25615 cmp->rbearing -= leftmost;
25618 if (left_padded && cmp->lbearing < 0)
25620 for (i = 0; i < cmp->glyph_len; i++)
25621 cmp->offsets[i * 2] -= cmp->lbearing;
25622 rightmost -= cmp->lbearing;
25623 cmp->rbearing -= cmp->lbearing;
25624 cmp->lbearing = 0;
25626 if (right_padded && rightmost < cmp->rbearing)
25628 rightmost = cmp->rbearing;
25631 cmp->pixel_width = rightmost;
25632 cmp->ascent = highest;
25633 cmp->descent = - lowest;
25634 if (cmp->ascent < font_ascent)
25635 cmp->ascent = font_ascent;
25636 if (cmp->descent < font_descent)
25637 cmp->descent = font_descent;
25640 if (it->glyph_row
25641 && (cmp->lbearing < 0
25642 || cmp->rbearing > cmp->pixel_width))
25643 it->glyph_row->contains_overlapping_glyphs_p = 1;
25645 it->pixel_width = cmp->pixel_width;
25646 it->ascent = it->phys_ascent = cmp->ascent;
25647 it->descent = it->phys_descent = cmp->descent;
25648 if (face->box != FACE_NO_BOX)
25650 int thick = face->box_line_width;
25652 if (thick > 0)
25654 it->ascent += thick;
25655 it->descent += thick;
25657 else
25658 thick = - thick;
25660 if (it->start_of_box_run_p)
25661 it->pixel_width += thick;
25662 if (it->end_of_box_run_p)
25663 it->pixel_width += thick;
25666 /* If face has an overline, add the height of the overline
25667 (1 pixel) and a 1 pixel margin to the character height. */
25668 if (face->overline_p)
25669 it->ascent += overline_margin;
25671 take_vertical_position_into_account (it);
25672 if (it->ascent < 0)
25673 it->ascent = 0;
25674 if (it->descent < 0)
25675 it->descent = 0;
25677 if (it->glyph_row && cmp->glyph_len > 0)
25678 append_composite_glyph (it);
25680 else if (it->what == IT_COMPOSITION)
25682 /* A dynamic (automatic) composition. */
25683 struct face *face = FACE_FROM_ID (it->f, it->face_id);
25684 Lisp_Object gstring;
25685 struct font_metrics metrics;
25687 it->nglyphs = 1;
25689 gstring = composition_gstring_from_id (it->cmp_it.id);
25690 it->pixel_width
25691 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
25692 &metrics);
25693 if (it->glyph_row
25694 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
25695 it->glyph_row->contains_overlapping_glyphs_p = 1;
25696 it->ascent = it->phys_ascent = metrics.ascent;
25697 it->descent = it->phys_descent = metrics.descent;
25698 if (face->box != FACE_NO_BOX)
25700 int thick = face->box_line_width;
25702 if (thick > 0)
25704 it->ascent += thick;
25705 it->descent += thick;
25707 else
25708 thick = - thick;
25710 if (it->start_of_box_run_p)
25711 it->pixel_width += thick;
25712 if (it->end_of_box_run_p)
25713 it->pixel_width += thick;
25715 /* If face has an overline, add the height of the overline
25716 (1 pixel) and a 1 pixel margin to the character height. */
25717 if (face->overline_p)
25718 it->ascent += overline_margin;
25719 take_vertical_position_into_account (it);
25720 if (it->ascent < 0)
25721 it->ascent = 0;
25722 if (it->descent < 0)
25723 it->descent = 0;
25725 if (it->glyph_row)
25726 append_composite_glyph (it);
25728 else if (it->what == IT_GLYPHLESS)
25729 produce_glyphless_glyph (it, 0, Qnil);
25730 else if (it->what == IT_IMAGE)
25731 produce_image_glyph (it);
25732 else if (it->what == IT_STRETCH)
25733 produce_stretch_glyph (it);
25735 done:
25736 /* Accumulate dimensions. Note: can't assume that it->descent > 0
25737 because this isn't true for images with `:ascent 100'. */
25738 eassert (it->ascent >= 0 && it->descent >= 0);
25739 if (it->area == TEXT_AREA)
25740 it->current_x += it->pixel_width;
25742 if (extra_line_spacing > 0)
25744 it->descent += extra_line_spacing;
25745 if (extra_line_spacing > it->max_extra_line_spacing)
25746 it->max_extra_line_spacing = extra_line_spacing;
25749 it->max_ascent = max (it->max_ascent, it->ascent);
25750 it->max_descent = max (it->max_descent, it->descent);
25751 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
25752 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
25755 /* EXPORT for RIF:
25756 Output LEN glyphs starting at START at the nominal cursor position.
25757 Advance the nominal cursor over the text. The global variable
25758 updated_row is the glyph row being updated, and updated_area is the
25759 area of that row being updated. */
25761 void
25762 x_write_glyphs (struct window *w, struct glyph *start, int len)
25764 int x, hpos, chpos = w->phys_cursor.hpos;
25766 eassert (updated_row);
25767 /* When the window is hscrolled, cursor hpos can legitimately be out
25768 of bounds, but we draw the cursor at the corresponding window
25769 margin in that case. */
25770 if (!updated_row->reversed_p && chpos < 0)
25771 chpos = 0;
25772 if (updated_row->reversed_p && chpos >= updated_row->used[TEXT_AREA])
25773 chpos = updated_row->used[TEXT_AREA] - 1;
25775 block_input ();
25777 /* Write glyphs. */
25779 hpos = start - updated_row->glyphs[updated_area];
25780 x = draw_glyphs (w, output_cursor.x,
25781 updated_row, updated_area,
25782 hpos, hpos + len,
25783 DRAW_NORMAL_TEXT, 0);
25785 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
25786 if (updated_area == TEXT_AREA
25787 && w->phys_cursor_on_p
25788 && w->phys_cursor.vpos == output_cursor.vpos
25789 && chpos >= hpos
25790 && chpos < hpos + len)
25791 w->phys_cursor_on_p = 0;
25793 unblock_input ();
25795 /* Advance the output cursor. */
25796 output_cursor.hpos += len;
25797 output_cursor.x = x;
25801 /* EXPORT for RIF:
25802 Insert LEN glyphs from START at the nominal cursor position. */
25804 void
25805 x_insert_glyphs (struct window *w, struct glyph *start, int len)
25807 struct frame *f;
25808 int line_height, shift_by_width, shifted_region_width;
25809 struct glyph_row *row;
25810 struct glyph *glyph;
25811 int frame_x, frame_y;
25812 ptrdiff_t hpos;
25814 eassert (updated_row);
25815 block_input ();
25816 f = XFRAME (WINDOW_FRAME (w));
25818 /* Get the height of the line we are in. */
25819 row = updated_row;
25820 line_height = row->height;
25822 /* Get the width of the glyphs to insert. */
25823 shift_by_width = 0;
25824 for (glyph = start; glyph < start + len; ++glyph)
25825 shift_by_width += glyph->pixel_width;
25827 /* Get the width of the region to shift right. */
25828 shifted_region_width = (window_box_width (w, updated_area)
25829 - output_cursor.x
25830 - shift_by_width);
25832 /* Shift right. */
25833 frame_x = window_box_left (w, updated_area) + output_cursor.x;
25834 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
25836 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
25837 line_height, shift_by_width);
25839 /* Write the glyphs. */
25840 hpos = start - row->glyphs[updated_area];
25841 draw_glyphs (w, output_cursor.x, row, updated_area,
25842 hpos, hpos + len,
25843 DRAW_NORMAL_TEXT, 0);
25845 /* Advance the output cursor. */
25846 output_cursor.hpos += len;
25847 output_cursor.x += shift_by_width;
25848 unblock_input ();
25852 /* EXPORT for RIF:
25853 Erase the current text line from the nominal cursor position
25854 (inclusive) to pixel column TO_X (exclusive). The idea is that
25855 everything from TO_X onward is already erased.
25857 TO_X is a pixel position relative to updated_area of currently
25858 updated window W. TO_X == -1 means clear to the end of this area. */
25860 void
25861 x_clear_end_of_line (struct window *w, int to_x)
25863 struct frame *f;
25864 int max_x, min_y, max_y;
25865 int from_x, from_y, to_y;
25867 eassert (updated_row);
25868 f = XFRAME (w->frame);
25870 if (updated_row->full_width_p)
25871 max_x = WINDOW_TOTAL_WIDTH (w);
25872 else
25873 max_x = window_box_width (w, updated_area);
25874 max_y = window_text_bottom_y (w);
25876 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
25877 of window. For TO_X > 0, truncate to end of drawing area. */
25878 if (to_x == 0)
25879 return;
25880 else if (to_x < 0)
25881 to_x = max_x;
25882 else
25883 to_x = min (to_x, max_x);
25885 to_y = min (max_y, output_cursor.y + updated_row->height);
25887 /* Notice if the cursor will be cleared by this operation. */
25888 if (!updated_row->full_width_p)
25889 notice_overwritten_cursor (w, updated_area,
25890 output_cursor.x, -1,
25891 updated_row->y,
25892 MATRIX_ROW_BOTTOM_Y (updated_row));
25894 from_x = output_cursor.x;
25896 /* Translate to frame coordinates. */
25897 if (updated_row->full_width_p)
25899 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
25900 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
25902 else
25904 int area_left = window_box_left (w, updated_area);
25905 from_x += area_left;
25906 to_x += area_left;
25909 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
25910 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
25911 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
25913 /* Prevent inadvertently clearing to end of the X window. */
25914 if (to_x > from_x && to_y > from_y)
25916 block_input ();
25917 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
25918 to_x - from_x, to_y - from_y);
25919 unblock_input ();
25923 #endif /* HAVE_WINDOW_SYSTEM */
25927 /***********************************************************************
25928 Cursor types
25929 ***********************************************************************/
25931 /* Value is the internal representation of the specified cursor type
25932 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
25933 of the bar cursor. */
25935 static enum text_cursor_kinds
25936 get_specified_cursor_type (Lisp_Object arg, int *width)
25938 enum text_cursor_kinds type;
25940 if (NILP (arg))
25941 return NO_CURSOR;
25943 if (EQ (arg, Qbox))
25944 return FILLED_BOX_CURSOR;
25946 if (EQ (arg, Qhollow))
25947 return HOLLOW_BOX_CURSOR;
25949 if (EQ (arg, Qbar))
25951 *width = 2;
25952 return BAR_CURSOR;
25955 if (CONSP (arg)
25956 && EQ (XCAR (arg), Qbar)
25957 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
25959 *width = XINT (XCDR (arg));
25960 return BAR_CURSOR;
25963 if (EQ (arg, Qhbar))
25965 *width = 2;
25966 return HBAR_CURSOR;
25969 if (CONSP (arg)
25970 && EQ (XCAR (arg), Qhbar)
25971 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
25973 *width = XINT (XCDR (arg));
25974 return HBAR_CURSOR;
25977 /* Treat anything unknown as "hollow box cursor".
25978 It was bad to signal an error; people have trouble fixing
25979 .Xdefaults with Emacs, when it has something bad in it. */
25980 type = HOLLOW_BOX_CURSOR;
25982 return type;
25985 /* Set the default cursor types for specified frame. */
25986 void
25987 set_frame_cursor_types (struct frame *f, Lisp_Object arg)
25989 int width = 1;
25990 Lisp_Object tem;
25992 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
25993 FRAME_CURSOR_WIDTH (f) = width;
25995 /* By default, set up the blink-off state depending on the on-state. */
25997 tem = Fassoc (arg, Vblink_cursor_alist);
25998 if (!NILP (tem))
26000 FRAME_BLINK_OFF_CURSOR (f)
26001 = get_specified_cursor_type (XCDR (tem), &width);
26002 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
26004 else
26005 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
26009 #ifdef HAVE_WINDOW_SYSTEM
26011 /* Return the cursor we want to be displayed in window W. Return
26012 width of bar/hbar cursor through WIDTH arg. Return with
26013 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
26014 (i.e. if the `system caret' should track this cursor).
26016 In a mini-buffer window, we want the cursor only to appear if we
26017 are reading input from this window. For the selected window, we
26018 want the cursor type given by the frame parameter or buffer local
26019 setting of cursor-type. If explicitly marked off, draw no cursor.
26020 In all other cases, we want a hollow box cursor. */
26022 static enum text_cursor_kinds
26023 get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
26024 int *active_cursor)
26026 struct frame *f = XFRAME (w->frame);
26027 struct buffer *b = XBUFFER (w->contents);
26028 int cursor_type = DEFAULT_CURSOR;
26029 Lisp_Object alt_cursor;
26030 int non_selected = 0;
26032 *active_cursor = 1;
26034 /* Echo area */
26035 if (cursor_in_echo_area
26036 && FRAME_HAS_MINIBUF_P (f)
26037 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
26039 if (w == XWINDOW (echo_area_window))
26041 if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
26043 *width = FRAME_CURSOR_WIDTH (f);
26044 return FRAME_DESIRED_CURSOR (f);
26046 else
26047 return get_specified_cursor_type (BVAR (b, cursor_type), width);
26050 *active_cursor = 0;
26051 non_selected = 1;
26054 /* Detect a nonselected window or nonselected frame. */
26055 else if (w != XWINDOW (f->selected_window)
26056 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame)
26058 *active_cursor = 0;
26060 if (MINI_WINDOW_P (w) && minibuf_level == 0)
26061 return NO_CURSOR;
26063 non_selected = 1;
26066 /* Never display a cursor in a window in which cursor-type is nil. */
26067 if (NILP (BVAR (b, cursor_type)))
26068 return NO_CURSOR;
26070 /* Get the normal cursor type for this window. */
26071 if (EQ (BVAR (b, cursor_type), Qt))
26073 cursor_type = FRAME_DESIRED_CURSOR (f);
26074 *width = FRAME_CURSOR_WIDTH (f);
26076 else
26077 cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
26079 /* Use cursor-in-non-selected-windows instead
26080 for non-selected window or frame. */
26081 if (non_selected)
26083 alt_cursor = BVAR (b, cursor_in_non_selected_windows);
26084 if (!EQ (Qt, alt_cursor))
26085 return get_specified_cursor_type (alt_cursor, width);
26086 /* t means modify the normal cursor type. */
26087 if (cursor_type == FILLED_BOX_CURSOR)
26088 cursor_type = HOLLOW_BOX_CURSOR;
26089 else if (cursor_type == BAR_CURSOR && *width > 1)
26090 --*width;
26091 return cursor_type;
26094 /* Use normal cursor if not blinked off. */
26095 if (!w->cursor_off_p)
26097 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
26099 if (cursor_type == FILLED_BOX_CURSOR)
26101 /* Using a block cursor on large images can be very annoying.
26102 So use a hollow cursor for "large" images.
26103 If image is not transparent (no mask), also use hollow cursor. */
26104 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
26105 if (img != NULL && IMAGEP (img->spec))
26107 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
26108 where N = size of default frame font size.
26109 This should cover most of the "tiny" icons people may use. */
26110 if (!img->mask
26111 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
26112 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
26113 cursor_type = HOLLOW_BOX_CURSOR;
26116 else if (cursor_type != NO_CURSOR)
26118 /* Display current only supports BOX and HOLLOW cursors for images.
26119 So for now, unconditionally use a HOLLOW cursor when cursor is
26120 not a solid box cursor. */
26121 cursor_type = HOLLOW_BOX_CURSOR;
26124 return cursor_type;
26127 /* Cursor is blinked off, so determine how to "toggle" it. */
26129 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
26130 if ((alt_cursor = Fassoc (BVAR (b, cursor_type), Vblink_cursor_alist), !NILP (alt_cursor)))
26131 return get_specified_cursor_type (XCDR (alt_cursor), width);
26133 /* Then see if frame has specified a specific blink off cursor type. */
26134 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
26136 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
26137 return FRAME_BLINK_OFF_CURSOR (f);
26140 #if 0
26141 /* Some people liked having a permanently visible blinking cursor,
26142 while others had very strong opinions against it. So it was
26143 decided to remove it. KFS 2003-09-03 */
26145 /* Finally perform built-in cursor blinking:
26146 filled box <-> hollow box
26147 wide [h]bar <-> narrow [h]bar
26148 narrow [h]bar <-> no cursor
26149 other type <-> no cursor */
26151 if (cursor_type == FILLED_BOX_CURSOR)
26152 return HOLLOW_BOX_CURSOR;
26154 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
26156 *width = 1;
26157 return cursor_type;
26159 #endif
26161 return NO_CURSOR;
26165 /* Notice when the text cursor of window W has been completely
26166 overwritten by a drawing operation that outputs glyphs in AREA
26167 starting at X0 and ending at X1 in the line starting at Y0 and
26168 ending at Y1. X coordinates are area-relative. X1 < 0 means all
26169 the rest of the line after X0 has been written. Y coordinates
26170 are window-relative. */
26172 static void
26173 notice_overwritten_cursor (struct window *w, enum glyph_row_area area,
26174 int x0, int x1, int y0, int y1)
26176 int cx0, cx1, cy0, cy1;
26177 struct glyph_row *row;
26179 if (!w->phys_cursor_on_p)
26180 return;
26181 if (area != TEXT_AREA)
26182 return;
26184 if (w->phys_cursor.vpos < 0
26185 || w->phys_cursor.vpos >= w->current_matrix->nrows
26186 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
26187 !(row->enabled_p && MATRIX_ROW_DISPLAYS_TEXT_P (row))))
26188 return;
26190 if (row->cursor_in_fringe_p)
26192 row->cursor_in_fringe_p = 0;
26193 draw_fringe_bitmap (w, row, row->reversed_p);
26194 w->phys_cursor_on_p = 0;
26195 return;
26198 cx0 = w->phys_cursor.x;
26199 cx1 = cx0 + w->phys_cursor_width;
26200 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
26201 return;
26203 /* The cursor image will be completely removed from the
26204 screen if the output area intersects the cursor area in
26205 y-direction. When we draw in [y0 y1[, and some part of
26206 the cursor is at y < y0, that part must have been drawn
26207 before. When scrolling, the cursor is erased before
26208 actually scrolling, so we don't come here. When not
26209 scrolling, the rows above the old cursor row must have
26210 changed, and in this case these rows must have written
26211 over the cursor image.
26213 Likewise if part of the cursor is below y1, with the
26214 exception of the cursor being in the first blank row at
26215 the buffer and window end because update_text_area
26216 doesn't draw that row. (Except when it does, but
26217 that's handled in update_text_area.) */
26219 cy0 = w->phys_cursor.y;
26220 cy1 = cy0 + w->phys_cursor_height;
26221 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
26222 return;
26224 w->phys_cursor_on_p = 0;
26227 #endif /* HAVE_WINDOW_SYSTEM */
26230 /************************************************************************
26231 Mouse Face
26232 ************************************************************************/
26234 #ifdef HAVE_WINDOW_SYSTEM
26236 /* EXPORT for RIF:
26237 Fix the display of area AREA of overlapping row ROW in window W
26238 with respect to the overlapping part OVERLAPS. */
26240 void
26241 x_fix_overlapping_area (struct window *w, struct glyph_row *row,
26242 enum glyph_row_area area, int overlaps)
26244 int i, x;
26246 block_input ();
26248 x = 0;
26249 for (i = 0; i < row->used[area];)
26251 if (row->glyphs[area][i].overlaps_vertically_p)
26253 int start = i, start_x = x;
26257 x += row->glyphs[area][i].pixel_width;
26258 ++i;
26260 while (i < row->used[area]
26261 && row->glyphs[area][i].overlaps_vertically_p);
26263 draw_glyphs (w, start_x, row, area,
26264 start, i,
26265 DRAW_NORMAL_TEXT, overlaps);
26267 else
26269 x += row->glyphs[area][i].pixel_width;
26270 ++i;
26274 unblock_input ();
26278 /* EXPORT:
26279 Draw the cursor glyph of window W in glyph row ROW. See the
26280 comment of draw_glyphs for the meaning of HL. */
26282 void
26283 draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
26284 enum draw_glyphs_face hl)
26286 /* If cursor hpos is out of bounds, don't draw garbage. This can
26287 happen in mini-buffer windows when switching between echo area
26288 glyphs and mini-buffer. */
26289 if ((row->reversed_p
26290 ? (w->phys_cursor.hpos >= 0)
26291 : (w->phys_cursor.hpos < row->used[TEXT_AREA])))
26293 int on_p = w->phys_cursor_on_p;
26294 int x1;
26295 int hpos = w->phys_cursor.hpos;
26297 /* When the window is hscrolled, cursor hpos can legitimately be
26298 out of bounds, but we draw the cursor at the corresponding
26299 window margin in that case. */
26300 if (!row->reversed_p && hpos < 0)
26301 hpos = 0;
26302 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26303 hpos = row->used[TEXT_AREA] - 1;
26305 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA, hpos, hpos + 1,
26306 hl, 0);
26307 w->phys_cursor_on_p = on_p;
26309 if (hl == DRAW_CURSOR)
26310 w->phys_cursor_width = x1 - w->phys_cursor.x;
26311 /* When we erase the cursor, and ROW is overlapped by other
26312 rows, make sure that these overlapping parts of other rows
26313 are redrawn. */
26314 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
26316 w->phys_cursor_width = x1 - w->phys_cursor.x;
26318 if (row > w->current_matrix->rows
26319 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
26320 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
26321 OVERLAPS_ERASED_CURSOR);
26323 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
26324 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
26325 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
26326 OVERLAPS_ERASED_CURSOR);
26332 /* EXPORT:
26333 Erase the image of a cursor of window W from the screen. */
26335 void
26336 erase_phys_cursor (struct window *w)
26338 struct frame *f = XFRAME (w->frame);
26339 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
26340 int hpos = w->phys_cursor.hpos;
26341 int vpos = w->phys_cursor.vpos;
26342 int mouse_face_here_p = 0;
26343 struct glyph_matrix *active_glyphs = w->current_matrix;
26344 struct glyph_row *cursor_row;
26345 struct glyph *cursor_glyph;
26346 enum draw_glyphs_face hl;
26348 /* No cursor displayed or row invalidated => nothing to do on the
26349 screen. */
26350 if (w->phys_cursor_type == NO_CURSOR)
26351 goto mark_cursor_off;
26353 /* VPOS >= active_glyphs->nrows means that window has been resized.
26354 Don't bother to erase the cursor. */
26355 if (vpos >= active_glyphs->nrows)
26356 goto mark_cursor_off;
26358 /* If row containing cursor is marked invalid, there is nothing we
26359 can do. */
26360 cursor_row = MATRIX_ROW (active_glyphs, vpos);
26361 if (!cursor_row->enabled_p)
26362 goto mark_cursor_off;
26364 /* If line spacing is > 0, old cursor may only be partially visible in
26365 window after split-window. So adjust visible height. */
26366 cursor_row->visible_height = min (cursor_row->visible_height,
26367 window_text_bottom_y (w) - cursor_row->y);
26369 /* If row is completely invisible, don't attempt to delete a cursor which
26370 isn't there. This can happen if cursor is at top of a window, and
26371 we switch to a buffer with a header line in that window. */
26372 if (cursor_row->visible_height <= 0)
26373 goto mark_cursor_off;
26375 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
26376 if (cursor_row->cursor_in_fringe_p)
26378 cursor_row->cursor_in_fringe_p = 0;
26379 draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
26380 goto mark_cursor_off;
26383 /* This can happen when the new row is shorter than the old one.
26384 In this case, either draw_glyphs or clear_end_of_line
26385 should have cleared the cursor. Note that we wouldn't be
26386 able to erase the cursor in this case because we don't have a
26387 cursor glyph at hand. */
26388 if ((cursor_row->reversed_p
26389 ? (w->phys_cursor.hpos < 0)
26390 : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
26391 goto mark_cursor_off;
26393 /* When the window is hscrolled, cursor hpos can legitimately be out
26394 of bounds, but we draw the cursor at the corresponding window
26395 margin in that case. */
26396 if (!cursor_row->reversed_p && hpos < 0)
26397 hpos = 0;
26398 if (cursor_row->reversed_p && hpos >= cursor_row->used[TEXT_AREA])
26399 hpos = cursor_row->used[TEXT_AREA] - 1;
26401 /* If the cursor is in the mouse face area, redisplay that when
26402 we clear the cursor. */
26403 if (! NILP (hlinfo->mouse_face_window)
26404 && coords_in_mouse_face_p (w, hpos, vpos)
26405 /* Don't redraw the cursor's spot in mouse face if it is at the
26406 end of a line (on a newline). The cursor appears there, but
26407 mouse highlighting does not. */
26408 && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
26409 mouse_face_here_p = 1;
26411 /* Maybe clear the display under the cursor. */
26412 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
26414 int x, y, left_x;
26415 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
26416 int width;
26418 cursor_glyph = get_phys_cursor_glyph (w);
26419 if (cursor_glyph == NULL)
26420 goto mark_cursor_off;
26422 width = cursor_glyph->pixel_width;
26423 left_x = window_box_left_offset (w, TEXT_AREA);
26424 x = w->phys_cursor.x;
26425 if (x < left_x)
26426 width -= left_x - x;
26427 width = min (width, window_box_width (w, TEXT_AREA) - x);
26428 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
26429 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
26431 if (width > 0)
26432 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
26435 /* Erase the cursor by redrawing the character underneath it. */
26436 if (mouse_face_here_p)
26437 hl = DRAW_MOUSE_FACE;
26438 else
26439 hl = DRAW_NORMAL_TEXT;
26440 draw_phys_cursor_glyph (w, cursor_row, hl);
26442 mark_cursor_off:
26443 w->phys_cursor_on_p = 0;
26444 w->phys_cursor_type = NO_CURSOR;
26448 /* EXPORT:
26449 Display or clear cursor of window W. If ON is zero, clear the
26450 cursor. If it is non-zero, display the cursor. If ON is nonzero,
26451 where to put the cursor is specified by HPOS, VPOS, X and Y. */
26453 void
26454 display_and_set_cursor (struct window *w, int on,
26455 int hpos, int vpos, int x, int y)
26457 struct frame *f = XFRAME (w->frame);
26458 int new_cursor_type;
26459 int new_cursor_width;
26460 int active_cursor;
26461 struct glyph_row *glyph_row;
26462 struct glyph *glyph;
26464 /* This is pointless on invisible frames, and dangerous on garbaged
26465 windows and frames; in the latter case, the frame or window may
26466 be in the midst of changing its size, and x and y may be off the
26467 window. */
26468 if (! FRAME_VISIBLE_P (f)
26469 || FRAME_GARBAGED_P (f)
26470 || vpos >= w->current_matrix->nrows
26471 || hpos >= w->current_matrix->matrix_w)
26472 return;
26474 /* If cursor is off and we want it off, return quickly. */
26475 if (!on && !w->phys_cursor_on_p)
26476 return;
26478 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
26479 /* If cursor row is not enabled, we don't really know where to
26480 display the cursor. */
26481 if (!glyph_row->enabled_p)
26483 w->phys_cursor_on_p = 0;
26484 return;
26487 glyph = NULL;
26488 if (!glyph_row->exact_window_width_line_p
26489 || (0 <= hpos && hpos < glyph_row->used[TEXT_AREA]))
26490 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
26492 eassert (input_blocked_p ());
26494 /* Set new_cursor_type to the cursor we want to be displayed. */
26495 new_cursor_type = get_window_cursor_type (w, glyph,
26496 &new_cursor_width, &active_cursor);
26498 /* If cursor is currently being shown and we don't want it to be or
26499 it is in the wrong place, or the cursor type is not what we want,
26500 erase it. */
26501 if (w->phys_cursor_on_p
26502 && (!on
26503 || w->phys_cursor.x != x
26504 || w->phys_cursor.y != y
26505 || new_cursor_type != w->phys_cursor_type
26506 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
26507 && new_cursor_width != w->phys_cursor_width)))
26508 erase_phys_cursor (w);
26510 /* Don't check phys_cursor_on_p here because that flag is only set
26511 to zero in some cases where we know that the cursor has been
26512 completely erased, to avoid the extra work of erasing the cursor
26513 twice. In other words, phys_cursor_on_p can be 1 and the cursor
26514 still not be visible, or it has only been partly erased. */
26515 if (on)
26517 w->phys_cursor_ascent = glyph_row->ascent;
26518 w->phys_cursor_height = glyph_row->height;
26520 /* Set phys_cursor_.* before x_draw_.* is called because some
26521 of them may need the information. */
26522 w->phys_cursor.x = x;
26523 w->phys_cursor.y = glyph_row->y;
26524 w->phys_cursor.hpos = hpos;
26525 w->phys_cursor.vpos = vpos;
26528 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
26529 new_cursor_type, new_cursor_width,
26530 on, active_cursor);
26534 /* Switch the display of W's cursor on or off, according to the value
26535 of ON. */
26537 static void
26538 update_window_cursor (struct window *w, int on)
26540 /* Don't update cursor in windows whose frame is in the process
26541 of being deleted. */
26542 if (w->current_matrix)
26544 int hpos = w->phys_cursor.hpos;
26545 int vpos = w->phys_cursor.vpos;
26546 struct glyph_row *row;
26548 if (vpos >= w->current_matrix->nrows
26549 || hpos >= w->current_matrix->matrix_w)
26550 return;
26552 row = MATRIX_ROW (w->current_matrix, vpos);
26554 /* When the window is hscrolled, cursor hpos can legitimately be
26555 out of bounds, but we draw the cursor at the corresponding
26556 window margin in that case. */
26557 if (!row->reversed_p && hpos < 0)
26558 hpos = 0;
26559 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26560 hpos = row->used[TEXT_AREA] - 1;
26562 block_input ();
26563 display_and_set_cursor (w, on, hpos, vpos,
26564 w->phys_cursor.x, w->phys_cursor.y);
26565 unblock_input ();
26570 /* Call update_window_cursor with parameter ON_P on all leaf windows
26571 in the window tree rooted at W. */
26573 static void
26574 update_cursor_in_window_tree (struct window *w, int on_p)
26576 while (w)
26578 if (WINDOWP (w->contents))
26579 update_cursor_in_window_tree (XWINDOW (w->contents), on_p);
26580 else
26581 update_window_cursor (w, on_p);
26583 w = NILP (w->next) ? 0 : XWINDOW (w->next);
26588 /* EXPORT:
26589 Display the cursor on window W, or clear it, according to ON_P.
26590 Don't change the cursor's position. */
26592 void
26593 x_update_cursor (struct frame *f, int on_p)
26595 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
26599 /* EXPORT:
26600 Clear the cursor of window W to background color, and mark the
26601 cursor as not shown. This is used when the text where the cursor
26602 is about to be rewritten. */
26604 void
26605 x_clear_cursor (struct window *w)
26607 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
26608 update_window_cursor (w, 0);
26611 #endif /* HAVE_WINDOW_SYSTEM */
26613 /* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
26614 and MSDOS. */
26615 static void
26616 draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
26617 int start_hpos, int end_hpos,
26618 enum draw_glyphs_face draw)
26620 #ifdef HAVE_WINDOW_SYSTEM
26621 if (FRAME_WINDOW_P (XFRAME (w->frame)))
26623 draw_glyphs (w, start_x, row, TEXT_AREA, start_hpos, end_hpos, draw, 0);
26624 return;
26626 #endif
26627 #if defined (HAVE_GPM) || defined (MSDOS) || defined (WINDOWSNT)
26628 tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
26629 #endif
26632 /* Display the active region described by mouse_face_* according to DRAW. */
26634 static void
26635 show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
26637 struct window *w = XWINDOW (hlinfo->mouse_face_window);
26638 struct frame *f = XFRAME (WINDOW_FRAME (w));
26640 if (/* If window is in the process of being destroyed, don't bother
26641 to do anything. */
26642 w->current_matrix != NULL
26643 /* Don't update mouse highlight if hidden */
26644 && (draw != DRAW_MOUSE_FACE || !hlinfo->mouse_face_hidden)
26645 /* Recognize when we are called to operate on rows that don't exist
26646 anymore. This can happen when a window is split. */
26647 && hlinfo->mouse_face_end_row < w->current_matrix->nrows)
26649 int phys_cursor_on_p = w->phys_cursor_on_p;
26650 struct glyph_row *row, *first, *last;
26652 first = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
26653 last = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
26655 for (row = first; row <= last && row->enabled_p; ++row)
26657 int start_hpos, end_hpos, start_x;
26659 /* For all but the first row, the highlight starts at column 0. */
26660 if (row == first)
26662 /* R2L rows have BEG and END in reversed order, but the
26663 screen drawing geometry is always left to right. So
26664 we need to mirror the beginning and end of the
26665 highlighted area in R2L rows. */
26666 if (!row->reversed_p)
26668 start_hpos = hlinfo->mouse_face_beg_col;
26669 start_x = hlinfo->mouse_face_beg_x;
26671 else if (row == last)
26673 start_hpos = hlinfo->mouse_face_end_col;
26674 start_x = hlinfo->mouse_face_end_x;
26676 else
26678 start_hpos = 0;
26679 start_x = 0;
26682 else if (row->reversed_p && row == last)
26684 start_hpos = hlinfo->mouse_face_end_col;
26685 start_x = hlinfo->mouse_face_end_x;
26687 else
26689 start_hpos = 0;
26690 start_x = 0;
26693 if (row == last)
26695 if (!row->reversed_p)
26696 end_hpos = hlinfo->mouse_face_end_col;
26697 else if (row == first)
26698 end_hpos = hlinfo->mouse_face_beg_col;
26699 else
26701 end_hpos = row->used[TEXT_AREA];
26702 if (draw == DRAW_NORMAL_TEXT)
26703 row->fill_line_p = 1; /* Clear to end of line */
26706 else if (row->reversed_p && row == first)
26707 end_hpos = hlinfo->mouse_face_beg_col;
26708 else
26710 end_hpos = row->used[TEXT_AREA];
26711 if (draw == DRAW_NORMAL_TEXT)
26712 row->fill_line_p = 1; /* Clear to end of line */
26715 if (end_hpos > start_hpos)
26717 draw_row_with_mouse_face (w, start_x, row,
26718 start_hpos, end_hpos, draw);
26720 row->mouse_face_p
26721 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
26725 #ifdef HAVE_WINDOW_SYSTEM
26726 /* When we've written over the cursor, arrange for it to
26727 be displayed again. */
26728 if (FRAME_WINDOW_P (f)
26729 && phys_cursor_on_p && !w->phys_cursor_on_p)
26731 int hpos = w->phys_cursor.hpos;
26733 /* When the window is hscrolled, cursor hpos can legitimately be
26734 out of bounds, but we draw the cursor at the corresponding
26735 window margin in that case. */
26736 if (!row->reversed_p && hpos < 0)
26737 hpos = 0;
26738 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26739 hpos = row->used[TEXT_AREA] - 1;
26741 block_input ();
26742 display_and_set_cursor (w, 1, hpos, w->phys_cursor.vpos,
26743 w->phys_cursor.x, w->phys_cursor.y);
26744 unblock_input ();
26746 #endif /* HAVE_WINDOW_SYSTEM */
26749 #ifdef HAVE_WINDOW_SYSTEM
26750 /* Change the mouse cursor. */
26751 if (FRAME_WINDOW_P (f))
26753 if (draw == DRAW_NORMAL_TEXT
26754 && !EQ (hlinfo->mouse_face_window, f->tool_bar_window))
26755 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
26756 else if (draw == DRAW_MOUSE_FACE)
26757 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
26758 else
26759 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
26761 #endif /* HAVE_WINDOW_SYSTEM */
26764 /* EXPORT:
26765 Clear out the mouse-highlighted active region.
26766 Redraw it un-highlighted first. Value is non-zero if mouse
26767 face was actually drawn unhighlighted. */
26770 clear_mouse_face (Mouse_HLInfo *hlinfo)
26772 int cleared = 0;
26774 if (!hlinfo->mouse_face_hidden && !NILP (hlinfo->mouse_face_window))
26776 show_mouse_face (hlinfo, DRAW_NORMAL_TEXT);
26777 cleared = 1;
26780 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
26781 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
26782 hlinfo->mouse_face_window = Qnil;
26783 hlinfo->mouse_face_overlay = Qnil;
26784 return cleared;
26787 /* Return non-zero if the coordinates HPOS and VPOS on windows W are
26788 within the mouse face on that window. */
26789 static int
26790 coords_in_mouse_face_p (struct window *w, int hpos, int vpos)
26792 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
26794 /* Quickly resolve the easy cases. */
26795 if (!(WINDOWP (hlinfo->mouse_face_window)
26796 && XWINDOW (hlinfo->mouse_face_window) == w))
26797 return 0;
26798 if (vpos < hlinfo->mouse_face_beg_row
26799 || vpos > hlinfo->mouse_face_end_row)
26800 return 0;
26801 if (vpos > hlinfo->mouse_face_beg_row
26802 && vpos < hlinfo->mouse_face_end_row)
26803 return 1;
26805 if (!MATRIX_ROW (w->current_matrix, vpos)->reversed_p)
26807 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
26809 if (hlinfo->mouse_face_beg_col <= hpos && hpos < hlinfo->mouse_face_end_col)
26810 return 1;
26812 else if ((vpos == hlinfo->mouse_face_beg_row
26813 && hpos >= hlinfo->mouse_face_beg_col)
26814 || (vpos == hlinfo->mouse_face_end_row
26815 && hpos < hlinfo->mouse_face_end_col))
26816 return 1;
26818 else
26820 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
26822 if (hlinfo->mouse_face_end_col < hpos && hpos <= hlinfo->mouse_face_beg_col)
26823 return 1;
26825 else if ((vpos == hlinfo->mouse_face_beg_row
26826 && hpos <= hlinfo->mouse_face_beg_col)
26827 || (vpos == hlinfo->mouse_face_end_row
26828 && hpos > hlinfo->mouse_face_end_col))
26829 return 1;
26831 return 0;
26835 /* EXPORT:
26836 Non-zero if physical cursor of window W is within mouse face. */
26839 cursor_in_mouse_face_p (struct window *w)
26841 int hpos = w->phys_cursor.hpos;
26842 int vpos = w->phys_cursor.vpos;
26843 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
26845 /* When the window is hscrolled, cursor hpos can legitimately be out
26846 of bounds, but we draw the cursor at the corresponding window
26847 margin in that case. */
26848 if (!row->reversed_p && hpos < 0)
26849 hpos = 0;
26850 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26851 hpos = row->used[TEXT_AREA] - 1;
26853 return coords_in_mouse_face_p (w, hpos, vpos);
26858 /* Find the glyph rows START_ROW and END_ROW of window W that display
26859 characters between buffer positions START_CHARPOS and END_CHARPOS
26860 (excluding END_CHARPOS). DISP_STRING is a display string that
26861 covers these buffer positions. This is similar to
26862 row_containing_pos, but is more accurate when bidi reordering makes
26863 buffer positions change non-linearly with glyph rows. */
26864 static void
26865 rows_from_pos_range (struct window *w,
26866 ptrdiff_t start_charpos, ptrdiff_t end_charpos,
26867 Lisp_Object disp_string,
26868 struct glyph_row **start, struct glyph_row **end)
26870 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
26871 int last_y = window_text_bottom_y (w);
26872 struct glyph_row *row;
26874 *start = NULL;
26875 *end = NULL;
26877 while (!first->enabled_p
26878 && first < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
26879 first++;
26881 /* Find the START row. */
26882 for (row = first;
26883 row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y;
26884 row++)
26886 /* A row can potentially be the START row if the range of the
26887 characters it displays intersects the range
26888 [START_CHARPOS..END_CHARPOS). */
26889 if (! ((start_charpos < MATRIX_ROW_START_CHARPOS (row)
26890 && end_charpos < MATRIX_ROW_START_CHARPOS (row))
26891 /* See the commentary in row_containing_pos, for the
26892 explanation of the complicated way to check whether
26893 some position is beyond the end of the characters
26894 displayed by a row. */
26895 || ((start_charpos > MATRIX_ROW_END_CHARPOS (row)
26896 || (start_charpos == MATRIX_ROW_END_CHARPOS (row)
26897 && !row->ends_at_zv_p
26898 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
26899 && (end_charpos > MATRIX_ROW_END_CHARPOS (row)
26900 || (end_charpos == MATRIX_ROW_END_CHARPOS (row)
26901 && !row->ends_at_zv_p
26902 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))))))
26904 /* Found a candidate row. Now make sure at least one of the
26905 glyphs it displays has a charpos from the range
26906 [START_CHARPOS..END_CHARPOS).
26908 This is not obvious because bidi reordering could make
26909 buffer positions of a row be 1,2,3,102,101,100, and if we
26910 want to highlight characters in [50..60), we don't want
26911 this row, even though [50..60) does intersect [1..103),
26912 the range of character positions given by the row's start
26913 and end positions. */
26914 struct glyph *g = row->glyphs[TEXT_AREA];
26915 struct glyph *e = g + row->used[TEXT_AREA];
26917 while (g < e)
26919 if (((BUFFERP (g->object) || INTEGERP (g->object))
26920 && start_charpos <= g->charpos && g->charpos < end_charpos)
26921 /* A glyph that comes from DISP_STRING is by
26922 definition to be highlighted. */
26923 || EQ (g->object, disp_string))
26924 *start = row;
26925 g++;
26927 if (*start)
26928 break;
26932 /* Find the END row. */
26933 if (!*start
26934 /* If the last row is partially visible, start looking for END
26935 from that row, instead of starting from FIRST. */
26936 && !(row->enabled_p
26937 && row->y < last_y && MATRIX_ROW_BOTTOM_Y (row) > last_y))
26938 row = first;
26939 for ( ; row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y; row++)
26941 struct glyph_row *next = row + 1;
26942 ptrdiff_t next_start = MATRIX_ROW_START_CHARPOS (next);
26944 if (!next->enabled_p
26945 || next >= MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)
26946 /* The first row >= START whose range of displayed characters
26947 does NOT intersect the range [START_CHARPOS..END_CHARPOS]
26948 is the row END + 1. */
26949 || (start_charpos < next_start
26950 && end_charpos < next_start)
26951 || ((start_charpos > MATRIX_ROW_END_CHARPOS (next)
26952 || (start_charpos == MATRIX_ROW_END_CHARPOS (next)
26953 && !next->ends_at_zv_p
26954 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))
26955 && (end_charpos > MATRIX_ROW_END_CHARPOS (next)
26956 || (end_charpos == MATRIX_ROW_END_CHARPOS (next)
26957 && !next->ends_at_zv_p
26958 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))))
26960 *end = row;
26961 break;
26963 else
26965 /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
26966 but none of the characters it displays are in the range, it is
26967 also END + 1. */
26968 struct glyph *g = next->glyphs[TEXT_AREA];
26969 struct glyph *s = g;
26970 struct glyph *e = g + next->used[TEXT_AREA];
26972 while (g < e)
26974 if (((BUFFERP (g->object) || INTEGERP (g->object))
26975 && ((start_charpos <= g->charpos && g->charpos < end_charpos)
26976 /* If the buffer position of the first glyph in
26977 the row is equal to END_CHARPOS, it means
26978 the last character to be highlighted is the
26979 newline of ROW, and we must consider NEXT as
26980 END, not END+1. */
26981 || (((!next->reversed_p && g == s)
26982 || (next->reversed_p && g == e - 1))
26983 && (g->charpos == end_charpos
26984 /* Special case for when NEXT is an
26985 empty line at ZV. */
26986 || (g->charpos == -1
26987 && !row->ends_at_zv_p
26988 && next_start == end_charpos)))))
26989 /* A glyph that comes from DISP_STRING is by
26990 definition to be highlighted. */
26991 || EQ (g->object, disp_string))
26992 break;
26993 g++;
26995 if (g == e)
26997 *end = row;
26998 break;
27000 /* The first row that ends at ZV must be the last to be
27001 highlighted. */
27002 else if (next->ends_at_zv_p)
27004 *end = next;
27005 break;
27011 /* This function sets the mouse_face_* elements of HLINFO, assuming
27012 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
27013 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
27014 for the overlay or run of text properties specifying the mouse
27015 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
27016 before-string and after-string that must also be highlighted.
27017 DISP_STRING, if non-nil, is a display string that may cover some
27018 or all of the highlighted text. */
27020 static void
27021 mouse_face_from_buffer_pos (Lisp_Object window,
27022 Mouse_HLInfo *hlinfo,
27023 ptrdiff_t mouse_charpos,
27024 ptrdiff_t start_charpos,
27025 ptrdiff_t end_charpos,
27026 Lisp_Object before_string,
27027 Lisp_Object after_string,
27028 Lisp_Object disp_string)
27030 struct window *w = XWINDOW (window);
27031 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
27032 struct glyph_row *r1, *r2;
27033 struct glyph *glyph, *end;
27034 ptrdiff_t ignore, pos;
27035 int x;
27037 eassert (NILP (disp_string) || STRINGP (disp_string));
27038 eassert (NILP (before_string) || STRINGP (before_string));
27039 eassert (NILP (after_string) || STRINGP (after_string));
27041 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
27042 rows_from_pos_range (w, start_charpos, end_charpos, disp_string, &r1, &r2);
27043 if (r1 == NULL)
27044 r1 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
27045 /* If the before-string or display-string contains newlines,
27046 rows_from_pos_range skips to its last row. Move back. */
27047 if (!NILP (before_string) || !NILP (disp_string))
27049 struct glyph_row *prev;
27050 while ((prev = r1 - 1, prev >= first)
27051 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
27052 && prev->used[TEXT_AREA] > 0)
27054 struct glyph *beg = prev->glyphs[TEXT_AREA];
27055 glyph = beg + prev->used[TEXT_AREA];
27056 while (--glyph >= beg && INTEGERP (glyph->object));
27057 if (glyph < beg
27058 || !(EQ (glyph->object, before_string)
27059 || EQ (glyph->object, disp_string)))
27060 break;
27061 r1 = prev;
27064 if (r2 == NULL)
27066 r2 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
27067 hlinfo->mouse_face_past_end = 1;
27069 else if (!NILP (after_string))
27071 /* If the after-string has newlines, advance to its last row. */
27072 struct glyph_row *next;
27073 struct glyph_row *last
27074 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
27076 for (next = r2 + 1;
27077 next <= last
27078 && next->used[TEXT_AREA] > 0
27079 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
27080 ++next)
27081 r2 = next;
27083 /* The rest of the display engine assumes that mouse_face_beg_row is
27084 either above mouse_face_end_row or identical to it. But with
27085 bidi-reordered continued lines, the row for START_CHARPOS could
27086 be below the row for END_CHARPOS. If so, swap the rows and store
27087 them in correct order. */
27088 if (r1->y > r2->y)
27090 struct glyph_row *tem = r2;
27092 r2 = r1;
27093 r1 = tem;
27096 hlinfo->mouse_face_beg_y = r1->y;
27097 hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
27098 hlinfo->mouse_face_end_y = r2->y;
27099 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
27101 /* For a bidi-reordered row, the positions of BEFORE_STRING,
27102 AFTER_STRING, DISP_STRING, START_CHARPOS, and END_CHARPOS
27103 could be anywhere in the row and in any order. The strategy
27104 below is to find the leftmost and the rightmost glyph that
27105 belongs to either of these 3 strings, or whose position is
27106 between START_CHARPOS and END_CHARPOS, and highlight all the
27107 glyphs between those two. This may cover more than just the text
27108 between START_CHARPOS and END_CHARPOS if the range of characters
27109 strides the bidi level boundary, e.g. if the beginning is in R2L
27110 text while the end is in L2R text or vice versa. */
27111 if (!r1->reversed_p)
27113 /* This row is in a left to right paragraph. Scan it left to
27114 right. */
27115 glyph = r1->glyphs[TEXT_AREA];
27116 end = glyph + r1->used[TEXT_AREA];
27117 x = r1->x;
27119 /* Skip truncation glyphs at the start of the glyph row. */
27120 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
27121 for (; glyph < end
27122 && INTEGERP (glyph->object)
27123 && glyph->charpos < 0;
27124 ++glyph)
27125 x += glyph->pixel_width;
27127 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
27128 or DISP_STRING, and the first glyph from buffer whose
27129 position is between START_CHARPOS and END_CHARPOS. */
27130 for (; glyph < end
27131 && !INTEGERP (glyph->object)
27132 && !EQ (glyph->object, disp_string)
27133 && !(BUFFERP (glyph->object)
27134 && (glyph->charpos >= start_charpos
27135 && glyph->charpos < end_charpos));
27136 ++glyph)
27138 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27139 are present at buffer positions between START_CHARPOS and
27140 END_CHARPOS, or if they come from an overlay. */
27141 if (EQ (glyph->object, before_string))
27143 pos = string_buffer_position (before_string,
27144 start_charpos);
27145 /* If pos == 0, it means before_string came from an
27146 overlay, not from a buffer position. */
27147 if (!pos || (pos >= start_charpos && pos < end_charpos))
27148 break;
27150 else if (EQ (glyph->object, after_string))
27152 pos = string_buffer_position (after_string, end_charpos);
27153 if (!pos || (pos >= start_charpos && pos < end_charpos))
27154 break;
27156 x += glyph->pixel_width;
27158 hlinfo->mouse_face_beg_x = x;
27159 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
27161 else
27163 /* This row is in a right to left paragraph. Scan it right to
27164 left. */
27165 struct glyph *g;
27167 end = r1->glyphs[TEXT_AREA] - 1;
27168 glyph = end + r1->used[TEXT_AREA];
27170 /* Skip truncation glyphs at the start of the glyph row. */
27171 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
27172 for (; glyph > end
27173 && INTEGERP (glyph->object)
27174 && glyph->charpos < 0;
27175 --glyph)
27178 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
27179 or DISP_STRING, and the first glyph from buffer whose
27180 position is between START_CHARPOS and END_CHARPOS. */
27181 for (; glyph > end
27182 && !INTEGERP (glyph->object)
27183 && !EQ (glyph->object, disp_string)
27184 && !(BUFFERP (glyph->object)
27185 && (glyph->charpos >= start_charpos
27186 && glyph->charpos < end_charpos));
27187 --glyph)
27189 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27190 are present at buffer positions between START_CHARPOS and
27191 END_CHARPOS, or if they come from an overlay. */
27192 if (EQ (glyph->object, before_string))
27194 pos = string_buffer_position (before_string, start_charpos);
27195 /* If pos == 0, it means before_string came from an
27196 overlay, not from a buffer position. */
27197 if (!pos || (pos >= start_charpos && pos < end_charpos))
27198 break;
27200 else if (EQ (glyph->object, after_string))
27202 pos = string_buffer_position (after_string, end_charpos);
27203 if (!pos || (pos >= start_charpos && pos < end_charpos))
27204 break;
27208 glyph++; /* first glyph to the right of the highlighted area */
27209 for (g = r1->glyphs[TEXT_AREA], x = r1->x; g < glyph; g++)
27210 x += g->pixel_width;
27211 hlinfo->mouse_face_beg_x = x;
27212 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
27215 /* If the highlight ends in a different row, compute GLYPH and END
27216 for the end row. Otherwise, reuse the values computed above for
27217 the row where the highlight begins. */
27218 if (r2 != r1)
27220 if (!r2->reversed_p)
27222 glyph = r2->glyphs[TEXT_AREA];
27223 end = glyph + r2->used[TEXT_AREA];
27224 x = r2->x;
27226 else
27228 end = r2->glyphs[TEXT_AREA] - 1;
27229 glyph = end + r2->used[TEXT_AREA];
27233 if (!r2->reversed_p)
27235 /* Skip truncation and continuation glyphs near the end of the
27236 row, and also blanks and stretch glyphs inserted by
27237 extend_face_to_end_of_line. */
27238 while (end > glyph
27239 && INTEGERP ((end - 1)->object))
27240 --end;
27241 /* Scan the rest of the glyph row from the end, looking for the
27242 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
27243 DISP_STRING, or whose position is between START_CHARPOS
27244 and END_CHARPOS */
27245 for (--end;
27246 end > glyph
27247 && !INTEGERP (end->object)
27248 && !EQ (end->object, disp_string)
27249 && !(BUFFERP (end->object)
27250 && (end->charpos >= start_charpos
27251 && end->charpos < end_charpos));
27252 --end)
27254 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27255 are present at buffer positions between START_CHARPOS and
27256 END_CHARPOS, or if they come from an overlay. */
27257 if (EQ (end->object, before_string))
27259 pos = string_buffer_position (before_string, start_charpos);
27260 if (!pos || (pos >= start_charpos && pos < end_charpos))
27261 break;
27263 else if (EQ (end->object, after_string))
27265 pos = string_buffer_position (after_string, end_charpos);
27266 if (!pos || (pos >= start_charpos && pos < end_charpos))
27267 break;
27270 /* Find the X coordinate of the last glyph to be highlighted. */
27271 for (; glyph <= end; ++glyph)
27272 x += glyph->pixel_width;
27274 hlinfo->mouse_face_end_x = x;
27275 hlinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
27277 else
27279 /* Skip truncation and continuation glyphs near the end of the
27280 row, and also blanks and stretch glyphs inserted by
27281 extend_face_to_end_of_line. */
27282 x = r2->x;
27283 end++;
27284 while (end < glyph
27285 && INTEGERP (end->object))
27287 x += end->pixel_width;
27288 ++end;
27290 /* Scan the rest of the glyph row from the end, looking for the
27291 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
27292 DISP_STRING, or whose position is between START_CHARPOS
27293 and END_CHARPOS */
27294 for ( ;
27295 end < glyph
27296 && !INTEGERP (end->object)
27297 && !EQ (end->object, disp_string)
27298 && !(BUFFERP (end->object)
27299 && (end->charpos >= start_charpos
27300 && end->charpos < end_charpos));
27301 ++end)
27303 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27304 are present at buffer positions between START_CHARPOS and
27305 END_CHARPOS, or if they come from an overlay. */
27306 if (EQ (end->object, before_string))
27308 pos = string_buffer_position (before_string, start_charpos);
27309 if (!pos || (pos >= start_charpos && pos < end_charpos))
27310 break;
27312 else if (EQ (end->object, after_string))
27314 pos = string_buffer_position (after_string, end_charpos);
27315 if (!pos || (pos >= start_charpos && pos < end_charpos))
27316 break;
27318 x += end->pixel_width;
27320 /* If we exited the above loop because we arrived at the last
27321 glyph of the row, and its buffer position is still not in
27322 range, it means the last character in range is the preceding
27323 newline. Bump the end column and x values to get past the
27324 last glyph. */
27325 if (end == glyph
27326 && BUFFERP (end->object)
27327 && (end->charpos < start_charpos
27328 || end->charpos >= end_charpos))
27330 x += end->pixel_width;
27331 ++end;
27333 hlinfo->mouse_face_end_x = x;
27334 hlinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
27337 hlinfo->mouse_face_window = window;
27338 hlinfo->mouse_face_face_id
27339 = face_at_buffer_position (w, mouse_charpos, 0, 0, &ignore,
27340 mouse_charpos + 1,
27341 !hlinfo->mouse_face_hidden, -1);
27342 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
27345 /* The following function is not used anymore (replaced with
27346 mouse_face_from_string_pos), but I leave it here for the time
27347 being, in case someone would. */
27349 #if 0 /* not used */
27351 /* Find the position of the glyph for position POS in OBJECT in
27352 window W's current matrix, and return in *X, *Y the pixel
27353 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
27355 RIGHT_P non-zero means return the position of the right edge of the
27356 glyph, RIGHT_P zero means return the left edge position.
27358 If no glyph for POS exists in the matrix, return the position of
27359 the glyph with the next smaller position that is in the matrix, if
27360 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
27361 exists in the matrix, return the position of the glyph with the
27362 next larger position in OBJECT.
27364 Value is non-zero if a glyph was found. */
27366 static int
27367 fast_find_string_pos (struct window *w, ptrdiff_t pos, Lisp_Object object,
27368 int *hpos, int *vpos, int *x, int *y, int right_p)
27370 int yb = window_text_bottom_y (w);
27371 struct glyph_row *r;
27372 struct glyph *best_glyph = NULL;
27373 struct glyph_row *best_row = NULL;
27374 int best_x = 0;
27376 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
27377 r->enabled_p && r->y < yb;
27378 ++r)
27380 struct glyph *g = r->glyphs[TEXT_AREA];
27381 struct glyph *e = g + r->used[TEXT_AREA];
27382 int gx;
27384 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
27385 if (EQ (g->object, object))
27387 if (g->charpos == pos)
27389 best_glyph = g;
27390 best_x = gx;
27391 best_row = r;
27392 goto found;
27394 else if (best_glyph == NULL
27395 || ((eabs (g->charpos - pos)
27396 < eabs (best_glyph->charpos - pos))
27397 && (right_p
27398 ? g->charpos < pos
27399 : g->charpos > pos)))
27401 best_glyph = g;
27402 best_x = gx;
27403 best_row = r;
27408 found:
27410 if (best_glyph)
27412 *x = best_x;
27413 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
27415 if (right_p)
27417 *x += best_glyph->pixel_width;
27418 ++*hpos;
27421 *y = best_row->y;
27422 *vpos = MATRIX_ROW_VPOS (best_row, w->current_matrix);
27425 return best_glyph != NULL;
27427 #endif /* not used */
27429 /* Find the positions of the first and the last glyphs in window W's
27430 current matrix that occlude positions [STARTPOS..ENDPOS] in OBJECT
27431 (assumed to be a string), and return in HLINFO's mouse_face_*
27432 members the pixel and column/row coordinates of those glyphs. */
27434 static void
27435 mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
27436 Lisp_Object object,
27437 ptrdiff_t startpos, ptrdiff_t endpos)
27439 int yb = window_text_bottom_y (w);
27440 struct glyph_row *r;
27441 struct glyph *g, *e;
27442 int gx;
27443 int found = 0;
27445 /* Find the glyph row with at least one position in the range
27446 [STARTPOS..ENDPOS], and the first glyph in that row whose
27447 position belongs to that range. */
27448 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
27449 r->enabled_p && r->y < yb;
27450 ++r)
27452 if (!r->reversed_p)
27454 g = r->glyphs[TEXT_AREA];
27455 e = g + r->used[TEXT_AREA];
27456 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
27457 if (EQ (g->object, object)
27458 && startpos <= g->charpos && g->charpos <= endpos)
27460 hlinfo->mouse_face_beg_row
27461 = MATRIX_ROW_VPOS (r, w->current_matrix);
27462 hlinfo->mouse_face_beg_y = r->y;
27463 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
27464 hlinfo->mouse_face_beg_x = gx;
27465 found = 1;
27466 break;
27469 else
27471 struct glyph *g1;
27473 e = r->glyphs[TEXT_AREA];
27474 g = e + r->used[TEXT_AREA];
27475 for ( ; g > e; --g)
27476 if (EQ ((g-1)->object, object)
27477 && startpos <= (g-1)->charpos && (g-1)->charpos <= endpos)
27479 hlinfo->mouse_face_beg_row
27480 = MATRIX_ROW_VPOS (r, w->current_matrix);
27481 hlinfo->mouse_face_beg_y = r->y;
27482 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
27483 for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
27484 gx += g1->pixel_width;
27485 hlinfo->mouse_face_beg_x = gx;
27486 found = 1;
27487 break;
27490 if (found)
27491 break;
27494 if (!found)
27495 return;
27497 /* Starting with the next row, look for the first row which does NOT
27498 include any glyphs whose positions are in the range. */
27499 for (++r; r->enabled_p && r->y < yb; ++r)
27501 g = r->glyphs[TEXT_AREA];
27502 e = g + r->used[TEXT_AREA];
27503 found = 0;
27504 for ( ; g < e; ++g)
27505 if (EQ (g->object, object)
27506 && startpos <= g->charpos && g->charpos <= endpos)
27508 found = 1;
27509 break;
27511 if (!found)
27512 break;
27515 /* The highlighted region ends on the previous row. */
27516 r--;
27518 /* Set the end row and its vertical pixel coordinate. */
27519 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r, w->current_matrix);
27520 hlinfo->mouse_face_end_y = r->y;
27522 /* Compute and set the end column and the end column's horizontal
27523 pixel coordinate. */
27524 if (!r->reversed_p)
27526 g = r->glyphs[TEXT_AREA];
27527 e = g + r->used[TEXT_AREA];
27528 for ( ; e > g; --e)
27529 if (EQ ((e-1)->object, object)
27530 && startpos <= (e-1)->charpos && (e-1)->charpos <= endpos)
27531 break;
27532 hlinfo->mouse_face_end_col = e - g;
27534 for (gx = r->x; g < e; ++g)
27535 gx += g->pixel_width;
27536 hlinfo->mouse_face_end_x = gx;
27538 else
27540 e = r->glyphs[TEXT_AREA];
27541 g = e + r->used[TEXT_AREA];
27542 for (gx = r->x ; e < g; ++e)
27544 if (EQ (e->object, object)
27545 && startpos <= e->charpos && e->charpos <= endpos)
27546 break;
27547 gx += e->pixel_width;
27549 hlinfo->mouse_face_end_col = e - r->glyphs[TEXT_AREA];
27550 hlinfo->mouse_face_end_x = gx;
27554 #ifdef HAVE_WINDOW_SYSTEM
27556 /* See if position X, Y is within a hot-spot of an image. */
27558 static int
27559 on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
27561 if (!CONSP (hot_spot))
27562 return 0;
27564 if (EQ (XCAR (hot_spot), Qrect))
27566 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
27567 Lisp_Object rect = XCDR (hot_spot);
27568 Lisp_Object tem;
27569 if (!CONSP (rect))
27570 return 0;
27571 if (!CONSP (XCAR (rect)))
27572 return 0;
27573 if (!CONSP (XCDR (rect)))
27574 return 0;
27575 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
27576 return 0;
27577 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
27578 return 0;
27579 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
27580 return 0;
27581 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
27582 return 0;
27583 return 1;
27585 else if (EQ (XCAR (hot_spot), Qcircle))
27587 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
27588 Lisp_Object circ = XCDR (hot_spot);
27589 Lisp_Object lr, lx0, ly0;
27590 if (CONSP (circ)
27591 && CONSP (XCAR (circ))
27592 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
27593 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
27594 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
27596 double r = XFLOATINT (lr);
27597 double dx = XINT (lx0) - x;
27598 double dy = XINT (ly0) - y;
27599 return (dx * dx + dy * dy <= r * r);
27602 else if (EQ (XCAR (hot_spot), Qpoly))
27604 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
27605 if (VECTORP (XCDR (hot_spot)))
27607 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
27608 Lisp_Object *poly = v->contents;
27609 ptrdiff_t n = v->header.size;
27610 ptrdiff_t i;
27611 int inside = 0;
27612 Lisp_Object lx, ly;
27613 int x0, y0;
27615 /* Need an even number of coordinates, and at least 3 edges. */
27616 if (n < 6 || n & 1)
27617 return 0;
27619 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
27620 If count is odd, we are inside polygon. Pixels on edges
27621 may or may not be included depending on actual geometry of the
27622 polygon. */
27623 if ((lx = poly[n-2], !INTEGERP (lx))
27624 || (ly = poly[n-1], !INTEGERP (lx)))
27625 return 0;
27626 x0 = XINT (lx), y0 = XINT (ly);
27627 for (i = 0; i < n; i += 2)
27629 int x1 = x0, y1 = y0;
27630 if ((lx = poly[i], !INTEGERP (lx))
27631 || (ly = poly[i+1], !INTEGERP (ly)))
27632 return 0;
27633 x0 = XINT (lx), y0 = XINT (ly);
27635 /* Does this segment cross the X line? */
27636 if (x0 >= x)
27638 if (x1 >= x)
27639 continue;
27641 else if (x1 < x)
27642 continue;
27643 if (y > y0 && y > y1)
27644 continue;
27645 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
27646 inside = !inside;
27648 return inside;
27651 return 0;
27654 Lisp_Object
27655 find_hot_spot (Lisp_Object map, int x, int y)
27657 while (CONSP (map))
27659 if (CONSP (XCAR (map))
27660 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
27661 return XCAR (map);
27662 map = XCDR (map);
27665 return Qnil;
27668 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
27669 3, 3, 0,
27670 doc: /* Lookup in image map MAP coordinates X and Y.
27671 An image map is an alist where each element has the format (AREA ID PLIST).
27672 An AREA is specified as either a rectangle, a circle, or a polygon:
27673 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
27674 pixel coordinates of the upper left and bottom right corners.
27675 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
27676 and the radius of the circle; r may be a float or integer.
27677 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
27678 vector describes one corner in the polygon.
27679 Returns the alist element for the first matching AREA in MAP. */)
27680 (Lisp_Object map, Lisp_Object x, Lisp_Object y)
27682 if (NILP (map))
27683 return Qnil;
27685 CHECK_NUMBER (x);
27686 CHECK_NUMBER (y);
27688 return find_hot_spot (map,
27689 clip_to_bounds (INT_MIN, XINT (x), INT_MAX),
27690 clip_to_bounds (INT_MIN, XINT (y), INT_MAX));
27694 /* Display frame CURSOR, optionally using shape defined by POINTER. */
27695 static void
27696 define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
27698 /* Do not change cursor shape while dragging mouse. */
27699 if (!NILP (do_mouse_tracking))
27700 return;
27702 if (!NILP (pointer))
27704 if (EQ (pointer, Qarrow))
27705 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27706 else if (EQ (pointer, Qhand))
27707 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
27708 else if (EQ (pointer, Qtext))
27709 cursor = FRAME_X_OUTPUT (f)->text_cursor;
27710 else if (EQ (pointer, intern ("hdrag")))
27711 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
27712 #ifdef HAVE_X_WINDOWS
27713 else if (EQ (pointer, intern ("vdrag")))
27714 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
27715 #endif
27716 else if (EQ (pointer, intern ("hourglass")))
27717 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
27718 else if (EQ (pointer, Qmodeline))
27719 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
27720 else
27721 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27724 if (cursor != No_Cursor)
27725 FRAME_RIF (f)->define_frame_cursor (f, cursor);
27728 #endif /* HAVE_WINDOW_SYSTEM */
27730 /* Take proper action when mouse has moved to the mode or header line
27731 or marginal area AREA of window W, x-position X and y-position Y.
27732 X is relative to the start of the text display area of W, so the
27733 width of bitmap areas and scroll bars must be subtracted to get a
27734 position relative to the start of the mode line. */
27736 static void
27737 note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
27738 enum window_part area)
27740 struct window *w = XWINDOW (window);
27741 struct frame *f = XFRAME (w->frame);
27742 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
27743 #ifdef HAVE_WINDOW_SYSTEM
27744 Display_Info *dpyinfo;
27745 #endif
27746 Cursor cursor = No_Cursor;
27747 Lisp_Object pointer = Qnil;
27748 int dx, dy, width, height;
27749 ptrdiff_t charpos;
27750 Lisp_Object string, object = Qnil;
27751 Lisp_Object pos IF_LINT (= Qnil), help;
27753 Lisp_Object mouse_face;
27754 int original_x_pixel = x;
27755 struct glyph * glyph = NULL, * row_start_glyph = NULL;
27756 struct glyph_row *row IF_LINT (= 0);
27758 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
27760 int x0;
27761 struct glyph *end;
27763 /* Kludge alert: mode_line_string takes X/Y in pixels, but
27764 returns them in row/column units! */
27765 string = mode_line_string (w, area, &x, &y, &charpos,
27766 &object, &dx, &dy, &width, &height);
27768 row = (area == ON_MODE_LINE
27769 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
27770 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
27772 /* Find the glyph under the mouse pointer. */
27773 if (row->mode_line_p && row->enabled_p)
27775 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
27776 end = glyph + row->used[TEXT_AREA];
27778 for (x0 = original_x_pixel;
27779 glyph < end && x0 >= glyph->pixel_width;
27780 ++glyph)
27781 x0 -= glyph->pixel_width;
27783 if (glyph >= end)
27784 glyph = NULL;
27787 else
27789 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
27790 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
27791 returns them in row/column units! */
27792 string = marginal_area_string (w, area, &x, &y, &charpos,
27793 &object, &dx, &dy, &width, &height);
27796 help = Qnil;
27798 #ifdef HAVE_WINDOW_SYSTEM
27799 if (IMAGEP (object))
27801 Lisp_Object image_map, hotspot;
27802 if ((image_map = Fplist_get (XCDR (object), QCmap),
27803 !NILP (image_map))
27804 && (hotspot = find_hot_spot (image_map, dx, dy),
27805 CONSP (hotspot))
27806 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
27808 Lisp_Object plist;
27810 /* Could check XCAR (hotspot) to see if we enter/leave this hot-spot.
27811 If so, we could look for mouse-enter, mouse-leave
27812 properties in PLIST (and do something...). */
27813 hotspot = XCDR (hotspot);
27814 if (CONSP (hotspot)
27815 && (plist = XCAR (hotspot), CONSP (plist)))
27817 pointer = Fplist_get (plist, Qpointer);
27818 if (NILP (pointer))
27819 pointer = Qhand;
27820 help = Fplist_get (plist, Qhelp_echo);
27821 if (!NILP (help))
27823 help_echo_string = help;
27824 XSETWINDOW (help_echo_window, w);
27825 help_echo_object = w->contents;
27826 help_echo_pos = charpos;
27830 if (NILP (pointer))
27831 pointer = Fplist_get (XCDR (object), QCpointer);
27833 #endif /* HAVE_WINDOW_SYSTEM */
27835 if (STRINGP (string))
27836 pos = make_number (charpos);
27838 /* Set the help text and mouse pointer. If the mouse is on a part
27839 of the mode line without any text (e.g. past the right edge of
27840 the mode line text), use the default help text and pointer. */
27841 if (STRINGP (string) || area == ON_MODE_LINE)
27843 /* Arrange to display the help by setting the global variables
27844 help_echo_string, help_echo_object, and help_echo_pos. */
27845 if (NILP (help))
27847 if (STRINGP (string))
27848 help = Fget_text_property (pos, Qhelp_echo, string);
27850 if (!NILP (help))
27852 help_echo_string = help;
27853 XSETWINDOW (help_echo_window, w);
27854 help_echo_object = string;
27855 help_echo_pos = charpos;
27857 else if (area == ON_MODE_LINE)
27859 Lisp_Object default_help
27860 = buffer_local_value_1 (Qmode_line_default_help_echo,
27861 w->contents);
27863 if (STRINGP (default_help))
27865 help_echo_string = default_help;
27866 XSETWINDOW (help_echo_window, w);
27867 help_echo_object = Qnil;
27868 help_echo_pos = -1;
27873 #ifdef HAVE_WINDOW_SYSTEM
27874 /* Change the mouse pointer according to what is under it. */
27875 if (FRAME_WINDOW_P (f))
27877 dpyinfo = FRAME_X_DISPLAY_INFO (f);
27878 if (STRINGP (string))
27880 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27882 if (NILP (pointer))
27883 pointer = Fget_text_property (pos, Qpointer, string);
27885 /* Change the mouse pointer according to what is under X/Y. */
27886 if (NILP (pointer)
27887 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
27889 Lisp_Object map;
27890 map = Fget_text_property (pos, Qlocal_map, string);
27891 if (!KEYMAPP (map))
27892 map = Fget_text_property (pos, Qkeymap, string);
27893 if (!KEYMAPP (map))
27894 cursor = dpyinfo->vertical_scroll_bar_cursor;
27897 else
27898 /* Default mode-line pointer. */
27899 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
27901 #endif
27904 /* Change the mouse face according to what is under X/Y. */
27905 if (STRINGP (string))
27907 mouse_face = Fget_text_property (pos, Qmouse_face, string);
27908 if (!NILP (Vmouse_highlight) && !NILP (mouse_face)
27909 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
27910 && glyph)
27912 Lisp_Object b, e;
27914 struct glyph * tmp_glyph;
27916 int gpos;
27917 int gseq_length;
27918 int total_pixel_width;
27919 ptrdiff_t begpos, endpos, ignore;
27921 int vpos, hpos;
27923 b = Fprevious_single_property_change (make_number (charpos + 1),
27924 Qmouse_face, string, Qnil);
27925 if (NILP (b))
27926 begpos = 0;
27927 else
27928 begpos = XINT (b);
27930 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
27931 if (NILP (e))
27932 endpos = SCHARS (string);
27933 else
27934 endpos = XINT (e);
27936 /* Calculate the glyph position GPOS of GLYPH in the
27937 displayed string, relative to the beginning of the
27938 highlighted part of the string.
27940 Note: GPOS is different from CHARPOS. CHARPOS is the
27941 position of GLYPH in the internal string object. A mode
27942 line string format has structures which are converted to
27943 a flattened string by the Emacs Lisp interpreter. The
27944 internal string is an element of those structures. The
27945 displayed string is the flattened string. */
27946 tmp_glyph = row_start_glyph;
27947 while (tmp_glyph < glyph
27948 && (!(EQ (tmp_glyph->object, glyph->object)
27949 && begpos <= tmp_glyph->charpos
27950 && tmp_glyph->charpos < endpos)))
27951 tmp_glyph++;
27952 gpos = glyph - tmp_glyph;
27954 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
27955 the highlighted part of the displayed string to which
27956 GLYPH belongs. Note: GSEQ_LENGTH is different from
27957 SCHARS (STRING), because the latter returns the length of
27958 the internal string. */
27959 for (tmp_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
27960 tmp_glyph > glyph
27961 && (!(EQ (tmp_glyph->object, glyph->object)
27962 && begpos <= tmp_glyph->charpos
27963 && tmp_glyph->charpos < endpos));
27964 tmp_glyph--)
27966 gseq_length = gpos + (tmp_glyph - glyph) + 1;
27968 /* Calculate the total pixel width of all the glyphs between
27969 the beginning of the highlighted area and GLYPH. */
27970 total_pixel_width = 0;
27971 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
27972 total_pixel_width += tmp_glyph->pixel_width;
27974 /* Pre calculation of re-rendering position. Note: X is in
27975 column units here, after the call to mode_line_string or
27976 marginal_area_string. */
27977 hpos = x - gpos;
27978 vpos = (area == ON_MODE_LINE
27979 ? (w->current_matrix)->nrows - 1
27980 : 0);
27982 /* If GLYPH's position is included in the region that is
27983 already drawn in mouse face, we have nothing to do. */
27984 if ( EQ (window, hlinfo->mouse_face_window)
27985 && (!row->reversed_p
27986 ? (hlinfo->mouse_face_beg_col <= hpos
27987 && hpos < hlinfo->mouse_face_end_col)
27988 /* In R2L rows we swap BEG and END, see below. */
27989 : (hlinfo->mouse_face_end_col <= hpos
27990 && hpos < hlinfo->mouse_face_beg_col))
27991 && hlinfo->mouse_face_beg_row == vpos )
27992 return;
27994 if (clear_mouse_face (hlinfo))
27995 cursor = No_Cursor;
27997 if (!row->reversed_p)
27999 hlinfo->mouse_face_beg_col = hpos;
28000 hlinfo->mouse_face_beg_x = original_x_pixel
28001 - (total_pixel_width + dx);
28002 hlinfo->mouse_face_end_col = hpos + gseq_length;
28003 hlinfo->mouse_face_end_x = 0;
28005 else
28007 /* In R2L rows, show_mouse_face expects BEG and END
28008 coordinates to be swapped. */
28009 hlinfo->mouse_face_end_col = hpos;
28010 hlinfo->mouse_face_end_x = original_x_pixel
28011 - (total_pixel_width + dx);
28012 hlinfo->mouse_face_beg_col = hpos + gseq_length;
28013 hlinfo->mouse_face_beg_x = 0;
28016 hlinfo->mouse_face_beg_row = vpos;
28017 hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row;
28018 hlinfo->mouse_face_beg_y = 0;
28019 hlinfo->mouse_face_end_y = 0;
28020 hlinfo->mouse_face_past_end = 0;
28021 hlinfo->mouse_face_window = window;
28023 hlinfo->mouse_face_face_id = face_at_string_position (w, string,
28024 charpos,
28025 0, 0, 0,
28026 &ignore,
28027 glyph->face_id,
28029 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
28031 if (NILP (pointer))
28032 pointer = Qhand;
28034 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
28035 clear_mouse_face (hlinfo);
28037 #ifdef HAVE_WINDOW_SYSTEM
28038 if (FRAME_WINDOW_P (f))
28039 define_frame_cursor1 (f, cursor, pointer);
28040 #endif
28044 /* EXPORT:
28045 Take proper action when the mouse has moved to position X, Y on
28046 frame F with regards to highlighting portions of display that have
28047 mouse-face properties. Also de-highlight portions of display where
28048 the mouse was before, set the mouse pointer shape as appropriate
28049 for the mouse coordinates, and activate help echo (tooltips).
28050 X and Y can be negative or out of range. */
28052 void
28053 note_mouse_highlight (struct frame *f, int x, int y)
28055 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
28056 enum window_part part = ON_NOTHING;
28057 Lisp_Object window;
28058 struct window *w;
28059 Cursor cursor = No_Cursor;
28060 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
28061 struct buffer *b;
28063 /* When a menu is active, don't highlight because this looks odd. */
28064 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
28065 if (popup_activated ())
28066 return;
28067 #endif
28069 if (!f->glyphs_initialized_p
28070 || f->pointer_invisible)
28071 return;
28073 hlinfo->mouse_face_mouse_x = x;
28074 hlinfo->mouse_face_mouse_y = y;
28075 hlinfo->mouse_face_mouse_frame = f;
28077 if (hlinfo->mouse_face_defer)
28078 return;
28080 /* Which window is that in? */
28081 window = window_from_coordinates (f, x, y, &part, 1);
28083 /* If displaying active text in another window, clear that. */
28084 if (! EQ (window, hlinfo->mouse_face_window)
28085 /* Also clear if we move out of text area in same window. */
28086 || (!NILP (hlinfo->mouse_face_window)
28087 && !NILP (window)
28088 && part != ON_TEXT
28089 && part != ON_MODE_LINE
28090 && part != ON_HEADER_LINE))
28091 clear_mouse_face (hlinfo);
28093 /* Not on a window -> return. */
28094 if (!WINDOWP (window))
28095 return;
28097 /* Reset help_echo_string. It will get recomputed below. */
28098 help_echo_string = Qnil;
28100 /* Convert to window-relative pixel coordinates. */
28101 w = XWINDOW (window);
28102 frame_to_window_pixel_xy (w, &x, &y);
28104 #ifdef HAVE_WINDOW_SYSTEM
28105 /* Handle tool-bar window differently since it doesn't display a
28106 buffer. */
28107 if (EQ (window, f->tool_bar_window))
28109 note_tool_bar_highlight (f, x, y);
28110 return;
28112 #endif
28114 /* Mouse is on the mode, header line or margin? */
28115 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
28116 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
28118 note_mode_line_or_margin_highlight (window, x, y, part);
28119 return;
28122 #ifdef HAVE_WINDOW_SYSTEM
28123 if (part == ON_VERTICAL_BORDER)
28125 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
28126 help_echo_string = build_string ("drag-mouse-1: resize");
28128 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
28129 || part == ON_SCROLL_BAR)
28130 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
28131 else
28132 cursor = FRAME_X_OUTPUT (f)->text_cursor;
28133 #endif
28135 /* Are we in a window whose display is up to date?
28136 And verify the buffer's text has not changed. */
28137 b = XBUFFER (w->contents);
28138 if (part == ON_TEXT && w->window_end_valid && !window_outdated (w))
28140 int hpos, vpos, dx, dy, area = LAST_AREA;
28141 ptrdiff_t pos;
28142 struct glyph *glyph;
28143 Lisp_Object object;
28144 Lisp_Object mouse_face = Qnil, position;
28145 Lisp_Object *overlay_vec = NULL;
28146 ptrdiff_t i, noverlays;
28147 struct buffer *obuf;
28148 ptrdiff_t obegv, ozv;
28149 int same_region;
28151 /* Find the glyph under X/Y. */
28152 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
28154 #ifdef HAVE_WINDOW_SYSTEM
28155 /* Look for :pointer property on image. */
28156 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
28158 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
28159 if (img != NULL && IMAGEP (img->spec))
28161 Lisp_Object image_map, hotspot;
28162 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
28163 !NILP (image_map))
28164 && (hotspot = find_hot_spot (image_map,
28165 glyph->slice.img.x + dx,
28166 glyph->slice.img.y + dy),
28167 CONSP (hotspot))
28168 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
28170 Lisp_Object plist;
28172 /* Could check XCAR (hotspot) to see if we enter/leave
28173 this hot-spot.
28174 If so, we could look for mouse-enter, mouse-leave
28175 properties in PLIST (and do something...). */
28176 hotspot = XCDR (hotspot);
28177 if (CONSP (hotspot)
28178 && (plist = XCAR (hotspot), CONSP (plist)))
28180 pointer = Fplist_get (plist, Qpointer);
28181 if (NILP (pointer))
28182 pointer = Qhand;
28183 help_echo_string = Fplist_get (plist, Qhelp_echo);
28184 if (!NILP (help_echo_string))
28186 help_echo_window = window;
28187 help_echo_object = glyph->object;
28188 help_echo_pos = glyph->charpos;
28192 if (NILP (pointer))
28193 pointer = Fplist_get (XCDR (img->spec), QCpointer);
28196 #endif /* HAVE_WINDOW_SYSTEM */
28198 /* Clear mouse face if X/Y not over text. */
28199 if (glyph == NULL
28200 || area != TEXT_AREA
28201 || !MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->current_matrix, vpos))
28202 /* Glyph's OBJECT is an integer for glyphs inserted by the
28203 display engine for its internal purposes, like truncation
28204 and continuation glyphs and blanks beyond the end of
28205 line's text on text terminals. If we are over such a
28206 glyph, we are not over any text. */
28207 || INTEGERP (glyph->object)
28208 /* R2L rows have a stretch glyph at their front, which
28209 stands for no text, whereas L2R rows have no glyphs at
28210 all beyond the end of text. Treat such stretch glyphs
28211 like we do with NULL glyphs in L2R rows. */
28212 || (MATRIX_ROW (w->current_matrix, vpos)->reversed_p
28213 && glyph == MATRIX_ROW_GLYPH_START (w->current_matrix, vpos)
28214 && glyph->type == STRETCH_GLYPH
28215 && glyph->avoid_cursor_p))
28217 if (clear_mouse_face (hlinfo))
28218 cursor = No_Cursor;
28219 #ifdef HAVE_WINDOW_SYSTEM
28220 if (FRAME_WINDOW_P (f) && NILP (pointer))
28222 if (area != TEXT_AREA)
28223 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
28224 else
28225 pointer = Vvoid_text_area_pointer;
28227 #endif
28228 goto set_cursor;
28231 pos = glyph->charpos;
28232 object = glyph->object;
28233 if (!STRINGP (object) && !BUFFERP (object))
28234 goto set_cursor;
28236 /* If we get an out-of-range value, return now; avoid an error. */
28237 if (BUFFERP (object) && pos > BUF_Z (b))
28238 goto set_cursor;
28240 /* Make the window's buffer temporarily current for
28241 overlays_at and compute_char_face. */
28242 obuf = current_buffer;
28243 current_buffer = b;
28244 obegv = BEGV;
28245 ozv = ZV;
28246 BEGV = BEG;
28247 ZV = Z;
28249 /* Is this char mouse-active or does it have help-echo? */
28250 position = make_number (pos);
28252 if (BUFFERP (object))
28254 /* Put all the overlays we want in a vector in overlay_vec. */
28255 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
28256 /* Sort overlays into increasing priority order. */
28257 noverlays = sort_overlays (overlay_vec, noverlays, w);
28259 else
28260 noverlays = 0;
28262 if (NILP (Vmouse_highlight))
28264 clear_mouse_face (hlinfo);
28265 goto check_help_echo;
28268 same_region = coords_in_mouse_face_p (w, hpos, vpos);
28270 if (same_region)
28271 cursor = No_Cursor;
28273 /* Check mouse-face highlighting. */
28274 if (! same_region
28275 /* If there exists an overlay with mouse-face overlapping
28276 the one we are currently highlighting, we have to
28277 check if we enter the overlapping overlay, and then
28278 highlight only that. */
28279 || (OVERLAYP (hlinfo->mouse_face_overlay)
28280 && mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
28282 /* Find the highest priority overlay with a mouse-face. */
28283 Lisp_Object overlay = Qnil;
28284 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
28286 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
28287 if (!NILP (mouse_face))
28288 overlay = overlay_vec[i];
28291 /* If we're highlighting the same overlay as before, there's
28292 no need to do that again. */
28293 if (!NILP (overlay) && EQ (overlay, hlinfo->mouse_face_overlay))
28294 goto check_help_echo;
28295 hlinfo->mouse_face_overlay = overlay;
28297 /* Clear the display of the old active region, if any. */
28298 if (clear_mouse_face (hlinfo))
28299 cursor = No_Cursor;
28301 /* If no overlay applies, get a text property. */
28302 if (NILP (overlay))
28303 mouse_face = Fget_text_property (position, Qmouse_face, object);
28305 /* Next, compute the bounds of the mouse highlighting and
28306 display it. */
28307 if (!NILP (mouse_face) && STRINGP (object))
28309 /* The mouse-highlighting comes from a display string
28310 with a mouse-face. */
28311 Lisp_Object s, e;
28312 ptrdiff_t ignore;
28314 s = Fprevious_single_property_change
28315 (make_number (pos + 1), Qmouse_face, object, Qnil);
28316 e = Fnext_single_property_change
28317 (position, Qmouse_face, object, Qnil);
28318 if (NILP (s))
28319 s = make_number (0);
28320 if (NILP (e))
28321 e = make_number (SCHARS (object) - 1);
28322 mouse_face_from_string_pos (w, hlinfo, object,
28323 XINT (s), XINT (e));
28324 hlinfo->mouse_face_past_end = 0;
28325 hlinfo->mouse_face_window = window;
28326 hlinfo->mouse_face_face_id
28327 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
28328 glyph->face_id, 1);
28329 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
28330 cursor = No_Cursor;
28332 else
28334 /* The mouse-highlighting, if any, comes from an overlay
28335 or text property in the buffer. */
28336 Lisp_Object buffer IF_LINT (= Qnil);
28337 Lisp_Object disp_string IF_LINT (= Qnil);
28339 if (STRINGP (object))
28341 /* If we are on a display string with no mouse-face,
28342 check if the text under it has one. */
28343 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
28344 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
28345 pos = string_buffer_position (object, start);
28346 if (pos > 0)
28348 mouse_face = get_char_property_and_overlay
28349 (make_number (pos), Qmouse_face, w->contents, &overlay);
28350 buffer = w->contents;
28351 disp_string = object;
28354 else
28356 buffer = object;
28357 disp_string = Qnil;
28360 if (!NILP (mouse_face))
28362 Lisp_Object before, after;
28363 Lisp_Object before_string, after_string;
28364 /* To correctly find the limits of mouse highlight
28365 in a bidi-reordered buffer, we must not use the
28366 optimization of limiting the search in
28367 previous-single-property-change and
28368 next-single-property-change, because
28369 rows_from_pos_range needs the real start and end
28370 positions to DTRT in this case. That's because
28371 the first row visible in a window does not
28372 necessarily display the character whose position
28373 is the smallest. */
28374 Lisp_Object lim1 =
28375 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
28376 ? Fmarker_position (w->start)
28377 : Qnil;
28378 Lisp_Object lim2 =
28379 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
28380 ? make_number (BUF_Z (XBUFFER (buffer))
28381 - XFASTINT (w->window_end_pos))
28382 : Qnil;
28384 if (NILP (overlay))
28386 /* Handle the text property case. */
28387 before = Fprevious_single_property_change
28388 (make_number (pos + 1), Qmouse_face, buffer, lim1);
28389 after = Fnext_single_property_change
28390 (make_number (pos), Qmouse_face, buffer, lim2);
28391 before_string = after_string = Qnil;
28393 else
28395 /* Handle the overlay case. */
28396 before = Foverlay_start (overlay);
28397 after = Foverlay_end (overlay);
28398 before_string = Foverlay_get (overlay, Qbefore_string);
28399 after_string = Foverlay_get (overlay, Qafter_string);
28401 if (!STRINGP (before_string)) before_string = Qnil;
28402 if (!STRINGP (after_string)) after_string = Qnil;
28405 mouse_face_from_buffer_pos (window, hlinfo, pos,
28406 NILP (before)
28408 : XFASTINT (before),
28409 NILP (after)
28410 ? BUF_Z (XBUFFER (buffer))
28411 : XFASTINT (after),
28412 before_string, after_string,
28413 disp_string);
28414 cursor = No_Cursor;
28419 check_help_echo:
28421 /* Look for a `help-echo' property. */
28422 if (NILP (help_echo_string)) {
28423 Lisp_Object help, overlay;
28425 /* Check overlays first. */
28426 help = overlay = Qnil;
28427 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
28429 overlay = overlay_vec[i];
28430 help = Foverlay_get (overlay, Qhelp_echo);
28433 if (!NILP (help))
28435 help_echo_string = help;
28436 help_echo_window = window;
28437 help_echo_object = overlay;
28438 help_echo_pos = pos;
28440 else
28442 Lisp_Object obj = glyph->object;
28443 ptrdiff_t charpos = glyph->charpos;
28445 /* Try text properties. */
28446 if (STRINGP (obj)
28447 && charpos >= 0
28448 && charpos < SCHARS (obj))
28450 help = Fget_text_property (make_number (charpos),
28451 Qhelp_echo, obj);
28452 if (NILP (help))
28454 /* If the string itself doesn't specify a help-echo,
28455 see if the buffer text ``under'' it does. */
28456 struct glyph_row *r
28457 = MATRIX_ROW (w->current_matrix, vpos);
28458 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
28459 ptrdiff_t p = string_buffer_position (obj, start);
28460 if (p > 0)
28462 help = Fget_char_property (make_number (p),
28463 Qhelp_echo, w->contents);
28464 if (!NILP (help))
28466 charpos = p;
28467 obj = w->contents;
28472 else if (BUFFERP (obj)
28473 && charpos >= BEGV
28474 && charpos < ZV)
28475 help = Fget_text_property (make_number (charpos), Qhelp_echo,
28476 obj);
28478 if (!NILP (help))
28480 help_echo_string = help;
28481 help_echo_window = window;
28482 help_echo_object = obj;
28483 help_echo_pos = charpos;
28488 #ifdef HAVE_WINDOW_SYSTEM
28489 /* Look for a `pointer' property. */
28490 if (FRAME_WINDOW_P (f) && NILP (pointer))
28492 /* Check overlays first. */
28493 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
28494 pointer = Foverlay_get (overlay_vec[i], Qpointer);
28496 if (NILP (pointer))
28498 Lisp_Object obj = glyph->object;
28499 ptrdiff_t charpos = glyph->charpos;
28501 /* Try text properties. */
28502 if (STRINGP (obj)
28503 && charpos >= 0
28504 && charpos < SCHARS (obj))
28506 pointer = Fget_text_property (make_number (charpos),
28507 Qpointer, obj);
28508 if (NILP (pointer))
28510 /* If the string itself doesn't specify a pointer,
28511 see if the buffer text ``under'' it does. */
28512 struct glyph_row *r
28513 = MATRIX_ROW (w->current_matrix, vpos);
28514 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
28515 ptrdiff_t p = string_buffer_position (obj, start);
28516 if (p > 0)
28517 pointer = Fget_char_property (make_number (p),
28518 Qpointer, w->contents);
28521 else if (BUFFERP (obj)
28522 && charpos >= BEGV
28523 && charpos < ZV)
28524 pointer = Fget_text_property (make_number (charpos),
28525 Qpointer, obj);
28528 #endif /* HAVE_WINDOW_SYSTEM */
28530 BEGV = obegv;
28531 ZV = ozv;
28532 current_buffer = obuf;
28535 set_cursor:
28537 #ifdef HAVE_WINDOW_SYSTEM
28538 if (FRAME_WINDOW_P (f))
28539 define_frame_cursor1 (f, cursor, pointer);
28540 #else
28541 /* This is here to prevent a compiler error, about "label at end of
28542 compound statement". */
28543 return;
28544 #endif
28548 /* EXPORT for RIF:
28549 Clear any mouse-face on window W. This function is part of the
28550 redisplay interface, and is called from try_window_id and similar
28551 functions to ensure the mouse-highlight is off. */
28553 void
28554 x_clear_window_mouse_face (struct window *w)
28556 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
28557 Lisp_Object window;
28559 block_input ();
28560 XSETWINDOW (window, w);
28561 if (EQ (window, hlinfo->mouse_face_window))
28562 clear_mouse_face (hlinfo);
28563 unblock_input ();
28567 /* EXPORT:
28568 Just discard the mouse face information for frame F, if any.
28569 This is used when the size of F is changed. */
28571 void
28572 cancel_mouse_face (struct frame *f)
28574 Lisp_Object window;
28575 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
28577 window = hlinfo->mouse_face_window;
28578 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
28580 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
28581 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
28582 hlinfo->mouse_face_window = Qnil;
28588 /***********************************************************************
28589 Exposure Events
28590 ***********************************************************************/
28592 #ifdef HAVE_WINDOW_SYSTEM
28594 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
28595 which intersects rectangle R. R is in window-relative coordinates. */
28597 static void
28598 expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
28599 enum glyph_row_area area)
28601 struct glyph *first = row->glyphs[area];
28602 struct glyph *end = row->glyphs[area] + row->used[area];
28603 struct glyph *last;
28604 int first_x, start_x, x;
28606 if (area == TEXT_AREA && row->fill_line_p)
28607 /* If row extends face to end of line write the whole line. */
28608 draw_glyphs (w, 0, row, area,
28609 0, row->used[area],
28610 DRAW_NORMAL_TEXT, 0);
28611 else
28613 /* Set START_X to the window-relative start position for drawing glyphs of
28614 AREA. The first glyph of the text area can be partially visible.
28615 The first glyphs of other areas cannot. */
28616 start_x = window_box_left_offset (w, area);
28617 x = start_x;
28618 if (area == TEXT_AREA)
28619 x += row->x;
28621 /* Find the first glyph that must be redrawn. */
28622 while (first < end
28623 && x + first->pixel_width < r->x)
28625 x += first->pixel_width;
28626 ++first;
28629 /* Find the last one. */
28630 last = first;
28631 first_x = x;
28632 while (last < end
28633 && x < r->x + r->width)
28635 x += last->pixel_width;
28636 ++last;
28639 /* Repaint. */
28640 if (last > first)
28641 draw_glyphs (w, first_x - start_x, row, area,
28642 first - row->glyphs[area], last - row->glyphs[area],
28643 DRAW_NORMAL_TEXT, 0);
28648 /* Redraw the parts of the glyph row ROW on window W intersecting
28649 rectangle R. R is in window-relative coordinates. Value is
28650 non-zero if mouse-face was overwritten. */
28652 static int
28653 expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
28655 eassert (row->enabled_p);
28657 if (row->mode_line_p || w->pseudo_window_p)
28658 draw_glyphs (w, 0, row, TEXT_AREA,
28659 0, row->used[TEXT_AREA],
28660 DRAW_NORMAL_TEXT, 0);
28661 else
28663 if (row->used[LEFT_MARGIN_AREA])
28664 expose_area (w, row, r, LEFT_MARGIN_AREA);
28665 if (row->used[TEXT_AREA])
28666 expose_area (w, row, r, TEXT_AREA);
28667 if (row->used[RIGHT_MARGIN_AREA])
28668 expose_area (w, row, r, RIGHT_MARGIN_AREA);
28669 draw_row_fringe_bitmaps (w, row);
28672 return row->mouse_face_p;
28676 /* Redraw those parts of glyphs rows during expose event handling that
28677 overlap other rows. Redrawing of an exposed line writes over parts
28678 of lines overlapping that exposed line; this function fixes that.
28680 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
28681 row in W's current matrix that is exposed and overlaps other rows.
28682 LAST_OVERLAPPING_ROW is the last such row. */
28684 static void
28685 expose_overlaps (struct window *w,
28686 struct glyph_row *first_overlapping_row,
28687 struct glyph_row *last_overlapping_row,
28688 XRectangle *r)
28690 struct glyph_row *row;
28692 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
28693 if (row->overlapping_p)
28695 eassert (row->enabled_p && !row->mode_line_p);
28697 row->clip = r;
28698 if (row->used[LEFT_MARGIN_AREA])
28699 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
28701 if (row->used[TEXT_AREA])
28702 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
28704 if (row->used[RIGHT_MARGIN_AREA])
28705 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
28706 row->clip = NULL;
28711 /* Return non-zero if W's cursor intersects rectangle R. */
28713 static int
28714 phys_cursor_in_rect_p (struct window *w, XRectangle *r)
28716 XRectangle cr, result;
28717 struct glyph *cursor_glyph;
28718 struct glyph_row *row;
28720 if (w->phys_cursor.vpos >= 0
28721 && w->phys_cursor.vpos < w->current_matrix->nrows
28722 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
28723 row->enabled_p)
28724 && row->cursor_in_fringe_p)
28726 /* Cursor is in the fringe. */
28727 cr.x = window_box_right_offset (w,
28728 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
28729 ? RIGHT_MARGIN_AREA
28730 : TEXT_AREA));
28731 cr.y = row->y;
28732 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
28733 cr.height = row->height;
28734 return x_intersect_rectangles (&cr, r, &result);
28737 cursor_glyph = get_phys_cursor_glyph (w);
28738 if (cursor_glyph)
28740 /* r is relative to W's box, but w->phys_cursor.x is relative
28741 to left edge of W's TEXT area. Adjust it. */
28742 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
28743 cr.y = w->phys_cursor.y;
28744 cr.width = cursor_glyph->pixel_width;
28745 cr.height = w->phys_cursor_height;
28746 /* ++KFS: W32 version used W32-specific IntersectRect here, but
28747 I assume the effect is the same -- and this is portable. */
28748 return x_intersect_rectangles (&cr, r, &result);
28750 /* If we don't understand the format, pretend we're not in the hot-spot. */
28751 return 0;
28755 /* EXPORT:
28756 Draw a vertical window border to the right of window W if W doesn't
28757 have vertical scroll bars. */
28759 void
28760 x_draw_vertical_border (struct window *w)
28762 struct frame *f = XFRAME (WINDOW_FRAME (w));
28764 /* We could do better, if we knew what type of scroll-bar the adjacent
28765 windows (on either side) have... But we don't :-(
28766 However, I think this works ok. ++KFS 2003-04-25 */
28768 /* Redraw borders between horizontally adjacent windows. Don't
28769 do it for frames with vertical scroll bars because either the
28770 right scroll bar of a window, or the left scroll bar of its
28771 neighbor will suffice as a border. */
28772 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
28773 return;
28775 /* Note: It is necessary to redraw both the left and the right
28776 borders, for when only this single window W is being
28777 redisplayed. */
28778 if (!WINDOW_RIGHTMOST_P (w)
28779 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
28781 int x0, x1, y0, y1;
28783 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
28784 y1 -= 1;
28786 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
28787 x1 -= 1;
28789 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
28791 if (!WINDOW_LEFTMOST_P (w)
28792 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
28794 int x0, x1, y0, y1;
28796 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
28797 y1 -= 1;
28799 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
28800 x0 -= 1;
28802 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
28807 /* Redraw the part of window W intersection rectangle FR. Pixel
28808 coordinates in FR are frame-relative. Call this function with
28809 input blocked. Value is non-zero if the exposure overwrites
28810 mouse-face. */
28812 static int
28813 expose_window (struct window *w, XRectangle *fr)
28815 struct frame *f = XFRAME (w->frame);
28816 XRectangle wr, r;
28817 int mouse_face_overwritten_p = 0;
28819 /* If window is not yet fully initialized, do nothing. This can
28820 happen when toolkit scroll bars are used and a window is split.
28821 Reconfiguring the scroll bar will generate an expose for a newly
28822 created window. */
28823 if (w->current_matrix == NULL)
28824 return 0;
28826 /* When we're currently updating the window, display and current
28827 matrix usually don't agree. Arrange for a thorough display
28828 later. */
28829 if (w->must_be_updated_p)
28831 SET_FRAME_GARBAGED (f);
28832 return 0;
28835 /* Frame-relative pixel rectangle of W. */
28836 wr.x = WINDOW_LEFT_EDGE_X (w);
28837 wr.y = WINDOW_TOP_EDGE_Y (w);
28838 wr.width = WINDOW_TOTAL_WIDTH (w);
28839 wr.height = WINDOW_TOTAL_HEIGHT (w);
28841 if (x_intersect_rectangles (fr, &wr, &r))
28843 int yb = window_text_bottom_y (w);
28844 struct glyph_row *row;
28845 int cursor_cleared_p, phys_cursor_on_p;
28846 struct glyph_row *first_overlapping_row, *last_overlapping_row;
28848 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
28849 r.x, r.y, r.width, r.height));
28851 /* Convert to window coordinates. */
28852 r.x -= WINDOW_LEFT_EDGE_X (w);
28853 r.y -= WINDOW_TOP_EDGE_Y (w);
28855 /* Turn off the cursor. */
28856 if (!w->pseudo_window_p
28857 && phys_cursor_in_rect_p (w, &r))
28859 x_clear_cursor (w);
28860 cursor_cleared_p = 1;
28862 else
28863 cursor_cleared_p = 0;
28865 /* If the row containing the cursor extends face to end of line,
28866 then expose_area might overwrite the cursor outside the
28867 rectangle and thus notice_overwritten_cursor might clear
28868 w->phys_cursor_on_p. We remember the original value and
28869 check later if it is changed. */
28870 phys_cursor_on_p = w->phys_cursor_on_p;
28872 /* Update lines intersecting rectangle R. */
28873 first_overlapping_row = last_overlapping_row = NULL;
28874 for (row = w->current_matrix->rows;
28875 row->enabled_p;
28876 ++row)
28878 int y0 = row->y;
28879 int y1 = MATRIX_ROW_BOTTOM_Y (row);
28881 if ((y0 >= r.y && y0 < r.y + r.height)
28882 || (y1 > r.y && y1 < r.y + r.height)
28883 || (r.y >= y0 && r.y < y1)
28884 || (r.y + r.height > y0 && r.y + r.height < y1))
28886 /* A header line may be overlapping, but there is no need
28887 to fix overlapping areas for them. KFS 2005-02-12 */
28888 if (row->overlapping_p && !row->mode_line_p)
28890 if (first_overlapping_row == NULL)
28891 first_overlapping_row = row;
28892 last_overlapping_row = row;
28895 row->clip = fr;
28896 if (expose_line (w, row, &r))
28897 mouse_face_overwritten_p = 1;
28898 row->clip = NULL;
28900 else if (row->overlapping_p)
28902 /* We must redraw a row overlapping the exposed area. */
28903 if (y0 < r.y
28904 ? y0 + row->phys_height > r.y
28905 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
28907 if (first_overlapping_row == NULL)
28908 first_overlapping_row = row;
28909 last_overlapping_row = row;
28913 if (y1 >= yb)
28914 break;
28917 /* Display the mode line if there is one. */
28918 if (WINDOW_WANTS_MODELINE_P (w)
28919 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
28920 row->enabled_p)
28921 && row->y < r.y + r.height)
28923 if (expose_line (w, row, &r))
28924 mouse_face_overwritten_p = 1;
28927 if (!w->pseudo_window_p)
28929 /* Fix the display of overlapping rows. */
28930 if (first_overlapping_row)
28931 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
28932 fr);
28934 /* Draw border between windows. */
28935 x_draw_vertical_border (w);
28937 /* Turn the cursor on again. */
28938 if (cursor_cleared_p
28939 || (phys_cursor_on_p && !w->phys_cursor_on_p))
28940 update_window_cursor (w, 1);
28944 return mouse_face_overwritten_p;
28949 /* Redraw (parts) of all windows in the window tree rooted at W that
28950 intersect R. R contains frame pixel coordinates. Value is
28951 non-zero if the exposure overwrites mouse-face. */
28953 static int
28954 expose_window_tree (struct window *w, XRectangle *r)
28956 struct frame *f = XFRAME (w->frame);
28957 int mouse_face_overwritten_p = 0;
28959 while (w && !FRAME_GARBAGED_P (f))
28961 if (WINDOWP (w->contents))
28962 mouse_face_overwritten_p
28963 |= expose_window_tree (XWINDOW (w->contents), r);
28964 else
28965 mouse_face_overwritten_p |= expose_window (w, r);
28967 w = NILP (w->next) ? NULL : XWINDOW (w->next);
28970 return mouse_face_overwritten_p;
28974 /* EXPORT:
28975 Redisplay an exposed area of frame F. X and Y are the upper-left
28976 corner of the exposed rectangle. W and H are width and height of
28977 the exposed area. All are pixel values. W or H zero means redraw
28978 the entire frame. */
28980 void
28981 expose_frame (struct frame *f, int x, int y, int w, int h)
28983 XRectangle r;
28984 int mouse_face_overwritten_p = 0;
28986 TRACE ((stderr, "expose_frame "));
28988 /* No need to redraw if frame will be redrawn soon. */
28989 if (FRAME_GARBAGED_P (f))
28991 TRACE ((stderr, " garbaged\n"));
28992 return;
28995 /* If basic faces haven't been realized yet, there is no point in
28996 trying to redraw anything. This can happen when we get an expose
28997 event while Emacs is starting, e.g. by moving another window. */
28998 if (FRAME_FACE_CACHE (f) == NULL
28999 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
29001 TRACE ((stderr, " no faces\n"));
29002 return;
29005 if (w == 0 || h == 0)
29007 r.x = r.y = 0;
29008 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
29009 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
29011 else
29013 r.x = x;
29014 r.y = y;
29015 r.width = w;
29016 r.height = h;
29019 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
29020 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
29022 if (WINDOWP (f->tool_bar_window))
29023 mouse_face_overwritten_p
29024 |= expose_window (XWINDOW (f->tool_bar_window), &r);
29026 #ifdef HAVE_X_WINDOWS
29027 #ifndef MSDOS
29028 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
29029 if (WINDOWP (f->menu_bar_window))
29030 mouse_face_overwritten_p
29031 |= expose_window (XWINDOW (f->menu_bar_window), &r);
29032 #endif /* not USE_X_TOOLKIT and not USE_GTK */
29033 #endif
29034 #endif
29036 /* Some window managers support a focus-follows-mouse style with
29037 delayed raising of frames. Imagine a partially obscured frame,
29038 and moving the mouse into partially obscured mouse-face on that
29039 frame. The visible part of the mouse-face will be highlighted,
29040 then the WM raises the obscured frame. With at least one WM, KDE
29041 2.1, Emacs is not getting any event for the raising of the frame
29042 (even tried with SubstructureRedirectMask), only Expose events.
29043 These expose events will draw text normally, i.e. not
29044 highlighted. Which means we must redo the highlight here.
29045 Subsume it under ``we love X''. --gerd 2001-08-15 */
29046 /* Included in Windows version because Windows most likely does not
29047 do the right thing if any third party tool offers
29048 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
29049 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
29051 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
29052 if (f == hlinfo->mouse_face_mouse_frame)
29054 int mouse_x = hlinfo->mouse_face_mouse_x;
29055 int mouse_y = hlinfo->mouse_face_mouse_y;
29056 clear_mouse_face (hlinfo);
29057 note_mouse_highlight (f, mouse_x, mouse_y);
29063 /* EXPORT:
29064 Determine the intersection of two rectangles R1 and R2. Return
29065 the intersection in *RESULT. Value is non-zero if RESULT is not
29066 empty. */
29069 x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
29071 XRectangle *left, *right;
29072 XRectangle *upper, *lower;
29073 int intersection_p = 0;
29075 /* Rearrange so that R1 is the left-most rectangle. */
29076 if (r1->x < r2->x)
29077 left = r1, right = r2;
29078 else
29079 left = r2, right = r1;
29081 /* X0 of the intersection is right.x0, if this is inside R1,
29082 otherwise there is no intersection. */
29083 if (right->x <= left->x + left->width)
29085 result->x = right->x;
29087 /* The right end of the intersection is the minimum of
29088 the right ends of left and right. */
29089 result->width = (min (left->x + left->width, right->x + right->width)
29090 - result->x);
29092 /* Same game for Y. */
29093 if (r1->y < r2->y)
29094 upper = r1, lower = r2;
29095 else
29096 upper = r2, lower = r1;
29098 /* The upper end of the intersection is lower.y0, if this is inside
29099 of upper. Otherwise, there is no intersection. */
29100 if (lower->y <= upper->y + upper->height)
29102 result->y = lower->y;
29104 /* The lower end of the intersection is the minimum of the lower
29105 ends of upper and lower. */
29106 result->height = (min (lower->y + lower->height,
29107 upper->y + upper->height)
29108 - result->y);
29109 intersection_p = 1;
29113 return intersection_p;
29116 #endif /* HAVE_WINDOW_SYSTEM */
29119 /***********************************************************************
29120 Initialization
29121 ***********************************************************************/
29123 void
29124 syms_of_xdisp (void)
29126 Vwith_echo_area_save_vector = Qnil;
29127 staticpro (&Vwith_echo_area_save_vector);
29129 Vmessage_stack = Qnil;
29130 staticpro (&Vmessage_stack);
29132 DEFSYM (Qinhibit_redisplay, "inhibit-redisplay");
29133 DEFSYM (Qredisplay_internal, "redisplay_internal (C function)");
29135 message_dolog_marker1 = Fmake_marker ();
29136 staticpro (&message_dolog_marker1);
29137 message_dolog_marker2 = Fmake_marker ();
29138 staticpro (&message_dolog_marker2);
29139 message_dolog_marker3 = Fmake_marker ();
29140 staticpro (&message_dolog_marker3);
29142 #ifdef GLYPH_DEBUG
29143 defsubr (&Sdump_frame_glyph_matrix);
29144 defsubr (&Sdump_glyph_matrix);
29145 defsubr (&Sdump_glyph_row);
29146 defsubr (&Sdump_tool_bar_row);
29147 defsubr (&Strace_redisplay);
29148 defsubr (&Strace_to_stderr);
29149 #endif
29150 #ifdef HAVE_WINDOW_SYSTEM
29151 defsubr (&Stool_bar_lines_needed);
29152 defsubr (&Slookup_image_map);
29153 #endif
29154 defsubr (&Sline_pixel_height);
29155 defsubr (&Sformat_mode_line);
29156 defsubr (&Sinvisible_p);
29157 defsubr (&Scurrent_bidi_paragraph_direction);
29158 defsubr (&Smove_point_visually);
29160 DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook");
29161 DEFSYM (Qoverriding_terminal_local_map, "overriding-terminal-local-map");
29162 DEFSYM (Qoverriding_local_map, "overriding-local-map");
29163 DEFSYM (Qwindow_scroll_functions, "window-scroll-functions");
29164 DEFSYM (Qwindow_text_change_functions, "window-text-change-functions");
29165 DEFSYM (Qredisplay_end_trigger_functions, "redisplay-end-trigger-functions");
29166 DEFSYM (Qinhibit_point_motion_hooks, "inhibit-point-motion-hooks");
29167 DEFSYM (Qeval, "eval");
29168 DEFSYM (QCdata, ":data");
29169 DEFSYM (Qdisplay, "display");
29170 DEFSYM (Qspace_width, "space-width");
29171 DEFSYM (Qraise, "raise");
29172 DEFSYM (Qslice, "slice");
29173 DEFSYM (Qspace, "space");
29174 DEFSYM (Qmargin, "margin");
29175 DEFSYM (Qpointer, "pointer");
29176 DEFSYM (Qleft_margin, "left-margin");
29177 DEFSYM (Qright_margin, "right-margin");
29178 DEFSYM (Qcenter, "center");
29179 DEFSYM (Qline_height, "line-height");
29180 DEFSYM (QCalign_to, ":align-to");
29181 DEFSYM (QCrelative_width, ":relative-width");
29182 DEFSYM (QCrelative_height, ":relative-height");
29183 DEFSYM (QCeval, ":eval");
29184 DEFSYM (QCpropertize, ":propertize");
29185 DEFSYM (QCfile, ":file");
29186 DEFSYM (Qfontified, "fontified");
29187 DEFSYM (Qfontification_functions, "fontification-functions");
29188 DEFSYM (Qtrailing_whitespace, "trailing-whitespace");
29189 DEFSYM (Qescape_glyph, "escape-glyph");
29190 DEFSYM (Qnobreak_space, "nobreak-space");
29191 DEFSYM (Qimage, "image");
29192 DEFSYM (Qtext, "text");
29193 DEFSYM (Qboth, "both");
29194 DEFSYM (Qboth_horiz, "both-horiz");
29195 DEFSYM (Qtext_image_horiz, "text-image-horiz");
29196 DEFSYM (QCmap, ":map");
29197 DEFSYM (QCpointer, ":pointer");
29198 DEFSYM (Qrect, "rect");
29199 DEFSYM (Qcircle, "circle");
29200 DEFSYM (Qpoly, "poly");
29201 DEFSYM (Qmessage_truncate_lines, "message-truncate-lines");
29202 DEFSYM (Qgrow_only, "grow-only");
29203 DEFSYM (Qinhibit_menubar_update, "inhibit-menubar-update");
29204 DEFSYM (Qinhibit_eval_during_redisplay, "inhibit-eval-during-redisplay");
29205 DEFSYM (Qposition, "position");
29206 DEFSYM (Qbuffer_position, "buffer-position");
29207 DEFSYM (Qobject, "object");
29208 DEFSYM (Qbar, "bar");
29209 DEFSYM (Qhbar, "hbar");
29210 DEFSYM (Qbox, "box");
29211 DEFSYM (Qhollow, "hollow");
29212 DEFSYM (Qhand, "hand");
29213 DEFSYM (Qarrow, "arrow");
29214 DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces");
29216 list_of_error = list1 (list2 (intern_c_string ("error"),
29217 intern_c_string ("void-variable")));
29218 staticpro (&list_of_error);
29220 DEFSYM (Qlast_arrow_position, "last-arrow-position");
29221 DEFSYM (Qlast_arrow_string, "last-arrow-string");
29222 DEFSYM (Qoverlay_arrow_string, "overlay-arrow-string");
29223 DEFSYM (Qoverlay_arrow_bitmap, "overlay-arrow-bitmap");
29225 echo_buffer[0] = echo_buffer[1] = Qnil;
29226 staticpro (&echo_buffer[0]);
29227 staticpro (&echo_buffer[1]);
29229 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
29230 staticpro (&echo_area_buffer[0]);
29231 staticpro (&echo_area_buffer[1]);
29233 Vmessages_buffer_name = build_pure_c_string ("*Messages*");
29234 staticpro (&Vmessages_buffer_name);
29236 mode_line_proptrans_alist = Qnil;
29237 staticpro (&mode_line_proptrans_alist);
29238 mode_line_string_list = Qnil;
29239 staticpro (&mode_line_string_list);
29240 mode_line_string_face = Qnil;
29241 staticpro (&mode_line_string_face);
29242 mode_line_string_face_prop = Qnil;
29243 staticpro (&mode_line_string_face_prop);
29244 Vmode_line_unwind_vector = Qnil;
29245 staticpro (&Vmode_line_unwind_vector);
29247 DEFSYM (Qmode_line_default_help_echo, "mode-line-default-help-echo");
29249 help_echo_string = Qnil;
29250 staticpro (&help_echo_string);
29251 help_echo_object = Qnil;
29252 staticpro (&help_echo_object);
29253 help_echo_window = Qnil;
29254 staticpro (&help_echo_window);
29255 previous_help_echo_string = Qnil;
29256 staticpro (&previous_help_echo_string);
29257 help_echo_pos = -1;
29259 DEFSYM (Qright_to_left, "right-to-left");
29260 DEFSYM (Qleft_to_right, "left-to-right");
29262 #ifdef HAVE_WINDOW_SYSTEM
29263 DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p,
29264 doc: /* Non-nil means draw block cursor as wide as the glyph under it.
29265 For example, if a block cursor is over a tab, it will be drawn as
29266 wide as that tab on the display. */);
29267 x_stretch_cursor_p = 0;
29268 #endif
29270 DEFVAR_LISP ("show-trailing-whitespace", Vshow_trailing_whitespace,
29271 doc: /* Non-nil means highlight trailing whitespace.
29272 The face used for trailing whitespace is `trailing-whitespace'. */);
29273 Vshow_trailing_whitespace = Qnil;
29275 DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display,
29276 doc: /* Control highlighting of non-ASCII space and hyphen chars.
29277 If the value is t, Emacs highlights non-ASCII chars which have the
29278 same appearance as an ASCII space or hyphen, using the `nobreak-space'
29279 or `escape-glyph' face respectively.
29281 U+00A0 (no-break space), U+00AD (soft hyphen), U+2010 (hyphen), and
29282 U+2011 (non-breaking hyphen) are affected.
29284 Any other non-nil value means to display these characters as a escape
29285 glyph followed by an ordinary space or hyphen.
29287 A value of nil means no special handling of these characters. */);
29288 Vnobreak_char_display = Qt;
29290 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer,
29291 doc: /* The pointer shape to show in void text areas.
29292 A value of nil means to show the text pointer. Other options are `arrow',
29293 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
29294 Vvoid_text_area_pointer = Qarrow;
29296 DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay,
29297 doc: /* Non-nil means don't actually do any redisplay.
29298 This is used for internal purposes. */);
29299 Vinhibit_redisplay = Qnil;
29301 DEFVAR_LISP ("global-mode-string", Vglobal_mode_string,
29302 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
29303 Vglobal_mode_string = Qnil;
29305 DEFVAR_LISP ("overlay-arrow-position", Voverlay_arrow_position,
29306 doc: /* Marker for where to display an arrow on top of the buffer text.
29307 This must be the beginning of a line in order to work.
29308 See also `overlay-arrow-string'. */);
29309 Voverlay_arrow_position = Qnil;
29311 DEFVAR_LISP ("overlay-arrow-string", Voverlay_arrow_string,
29312 doc: /* String to display as an arrow in non-window frames.
29313 See also `overlay-arrow-position'. */);
29314 Voverlay_arrow_string = build_pure_c_string ("=>");
29316 DEFVAR_LISP ("overlay-arrow-variable-list", Voverlay_arrow_variable_list,
29317 doc: /* List of variables (symbols) which hold markers for overlay arrows.
29318 The symbols on this list are examined during redisplay to determine
29319 where to display overlay arrows. */);
29320 Voverlay_arrow_variable_list
29321 = list1 (intern_c_string ("overlay-arrow-position"));
29323 DEFVAR_INT ("scroll-step", emacs_scroll_step,
29324 doc: /* The number of lines to try scrolling a window by when point moves out.
29325 If that fails to bring point back on frame, point is centered instead.
29326 If this is zero, point is always centered after it moves off frame.
29327 If you want scrolling to always be a line at a time, you should set
29328 `scroll-conservatively' to a large value rather than set this to 1. */);
29330 DEFVAR_INT ("scroll-conservatively", scroll_conservatively,
29331 doc: /* Scroll up to this many lines, to bring point back on screen.
29332 If point moves off-screen, redisplay will scroll by up to
29333 `scroll-conservatively' lines in order to bring point just barely
29334 onto the screen again. If that cannot be done, then redisplay
29335 recenters point as usual.
29337 If the value is greater than 100, redisplay will never recenter point,
29338 but will always scroll just enough text to bring point into view, even
29339 if you move far away.
29341 A value of zero means always recenter point if it moves off screen. */);
29342 scroll_conservatively = 0;
29344 DEFVAR_INT ("scroll-margin", scroll_margin,
29345 doc: /* Number of lines of margin at the top and bottom of a window.
29346 Recenter the window whenever point gets within this many lines
29347 of the top or bottom of the window. */);
29348 scroll_margin = 0;
29350 DEFVAR_LISP ("display-pixels-per-inch", Vdisplay_pixels_per_inch,
29351 doc: /* Pixels per inch value for non-window system displays.
29352 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
29353 Vdisplay_pixels_per_inch = make_float (72.0);
29355 #ifdef GLYPH_DEBUG
29356 DEFVAR_INT ("debug-end-pos", debug_end_pos, doc: /* Don't ask. */);
29357 #endif
29359 DEFVAR_LISP ("truncate-partial-width-windows",
29360 Vtruncate_partial_width_windows,
29361 doc: /* Non-nil means truncate lines in windows narrower than the frame.
29362 For an integer value, truncate lines in each window narrower than the
29363 full frame width, provided the window width is less than that integer;
29364 otherwise, respect the value of `truncate-lines'.
29366 For any other non-nil value, truncate lines in all windows that do
29367 not span the full frame width.
29369 A value of nil means to respect the value of `truncate-lines'.
29371 If `word-wrap' is enabled, you might want to reduce this. */);
29372 Vtruncate_partial_width_windows = make_number (50);
29374 DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit,
29375 doc: /* Maximum buffer size for which line number should be displayed.
29376 If the buffer is bigger than this, the line number does not appear
29377 in the mode line. A value of nil means no limit. */);
29378 Vline_number_display_limit = Qnil;
29380 DEFVAR_INT ("line-number-display-limit-width",
29381 line_number_display_limit_width,
29382 doc: /* Maximum line width (in characters) for line number display.
29383 If the average length of the lines near point is bigger than this, then the
29384 line number may be omitted from the mode line. */);
29385 line_number_display_limit_width = 200;
29387 DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows,
29388 doc: /* Non-nil means highlight region even in nonselected windows. */);
29389 highlight_nonselected_windows = 0;
29391 DEFVAR_BOOL ("multiple-frames", multiple_frames,
29392 doc: /* Non-nil if more than one frame is visible on this display.
29393 Minibuffer-only frames don't count, but iconified frames do.
29394 This variable is not guaranteed to be accurate except while processing
29395 `frame-title-format' and `icon-title-format'. */);
29397 DEFVAR_LISP ("frame-title-format", Vframe_title_format,
29398 doc: /* Template for displaying the title bar of visible frames.
29399 \(Assuming the window manager supports this feature.)
29401 This variable has the same structure as `mode-line-format', except that
29402 the %c and %l constructs are ignored. It is used only on frames for
29403 which no explicit name has been set \(see `modify-frame-parameters'). */);
29405 DEFVAR_LISP ("icon-title-format", Vicon_title_format,
29406 doc: /* Template for displaying the title bar of an iconified frame.
29407 \(Assuming the window manager supports this feature.)
29408 This variable has the same structure as `mode-line-format' (which see),
29409 and is used only on frames for which no explicit name has been set
29410 \(see `modify-frame-parameters'). */);
29411 Vicon_title_format
29412 = Vframe_title_format
29413 = listn (CONSTYPE_PURE, 3,
29414 intern_c_string ("multiple-frames"),
29415 build_pure_c_string ("%b"),
29416 listn (CONSTYPE_PURE, 4,
29417 empty_unibyte_string,
29418 intern_c_string ("invocation-name"),
29419 build_pure_c_string ("@"),
29420 intern_c_string ("system-name")));
29422 DEFVAR_LISP ("message-log-max", Vmessage_log_max,
29423 doc: /* Maximum number of lines to keep in the message log buffer.
29424 If nil, disable message logging. If t, log messages but don't truncate
29425 the buffer when it becomes large. */);
29426 Vmessage_log_max = make_number (1000);
29428 DEFVAR_LISP ("window-size-change-functions", Vwindow_size_change_functions,
29429 doc: /* Functions called before redisplay, if window sizes have changed.
29430 The value should be a list of functions that take one argument.
29431 Just before redisplay, for each frame, if any of its windows have changed
29432 size since the last redisplay, or have been split or deleted,
29433 all the functions in the list are called, with the frame as argument. */);
29434 Vwindow_size_change_functions = Qnil;
29436 DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions,
29437 doc: /* List of functions to call before redisplaying a window with scrolling.
29438 Each function is called with two arguments, the window and its new
29439 display-start position. Note that these functions are also called by
29440 `set-window-buffer'. Also note that the value of `window-end' is not
29441 valid when these functions are called.
29443 Warning: Do not use this feature to alter the way the window
29444 is scrolled. It is not designed for that, and such use probably won't
29445 work. */);
29446 Vwindow_scroll_functions = Qnil;
29448 DEFVAR_LISP ("window-text-change-functions",
29449 Vwindow_text_change_functions,
29450 doc: /* Functions to call in redisplay when text in the window might change. */);
29451 Vwindow_text_change_functions = Qnil;
29453 DEFVAR_LISP ("redisplay-end-trigger-functions", Vredisplay_end_trigger_functions,
29454 doc: /* Functions called when redisplay of a window reaches the end trigger.
29455 Each function is called with two arguments, the window and the end trigger value.
29456 See `set-window-redisplay-end-trigger'. */);
29457 Vredisplay_end_trigger_functions = Qnil;
29459 DEFVAR_LISP ("mouse-autoselect-window", Vmouse_autoselect_window,
29460 doc: /* Non-nil means autoselect window with mouse pointer.
29461 If nil, do not autoselect windows.
29462 A positive number means delay autoselection by that many seconds: a
29463 window is autoselected only after the mouse has remained in that
29464 window for the duration of the delay.
29465 A negative number has a similar effect, but causes windows to be
29466 autoselected only after the mouse has stopped moving. \(Because of
29467 the way Emacs compares mouse events, you will occasionally wait twice
29468 that time before the window gets selected.\)
29469 Any other value means to autoselect window instantaneously when the
29470 mouse pointer enters it.
29472 Autoselection selects the minibuffer only if it is active, and never
29473 unselects the minibuffer if it is active.
29475 When customizing this variable make sure that the actual value of
29476 `focus-follows-mouse' matches the behavior of your window manager. */);
29477 Vmouse_autoselect_window = Qnil;
29479 DEFVAR_LISP ("auto-resize-tool-bars", Vauto_resize_tool_bars,
29480 doc: /* Non-nil means automatically resize tool-bars.
29481 This dynamically changes the tool-bar's height to the minimum height
29482 that is needed to make all tool-bar items visible.
29483 If value is `grow-only', the tool-bar's height is only increased
29484 automatically; to decrease the tool-bar height, use \\[recenter]. */);
29485 Vauto_resize_tool_bars = Qt;
29487 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p,
29488 doc: /* Non-nil means raise tool-bar buttons when the mouse moves over them. */);
29489 auto_raise_tool_bar_buttons_p = 1;
29491 DEFVAR_BOOL ("make-cursor-line-fully-visible", make_cursor_line_fully_visible_p,
29492 doc: /* Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
29493 make_cursor_line_fully_visible_p = 1;
29495 DEFVAR_LISP ("tool-bar-border", Vtool_bar_border,
29496 doc: /* Border below tool-bar in pixels.
29497 If an integer, use it as the height of the border.
29498 If it is one of `internal-border-width' or `border-width', use the
29499 value of the corresponding frame parameter.
29500 Otherwise, no border is added below the tool-bar. */);
29501 Vtool_bar_border = Qinternal_border_width;
29503 DEFVAR_LISP ("tool-bar-button-margin", Vtool_bar_button_margin,
29504 doc: /* Margin around tool-bar buttons in pixels.
29505 If an integer, use that for both horizontal and vertical margins.
29506 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
29507 HORZ specifying the horizontal margin, and VERT specifying the
29508 vertical margin. */);
29509 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
29511 DEFVAR_INT ("tool-bar-button-relief", tool_bar_button_relief,
29512 doc: /* Relief thickness of tool-bar buttons. */);
29513 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
29515 DEFVAR_LISP ("tool-bar-style", Vtool_bar_style,
29516 doc: /* Tool bar style to use.
29517 It can be one of
29518 image - show images only
29519 text - show text only
29520 both - show both, text below image
29521 both-horiz - show text to the right of the image
29522 text-image-horiz - show text to the left of the image
29523 any other - use system default or image if no system default.
29525 This variable only affects the GTK+ toolkit version of Emacs. */);
29526 Vtool_bar_style = Qnil;
29528 DEFVAR_INT ("tool-bar-max-label-size", tool_bar_max_label_size,
29529 doc: /* Maximum number of characters a label can have to be shown.
29530 The tool bar style must also show labels for this to have any effect, see
29531 `tool-bar-style'. */);
29532 tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
29534 DEFVAR_LISP ("fontification-functions", Vfontification_functions,
29535 doc: /* List of functions to call to fontify regions of text.
29536 Each function is called with one argument POS. Functions must
29537 fontify a region starting at POS in the current buffer, and give
29538 fontified regions the property `fontified'. */);
29539 Vfontification_functions = Qnil;
29540 Fmake_variable_buffer_local (Qfontification_functions);
29542 DEFVAR_BOOL ("unibyte-display-via-language-environment",
29543 unibyte_display_via_language_environment,
29544 doc: /* Non-nil means display unibyte text according to language environment.
29545 Specifically, this means that raw bytes in the range 160-255 decimal
29546 are displayed by converting them to the equivalent multibyte characters
29547 according to the current language environment. As a result, they are
29548 displayed according to the current fontset.
29550 Note that this variable affects only how these bytes are displayed,
29551 but does not change the fact they are interpreted as raw bytes. */);
29552 unibyte_display_via_language_environment = 0;
29554 DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height,
29555 doc: /* Maximum height for resizing mini-windows (the minibuffer and the echo area).
29556 If a float, it specifies a fraction of the mini-window frame's height.
29557 If an integer, it specifies a number of lines. */);
29558 Vmax_mini_window_height = make_float (0.25);
29560 DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows,
29561 doc: /* How to resize mini-windows (the minibuffer and the echo area).
29562 A value of nil means don't automatically resize mini-windows.
29563 A value of t means resize them to fit the text displayed in them.
29564 A value of `grow-only', the default, means let mini-windows grow only;
29565 they return to their normal size when the minibuffer is closed, or the
29566 echo area becomes empty. */);
29567 Vresize_mini_windows = Qgrow_only;
29569 DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist,
29570 doc: /* Alist specifying how to blink the cursor off.
29571 Each element has the form (ON-STATE . OFF-STATE). Whenever the
29572 `cursor-type' frame-parameter or variable equals ON-STATE,
29573 comparing using `equal', Emacs uses OFF-STATE to specify
29574 how to blink it off. ON-STATE and OFF-STATE are values for
29575 the `cursor-type' frame parameter.
29577 If a frame's ON-STATE has no entry in this list,
29578 the frame's other specifications determine how to blink the cursor off. */);
29579 Vblink_cursor_alist = Qnil;
29581 DEFVAR_BOOL ("auto-hscroll-mode", automatic_hscrolling_p,
29582 doc: /* Allow or disallow automatic horizontal scrolling of windows.
29583 If non-nil, windows are automatically scrolled horizontally to make
29584 point visible. */);
29585 automatic_hscrolling_p = 1;
29586 DEFSYM (Qauto_hscroll_mode, "auto-hscroll-mode");
29588 DEFVAR_INT ("hscroll-margin", hscroll_margin,
29589 doc: /* How many columns away from the window edge point is allowed to get
29590 before automatic hscrolling will horizontally scroll the window. */);
29591 hscroll_margin = 5;
29593 DEFVAR_LISP ("hscroll-step", Vhscroll_step,
29594 doc: /* How many columns to scroll the window when point gets too close to the edge.
29595 When point is less than `hscroll-margin' columns from the window
29596 edge, automatic hscrolling will scroll the window by the amount of columns
29597 determined by this variable. If its value is a positive integer, scroll that
29598 many columns. If it's a positive floating-point number, it specifies the
29599 fraction of the window's width to scroll. If it's nil or zero, point will be
29600 centered horizontally after the scroll. Any other value, including negative
29601 numbers, are treated as if the value were zero.
29603 Automatic hscrolling always moves point outside the scroll margin, so if
29604 point was more than scroll step columns inside the margin, the window will
29605 scroll more than the value given by the scroll step.
29607 Note that the lower bound for automatic hscrolling specified by `scroll-left'
29608 and `scroll-right' overrides this variable's effect. */);
29609 Vhscroll_step = make_number (0);
29611 DEFVAR_BOOL ("message-truncate-lines", message_truncate_lines,
29612 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
29613 Bind this around calls to `message' to let it take effect. */);
29614 message_truncate_lines = 0;
29616 DEFVAR_LISP ("menu-bar-update-hook", Vmenu_bar_update_hook,
29617 doc: /* Normal hook run to update the menu bar definitions.
29618 Redisplay runs this hook before it redisplays the menu bar.
29619 This is used to update submenus such as Buffers,
29620 whose contents depend on various data. */);
29621 Vmenu_bar_update_hook = Qnil;
29623 DEFVAR_LISP ("menu-updating-frame", Vmenu_updating_frame,
29624 doc: /* Frame for which we are updating a menu.
29625 The enable predicate for a menu binding should check this variable. */);
29626 Vmenu_updating_frame = Qnil;
29628 DEFVAR_BOOL ("inhibit-menubar-update", inhibit_menubar_update,
29629 doc: /* Non-nil means don't update menu bars. Internal use only. */);
29630 inhibit_menubar_update = 0;
29632 DEFVAR_LISP ("wrap-prefix", Vwrap_prefix,
29633 doc: /* Prefix prepended to all continuation lines at display time.
29634 The value may be a string, an image, or a stretch-glyph; it is
29635 interpreted in the same way as the value of a `display' text property.
29637 This variable is overridden by any `wrap-prefix' text or overlay
29638 property.
29640 To add a prefix to non-continuation lines, use `line-prefix'. */);
29641 Vwrap_prefix = Qnil;
29642 DEFSYM (Qwrap_prefix, "wrap-prefix");
29643 Fmake_variable_buffer_local (Qwrap_prefix);
29645 DEFVAR_LISP ("line-prefix", Vline_prefix,
29646 doc: /* Prefix prepended to all non-continuation lines at display time.
29647 The value may be a string, an image, or a stretch-glyph; it is
29648 interpreted in the same way as the value of a `display' text property.
29650 This variable is overridden by any `line-prefix' text or overlay
29651 property.
29653 To add a prefix to continuation lines, use `wrap-prefix'. */);
29654 Vline_prefix = Qnil;
29655 DEFSYM (Qline_prefix, "line-prefix");
29656 Fmake_variable_buffer_local (Qline_prefix);
29658 DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay,
29659 doc: /* Non-nil means don't eval Lisp during redisplay. */);
29660 inhibit_eval_during_redisplay = 0;
29662 DEFVAR_BOOL ("inhibit-free-realized-faces", inhibit_free_realized_faces,
29663 doc: /* Non-nil means don't free realized faces. Internal use only. */);
29664 inhibit_free_realized_faces = 0;
29666 #ifdef GLYPH_DEBUG
29667 DEFVAR_BOOL ("inhibit-try-window-id", inhibit_try_window_id,
29668 doc: /* Inhibit try_window_id display optimization. */);
29669 inhibit_try_window_id = 0;
29671 DEFVAR_BOOL ("inhibit-try-window-reusing", inhibit_try_window_reusing,
29672 doc: /* Inhibit try_window_reusing display optimization. */);
29673 inhibit_try_window_reusing = 0;
29675 DEFVAR_BOOL ("inhibit-try-cursor-movement", inhibit_try_cursor_movement,
29676 doc: /* Inhibit try_cursor_movement display optimization. */);
29677 inhibit_try_cursor_movement = 0;
29678 #endif /* GLYPH_DEBUG */
29680 DEFVAR_INT ("overline-margin", overline_margin,
29681 doc: /* Space between overline and text, in pixels.
29682 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
29683 margin to the character height. */);
29684 overline_margin = 2;
29686 DEFVAR_INT ("underline-minimum-offset",
29687 underline_minimum_offset,
29688 doc: /* Minimum distance between baseline and underline.
29689 This can improve legibility of underlined text at small font sizes,
29690 particularly when using variable `x-use-underline-position-properties'
29691 with fonts that specify an UNDERLINE_POSITION relatively close to the
29692 baseline. The default value is 1. */);
29693 underline_minimum_offset = 1;
29695 DEFVAR_BOOL ("display-hourglass", display_hourglass_p,
29696 doc: /* Non-nil means show an hourglass pointer, when Emacs is busy.
29697 This feature only works when on a window system that can change
29698 cursor shapes. */);
29699 display_hourglass_p = 1;
29701 DEFVAR_LISP ("hourglass-delay", Vhourglass_delay,
29702 doc: /* Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
29703 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
29705 hourglass_atimer = NULL;
29706 hourglass_shown_p = 0;
29708 DEFSYM (Qglyphless_char, "glyphless-char");
29709 DEFSYM (Qhex_code, "hex-code");
29710 DEFSYM (Qempty_box, "empty-box");
29711 DEFSYM (Qthin_space, "thin-space");
29712 DEFSYM (Qzero_width, "zero-width");
29714 DEFSYM (Qglyphless_char_display, "glyphless-char-display");
29715 /* Intern this now in case it isn't already done.
29716 Setting this variable twice is harmless.
29717 But don't staticpro it here--that is done in alloc.c. */
29718 Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots");
29719 Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
29721 DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display,
29722 doc: /* Char-table defining glyphless characters.
29723 Each element, if non-nil, should be one of the following:
29724 an ASCII acronym string: display this string in a box
29725 `hex-code': display the hexadecimal code of a character in a box
29726 `empty-box': display as an empty box
29727 `thin-space': display as 1-pixel width space
29728 `zero-width': don't display
29729 An element may also be a cons cell (GRAPHICAL . TEXT), which specifies the
29730 display method for graphical terminals and text terminals respectively.
29731 GRAPHICAL and TEXT should each have one of the values listed above.
29733 The char-table has one extra slot to control the display of a character for
29734 which no font is found. This slot only takes effect on graphical terminals.
29735 Its value should be an ASCII acronym string, `hex-code', `empty-box', or
29736 `thin-space'. The default is `empty-box'. */);
29737 Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
29738 Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
29739 Qempty_box);
29741 DEFVAR_LISP ("debug-on-message", Vdebug_on_message,
29742 doc: /* If non-nil, debug if a message matching this regexp is displayed. */);
29743 Vdebug_on_message = Qnil;
29747 /* Initialize this module when Emacs starts. */
29749 void
29750 init_xdisp (void)
29752 current_header_line_height = current_mode_line_height = -1;
29754 CHARPOS (this_line_start_pos) = 0;
29756 if (!noninteractive)
29758 struct window *m = XWINDOW (minibuf_window);
29759 Lisp_Object frame = m->frame;
29760 struct frame *f = XFRAME (frame);
29761 Lisp_Object root = FRAME_ROOT_WINDOW (f);
29762 struct window *r = XWINDOW (root);
29763 int i;
29765 echo_area_window = minibuf_window;
29767 r->top_line = FRAME_TOP_MARGIN (f);
29768 r->total_lines = FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f);
29769 r->total_cols = FRAME_COLS (f);
29771 m->top_line = FRAME_LINES (f) - 1;
29772 m->total_lines = 1;
29773 m->total_cols = FRAME_COLS (f);
29775 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
29776 scratch_glyph_row.glyphs[TEXT_AREA + 1]
29777 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
29779 /* The default ellipsis glyphs `...'. */
29780 for (i = 0; i < 3; ++i)
29781 default_invis_vector[i] = make_number ('.');
29785 /* Allocate the buffer for frame titles.
29786 Also used for `format-mode-line'. */
29787 int size = 100;
29788 mode_line_noprop_buf = xmalloc (size);
29789 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
29790 mode_line_noprop_ptr = mode_line_noprop_buf;
29791 mode_line_target = MODE_LINE_DISPLAY;
29794 help_echo_showing_p = 0;
29797 /* Platform-independent portion of hourglass implementation. */
29799 /* Cancel a currently active hourglass timer, and start a new one. */
29800 void
29801 start_hourglass (void)
29803 #if defined (HAVE_WINDOW_SYSTEM)
29804 EMACS_TIME delay;
29806 cancel_hourglass ();
29808 if (INTEGERP (Vhourglass_delay)
29809 && XINT (Vhourglass_delay) > 0)
29810 delay = make_emacs_time (min (XINT (Vhourglass_delay),
29811 TYPE_MAXIMUM (time_t)),
29813 else if (FLOATP (Vhourglass_delay)
29814 && XFLOAT_DATA (Vhourglass_delay) > 0)
29815 delay = EMACS_TIME_FROM_DOUBLE (XFLOAT_DATA (Vhourglass_delay));
29816 else
29817 delay = make_emacs_time (DEFAULT_HOURGLASS_DELAY, 0);
29819 #ifdef HAVE_NTGUI
29821 extern void w32_note_current_window (void);
29822 w32_note_current_window ();
29824 #endif /* HAVE_NTGUI */
29826 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
29827 show_hourglass, NULL);
29828 #endif
29832 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
29833 shown. */
29834 void
29835 cancel_hourglass (void)
29837 #if defined (HAVE_WINDOW_SYSTEM)
29838 if (hourglass_atimer)
29840 cancel_atimer (hourglass_atimer);
29841 hourglass_atimer = NULL;
29844 if (hourglass_shown_p)
29845 hide_hourglass ();
29846 #endif