Fix bug #15064 with assertion violation due to mouse face.
[emacs.git] / src / xdisp.c
blob35abf71e5bfe24023f0e2c23cbefeb87224cac73
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 *entry1 = (struct overlay_entry *) e1;
5512 struct overlay_entry *entry2 = (struct overlay_entry *) 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, (char *)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);
10463 freeze_window_starts (f, 1);
10464 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10465 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10467 else if (height < WINDOW_TOTAL_LINES (w)
10468 && (exact_p || BEGV == ZV))
10470 int old_height = WINDOW_TOTAL_LINES (w);
10471 freeze_window_starts (f, 0);
10472 shrink_mini_window (w);
10473 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10476 else
10478 /* Always resize to exact size needed. */
10479 if (height > WINDOW_TOTAL_LINES (w))
10481 int old_height = WINDOW_TOTAL_LINES (w);
10482 freeze_window_starts (f, 1);
10483 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10484 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10486 else if (height < WINDOW_TOTAL_LINES (w))
10488 int old_height = WINDOW_TOTAL_LINES (w);
10489 freeze_window_starts (f, 0);
10490 shrink_mini_window (w);
10492 if (height)
10494 freeze_window_starts (f, 1);
10495 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10498 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10502 if (old_current_buffer)
10503 set_buffer_internal (old_current_buffer);
10506 return window_height_changed_p;
10510 /* Value is the current message, a string, or nil if there is no
10511 current message. */
10513 Lisp_Object
10514 current_message (void)
10516 Lisp_Object msg;
10518 if (!BUFFERP (echo_area_buffer[0]))
10519 msg = Qnil;
10520 else
10522 with_echo_area_buffer (0, 0, current_message_1,
10523 (intptr_t) &msg, Qnil);
10524 if (NILP (msg))
10525 echo_area_buffer[0] = Qnil;
10528 return msg;
10532 static int
10533 current_message_1 (ptrdiff_t a1, Lisp_Object a2)
10535 intptr_t i1 = a1;
10536 Lisp_Object *msg = (Lisp_Object *) i1;
10538 if (Z > BEG)
10539 *msg = make_buffer_string (BEG, Z, 1);
10540 else
10541 *msg = Qnil;
10542 return 0;
10546 /* Push the current message on Vmessage_stack for later restoration
10547 by restore_message. Value is non-zero if the current message isn't
10548 empty. This is a relatively infrequent operation, so it's not
10549 worth optimizing. */
10551 bool
10552 push_message (void)
10554 Lisp_Object msg = current_message ();
10555 Vmessage_stack = Fcons (msg, Vmessage_stack);
10556 return STRINGP (msg);
10560 /* Restore message display from the top of Vmessage_stack. */
10562 void
10563 restore_message (void)
10565 eassert (CONSP (Vmessage_stack));
10566 message3_nolog (XCAR (Vmessage_stack));
10570 /* Handler for unwind-protect calling pop_message. */
10572 void
10573 pop_message_unwind (void)
10575 /* Pop the top-most entry off Vmessage_stack. */
10576 eassert (CONSP (Vmessage_stack));
10577 Vmessage_stack = XCDR (Vmessage_stack);
10581 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
10582 exits. If the stack is not empty, we have a missing pop_message
10583 somewhere. */
10585 void
10586 check_message_stack (void)
10588 if (!NILP (Vmessage_stack))
10589 emacs_abort ();
10593 /* Truncate to NCHARS what will be displayed in the echo area the next
10594 time we display it---but don't redisplay it now. */
10596 void
10597 truncate_echo_area (ptrdiff_t nchars)
10599 if (nchars == 0)
10600 echo_area_buffer[0] = Qnil;
10601 else if (!noninteractive
10602 && INTERACTIVE
10603 && !NILP (echo_area_buffer[0]))
10605 struct frame *sf = SELECTED_FRAME ();
10606 /* Error messages get reported properly by cmd_error, so this must be
10607 just an informative message; if the frame hasn't really been
10608 initialized yet, just toss it. */
10609 if (sf->glyphs_initialized_p)
10610 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil);
10615 /* Helper function for truncate_echo_area. Truncate the current
10616 message to at most NCHARS characters. */
10618 static int
10619 truncate_message_1 (ptrdiff_t nchars, Lisp_Object a2)
10621 if (BEG + nchars < Z)
10622 del_range (BEG + nchars, Z);
10623 if (Z == BEG)
10624 echo_area_buffer[0] = Qnil;
10625 return 0;
10628 /* Set the current message to STRING. */
10630 static void
10631 set_message (Lisp_Object string)
10633 eassert (STRINGP (string));
10635 message_enable_multibyte = STRING_MULTIBYTE (string);
10637 with_echo_area_buffer (0, -1, set_message_1, 0, string);
10638 message_buf_print = 0;
10639 help_echo_showing_p = 0;
10641 if (STRINGP (Vdebug_on_message)
10642 && STRINGP (string)
10643 && fast_string_match (Vdebug_on_message, string) >= 0)
10644 call_debugger (list2 (Qerror, string));
10648 /* Helper function for set_message. First argument is ignored and second
10649 argument has the same meaning as for set_message.
10650 This function is called with the echo area buffer being current. */
10652 static int
10653 set_message_1 (ptrdiff_t a1, Lisp_Object string)
10655 eassert (STRINGP (string));
10657 /* Change multibyteness of the echo buffer appropriately. */
10658 if (message_enable_multibyte
10659 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
10660 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
10662 bset_truncate_lines (current_buffer, message_truncate_lines ? Qt : Qnil);
10663 if (!NILP (BVAR (current_buffer, bidi_display_reordering)))
10664 bset_bidi_paragraph_direction (current_buffer, Qleft_to_right);
10666 /* Insert new message at BEG. */
10667 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
10669 /* This function takes care of single/multibyte conversion.
10670 We just have to ensure that the echo area buffer has the right
10671 setting of enable_multibyte_characters. */
10672 insert_from_string (string, 0, 0, SCHARS (string), SBYTES (string), 1);
10674 return 0;
10678 /* Clear messages. CURRENT_P non-zero means clear the current
10679 message. LAST_DISPLAYED_P non-zero means clear the message
10680 last displayed. */
10682 void
10683 clear_message (int current_p, int last_displayed_p)
10685 if (current_p)
10687 echo_area_buffer[0] = Qnil;
10688 message_cleared_p = 1;
10691 if (last_displayed_p)
10692 echo_area_buffer[1] = Qnil;
10694 message_buf_print = 0;
10697 /* Clear garbaged frames.
10699 This function is used where the old redisplay called
10700 redraw_garbaged_frames which in turn called redraw_frame which in
10701 turn called clear_frame. The call to clear_frame was a source of
10702 flickering. I believe a clear_frame is not necessary. It should
10703 suffice in the new redisplay to invalidate all current matrices,
10704 and ensure a complete redisplay of all windows. */
10706 static void
10707 clear_garbaged_frames (void)
10709 if (frame_garbaged)
10711 Lisp_Object tail, frame;
10712 int changed_count = 0;
10714 FOR_EACH_FRAME (tail, frame)
10716 struct frame *f = XFRAME (frame);
10718 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
10720 if (f->resized_p)
10722 redraw_frame (f);
10723 f->force_flush_display_p = 1;
10725 clear_current_matrices (f);
10726 changed_count++;
10727 f->garbaged = 0;
10728 f->resized_p = 0;
10732 frame_garbaged = 0;
10733 if (changed_count)
10734 ++windows_or_buffers_changed;
10739 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
10740 is non-zero update selected_frame. Value is non-zero if the
10741 mini-windows height has been changed. */
10743 static int
10744 echo_area_display (int update_frame_p)
10746 Lisp_Object mini_window;
10747 struct window *w;
10748 struct frame *f;
10749 int window_height_changed_p = 0;
10750 struct frame *sf = SELECTED_FRAME ();
10752 mini_window = FRAME_MINIBUF_WINDOW (sf);
10753 w = XWINDOW (mini_window);
10754 f = XFRAME (WINDOW_FRAME (w));
10756 /* Don't display if frame is invisible or not yet initialized. */
10757 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
10758 return 0;
10760 #ifdef HAVE_WINDOW_SYSTEM
10761 /* When Emacs starts, selected_frame may be the initial terminal
10762 frame. If we let this through, a message would be displayed on
10763 the terminal. */
10764 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
10765 return 0;
10766 #endif /* HAVE_WINDOW_SYSTEM */
10768 /* Redraw garbaged frames. */
10769 clear_garbaged_frames ();
10771 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
10773 echo_area_window = mini_window;
10774 window_height_changed_p = display_echo_area (w);
10775 w->must_be_updated_p = 1;
10777 /* Update the display, unless called from redisplay_internal.
10778 Also don't update the screen during redisplay itself. The
10779 update will happen at the end of redisplay, and an update
10780 here could cause confusion. */
10781 if (update_frame_p && !redisplaying_p)
10783 int n = 0;
10785 /* If the display update has been interrupted by pending
10786 input, update mode lines in the frame. Due to the
10787 pending input, it might have been that redisplay hasn't
10788 been called, so that mode lines above the echo area are
10789 garbaged. This looks odd, so we prevent it here. */
10790 if (!display_completed)
10791 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
10793 if (window_height_changed_p
10794 /* Don't do this if Emacs is shutting down. Redisplay
10795 needs to run hooks. */
10796 && !NILP (Vrun_hooks))
10798 /* Must update other windows. Likewise as in other
10799 cases, don't let this update be interrupted by
10800 pending input. */
10801 ptrdiff_t count = SPECPDL_INDEX ();
10802 specbind (Qredisplay_dont_pause, Qt);
10803 windows_or_buffers_changed = 1;
10804 redisplay_internal ();
10805 unbind_to (count, Qnil);
10807 else if (FRAME_WINDOW_P (f) && n == 0)
10809 /* Window configuration is the same as before.
10810 Can do with a display update of the echo area,
10811 unless we displayed some mode lines. */
10812 update_single_window (w, 1);
10813 FRAME_RIF (f)->flush_display (f);
10815 else
10816 update_frame (f, 1, 1);
10818 /* If cursor is in the echo area, make sure that the next
10819 redisplay displays the minibuffer, so that the cursor will
10820 be replaced with what the minibuffer wants. */
10821 if (cursor_in_echo_area)
10822 ++windows_or_buffers_changed;
10825 else if (!EQ (mini_window, selected_window))
10826 windows_or_buffers_changed++;
10828 /* Last displayed message is now the current message. */
10829 echo_area_buffer[1] = echo_area_buffer[0];
10830 /* Inform read_char that we're not echoing. */
10831 echo_message_buffer = Qnil;
10833 /* Prevent redisplay optimization in redisplay_internal by resetting
10834 this_line_start_pos. This is done because the mini-buffer now
10835 displays the message instead of its buffer text. */
10836 if (EQ (mini_window, selected_window))
10837 CHARPOS (this_line_start_pos) = 0;
10839 return window_height_changed_p;
10842 /* Nonzero if the current window's buffer is shown in more than one
10843 window and was modified since last redisplay. */
10845 static int
10846 buffer_shared_and_changed (void)
10848 return (buffer_window_count (current_buffer) > 1
10849 && UNCHANGED_MODIFIED < MODIFF);
10852 /* Nonzero if W's buffer was changed but not saved or Transient Mark mode
10853 is enabled and mark of W's buffer was changed since last W's update. */
10855 static int
10856 window_buffer_changed (struct window *w)
10858 struct buffer *b = XBUFFER (w->contents);
10860 eassert (BUFFER_LIVE_P (b));
10862 return (((BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) != w->last_had_star)
10863 || ((!NILP (Vtransient_mark_mode) && !NILP (BVAR (b, mark_active)))
10864 != (w->region_showing != 0)));
10867 /* Nonzero if W has %c in its mode line and mode line should be updated. */
10869 static int
10870 mode_line_update_needed (struct window *w)
10872 return (w->column_number_displayed != -1
10873 && !(PT == w->last_point && !window_outdated (w))
10874 && (w->column_number_displayed != current_column ()));
10877 /***********************************************************************
10878 Mode Lines and Frame Titles
10879 ***********************************************************************/
10881 /* A buffer for constructing non-propertized mode-line strings and
10882 frame titles in it; allocated from the heap in init_xdisp and
10883 resized as needed in store_mode_line_noprop_char. */
10885 static char *mode_line_noprop_buf;
10887 /* The buffer's end, and a current output position in it. */
10889 static char *mode_line_noprop_buf_end;
10890 static char *mode_line_noprop_ptr;
10892 #define MODE_LINE_NOPROP_LEN(start) \
10893 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
10895 static enum {
10896 MODE_LINE_DISPLAY = 0,
10897 MODE_LINE_TITLE,
10898 MODE_LINE_NOPROP,
10899 MODE_LINE_STRING
10900 } mode_line_target;
10902 /* Alist that caches the results of :propertize.
10903 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
10904 static Lisp_Object mode_line_proptrans_alist;
10906 /* List of strings making up the mode-line. */
10907 static Lisp_Object mode_line_string_list;
10909 /* Base face property when building propertized mode line string. */
10910 static Lisp_Object mode_line_string_face;
10911 static Lisp_Object mode_line_string_face_prop;
10914 /* Unwind data for mode line strings */
10916 static Lisp_Object Vmode_line_unwind_vector;
10918 static Lisp_Object
10919 format_mode_line_unwind_data (struct frame *target_frame,
10920 struct buffer *obuf,
10921 Lisp_Object owin,
10922 int save_proptrans)
10924 Lisp_Object vector, tmp;
10926 /* Reduce consing by keeping one vector in
10927 Vwith_echo_area_save_vector. */
10928 vector = Vmode_line_unwind_vector;
10929 Vmode_line_unwind_vector = Qnil;
10931 if (NILP (vector))
10932 vector = Fmake_vector (make_number (10), Qnil);
10934 ASET (vector, 0, make_number (mode_line_target));
10935 ASET (vector, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
10936 ASET (vector, 2, mode_line_string_list);
10937 ASET (vector, 3, save_proptrans ? mode_line_proptrans_alist : Qt);
10938 ASET (vector, 4, mode_line_string_face);
10939 ASET (vector, 5, mode_line_string_face_prop);
10941 if (obuf)
10942 XSETBUFFER (tmp, obuf);
10943 else
10944 tmp = Qnil;
10945 ASET (vector, 6, tmp);
10946 ASET (vector, 7, owin);
10947 if (target_frame)
10949 /* Similarly to `with-selected-window', if the operation selects
10950 a window on another frame, we must restore that frame's
10951 selected window, and (for a tty) the top-frame. */
10952 ASET (vector, 8, target_frame->selected_window);
10953 if (FRAME_TERMCAP_P (target_frame))
10954 ASET (vector, 9, FRAME_TTY (target_frame)->top_frame);
10957 return vector;
10960 static void
10961 unwind_format_mode_line (Lisp_Object vector)
10963 Lisp_Object old_window = AREF (vector, 7);
10964 Lisp_Object target_frame_window = AREF (vector, 8);
10965 Lisp_Object old_top_frame = AREF (vector, 9);
10967 mode_line_target = XINT (AREF (vector, 0));
10968 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
10969 mode_line_string_list = AREF (vector, 2);
10970 if (! EQ (AREF (vector, 3), Qt))
10971 mode_line_proptrans_alist = AREF (vector, 3);
10972 mode_line_string_face = AREF (vector, 4);
10973 mode_line_string_face_prop = AREF (vector, 5);
10975 /* Select window before buffer, since it may change the buffer. */
10976 if (!NILP (old_window))
10978 /* If the operation that we are unwinding had selected a window
10979 on a different frame, reset its frame-selected-window. For a
10980 text terminal, reset its top-frame if necessary. */
10981 if (!NILP (target_frame_window))
10983 Lisp_Object frame
10984 = WINDOW_FRAME (XWINDOW (target_frame_window));
10986 if (!EQ (frame, WINDOW_FRAME (XWINDOW (old_window))))
10987 Fselect_window (target_frame_window, Qt);
10989 if (!NILP (old_top_frame) && !EQ (old_top_frame, frame))
10990 Fselect_frame (old_top_frame, Qt);
10993 Fselect_window (old_window, Qt);
10996 if (!NILP (AREF (vector, 6)))
10998 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
10999 ASET (vector, 6, Qnil);
11002 Vmode_line_unwind_vector = vector;
11006 /* Store a single character C for the frame title in mode_line_noprop_buf.
11007 Re-allocate mode_line_noprop_buf if necessary. */
11009 static void
11010 store_mode_line_noprop_char (char c)
11012 /* If output position has reached the end of the allocated buffer,
11013 increase the buffer's size. */
11014 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
11016 ptrdiff_t len = MODE_LINE_NOPROP_LEN (0);
11017 ptrdiff_t size = len;
11018 mode_line_noprop_buf =
11019 xpalloc (mode_line_noprop_buf, &size, 1, STRING_BYTES_BOUND, 1);
11020 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
11021 mode_line_noprop_ptr = mode_line_noprop_buf + len;
11024 *mode_line_noprop_ptr++ = c;
11028 /* Store part of a frame title in mode_line_noprop_buf, beginning at
11029 mode_line_noprop_ptr. STRING is the string to store. Do not copy
11030 characters that yield more columns than PRECISION; PRECISION <= 0
11031 means copy the whole string. Pad with spaces until FIELD_WIDTH
11032 number of characters have been copied; FIELD_WIDTH <= 0 means don't
11033 pad. Called from display_mode_element when it is used to build a
11034 frame title. */
11036 static int
11037 store_mode_line_noprop (const char *string, int field_width, int precision)
11039 const unsigned char *str = (const unsigned char *) string;
11040 int n = 0;
11041 ptrdiff_t dummy, nbytes;
11043 /* Copy at most PRECISION chars from STR. */
11044 nbytes = strlen (string);
11045 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
11046 while (nbytes--)
11047 store_mode_line_noprop_char (*str++);
11049 /* Fill up with spaces until FIELD_WIDTH reached. */
11050 while (field_width > 0
11051 && n < field_width)
11053 store_mode_line_noprop_char (' ');
11054 ++n;
11057 return n;
11060 /***********************************************************************
11061 Frame Titles
11062 ***********************************************************************/
11064 #ifdef HAVE_WINDOW_SYSTEM
11066 /* Set the title of FRAME, if it has changed. The title format is
11067 Vicon_title_format if FRAME is iconified, otherwise it is
11068 frame_title_format. */
11070 static void
11071 x_consider_frame_title (Lisp_Object frame)
11073 struct frame *f = XFRAME (frame);
11075 if (FRAME_WINDOW_P (f)
11076 || FRAME_MINIBUF_ONLY_P (f)
11077 || f->explicit_name)
11079 /* Do we have more than one visible frame on this X display? */
11080 Lisp_Object tail, other_frame, fmt;
11081 ptrdiff_t title_start;
11082 char *title;
11083 ptrdiff_t len;
11084 struct it it;
11085 ptrdiff_t count = SPECPDL_INDEX ();
11087 FOR_EACH_FRAME (tail, other_frame)
11089 struct frame *tf = XFRAME (other_frame);
11091 if (tf != f
11092 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
11093 && !FRAME_MINIBUF_ONLY_P (tf)
11094 && !EQ (other_frame, tip_frame)
11095 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
11096 break;
11099 /* Set global variable indicating that multiple frames exist. */
11100 multiple_frames = CONSP (tail);
11102 /* Switch to the buffer of selected window of the frame. Set up
11103 mode_line_target so that display_mode_element will output into
11104 mode_line_noprop_buf; then display the title. */
11105 record_unwind_protect (unwind_format_mode_line,
11106 format_mode_line_unwind_data
11107 (f, current_buffer, selected_window, 0));
11109 Fselect_window (f->selected_window, Qt);
11110 set_buffer_internal_1
11111 (XBUFFER (XWINDOW (f->selected_window)->contents));
11112 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
11114 mode_line_target = MODE_LINE_TITLE;
11115 title_start = MODE_LINE_NOPROP_LEN (0);
11116 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
11117 NULL, DEFAULT_FACE_ID);
11118 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
11119 len = MODE_LINE_NOPROP_LEN (title_start);
11120 title = mode_line_noprop_buf + title_start;
11121 unbind_to (count, Qnil);
11123 /* Set the title only if it's changed. This avoids consing in
11124 the common case where it hasn't. (If it turns out that we've
11125 already wasted too much time by walking through the list with
11126 display_mode_element, then we might need to optimize at a
11127 higher level than this.) */
11128 if (! STRINGP (f->name)
11129 || SBYTES (f->name) != len
11130 || memcmp (title, SDATA (f->name), len) != 0)
11131 x_implicitly_set_name (f, make_string (title, len), Qnil);
11135 #endif /* not HAVE_WINDOW_SYSTEM */
11138 /***********************************************************************
11139 Menu Bars
11140 ***********************************************************************/
11143 /* Prepare for redisplay by updating menu-bar item lists when
11144 appropriate. This can call eval. */
11146 void
11147 prepare_menu_bars (void)
11149 int all_windows;
11150 struct gcpro gcpro1, gcpro2;
11151 struct frame *f;
11152 Lisp_Object tooltip_frame;
11154 #ifdef HAVE_WINDOW_SYSTEM
11155 tooltip_frame = tip_frame;
11156 #else
11157 tooltip_frame = Qnil;
11158 #endif
11160 /* Update all frame titles based on their buffer names, etc. We do
11161 this before the menu bars so that the buffer-menu will show the
11162 up-to-date frame titles. */
11163 #ifdef HAVE_WINDOW_SYSTEM
11164 if (windows_or_buffers_changed || update_mode_lines)
11166 Lisp_Object tail, frame;
11168 FOR_EACH_FRAME (tail, frame)
11170 f = XFRAME (frame);
11171 if (!EQ (frame, tooltip_frame)
11172 && (FRAME_ICONIFIED_P (f)
11173 || FRAME_VISIBLE_P (f) == 1
11174 /* Exclude TTY frames that are obscured because they
11175 are not the top frame on their console. This is
11176 because x_consider_frame_title actually switches
11177 to the frame, which for TTY frames means it is
11178 marked as garbaged, and will be completely
11179 redrawn on the next redisplay cycle. This causes
11180 TTY frames to be completely redrawn, when there
11181 are more than one of them, even though nothing
11182 should be changed on display. */
11183 || (FRAME_VISIBLE_P (f) == 2 && FRAME_WINDOW_P (f))))
11184 x_consider_frame_title (frame);
11187 #endif /* HAVE_WINDOW_SYSTEM */
11189 /* Update the menu bar item lists, if appropriate. This has to be
11190 done before any actual redisplay or generation of display lines. */
11191 all_windows = (update_mode_lines
11192 || buffer_shared_and_changed ()
11193 || windows_or_buffers_changed);
11194 if (all_windows)
11196 Lisp_Object tail, frame;
11197 ptrdiff_t count = SPECPDL_INDEX ();
11198 /* 1 means that update_menu_bar has run its hooks
11199 so any further calls to update_menu_bar shouldn't do so again. */
11200 int menu_bar_hooks_run = 0;
11202 record_unwind_save_match_data ();
11204 FOR_EACH_FRAME (tail, frame)
11206 f = XFRAME (frame);
11208 /* Ignore tooltip frame. */
11209 if (EQ (frame, tooltip_frame))
11210 continue;
11212 /* If a window on this frame changed size, report that to
11213 the user and clear the size-change flag. */
11214 if (FRAME_WINDOW_SIZES_CHANGED (f))
11216 Lisp_Object functions;
11218 /* Clear flag first in case we get an error below. */
11219 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
11220 functions = Vwindow_size_change_functions;
11221 GCPRO2 (tail, functions);
11223 while (CONSP (functions))
11225 if (!EQ (XCAR (functions), Qt))
11226 call1 (XCAR (functions), frame);
11227 functions = XCDR (functions);
11229 UNGCPRO;
11232 GCPRO1 (tail);
11233 menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
11234 #ifdef HAVE_WINDOW_SYSTEM
11235 update_tool_bar (f, 0);
11236 #endif
11237 #ifdef HAVE_NS
11238 if (windows_or_buffers_changed
11239 && FRAME_NS_P (f))
11240 ns_set_doc_edited
11241 (f, Fbuffer_modified_p (XWINDOW (f->selected_window)->contents));
11242 #endif
11243 UNGCPRO;
11246 unbind_to (count, Qnil);
11248 else
11250 struct frame *sf = SELECTED_FRAME ();
11251 update_menu_bar (sf, 1, 0);
11252 #ifdef HAVE_WINDOW_SYSTEM
11253 update_tool_bar (sf, 1);
11254 #endif
11259 /* Update the menu bar item list for frame F. This has to be done
11260 before we start to fill in any display lines, because it can call
11261 eval.
11263 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
11265 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
11266 already ran the menu bar hooks for this redisplay, so there
11267 is no need to run them again. The return value is the
11268 updated value of this flag, to pass to the next call. */
11270 static int
11271 update_menu_bar (struct frame *f, int save_match_data, int hooks_run)
11273 Lisp_Object window;
11274 register struct window *w;
11276 /* If called recursively during a menu update, do nothing. This can
11277 happen when, for instance, an activate-menubar-hook causes a
11278 redisplay. */
11279 if (inhibit_menubar_update)
11280 return hooks_run;
11282 window = FRAME_SELECTED_WINDOW (f);
11283 w = XWINDOW (window);
11285 if (FRAME_WINDOW_P (f)
11287 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11288 || defined (HAVE_NS) || defined (USE_GTK)
11289 FRAME_EXTERNAL_MENU_BAR (f)
11290 #else
11291 FRAME_MENU_BAR_LINES (f) > 0
11292 #endif
11293 : FRAME_MENU_BAR_LINES (f) > 0)
11295 /* If the user has switched buffers or windows, we need to
11296 recompute to reflect the new bindings. But we'll
11297 recompute when update_mode_lines is set too; that means
11298 that people can use force-mode-line-update to request
11299 that the menu bar be recomputed. The adverse effect on
11300 the rest of the redisplay algorithm is about the same as
11301 windows_or_buffers_changed anyway. */
11302 if (windows_or_buffers_changed
11303 /* This used to test w->update_mode_line, but we believe
11304 there is no need to recompute the menu in that case. */
11305 || update_mode_lines
11306 || window_buffer_changed (w))
11308 struct buffer *prev = current_buffer;
11309 ptrdiff_t count = SPECPDL_INDEX ();
11311 specbind (Qinhibit_menubar_update, Qt);
11313 set_buffer_internal_1 (XBUFFER (w->contents));
11314 if (save_match_data)
11315 record_unwind_save_match_data ();
11316 if (NILP (Voverriding_local_map_menu_flag))
11318 specbind (Qoverriding_terminal_local_map, Qnil);
11319 specbind (Qoverriding_local_map, Qnil);
11322 if (!hooks_run)
11324 /* Run the Lucid hook. */
11325 safe_run_hooks (Qactivate_menubar_hook);
11327 /* If it has changed current-menubar from previous value,
11328 really recompute the menu-bar from the value. */
11329 if (! NILP (Vlucid_menu_bar_dirty_flag))
11330 call0 (Qrecompute_lucid_menubar);
11332 safe_run_hooks (Qmenu_bar_update_hook);
11334 hooks_run = 1;
11337 XSETFRAME (Vmenu_updating_frame, f);
11338 fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f)));
11340 /* Redisplay the menu bar in case we changed it. */
11341 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11342 || defined (HAVE_NS) || defined (USE_GTK)
11343 if (FRAME_WINDOW_P (f))
11345 #if defined (HAVE_NS)
11346 /* All frames on Mac OS share the same menubar. So only
11347 the selected frame should be allowed to set it. */
11348 if (f == SELECTED_FRAME ())
11349 #endif
11350 set_frame_menubar (f, 0, 0);
11352 else
11353 /* On a terminal screen, the menu bar is an ordinary screen
11354 line, and this makes it get updated. */
11355 w->update_mode_line = 1;
11356 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11357 /* In the non-toolkit version, the menu bar is an ordinary screen
11358 line, and this makes it get updated. */
11359 w->update_mode_line = 1;
11360 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11362 unbind_to (count, Qnil);
11363 set_buffer_internal_1 (prev);
11367 return hooks_run;
11372 /***********************************************************************
11373 Output Cursor
11374 ***********************************************************************/
11376 #ifdef HAVE_WINDOW_SYSTEM
11378 /* EXPORT:
11379 Nominal cursor position -- where to draw output.
11380 HPOS and VPOS are window relative glyph matrix coordinates.
11381 X and Y are window relative pixel coordinates. */
11383 struct cursor_pos output_cursor;
11386 /* EXPORT:
11387 Set the global variable output_cursor to CURSOR. All cursor
11388 positions are relative to currently updated window. */
11390 void
11391 set_output_cursor (struct cursor_pos *cursor)
11393 output_cursor.hpos = cursor->hpos;
11394 output_cursor.vpos = cursor->vpos;
11395 output_cursor.x = cursor->x;
11396 output_cursor.y = cursor->y;
11400 /* EXPORT for RIF:
11401 Set a nominal cursor position.
11403 HPOS and VPOS are column/row positions in a window glyph matrix.
11404 X and Y are window text area relative pixel positions.
11406 This is always done during window update, so the position is the
11407 future output cursor position for currently updated window W.
11408 NOTE: W is used only to check whether this function is called
11409 in a consistent manner via the redisplay interface. */
11411 void
11412 x_cursor_to (struct window *w, int vpos, int hpos, int y, int x)
11414 eassert (w);
11416 /* Set the output cursor. */
11417 output_cursor.hpos = hpos;
11418 output_cursor.vpos = vpos;
11419 output_cursor.x = x;
11420 output_cursor.y = y;
11423 #endif /* HAVE_WINDOW_SYSTEM */
11426 /***********************************************************************
11427 Tool-bars
11428 ***********************************************************************/
11430 #ifdef HAVE_WINDOW_SYSTEM
11432 /* Where the mouse was last time we reported a mouse event. */
11434 struct frame *last_mouse_frame;
11436 /* Tool-bar item index of the item on which a mouse button was pressed
11437 or -1. */
11439 int last_tool_bar_item;
11441 /* Select `frame' temporarily without running all the code in
11442 do_switch_frame.
11443 FIXME: Maybe do_switch_frame should be trimmed down similarly
11444 when `norecord' is set. */
11445 static void
11446 fast_set_selected_frame (Lisp_Object frame)
11448 if (!EQ (selected_frame, frame))
11450 selected_frame = frame;
11451 selected_window = XFRAME (frame)->selected_window;
11455 /* Update the tool-bar item list for frame F. This has to be done
11456 before we start to fill in any display lines. Called from
11457 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
11458 and restore it here. */
11460 static void
11461 update_tool_bar (struct frame *f, int save_match_data)
11463 #if defined (USE_GTK) || defined (HAVE_NS)
11464 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
11465 #else
11466 int do_update = WINDOWP (f->tool_bar_window)
11467 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
11468 #endif
11470 if (do_update)
11472 Lisp_Object window;
11473 struct window *w;
11475 window = FRAME_SELECTED_WINDOW (f);
11476 w = XWINDOW (window);
11478 /* If the user has switched buffers or windows, we need to
11479 recompute to reflect the new bindings. But we'll
11480 recompute when update_mode_lines is set too; that means
11481 that people can use force-mode-line-update to request
11482 that the menu bar be recomputed. The adverse effect on
11483 the rest of the redisplay algorithm is about the same as
11484 windows_or_buffers_changed anyway. */
11485 if (windows_or_buffers_changed
11486 || w->update_mode_line
11487 || update_mode_lines
11488 || window_buffer_changed (w))
11490 struct buffer *prev = current_buffer;
11491 ptrdiff_t count = SPECPDL_INDEX ();
11492 Lisp_Object frame, new_tool_bar;
11493 int new_n_tool_bar;
11494 struct gcpro gcpro1;
11496 /* Set current_buffer to the buffer of the selected
11497 window of the frame, so that we get the right local
11498 keymaps. */
11499 set_buffer_internal_1 (XBUFFER (w->contents));
11501 /* Save match data, if we must. */
11502 if (save_match_data)
11503 record_unwind_save_match_data ();
11505 /* Make sure that we don't accidentally use bogus keymaps. */
11506 if (NILP (Voverriding_local_map_menu_flag))
11508 specbind (Qoverriding_terminal_local_map, Qnil);
11509 specbind (Qoverriding_local_map, Qnil);
11512 GCPRO1 (new_tool_bar);
11514 /* We must temporarily set the selected frame to this frame
11515 before calling tool_bar_items, because the calculation of
11516 the tool-bar keymap uses the selected frame (see
11517 `tool-bar-make-keymap' in tool-bar.el). */
11518 eassert (EQ (selected_window,
11519 /* Since we only explicitly preserve selected_frame,
11520 check that selected_window would be redundant. */
11521 XFRAME (selected_frame)->selected_window));
11522 record_unwind_protect (fast_set_selected_frame, selected_frame);
11523 XSETFRAME (frame, f);
11524 fast_set_selected_frame (frame);
11526 /* Build desired tool-bar items from keymaps. */
11527 new_tool_bar
11528 = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
11529 &new_n_tool_bar);
11531 /* Redisplay the tool-bar if we changed it. */
11532 if (new_n_tool_bar != f->n_tool_bar_items
11533 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
11535 /* Redisplay that happens asynchronously due to an expose event
11536 may access f->tool_bar_items. Make sure we update both
11537 variables within BLOCK_INPUT so no such event interrupts. */
11538 block_input ();
11539 fset_tool_bar_items (f, new_tool_bar);
11540 f->n_tool_bar_items = new_n_tool_bar;
11541 w->update_mode_line = 1;
11542 unblock_input ();
11545 UNGCPRO;
11547 unbind_to (count, Qnil);
11548 set_buffer_internal_1 (prev);
11554 /* Set F->desired_tool_bar_string to a Lisp string representing frame
11555 F's desired tool-bar contents. F->tool_bar_items must have
11556 been set up previously by calling prepare_menu_bars. */
11558 static void
11559 build_desired_tool_bar_string (struct frame *f)
11561 int i, size, size_needed;
11562 struct gcpro gcpro1, gcpro2, gcpro3;
11563 Lisp_Object image, plist, props;
11565 image = plist = props = Qnil;
11566 GCPRO3 (image, plist, props);
11568 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
11569 Otherwise, make a new string. */
11571 /* The size of the string we might be able to reuse. */
11572 size = (STRINGP (f->desired_tool_bar_string)
11573 ? SCHARS (f->desired_tool_bar_string)
11574 : 0);
11576 /* We need one space in the string for each image. */
11577 size_needed = f->n_tool_bar_items;
11579 /* Reuse f->desired_tool_bar_string, if possible. */
11580 if (size < size_needed || NILP (f->desired_tool_bar_string))
11581 fset_desired_tool_bar_string
11582 (f, Fmake_string (make_number (size_needed), make_number (' ')));
11583 else
11585 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
11586 Fremove_text_properties (make_number (0), make_number (size),
11587 props, f->desired_tool_bar_string);
11590 /* Put a `display' property on the string for the images to display,
11591 put a `menu_item' property on tool-bar items with a value that
11592 is the index of the item in F's tool-bar item vector. */
11593 for (i = 0; i < f->n_tool_bar_items; ++i)
11595 #define PROP(IDX) \
11596 AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
11598 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
11599 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
11600 int hmargin, vmargin, relief, idx, end;
11602 /* If image is a vector, choose the image according to the
11603 button state. */
11604 image = PROP (TOOL_BAR_ITEM_IMAGES);
11605 if (VECTORP (image))
11607 if (enabled_p)
11608 idx = (selected_p
11609 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
11610 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
11611 else
11612 idx = (selected_p
11613 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
11614 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
11616 eassert (ASIZE (image) >= idx);
11617 image = AREF (image, idx);
11619 else
11620 idx = -1;
11622 /* Ignore invalid image specifications. */
11623 if (!valid_image_p (image))
11624 continue;
11626 /* Display the tool-bar button pressed, or depressed. */
11627 plist = Fcopy_sequence (XCDR (image));
11629 /* Compute margin and relief to draw. */
11630 relief = (tool_bar_button_relief >= 0
11631 ? tool_bar_button_relief
11632 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
11633 hmargin = vmargin = relief;
11635 if (RANGED_INTEGERP (1, Vtool_bar_button_margin,
11636 INT_MAX - max (hmargin, vmargin)))
11638 hmargin += XFASTINT (Vtool_bar_button_margin);
11639 vmargin += XFASTINT (Vtool_bar_button_margin);
11641 else if (CONSP (Vtool_bar_button_margin))
11643 if (RANGED_INTEGERP (1, XCAR (Vtool_bar_button_margin),
11644 INT_MAX - hmargin))
11645 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
11647 if (RANGED_INTEGERP (1, XCDR (Vtool_bar_button_margin),
11648 INT_MAX - vmargin))
11649 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
11652 if (auto_raise_tool_bar_buttons_p)
11654 /* Add a `:relief' property to the image spec if the item is
11655 selected. */
11656 if (selected_p)
11658 plist = Fplist_put (plist, QCrelief, make_number (-relief));
11659 hmargin -= relief;
11660 vmargin -= relief;
11663 else
11665 /* If image is selected, display it pressed, i.e. with a
11666 negative relief. If it's not selected, display it with a
11667 raised relief. */
11668 plist = Fplist_put (plist, QCrelief,
11669 (selected_p
11670 ? make_number (-relief)
11671 : make_number (relief)));
11672 hmargin -= relief;
11673 vmargin -= relief;
11676 /* Put a margin around the image. */
11677 if (hmargin || vmargin)
11679 if (hmargin == vmargin)
11680 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
11681 else
11682 plist = Fplist_put (plist, QCmargin,
11683 Fcons (make_number (hmargin),
11684 make_number (vmargin)));
11687 /* If button is not enabled, and we don't have special images
11688 for the disabled state, make the image appear disabled by
11689 applying an appropriate algorithm to it. */
11690 if (!enabled_p && idx < 0)
11691 plist = Fplist_put (plist, QCconversion, Qdisabled);
11693 /* Put a `display' text property on the string for the image to
11694 display. Put a `menu-item' property on the string that gives
11695 the start of this item's properties in the tool-bar items
11696 vector. */
11697 image = Fcons (Qimage, plist);
11698 props = list4 (Qdisplay, image,
11699 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
11701 /* Let the last image hide all remaining spaces in the tool bar
11702 string. The string can be longer than needed when we reuse a
11703 previous string. */
11704 if (i + 1 == f->n_tool_bar_items)
11705 end = SCHARS (f->desired_tool_bar_string);
11706 else
11707 end = i + 1;
11708 Fadd_text_properties (make_number (i), make_number (end),
11709 props, f->desired_tool_bar_string);
11710 #undef PROP
11713 UNGCPRO;
11717 /* Display one line of the tool-bar of frame IT->f.
11719 HEIGHT specifies the desired height of the tool-bar line.
11720 If the actual height of the glyph row is less than HEIGHT, the
11721 row's height is increased to HEIGHT, and the icons are centered
11722 vertically in the new height.
11724 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
11725 count a final empty row in case the tool-bar width exactly matches
11726 the window width.
11729 static void
11730 display_tool_bar_line (struct it *it, int height)
11732 struct glyph_row *row = it->glyph_row;
11733 int max_x = it->last_visible_x;
11734 struct glyph *last;
11736 prepare_desired_row (row);
11737 row->y = it->current_y;
11739 /* Note that this isn't made use of if the face hasn't a box,
11740 so there's no need to check the face here. */
11741 it->start_of_box_run_p = 1;
11743 while (it->current_x < max_x)
11745 int x, n_glyphs_before, i, nglyphs;
11746 struct it it_before;
11748 /* Get the next display element. */
11749 if (!get_next_display_element (it))
11751 /* Don't count empty row if we are counting needed tool-bar lines. */
11752 if (height < 0 && !it->hpos)
11753 return;
11754 break;
11757 /* Produce glyphs. */
11758 n_glyphs_before = row->used[TEXT_AREA];
11759 it_before = *it;
11761 PRODUCE_GLYPHS (it);
11763 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
11764 i = 0;
11765 x = it_before.current_x;
11766 while (i < nglyphs)
11768 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
11770 if (x + glyph->pixel_width > max_x)
11772 /* Glyph doesn't fit on line. Backtrack. */
11773 row->used[TEXT_AREA] = n_glyphs_before;
11774 *it = it_before;
11775 /* If this is the only glyph on this line, it will never fit on the
11776 tool-bar, so skip it. But ensure there is at least one glyph,
11777 so we don't accidentally disable the tool-bar. */
11778 if (n_glyphs_before == 0
11779 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
11780 break;
11781 goto out;
11784 ++it->hpos;
11785 x += glyph->pixel_width;
11786 ++i;
11789 /* Stop at line end. */
11790 if (ITERATOR_AT_END_OF_LINE_P (it))
11791 break;
11793 set_iterator_to_next (it, 1);
11796 out:;
11798 row->displays_text_p = row->used[TEXT_AREA] != 0;
11800 /* Use default face for the border below the tool bar.
11802 FIXME: When auto-resize-tool-bars is grow-only, there is
11803 no additional border below the possibly empty tool-bar lines.
11804 So to make the extra empty lines look "normal", we have to
11805 use the tool-bar face for the border too. */
11806 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
11807 && !EQ (Vauto_resize_tool_bars, Qgrow_only))
11808 it->face_id = DEFAULT_FACE_ID;
11810 extend_face_to_end_of_line (it);
11811 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
11812 last->right_box_line_p = 1;
11813 if (last == row->glyphs[TEXT_AREA])
11814 last->left_box_line_p = 1;
11816 /* Make line the desired height and center it vertically. */
11817 if ((height -= it->max_ascent + it->max_descent) > 0)
11819 /* Don't add more than one line height. */
11820 height %= FRAME_LINE_HEIGHT (it->f);
11821 it->max_ascent += height / 2;
11822 it->max_descent += (height + 1) / 2;
11825 compute_line_metrics (it);
11827 /* If line is empty, make it occupy the rest of the tool-bar. */
11828 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row))
11830 row->height = row->phys_height = it->last_visible_y - row->y;
11831 row->visible_height = row->height;
11832 row->ascent = row->phys_ascent = 0;
11833 row->extra_line_spacing = 0;
11836 row->full_width_p = 1;
11837 row->continued_p = 0;
11838 row->truncated_on_left_p = 0;
11839 row->truncated_on_right_p = 0;
11841 it->current_x = it->hpos = 0;
11842 it->current_y += row->height;
11843 ++it->vpos;
11844 ++it->glyph_row;
11848 /* Max tool-bar height. */
11850 #define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
11851 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
11853 /* Value is the number of screen lines needed to make all tool-bar
11854 items of frame F visible. The number of actual rows needed is
11855 returned in *N_ROWS if non-NULL. */
11857 static int
11858 tool_bar_lines_needed (struct frame *f, int *n_rows)
11860 struct window *w = XWINDOW (f->tool_bar_window);
11861 struct it it;
11862 /* tool_bar_lines_needed is called from redisplay_tool_bar after building
11863 the desired matrix, so use (unused) mode-line row as temporary row to
11864 avoid destroying the first tool-bar row. */
11865 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
11867 /* Initialize an iterator for iteration over
11868 F->desired_tool_bar_string in the tool-bar window of frame F. */
11869 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
11870 it.first_visible_x = 0;
11871 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
11872 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
11873 it.paragraph_embedding = L2R;
11875 while (!ITERATOR_AT_END_P (&it))
11877 clear_glyph_row (temp_row);
11878 it.glyph_row = temp_row;
11879 display_tool_bar_line (&it, -1);
11881 clear_glyph_row (temp_row);
11883 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
11884 if (n_rows)
11885 *n_rows = it.vpos > 0 ? it.vpos : -1;
11887 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
11891 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
11892 0, 1, 0,
11893 doc: /* Return the number of lines occupied by the tool bar of FRAME.
11894 If FRAME is nil or omitted, use the selected frame. */)
11895 (Lisp_Object frame)
11897 struct frame *f = decode_any_frame (frame);
11898 struct window *w;
11899 int nlines = 0;
11901 if (WINDOWP (f->tool_bar_window)
11902 && (w = XWINDOW (f->tool_bar_window),
11903 WINDOW_TOTAL_LINES (w) > 0))
11905 update_tool_bar (f, 1);
11906 if (f->n_tool_bar_items)
11908 build_desired_tool_bar_string (f);
11909 nlines = tool_bar_lines_needed (f, NULL);
11913 return make_number (nlines);
11917 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
11918 height should be changed. */
11920 static int
11921 redisplay_tool_bar (struct frame *f)
11923 struct window *w;
11924 struct it it;
11925 struct glyph_row *row;
11927 #if defined (USE_GTK) || defined (HAVE_NS)
11928 if (FRAME_EXTERNAL_TOOL_BAR (f))
11929 update_frame_tool_bar (f);
11930 return 0;
11931 #endif
11933 /* If frame hasn't a tool-bar window or if it is zero-height, don't
11934 do anything. This means you must start with tool-bar-lines
11935 non-zero to get the auto-sizing effect. Or in other words, you
11936 can turn off tool-bars by specifying tool-bar-lines zero. */
11937 if (!WINDOWP (f->tool_bar_window)
11938 || (w = XWINDOW (f->tool_bar_window),
11939 WINDOW_TOTAL_LINES (w) == 0))
11940 return 0;
11942 /* Set up an iterator for the tool-bar window. */
11943 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
11944 it.first_visible_x = 0;
11945 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
11946 row = it.glyph_row;
11948 /* Build a string that represents the contents of the tool-bar. */
11949 build_desired_tool_bar_string (f);
11950 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
11951 /* FIXME: This should be controlled by a user option. But it
11952 doesn't make sense to have an R2L tool bar if the menu bar cannot
11953 be drawn also R2L, and making the menu bar R2L is tricky due
11954 toolkit-specific code that implements it. If an R2L tool bar is
11955 ever supported, display_tool_bar_line should also be augmented to
11956 call unproduce_glyphs like display_line and display_string
11957 do. */
11958 it.paragraph_embedding = L2R;
11960 if (f->n_tool_bar_rows == 0)
11962 int nlines;
11964 if ((nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
11965 nlines != WINDOW_TOTAL_LINES (w)))
11967 Lisp_Object frame;
11968 int old_height = WINDOW_TOTAL_LINES (w);
11970 XSETFRAME (frame, f);
11971 Fmodify_frame_parameters (frame,
11972 list1 (Fcons (Qtool_bar_lines,
11973 make_number (nlines))));
11974 if (WINDOW_TOTAL_LINES (w) != old_height)
11976 clear_glyph_matrix (w->desired_matrix);
11977 fonts_changed_p = 1;
11978 return 1;
11983 /* Display as many lines as needed to display all tool-bar items. */
11985 if (f->n_tool_bar_rows > 0)
11987 int border, rows, height, extra;
11989 if (TYPE_RANGED_INTEGERP (int, Vtool_bar_border))
11990 border = XINT (Vtool_bar_border);
11991 else if (EQ (Vtool_bar_border, Qinternal_border_width))
11992 border = FRAME_INTERNAL_BORDER_WIDTH (f);
11993 else if (EQ (Vtool_bar_border, Qborder_width))
11994 border = f->border_width;
11995 else
11996 border = 0;
11997 if (border < 0)
11998 border = 0;
12000 rows = f->n_tool_bar_rows;
12001 height = max (1, (it.last_visible_y - border) / rows);
12002 extra = it.last_visible_y - border - height * rows;
12004 while (it.current_y < it.last_visible_y)
12006 int h = 0;
12007 if (extra > 0 && rows-- > 0)
12009 h = (extra + rows - 1) / rows;
12010 extra -= h;
12012 display_tool_bar_line (&it, height + h);
12015 else
12017 while (it.current_y < it.last_visible_y)
12018 display_tool_bar_line (&it, 0);
12021 /* It doesn't make much sense to try scrolling in the tool-bar
12022 window, so don't do it. */
12023 w->desired_matrix->no_scrolling_p = 1;
12024 w->must_be_updated_p = 1;
12026 if (!NILP (Vauto_resize_tool_bars))
12028 int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
12029 int change_height_p = 0;
12031 /* If we couldn't display everything, change the tool-bar's
12032 height if there is room for more. */
12033 if (IT_STRING_CHARPOS (it) < it.end_charpos
12034 && it.current_y < max_tool_bar_height)
12035 change_height_p = 1;
12037 row = it.glyph_row - 1;
12039 /* If there are blank lines at the end, except for a partially
12040 visible blank line at the end that is smaller than
12041 FRAME_LINE_HEIGHT, change the tool-bar's height. */
12042 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
12043 && row->height >= FRAME_LINE_HEIGHT (f))
12044 change_height_p = 1;
12046 /* If row displays tool-bar items, but is partially visible,
12047 change the tool-bar's height. */
12048 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12049 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y
12050 && MATRIX_ROW_BOTTOM_Y (row) < max_tool_bar_height)
12051 change_height_p = 1;
12053 /* Resize windows as needed by changing the `tool-bar-lines'
12054 frame parameter. */
12055 if (change_height_p)
12057 Lisp_Object frame;
12058 int old_height = WINDOW_TOTAL_LINES (w);
12059 int nrows;
12060 int nlines = tool_bar_lines_needed (f, &nrows);
12062 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
12063 && !f->minimize_tool_bar_window_p)
12064 ? (nlines > old_height)
12065 : (nlines != old_height));
12066 f->minimize_tool_bar_window_p = 0;
12068 if (change_height_p)
12070 XSETFRAME (frame, f);
12071 Fmodify_frame_parameters (frame,
12072 list1 (Fcons (Qtool_bar_lines,
12073 make_number (nlines))));
12074 if (WINDOW_TOTAL_LINES (w) != old_height)
12076 clear_glyph_matrix (w->desired_matrix);
12077 f->n_tool_bar_rows = nrows;
12078 fonts_changed_p = 1;
12079 return 1;
12085 f->minimize_tool_bar_window_p = 0;
12086 return 0;
12090 /* Get information about the tool-bar item which is displayed in GLYPH
12091 on frame F. Return in *PROP_IDX the index where tool-bar item
12092 properties start in F->tool_bar_items. Value is zero if
12093 GLYPH doesn't display a tool-bar item. */
12095 static int
12096 tool_bar_item_info (struct frame *f, struct glyph *glyph, int *prop_idx)
12098 Lisp_Object prop;
12099 int success_p;
12100 int charpos;
12102 /* This function can be called asynchronously, which means we must
12103 exclude any possibility that Fget_text_property signals an
12104 error. */
12105 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
12106 charpos = max (0, charpos);
12108 /* Get the text property `menu-item' at pos. The value of that
12109 property is the start index of this item's properties in
12110 F->tool_bar_items. */
12111 prop = Fget_text_property (make_number (charpos),
12112 Qmenu_item, f->current_tool_bar_string);
12113 if (INTEGERP (prop))
12115 *prop_idx = XINT (prop);
12116 success_p = 1;
12118 else
12119 success_p = 0;
12121 return success_p;
12125 /* Get information about the tool-bar item at position X/Y on frame F.
12126 Return in *GLYPH a pointer to the glyph of the tool-bar item in
12127 the current matrix of the tool-bar window of F, or NULL if not
12128 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
12129 item in F->tool_bar_items. Value is
12131 -1 if X/Y is not on a tool-bar item
12132 0 if X/Y is on the same item that was highlighted before.
12133 1 otherwise. */
12135 static int
12136 get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
12137 int *hpos, int *vpos, int *prop_idx)
12139 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12140 struct window *w = XWINDOW (f->tool_bar_window);
12141 int area;
12143 /* Find the glyph under X/Y. */
12144 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
12145 if (*glyph == NULL)
12146 return -1;
12148 /* Get the start of this tool-bar item's properties in
12149 f->tool_bar_items. */
12150 if (!tool_bar_item_info (f, *glyph, prop_idx))
12151 return -1;
12153 /* Is mouse on the highlighted item? */
12154 if (EQ (f->tool_bar_window, hlinfo->mouse_face_window)
12155 && *vpos >= hlinfo->mouse_face_beg_row
12156 && *vpos <= hlinfo->mouse_face_end_row
12157 && (*vpos > hlinfo->mouse_face_beg_row
12158 || *hpos >= hlinfo->mouse_face_beg_col)
12159 && (*vpos < hlinfo->mouse_face_end_row
12160 || *hpos < hlinfo->mouse_face_end_col
12161 || hlinfo->mouse_face_past_end))
12162 return 0;
12164 return 1;
12168 /* EXPORT:
12169 Handle mouse button event on the tool-bar of frame F, at
12170 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
12171 0 for button release. MODIFIERS is event modifiers for button
12172 release. */
12174 void
12175 handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
12176 int modifiers)
12178 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12179 struct window *w = XWINDOW (f->tool_bar_window);
12180 int hpos, vpos, prop_idx;
12181 struct glyph *glyph;
12182 Lisp_Object enabled_p;
12183 int ts;
12185 /* If not on the highlighted tool-bar item, and mouse-highlight is
12186 non-nil, return. This is so we generate the tool-bar button
12187 click only when the mouse button is released on the same item as
12188 where it was pressed. However, when mouse-highlight is disabled,
12189 generate the click when the button is released regardless of the
12190 highlight, since tool-bar items are not highlighted in that
12191 case. */
12192 frame_to_window_pixel_xy (w, &x, &y);
12193 ts = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
12194 if (ts == -1
12195 || (ts != 0 && !NILP (Vmouse_highlight)))
12196 return;
12198 /* When mouse-highlight is off, generate the click for the item
12199 where the button was pressed, disregarding where it was
12200 released. */
12201 if (NILP (Vmouse_highlight) && !down_p)
12202 prop_idx = last_tool_bar_item;
12204 /* If item is disabled, do nothing. */
12205 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
12206 if (NILP (enabled_p))
12207 return;
12209 if (down_p)
12211 /* Show item in pressed state. */
12212 if (!NILP (Vmouse_highlight))
12213 show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN);
12214 last_tool_bar_item = prop_idx;
12216 else
12218 Lisp_Object key, frame;
12219 struct input_event event;
12220 EVENT_INIT (event);
12222 /* Show item in released state. */
12223 if (!NILP (Vmouse_highlight))
12224 show_mouse_face (hlinfo, DRAW_IMAGE_RAISED);
12226 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
12228 XSETFRAME (frame, f);
12229 event.kind = TOOL_BAR_EVENT;
12230 event.frame_or_window = frame;
12231 event.arg = frame;
12232 kbd_buffer_store_event (&event);
12234 event.kind = TOOL_BAR_EVENT;
12235 event.frame_or_window = frame;
12236 event.arg = key;
12237 event.modifiers = modifiers;
12238 kbd_buffer_store_event (&event);
12239 last_tool_bar_item = -1;
12244 /* Possibly highlight a tool-bar item on frame F when mouse moves to
12245 tool-bar window-relative coordinates X/Y. Called from
12246 note_mouse_highlight. */
12248 static void
12249 note_tool_bar_highlight (struct frame *f, int x, int y)
12251 Lisp_Object window = f->tool_bar_window;
12252 struct window *w = XWINDOW (window);
12253 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
12254 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12255 int hpos, vpos;
12256 struct glyph *glyph;
12257 struct glyph_row *row;
12258 int i;
12259 Lisp_Object enabled_p;
12260 int prop_idx;
12261 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
12262 int mouse_down_p, rc;
12264 /* Function note_mouse_highlight is called with negative X/Y
12265 values when mouse moves outside of the frame. */
12266 if (x <= 0 || y <= 0)
12268 clear_mouse_face (hlinfo);
12269 return;
12272 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
12273 if (rc < 0)
12275 /* Not on tool-bar item. */
12276 clear_mouse_face (hlinfo);
12277 return;
12279 else if (rc == 0)
12280 /* On same tool-bar item as before. */
12281 goto set_help_echo;
12283 clear_mouse_face (hlinfo);
12285 /* Mouse is down, but on different tool-bar item? */
12286 mouse_down_p = (dpyinfo->grabbed
12287 && f == last_mouse_frame
12288 && FRAME_LIVE_P (f));
12289 if (mouse_down_p
12290 && last_tool_bar_item != prop_idx)
12291 return;
12293 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
12295 /* If tool-bar item is not enabled, don't highlight it. */
12296 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
12297 if (!NILP (enabled_p) && !NILP (Vmouse_highlight))
12299 /* Compute the x-position of the glyph. In front and past the
12300 image is a space. We include this in the highlighted area. */
12301 row = MATRIX_ROW (w->current_matrix, vpos);
12302 for (i = x = 0; i < hpos; ++i)
12303 x += row->glyphs[TEXT_AREA][i].pixel_width;
12305 /* Record this as the current active region. */
12306 hlinfo->mouse_face_beg_col = hpos;
12307 hlinfo->mouse_face_beg_row = vpos;
12308 hlinfo->mouse_face_beg_x = x;
12309 hlinfo->mouse_face_beg_y = row->y;
12310 hlinfo->mouse_face_past_end = 0;
12312 hlinfo->mouse_face_end_col = hpos + 1;
12313 hlinfo->mouse_face_end_row = vpos;
12314 hlinfo->mouse_face_end_x = x + glyph->pixel_width;
12315 hlinfo->mouse_face_end_y = row->y;
12316 hlinfo->mouse_face_window = window;
12317 hlinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
12319 /* Display it as active. */
12320 show_mouse_face (hlinfo, draw);
12323 set_help_echo:
12325 /* Set help_echo_string to a help string to display for this tool-bar item.
12326 XTread_socket does the rest. */
12327 help_echo_object = help_echo_window = Qnil;
12328 help_echo_pos = -1;
12329 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
12330 if (NILP (help_echo_string))
12331 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
12334 #endif /* HAVE_WINDOW_SYSTEM */
12338 /************************************************************************
12339 Horizontal scrolling
12340 ************************************************************************/
12342 static int hscroll_window_tree (Lisp_Object);
12343 static int hscroll_windows (Lisp_Object);
12345 /* For all leaf windows in the window tree rooted at WINDOW, set their
12346 hscroll value so that PT is (i) visible in the window, and (ii) so
12347 that it is not within a certain margin at the window's left and
12348 right border. Value is non-zero if any window's hscroll has been
12349 changed. */
12351 static int
12352 hscroll_window_tree (Lisp_Object window)
12354 int hscrolled_p = 0;
12355 int hscroll_relative_p = FLOATP (Vhscroll_step);
12356 int hscroll_step_abs = 0;
12357 double hscroll_step_rel = 0;
12359 if (hscroll_relative_p)
12361 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
12362 if (hscroll_step_rel < 0)
12364 hscroll_relative_p = 0;
12365 hscroll_step_abs = 0;
12368 else if (TYPE_RANGED_INTEGERP (int, Vhscroll_step))
12370 hscroll_step_abs = XINT (Vhscroll_step);
12371 if (hscroll_step_abs < 0)
12372 hscroll_step_abs = 0;
12374 else
12375 hscroll_step_abs = 0;
12377 while (WINDOWP (window))
12379 struct window *w = XWINDOW (window);
12381 if (WINDOWP (w->contents))
12382 hscrolled_p |= hscroll_window_tree (w->contents);
12383 else if (w->cursor.vpos >= 0)
12385 int h_margin;
12386 int text_area_width;
12387 struct glyph_row *current_cursor_row
12388 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
12389 struct glyph_row *desired_cursor_row
12390 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
12391 struct glyph_row *cursor_row
12392 = (desired_cursor_row->enabled_p
12393 ? desired_cursor_row
12394 : current_cursor_row);
12395 int row_r2l_p = cursor_row->reversed_p;
12397 text_area_width = window_box_width (w, TEXT_AREA);
12399 /* Scroll when cursor is inside this scroll margin. */
12400 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
12402 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->contents))
12403 /* For left-to-right rows, hscroll when cursor is either
12404 (i) inside the right hscroll margin, or (ii) if it is
12405 inside the left margin and the window is already
12406 hscrolled. */
12407 && ((!row_r2l_p
12408 && ((w->hscroll
12409 && w->cursor.x <= h_margin)
12410 || (cursor_row->enabled_p
12411 && cursor_row->truncated_on_right_p
12412 && (w->cursor.x >= text_area_width - h_margin))))
12413 /* For right-to-left rows, the logic is similar,
12414 except that rules for scrolling to left and right
12415 are reversed. E.g., if cursor.x <= h_margin, we
12416 need to hscroll "to the right" unconditionally,
12417 and that will scroll the screen to the left so as
12418 to reveal the next portion of the row. */
12419 || (row_r2l_p
12420 && ((cursor_row->enabled_p
12421 /* FIXME: It is confusing to set the
12422 truncated_on_right_p flag when R2L rows
12423 are actually truncated on the left. */
12424 && cursor_row->truncated_on_right_p
12425 && w->cursor.x <= h_margin)
12426 || (w->hscroll
12427 && (w->cursor.x >= text_area_width - h_margin))))))
12429 struct it it;
12430 ptrdiff_t hscroll;
12431 struct buffer *saved_current_buffer;
12432 ptrdiff_t pt;
12433 int wanted_x;
12435 /* Find point in a display of infinite width. */
12436 saved_current_buffer = current_buffer;
12437 current_buffer = XBUFFER (w->contents);
12439 if (w == XWINDOW (selected_window))
12440 pt = PT;
12441 else
12442 pt = clip_to_bounds (BEGV, marker_position (w->pointm), ZV);
12444 /* Move iterator to pt starting at cursor_row->start in
12445 a line with infinite width. */
12446 init_to_row_start (&it, w, cursor_row);
12447 it.last_visible_x = INFINITY;
12448 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
12449 current_buffer = saved_current_buffer;
12451 /* Position cursor in window. */
12452 if (!hscroll_relative_p && hscroll_step_abs == 0)
12453 hscroll = max (0, (it.current_x
12454 - (ITERATOR_AT_END_OF_LINE_P (&it)
12455 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
12456 : (text_area_width / 2))))
12457 / FRAME_COLUMN_WIDTH (it.f);
12458 else if ((!row_r2l_p
12459 && w->cursor.x >= text_area_width - h_margin)
12460 || (row_r2l_p && w->cursor.x <= h_margin))
12462 if (hscroll_relative_p)
12463 wanted_x = text_area_width * (1 - hscroll_step_rel)
12464 - h_margin;
12465 else
12466 wanted_x = text_area_width
12467 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
12468 - h_margin;
12469 hscroll
12470 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
12472 else
12474 if (hscroll_relative_p)
12475 wanted_x = text_area_width * hscroll_step_rel
12476 + h_margin;
12477 else
12478 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
12479 + h_margin;
12480 hscroll
12481 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
12483 hscroll = max (hscroll, w->min_hscroll);
12485 /* Don't prevent redisplay optimizations if hscroll
12486 hasn't changed, as it will unnecessarily slow down
12487 redisplay. */
12488 if (w->hscroll != hscroll)
12490 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
12491 w->hscroll = hscroll;
12492 hscrolled_p = 1;
12497 window = w->next;
12500 /* Value is non-zero if hscroll of any leaf window has been changed. */
12501 return hscrolled_p;
12505 /* Set hscroll so that cursor is visible and not inside horizontal
12506 scroll margins for all windows in the tree rooted at WINDOW. See
12507 also hscroll_window_tree above. Value is non-zero if any window's
12508 hscroll has been changed. If it has, desired matrices on the frame
12509 of WINDOW are cleared. */
12511 static int
12512 hscroll_windows (Lisp_Object window)
12514 int hscrolled_p = hscroll_window_tree (window);
12515 if (hscrolled_p)
12516 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
12517 return hscrolled_p;
12522 /************************************************************************
12523 Redisplay
12524 ************************************************************************/
12526 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
12527 to a non-zero value. This is sometimes handy to have in a debugger
12528 session. */
12530 #ifdef GLYPH_DEBUG
12532 /* First and last unchanged row for try_window_id. */
12534 static int debug_first_unchanged_at_end_vpos;
12535 static int debug_last_unchanged_at_beg_vpos;
12537 /* Delta vpos and y. */
12539 static int debug_dvpos, debug_dy;
12541 /* Delta in characters and bytes for try_window_id. */
12543 static ptrdiff_t debug_delta, debug_delta_bytes;
12545 /* Values of window_end_pos and window_end_vpos at the end of
12546 try_window_id. */
12548 static ptrdiff_t debug_end_vpos;
12550 /* Append a string to W->desired_matrix->method. FMT is a printf
12551 format string. If trace_redisplay_p is non-zero also printf the
12552 resulting string to stderr. */
12554 static void debug_method_add (struct window *, char const *, ...)
12555 ATTRIBUTE_FORMAT_PRINTF (2, 3);
12557 static void
12558 debug_method_add (struct window *w, char const *fmt, ...)
12560 void *ptr = w;
12561 char *method = w->desired_matrix->method;
12562 int len = strlen (method);
12563 int size = sizeof w->desired_matrix->method;
12564 int remaining = size - len - 1;
12565 va_list ap;
12567 if (len && remaining)
12569 method[len] = '|';
12570 --remaining, ++len;
12573 va_start (ap, fmt);
12574 vsnprintf (method + len, remaining + 1, fmt, ap);
12575 va_end (ap);
12577 if (trace_redisplay_p)
12578 fprintf (stderr, "%p (%s): %s\n",
12579 ptr,
12580 ((BUFFERP (w->contents)
12581 && STRINGP (BVAR (XBUFFER (w->contents), name)))
12582 ? SSDATA (BVAR (XBUFFER (w->contents), name))
12583 : "no buffer"),
12584 method + len);
12587 #endif /* GLYPH_DEBUG */
12590 /* Value is non-zero if all changes in window W, which displays
12591 current_buffer, are in the text between START and END. START is a
12592 buffer position, END is given as a distance from Z. Used in
12593 redisplay_internal for display optimization. */
12595 static int
12596 text_outside_line_unchanged_p (struct window *w,
12597 ptrdiff_t start, ptrdiff_t end)
12599 int unchanged_p = 1;
12601 /* If text or overlays have changed, see where. */
12602 if (window_outdated (w))
12604 /* Gap in the line? */
12605 if (GPT < start || Z - GPT < end)
12606 unchanged_p = 0;
12608 /* Changes start in front of the line, or end after it? */
12609 if (unchanged_p
12610 && (BEG_UNCHANGED < start - 1
12611 || END_UNCHANGED < end))
12612 unchanged_p = 0;
12614 /* If selective display, can't optimize if changes start at the
12615 beginning of the line. */
12616 if (unchanged_p
12617 && INTEGERP (BVAR (current_buffer, selective_display))
12618 && XINT (BVAR (current_buffer, selective_display)) > 0
12619 && (BEG_UNCHANGED < start || GPT <= start))
12620 unchanged_p = 0;
12622 /* If there are overlays at the start or end of the line, these
12623 may have overlay strings with newlines in them. A change at
12624 START, for instance, may actually concern the display of such
12625 overlay strings as well, and they are displayed on different
12626 lines. So, quickly rule out this case. (For the future, it
12627 might be desirable to implement something more telling than
12628 just BEG/END_UNCHANGED.) */
12629 if (unchanged_p)
12631 if (BEG + BEG_UNCHANGED == start
12632 && overlay_touches_p (start))
12633 unchanged_p = 0;
12634 if (END_UNCHANGED == end
12635 && overlay_touches_p (Z - end))
12636 unchanged_p = 0;
12639 /* Under bidi reordering, adding or deleting a character in the
12640 beginning of a paragraph, before the first strong directional
12641 character, can change the base direction of the paragraph (unless
12642 the buffer specifies a fixed paragraph direction), which will
12643 require to redisplay the whole paragraph. It might be worthwhile
12644 to find the paragraph limits and widen the range of redisplayed
12645 lines to that, but for now just give up this optimization. */
12646 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
12647 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
12648 unchanged_p = 0;
12651 return unchanged_p;
12655 /* Do a frame update, taking possible shortcuts into account. This is
12656 the main external entry point for redisplay.
12658 If the last redisplay displayed an echo area message and that message
12659 is no longer requested, we clear the echo area or bring back the
12660 mini-buffer if that is in use. */
12662 void
12663 redisplay (void)
12665 redisplay_internal ();
12669 static Lisp_Object
12670 overlay_arrow_string_or_property (Lisp_Object var)
12672 Lisp_Object val;
12674 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
12675 return val;
12677 return Voverlay_arrow_string;
12680 /* Return 1 if there are any overlay-arrows in current_buffer. */
12681 static int
12682 overlay_arrow_in_current_buffer_p (void)
12684 Lisp_Object vlist;
12686 for (vlist = Voverlay_arrow_variable_list;
12687 CONSP (vlist);
12688 vlist = XCDR (vlist))
12690 Lisp_Object var = XCAR (vlist);
12691 Lisp_Object val;
12693 if (!SYMBOLP (var))
12694 continue;
12695 val = find_symbol_value (var);
12696 if (MARKERP (val)
12697 && current_buffer == XMARKER (val)->buffer)
12698 return 1;
12700 return 0;
12704 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
12705 has changed. */
12707 static int
12708 overlay_arrows_changed_p (void)
12710 Lisp_Object vlist;
12712 for (vlist = Voverlay_arrow_variable_list;
12713 CONSP (vlist);
12714 vlist = XCDR (vlist))
12716 Lisp_Object var = XCAR (vlist);
12717 Lisp_Object val, pstr;
12719 if (!SYMBOLP (var))
12720 continue;
12721 val = find_symbol_value (var);
12722 if (!MARKERP (val))
12723 continue;
12724 if (! EQ (COERCE_MARKER (val),
12725 Fget (var, Qlast_arrow_position))
12726 || ! (pstr = overlay_arrow_string_or_property (var),
12727 EQ (pstr, Fget (var, Qlast_arrow_string))))
12728 return 1;
12730 return 0;
12733 /* Mark overlay arrows to be updated on next redisplay. */
12735 static void
12736 update_overlay_arrows (int up_to_date)
12738 Lisp_Object vlist;
12740 for (vlist = Voverlay_arrow_variable_list;
12741 CONSP (vlist);
12742 vlist = XCDR (vlist))
12744 Lisp_Object var = XCAR (vlist);
12746 if (!SYMBOLP (var))
12747 continue;
12749 if (up_to_date > 0)
12751 Lisp_Object val = find_symbol_value (var);
12752 Fput (var, Qlast_arrow_position,
12753 COERCE_MARKER (val));
12754 Fput (var, Qlast_arrow_string,
12755 overlay_arrow_string_or_property (var));
12757 else if (up_to_date < 0
12758 || !NILP (Fget (var, Qlast_arrow_position)))
12760 Fput (var, Qlast_arrow_position, Qt);
12761 Fput (var, Qlast_arrow_string, Qt);
12767 /* Return overlay arrow string to display at row.
12768 Return integer (bitmap number) for arrow bitmap in left fringe.
12769 Return nil if no overlay arrow. */
12771 static Lisp_Object
12772 overlay_arrow_at_row (struct it *it, struct glyph_row *row)
12774 Lisp_Object vlist;
12776 for (vlist = Voverlay_arrow_variable_list;
12777 CONSP (vlist);
12778 vlist = XCDR (vlist))
12780 Lisp_Object var = XCAR (vlist);
12781 Lisp_Object val;
12783 if (!SYMBOLP (var))
12784 continue;
12786 val = find_symbol_value (var);
12788 if (MARKERP (val)
12789 && current_buffer == XMARKER (val)->buffer
12790 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
12792 if (FRAME_WINDOW_P (it->f)
12793 /* FIXME: if ROW->reversed_p is set, this should test
12794 the right fringe, not the left one. */
12795 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
12797 #ifdef HAVE_WINDOW_SYSTEM
12798 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
12800 int fringe_bitmap;
12801 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
12802 return make_number (fringe_bitmap);
12804 #endif
12805 return make_number (-1); /* Use default arrow bitmap. */
12807 return overlay_arrow_string_or_property (var);
12811 return Qnil;
12814 /* Return 1 if point moved out of or into a composition. Otherwise
12815 return 0. PREV_BUF and PREV_PT are the last point buffer and
12816 position. BUF and PT are the current point buffer and position. */
12818 static int
12819 check_point_in_composition (struct buffer *prev_buf, ptrdiff_t prev_pt,
12820 struct buffer *buf, ptrdiff_t pt)
12822 ptrdiff_t start, end;
12823 Lisp_Object prop;
12824 Lisp_Object buffer;
12826 XSETBUFFER (buffer, buf);
12827 /* Check a composition at the last point if point moved within the
12828 same buffer. */
12829 if (prev_buf == buf)
12831 if (prev_pt == pt)
12832 /* Point didn't move. */
12833 return 0;
12835 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
12836 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
12837 && composition_valid_p (start, end, prop)
12838 && start < prev_pt && end > prev_pt)
12839 /* The last point was within the composition. Return 1 iff
12840 point moved out of the composition. */
12841 return (pt <= start || pt >= end);
12844 /* Check a composition at the current point. */
12845 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
12846 && find_composition (pt, -1, &start, &end, &prop, buffer)
12847 && composition_valid_p (start, end, prop)
12848 && start < pt && end > pt);
12851 /* Reconsider the clip changes of buffer which is displayed in W. */
12853 static void
12854 reconsider_clip_changes (struct window *w)
12856 struct buffer *b = XBUFFER (w->contents);
12858 if (b->clip_changed
12859 && w->window_end_valid
12860 && w->current_matrix->buffer == b
12861 && w->current_matrix->zv == BUF_ZV (b)
12862 && w->current_matrix->begv == BUF_BEGV (b))
12863 b->clip_changed = 0;
12865 /* If display wasn't paused, and W is not a tool bar window, see if
12866 point has been moved into or out of a composition. In that case,
12867 we set b->clip_changed to 1 to force updating the screen. If
12868 b->clip_changed has already been set to 1, we can skip this
12869 check. */
12870 if (!b->clip_changed && w->window_end_valid)
12872 ptrdiff_t pt = (w == XWINDOW (selected_window)
12873 ? PT : marker_position (w->pointm));
12875 if ((w->current_matrix->buffer != b || pt != w->last_point)
12876 && check_point_in_composition (w->current_matrix->buffer,
12877 w->last_point, b, pt))
12878 b->clip_changed = 1;
12882 #define STOP_POLLING \
12883 do { if (! polling_stopped_here) stop_polling (); \
12884 polling_stopped_here = 1; } while (0)
12886 #define RESUME_POLLING \
12887 do { if (polling_stopped_here) start_polling (); \
12888 polling_stopped_here = 0; } while (0)
12891 /* Perhaps in the future avoid recentering windows if it
12892 is not necessary; currently that causes some problems. */
12894 static void
12895 redisplay_internal (void)
12897 struct window *w = XWINDOW (selected_window);
12898 struct window *sw;
12899 struct frame *fr;
12900 int pending;
12901 bool must_finish = 0, match_p;
12902 struct text_pos tlbufpos, tlendpos;
12903 int number_of_visible_frames;
12904 ptrdiff_t count;
12905 struct frame *sf;
12906 int polling_stopped_here = 0;
12907 Lisp_Object tail, frame;
12909 /* Non-zero means redisplay has to consider all windows on all
12910 frames. Zero means, only selected_window is considered. */
12911 int consider_all_windows_p;
12913 /* Non-zero means redisplay has to redisplay the miniwindow. */
12914 int update_miniwindow_p = 0;
12916 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
12918 /* No redisplay if running in batch mode or frame is not yet fully
12919 initialized, or redisplay is explicitly turned off by setting
12920 Vinhibit_redisplay. */
12921 if (FRAME_INITIAL_P (SELECTED_FRAME ())
12922 || !NILP (Vinhibit_redisplay))
12923 return;
12925 /* Don't examine these until after testing Vinhibit_redisplay.
12926 When Emacs is shutting down, perhaps because its connection to
12927 X has dropped, we should not look at them at all. */
12928 fr = XFRAME (w->frame);
12929 sf = SELECTED_FRAME ();
12931 if (!fr->glyphs_initialized_p)
12932 return;
12934 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
12935 if (popup_activated ())
12936 return;
12937 #endif
12939 /* I don't think this happens but let's be paranoid. */
12940 if (redisplaying_p)
12941 return;
12943 /* Record a function that clears redisplaying_p
12944 when we leave this function. */
12945 count = SPECPDL_INDEX ();
12946 record_unwind_protect_void (unwind_redisplay);
12947 redisplaying_p = 1;
12948 specbind (Qinhibit_free_realized_faces, Qnil);
12950 /* Record this function, so it appears on the profiler's backtraces. */
12951 record_in_backtrace (Qredisplay_internal, &Qnil, 0);
12953 FOR_EACH_FRAME (tail, frame)
12954 XFRAME (frame)->already_hscrolled_p = 0;
12956 retry:
12957 /* Remember the currently selected window. */
12958 sw = w;
12960 pending = 0;
12961 last_escape_glyph_frame = NULL;
12962 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
12963 last_glyphless_glyph_frame = NULL;
12964 last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
12966 /* If new fonts have been loaded that make a glyph matrix adjustment
12967 necessary, do it. */
12968 if (fonts_changed_p)
12970 adjust_glyphs (NULL);
12971 ++windows_or_buffers_changed;
12972 fonts_changed_p = 0;
12975 /* If face_change_count is non-zero, init_iterator will free all
12976 realized faces, which includes the faces referenced from current
12977 matrices. So, we can't reuse current matrices in this case. */
12978 if (face_change_count)
12979 ++windows_or_buffers_changed;
12981 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
12982 && FRAME_TTY (sf)->previous_frame != sf)
12984 /* Since frames on a single ASCII terminal share the same
12985 display area, displaying a different frame means redisplay
12986 the whole thing. */
12987 windows_or_buffers_changed++;
12988 SET_FRAME_GARBAGED (sf);
12989 #ifndef DOS_NT
12990 set_tty_color_mode (FRAME_TTY (sf), sf);
12991 #endif
12992 FRAME_TTY (sf)->previous_frame = sf;
12995 /* Set the visible flags for all frames. Do this before checking for
12996 resized or garbaged frames; they want to know if their frames are
12997 visible. See the comment in frame.h for FRAME_SAMPLE_VISIBILITY. */
12998 number_of_visible_frames = 0;
13000 FOR_EACH_FRAME (tail, frame)
13002 struct frame *f = XFRAME (frame);
13004 if (FRAME_VISIBLE_P (f))
13005 ++number_of_visible_frames;
13006 clear_desired_matrices (f);
13009 /* Notice any pending interrupt request to change frame size. */
13010 do_pending_window_change (1);
13012 /* do_pending_window_change could change the selected_window due to
13013 frame resizing which makes the selected window too small. */
13014 if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw)
13015 sw = w;
13017 /* Clear frames marked as garbaged. */
13018 clear_garbaged_frames ();
13020 /* Build menubar and tool-bar items. */
13021 if (NILP (Vmemory_full))
13022 prepare_menu_bars ();
13024 if (windows_or_buffers_changed)
13025 update_mode_lines++;
13027 reconsider_clip_changes (w);
13029 /* In most cases selected window displays current buffer. */
13030 match_p = XBUFFER (w->contents) == current_buffer;
13031 if (match_p)
13033 ptrdiff_t count1;
13035 /* Detect case that we need to write or remove a star in the mode line. */
13036 if ((SAVE_MODIFF < MODIFF) != w->last_had_star)
13038 w->update_mode_line = 1;
13039 if (buffer_shared_and_changed ())
13040 update_mode_lines++;
13043 /* Avoid invocation of point motion hooks by `current_column' below. */
13044 count1 = SPECPDL_INDEX ();
13045 specbind (Qinhibit_point_motion_hooks, Qt);
13047 if (mode_line_update_needed (w))
13048 w->update_mode_line = 1;
13050 unbind_to (count1, Qnil);
13053 consider_all_windows_p = (update_mode_lines
13054 || buffer_shared_and_changed ()
13055 || cursor_type_changed);
13057 /* If specs for an arrow have changed, do thorough redisplay
13058 to ensure we remove any arrow that should no longer exist. */
13059 if (overlay_arrows_changed_p ())
13060 consider_all_windows_p = windows_or_buffers_changed = 1;
13062 /* Normally the message* functions will have already displayed and
13063 updated the echo area, but the frame may have been trashed, or
13064 the update may have been preempted, so display the echo area
13065 again here. Checking message_cleared_p captures the case that
13066 the echo area should be cleared. */
13067 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
13068 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
13069 || (message_cleared_p
13070 && minibuf_level == 0
13071 /* If the mini-window is currently selected, this means the
13072 echo-area doesn't show through. */
13073 && !MINI_WINDOW_P (XWINDOW (selected_window))))
13075 int window_height_changed_p = echo_area_display (0);
13077 if (message_cleared_p)
13078 update_miniwindow_p = 1;
13080 must_finish = 1;
13082 /* If we don't display the current message, don't clear the
13083 message_cleared_p flag, because, if we did, we wouldn't clear
13084 the echo area in the next redisplay which doesn't preserve
13085 the echo area. */
13086 if (!display_last_displayed_message_p)
13087 message_cleared_p = 0;
13089 if (fonts_changed_p)
13090 goto retry;
13091 else if (window_height_changed_p)
13093 consider_all_windows_p = 1;
13094 ++update_mode_lines;
13095 ++windows_or_buffers_changed;
13097 /* If window configuration was changed, frames may have been
13098 marked garbaged. Clear them or we will experience
13099 surprises wrt scrolling. */
13100 clear_garbaged_frames ();
13103 else if (EQ (selected_window, minibuf_window)
13104 && (current_buffer->clip_changed || window_outdated (w))
13105 && resize_mini_window (w, 0))
13107 /* Resized active mini-window to fit the size of what it is
13108 showing if its contents might have changed. */
13109 must_finish = 1;
13110 /* FIXME: this causes all frames to be updated, which seems unnecessary
13111 since only the current frame needs to be considered. This function
13112 needs to be rewritten with two variables, consider_all_windows and
13113 consider_all_frames. */
13114 consider_all_windows_p = 1;
13115 ++windows_or_buffers_changed;
13116 ++update_mode_lines;
13118 /* If window configuration was changed, frames may have been
13119 marked garbaged. Clear them or we will experience
13120 surprises wrt scrolling. */
13121 clear_garbaged_frames ();
13124 /* If showing the region, and mark has changed, we must redisplay
13125 the whole window. The assignment to this_line_start_pos prevents
13126 the optimization directly below this if-statement. */
13127 if (((!NILP (Vtransient_mark_mode)
13128 && !NILP (BVAR (XBUFFER (w->contents), mark_active)))
13129 != (w->region_showing > 0))
13130 || (w->region_showing
13131 && w->region_showing
13132 != XINT (Fmarker_position (BVAR (XBUFFER (w->contents), mark)))))
13133 CHARPOS (this_line_start_pos) = 0;
13135 /* Optimize the case that only the line containing the cursor in the
13136 selected window has changed. Variables starting with this_ are
13137 set in display_line and record information about the line
13138 containing the cursor. */
13139 tlbufpos = this_line_start_pos;
13140 tlendpos = this_line_end_pos;
13141 if (!consider_all_windows_p
13142 && CHARPOS (tlbufpos) > 0
13143 && !w->update_mode_line
13144 && !current_buffer->clip_changed
13145 && !current_buffer->prevent_redisplay_optimizations_p
13146 && FRAME_VISIBLE_P (XFRAME (w->frame))
13147 && !FRAME_OBSCURED_P (XFRAME (w->frame))
13148 /* Make sure recorded data applies to current buffer, etc. */
13149 && this_line_buffer == current_buffer
13150 && match_p
13151 && !w->force_start
13152 && !w->optional_new_start
13153 /* Point must be on the line that we have info recorded about. */
13154 && PT >= CHARPOS (tlbufpos)
13155 && PT <= Z - CHARPOS (tlendpos)
13156 /* All text outside that line, including its final newline,
13157 must be unchanged. */
13158 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
13159 CHARPOS (tlendpos)))
13161 if (CHARPOS (tlbufpos) > BEGV
13162 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
13163 && (CHARPOS (tlbufpos) == ZV
13164 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
13165 /* Former continuation line has disappeared by becoming empty. */
13166 goto cancel;
13167 else if (window_outdated (w) || MINI_WINDOW_P (w))
13169 /* We have to handle the case of continuation around a
13170 wide-column character (see the comment in indent.c around
13171 line 1340).
13173 For instance, in the following case:
13175 -------- Insert --------
13176 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
13177 J_I_ ==> J_I_ `^^' are cursors.
13178 ^^ ^^
13179 -------- --------
13181 As we have to redraw the line above, we cannot use this
13182 optimization. */
13184 struct it it;
13185 int line_height_before = this_line_pixel_height;
13187 /* Note that start_display will handle the case that the
13188 line starting at tlbufpos is a continuation line. */
13189 start_display (&it, w, tlbufpos);
13191 /* Implementation note: It this still necessary? */
13192 if (it.current_x != this_line_start_x)
13193 goto cancel;
13195 TRACE ((stderr, "trying display optimization 1\n"));
13196 w->cursor.vpos = -1;
13197 overlay_arrow_seen = 0;
13198 it.vpos = this_line_vpos;
13199 it.current_y = this_line_y;
13200 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
13201 display_line (&it);
13203 /* If line contains point, is not continued,
13204 and ends at same distance from eob as before, we win. */
13205 if (w->cursor.vpos >= 0
13206 /* Line is not continued, otherwise this_line_start_pos
13207 would have been set to 0 in display_line. */
13208 && CHARPOS (this_line_start_pos)
13209 /* Line ends as before. */
13210 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
13211 /* Line has same height as before. Otherwise other lines
13212 would have to be shifted up or down. */
13213 && this_line_pixel_height == line_height_before)
13215 /* If this is not the window's last line, we must adjust
13216 the charstarts of the lines below. */
13217 if (it.current_y < it.last_visible_y)
13219 struct glyph_row *row
13220 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
13221 ptrdiff_t delta, delta_bytes;
13223 /* We used to distinguish between two cases here,
13224 conditioned by Z - CHARPOS (tlendpos) == ZV, for
13225 when the line ends in a newline or the end of the
13226 buffer's accessible portion. But both cases did
13227 the same, so they were collapsed. */
13228 delta = (Z
13229 - CHARPOS (tlendpos)
13230 - MATRIX_ROW_START_CHARPOS (row));
13231 delta_bytes = (Z_BYTE
13232 - BYTEPOS (tlendpos)
13233 - MATRIX_ROW_START_BYTEPOS (row));
13235 increment_matrix_positions (w->current_matrix,
13236 this_line_vpos + 1,
13237 w->current_matrix->nrows,
13238 delta, delta_bytes);
13241 /* If this row displays text now but previously didn't,
13242 or vice versa, w->window_end_vpos may have to be
13243 adjusted. */
13244 if (MATRIX_ROW_DISPLAYS_TEXT_P (it.glyph_row - 1))
13246 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
13247 wset_window_end_vpos (w, make_number (this_line_vpos));
13249 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
13250 && this_line_vpos > 0)
13251 wset_window_end_vpos (w, make_number (this_line_vpos - 1));
13252 w->window_end_valid = 0;
13254 /* Update hint: No need to try to scroll in update_window. */
13255 w->desired_matrix->no_scrolling_p = 1;
13257 #ifdef GLYPH_DEBUG
13258 *w->desired_matrix->method = 0;
13259 debug_method_add (w, "optimization 1");
13260 #endif
13261 #ifdef HAVE_WINDOW_SYSTEM
13262 update_window_fringes (w, 0);
13263 #endif
13264 goto update;
13266 else
13267 goto cancel;
13269 else if (/* Cursor position hasn't changed. */
13270 PT == w->last_point
13271 /* Make sure the cursor was last displayed
13272 in this window. Otherwise we have to reposition it. */
13273 && 0 <= w->cursor.vpos
13274 && w->cursor.vpos < WINDOW_TOTAL_LINES (w))
13276 if (!must_finish)
13278 do_pending_window_change (1);
13279 /* If selected_window changed, redisplay again. */
13280 if (WINDOWP (selected_window)
13281 && (w = XWINDOW (selected_window)) != sw)
13282 goto retry;
13284 /* We used to always goto end_of_redisplay here, but this
13285 isn't enough if we have a blinking cursor. */
13286 if (w->cursor_off_p == w->last_cursor_off_p)
13287 goto end_of_redisplay;
13289 goto update;
13291 /* If highlighting the region, or if the cursor is in the echo area,
13292 then we can't just move the cursor. */
13293 else if (! (!NILP (Vtransient_mark_mode)
13294 && !NILP (BVAR (current_buffer, mark_active)))
13295 && (EQ (selected_window,
13296 BVAR (current_buffer, last_selected_window))
13297 || highlight_nonselected_windows)
13298 && !w->region_showing
13299 && NILP (Vshow_trailing_whitespace)
13300 && !cursor_in_echo_area)
13302 struct it it;
13303 struct glyph_row *row;
13305 /* Skip from tlbufpos to PT and see where it is. Note that
13306 PT may be in invisible text. If so, we will end at the
13307 next visible position. */
13308 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
13309 NULL, DEFAULT_FACE_ID);
13310 it.current_x = this_line_start_x;
13311 it.current_y = this_line_y;
13312 it.vpos = this_line_vpos;
13314 /* The call to move_it_to stops in front of PT, but
13315 moves over before-strings. */
13316 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
13318 if (it.vpos == this_line_vpos
13319 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
13320 row->enabled_p))
13322 eassert (this_line_vpos == it.vpos);
13323 eassert (this_line_y == it.current_y);
13324 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13325 #ifdef GLYPH_DEBUG
13326 *w->desired_matrix->method = 0;
13327 debug_method_add (w, "optimization 3");
13328 #endif
13329 goto update;
13331 else
13332 goto cancel;
13335 cancel:
13336 /* Text changed drastically or point moved off of line. */
13337 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
13340 CHARPOS (this_line_start_pos) = 0;
13341 consider_all_windows_p |= buffer_shared_and_changed ();
13342 ++clear_face_cache_count;
13343 #ifdef HAVE_WINDOW_SYSTEM
13344 ++clear_image_cache_count;
13345 #endif
13347 /* Build desired matrices, and update the display. If
13348 consider_all_windows_p is non-zero, do it for all windows on all
13349 frames. Otherwise do it for selected_window, only. */
13351 if (consider_all_windows_p)
13353 FOR_EACH_FRAME (tail, frame)
13354 XFRAME (frame)->updated_p = 0;
13356 FOR_EACH_FRAME (tail, frame)
13358 struct frame *f = XFRAME (frame);
13360 /* We don't have to do anything for unselected terminal
13361 frames. */
13362 if ((FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
13363 && !EQ (FRAME_TTY (f)->top_frame, frame))
13364 continue;
13366 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
13368 /* Mark all the scroll bars to be removed; we'll redeem
13369 the ones we want when we redisplay their windows. */
13370 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
13371 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
13373 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
13374 redisplay_windows (FRAME_ROOT_WINDOW (f));
13376 /* The X error handler may have deleted that frame. */
13377 if (!FRAME_LIVE_P (f))
13378 continue;
13380 /* Any scroll bars which redisplay_windows should have
13381 nuked should now go away. */
13382 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
13383 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
13385 /* If fonts changed, display again. */
13386 /* ??? rms: I suspect it is a mistake to jump all the way
13387 back to retry here. It should just retry this frame. */
13388 if (fonts_changed_p)
13389 goto retry;
13391 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
13393 /* See if we have to hscroll. */
13394 if (!f->already_hscrolled_p)
13396 f->already_hscrolled_p = 1;
13397 if (hscroll_windows (f->root_window))
13398 goto retry;
13401 /* Prevent various kinds of signals during display
13402 update. stdio is not robust about handling
13403 signals, which can cause an apparent I/O
13404 error. */
13405 if (interrupt_input)
13406 unrequest_sigio ();
13407 STOP_POLLING;
13409 /* Update the display. */
13410 set_window_update_flags (XWINDOW (f->root_window), 1);
13411 pending |= update_frame (f, 0, 0);
13412 f->updated_p = 1;
13417 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
13419 if (!pending)
13421 /* Do the mark_window_display_accurate after all windows have
13422 been redisplayed because this call resets flags in buffers
13423 which are needed for proper redisplay. */
13424 FOR_EACH_FRAME (tail, frame)
13426 struct frame *f = XFRAME (frame);
13427 if (f->updated_p)
13429 mark_window_display_accurate (f->root_window, 1);
13430 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
13431 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
13436 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
13438 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
13439 struct frame *mini_frame;
13441 displayed_buffer = XBUFFER (XWINDOW (selected_window)->contents);
13442 /* Use list_of_error, not Qerror, so that
13443 we catch only errors and don't run the debugger. */
13444 internal_condition_case_1 (redisplay_window_1, selected_window,
13445 list_of_error,
13446 redisplay_window_error);
13447 if (update_miniwindow_p)
13448 internal_condition_case_1 (redisplay_window_1, mini_window,
13449 list_of_error,
13450 redisplay_window_error);
13452 /* Compare desired and current matrices, perform output. */
13454 update:
13455 /* If fonts changed, display again. */
13456 if (fonts_changed_p)
13457 goto retry;
13459 /* Prevent various kinds of signals during display update.
13460 stdio is not robust about handling signals,
13461 which can cause an apparent I/O error. */
13462 if (interrupt_input)
13463 unrequest_sigio ();
13464 STOP_POLLING;
13466 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
13468 if (hscroll_windows (selected_window))
13469 goto retry;
13471 XWINDOW (selected_window)->must_be_updated_p = 1;
13472 pending = update_frame (sf, 0, 0);
13475 /* We may have called echo_area_display at the top of this
13476 function. If the echo area is on another frame, that may
13477 have put text on a frame other than the selected one, so the
13478 above call to update_frame would not have caught it. Catch
13479 it here. */
13480 mini_window = FRAME_MINIBUF_WINDOW (sf);
13481 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
13483 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
13485 XWINDOW (mini_window)->must_be_updated_p = 1;
13486 pending |= update_frame (mini_frame, 0, 0);
13487 if (!pending && hscroll_windows (mini_window))
13488 goto retry;
13492 /* If display was paused because of pending input, make sure we do a
13493 thorough update the next time. */
13494 if (pending)
13496 /* Prevent the optimization at the beginning of
13497 redisplay_internal that tries a single-line update of the
13498 line containing the cursor in the selected window. */
13499 CHARPOS (this_line_start_pos) = 0;
13501 /* Let the overlay arrow be updated the next time. */
13502 update_overlay_arrows (0);
13504 /* If we pause after scrolling, some rows in the current
13505 matrices of some windows are not valid. */
13506 if (!WINDOW_FULL_WIDTH_P (w)
13507 && !FRAME_WINDOW_P (XFRAME (w->frame)))
13508 update_mode_lines = 1;
13510 else
13512 if (!consider_all_windows_p)
13514 /* This has already been done above if
13515 consider_all_windows_p is set. */
13516 mark_window_display_accurate_1 (w, 1);
13518 /* Say overlay arrows are up to date. */
13519 update_overlay_arrows (1);
13521 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
13522 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
13525 update_mode_lines = 0;
13526 windows_or_buffers_changed = 0;
13527 cursor_type_changed = 0;
13530 /* Start SIGIO interrupts coming again. Having them off during the
13531 code above makes it less likely one will discard output, but not
13532 impossible, since there might be stuff in the system buffer here.
13533 But it is much hairier to try to do anything about that. */
13534 if (interrupt_input)
13535 request_sigio ();
13536 RESUME_POLLING;
13538 /* If a frame has become visible which was not before, redisplay
13539 again, so that we display it. Expose events for such a frame
13540 (which it gets when becoming visible) don't call the parts of
13541 redisplay constructing glyphs, so simply exposing a frame won't
13542 display anything in this case. So, we have to display these
13543 frames here explicitly. */
13544 if (!pending)
13546 int new_count = 0;
13548 FOR_EACH_FRAME (tail, frame)
13550 int this_is_visible = 0;
13552 if (XFRAME (frame)->visible)
13553 this_is_visible = 1;
13555 if (this_is_visible)
13556 new_count++;
13559 if (new_count != number_of_visible_frames)
13560 windows_or_buffers_changed++;
13563 /* Change frame size now if a change is pending. */
13564 do_pending_window_change (1);
13566 /* If we just did a pending size change, or have additional
13567 visible frames, or selected_window changed, redisplay again. */
13568 if ((windows_or_buffers_changed && !pending)
13569 || (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw))
13570 goto retry;
13572 /* Clear the face and image caches.
13574 We used to do this only if consider_all_windows_p. But the cache
13575 needs to be cleared if a timer creates images in the current
13576 buffer (e.g. the test case in Bug#6230). */
13578 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
13580 clear_face_cache (0);
13581 clear_face_cache_count = 0;
13584 #ifdef HAVE_WINDOW_SYSTEM
13585 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
13587 clear_image_caches (Qnil);
13588 clear_image_cache_count = 0;
13590 #endif /* HAVE_WINDOW_SYSTEM */
13592 end_of_redisplay:
13593 unbind_to (count, Qnil);
13594 RESUME_POLLING;
13598 /* Redisplay, but leave alone any recent echo area message unless
13599 another message has been requested in its place.
13601 This is useful in situations where you need to redisplay but no
13602 user action has occurred, making it inappropriate for the message
13603 area to be cleared. See tracking_off and
13604 wait_reading_process_output for examples of these situations.
13606 FROM_WHERE is an integer saying from where this function was
13607 called. This is useful for debugging. */
13609 void
13610 redisplay_preserve_echo_area (int from_where)
13612 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
13614 if (!NILP (echo_area_buffer[1]))
13616 /* We have a previously displayed message, but no current
13617 message. Redisplay the previous message. */
13618 display_last_displayed_message_p = 1;
13619 redisplay_internal ();
13620 display_last_displayed_message_p = 0;
13622 else
13623 redisplay_internal ();
13625 if (FRAME_RIF (SELECTED_FRAME ()) != NULL
13626 && FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
13627 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (NULL);
13631 /* Function registered with record_unwind_protect in redisplay_internal. */
13633 static void
13634 unwind_redisplay (void)
13636 redisplaying_p = 0;
13640 /* Mark the display of leaf window W as accurate or inaccurate.
13641 If ACCURATE_P is non-zero mark display of W as accurate. If
13642 ACCURATE_P is zero, arrange for W to be redisplayed the next
13643 time redisplay_internal is called. */
13645 static void
13646 mark_window_display_accurate_1 (struct window *w, int accurate_p)
13648 struct buffer *b = XBUFFER (w->contents);
13650 w->last_modified = accurate_p ? BUF_MODIFF (b) : 0;
13651 w->last_overlay_modified = accurate_p ? BUF_OVERLAY_MODIFF (b) : 0;
13652 w->last_had_star = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b);
13654 if (accurate_p)
13656 b->clip_changed = 0;
13657 b->prevent_redisplay_optimizations_p = 0;
13659 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
13660 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
13661 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
13662 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
13664 w->current_matrix->buffer = b;
13665 w->current_matrix->begv = BUF_BEGV (b);
13666 w->current_matrix->zv = BUF_ZV (b);
13668 w->last_cursor = w->cursor;
13669 w->last_cursor_off_p = w->cursor_off_p;
13671 if (w == XWINDOW (selected_window))
13672 w->last_point = BUF_PT (b);
13673 else
13674 w->last_point = marker_position (w->pointm);
13676 w->window_end_valid = 1;
13677 w->update_mode_line = 0;
13682 /* Mark the display of windows in the window tree rooted at WINDOW as
13683 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
13684 windows as accurate. If ACCURATE_P is zero, arrange for windows to
13685 be redisplayed the next time redisplay_internal is called. */
13687 void
13688 mark_window_display_accurate (Lisp_Object window, int accurate_p)
13690 struct window *w;
13692 for (; !NILP (window); window = w->next)
13694 w = XWINDOW (window);
13695 if (WINDOWP (w->contents))
13696 mark_window_display_accurate (w->contents, accurate_p);
13697 else
13698 mark_window_display_accurate_1 (w, accurate_p);
13701 if (accurate_p)
13702 update_overlay_arrows (1);
13703 else
13704 /* Force a thorough redisplay the next time by setting
13705 last_arrow_position and last_arrow_string to t, which is
13706 unequal to any useful value of Voverlay_arrow_... */
13707 update_overlay_arrows (-1);
13711 /* Return value in display table DP (Lisp_Char_Table *) for character
13712 C. Since a display table doesn't have any parent, we don't have to
13713 follow parent. Do not call this function directly but use the
13714 macro DISP_CHAR_VECTOR. */
13716 Lisp_Object
13717 disp_char_vector (struct Lisp_Char_Table *dp, int c)
13719 Lisp_Object val;
13721 if (ASCII_CHAR_P (c))
13723 val = dp->ascii;
13724 if (SUB_CHAR_TABLE_P (val))
13725 val = XSUB_CHAR_TABLE (val)->contents[c];
13727 else
13729 Lisp_Object table;
13731 XSETCHAR_TABLE (table, dp);
13732 val = char_table_ref (table, c);
13734 if (NILP (val))
13735 val = dp->defalt;
13736 return val;
13741 /***********************************************************************
13742 Window Redisplay
13743 ***********************************************************************/
13745 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
13747 static void
13748 redisplay_windows (Lisp_Object window)
13750 while (!NILP (window))
13752 struct window *w = XWINDOW (window);
13754 if (WINDOWP (w->contents))
13755 redisplay_windows (w->contents);
13756 else if (BUFFERP (w->contents))
13758 displayed_buffer = XBUFFER (w->contents);
13759 /* Use list_of_error, not Qerror, so that
13760 we catch only errors and don't run the debugger. */
13761 internal_condition_case_1 (redisplay_window_0, window,
13762 list_of_error,
13763 redisplay_window_error);
13766 window = w->next;
13770 static Lisp_Object
13771 redisplay_window_error (Lisp_Object ignore)
13773 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
13774 return Qnil;
13777 static Lisp_Object
13778 redisplay_window_0 (Lisp_Object window)
13780 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
13781 redisplay_window (window, 0);
13782 return Qnil;
13785 static Lisp_Object
13786 redisplay_window_1 (Lisp_Object window)
13788 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
13789 redisplay_window (window, 1);
13790 return Qnil;
13794 /* Set cursor position of W. PT is assumed to be displayed in ROW.
13795 DELTA and DELTA_BYTES are the numbers of characters and bytes by
13796 which positions recorded in ROW differ from current buffer
13797 positions.
13799 Return 0 if cursor is not on this row, 1 otherwise. */
13801 static int
13802 set_cursor_from_row (struct window *w, struct glyph_row *row,
13803 struct glyph_matrix *matrix,
13804 ptrdiff_t delta, ptrdiff_t delta_bytes,
13805 int dy, int dvpos)
13807 struct glyph *glyph = row->glyphs[TEXT_AREA];
13808 struct glyph *end = glyph + row->used[TEXT_AREA];
13809 struct glyph *cursor = NULL;
13810 /* The last known character position in row. */
13811 ptrdiff_t last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
13812 int x = row->x;
13813 ptrdiff_t pt_old = PT - delta;
13814 ptrdiff_t pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
13815 ptrdiff_t pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
13816 struct glyph *glyph_before = glyph - 1, *glyph_after = end;
13817 /* A glyph beyond the edge of TEXT_AREA which we should never
13818 touch. */
13819 struct glyph *glyphs_end = end;
13820 /* Non-zero means we've found a match for cursor position, but that
13821 glyph has the avoid_cursor_p flag set. */
13822 int match_with_avoid_cursor = 0;
13823 /* Non-zero means we've seen at least one glyph that came from a
13824 display string. */
13825 int string_seen = 0;
13826 /* Largest and smallest buffer positions seen so far during scan of
13827 glyph row. */
13828 ptrdiff_t bpos_max = pos_before;
13829 ptrdiff_t bpos_min = pos_after;
13830 /* Last buffer position covered by an overlay string with an integer
13831 `cursor' property. */
13832 ptrdiff_t bpos_covered = 0;
13833 /* Non-zero means the display string on which to display the cursor
13834 comes from a text property, not from an overlay. */
13835 int string_from_text_prop = 0;
13837 /* Don't even try doing anything if called for a mode-line or
13838 header-line row, since the rest of the code isn't prepared to
13839 deal with such calamities. */
13840 eassert (!row->mode_line_p);
13841 if (row->mode_line_p)
13842 return 0;
13844 /* Skip over glyphs not having an object at the start and the end of
13845 the row. These are special glyphs like truncation marks on
13846 terminal frames. */
13847 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
13849 if (!row->reversed_p)
13851 while (glyph < end
13852 && INTEGERP (glyph->object)
13853 && glyph->charpos < 0)
13855 x += glyph->pixel_width;
13856 ++glyph;
13858 while (end > glyph
13859 && INTEGERP ((end - 1)->object)
13860 /* CHARPOS is zero for blanks and stretch glyphs
13861 inserted by extend_face_to_end_of_line. */
13862 && (end - 1)->charpos <= 0)
13863 --end;
13864 glyph_before = glyph - 1;
13865 glyph_after = end;
13867 else
13869 struct glyph *g;
13871 /* If the glyph row is reversed, we need to process it from back
13872 to front, so swap the edge pointers. */
13873 glyphs_end = end = glyph - 1;
13874 glyph += row->used[TEXT_AREA] - 1;
13876 while (glyph > end + 1
13877 && INTEGERP (glyph->object)
13878 && glyph->charpos < 0)
13880 --glyph;
13881 x -= glyph->pixel_width;
13883 if (INTEGERP (glyph->object) && glyph->charpos < 0)
13884 --glyph;
13885 /* By default, in reversed rows we put the cursor on the
13886 rightmost (first in the reading order) glyph. */
13887 for (g = end + 1; g < glyph; g++)
13888 x += g->pixel_width;
13889 while (end < glyph
13890 && INTEGERP ((end + 1)->object)
13891 && (end + 1)->charpos <= 0)
13892 ++end;
13893 glyph_before = glyph + 1;
13894 glyph_after = end;
13897 else if (row->reversed_p)
13899 /* In R2L rows that don't display text, put the cursor on the
13900 rightmost glyph. Case in point: an empty last line that is
13901 part of an R2L paragraph. */
13902 cursor = end - 1;
13903 /* Avoid placing the cursor on the last glyph of the row, where
13904 on terminal frames we hold the vertical border between
13905 adjacent windows. */
13906 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w))
13907 && !WINDOW_RIGHTMOST_P (w)
13908 && cursor == row->glyphs[LAST_AREA] - 1)
13909 cursor--;
13910 x = -1; /* will be computed below, at label compute_x */
13913 /* Step 1: Try to find the glyph whose character position
13914 corresponds to point. If that's not possible, find 2 glyphs
13915 whose character positions are the closest to point, one before
13916 point, the other after it. */
13917 if (!row->reversed_p)
13918 while (/* not marched to end of glyph row */
13919 glyph < end
13920 /* glyph was not inserted by redisplay for internal purposes */
13921 && !INTEGERP (glyph->object))
13923 if (BUFFERP (glyph->object))
13925 ptrdiff_t dpos = glyph->charpos - pt_old;
13927 if (glyph->charpos > bpos_max)
13928 bpos_max = glyph->charpos;
13929 if (glyph->charpos < bpos_min)
13930 bpos_min = glyph->charpos;
13931 if (!glyph->avoid_cursor_p)
13933 /* If we hit point, we've found the glyph on which to
13934 display the cursor. */
13935 if (dpos == 0)
13937 match_with_avoid_cursor = 0;
13938 break;
13940 /* See if we've found a better approximation to
13941 POS_BEFORE or to POS_AFTER. */
13942 if (0 > dpos && dpos > pos_before - pt_old)
13944 pos_before = glyph->charpos;
13945 glyph_before = glyph;
13947 else if (0 < dpos && dpos < pos_after - pt_old)
13949 pos_after = glyph->charpos;
13950 glyph_after = glyph;
13953 else if (dpos == 0)
13954 match_with_avoid_cursor = 1;
13956 else if (STRINGP (glyph->object))
13958 Lisp_Object chprop;
13959 ptrdiff_t glyph_pos = glyph->charpos;
13961 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
13962 glyph->object);
13963 if (!NILP (chprop))
13965 /* If the string came from a `display' text property,
13966 look up the buffer position of that property and
13967 use that position to update bpos_max, as if we
13968 actually saw such a position in one of the row's
13969 glyphs. This helps with supporting integer values
13970 of `cursor' property on the display string in
13971 situations where most or all of the row's buffer
13972 text is completely covered by display properties,
13973 so that no glyph with valid buffer positions is
13974 ever seen in the row. */
13975 ptrdiff_t prop_pos =
13976 string_buffer_position_lim (glyph->object, pos_before,
13977 pos_after, 0);
13979 if (prop_pos >= pos_before)
13980 bpos_max = prop_pos - 1;
13982 if (INTEGERP (chprop))
13984 bpos_covered = bpos_max + XINT (chprop);
13985 /* If the `cursor' property covers buffer positions up
13986 to and including point, we should display cursor on
13987 this glyph. Note that, if a `cursor' property on one
13988 of the string's characters has an integer value, we
13989 will break out of the loop below _before_ we get to
13990 the position match above. IOW, integer values of
13991 the `cursor' property override the "exact match for
13992 point" strategy of positioning the cursor. */
13993 /* Implementation note: bpos_max == pt_old when, e.g.,
13994 we are in an empty line, where bpos_max is set to
13995 MATRIX_ROW_START_CHARPOS, see above. */
13996 if (bpos_max <= pt_old && bpos_covered >= pt_old)
13998 cursor = glyph;
13999 break;
14003 string_seen = 1;
14005 x += glyph->pixel_width;
14006 ++glyph;
14008 else if (glyph > end) /* row is reversed */
14009 while (!INTEGERP (glyph->object))
14011 if (BUFFERP (glyph->object))
14013 ptrdiff_t dpos = glyph->charpos - pt_old;
14015 if (glyph->charpos > bpos_max)
14016 bpos_max = glyph->charpos;
14017 if (glyph->charpos < bpos_min)
14018 bpos_min = glyph->charpos;
14019 if (!glyph->avoid_cursor_p)
14021 if (dpos == 0)
14023 match_with_avoid_cursor = 0;
14024 break;
14026 if (0 > dpos && dpos > pos_before - pt_old)
14028 pos_before = glyph->charpos;
14029 glyph_before = glyph;
14031 else if (0 < dpos && dpos < pos_after - pt_old)
14033 pos_after = glyph->charpos;
14034 glyph_after = glyph;
14037 else if (dpos == 0)
14038 match_with_avoid_cursor = 1;
14040 else if (STRINGP (glyph->object))
14042 Lisp_Object chprop;
14043 ptrdiff_t glyph_pos = glyph->charpos;
14045 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
14046 glyph->object);
14047 if (!NILP (chprop))
14049 ptrdiff_t prop_pos =
14050 string_buffer_position_lim (glyph->object, pos_before,
14051 pos_after, 0);
14053 if (prop_pos >= pos_before)
14054 bpos_max = prop_pos - 1;
14056 if (INTEGERP (chprop))
14058 bpos_covered = bpos_max + XINT (chprop);
14059 /* If the `cursor' property covers buffer positions up
14060 to and including point, we should display cursor on
14061 this glyph. */
14062 if (bpos_max <= pt_old && bpos_covered >= pt_old)
14064 cursor = glyph;
14065 break;
14068 string_seen = 1;
14070 --glyph;
14071 if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
14073 x--; /* can't use any pixel_width */
14074 break;
14076 x -= glyph->pixel_width;
14079 /* Step 2: If we didn't find an exact match for point, we need to
14080 look for a proper place to put the cursor among glyphs between
14081 GLYPH_BEFORE and GLYPH_AFTER. */
14082 if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
14083 && BUFFERP (glyph->object) && glyph->charpos == pt_old)
14084 && !(bpos_max < pt_old && pt_old <= bpos_covered))
14086 /* An empty line has a single glyph whose OBJECT is zero and
14087 whose CHARPOS is the position of a newline on that line.
14088 Note that on a TTY, there are more glyphs after that, which
14089 were produced by extend_face_to_end_of_line, but their
14090 CHARPOS is zero or negative. */
14091 int empty_line_p =
14092 (row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
14093 && INTEGERP (glyph->object) && glyph->charpos > 0
14094 /* On a TTY, continued and truncated rows also have a glyph at
14095 their end whose OBJECT is zero and whose CHARPOS is
14096 positive (the continuation and truncation glyphs), but such
14097 rows are obviously not "empty". */
14098 && !(row->continued_p || row->truncated_on_right_p);
14100 if (row->ends_in_ellipsis_p && pos_after == last_pos)
14102 ptrdiff_t ellipsis_pos;
14104 /* Scan back over the ellipsis glyphs. */
14105 if (!row->reversed_p)
14107 ellipsis_pos = (glyph - 1)->charpos;
14108 while (glyph > row->glyphs[TEXT_AREA]
14109 && (glyph - 1)->charpos == ellipsis_pos)
14110 glyph--, x -= glyph->pixel_width;
14111 /* That loop always goes one position too far, including
14112 the glyph before the ellipsis. So scan forward over
14113 that one. */
14114 x += glyph->pixel_width;
14115 glyph++;
14117 else /* row is reversed */
14119 ellipsis_pos = (glyph + 1)->charpos;
14120 while (glyph < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14121 && (glyph + 1)->charpos == ellipsis_pos)
14122 glyph++, x += glyph->pixel_width;
14123 x -= glyph->pixel_width;
14124 glyph--;
14127 else if (match_with_avoid_cursor)
14129 cursor = glyph_after;
14130 x = -1;
14132 else if (string_seen)
14134 int incr = row->reversed_p ? -1 : +1;
14136 /* Need to find the glyph that came out of a string which is
14137 present at point. That glyph is somewhere between
14138 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
14139 positioned between POS_BEFORE and POS_AFTER in the
14140 buffer. */
14141 struct glyph *start, *stop;
14142 ptrdiff_t pos = pos_before;
14144 x = -1;
14146 /* If the row ends in a newline from a display string,
14147 reordering could have moved the glyphs belonging to the
14148 string out of the [GLYPH_BEFORE..GLYPH_AFTER] range. So
14149 in this case we extend the search to the last glyph in
14150 the row that was not inserted by redisplay. */
14151 if (row->ends_in_newline_from_string_p)
14153 glyph_after = end;
14154 pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
14157 /* GLYPH_BEFORE and GLYPH_AFTER are the glyphs that
14158 correspond to POS_BEFORE and POS_AFTER, respectively. We
14159 need START and STOP in the order that corresponds to the
14160 row's direction as given by its reversed_p flag. If the
14161 directionality of characters between POS_BEFORE and
14162 POS_AFTER is the opposite of the row's base direction,
14163 these characters will have been reordered for display,
14164 and we need to reverse START and STOP. */
14165 if (!row->reversed_p)
14167 start = min (glyph_before, glyph_after);
14168 stop = max (glyph_before, glyph_after);
14170 else
14172 start = max (glyph_before, glyph_after);
14173 stop = min (glyph_before, glyph_after);
14175 for (glyph = start + incr;
14176 row->reversed_p ? glyph > stop : glyph < stop; )
14179 /* Any glyphs that come from the buffer are here because
14180 of bidi reordering. Skip them, and only pay
14181 attention to glyphs that came from some string. */
14182 if (STRINGP (glyph->object))
14184 Lisp_Object str;
14185 ptrdiff_t tem;
14186 /* If the display property covers the newline, we
14187 need to search for it one position farther. */
14188 ptrdiff_t lim = pos_after
14189 + (pos_after == MATRIX_ROW_END_CHARPOS (row) + delta);
14191 string_from_text_prop = 0;
14192 str = glyph->object;
14193 tem = string_buffer_position_lim (str, pos, lim, 0);
14194 if (tem == 0 /* from overlay */
14195 || pos <= tem)
14197 /* If the string from which this glyph came is
14198 found in the buffer at point, or at position
14199 that is closer to point than pos_after, then
14200 we've found the glyph we've been looking for.
14201 If it comes from an overlay (tem == 0), and
14202 it has the `cursor' property on one of its
14203 glyphs, record that glyph as a candidate for
14204 displaying the cursor. (As in the
14205 unidirectional version, we will display the
14206 cursor on the last candidate we find.) */
14207 if (tem == 0
14208 || tem == pt_old
14209 || (tem - pt_old > 0 && tem < pos_after))
14211 /* The glyphs from this string could have
14212 been reordered. Find the one with the
14213 smallest string position. Or there could
14214 be a character in the string with the
14215 `cursor' property, which means display
14216 cursor on that character's glyph. */
14217 ptrdiff_t strpos = glyph->charpos;
14219 if (tem)
14221 cursor = glyph;
14222 string_from_text_prop = 1;
14224 for ( ;
14225 (row->reversed_p ? glyph > stop : glyph < stop)
14226 && EQ (glyph->object, str);
14227 glyph += incr)
14229 Lisp_Object cprop;
14230 ptrdiff_t gpos = glyph->charpos;
14232 cprop = Fget_char_property (make_number (gpos),
14233 Qcursor,
14234 glyph->object);
14235 if (!NILP (cprop))
14237 cursor = glyph;
14238 break;
14240 if (tem && glyph->charpos < strpos)
14242 strpos = glyph->charpos;
14243 cursor = glyph;
14247 if (tem == pt_old
14248 || (tem - pt_old > 0 && tem < pos_after))
14249 goto compute_x;
14251 if (tem)
14252 pos = tem + 1; /* don't find previous instances */
14254 /* This string is not what we want; skip all of the
14255 glyphs that came from it. */
14256 while ((row->reversed_p ? glyph > stop : glyph < stop)
14257 && EQ (glyph->object, str))
14258 glyph += incr;
14260 else
14261 glyph += incr;
14264 /* If we reached the end of the line, and END was from a string,
14265 the cursor is not on this line. */
14266 if (cursor == NULL
14267 && (row->reversed_p ? glyph <= end : glyph >= end)
14268 && (row->reversed_p ? end > glyphs_end : end < glyphs_end)
14269 && STRINGP (end->object)
14270 && row->continued_p)
14271 return 0;
14273 /* A truncated row may not include PT among its character positions.
14274 Setting the cursor inside the scroll margin will trigger
14275 recalculation of hscroll in hscroll_window_tree. But if a
14276 display string covers point, defer to the string-handling
14277 code below to figure this out. */
14278 else if (row->truncated_on_left_p && pt_old < bpos_min)
14280 cursor = glyph_before;
14281 x = -1;
14283 else if ((row->truncated_on_right_p && pt_old > bpos_max)
14284 /* Zero-width characters produce no glyphs. */
14285 || (!empty_line_p
14286 && (row->reversed_p
14287 ? glyph_after > glyphs_end
14288 : glyph_after < glyphs_end)))
14290 cursor = glyph_after;
14291 x = -1;
14295 compute_x:
14296 if (cursor != NULL)
14297 glyph = cursor;
14298 else if (glyph == glyphs_end
14299 && pos_before == pos_after
14300 && STRINGP ((row->reversed_p
14301 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14302 : row->glyphs[TEXT_AREA])->object))
14304 /* If all the glyphs of this row came from strings, put the
14305 cursor on the first glyph of the row. This avoids having the
14306 cursor outside of the text area in this very rare and hard
14307 use case. */
14308 glyph =
14309 row->reversed_p
14310 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14311 : row->glyphs[TEXT_AREA];
14313 if (x < 0)
14315 struct glyph *g;
14317 /* Need to compute x that corresponds to GLYPH. */
14318 for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++)
14320 if (g >= row->glyphs[TEXT_AREA] + row->used[TEXT_AREA])
14321 emacs_abort ();
14322 x += g->pixel_width;
14326 /* ROW could be part of a continued line, which, under bidi
14327 reordering, might have other rows whose start and end charpos
14328 occlude point. Only set w->cursor if we found a better
14329 approximation to the cursor position than we have from previously
14330 examined candidate rows belonging to the same continued line. */
14331 if (/* we already have a candidate row */
14332 w->cursor.vpos >= 0
14333 /* that candidate is not the row we are processing */
14334 && MATRIX_ROW (matrix, w->cursor.vpos) != row
14335 /* Make sure cursor.vpos specifies a row whose start and end
14336 charpos occlude point, and it is valid candidate for being a
14337 cursor-row. This is because some callers of this function
14338 leave cursor.vpos at the row where the cursor was displayed
14339 during the last redisplay cycle. */
14340 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old
14341 && pt_old <= MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14342 && cursor_row_p (MATRIX_ROW (matrix, w->cursor.vpos)))
14344 struct glyph *g1 =
14345 MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
14347 /* Don't consider glyphs that are outside TEXT_AREA. */
14348 if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
14349 return 0;
14350 /* Keep the candidate whose buffer position is the closest to
14351 point or has the `cursor' property. */
14352 if (/* previous candidate is a glyph in TEXT_AREA of that row */
14353 w->cursor.hpos >= 0
14354 && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
14355 && ((BUFFERP (g1->object)
14356 && (g1->charpos == pt_old /* an exact match always wins */
14357 || (BUFFERP (glyph->object)
14358 && eabs (g1->charpos - pt_old)
14359 < eabs (glyph->charpos - pt_old))))
14360 /* previous candidate is a glyph from a string that has
14361 a non-nil `cursor' property */
14362 || (STRINGP (g1->object)
14363 && (!NILP (Fget_char_property (make_number (g1->charpos),
14364 Qcursor, g1->object))
14365 /* previous candidate is from the same display
14366 string as this one, and the display string
14367 came from a text property */
14368 || (EQ (g1->object, glyph->object)
14369 && string_from_text_prop)
14370 /* this candidate is from newline and its
14371 position is not an exact match */
14372 || (INTEGERP (glyph->object)
14373 && glyph->charpos != pt_old)))))
14374 return 0;
14375 /* If this candidate gives an exact match, use that. */
14376 if (!((BUFFERP (glyph->object) && glyph->charpos == pt_old)
14377 /* If this candidate is a glyph created for the
14378 terminating newline of a line, and point is on that
14379 newline, it wins because it's an exact match. */
14380 || (!row->continued_p
14381 && INTEGERP (glyph->object)
14382 && glyph->charpos == 0
14383 && pt_old == MATRIX_ROW_END_CHARPOS (row) - 1))
14384 /* Otherwise, keep the candidate that comes from a row
14385 spanning less buffer positions. This may win when one or
14386 both candidate positions are on glyphs that came from
14387 display strings, for which we cannot compare buffer
14388 positions. */
14389 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14390 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14391 < MATRIX_ROW_END_CHARPOS (row) - MATRIX_ROW_START_CHARPOS (row))
14392 return 0;
14394 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
14395 w->cursor.x = x;
14396 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
14397 w->cursor.y = row->y + dy;
14399 if (w == XWINDOW (selected_window))
14401 if (!row->continued_p
14402 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
14403 && row->x == 0)
14405 this_line_buffer = XBUFFER (w->contents);
14407 CHARPOS (this_line_start_pos)
14408 = MATRIX_ROW_START_CHARPOS (row) + delta;
14409 BYTEPOS (this_line_start_pos)
14410 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
14412 CHARPOS (this_line_end_pos)
14413 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
14414 BYTEPOS (this_line_end_pos)
14415 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
14417 this_line_y = w->cursor.y;
14418 this_line_pixel_height = row->height;
14419 this_line_vpos = w->cursor.vpos;
14420 this_line_start_x = row->x;
14422 else
14423 CHARPOS (this_line_start_pos) = 0;
14426 return 1;
14430 /* Run window scroll functions, if any, for WINDOW with new window
14431 start STARTP. Sets the window start of WINDOW to that position.
14433 We assume that the window's buffer is really current. */
14435 static struct text_pos
14436 run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
14438 struct window *w = XWINDOW (window);
14439 SET_MARKER_FROM_TEXT_POS (w->start, startp);
14441 eassert (current_buffer == XBUFFER (w->contents));
14443 if (!NILP (Vwindow_scroll_functions))
14445 run_hook_with_args_2 (Qwindow_scroll_functions, window,
14446 make_number (CHARPOS (startp)));
14447 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14448 /* In case the hook functions switch buffers. */
14449 set_buffer_internal (XBUFFER (w->contents));
14452 return startp;
14456 /* Make sure the line containing the cursor is fully visible.
14457 A value of 1 means there is nothing to be done.
14458 (Either the line is fully visible, or it cannot be made so,
14459 or we cannot tell.)
14461 If FORCE_P is non-zero, return 0 even if partial visible cursor row
14462 is higher than window.
14464 A value of 0 means the caller should do scrolling
14465 as if point had gone off the screen. */
14467 static int
14468 cursor_row_fully_visible_p (struct window *w, int force_p, int current_matrix_p)
14470 struct glyph_matrix *matrix;
14471 struct glyph_row *row;
14472 int window_height;
14474 if (!make_cursor_line_fully_visible_p)
14475 return 1;
14477 /* It's not always possible to find the cursor, e.g, when a window
14478 is full of overlay strings. Don't do anything in that case. */
14479 if (w->cursor.vpos < 0)
14480 return 1;
14482 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
14483 row = MATRIX_ROW (matrix, w->cursor.vpos);
14485 /* If the cursor row is not partially visible, there's nothing to do. */
14486 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
14487 return 1;
14489 /* If the row the cursor is in is taller than the window's height,
14490 it's not clear what to do, so do nothing. */
14491 window_height = window_box_height (w);
14492 if (row->height >= window_height)
14494 if (!force_p || MINI_WINDOW_P (w)
14495 || w->vscroll || w->cursor.vpos == 0)
14496 return 1;
14498 return 0;
14502 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
14503 non-zero means only WINDOW is redisplayed in redisplay_internal.
14504 TEMP_SCROLL_STEP has the same meaning as emacs_scroll_step, and is used
14505 in redisplay_window to bring a partially visible line into view in
14506 the case that only the cursor has moved.
14508 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
14509 last screen line's vertical height extends past the end of the screen.
14511 Value is
14513 1 if scrolling succeeded
14515 0 if scrolling didn't find point.
14517 -1 if new fonts have been loaded so that we must interrupt
14518 redisplay, adjust glyph matrices, and try again. */
14520 enum
14522 SCROLLING_SUCCESS,
14523 SCROLLING_FAILED,
14524 SCROLLING_NEED_LARGER_MATRICES
14527 /* If scroll-conservatively is more than this, never recenter.
14529 If you change this, don't forget to update the doc string of
14530 `scroll-conservatively' and the Emacs manual. */
14531 #define SCROLL_LIMIT 100
14533 static int
14534 try_scrolling (Lisp_Object window, int just_this_one_p,
14535 ptrdiff_t arg_scroll_conservatively, ptrdiff_t scroll_step,
14536 int temp_scroll_step, int last_line_misfit)
14538 struct window *w = XWINDOW (window);
14539 struct frame *f = XFRAME (w->frame);
14540 struct text_pos pos, startp;
14541 struct it it;
14542 int this_scroll_margin, scroll_max, rc, height;
14543 int dy = 0, amount_to_scroll = 0, scroll_down_p = 0;
14544 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
14545 Lisp_Object aggressive;
14546 /* We will never try scrolling more than this number of lines. */
14547 int scroll_limit = SCROLL_LIMIT;
14548 int frame_line_height = default_line_pixel_height (w);
14549 int window_total_lines
14550 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
14552 #ifdef GLYPH_DEBUG
14553 debug_method_add (w, "try_scrolling");
14554 #endif
14556 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14558 /* Compute scroll margin height in pixels. We scroll when point is
14559 within this distance from the top or bottom of the window. */
14560 if (scroll_margin > 0)
14561 this_scroll_margin = min (scroll_margin, window_total_lines / 4)
14562 * frame_line_height;
14563 else
14564 this_scroll_margin = 0;
14566 /* Force arg_scroll_conservatively to have a reasonable value, to
14567 avoid scrolling too far away with slow move_it_* functions. Note
14568 that the user can supply scroll-conservatively equal to
14569 `most-positive-fixnum', which can be larger than INT_MAX. */
14570 if (arg_scroll_conservatively > scroll_limit)
14572 arg_scroll_conservatively = scroll_limit + 1;
14573 scroll_max = scroll_limit * frame_line_height;
14575 else if (scroll_step || arg_scroll_conservatively || temp_scroll_step)
14576 /* Compute how much we should try to scroll maximally to bring
14577 point into view. */
14578 scroll_max = (max (scroll_step,
14579 max (arg_scroll_conservatively, temp_scroll_step))
14580 * frame_line_height);
14581 else if (NUMBERP (BVAR (current_buffer, scroll_down_aggressively))
14582 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively)))
14583 /* We're trying to scroll because of aggressive scrolling but no
14584 scroll_step is set. Choose an arbitrary one. */
14585 scroll_max = 10 * frame_line_height;
14586 else
14587 scroll_max = 0;
14589 too_near_end:
14591 /* Decide whether to scroll down. */
14592 if (PT > CHARPOS (startp))
14594 int scroll_margin_y;
14596 /* Compute the pixel ypos of the scroll margin, then move IT to
14597 either that ypos or PT, whichever comes first. */
14598 start_display (&it, w, startp);
14599 scroll_margin_y = it.last_visible_y - this_scroll_margin
14600 - frame_line_height * extra_scroll_margin_lines;
14601 move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
14602 (MOVE_TO_POS | MOVE_TO_Y));
14604 if (PT > CHARPOS (it.current.pos))
14606 int y0 = line_bottom_y (&it);
14607 /* Compute how many pixels below window bottom to stop searching
14608 for PT. This avoids costly search for PT that is far away if
14609 the user limited scrolling by a small number of lines, but
14610 always finds PT if scroll_conservatively is set to a large
14611 number, such as most-positive-fixnum. */
14612 int slack = max (scroll_max, 10 * frame_line_height);
14613 int y_to_move = it.last_visible_y + slack;
14615 /* Compute the distance from the scroll margin to PT or to
14616 the scroll limit, whichever comes first. This should
14617 include the height of the cursor line, to make that line
14618 fully visible. */
14619 move_it_to (&it, PT, -1, y_to_move,
14620 -1, MOVE_TO_POS | MOVE_TO_Y);
14621 dy = line_bottom_y (&it) - y0;
14623 if (dy > scroll_max)
14624 return SCROLLING_FAILED;
14626 if (dy > 0)
14627 scroll_down_p = 1;
14631 if (scroll_down_p)
14633 /* Point is in or below the bottom scroll margin, so move the
14634 window start down. If scrolling conservatively, move it just
14635 enough down to make point visible. If scroll_step is set,
14636 move it down by scroll_step. */
14637 if (arg_scroll_conservatively)
14638 amount_to_scroll
14639 = min (max (dy, frame_line_height),
14640 frame_line_height * arg_scroll_conservatively);
14641 else if (scroll_step || temp_scroll_step)
14642 amount_to_scroll = scroll_max;
14643 else
14645 aggressive = BVAR (current_buffer, scroll_up_aggressively);
14646 height = WINDOW_BOX_TEXT_HEIGHT (w);
14647 if (NUMBERP (aggressive))
14649 double float_amount = XFLOATINT (aggressive) * height;
14650 int aggressive_scroll = float_amount;
14651 if (aggressive_scroll == 0 && float_amount > 0)
14652 aggressive_scroll = 1;
14653 /* Don't let point enter the scroll margin near top of
14654 the window. This could happen if the value of
14655 scroll_up_aggressively is too large and there are
14656 non-zero margins, because scroll_up_aggressively
14657 means put point that fraction of window height
14658 _from_the_bottom_margin_. */
14659 if (aggressive_scroll + 2*this_scroll_margin > height)
14660 aggressive_scroll = height - 2*this_scroll_margin;
14661 amount_to_scroll = dy + aggressive_scroll;
14665 if (amount_to_scroll <= 0)
14666 return SCROLLING_FAILED;
14668 start_display (&it, w, startp);
14669 if (arg_scroll_conservatively <= scroll_limit)
14670 move_it_vertically (&it, amount_to_scroll);
14671 else
14673 /* Extra precision for users who set scroll-conservatively
14674 to a large number: make sure the amount we scroll
14675 the window start is never less than amount_to_scroll,
14676 which was computed as distance from window bottom to
14677 point. This matters when lines at window top and lines
14678 below window bottom have different height. */
14679 struct it it1;
14680 void *it1data = NULL;
14681 /* We use a temporary it1 because line_bottom_y can modify
14682 its argument, if it moves one line down; see there. */
14683 int start_y;
14685 SAVE_IT (it1, it, it1data);
14686 start_y = line_bottom_y (&it1);
14687 do {
14688 RESTORE_IT (&it, &it, it1data);
14689 move_it_by_lines (&it, 1);
14690 SAVE_IT (it1, it, it1data);
14691 } while (line_bottom_y (&it1) - start_y < amount_to_scroll);
14694 /* If STARTP is unchanged, move it down another screen line. */
14695 if (CHARPOS (it.current.pos) == CHARPOS (startp))
14696 move_it_by_lines (&it, 1);
14697 startp = it.current.pos;
14699 else
14701 struct text_pos scroll_margin_pos = startp;
14702 int y_offset = 0;
14704 /* See if point is inside the scroll margin at the top of the
14705 window. */
14706 if (this_scroll_margin)
14708 int y_start;
14710 start_display (&it, w, startp);
14711 y_start = it.current_y;
14712 move_it_vertically (&it, this_scroll_margin);
14713 scroll_margin_pos = it.current.pos;
14714 /* If we didn't move enough before hitting ZV, request
14715 additional amount of scroll, to move point out of the
14716 scroll margin. */
14717 if (IT_CHARPOS (it) == ZV
14718 && it.current_y - y_start < this_scroll_margin)
14719 y_offset = this_scroll_margin - (it.current_y - y_start);
14722 if (PT < CHARPOS (scroll_margin_pos))
14724 /* Point is in the scroll margin at the top of the window or
14725 above what is displayed in the window. */
14726 int y0, y_to_move;
14728 /* Compute the vertical distance from PT to the scroll
14729 margin position. Move as far as scroll_max allows, or
14730 one screenful, or 10 screen lines, whichever is largest.
14731 Give up if distance is greater than scroll_max or if we
14732 didn't reach the scroll margin position. */
14733 SET_TEXT_POS (pos, PT, PT_BYTE);
14734 start_display (&it, w, pos);
14735 y0 = it.current_y;
14736 y_to_move = max (it.last_visible_y,
14737 max (scroll_max, 10 * frame_line_height));
14738 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
14739 y_to_move, -1,
14740 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
14741 dy = it.current_y - y0;
14742 if (dy > scroll_max
14743 || IT_CHARPOS (it) < CHARPOS (scroll_margin_pos))
14744 return SCROLLING_FAILED;
14746 /* Additional scroll for when ZV was too close to point. */
14747 dy += y_offset;
14749 /* Compute new window start. */
14750 start_display (&it, w, startp);
14752 if (arg_scroll_conservatively)
14753 amount_to_scroll = max (dy, frame_line_height *
14754 max (scroll_step, temp_scroll_step));
14755 else if (scroll_step || temp_scroll_step)
14756 amount_to_scroll = scroll_max;
14757 else
14759 aggressive = BVAR (current_buffer, scroll_down_aggressively);
14760 height = WINDOW_BOX_TEXT_HEIGHT (w);
14761 if (NUMBERP (aggressive))
14763 double float_amount = XFLOATINT (aggressive) * height;
14764 int aggressive_scroll = float_amount;
14765 if (aggressive_scroll == 0 && float_amount > 0)
14766 aggressive_scroll = 1;
14767 /* Don't let point enter the scroll margin near
14768 bottom of the window, if the value of
14769 scroll_down_aggressively happens to be too
14770 large. */
14771 if (aggressive_scroll + 2*this_scroll_margin > height)
14772 aggressive_scroll = height - 2*this_scroll_margin;
14773 amount_to_scroll = dy + aggressive_scroll;
14777 if (amount_to_scroll <= 0)
14778 return SCROLLING_FAILED;
14780 move_it_vertically_backward (&it, amount_to_scroll);
14781 startp = it.current.pos;
14785 /* Run window scroll functions. */
14786 startp = run_window_scroll_functions (window, startp);
14788 /* Display the window. Give up if new fonts are loaded, or if point
14789 doesn't appear. */
14790 if (!try_window (window, startp, 0))
14791 rc = SCROLLING_NEED_LARGER_MATRICES;
14792 else if (w->cursor.vpos < 0)
14794 clear_glyph_matrix (w->desired_matrix);
14795 rc = SCROLLING_FAILED;
14797 else
14799 /* Maybe forget recorded base line for line number display. */
14800 if (!just_this_one_p
14801 || current_buffer->clip_changed
14802 || BEG_UNCHANGED < CHARPOS (startp))
14803 w->base_line_number = 0;
14805 /* If cursor ends up on a partially visible line,
14806 treat that as being off the bottom of the screen. */
14807 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0)
14808 /* It's possible that the cursor is on the first line of the
14809 buffer, which is partially obscured due to a vscroll
14810 (Bug#7537). In that case, avoid looping forever . */
14811 && extra_scroll_margin_lines < w->desired_matrix->nrows - 1)
14813 clear_glyph_matrix (w->desired_matrix);
14814 ++extra_scroll_margin_lines;
14815 goto too_near_end;
14817 rc = SCROLLING_SUCCESS;
14820 return rc;
14824 /* Compute a suitable window start for window W if display of W starts
14825 on a continuation line. Value is non-zero if a new window start
14826 was computed.
14828 The new window start will be computed, based on W's width, starting
14829 from the start of the continued line. It is the start of the
14830 screen line with the minimum distance from the old start W->start. */
14832 static int
14833 compute_window_start_on_continuation_line (struct window *w)
14835 struct text_pos pos, start_pos;
14836 int window_start_changed_p = 0;
14838 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
14840 /* If window start is on a continuation line... Window start may be
14841 < BEGV in case there's invisible text at the start of the
14842 buffer (M-x rmail, for example). */
14843 if (CHARPOS (start_pos) > BEGV
14844 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
14846 struct it it;
14847 struct glyph_row *row;
14849 /* Handle the case that the window start is out of range. */
14850 if (CHARPOS (start_pos) < BEGV)
14851 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
14852 else if (CHARPOS (start_pos) > ZV)
14853 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
14855 /* Find the start of the continued line. This should be fast
14856 because find_newline is fast (newline cache). */
14857 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
14858 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
14859 row, DEFAULT_FACE_ID);
14860 reseat_at_previous_visible_line_start (&it);
14862 /* If the line start is "too far" away from the window start,
14863 say it takes too much time to compute a new window start. */
14864 if (CHARPOS (start_pos) - IT_CHARPOS (it)
14865 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
14867 int min_distance, distance;
14869 /* Move forward by display lines to find the new window
14870 start. If window width was enlarged, the new start can
14871 be expected to be > the old start. If window width was
14872 decreased, the new window start will be < the old start.
14873 So, we're looking for the display line start with the
14874 minimum distance from the old window start. */
14875 pos = it.current.pos;
14876 min_distance = INFINITY;
14877 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
14878 distance < min_distance)
14880 min_distance = distance;
14881 pos = it.current.pos;
14882 move_it_by_lines (&it, 1);
14885 /* Set the window start there. */
14886 SET_MARKER_FROM_TEXT_POS (w->start, pos);
14887 window_start_changed_p = 1;
14891 return window_start_changed_p;
14895 /* Try cursor movement in case text has not changed in window WINDOW,
14896 with window start STARTP. Value is
14898 CURSOR_MOVEMENT_SUCCESS if successful
14900 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
14902 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
14903 display. *SCROLL_STEP is set to 1, under certain circumstances, if
14904 we want to scroll as if scroll-step were set to 1. See the code.
14906 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
14907 which case we have to abort this redisplay, and adjust matrices
14908 first. */
14910 enum
14912 CURSOR_MOVEMENT_SUCCESS,
14913 CURSOR_MOVEMENT_CANNOT_BE_USED,
14914 CURSOR_MOVEMENT_MUST_SCROLL,
14915 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
14918 static int
14919 try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_step)
14921 struct window *w = XWINDOW (window);
14922 struct frame *f = XFRAME (w->frame);
14923 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
14925 #ifdef GLYPH_DEBUG
14926 if (inhibit_try_cursor_movement)
14927 return rc;
14928 #endif
14930 /* Previously, there was a check for Lisp integer in the
14931 if-statement below. Now, this field is converted to
14932 ptrdiff_t, thus zero means invalid position in a buffer. */
14933 eassert (w->last_point > 0);
14935 /* Handle case where text has not changed, only point, and it has
14936 not moved off the frame. */
14937 if (/* Point may be in this window. */
14938 PT >= CHARPOS (startp)
14939 /* Selective display hasn't changed. */
14940 && !current_buffer->clip_changed
14941 /* Function force-mode-line-update is used to force a thorough
14942 redisplay. It sets either windows_or_buffers_changed or
14943 update_mode_lines. So don't take a shortcut here for these
14944 cases. */
14945 && !update_mode_lines
14946 && !windows_or_buffers_changed
14947 && !cursor_type_changed
14948 /* Can't use this case if highlighting a region. When a
14949 region exists, cursor movement has to do more than just
14950 set the cursor. */
14951 && markpos_of_region () < 0
14952 && !w->region_showing
14953 && NILP (Vshow_trailing_whitespace)
14954 /* This code is not used for mini-buffer for the sake of the case
14955 of redisplaying to replace an echo area message; since in
14956 that case the mini-buffer contents per se are usually
14957 unchanged. This code is of no real use in the mini-buffer
14958 since the handling of this_line_start_pos, etc., in redisplay
14959 handles the same cases. */
14960 && !EQ (window, minibuf_window)
14961 /* When splitting windows or for new windows, it happens that
14962 redisplay is called with a nil window_end_vpos or one being
14963 larger than the window. This should really be fixed in
14964 window.c. I don't have this on my list, now, so we do
14965 approximately the same as the old redisplay code. --gerd. */
14966 && INTEGERP (w->window_end_vpos)
14967 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
14968 && (FRAME_WINDOW_P (f)
14969 || !overlay_arrow_in_current_buffer_p ()))
14971 int this_scroll_margin, top_scroll_margin;
14972 struct glyph_row *row = NULL;
14973 int frame_line_height = default_line_pixel_height (w);
14974 int window_total_lines
14975 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
14977 #ifdef GLYPH_DEBUG
14978 debug_method_add (w, "cursor movement");
14979 #endif
14981 /* Scroll if point within this distance from the top or bottom
14982 of the window. This is a pixel value. */
14983 if (scroll_margin > 0)
14985 this_scroll_margin = min (scroll_margin, window_total_lines / 4);
14986 this_scroll_margin *= frame_line_height;
14988 else
14989 this_scroll_margin = 0;
14991 top_scroll_margin = this_scroll_margin;
14992 if (WINDOW_WANTS_HEADER_LINE_P (w))
14993 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
14995 /* Start with the row the cursor was displayed during the last
14996 not paused redisplay. Give up if that row is not valid. */
14997 if (w->last_cursor.vpos < 0
14998 || w->last_cursor.vpos >= w->current_matrix->nrows)
14999 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15000 else
15002 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
15003 if (row->mode_line_p)
15004 ++row;
15005 if (!row->enabled_p)
15006 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15009 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
15011 int scroll_p = 0, must_scroll = 0;
15012 int last_y = window_text_bottom_y (w) - this_scroll_margin;
15014 if (PT > w->last_point)
15016 /* Point has moved forward. */
15017 while (MATRIX_ROW_END_CHARPOS (row) < PT
15018 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
15020 eassert (row->enabled_p);
15021 ++row;
15024 /* If the end position of a row equals the start
15025 position of the next row, and PT is at that position,
15026 we would rather display cursor in the next line. */
15027 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15028 && MATRIX_ROW_END_CHARPOS (row) == PT
15029 && row < MATRIX_MODE_LINE_ROW (w->current_matrix)
15030 && MATRIX_ROW_START_CHARPOS (row+1) == PT
15031 && !cursor_row_p (row))
15032 ++row;
15034 /* If within the scroll margin, scroll. Note that
15035 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
15036 the next line would be drawn, and that
15037 this_scroll_margin can be zero. */
15038 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
15039 || PT > MATRIX_ROW_END_CHARPOS (row)
15040 /* Line is completely visible last line in window
15041 and PT is to be set in the next line. */
15042 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
15043 && PT == MATRIX_ROW_END_CHARPOS (row)
15044 && !row->ends_at_zv_p
15045 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
15046 scroll_p = 1;
15048 else if (PT < w->last_point)
15050 /* Cursor has to be moved backward. Note that PT >=
15051 CHARPOS (startp) because of the outer if-statement. */
15052 while (!row->mode_line_p
15053 && (MATRIX_ROW_START_CHARPOS (row) > PT
15054 || (MATRIX_ROW_START_CHARPOS (row) == PT
15055 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
15056 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
15057 row > w->current_matrix->rows
15058 && (row-1)->ends_in_newline_from_string_p))))
15059 && (row->y > top_scroll_margin
15060 || CHARPOS (startp) == BEGV))
15062 eassert (row->enabled_p);
15063 --row;
15066 /* Consider the following case: Window starts at BEGV,
15067 there is invisible, intangible text at BEGV, so that
15068 display starts at some point START > BEGV. It can
15069 happen that we are called with PT somewhere between
15070 BEGV and START. Try to handle that case. */
15071 if (row < w->current_matrix->rows
15072 || row->mode_line_p)
15074 row = w->current_matrix->rows;
15075 if (row->mode_line_p)
15076 ++row;
15079 /* Due to newlines in overlay strings, we may have to
15080 skip forward over overlay strings. */
15081 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15082 && MATRIX_ROW_END_CHARPOS (row) == PT
15083 && !cursor_row_p (row))
15084 ++row;
15086 /* If within the scroll margin, scroll. */
15087 if (row->y < top_scroll_margin
15088 && CHARPOS (startp) != BEGV)
15089 scroll_p = 1;
15091 else
15093 /* Cursor did not move. So don't scroll even if cursor line
15094 is partially visible, as it was so before. */
15095 rc = CURSOR_MOVEMENT_SUCCESS;
15098 if (PT < MATRIX_ROW_START_CHARPOS (row)
15099 || PT > MATRIX_ROW_END_CHARPOS (row))
15101 /* if PT is not in the glyph row, give up. */
15102 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15103 must_scroll = 1;
15105 else if (rc != CURSOR_MOVEMENT_SUCCESS
15106 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
15108 struct glyph_row *row1;
15110 /* If rows are bidi-reordered and point moved, back up
15111 until we find a row that does not belong to a
15112 continuation line. This is because we must consider
15113 all rows of a continued line as candidates for the
15114 new cursor positioning, since row start and end
15115 positions change non-linearly with vertical position
15116 in such rows. */
15117 /* FIXME: Revisit this when glyph ``spilling'' in
15118 continuation lines' rows is implemented for
15119 bidi-reordered rows. */
15120 for (row1 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
15121 MATRIX_ROW_CONTINUATION_LINE_P (row);
15122 --row)
15124 /* If we hit the beginning of the displayed portion
15125 without finding the first row of a continued
15126 line, give up. */
15127 if (row <= row1)
15129 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15130 break;
15132 eassert (row->enabled_p);
15135 if (must_scroll)
15137 else if (rc != CURSOR_MOVEMENT_SUCCESS
15138 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
15139 /* Make sure this isn't a header line by any chance, since
15140 then MATRIX_ROW_PARTIALLY_VISIBLE_P might yield non-zero. */
15141 && !row->mode_line_p
15142 && make_cursor_line_fully_visible_p)
15144 if (PT == MATRIX_ROW_END_CHARPOS (row)
15145 && !row->ends_at_zv_p
15146 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
15147 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15148 else if (row->height > window_box_height (w))
15150 /* If we end up in a partially visible line, let's
15151 make it fully visible, except when it's taller
15152 than the window, in which case we can't do much
15153 about it. */
15154 *scroll_step = 1;
15155 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15157 else
15159 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
15160 if (!cursor_row_fully_visible_p (w, 0, 1))
15161 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15162 else
15163 rc = CURSOR_MOVEMENT_SUCCESS;
15166 else if (scroll_p)
15167 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15168 else if (rc != CURSOR_MOVEMENT_SUCCESS
15169 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
15171 /* With bidi-reordered rows, there could be more than
15172 one candidate row whose start and end positions
15173 occlude point. We need to let set_cursor_from_row
15174 find the best candidate. */
15175 /* FIXME: Revisit this when glyph ``spilling'' in
15176 continuation lines' rows is implemented for
15177 bidi-reordered rows. */
15178 int rv = 0;
15182 int at_zv_p = 0, exact_match_p = 0;
15184 if (MATRIX_ROW_START_CHARPOS (row) <= PT
15185 && PT <= MATRIX_ROW_END_CHARPOS (row)
15186 && cursor_row_p (row))
15187 rv |= set_cursor_from_row (w, row, w->current_matrix,
15188 0, 0, 0, 0);
15189 /* As soon as we've found the exact match for point,
15190 or the first suitable row whose ends_at_zv_p flag
15191 is set, we are done. */
15192 at_zv_p =
15193 MATRIX_ROW (w->current_matrix, w->cursor.vpos)->ends_at_zv_p;
15194 if (rv && !at_zv_p
15195 && w->cursor.hpos >= 0
15196 && w->cursor.hpos < MATRIX_ROW_USED (w->current_matrix,
15197 w->cursor.vpos))
15199 struct glyph_row *candidate =
15200 MATRIX_ROW (w->current_matrix, w->cursor.vpos);
15201 struct glyph *g =
15202 candidate->glyphs[TEXT_AREA] + w->cursor.hpos;
15203 ptrdiff_t endpos = MATRIX_ROW_END_CHARPOS (candidate);
15205 exact_match_p =
15206 (BUFFERP (g->object) && g->charpos == PT)
15207 || (INTEGERP (g->object)
15208 && (g->charpos == PT
15209 || (g->charpos == 0 && endpos - 1 == PT)));
15211 if (rv && (at_zv_p || exact_match_p))
15213 rc = CURSOR_MOVEMENT_SUCCESS;
15214 break;
15216 if (MATRIX_ROW_BOTTOM_Y (row) == last_y)
15217 break;
15218 ++row;
15220 while (((MATRIX_ROW_CONTINUATION_LINE_P (row)
15221 || row->continued_p)
15222 && MATRIX_ROW_BOTTOM_Y (row) <= last_y)
15223 || (MATRIX_ROW_START_CHARPOS (row) == PT
15224 && MATRIX_ROW_BOTTOM_Y (row) < last_y));
15225 /* If we didn't find any candidate rows, or exited the
15226 loop before all the candidates were examined, signal
15227 to the caller that this method failed. */
15228 if (rc != CURSOR_MOVEMENT_SUCCESS
15229 && !(rv
15230 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
15231 && !row->continued_p))
15232 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15233 else if (rv)
15234 rc = CURSOR_MOVEMENT_SUCCESS;
15236 else
15240 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
15242 rc = CURSOR_MOVEMENT_SUCCESS;
15243 break;
15245 ++row;
15247 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15248 && MATRIX_ROW_START_CHARPOS (row) == PT
15249 && cursor_row_p (row));
15254 return rc;
15257 #if !defined USE_TOOLKIT_SCROLL_BARS || defined USE_GTK
15258 static
15259 #endif
15260 void
15261 set_vertical_scroll_bar (struct window *w)
15263 ptrdiff_t start, end, whole;
15265 /* Calculate the start and end positions for the current window.
15266 At some point, it would be nice to choose between scrollbars
15267 which reflect the whole buffer size, with special markers
15268 indicating narrowing, and scrollbars which reflect only the
15269 visible region.
15271 Note that mini-buffers sometimes aren't displaying any text. */
15272 if (!MINI_WINDOW_P (w)
15273 || (w == XWINDOW (minibuf_window)
15274 && NILP (echo_area_buffer[0])))
15276 struct buffer *buf = XBUFFER (w->contents);
15277 whole = BUF_ZV (buf) - BUF_BEGV (buf);
15278 start = marker_position (w->start) - BUF_BEGV (buf);
15279 /* I don't think this is guaranteed to be right. For the
15280 moment, we'll pretend it is. */
15281 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
15283 if (end < start)
15284 end = start;
15285 if (whole < (end - start))
15286 whole = end - start;
15288 else
15289 start = end = whole = 0;
15291 /* Indicate what this scroll bar ought to be displaying now. */
15292 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
15293 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
15294 (w, end - start, whole, start);
15298 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
15299 selected_window is redisplayed.
15301 We can return without actually redisplaying the window if
15302 fonts_changed_p. In that case, redisplay_internal will
15303 retry. */
15305 static void
15306 redisplay_window (Lisp_Object window, int just_this_one_p)
15308 struct window *w = XWINDOW (window);
15309 struct frame *f = XFRAME (w->frame);
15310 struct buffer *buffer = XBUFFER (w->contents);
15311 struct buffer *old = current_buffer;
15312 struct text_pos lpoint, opoint, startp;
15313 int update_mode_line;
15314 int tem;
15315 struct it it;
15316 /* Record it now because it's overwritten. */
15317 int current_matrix_up_to_date_p = 0;
15318 int used_current_matrix_p = 0;
15319 /* This is less strict than current_matrix_up_to_date_p.
15320 It indicates that the buffer contents and narrowing are unchanged. */
15321 int buffer_unchanged_p = 0;
15322 int temp_scroll_step = 0;
15323 ptrdiff_t count = SPECPDL_INDEX ();
15324 int rc;
15325 int centering_position = -1;
15326 int last_line_misfit = 0;
15327 ptrdiff_t beg_unchanged, end_unchanged;
15328 int frame_line_height;
15330 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15331 opoint = lpoint;
15333 #ifdef GLYPH_DEBUG
15334 *w->desired_matrix->method = 0;
15335 #endif
15337 /* Make sure that both W's markers are valid. */
15338 eassert (XMARKER (w->start)->buffer == buffer);
15339 eassert (XMARKER (w->pointm)->buffer == buffer);
15341 restart:
15342 reconsider_clip_changes (w);
15343 frame_line_height = default_line_pixel_height (w);
15345 /* Has the mode line to be updated? */
15346 update_mode_line = (w->update_mode_line
15347 || update_mode_lines
15348 || buffer->clip_changed
15349 || buffer->prevent_redisplay_optimizations_p);
15351 if (MINI_WINDOW_P (w))
15353 if (w == XWINDOW (echo_area_window)
15354 && !NILP (echo_area_buffer[0]))
15356 if (update_mode_line)
15357 /* We may have to update a tty frame's menu bar or a
15358 tool-bar. Example `M-x C-h C-h C-g'. */
15359 goto finish_menu_bars;
15360 else
15361 /* We've already displayed the echo area glyphs in this window. */
15362 goto finish_scroll_bars;
15364 else if ((w != XWINDOW (minibuf_window)
15365 || minibuf_level == 0)
15366 /* When buffer is nonempty, redisplay window normally. */
15367 && BUF_Z (XBUFFER (w->contents)) == BUF_BEG (XBUFFER (w->contents))
15368 /* Quail displays non-mini buffers in minibuffer window.
15369 In that case, redisplay the window normally. */
15370 && !NILP (Fmemq (w->contents, Vminibuffer_list)))
15372 /* W is a mini-buffer window, but it's not active, so clear
15373 it. */
15374 int yb = window_text_bottom_y (w);
15375 struct glyph_row *row;
15376 int y;
15378 for (y = 0, row = w->desired_matrix->rows;
15379 y < yb;
15380 y += row->height, ++row)
15381 blank_row (w, row, y);
15382 goto finish_scroll_bars;
15385 clear_glyph_matrix (w->desired_matrix);
15388 /* Otherwise set up data on this window; select its buffer and point
15389 value. */
15390 /* Really select the buffer, for the sake of buffer-local
15391 variables. */
15392 set_buffer_internal_1 (XBUFFER (w->contents));
15394 current_matrix_up_to_date_p
15395 = (w->window_end_valid
15396 && !current_buffer->clip_changed
15397 && !current_buffer->prevent_redisplay_optimizations_p
15398 && !window_outdated (w));
15400 /* Run the window-bottom-change-functions
15401 if it is possible that the text on the screen has changed
15402 (either due to modification of the text, or any other reason). */
15403 if (!current_matrix_up_to_date_p
15404 && !NILP (Vwindow_text_change_functions))
15406 safe_run_hooks (Qwindow_text_change_functions);
15407 goto restart;
15410 beg_unchanged = BEG_UNCHANGED;
15411 end_unchanged = END_UNCHANGED;
15413 SET_TEXT_POS (opoint, PT, PT_BYTE);
15415 specbind (Qinhibit_point_motion_hooks, Qt);
15417 buffer_unchanged_p
15418 = (w->window_end_valid
15419 && !current_buffer->clip_changed
15420 && !window_outdated (w));
15422 /* When windows_or_buffers_changed is non-zero, we can't rely on
15423 the window end being valid, so set it to nil there. */
15424 if (windows_or_buffers_changed)
15426 /* If window starts on a continuation line, maybe adjust the
15427 window start in case the window's width changed. */
15428 if (XMARKER (w->start)->buffer == current_buffer)
15429 compute_window_start_on_continuation_line (w);
15431 w->window_end_valid = 0;
15434 /* Some sanity checks. */
15435 CHECK_WINDOW_END (w);
15436 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
15437 emacs_abort ();
15438 if (BYTEPOS (opoint) < CHARPOS (opoint))
15439 emacs_abort ();
15441 if (mode_line_update_needed (w))
15442 update_mode_line = 1;
15444 /* Point refers normally to the selected window. For any other
15445 window, set up appropriate value. */
15446 if (!EQ (window, selected_window))
15448 ptrdiff_t new_pt = marker_position (w->pointm);
15449 ptrdiff_t new_pt_byte = marker_byte_position (w->pointm);
15450 if (new_pt < BEGV)
15452 new_pt = BEGV;
15453 new_pt_byte = BEGV_BYTE;
15454 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
15456 else if (new_pt > (ZV - 1))
15458 new_pt = ZV;
15459 new_pt_byte = ZV_BYTE;
15460 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
15463 /* We don't use SET_PT so that the point-motion hooks don't run. */
15464 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
15467 /* If any of the character widths specified in the display table
15468 have changed, invalidate the width run cache. It's true that
15469 this may be a bit late to catch such changes, but the rest of
15470 redisplay goes (non-fatally) haywire when the display table is
15471 changed, so why should we worry about doing any better? */
15472 if (current_buffer->width_run_cache)
15474 struct Lisp_Char_Table *disptab = buffer_display_table ();
15476 if (! disptab_matches_widthtab
15477 (disptab, XVECTOR (BVAR (current_buffer, width_table))))
15479 invalidate_region_cache (current_buffer,
15480 current_buffer->width_run_cache,
15481 BEG, Z);
15482 recompute_width_table (current_buffer, disptab);
15486 /* If window-start is screwed up, choose a new one. */
15487 if (XMARKER (w->start)->buffer != current_buffer)
15488 goto recenter;
15490 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15492 /* If someone specified a new starting point but did not insist,
15493 check whether it can be used. */
15494 if (w->optional_new_start
15495 && CHARPOS (startp) >= BEGV
15496 && CHARPOS (startp) <= ZV)
15498 w->optional_new_start = 0;
15499 start_display (&it, w, startp);
15500 move_it_to (&it, PT, 0, it.last_visible_y, -1,
15501 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
15502 if (IT_CHARPOS (it) == PT)
15503 w->force_start = 1;
15504 /* IT may overshoot PT if text at PT is invisible. */
15505 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
15506 w->force_start = 1;
15509 force_start:
15511 /* Handle case where place to start displaying has been specified,
15512 unless the specified location is outside the accessible range. */
15513 if (w->force_start || w->frozen_window_start_p)
15515 /* We set this later on if we have to adjust point. */
15516 int new_vpos = -1;
15518 w->force_start = 0;
15519 w->vscroll = 0;
15520 w->window_end_valid = 0;
15522 /* Forget any recorded base line for line number display. */
15523 if (!buffer_unchanged_p)
15524 w->base_line_number = 0;
15526 /* Redisplay the mode line. Select the buffer properly for that.
15527 Also, run the hook window-scroll-functions
15528 because we have scrolled. */
15529 /* Note, we do this after clearing force_start because
15530 if there's an error, it is better to forget about force_start
15531 than to get into an infinite loop calling the hook functions
15532 and having them get more errors. */
15533 if (!update_mode_line
15534 || ! NILP (Vwindow_scroll_functions))
15536 update_mode_line = 1;
15537 w->update_mode_line = 1;
15538 startp = run_window_scroll_functions (window, startp);
15541 if (CHARPOS (startp) < BEGV)
15542 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
15543 else if (CHARPOS (startp) > ZV)
15544 SET_TEXT_POS (startp, ZV, ZV_BYTE);
15546 /* Redisplay, then check if cursor has been set during the
15547 redisplay. Give up if new fonts were loaded. */
15548 /* We used to issue a CHECK_MARGINS argument to try_window here,
15549 but this causes scrolling to fail when point begins inside
15550 the scroll margin (bug#148) -- cyd */
15551 if (!try_window (window, startp, 0))
15553 w->force_start = 1;
15554 clear_glyph_matrix (w->desired_matrix);
15555 goto need_larger_matrices;
15558 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
15560 /* If point does not appear, try to move point so it does
15561 appear. The desired matrix has been built above, so we
15562 can use it here. */
15563 new_vpos = window_box_height (w) / 2;
15566 if (!cursor_row_fully_visible_p (w, 0, 0))
15568 /* Point does appear, but on a line partly visible at end of window.
15569 Move it back to a fully-visible line. */
15570 new_vpos = window_box_height (w);
15572 else if (w->cursor.vpos >=0)
15574 /* Some people insist on not letting point enter the scroll
15575 margin, even though this part handles windows that didn't
15576 scroll at all. */
15577 int window_total_lines
15578 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
15579 int margin = min (scroll_margin, window_total_lines / 4);
15580 int pixel_margin = margin * frame_line_height;
15581 bool header_line = WINDOW_WANTS_HEADER_LINE_P (w);
15583 /* Note: We add an extra FRAME_LINE_HEIGHT, because the loop
15584 below, which finds the row to move point to, advances by
15585 the Y coordinate of the _next_ row, see the definition of
15586 MATRIX_ROW_BOTTOM_Y. */
15587 if (w->cursor.vpos < margin + header_line)
15589 w->cursor.vpos = -1;
15590 clear_glyph_matrix (w->desired_matrix);
15591 goto try_to_scroll;
15593 else
15595 int window_height = window_box_height (w);
15597 if (header_line)
15598 window_height += CURRENT_HEADER_LINE_HEIGHT (w);
15599 if (w->cursor.y >= window_height - pixel_margin)
15601 w->cursor.vpos = -1;
15602 clear_glyph_matrix (w->desired_matrix);
15603 goto try_to_scroll;
15608 /* If we need to move point for either of the above reasons,
15609 now actually do it. */
15610 if (new_vpos >= 0)
15612 struct glyph_row *row;
15614 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
15615 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
15616 ++row;
15618 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
15619 MATRIX_ROW_START_BYTEPOS (row));
15621 if (w != XWINDOW (selected_window))
15622 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
15623 else if (current_buffer == old)
15624 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15626 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
15628 /* If we are highlighting the region, then we just changed
15629 the region, so redisplay to show it. */
15630 if (markpos_of_region () >= 0)
15632 clear_glyph_matrix (w->desired_matrix);
15633 if (!try_window (window, startp, 0))
15634 goto need_larger_matrices;
15638 #ifdef GLYPH_DEBUG
15639 debug_method_add (w, "forced window start");
15640 #endif
15641 goto done;
15644 /* Handle case where text has not changed, only point, and it has
15645 not moved off the frame, and we are not retrying after hscroll.
15646 (current_matrix_up_to_date_p is nonzero when retrying.) */
15647 if (current_matrix_up_to_date_p
15648 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
15649 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
15651 switch (rc)
15653 case CURSOR_MOVEMENT_SUCCESS:
15654 used_current_matrix_p = 1;
15655 goto done;
15657 case CURSOR_MOVEMENT_MUST_SCROLL:
15658 goto try_to_scroll;
15660 default:
15661 emacs_abort ();
15664 /* If current starting point was originally the beginning of a line
15665 but no longer is, find a new starting point. */
15666 else if (w->start_at_line_beg
15667 && !(CHARPOS (startp) <= BEGV
15668 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
15670 #ifdef GLYPH_DEBUG
15671 debug_method_add (w, "recenter 1");
15672 #endif
15673 goto recenter;
15676 /* Try scrolling with try_window_id. Value is > 0 if update has
15677 been done, it is -1 if we know that the same window start will
15678 not work. It is 0 if unsuccessful for some other reason. */
15679 else if ((tem = try_window_id (w)) != 0)
15681 #ifdef GLYPH_DEBUG
15682 debug_method_add (w, "try_window_id %d", tem);
15683 #endif
15685 if (fonts_changed_p)
15686 goto need_larger_matrices;
15687 if (tem > 0)
15688 goto done;
15690 /* Otherwise try_window_id has returned -1 which means that we
15691 don't want the alternative below this comment to execute. */
15693 else if (CHARPOS (startp) >= BEGV
15694 && CHARPOS (startp) <= ZV
15695 && PT >= CHARPOS (startp)
15696 && (CHARPOS (startp) < ZV
15697 /* Avoid starting at end of buffer. */
15698 || CHARPOS (startp) == BEGV
15699 || !window_outdated (w)))
15701 int d1, d2, d3, d4, d5, d6;
15703 /* If first window line is a continuation line, and window start
15704 is inside the modified region, but the first change is before
15705 current window start, we must select a new window start.
15707 However, if this is the result of a down-mouse event (e.g. by
15708 extending the mouse-drag-overlay), we don't want to select a
15709 new window start, since that would change the position under
15710 the mouse, resulting in an unwanted mouse-movement rather
15711 than a simple mouse-click. */
15712 if (!w->start_at_line_beg
15713 && NILP (do_mouse_tracking)
15714 && CHARPOS (startp) > BEGV
15715 && CHARPOS (startp) > BEG + beg_unchanged
15716 && CHARPOS (startp) <= Z - end_unchanged
15717 /* Even if w->start_at_line_beg is nil, a new window may
15718 start at a line_beg, since that's how set_buffer_window
15719 sets it. So, we need to check the return value of
15720 compute_window_start_on_continuation_line. (See also
15721 bug#197). */
15722 && XMARKER (w->start)->buffer == current_buffer
15723 && compute_window_start_on_continuation_line (w)
15724 /* It doesn't make sense to force the window start like we
15725 do at label force_start if it is already known that point
15726 will not be visible in the resulting window, because
15727 doing so will move point from its correct position
15728 instead of scrolling the window to bring point into view.
15729 See bug#9324. */
15730 && pos_visible_p (w, PT, &d1, &d2, &d3, &d4, &d5, &d6))
15732 w->force_start = 1;
15733 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15734 goto force_start;
15737 #ifdef GLYPH_DEBUG
15738 debug_method_add (w, "same window start");
15739 #endif
15741 /* Try to redisplay starting at same place as before.
15742 If point has not moved off frame, accept the results. */
15743 if (!current_matrix_up_to_date_p
15744 /* Don't use try_window_reusing_current_matrix in this case
15745 because a window scroll function can have changed the
15746 buffer. */
15747 || !NILP (Vwindow_scroll_functions)
15748 || MINI_WINDOW_P (w)
15749 || !(used_current_matrix_p
15750 = try_window_reusing_current_matrix (w)))
15752 IF_DEBUG (debug_method_add (w, "1"));
15753 if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
15754 /* -1 means we need to scroll.
15755 0 means we need new matrices, but fonts_changed_p
15756 is set in that case, so we will detect it below. */
15757 goto try_to_scroll;
15760 if (fonts_changed_p)
15761 goto need_larger_matrices;
15763 if (w->cursor.vpos >= 0)
15765 if (!just_this_one_p
15766 || current_buffer->clip_changed
15767 || BEG_UNCHANGED < CHARPOS (startp))
15768 /* Forget any recorded base line for line number display. */
15769 w->base_line_number = 0;
15771 if (!cursor_row_fully_visible_p (w, 1, 0))
15773 clear_glyph_matrix (w->desired_matrix);
15774 last_line_misfit = 1;
15776 /* Drop through and scroll. */
15777 else
15778 goto done;
15780 else
15781 clear_glyph_matrix (w->desired_matrix);
15784 try_to_scroll:
15786 /* Redisplay the mode line. Select the buffer properly for that. */
15787 if (!update_mode_line)
15789 update_mode_line = 1;
15790 w->update_mode_line = 1;
15793 /* Try to scroll by specified few lines. */
15794 if ((scroll_conservatively
15795 || emacs_scroll_step
15796 || temp_scroll_step
15797 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively))
15798 || NUMBERP (BVAR (current_buffer, scroll_down_aggressively)))
15799 && CHARPOS (startp) >= BEGV
15800 && CHARPOS (startp) <= ZV)
15802 /* The function returns -1 if new fonts were loaded, 1 if
15803 successful, 0 if not successful. */
15804 int ss = try_scrolling (window, just_this_one_p,
15805 scroll_conservatively,
15806 emacs_scroll_step,
15807 temp_scroll_step, last_line_misfit);
15808 switch (ss)
15810 case SCROLLING_SUCCESS:
15811 goto done;
15813 case SCROLLING_NEED_LARGER_MATRICES:
15814 goto need_larger_matrices;
15816 case SCROLLING_FAILED:
15817 break;
15819 default:
15820 emacs_abort ();
15824 /* Finally, just choose a place to start which positions point
15825 according to user preferences. */
15827 recenter:
15829 #ifdef GLYPH_DEBUG
15830 debug_method_add (w, "recenter");
15831 #endif
15833 /* Forget any previously recorded base line for line number display. */
15834 if (!buffer_unchanged_p)
15835 w->base_line_number = 0;
15837 /* Determine the window start relative to point. */
15838 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
15839 it.current_y = it.last_visible_y;
15840 if (centering_position < 0)
15842 int window_total_lines
15843 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
15844 int margin =
15845 scroll_margin > 0
15846 ? min (scroll_margin, window_total_lines / 4)
15847 : 0;
15848 ptrdiff_t margin_pos = CHARPOS (startp);
15849 Lisp_Object aggressive;
15850 int scrolling_up;
15852 /* If there is a scroll margin at the top of the window, find
15853 its character position. */
15854 if (margin
15855 /* Cannot call start_display if startp is not in the
15856 accessible region of the buffer. This can happen when we
15857 have just switched to a different buffer and/or changed
15858 its restriction. In that case, startp is initialized to
15859 the character position 1 (BEGV) because we did not yet
15860 have chance to display the buffer even once. */
15861 && BEGV <= CHARPOS (startp) && CHARPOS (startp) <= ZV)
15863 struct it it1;
15864 void *it1data = NULL;
15866 SAVE_IT (it1, it, it1data);
15867 start_display (&it1, w, startp);
15868 move_it_vertically (&it1, margin * frame_line_height);
15869 margin_pos = IT_CHARPOS (it1);
15870 RESTORE_IT (&it, &it, it1data);
15872 scrolling_up = PT > margin_pos;
15873 aggressive =
15874 scrolling_up
15875 ? BVAR (current_buffer, scroll_up_aggressively)
15876 : BVAR (current_buffer, scroll_down_aggressively);
15878 if (!MINI_WINDOW_P (w)
15879 && (scroll_conservatively > SCROLL_LIMIT || NUMBERP (aggressive)))
15881 int pt_offset = 0;
15883 /* Setting scroll-conservatively overrides
15884 scroll-*-aggressively. */
15885 if (!scroll_conservatively && NUMBERP (aggressive))
15887 double float_amount = XFLOATINT (aggressive);
15889 pt_offset = float_amount * WINDOW_BOX_TEXT_HEIGHT (w);
15890 if (pt_offset == 0 && float_amount > 0)
15891 pt_offset = 1;
15892 if (pt_offset && margin > 0)
15893 margin -= 1;
15895 /* Compute how much to move the window start backward from
15896 point so that point will be displayed where the user
15897 wants it. */
15898 if (scrolling_up)
15900 centering_position = it.last_visible_y;
15901 if (pt_offset)
15902 centering_position -= pt_offset;
15903 centering_position -=
15904 frame_line_height * (1 + margin + (last_line_misfit != 0))
15905 + WINDOW_HEADER_LINE_HEIGHT (w);
15906 /* Don't let point enter the scroll margin near top of
15907 the window. */
15908 if (centering_position < margin * frame_line_height)
15909 centering_position = margin * frame_line_height;
15911 else
15912 centering_position = margin * frame_line_height + pt_offset;
15914 else
15915 /* Set the window start half the height of the window backward
15916 from point. */
15917 centering_position = window_box_height (w) / 2;
15919 move_it_vertically_backward (&it, centering_position);
15921 eassert (IT_CHARPOS (it) >= BEGV);
15923 /* The function move_it_vertically_backward may move over more
15924 than the specified y-distance. If it->w is small, e.g. a
15925 mini-buffer window, we may end up in front of the window's
15926 display area. Start displaying at the start of the line
15927 containing PT in this case. */
15928 if (it.current_y <= 0)
15930 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
15931 move_it_vertically_backward (&it, 0);
15932 it.current_y = 0;
15935 it.current_x = it.hpos = 0;
15937 /* Set the window start position here explicitly, to avoid an
15938 infinite loop in case the functions in window-scroll-functions
15939 get errors. */
15940 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
15942 /* Run scroll hooks. */
15943 startp = run_window_scroll_functions (window, it.current.pos);
15945 /* Redisplay the window. */
15946 if (!current_matrix_up_to_date_p
15947 || windows_or_buffers_changed
15948 || cursor_type_changed
15949 /* Don't use try_window_reusing_current_matrix in this case
15950 because it can have changed the buffer. */
15951 || !NILP (Vwindow_scroll_functions)
15952 || !just_this_one_p
15953 || MINI_WINDOW_P (w)
15954 || !(used_current_matrix_p
15955 = try_window_reusing_current_matrix (w)))
15956 try_window (window, startp, 0);
15958 /* If new fonts have been loaded (due to fontsets), give up. We
15959 have to start a new redisplay since we need to re-adjust glyph
15960 matrices. */
15961 if (fonts_changed_p)
15962 goto need_larger_matrices;
15964 /* If cursor did not appear assume that the middle of the window is
15965 in the first line of the window. Do it again with the next line.
15966 (Imagine a window of height 100, displaying two lines of height
15967 60. Moving back 50 from it->last_visible_y will end in the first
15968 line.) */
15969 if (w->cursor.vpos < 0)
15971 if (w->window_end_valid && PT >= Z - XFASTINT (w->window_end_pos))
15973 clear_glyph_matrix (w->desired_matrix);
15974 move_it_by_lines (&it, 1);
15975 try_window (window, it.current.pos, 0);
15977 else if (PT < IT_CHARPOS (it))
15979 clear_glyph_matrix (w->desired_matrix);
15980 move_it_by_lines (&it, -1);
15981 try_window (window, it.current.pos, 0);
15983 else
15985 /* Not much we can do about it. */
15989 /* Consider the following case: Window starts at BEGV, there is
15990 invisible, intangible text at BEGV, so that display starts at
15991 some point START > BEGV. It can happen that we are called with
15992 PT somewhere between BEGV and START. Try to handle that case. */
15993 if (w->cursor.vpos < 0)
15995 struct glyph_row *row = w->current_matrix->rows;
15996 if (row->mode_line_p)
15997 ++row;
15998 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
16001 if (!cursor_row_fully_visible_p (w, 0, 0))
16003 /* If vscroll is enabled, disable it and try again. */
16004 if (w->vscroll)
16006 w->vscroll = 0;
16007 clear_glyph_matrix (w->desired_matrix);
16008 goto recenter;
16011 /* Users who set scroll-conservatively to a large number want
16012 point just above/below the scroll margin. If we ended up
16013 with point's row partially visible, move the window start to
16014 make that row fully visible and out of the margin. */
16015 if (scroll_conservatively > SCROLL_LIMIT)
16017 int window_total_lines
16018 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) * frame_line_height;
16019 int margin =
16020 scroll_margin > 0
16021 ? min (scroll_margin, window_total_lines / 4)
16022 : 0;
16023 int move_down = w->cursor.vpos >= window_total_lines / 2;
16025 move_it_by_lines (&it, move_down ? margin + 1 : -(margin + 1));
16026 clear_glyph_matrix (w->desired_matrix);
16027 if (1 == try_window (window, it.current.pos,
16028 TRY_WINDOW_CHECK_MARGINS))
16029 goto done;
16032 /* If centering point failed to make the whole line visible,
16033 put point at the top instead. That has to make the whole line
16034 visible, if it can be done. */
16035 if (centering_position == 0)
16036 goto done;
16038 clear_glyph_matrix (w->desired_matrix);
16039 centering_position = 0;
16040 goto recenter;
16043 done:
16045 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16046 w->start_at_line_beg = (CHARPOS (startp) == BEGV
16047 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n');
16049 /* Display the mode line, if we must. */
16050 if ((update_mode_line
16051 /* If window not full width, must redo its mode line
16052 if (a) the window to its side is being redone and
16053 (b) we do a frame-based redisplay. This is a consequence
16054 of how inverted lines are drawn in frame-based redisplay. */
16055 || (!just_this_one_p
16056 && !FRAME_WINDOW_P (f)
16057 && !WINDOW_FULL_WIDTH_P (w))
16058 /* Line number to display. */
16059 || w->base_line_pos > 0
16060 /* Column number is displayed and different from the one displayed. */
16061 || (w->column_number_displayed != -1
16062 && (w->column_number_displayed != current_column ())))
16063 /* This means that the window has a mode line. */
16064 && (WINDOW_WANTS_MODELINE_P (w)
16065 || WINDOW_WANTS_HEADER_LINE_P (w)))
16067 display_mode_lines (w);
16069 /* If mode line height has changed, arrange for a thorough
16070 immediate redisplay using the correct mode line height. */
16071 if (WINDOW_WANTS_MODELINE_P (w)
16072 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
16074 fonts_changed_p = 1;
16075 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
16076 = DESIRED_MODE_LINE_HEIGHT (w);
16079 /* If header line height has changed, arrange for a thorough
16080 immediate redisplay using the correct header line height. */
16081 if (WINDOW_WANTS_HEADER_LINE_P (w)
16082 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
16084 fonts_changed_p = 1;
16085 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
16086 = DESIRED_HEADER_LINE_HEIGHT (w);
16089 if (fonts_changed_p)
16090 goto need_larger_matrices;
16093 if (!line_number_displayed && w->base_line_pos != -1)
16095 w->base_line_pos = 0;
16096 w->base_line_number = 0;
16099 finish_menu_bars:
16101 /* When we reach a frame's selected window, redo the frame's menu bar. */
16102 if (update_mode_line
16103 && EQ (FRAME_SELECTED_WINDOW (f), window))
16105 int redisplay_menu_p = 0;
16107 if (FRAME_WINDOW_P (f))
16109 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
16110 || defined (HAVE_NS) || defined (USE_GTK)
16111 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
16112 #else
16113 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
16114 #endif
16116 else
16117 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
16119 if (redisplay_menu_p)
16120 display_menu_bar (w);
16122 #ifdef HAVE_WINDOW_SYSTEM
16123 if (FRAME_WINDOW_P (f))
16125 #if defined (USE_GTK) || defined (HAVE_NS)
16126 if (FRAME_EXTERNAL_TOOL_BAR (f))
16127 redisplay_tool_bar (f);
16128 #else
16129 if (WINDOWP (f->tool_bar_window)
16130 && (FRAME_TOOL_BAR_LINES (f) > 0
16131 || !NILP (Vauto_resize_tool_bars))
16132 && redisplay_tool_bar (f))
16133 ignore_mouse_drag_p = 1;
16134 #endif
16136 #endif
16139 #ifdef HAVE_WINDOW_SYSTEM
16140 if (FRAME_WINDOW_P (f)
16141 && update_window_fringes (w, (just_this_one_p
16142 || (!used_current_matrix_p && !overlay_arrow_seen)
16143 || w->pseudo_window_p)))
16145 update_begin (f);
16146 block_input ();
16147 if (draw_window_fringes (w, 1))
16148 x_draw_vertical_border (w);
16149 unblock_input ();
16150 update_end (f);
16152 #endif /* HAVE_WINDOW_SYSTEM */
16154 /* We go to this label, with fonts_changed_p set,
16155 if it is necessary to try again using larger glyph matrices.
16156 We have to redeem the scroll bar even in this case,
16157 because the loop in redisplay_internal expects that. */
16158 need_larger_matrices:
16160 finish_scroll_bars:
16162 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
16164 /* Set the thumb's position and size. */
16165 set_vertical_scroll_bar (w);
16167 /* Note that we actually used the scroll bar attached to this
16168 window, so it shouldn't be deleted at the end of redisplay. */
16169 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
16170 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
16173 /* Restore current_buffer and value of point in it. The window
16174 update may have changed the buffer, so first make sure `opoint'
16175 is still valid (Bug#6177). */
16176 if (CHARPOS (opoint) < BEGV)
16177 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
16178 else if (CHARPOS (opoint) > ZV)
16179 TEMP_SET_PT_BOTH (Z, Z_BYTE);
16180 else
16181 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
16183 set_buffer_internal_1 (old);
16184 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
16185 shorter. This can be caused by log truncation in *Messages*. */
16186 if (CHARPOS (lpoint) <= ZV)
16187 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
16189 unbind_to (count, Qnil);
16193 /* Build the complete desired matrix of WINDOW with a window start
16194 buffer position POS.
16196 Value is 1 if successful. It is zero if fonts were loaded during
16197 redisplay which makes re-adjusting glyph matrices necessary, and -1
16198 if point would appear in the scroll margins.
16199 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
16200 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
16201 set in FLAGS.) */
16204 try_window (Lisp_Object window, struct text_pos pos, int flags)
16206 struct window *w = XWINDOW (window);
16207 struct it it;
16208 struct glyph_row *last_text_row = NULL;
16209 struct frame *f = XFRAME (w->frame);
16210 int frame_line_height = default_line_pixel_height (w);
16212 /* Make POS the new window start. */
16213 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
16215 /* Mark cursor position as unknown. No overlay arrow seen. */
16216 w->cursor.vpos = -1;
16217 overlay_arrow_seen = 0;
16219 /* Initialize iterator and info to start at POS. */
16220 start_display (&it, w, pos);
16222 /* Display all lines of W. */
16223 while (it.current_y < it.last_visible_y)
16225 if (display_line (&it))
16226 last_text_row = it.glyph_row - 1;
16227 if (fonts_changed_p && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
16228 return 0;
16231 /* Don't let the cursor end in the scroll margins. */
16232 if ((flags & TRY_WINDOW_CHECK_MARGINS)
16233 && !MINI_WINDOW_P (w))
16235 int this_scroll_margin;
16236 int window_total_lines
16237 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
16239 if (scroll_margin > 0)
16241 this_scroll_margin = min (scroll_margin, window_total_lines / 4);
16242 this_scroll_margin *= frame_line_height;
16244 else
16245 this_scroll_margin = 0;
16247 if ((w->cursor.y >= 0 /* not vscrolled */
16248 && w->cursor.y < this_scroll_margin
16249 && CHARPOS (pos) > BEGV
16250 && IT_CHARPOS (it) < ZV)
16251 /* rms: considering make_cursor_line_fully_visible_p here
16252 seems to give wrong results. We don't want to recenter
16253 when the last line is partly visible, we want to allow
16254 that case to be handled in the usual way. */
16255 || w->cursor.y > it.last_visible_y - this_scroll_margin - 1)
16257 w->cursor.vpos = -1;
16258 clear_glyph_matrix (w->desired_matrix);
16259 return -1;
16263 /* If bottom moved off end of frame, change mode line percentage. */
16264 if (XFASTINT (w->window_end_pos) <= 0
16265 && Z != IT_CHARPOS (it))
16266 w->update_mode_line = 1;
16268 /* Set window_end_pos to the offset of the last character displayed
16269 on the window from the end of current_buffer. Set
16270 window_end_vpos to its row number. */
16271 if (last_text_row)
16273 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
16274 w->window_end_bytepos
16275 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16276 wset_window_end_pos
16277 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
16278 wset_window_end_vpos
16279 (w, make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix)));
16280 eassert
16281 (MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->desired_matrix,
16282 XFASTINT (w->window_end_vpos))));
16284 else
16286 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
16287 wset_window_end_pos (w, make_number (Z - ZV));
16288 wset_window_end_vpos (w, make_number (0));
16291 /* But that is not valid info until redisplay finishes. */
16292 w->window_end_valid = 0;
16293 return 1;
16298 /************************************************************************
16299 Window redisplay reusing current matrix when buffer has not changed
16300 ************************************************************************/
16302 /* Try redisplay of window W showing an unchanged buffer with a
16303 different window start than the last time it was displayed by
16304 reusing its current matrix. Value is non-zero if successful.
16305 W->start is the new window start. */
16307 static int
16308 try_window_reusing_current_matrix (struct window *w)
16310 struct frame *f = XFRAME (w->frame);
16311 struct glyph_row *bottom_row;
16312 struct it it;
16313 struct run run;
16314 struct text_pos start, new_start;
16315 int nrows_scrolled, i;
16316 struct glyph_row *last_text_row;
16317 struct glyph_row *last_reused_text_row;
16318 struct glyph_row *start_row;
16319 int start_vpos, min_y, max_y;
16321 #ifdef GLYPH_DEBUG
16322 if (inhibit_try_window_reusing)
16323 return 0;
16324 #endif
16326 if (/* This function doesn't handle terminal frames. */
16327 !FRAME_WINDOW_P (f)
16328 /* Don't try to reuse the display if windows have been split
16329 or such. */
16330 || windows_or_buffers_changed
16331 || cursor_type_changed)
16332 return 0;
16334 /* Can't do this if region may have changed. */
16335 if (markpos_of_region () >= 0
16336 || w->region_showing
16337 || !NILP (Vshow_trailing_whitespace))
16338 return 0;
16340 /* If top-line visibility has changed, give up. */
16341 if (WINDOW_WANTS_HEADER_LINE_P (w)
16342 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
16343 return 0;
16345 /* Give up if old or new display is scrolled vertically. We could
16346 make this function handle this, but right now it doesn't. */
16347 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16348 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
16349 return 0;
16351 /* The variable new_start now holds the new window start. The old
16352 start `start' can be determined from the current matrix. */
16353 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
16354 start = start_row->minpos;
16355 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
16357 /* Clear the desired matrix for the display below. */
16358 clear_glyph_matrix (w->desired_matrix);
16360 if (CHARPOS (new_start) <= CHARPOS (start))
16362 /* Don't use this method if the display starts with an ellipsis
16363 displayed for invisible text. It's not easy to handle that case
16364 below, and it's certainly not worth the effort since this is
16365 not a frequent case. */
16366 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
16367 return 0;
16369 IF_DEBUG (debug_method_add (w, "twu1"));
16371 /* Display up to a row that can be reused. The variable
16372 last_text_row is set to the last row displayed that displays
16373 text. Note that it.vpos == 0 if or if not there is a
16374 header-line; it's not the same as the MATRIX_ROW_VPOS! */
16375 start_display (&it, w, new_start);
16376 w->cursor.vpos = -1;
16377 last_text_row = last_reused_text_row = NULL;
16379 while (it.current_y < it.last_visible_y
16380 && !fonts_changed_p)
16382 /* If we have reached into the characters in the START row,
16383 that means the line boundaries have changed. So we
16384 can't start copying with the row START. Maybe it will
16385 work to start copying with the following row. */
16386 while (IT_CHARPOS (it) > CHARPOS (start))
16388 /* Advance to the next row as the "start". */
16389 start_row++;
16390 start = start_row->minpos;
16391 /* If there are no more rows to try, or just one, give up. */
16392 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
16393 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
16394 || CHARPOS (start) == ZV)
16396 clear_glyph_matrix (w->desired_matrix);
16397 return 0;
16400 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
16402 /* If we have reached alignment, we can copy the rest of the
16403 rows. */
16404 if (IT_CHARPOS (it) == CHARPOS (start)
16405 /* Don't accept "alignment" inside a display vector,
16406 since start_row could have started in the middle of
16407 that same display vector (thus their character
16408 positions match), and we have no way of telling if
16409 that is the case. */
16410 && it.current.dpvec_index < 0)
16411 break;
16413 if (display_line (&it))
16414 last_text_row = it.glyph_row - 1;
16418 /* A value of current_y < last_visible_y means that we stopped
16419 at the previous window start, which in turn means that we
16420 have at least one reusable row. */
16421 if (it.current_y < it.last_visible_y)
16423 struct glyph_row *row;
16425 /* IT.vpos always starts from 0; it counts text lines. */
16426 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
16428 /* Find PT if not already found in the lines displayed. */
16429 if (w->cursor.vpos < 0)
16431 int dy = it.current_y - start_row->y;
16433 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16434 row = row_containing_pos (w, PT, row, NULL, dy);
16435 if (row)
16436 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
16437 dy, nrows_scrolled);
16438 else
16440 clear_glyph_matrix (w->desired_matrix);
16441 return 0;
16445 /* Scroll the display. Do it before the current matrix is
16446 changed. The problem here is that update has not yet
16447 run, i.e. part of the current matrix is not up to date.
16448 scroll_run_hook will clear the cursor, and use the
16449 current matrix to get the height of the row the cursor is
16450 in. */
16451 run.current_y = start_row->y;
16452 run.desired_y = it.current_y;
16453 run.height = it.last_visible_y - it.current_y;
16455 if (run.height > 0 && run.current_y != run.desired_y)
16457 update_begin (f);
16458 FRAME_RIF (f)->update_window_begin_hook (w);
16459 FRAME_RIF (f)->clear_window_mouse_face (w);
16460 FRAME_RIF (f)->scroll_run_hook (w, &run);
16461 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
16462 update_end (f);
16465 /* Shift current matrix down by nrows_scrolled lines. */
16466 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
16467 rotate_matrix (w->current_matrix,
16468 start_vpos,
16469 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
16470 nrows_scrolled);
16472 /* Disable lines that must be updated. */
16473 for (i = 0; i < nrows_scrolled; ++i)
16474 (start_row + i)->enabled_p = 0;
16476 /* Re-compute Y positions. */
16477 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
16478 max_y = it.last_visible_y;
16479 for (row = start_row + nrows_scrolled;
16480 row < bottom_row;
16481 ++row)
16483 row->y = it.current_y;
16484 row->visible_height = row->height;
16486 if (row->y < min_y)
16487 row->visible_height -= min_y - row->y;
16488 if (row->y + row->height > max_y)
16489 row->visible_height -= row->y + row->height - max_y;
16490 if (row->fringe_bitmap_periodic_p)
16491 row->redraw_fringe_bitmaps_p = 1;
16493 it.current_y += row->height;
16495 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16496 last_reused_text_row = row;
16497 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
16498 break;
16501 /* Disable lines in the current matrix which are now
16502 below the window. */
16503 for (++row; row < bottom_row; ++row)
16504 row->enabled_p = row->mode_line_p = 0;
16507 /* Update window_end_pos etc.; last_reused_text_row is the last
16508 reused row from the current matrix containing text, if any.
16509 The value of last_text_row is the last displayed line
16510 containing text. */
16511 if (last_reused_text_row)
16513 w->window_end_bytepos
16514 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
16515 wset_window_end_pos
16516 (w, make_number (Z
16517 - MATRIX_ROW_END_CHARPOS (last_reused_text_row)));
16518 wset_window_end_vpos
16519 (w, make_number (MATRIX_ROW_VPOS (last_reused_text_row,
16520 w->current_matrix)));
16522 else if (last_text_row)
16524 w->window_end_bytepos
16525 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16526 wset_window_end_pos
16527 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
16528 wset_window_end_vpos
16529 (w, make_number (MATRIX_ROW_VPOS (last_text_row,
16530 w->desired_matrix)));
16532 else
16534 /* This window must be completely empty. */
16535 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
16536 wset_window_end_pos (w, make_number (Z - ZV));
16537 wset_window_end_vpos (w, make_number (0));
16539 w->window_end_valid = 0;
16541 /* Update hint: don't try scrolling again in update_window. */
16542 w->desired_matrix->no_scrolling_p = 1;
16544 #ifdef GLYPH_DEBUG
16545 debug_method_add (w, "try_window_reusing_current_matrix 1");
16546 #endif
16547 return 1;
16549 else if (CHARPOS (new_start) > CHARPOS (start))
16551 struct glyph_row *pt_row, *row;
16552 struct glyph_row *first_reusable_row;
16553 struct glyph_row *first_row_to_display;
16554 int dy;
16555 int yb = window_text_bottom_y (w);
16557 /* Find the row starting at new_start, if there is one. Don't
16558 reuse a partially visible line at the end. */
16559 first_reusable_row = start_row;
16560 while (first_reusable_row->enabled_p
16561 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
16562 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
16563 < CHARPOS (new_start)))
16564 ++first_reusable_row;
16566 /* Give up if there is no row to reuse. */
16567 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
16568 || !first_reusable_row->enabled_p
16569 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
16570 != CHARPOS (new_start)))
16571 return 0;
16573 /* We can reuse fully visible rows beginning with
16574 first_reusable_row to the end of the window. Set
16575 first_row_to_display to the first row that cannot be reused.
16576 Set pt_row to the row containing point, if there is any. */
16577 pt_row = NULL;
16578 for (first_row_to_display = first_reusable_row;
16579 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
16580 ++first_row_to_display)
16582 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
16583 && (PT < MATRIX_ROW_END_CHARPOS (first_row_to_display)
16584 || (PT == MATRIX_ROW_END_CHARPOS (first_row_to_display)
16585 && first_row_to_display->ends_at_zv_p
16586 && pt_row == NULL)))
16587 pt_row = first_row_to_display;
16590 /* Start displaying at the start of first_row_to_display. */
16591 eassert (first_row_to_display->y < yb);
16592 init_to_row_start (&it, w, first_row_to_display);
16594 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
16595 - start_vpos);
16596 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
16597 - nrows_scrolled);
16598 it.current_y = (first_row_to_display->y - first_reusable_row->y
16599 + WINDOW_HEADER_LINE_HEIGHT (w));
16601 /* Display lines beginning with first_row_to_display in the
16602 desired matrix. Set last_text_row to the last row displayed
16603 that displays text. */
16604 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
16605 if (pt_row == NULL)
16606 w->cursor.vpos = -1;
16607 last_text_row = NULL;
16608 while (it.current_y < it.last_visible_y && !fonts_changed_p)
16609 if (display_line (&it))
16610 last_text_row = it.glyph_row - 1;
16612 /* If point is in a reused row, adjust y and vpos of the cursor
16613 position. */
16614 if (pt_row)
16616 w->cursor.vpos -= nrows_scrolled;
16617 w->cursor.y -= first_reusable_row->y - start_row->y;
16620 /* Give up if point isn't in a row displayed or reused. (This
16621 also handles the case where w->cursor.vpos < nrows_scrolled
16622 after the calls to display_line, which can happen with scroll
16623 margins. See bug#1295.) */
16624 if (w->cursor.vpos < 0)
16626 clear_glyph_matrix (w->desired_matrix);
16627 return 0;
16630 /* Scroll the display. */
16631 run.current_y = first_reusable_row->y;
16632 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
16633 run.height = it.last_visible_y - run.current_y;
16634 dy = run.current_y - run.desired_y;
16636 if (run.height)
16638 update_begin (f);
16639 FRAME_RIF (f)->update_window_begin_hook (w);
16640 FRAME_RIF (f)->clear_window_mouse_face (w);
16641 FRAME_RIF (f)->scroll_run_hook (w, &run);
16642 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
16643 update_end (f);
16646 /* Adjust Y positions of reused rows. */
16647 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
16648 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
16649 max_y = it.last_visible_y;
16650 for (row = first_reusable_row; row < first_row_to_display; ++row)
16652 row->y -= dy;
16653 row->visible_height = row->height;
16654 if (row->y < min_y)
16655 row->visible_height -= min_y - row->y;
16656 if (row->y + row->height > max_y)
16657 row->visible_height -= row->y + row->height - max_y;
16658 if (row->fringe_bitmap_periodic_p)
16659 row->redraw_fringe_bitmaps_p = 1;
16662 /* Scroll the current matrix. */
16663 eassert (nrows_scrolled > 0);
16664 rotate_matrix (w->current_matrix,
16665 start_vpos,
16666 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
16667 -nrows_scrolled);
16669 /* Disable rows not reused. */
16670 for (row -= nrows_scrolled; row < bottom_row; ++row)
16671 row->enabled_p = 0;
16673 /* Point may have moved to a different line, so we cannot assume that
16674 the previous cursor position is valid; locate the correct row. */
16675 if (pt_row)
16677 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
16678 row < bottom_row
16679 && PT >= MATRIX_ROW_END_CHARPOS (row)
16680 && !row->ends_at_zv_p;
16681 row++)
16683 w->cursor.vpos++;
16684 w->cursor.y = row->y;
16686 if (row < bottom_row)
16688 /* Can't simply scan the row for point with
16689 bidi-reordered glyph rows. Let set_cursor_from_row
16690 figure out where to put the cursor, and if it fails,
16691 give up. */
16692 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
16694 if (!set_cursor_from_row (w, row, w->current_matrix,
16695 0, 0, 0, 0))
16697 clear_glyph_matrix (w->desired_matrix);
16698 return 0;
16701 else
16703 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
16704 struct glyph *end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
16706 for (; glyph < end
16707 && (!BUFFERP (glyph->object)
16708 || glyph->charpos < PT);
16709 glyph++)
16711 w->cursor.hpos++;
16712 w->cursor.x += glyph->pixel_width;
16718 /* Adjust window end. A null value of last_text_row means that
16719 the window end is in reused rows which in turn means that
16720 only its vpos can have changed. */
16721 if (last_text_row)
16723 w->window_end_bytepos
16724 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16725 wset_window_end_pos
16726 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
16727 wset_window_end_vpos
16728 (w, make_number (MATRIX_ROW_VPOS (last_text_row,
16729 w->desired_matrix)));
16731 else
16733 wset_window_end_vpos
16734 (w, make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled));
16737 w->window_end_valid = 0;
16738 w->desired_matrix->no_scrolling_p = 1;
16740 #ifdef GLYPH_DEBUG
16741 debug_method_add (w, "try_window_reusing_current_matrix 2");
16742 #endif
16743 return 1;
16746 return 0;
16751 /************************************************************************
16752 Window redisplay reusing current matrix when buffer has changed
16753 ************************************************************************/
16755 static struct glyph_row *find_last_unchanged_at_beg_row (struct window *);
16756 static struct glyph_row *find_first_unchanged_at_end_row (struct window *,
16757 ptrdiff_t *, ptrdiff_t *);
16758 static struct glyph_row *
16759 find_last_row_displaying_text (struct glyph_matrix *, struct it *,
16760 struct glyph_row *);
16763 /* Return the last row in MATRIX displaying text. If row START is
16764 non-null, start searching with that row. IT gives the dimensions
16765 of the display. Value is null if matrix is empty; otherwise it is
16766 a pointer to the row found. */
16768 static struct glyph_row *
16769 find_last_row_displaying_text (struct glyph_matrix *matrix, struct it *it,
16770 struct glyph_row *start)
16772 struct glyph_row *row, *row_found;
16774 /* Set row_found to the last row in IT->w's current matrix
16775 displaying text. The loop looks funny but think of partially
16776 visible lines. */
16777 row_found = NULL;
16778 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
16779 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16781 eassert (row->enabled_p);
16782 row_found = row;
16783 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
16784 break;
16785 ++row;
16788 return row_found;
16792 /* Return the last row in the current matrix of W that is not affected
16793 by changes at the start of current_buffer that occurred since W's
16794 current matrix was built. Value is null if no such row exists.
16796 BEG_UNCHANGED us the number of characters unchanged at the start of
16797 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
16798 first changed character in current_buffer. Characters at positions <
16799 BEG + BEG_UNCHANGED are at the same buffer positions as they were
16800 when the current matrix was built. */
16802 static struct glyph_row *
16803 find_last_unchanged_at_beg_row (struct window *w)
16805 ptrdiff_t first_changed_pos = BEG + BEG_UNCHANGED;
16806 struct glyph_row *row;
16807 struct glyph_row *row_found = NULL;
16808 int yb = window_text_bottom_y (w);
16810 /* Find the last row displaying unchanged text. */
16811 for (row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16812 MATRIX_ROW_DISPLAYS_TEXT_P (row)
16813 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos;
16814 ++row)
16816 if (/* If row ends before first_changed_pos, it is unchanged,
16817 except in some case. */
16818 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
16819 /* When row ends in ZV and we write at ZV it is not
16820 unchanged. */
16821 && !row->ends_at_zv_p
16822 /* When first_changed_pos is the end of a continued line,
16823 row is not unchanged because it may be no longer
16824 continued. */
16825 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
16826 && (row->continued_p
16827 || row->exact_window_width_line_p))
16828 /* If ROW->end is beyond ZV, then ROW->end is outdated and
16829 needs to be recomputed, so don't consider this row as
16830 unchanged. This happens when the last line was
16831 bidi-reordered and was killed immediately before this
16832 redisplay cycle. In that case, ROW->end stores the
16833 buffer position of the first visual-order character of
16834 the killed text, which is now beyond ZV. */
16835 && CHARPOS (row->end.pos) <= ZV)
16836 row_found = row;
16838 /* Stop if last visible row. */
16839 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
16840 break;
16843 return row_found;
16847 /* Find the first glyph row in the current matrix of W that is not
16848 affected by changes at the end of current_buffer since the
16849 time W's current matrix was built.
16851 Return in *DELTA the number of chars by which buffer positions in
16852 unchanged text at the end of current_buffer must be adjusted.
16854 Return in *DELTA_BYTES the corresponding number of bytes.
16856 Value is null if no such row exists, i.e. all rows are affected by
16857 changes. */
16859 static struct glyph_row *
16860 find_first_unchanged_at_end_row (struct window *w,
16861 ptrdiff_t *delta, ptrdiff_t *delta_bytes)
16863 struct glyph_row *row;
16864 struct glyph_row *row_found = NULL;
16866 *delta = *delta_bytes = 0;
16868 /* Display must not have been paused, otherwise the current matrix
16869 is not up to date. */
16870 eassert (w->window_end_valid);
16872 /* A value of window_end_pos >= END_UNCHANGED means that the window
16873 end is in the range of changed text. If so, there is no
16874 unchanged row at the end of W's current matrix. */
16875 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
16876 return NULL;
16878 /* Set row to the last row in W's current matrix displaying text. */
16879 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
16881 /* If matrix is entirely empty, no unchanged row exists. */
16882 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16884 /* The value of row is the last glyph row in the matrix having a
16885 meaningful buffer position in it. The end position of row
16886 corresponds to window_end_pos. This allows us to translate
16887 buffer positions in the current matrix to current buffer
16888 positions for characters not in changed text. */
16889 ptrdiff_t Z_old =
16890 MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
16891 ptrdiff_t Z_BYTE_old =
16892 MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
16893 ptrdiff_t last_unchanged_pos, last_unchanged_pos_old;
16894 struct glyph_row *first_text_row
16895 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16897 *delta = Z - Z_old;
16898 *delta_bytes = Z_BYTE - Z_BYTE_old;
16900 /* Set last_unchanged_pos to the buffer position of the last
16901 character in the buffer that has not been changed. Z is the
16902 index + 1 of the last character in current_buffer, i.e. by
16903 subtracting END_UNCHANGED we get the index of the last
16904 unchanged character, and we have to add BEG to get its buffer
16905 position. */
16906 last_unchanged_pos = Z - END_UNCHANGED + BEG;
16907 last_unchanged_pos_old = last_unchanged_pos - *delta;
16909 /* Search backward from ROW for a row displaying a line that
16910 starts at a minimum position >= last_unchanged_pos_old. */
16911 for (; row > first_text_row; --row)
16913 /* This used to abort, but it can happen.
16914 It is ok to just stop the search instead here. KFS. */
16915 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
16916 break;
16918 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
16919 row_found = row;
16923 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
16925 return row_found;
16929 /* Make sure that glyph rows in the current matrix of window W
16930 reference the same glyph memory as corresponding rows in the
16931 frame's frame matrix. This function is called after scrolling W's
16932 current matrix on a terminal frame in try_window_id and
16933 try_window_reusing_current_matrix. */
16935 static void
16936 sync_frame_with_window_matrix_rows (struct window *w)
16938 struct frame *f = XFRAME (w->frame);
16939 struct glyph_row *window_row, *window_row_end, *frame_row;
16941 /* Preconditions: W must be a leaf window and full-width. Its frame
16942 must have a frame matrix. */
16943 eassert (BUFFERP (w->contents));
16944 eassert (WINDOW_FULL_WIDTH_P (w));
16945 eassert (!FRAME_WINDOW_P (f));
16947 /* If W is a full-width window, glyph pointers in W's current matrix
16948 have, by definition, to be the same as glyph pointers in the
16949 corresponding frame matrix. Note that frame matrices have no
16950 marginal areas (see build_frame_matrix). */
16951 window_row = w->current_matrix->rows;
16952 window_row_end = window_row + w->current_matrix->nrows;
16953 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
16954 while (window_row < window_row_end)
16956 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
16957 struct glyph *end = window_row->glyphs[LAST_AREA];
16959 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
16960 frame_row->glyphs[TEXT_AREA] = start;
16961 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
16962 frame_row->glyphs[LAST_AREA] = end;
16964 /* Disable frame rows whose corresponding window rows have
16965 been disabled in try_window_id. */
16966 if (!window_row->enabled_p)
16967 frame_row->enabled_p = 0;
16969 ++window_row, ++frame_row;
16974 /* Find the glyph row in window W containing CHARPOS. Consider all
16975 rows between START and END (not inclusive). END null means search
16976 all rows to the end of the display area of W. Value is the row
16977 containing CHARPOS or null. */
16979 struct glyph_row *
16980 row_containing_pos (struct window *w, ptrdiff_t charpos,
16981 struct glyph_row *start, struct glyph_row *end, int dy)
16983 struct glyph_row *row = start;
16984 struct glyph_row *best_row = NULL;
16985 ptrdiff_t mindif = BUF_ZV (XBUFFER (w->contents)) + 1;
16986 int last_y;
16988 /* If we happen to start on a header-line, skip that. */
16989 if (row->mode_line_p)
16990 ++row;
16992 if ((end && row >= end) || !row->enabled_p)
16993 return NULL;
16995 last_y = window_text_bottom_y (w) - dy;
16997 while (1)
16999 /* Give up if we have gone too far. */
17000 if (end && row >= end)
17001 return NULL;
17002 /* This formerly returned if they were equal.
17003 I think that both quantities are of a "last plus one" type;
17004 if so, when they are equal, the row is within the screen. -- rms. */
17005 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
17006 return NULL;
17008 /* If it is in this row, return this row. */
17009 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
17010 || (MATRIX_ROW_END_CHARPOS (row) == charpos
17011 /* The end position of a row equals the start
17012 position of the next row. If CHARPOS is there, we
17013 would rather consider it displayed in the next
17014 line, except when this line ends in ZV. */
17015 && !row_for_charpos_p (row, charpos)))
17016 && charpos >= MATRIX_ROW_START_CHARPOS (row))
17018 struct glyph *g;
17020 if (NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
17021 || (!best_row && !row->continued_p))
17022 return row;
17023 /* In bidi-reordered rows, there could be several rows whose
17024 edges surround CHARPOS, all of these rows belonging to
17025 the same continued line. We need to find the row which
17026 fits CHARPOS the best. */
17027 for (g = row->glyphs[TEXT_AREA];
17028 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
17029 g++)
17031 if (!STRINGP (g->object))
17033 if (g->charpos > 0 && eabs (g->charpos - charpos) < mindif)
17035 mindif = eabs (g->charpos - charpos);
17036 best_row = row;
17037 /* Exact match always wins. */
17038 if (mindif == 0)
17039 return best_row;
17044 else if (best_row && !row->continued_p)
17045 return best_row;
17046 ++row;
17051 /* Try to redisplay window W by reusing its existing display. W's
17052 current matrix must be up to date when this function is called,
17053 i.e. window_end_valid must be nonzero.
17055 Value is
17057 1 if display has been updated
17058 0 if otherwise unsuccessful
17059 -1 if redisplay with same window start is known not to succeed
17061 The following steps are performed:
17063 1. Find the last row in the current matrix of W that is not
17064 affected by changes at the start of current_buffer. If no such row
17065 is found, give up.
17067 2. Find the first row in W's current matrix that is not affected by
17068 changes at the end of current_buffer. Maybe there is no such row.
17070 3. Display lines beginning with the row + 1 found in step 1 to the
17071 row found in step 2 or, if step 2 didn't find a row, to the end of
17072 the window.
17074 4. If cursor is not known to appear on the window, give up.
17076 5. If display stopped at the row found in step 2, scroll the
17077 display and current matrix as needed.
17079 6. Maybe display some lines at the end of W, if we must. This can
17080 happen under various circumstances, like a partially visible line
17081 becoming fully visible, or because newly displayed lines are displayed
17082 in smaller font sizes.
17084 7. Update W's window end information. */
17086 static int
17087 try_window_id (struct window *w)
17089 struct frame *f = XFRAME (w->frame);
17090 struct glyph_matrix *current_matrix = w->current_matrix;
17091 struct glyph_matrix *desired_matrix = w->desired_matrix;
17092 struct glyph_row *last_unchanged_at_beg_row;
17093 struct glyph_row *first_unchanged_at_end_row;
17094 struct glyph_row *row;
17095 struct glyph_row *bottom_row;
17096 int bottom_vpos;
17097 struct it it;
17098 ptrdiff_t delta = 0, delta_bytes = 0, stop_pos;
17099 int dvpos, dy;
17100 struct text_pos start_pos;
17101 struct run run;
17102 int first_unchanged_at_end_vpos = 0;
17103 struct glyph_row *last_text_row, *last_text_row_at_end;
17104 struct text_pos start;
17105 ptrdiff_t first_changed_charpos, last_changed_charpos;
17107 #ifdef GLYPH_DEBUG
17108 if (inhibit_try_window_id)
17109 return 0;
17110 #endif
17112 /* This is handy for debugging. */
17113 #if 0
17114 #define GIVE_UP(X) \
17115 do { \
17116 fprintf (stderr, "try_window_id give up %d\n", (X)); \
17117 return 0; \
17118 } while (0)
17119 #else
17120 #define GIVE_UP(X) return 0
17121 #endif
17123 SET_TEXT_POS_FROM_MARKER (start, w->start);
17125 /* Don't use this for mini-windows because these can show
17126 messages and mini-buffers, and we don't handle that here. */
17127 if (MINI_WINDOW_P (w))
17128 GIVE_UP (1);
17130 /* This flag is used to prevent redisplay optimizations. */
17131 if (windows_or_buffers_changed || cursor_type_changed)
17132 GIVE_UP (2);
17134 /* Verify that narrowing has not changed.
17135 Also verify that we were not told to prevent redisplay optimizations.
17136 It would be nice to further
17137 reduce the number of cases where this prevents try_window_id. */
17138 if (current_buffer->clip_changed
17139 || current_buffer->prevent_redisplay_optimizations_p)
17140 GIVE_UP (3);
17142 /* Window must either use window-based redisplay or be full width. */
17143 if (!FRAME_WINDOW_P (f)
17144 && (!FRAME_LINE_INS_DEL_OK (f)
17145 || !WINDOW_FULL_WIDTH_P (w)))
17146 GIVE_UP (4);
17148 /* Give up if point is known NOT to appear in W. */
17149 if (PT < CHARPOS (start))
17150 GIVE_UP (5);
17152 /* Another way to prevent redisplay optimizations. */
17153 if (w->last_modified == 0)
17154 GIVE_UP (6);
17156 /* Verify that window is not hscrolled. */
17157 if (w->hscroll != 0)
17158 GIVE_UP (7);
17160 /* Verify that display wasn't paused. */
17161 if (!w->window_end_valid)
17162 GIVE_UP (8);
17164 /* Can't use this if highlighting a region because a cursor movement
17165 will do more than just set the cursor. */
17166 if (markpos_of_region () >= 0)
17167 GIVE_UP (9);
17169 /* Likewise if highlighting trailing whitespace. */
17170 if (!NILP (Vshow_trailing_whitespace))
17171 GIVE_UP (11);
17173 /* Likewise if showing a region. */
17174 if (w->region_showing)
17175 GIVE_UP (10);
17177 /* Can't use this if overlay arrow position and/or string have
17178 changed. */
17179 if (overlay_arrows_changed_p ())
17180 GIVE_UP (12);
17182 /* When word-wrap is on, adding a space to the first word of a
17183 wrapped line can change the wrap position, altering the line
17184 above it. It might be worthwhile to handle this more
17185 intelligently, but for now just redisplay from scratch. */
17186 if (!NILP (BVAR (XBUFFER (w->contents), word_wrap)))
17187 GIVE_UP (21);
17189 /* Under bidi reordering, adding or deleting a character in the
17190 beginning of a paragraph, before the first strong directional
17191 character, can change the base direction of the paragraph (unless
17192 the buffer specifies a fixed paragraph direction), which will
17193 require to redisplay the whole paragraph. It might be worthwhile
17194 to find the paragraph limits and widen the range of redisplayed
17195 lines to that, but for now just give up this optimization and
17196 redisplay from scratch. */
17197 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
17198 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
17199 GIVE_UP (22);
17201 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
17202 only if buffer has really changed. The reason is that the gap is
17203 initially at Z for freshly visited files. The code below would
17204 set end_unchanged to 0 in that case. */
17205 if (MODIFF > SAVE_MODIFF
17206 /* This seems to happen sometimes after saving a buffer. */
17207 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
17209 if (GPT - BEG < BEG_UNCHANGED)
17210 BEG_UNCHANGED = GPT - BEG;
17211 if (Z - GPT < END_UNCHANGED)
17212 END_UNCHANGED = Z - GPT;
17215 /* The position of the first and last character that has been changed. */
17216 first_changed_charpos = BEG + BEG_UNCHANGED;
17217 last_changed_charpos = Z - END_UNCHANGED;
17219 /* If window starts after a line end, and the last change is in
17220 front of that newline, then changes don't affect the display.
17221 This case happens with stealth-fontification. Note that although
17222 the display is unchanged, glyph positions in the matrix have to
17223 be adjusted, of course. */
17224 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
17225 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
17226 && ((last_changed_charpos < CHARPOS (start)
17227 && CHARPOS (start) == BEGV)
17228 || (last_changed_charpos < CHARPOS (start) - 1
17229 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
17231 ptrdiff_t Z_old, Z_delta, Z_BYTE_old, Z_delta_bytes;
17232 struct glyph_row *r0;
17234 /* Compute how many chars/bytes have been added to or removed
17235 from the buffer. */
17236 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
17237 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
17238 Z_delta = Z - Z_old;
17239 Z_delta_bytes = Z_BYTE - Z_BYTE_old;
17241 /* Give up if PT is not in the window. Note that it already has
17242 been checked at the start of try_window_id that PT is not in
17243 front of the window start. */
17244 if (PT >= MATRIX_ROW_END_CHARPOS (row) + Z_delta)
17245 GIVE_UP (13);
17247 /* If window start is unchanged, we can reuse the whole matrix
17248 as is, after adjusting glyph positions. No need to compute
17249 the window end again, since its offset from Z hasn't changed. */
17250 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
17251 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + Z_delta
17252 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + Z_delta_bytes
17253 /* PT must not be in a partially visible line. */
17254 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + Z_delta
17255 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
17257 /* Adjust positions in the glyph matrix. */
17258 if (Z_delta || Z_delta_bytes)
17260 struct glyph_row *r1
17261 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
17262 increment_matrix_positions (w->current_matrix,
17263 MATRIX_ROW_VPOS (r0, current_matrix),
17264 MATRIX_ROW_VPOS (r1, current_matrix),
17265 Z_delta, Z_delta_bytes);
17268 /* Set the cursor. */
17269 row = row_containing_pos (w, PT, r0, NULL, 0);
17270 if (row)
17271 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
17272 else
17273 emacs_abort ();
17274 return 1;
17278 /* Handle the case that changes are all below what is displayed in
17279 the window, and that PT is in the window. This shortcut cannot
17280 be taken if ZV is visible in the window, and text has been added
17281 there that is visible in the window. */
17282 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
17283 /* ZV is not visible in the window, or there are no
17284 changes at ZV, actually. */
17285 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
17286 || first_changed_charpos == last_changed_charpos))
17288 struct glyph_row *r0;
17290 /* Give up if PT is not in the window. Note that it already has
17291 been checked at the start of try_window_id that PT is not in
17292 front of the window start. */
17293 if (PT >= MATRIX_ROW_END_CHARPOS (row))
17294 GIVE_UP (14);
17296 /* If window start is unchanged, we can reuse the whole matrix
17297 as is, without changing glyph positions since no text has
17298 been added/removed in front of the window end. */
17299 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
17300 if (TEXT_POS_EQUAL_P (start, r0->minpos)
17301 /* PT must not be in a partially visible line. */
17302 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
17303 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
17305 /* We have to compute the window end anew since text
17306 could have been added/removed after it. */
17307 wset_window_end_pos
17308 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row)));
17309 w->window_end_bytepos
17310 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17312 /* Set the cursor. */
17313 row = row_containing_pos (w, PT, r0, NULL, 0);
17314 if (row)
17315 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
17316 else
17317 emacs_abort ();
17318 return 2;
17322 /* Give up if window start is in the changed area.
17324 The condition used to read
17326 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
17328 but why that was tested escapes me at the moment. */
17329 if (CHARPOS (start) >= first_changed_charpos
17330 && CHARPOS (start) <= last_changed_charpos)
17331 GIVE_UP (15);
17333 /* Check that window start agrees with the start of the first glyph
17334 row in its current matrix. Check this after we know the window
17335 start is not in changed text, otherwise positions would not be
17336 comparable. */
17337 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
17338 if (!TEXT_POS_EQUAL_P (start, row->minpos))
17339 GIVE_UP (16);
17341 /* Give up if the window ends in strings. Overlay strings
17342 at the end are difficult to handle, so don't try. */
17343 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
17344 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
17345 GIVE_UP (20);
17347 /* Compute the position at which we have to start displaying new
17348 lines. Some of the lines at the top of the window might be
17349 reusable because they are not displaying changed text. Find the
17350 last row in W's current matrix not affected by changes at the
17351 start of current_buffer. Value is null if changes start in the
17352 first line of window. */
17353 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
17354 if (last_unchanged_at_beg_row)
17356 /* Avoid starting to display in the middle of a character, a TAB
17357 for instance. This is easier than to set up the iterator
17358 exactly, and it's not a frequent case, so the additional
17359 effort wouldn't really pay off. */
17360 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
17361 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
17362 && last_unchanged_at_beg_row > w->current_matrix->rows)
17363 --last_unchanged_at_beg_row;
17365 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
17366 GIVE_UP (17);
17368 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
17369 GIVE_UP (18);
17370 start_pos = it.current.pos;
17372 /* Start displaying new lines in the desired matrix at the same
17373 vpos we would use in the current matrix, i.e. below
17374 last_unchanged_at_beg_row. */
17375 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
17376 current_matrix);
17377 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
17378 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
17380 eassert (it.hpos == 0 && it.current_x == 0);
17382 else
17384 /* There are no reusable lines at the start of the window.
17385 Start displaying in the first text line. */
17386 start_display (&it, w, start);
17387 it.vpos = it.first_vpos;
17388 start_pos = it.current.pos;
17391 /* Find the first row that is not affected by changes at the end of
17392 the buffer. Value will be null if there is no unchanged row, in
17393 which case we must redisplay to the end of the window. delta
17394 will be set to the value by which buffer positions beginning with
17395 first_unchanged_at_end_row have to be adjusted due to text
17396 changes. */
17397 first_unchanged_at_end_row
17398 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
17399 IF_DEBUG (debug_delta = delta);
17400 IF_DEBUG (debug_delta_bytes = delta_bytes);
17402 /* Set stop_pos to the buffer position up to which we will have to
17403 display new lines. If first_unchanged_at_end_row != NULL, this
17404 is the buffer position of the start of the line displayed in that
17405 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
17406 that we don't stop at a buffer position. */
17407 stop_pos = 0;
17408 if (first_unchanged_at_end_row)
17410 eassert (last_unchanged_at_beg_row == NULL
17411 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
17413 /* If this is a continuation line, move forward to the next one
17414 that isn't. Changes in lines above affect this line.
17415 Caution: this may move first_unchanged_at_end_row to a row
17416 not displaying text. */
17417 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
17418 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
17419 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
17420 < it.last_visible_y))
17421 ++first_unchanged_at_end_row;
17423 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
17424 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
17425 >= it.last_visible_y))
17426 first_unchanged_at_end_row = NULL;
17427 else
17429 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
17430 + delta);
17431 first_unchanged_at_end_vpos
17432 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
17433 eassert (stop_pos >= Z - END_UNCHANGED);
17436 else if (last_unchanged_at_beg_row == NULL)
17437 GIVE_UP (19);
17440 #ifdef GLYPH_DEBUG
17442 /* Either there is no unchanged row at the end, or the one we have
17443 now displays text. This is a necessary condition for the window
17444 end pos calculation at the end of this function. */
17445 eassert (first_unchanged_at_end_row == NULL
17446 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
17448 debug_last_unchanged_at_beg_vpos
17449 = (last_unchanged_at_beg_row
17450 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
17451 : -1);
17452 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
17454 #endif /* GLYPH_DEBUG */
17457 /* Display new lines. Set last_text_row to the last new line
17458 displayed which has text on it, i.e. might end up as being the
17459 line where the window_end_vpos is. */
17460 w->cursor.vpos = -1;
17461 last_text_row = NULL;
17462 overlay_arrow_seen = 0;
17463 while (it.current_y < it.last_visible_y
17464 && !fonts_changed_p
17465 && (first_unchanged_at_end_row == NULL
17466 || IT_CHARPOS (it) < stop_pos))
17468 if (display_line (&it))
17469 last_text_row = it.glyph_row - 1;
17472 if (fonts_changed_p)
17473 return -1;
17476 /* Compute differences in buffer positions, y-positions etc. for
17477 lines reused at the bottom of the window. Compute what we can
17478 scroll. */
17479 if (first_unchanged_at_end_row
17480 /* No lines reused because we displayed everything up to the
17481 bottom of the window. */
17482 && it.current_y < it.last_visible_y)
17484 dvpos = (it.vpos
17485 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
17486 current_matrix));
17487 dy = it.current_y - first_unchanged_at_end_row->y;
17488 run.current_y = first_unchanged_at_end_row->y;
17489 run.desired_y = run.current_y + dy;
17490 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
17492 else
17494 delta = delta_bytes = dvpos = dy
17495 = run.current_y = run.desired_y = run.height = 0;
17496 first_unchanged_at_end_row = NULL;
17498 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
17501 /* Find the cursor if not already found. We have to decide whether
17502 PT will appear on this window (it sometimes doesn't, but this is
17503 not a very frequent case.) This decision has to be made before
17504 the current matrix is altered. A value of cursor.vpos < 0 means
17505 that PT is either in one of the lines beginning at
17506 first_unchanged_at_end_row or below the window. Don't care for
17507 lines that might be displayed later at the window end; as
17508 mentioned, this is not a frequent case. */
17509 if (w->cursor.vpos < 0)
17511 /* Cursor in unchanged rows at the top? */
17512 if (PT < CHARPOS (start_pos)
17513 && last_unchanged_at_beg_row)
17515 row = row_containing_pos (w, PT,
17516 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
17517 last_unchanged_at_beg_row + 1, 0);
17518 if (row)
17519 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
17522 /* Start from first_unchanged_at_end_row looking for PT. */
17523 else if (first_unchanged_at_end_row)
17525 row = row_containing_pos (w, PT - delta,
17526 first_unchanged_at_end_row, NULL, 0);
17527 if (row)
17528 set_cursor_from_row (w, row, w->current_matrix, delta,
17529 delta_bytes, dy, dvpos);
17532 /* Give up if cursor was not found. */
17533 if (w->cursor.vpos < 0)
17535 clear_glyph_matrix (w->desired_matrix);
17536 return -1;
17540 /* Don't let the cursor end in the scroll margins. */
17542 int this_scroll_margin, cursor_height;
17543 int frame_line_height = default_line_pixel_height (w);
17544 int window_total_lines
17545 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (it.f) / frame_line_height;
17547 this_scroll_margin =
17548 max (0, min (scroll_margin, window_total_lines / 4));
17549 this_scroll_margin *= frame_line_height;
17550 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
17552 if ((w->cursor.y < this_scroll_margin
17553 && CHARPOS (start) > BEGV)
17554 /* Old redisplay didn't take scroll margin into account at the bottom,
17555 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
17556 || (w->cursor.y + (make_cursor_line_fully_visible_p
17557 ? cursor_height + this_scroll_margin
17558 : 1)) > it.last_visible_y)
17560 w->cursor.vpos = -1;
17561 clear_glyph_matrix (w->desired_matrix);
17562 return -1;
17566 /* Scroll the display. Do it before changing the current matrix so
17567 that xterm.c doesn't get confused about where the cursor glyph is
17568 found. */
17569 if (dy && run.height)
17571 update_begin (f);
17573 if (FRAME_WINDOW_P (f))
17575 FRAME_RIF (f)->update_window_begin_hook (w);
17576 FRAME_RIF (f)->clear_window_mouse_face (w);
17577 FRAME_RIF (f)->scroll_run_hook (w, &run);
17578 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
17580 else
17582 /* Terminal frame. In this case, dvpos gives the number of
17583 lines to scroll by; dvpos < 0 means scroll up. */
17584 int from_vpos
17585 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
17586 int from = WINDOW_TOP_EDGE_LINE (w) + from_vpos;
17587 int end = (WINDOW_TOP_EDGE_LINE (w)
17588 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
17589 + window_internal_height (w));
17591 #if defined (HAVE_GPM) || defined (MSDOS)
17592 x_clear_window_mouse_face (w);
17593 #endif
17594 /* Perform the operation on the screen. */
17595 if (dvpos > 0)
17597 /* Scroll last_unchanged_at_beg_row to the end of the
17598 window down dvpos lines. */
17599 set_terminal_window (f, end);
17601 /* On dumb terminals delete dvpos lines at the end
17602 before inserting dvpos empty lines. */
17603 if (!FRAME_SCROLL_REGION_OK (f))
17604 ins_del_lines (f, end - dvpos, -dvpos);
17606 /* Insert dvpos empty lines in front of
17607 last_unchanged_at_beg_row. */
17608 ins_del_lines (f, from, dvpos);
17610 else if (dvpos < 0)
17612 /* Scroll up last_unchanged_at_beg_vpos to the end of
17613 the window to last_unchanged_at_beg_vpos - |dvpos|. */
17614 set_terminal_window (f, end);
17616 /* Delete dvpos lines in front of
17617 last_unchanged_at_beg_vpos. ins_del_lines will set
17618 the cursor to the given vpos and emit |dvpos| delete
17619 line sequences. */
17620 ins_del_lines (f, from + dvpos, dvpos);
17622 /* On a dumb terminal insert dvpos empty lines at the
17623 end. */
17624 if (!FRAME_SCROLL_REGION_OK (f))
17625 ins_del_lines (f, end + dvpos, -dvpos);
17628 set_terminal_window (f, 0);
17631 update_end (f);
17634 /* Shift reused rows of the current matrix to the right position.
17635 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
17636 text. */
17637 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
17638 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
17639 if (dvpos < 0)
17641 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
17642 bottom_vpos, dvpos);
17643 clear_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
17644 bottom_vpos);
17646 else if (dvpos > 0)
17648 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
17649 bottom_vpos, dvpos);
17650 clear_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
17651 first_unchanged_at_end_vpos + dvpos);
17654 /* For frame-based redisplay, make sure that current frame and window
17655 matrix are in sync with respect to glyph memory. */
17656 if (!FRAME_WINDOW_P (f))
17657 sync_frame_with_window_matrix_rows (w);
17659 /* Adjust buffer positions in reused rows. */
17660 if (delta || delta_bytes)
17661 increment_matrix_positions (current_matrix,
17662 first_unchanged_at_end_vpos + dvpos,
17663 bottom_vpos, delta, delta_bytes);
17665 /* Adjust Y positions. */
17666 if (dy)
17667 shift_glyph_matrix (w, current_matrix,
17668 first_unchanged_at_end_vpos + dvpos,
17669 bottom_vpos, dy);
17671 if (first_unchanged_at_end_row)
17673 first_unchanged_at_end_row += dvpos;
17674 if (first_unchanged_at_end_row->y >= it.last_visible_y
17675 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
17676 first_unchanged_at_end_row = NULL;
17679 /* If scrolling up, there may be some lines to display at the end of
17680 the window. */
17681 last_text_row_at_end = NULL;
17682 if (dy < 0)
17684 /* Scrolling up can leave for example a partially visible line
17685 at the end of the window to be redisplayed. */
17686 /* Set last_row to the glyph row in the current matrix where the
17687 window end line is found. It has been moved up or down in
17688 the matrix by dvpos. */
17689 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
17690 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
17692 /* If last_row is the window end line, it should display text. */
17693 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_row));
17695 /* If window end line was partially visible before, begin
17696 displaying at that line. Otherwise begin displaying with the
17697 line following it. */
17698 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
17700 init_to_row_start (&it, w, last_row);
17701 it.vpos = last_vpos;
17702 it.current_y = last_row->y;
17704 else
17706 init_to_row_end (&it, w, last_row);
17707 it.vpos = 1 + last_vpos;
17708 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
17709 ++last_row;
17712 /* We may start in a continuation line. If so, we have to
17713 get the right continuation_lines_width and current_x. */
17714 it.continuation_lines_width = last_row->continuation_lines_width;
17715 it.hpos = it.current_x = 0;
17717 /* Display the rest of the lines at the window end. */
17718 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
17719 while (it.current_y < it.last_visible_y
17720 && !fonts_changed_p)
17722 /* Is it always sure that the display agrees with lines in
17723 the current matrix? I don't think so, so we mark rows
17724 displayed invalid in the current matrix by setting their
17725 enabled_p flag to zero. */
17726 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
17727 if (display_line (&it))
17728 last_text_row_at_end = it.glyph_row - 1;
17732 /* Update window_end_pos and window_end_vpos. */
17733 if (first_unchanged_at_end_row
17734 && !last_text_row_at_end)
17736 /* Window end line if one of the preserved rows from the current
17737 matrix. Set row to the last row displaying text in current
17738 matrix starting at first_unchanged_at_end_row, after
17739 scrolling. */
17740 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
17741 row = find_last_row_displaying_text (w->current_matrix, &it,
17742 first_unchanged_at_end_row);
17743 eassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
17745 wset_window_end_pos (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row)));
17746 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17747 wset_window_end_vpos
17748 (w, make_number (MATRIX_ROW_VPOS (row, w->current_matrix)));
17749 eassert (w->window_end_bytepos >= 0);
17750 IF_DEBUG (debug_method_add (w, "A"));
17752 else if (last_text_row_at_end)
17754 wset_window_end_pos
17755 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end)));
17756 w->window_end_bytepos
17757 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
17758 wset_window_end_vpos
17759 (w, make_number (MATRIX_ROW_VPOS (last_text_row_at_end,
17760 desired_matrix)));
17761 eassert (w->window_end_bytepos >= 0);
17762 IF_DEBUG (debug_method_add (w, "B"));
17764 else if (last_text_row)
17766 /* We have displayed either to the end of the window or at the
17767 end of the window, i.e. the last row with text is to be found
17768 in the desired matrix. */
17769 wset_window_end_pos
17770 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
17771 w->window_end_bytepos
17772 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
17773 wset_window_end_vpos
17774 (w, make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix)));
17775 eassert (w->window_end_bytepos >= 0);
17777 else if (first_unchanged_at_end_row == NULL
17778 && last_text_row == NULL
17779 && last_text_row_at_end == NULL)
17781 /* Displayed to end of window, but no line containing text was
17782 displayed. Lines were deleted at the end of the window. */
17783 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
17784 int vpos = XFASTINT (w->window_end_vpos);
17785 struct glyph_row *current_row = current_matrix->rows + vpos;
17786 struct glyph_row *desired_row = desired_matrix->rows + vpos;
17788 for (row = NULL;
17789 row == NULL && vpos >= first_vpos;
17790 --vpos, --current_row, --desired_row)
17792 if (desired_row->enabled_p)
17794 if (MATRIX_ROW_DISPLAYS_TEXT_P (desired_row))
17795 row = desired_row;
17797 else if (MATRIX_ROW_DISPLAYS_TEXT_P (current_row))
17798 row = current_row;
17801 eassert (row != NULL);
17802 wset_window_end_vpos (w, make_number (vpos + 1));
17803 wset_window_end_pos (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row)));
17804 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17805 eassert (w->window_end_bytepos >= 0);
17806 IF_DEBUG (debug_method_add (w, "C"));
17808 else
17809 emacs_abort ();
17811 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
17812 debug_end_vpos = XFASTINT (w->window_end_vpos));
17814 /* Record that display has not been completed. */
17815 w->window_end_valid = 0;
17816 w->desired_matrix->no_scrolling_p = 1;
17817 return 3;
17819 #undef GIVE_UP
17824 /***********************************************************************
17825 More debugging support
17826 ***********************************************************************/
17828 #ifdef GLYPH_DEBUG
17830 void dump_glyph_row (struct glyph_row *, int, int) EXTERNALLY_VISIBLE;
17831 void dump_glyph_matrix (struct glyph_matrix *, int) EXTERNALLY_VISIBLE;
17832 void dump_glyph (struct glyph_row *, struct glyph *, int) EXTERNALLY_VISIBLE;
17835 /* Dump the contents of glyph matrix MATRIX on stderr.
17837 GLYPHS 0 means don't show glyph contents.
17838 GLYPHS 1 means show glyphs in short form
17839 GLYPHS > 1 means show glyphs in long form. */
17841 void
17842 dump_glyph_matrix (struct glyph_matrix *matrix, int glyphs)
17844 int i;
17845 for (i = 0; i < matrix->nrows; ++i)
17846 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
17850 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
17851 the glyph row and area where the glyph comes from. */
17853 void
17854 dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
17856 if (glyph->type == CHAR_GLYPH
17857 || glyph->type == GLYPHLESS_GLYPH)
17859 fprintf (stderr,
17860 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
17861 glyph - row->glyphs[TEXT_AREA],
17862 (glyph->type == CHAR_GLYPH
17863 ? 'C'
17864 : 'G'),
17865 glyph->charpos,
17866 (BUFFERP (glyph->object)
17867 ? 'B'
17868 : (STRINGP (glyph->object)
17869 ? 'S'
17870 : (INTEGERP (glyph->object)
17871 ? '0'
17872 : '-'))),
17873 glyph->pixel_width,
17874 glyph->u.ch,
17875 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
17876 ? glyph->u.ch
17877 : '.'),
17878 glyph->face_id,
17879 glyph->left_box_line_p,
17880 glyph->right_box_line_p);
17882 else if (glyph->type == STRETCH_GLYPH)
17884 fprintf (stderr,
17885 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
17886 glyph - row->glyphs[TEXT_AREA],
17887 'S',
17888 glyph->charpos,
17889 (BUFFERP (glyph->object)
17890 ? 'B'
17891 : (STRINGP (glyph->object)
17892 ? 'S'
17893 : (INTEGERP (glyph->object)
17894 ? '0'
17895 : '-'))),
17896 glyph->pixel_width,
17898 ' ',
17899 glyph->face_id,
17900 glyph->left_box_line_p,
17901 glyph->right_box_line_p);
17903 else if (glyph->type == IMAGE_GLYPH)
17905 fprintf (stderr,
17906 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
17907 glyph - row->glyphs[TEXT_AREA],
17908 'I',
17909 glyph->charpos,
17910 (BUFFERP (glyph->object)
17911 ? 'B'
17912 : (STRINGP (glyph->object)
17913 ? 'S'
17914 : (INTEGERP (glyph->object)
17915 ? '0'
17916 : '-'))),
17917 glyph->pixel_width,
17918 glyph->u.img_id,
17919 '.',
17920 glyph->face_id,
17921 glyph->left_box_line_p,
17922 glyph->right_box_line_p);
17924 else if (glyph->type == COMPOSITE_GLYPH)
17926 fprintf (stderr,
17927 " %5"pD"d %c %9"pI"d %c %3d 0x%06x",
17928 glyph - row->glyphs[TEXT_AREA],
17929 '+',
17930 glyph->charpos,
17931 (BUFFERP (glyph->object)
17932 ? 'B'
17933 : (STRINGP (glyph->object)
17934 ? 'S'
17935 : (INTEGERP (glyph->object)
17936 ? '0'
17937 : '-'))),
17938 glyph->pixel_width,
17939 glyph->u.cmp.id);
17940 if (glyph->u.cmp.automatic)
17941 fprintf (stderr,
17942 "[%d-%d]",
17943 glyph->slice.cmp.from, glyph->slice.cmp.to);
17944 fprintf (stderr, " . %4d %1.1d%1.1d\n",
17945 glyph->face_id,
17946 glyph->left_box_line_p,
17947 glyph->right_box_line_p);
17952 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
17953 GLYPHS 0 means don't show glyph contents.
17954 GLYPHS 1 means show glyphs in short form
17955 GLYPHS > 1 means show glyphs in long form. */
17957 void
17958 dump_glyph_row (struct glyph_row *row, int vpos, int glyphs)
17960 if (glyphs != 1)
17962 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
17963 fprintf (stderr, "==============================================================================\n");
17965 fprintf (stderr, "%3d %9"pI"d %9"pI"d %4d %1.1d%1.1d%1.1d%1.1d\
17966 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
17967 vpos,
17968 MATRIX_ROW_START_CHARPOS (row),
17969 MATRIX_ROW_END_CHARPOS (row),
17970 row->used[TEXT_AREA],
17971 row->contains_overlapping_glyphs_p,
17972 row->enabled_p,
17973 row->truncated_on_left_p,
17974 row->truncated_on_right_p,
17975 row->continued_p,
17976 MATRIX_ROW_CONTINUATION_LINE_P (row),
17977 MATRIX_ROW_DISPLAYS_TEXT_P (row),
17978 row->ends_at_zv_p,
17979 row->fill_line_p,
17980 row->ends_in_middle_of_char_p,
17981 row->starts_in_middle_of_char_p,
17982 row->mouse_face_p,
17983 row->x,
17984 row->y,
17985 row->pixel_width,
17986 row->height,
17987 row->visible_height,
17988 row->ascent,
17989 row->phys_ascent);
17990 /* The next 3 lines should align to "Start" in the header. */
17991 fprintf (stderr, " %9"pD"d %9"pD"d\t%5d\n", row->start.overlay_string_index,
17992 row->end.overlay_string_index,
17993 row->continuation_lines_width);
17994 fprintf (stderr, " %9"pI"d %9"pI"d\n",
17995 CHARPOS (row->start.string_pos),
17996 CHARPOS (row->end.string_pos));
17997 fprintf (stderr, " %9d %9d\n", row->start.dpvec_index,
17998 row->end.dpvec_index);
18001 if (glyphs > 1)
18003 int area;
18005 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18007 struct glyph *glyph = row->glyphs[area];
18008 struct glyph *glyph_end = glyph + row->used[area];
18010 /* Glyph for a line end in text. */
18011 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
18012 ++glyph_end;
18014 if (glyph < glyph_end)
18015 fprintf (stderr, " Glyph# Type Pos O W Code C Face LR\n");
18017 for (; glyph < glyph_end; ++glyph)
18018 dump_glyph (row, glyph, area);
18021 else if (glyphs == 1)
18023 int area;
18025 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18027 char *s = alloca (row->used[area] + 4);
18028 int i;
18030 for (i = 0; i < row->used[area]; ++i)
18032 struct glyph *glyph = row->glyphs[area] + i;
18033 if (i == row->used[area] - 1
18034 && area == TEXT_AREA
18035 && INTEGERP (glyph->object)
18036 && glyph->type == CHAR_GLYPH
18037 && glyph->u.ch == ' ')
18039 strcpy (&s[i], "[\\n]");
18040 i += 4;
18042 else if (glyph->type == CHAR_GLYPH
18043 && glyph->u.ch < 0x80
18044 && glyph->u.ch >= ' ')
18045 s[i] = glyph->u.ch;
18046 else
18047 s[i] = '.';
18050 s[i] = '\0';
18051 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
18057 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
18058 Sdump_glyph_matrix, 0, 1, "p",
18059 doc: /* Dump the current matrix of the selected window to stderr.
18060 Shows contents of glyph row structures. With non-nil
18061 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
18062 glyphs in short form, otherwise show glyphs in long form. */)
18063 (Lisp_Object glyphs)
18065 struct window *w = XWINDOW (selected_window);
18066 struct buffer *buffer = XBUFFER (w->contents);
18068 fprintf (stderr, "PT = %"pI"d, BEGV = %"pI"d. ZV = %"pI"d\n",
18069 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
18070 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
18071 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
18072 fprintf (stderr, "=============================================\n");
18073 dump_glyph_matrix (w->current_matrix,
18074 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 0);
18075 return Qnil;
18079 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
18080 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
18081 (void)
18083 struct frame *f = XFRAME (selected_frame);
18084 dump_glyph_matrix (f->current_matrix, 1);
18085 return Qnil;
18089 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
18090 doc: /* Dump glyph row ROW to stderr.
18091 GLYPH 0 means don't dump glyphs.
18092 GLYPH 1 means dump glyphs in short form.
18093 GLYPH > 1 or omitted means dump glyphs in long form. */)
18094 (Lisp_Object row, Lisp_Object glyphs)
18096 struct glyph_matrix *matrix;
18097 EMACS_INT vpos;
18099 CHECK_NUMBER (row);
18100 matrix = XWINDOW (selected_window)->current_matrix;
18101 vpos = XINT (row);
18102 if (vpos >= 0 && vpos < matrix->nrows)
18103 dump_glyph_row (MATRIX_ROW (matrix, vpos),
18104 vpos,
18105 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
18106 return Qnil;
18110 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
18111 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
18112 GLYPH 0 means don't dump glyphs.
18113 GLYPH 1 means dump glyphs in short form.
18114 GLYPH > 1 or omitted means dump glyphs in long form. */)
18115 (Lisp_Object row, Lisp_Object glyphs)
18117 struct frame *sf = SELECTED_FRAME ();
18118 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
18119 EMACS_INT vpos;
18121 CHECK_NUMBER (row);
18122 vpos = XINT (row);
18123 if (vpos >= 0 && vpos < m->nrows)
18124 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
18125 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
18126 return Qnil;
18130 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
18131 doc: /* Toggle tracing of redisplay.
18132 With ARG, turn tracing on if and only if ARG is positive. */)
18133 (Lisp_Object arg)
18135 if (NILP (arg))
18136 trace_redisplay_p = !trace_redisplay_p;
18137 else
18139 arg = Fprefix_numeric_value (arg);
18140 trace_redisplay_p = XINT (arg) > 0;
18143 return Qnil;
18147 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
18148 doc: /* Like `format', but print result to stderr.
18149 usage: (trace-to-stderr STRING &rest OBJECTS) */)
18150 (ptrdiff_t nargs, Lisp_Object *args)
18152 Lisp_Object s = Fformat (nargs, args);
18153 fprintf (stderr, "%s", SDATA (s));
18154 return Qnil;
18157 #endif /* GLYPH_DEBUG */
18161 /***********************************************************************
18162 Building Desired Matrix Rows
18163 ***********************************************************************/
18165 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
18166 Used for non-window-redisplay windows, and for windows w/o left fringe. */
18168 static struct glyph_row *
18169 get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
18171 struct frame *f = XFRAME (WINDOW_FRAME (w));
18172 struct buffer *buffer = XBUFFER (w->contents);
18173 struct buffer *old = current_buffer;
18174 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
18175 int arrow_len = SCHARS (overlay_arrow_string);
18176 const unsigned char *arrow_end = arrow_string + arrow_len;
18177 const unsigned char *p;
18178 struct it it;
18179 bool multibyte_p;
18180 int n_glyphs_before;
18182 set_buffer_temp (buffer);
18183 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
18184 it.glyph_row->used[TEXT_AREA] = 0;
18185 SET_TEXT_POS (it.position, 0, 0);
18187 multibyte_p = !NILP (BVAR (buffer, enable_multibyte_characters));
18188 p = arrow_string;
18189 while (p < arrow_end)
18191 Lisp_Object face, ilisp;
18193 /* Get the next character. */
18194 if (multibyte_p)
18195 it.c = it.char_to_display = string_char_and_length (p, &it.len);
18196 else
18198 it.c = it.char_to_display = *p, it.len = 1;
18199 if (! ASCII_CHAR_P (it.c))
18200 it.char_to_display = BYTE8_TO_CHAR (it.c);
18202 p += it.len;
18204 /* Get its face. */
18205 ilisp = make_number (p - arrow_string);
18206 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
18207 it.face_id = compute_char_face (f, it.char_to_display, face);
18209 /* Compute its width, get its glyphs. */
18210 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
18211 SET_TEXT_POS (it.position, -1, -1);
18212 PRODUCE_GLYPHS (&it);
18214 /* If this character doesn't fit any more in the line, we have
18215 to remove some glyphs. */
18216 if (it.current_x > it.last_visible_x)
18218 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
18219 break;
18223 set_buffer_temp (old);
18224 return it.glyph_row;
18228 /* Insert truncation glyphs at the start of IT->glyph_row. Which
18229 glyphs to insert is determined by produce_special_glyphs. */
18231 static void
18232 insert_left_trunc_glyphs (struct it *it)
18234 struct it truncate_it;
18235 struct glyph *from, *end, *to, *toend;
18237 eassert (!FRAME_WINDOW_P (it->f)
18238 || (!it->glyph_row->reversed_p
18239 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)
18240 || (it->glyph_row->reversed_p
18241 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0));
18243 /* Get the truncation glyphs. */
18244 truncate_it = *it;
18245 truncate_it.current_x = 0;
18246 truncate_it.face_id = DEFAULT_FACE_ID;
18247 truncate_it.glyph_row = &scratch_glyph_row;
18248 truncate_it.glyph_row->used[TEXT_AREA] = 0;
18249 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
18250 truncate_it.object = make_number (0);
18251 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
18253 /* Overwrite glyphs from IT with truncation glyphs. */
18254 if (!it->glyph_row->reversed_p)
18256 short tused = truncate_it.glyph_row->used[TEXT_AREA];
18258 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
18259 end = from + tused;
18260 to = it->glyph_row->glyphs[TEXT_AREA];
18261 toend = to + it->glyph_row->used[TEXT_AREA];
18262 if (FRAME_WINDOW_P (it->f))
18264 /* On GUI frames, when variable-size fonts are displayed,
18265 the truncation glyphs may need more pixels than the row's
18266 glyphs they overwrite. We overwrite more glyphs to free
18267 enough screen real estate, and enlarge the stretch glyph
18268 on the right (see display_line), if there is one, to
18269 preserve the screen position of the truncation glyphs on
18270 the right. */
18271 int w = 0;
18272 struct glyph *g = to;
18273 short used;
18275 /* The first glyph could be partially visible, in which case
18276 it->glyph_row->x will be negative. But we want the left
18277 truncation glyphs to be aligned at the left margin of the
18278 window, so we override the x coordinate at which the row
18279 will begin. */
18280 it->glyph_row->x = 0;
18281 while (g < toend && w < it->truncation_pixel_width)
18283 w += g->pixel_width;
18284 ++g;
18286 if (g - to - tused > 0)
18288 memmove (to + tused, g, (toend - g) * sizeof(*g));
18289 it->glyph_row->used[TEXT_AREA] -= g - to - tused;
18291 used = it->glyph_row->used[TEXT_AREA];
18292 if (it->glyph_row->truncated_on_right_p
18293 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
18294 && it->glyph_row->glyphs[TEXT_AREA][used - 2].type
18295 == STRETCH_GLYPH)
18297 int extra = w - it->truncation_pixel_width;
18299 it->glyph_row->glyphs[TEXT_AREA][used - 2].pixel_width += extra;
18303 while (from < end)
18304 *to++ = *from++;
18306 /* There may be padding glyphs left over. Overwrite them too. */
18307 if (!FRAME_WINDOW_P (it->f))
18309 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
18311 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
18312 while (from < end)
18313 *to++ = *from++;
18317 if (to > toend)
18318 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
18320 else
18322 short tused = truncate_it.glyph_row->used[TEXT_AREA];
18324 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
18325 that back to front. */
18326 end = truncate_it.glyph_row->glyphs[TEXT_AREA];
18327 from = end + truncate_it.glyph_row->used[TEXT_AREA] - 1;
18328 toend = it->glyph_row->glyphs[TEXT_AREA];
18329 to = toend + it->glyph_row->used[TEXT_AREA] - 1;
18330 if (FRAME_WINDOW_P (it->f))
18332 int w = 0;
18333 struct glyph *g = to;
18335 while (g >= toend && w < it->truncation_pixel_width)
18337 w += g->pixel_width;
18338 --g;
18340 if (to - g - tused > 0)
18341 to = g + tused;
18342 if (it->glyph_row->truncated_on_right_p
18343 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0
18344 && it->glyph_row->glyphs[TEXT_AREA][1].type == STRETCH_GLYPH)
18346 int extra = w - it->truncation_pixel_width;
18348 it->glyph_row->glyphs[TEXT_AREA][1].pixel_width += extra;
18352 while (from >= end && to >= toend)
18353 *to-- = *from--;
18354 if (!FRAME_WINDOW_P (it->f))
18356 while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
18358 from =
18359 truncate_it.glyph_row->glyphs[TEXT_AREA]
18360 + truncate_it.glyph_row->used[TEXT_AREA] - 1;
18361 while (from >= end && to >= toend)
18362 *to-- = *from--;
18365 if (from >= end)
18367 /* Need to free some room before prepending additional
18368 glyphs. */
18369 int move_by = from - end + 1;
18370 struct glyph *g0 = it->glyph_row->glyphs[TEXT_AREA];
18371 struct glyph *g = g0 + it->glyph_row->used[TEXT_AREA] - 1;
18373 for ( ; g >= g0; g--)
18374 g[move_by] = *g;
18375 while (from >= end)
18376 *to-- = *from--;
18377 it->glyph_row->used[TEXT_AREA] += move_by;
18382 /* Compute the hash code for ROW. */
18383 unsigned
18384 row_hash (struct glyph_row *row)
18386 int area, k;
18387 unsigned hashval = 0;
18389 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18390 for (k = 0; k < row->used[area]; ++k)
18391 hashval = ((((hashval << 4) + (hashval >> 24)) & 0x0fffffff)
18392 + row->glyphs[area][k].u.val
18393 + row->glyphs[area][k].face_id
18394 + row->glyphs[area][k].padding_p
18395 + (row->glyphs[area][k].type << 2));
18397 return hashval;
18400 /* Compute the pixel height and width of IT->glyph_row.
18402 Most of the time, ascent and height of a display line will be equal
18403 to the max_ascent and max_height values of the display iterator
18404 structure. This is not the case if
18406 1. We hit ZV without displaying anything. In this case, max_ascent
18407 and max_height will be zero.
18409 2. We have some glyphs that don't contribute to the line height.
18410 (The glyph row flag contributes_to_line_height_p is for future
18411 pixmap extensions).
18413 The first case is easily covered by using default values because in
18414 these cases, the line height does not really matter, except that it
18415 must not be zero. */
18417 static void
18418 compute_line_metrics (struct it *it)
18420 struct glyph_row *row = it->glyph_row;
18422 if (FRAME_WINDOW_P (it->f))
18424 int i, min_y, max_y;
18426 /* The line may consist of one space only, that was added to
18427 place the cursor on it. If so, the row's height hasn't been
18428 computed yet. */
18429 if (row->height == 0)
18431 if (it->max_ascent + it->max_descent == 0)
18432 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
18433 row->ascent = it->max_ascent;
18434 row->height = it->max_ascent + it->max_descent;
18435 row->phys_ascent = it->max_phys_ascent;
18436 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
18437 row->extra_line_spacing = it->max_extra_line_spacing;
18440 /* Compute the width of this line. */
18441 row->pixel_width = row->x;
18442 for (i = 0; i < row->used[TEXT_AREA]; ++i)
18443 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
18445 eassert (row->pixel_width >= 0);
18446 eassert (row->ascent >= 0 && row->height > 0);
18448 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
18449 || MATRIX_ROW_OVERLAPS_PRED_P (row));
18451 /* If first line's physical ascent is larger than its logical
18452 ascent, use the physical ascent, and make the row taller.
18453 This makes accented characters fully visible. */
18454 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
18455 && row->phys_ascent > row->ascent)
18457 row->height += row->phys_ascent - row->ascent;
18458 row->ascent = row->phys_ascent;
18461 /* Compute how much of the line is visible. */
18462 row->visible_height = row->height;
18464 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
18465 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
18467 if (row->y < min_y)
18468 row->visible_height -= min_y - row->y;
18469 if (row->y + row->height > max_y)
18470 row->visible_height -= row->y + row->height - max_y;
18472 else
18474 row->pixel_width = row->used[TEXT_AREA];
18475 if (row->continued_p)
18476 row->pixel_width -= it->continuation_pixel_width;
18477 else if (row->truncated_on_right_p)
18478 row->pixel_width -= it->truncation_pixel_width;
18479 row->ascent = row->phys_ascent = 0;
18480 row->height = row->phys_height = row->visible_height = 1;
18481 row->extra_line_spacing = 0;
18484 /* Compute a hash code for this row. */
18485 row->hash = row_hash (row);
18487 it->max_ascent = it->max_descent = 0;
18488 it->max_phys_ascent = it->max_phys_descent = 0;
18492 /* Append one space to the glyph row of iterator IT if doing a
18493 window-based redisplay. The space has the same face as
18494 IT->face_id. Value is non-zero if a space was added.
18496 This function is called to make sure that there is always one glyph
18497 at the end of a glyph row that the cursor can be set on under
18498 window-systems. (If there weren't such a glyph we would not know
18499 how wide and tall a box cursor should be displayed).
18501 At the same time this space let's a nicely handle clearing to the
18502 end of the line if the row ends in italic text. */
18504 static int
18505 append_space_for_newline (struct it *it, int default_face_p)
18507 if (FRAME_WINDOW_P (it->f))
18509 int n = it->glyph_row->used[TEXT_AREA];
18511 if (it->glyph_row->glyphs[TEXT_AREA] + n
18512 < it->glyph_row->glyphs[1 + TEXT_AREA])
18514 /* Save some values that must not be changed.
18515 Must save IT->c and IT->len because otherwise
18516 ITERATOR_AT_END_P wouldn't work anymore after
18517 append_space_for_newline has been called. */
18518 enum display_element_type saved_what = it->what;
18519 int saved_c = it->c, saved_len = it->len;
18520 int saved_char_to_display = it->char_to_display;
18521 int saved_x = it->current_x;
18522 int saved_face_id = it->face_id;
18523 int saved_box_end = it->end_of_box_run_p;
18524 struct text_pos saved_pos;
18525 Lisp_Object saved_object;
18526 struct face *face;
18528 saved_object = it->object;
18529 saved_pos = it->position;
18531 it->what = IT_CHARACTER;
18532 memset (&it->position, 0, sizeof it->position);
18533 it->object = make_number (0);
18534 it->c = it->char_to_display = ' ';
18535 it->len = 1;
18537 /* If the default face was remapped, be sure to use the
18538 remapped face for the appended newline. */
18539 if (default_face_p)
18540 it->face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
18541 else if (it->face_before_selective_p)
18542 it->face_id = it->saved_face_id;
18543 face = FACE_FROM_ID (it->f, it->face_id);
18544 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
18545 /* In R2L rows, we will prepend a stretch glyph that will
18546 have the end_of_box_run_p flag set for it, so there's no
18547 need for the appended newline glyph to have that flag
18548 set. */
18549 if (it->glyph_row->reversed_p
18550 /* But if the appended newline glyph goes all the way to
18551 the end of the row, there will be no stretch glyph,
18552 so leave the box flag set. */
18553 && saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x)
18554 it->end_of_box_run_p = 0;
18556 PRODUCE_GLYPHS (it);
18558 it->override_ascent = -1;
18559 it->constrain_row_ascent_descent_p = 0;
18560 it->current_x = saved_x;
18561 it->object = saved_object;
18562 it->position = saved_pos;
18563 it->what = saved_what;
18564 it->face_id = saved_face_id;
18565 it->len = saved_len;
18566 it->c = saved_c;
18567 it->char_to_display = saved_char_to_display;
18568 it->end_of_box_run_p = saved_box_end;
18569 return 1;
18573 return 0;
18577 /* Extend the face of the last glyph in the text area of IT->glyph_row
18578 to the end of the display line. Called from display_line. If the
18579 glyph row is empty, add a space glyph to it so that we know the
18580 face to draw. Set the glyph row flag fill_line_p. If the glyph
18581 row is R2L, prepend a stretch glyph to cover the empty space to the
18582 left of the leftmost glyph. */
18584 static void
18585 extend_face_to_end_of_line (struct it *it)
18587 struct face *face, *default_face;
18588 struct frame *f = it->f;
18590 /* If line is already filled, do nothing. Non window-system frames
18591 get a grace of one more ``pixel'' because their characters are
18592 1-``pixel'' wide, so they hit the equality too early. This grace
18593 is needed only for R2L rows that are not continued, to produce
18594 one extra blank where we could display the cursor. */
18595 if (it->current_x >= it->last_visible_x
18596 + (!FRAME_WINDOW_P (f)
18597 && it->glyph_row->reversed_p
18598 && !it->glyph_row->continued_p))
18599 return;
18601 /* The default face, possibly remapped. */
18602 default_face = FACE_FROM_ID (f, lookup_basic_face (f, DEFAULT_FACE_ID));
18604 /* Face extension extends the background and box of IT->face_id
18605 to the end of the line. If the background equals the background
18606 of the frame, we don't have to do anything. */
18607 if (it->face_before_selective_p)
18608 face = FACE_FROM_ID (f, it->saved_face_id);
18609 else
18610 face = FACE_FROM_ID (f, it->face_id);
18612 if (FRAME_WINDOW_P (f)
18613 && MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row)
18614 && face->box == FACE_NO_BOX
18615 && face->background == FRAME_BACKGROUND_PIXEL (f)
18616 && !face->stipple
18617 && !it->glyph_row->reversed_p)
18618 return;
18620 /* Set the glyph row flag indicating that the face of the last glyph
18621 in the text area has to be drawn to the end of the text area. */
18622 it->glyph_row->fill_line_p = 1;
18624 /* If current character of IT is not ASCII, make sure we have the
18625 ASCII face. This will be automatically undone the next time
18626 get_next_display_element returns a multibyte character. Note
18627 that the character will always be single byte in unibyte
18628 text. */
18629 if (!ASCII_CHAR_P (it->c))
18631 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
18634 if (FRAME_WINDOW_P (f))
18636 /* If the row is empty, add a space with the current face of IT,
18637 so that we know which face to draw. */
18638 if (it->glyph_row->used[TEXT_AREA] == 0)
18640 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
18641 it->glyph_row->glyphs[TEXT_AREA][0].face_id = face->id;
18642 it->glyph_row->used[TEXT_AREA] = 1;
18644 #ifdef HAVE_WINDOW_SYSTEM
18645 if (it->glyph_row->reversed_p)
18647 /* Prepend a stretch glyph to the row, such that the
18648 rightmost glyph will be drawn flushed all the way to the
18649 right margin of the window. The stretch glyph that will
18650 occupy the empty space, if any, to the left of the
18651 glyphs. */
18652 struct font *font = face->font ? face->font : FRAME_FONT (f);
18653 struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA];
18654 struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA];
18655 struct glyph *g;
18656 int row_width, stretch_ascent, stretch_width;
18657 struct text_pos saved_pos;
18658 int saved_face_id, saved_avoid_cursor, saved_box_start;
18660 for (row_width = 0, g = row_start; g < row_end; g++)
18661 row_width += g->pixel_width;
18662 stretch_width = window_box_width (it->w, TEXT_AREA) - row_width;
18663 if (stretch_width > 0)
18665 stretch_ascent =
18666 (((it->ascent + it->descent)
18667 * FONT_BASE (font)) / FONT_HEIGHT (font));
18668 saved_pos = it->position;
18669 memset (&it->position, 0, sizeof it->position);
18670 saved_avoid_cursor = it->avoid_cursor_p;
18671 it->avoid_cursor_p = 1;
18672 saved_face_id = it->face_id;
18673 saved_box_start = it->start_of_box_run_p;
18674 /* The last row's stretch glyph should get the default
18675 face, to avoid painting the rest of the window with
18676 the region face, if the region ends at ZV. */
18677 if (it->glyph_row->ends_at_zv_p)
18678 it->face_id = default_face->id;
18679 else
18680 it->face_id = face->id;
18681 it->start_of_box_run_p = 0;
18682 append_stretch_glyph (it, make_number (0), stretch_width,
18683 it->ascent + it->descent, stretch_ascent);
18684 it->position = saved_pos;
18685 it->avoid_cursor_p = saved_avoid_cursor;
18686 it->face_id = saved_face_id;
18687 it->start_of_box_run_p = saved_box_start;
18690 #endif /* HAVE_WINDOW_SYSTEM */
18692 else
18694 /* Save some values that must not be changed. */
18695 int saved_x = it->current_x;
18696 struct text_pos saved_pos;
18697 Lisp_Object saved_object;
18698 enum display_element_type saved_what = it->what;
18699 int saved_face_id = it->face_id;
18701 saved_object = it->object;
18702 saved_pos = it->position;
18704 it->what = IT_CHARACTER;
18705 memset (&it->position, 0, sizeof it->position);
18706 it->object = make_number (0);
18707 it->c = it->char_to_display = ' ';
18708 it->len = 1;
18709 /* The last row's blank glyphs should get the default face, to
18710 avoid painting the rest of the window with the region face,
18711 if the region ends at ZV. */
18712 if (it->glyph_row->ends_at_zv_p)
18713 it->face_id = default_face->id;
18714 else
18715 it->face_id = face->id;
18717 PRODUCE_GLYPHS (it);
18719 while (it->current_x <= it->last_visible_x)
18720 PRODUCE_GLYPHS (it);
18722 /* Don't count these blanks really. It would let us insert a left
18723 truncation glyph below and make us set the cursor on them, maybe. */
18724 it->current_x = saved_x;
18725 it->object = saved_object;
18726 it->position = saved_pos;
18727 it->what = saved_what;
18728 it->face_id = saved_face_id;
18733 /* Value is non-zero if text starting at CHARPOS in current_buffer is
18734 trailing whitespace. */
18736 static int
18737 trailing_whitespace_p (ptrdiff_t charpos)
18739 ptrdiff_t bytepos = CHAR_TO_BYTE (charpos);
18740 int c = 0;
18742 while (bytepos < ZV_BYTE
18743 && (c = FETCH_CHAR (bytepos),
18744 c == ' ' || c == '\t'))
18745 ++bytepos;
18747 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
18749 if (bytepos != PT_BYTE)
18750 return 1;
18752 return 0;
18756 /* Highlight trailing whitespace, if any, in ROW. */
18758 static void
18759 highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
18761 int used = row->used[TEXT_AREA];
18763 if (used)
18765 struct glyph *start = row->glyphs[TEXT_AREA];
18766 struct glyph *glyph = start + used - 1;
18768 if (row->reversed_p)
18770 /* Right-to-left rows need to be processed in the opposite
18771 direction, so swap the edge pointers. */
18772 glyph = start;
18773 start = row->glyphs[TEXT_AREA] + used - 1;
18776 /* Skip over glyphs inserted to display the cursor at the
18777 end of a line, for extending the face of the last glyph
18778 to the end of the line on terminals, and for truncation
18779 and continuation glyphs. */
18780 if (!row->reversed_p)
18782 while (glyph >= start
18783 && glyph->type == CHAR_GLYPH
18784 && INTEGERP (glyph->object))
18785 --glyph;
18787 else
18789 while (glyph <= start
18790 && glyph->type == CHAR_GLYPH
18791 && INTEGERP (glyph->object))
18792 ++glyph;
18795 /* If last glyph is a space or stretch, and it's trailing
18796 whitespace, set the face of all trailing whitespace glyphs in
18797 IT->glyph_row to `trailing-whitespace'. */
18798 if ((row->reversed_p ? glyph <= start : glyph >= start)
18799 && BUFFERP (glyph->object)
18800 && (glyph->type == STRETCH_GLYPH
18801 || (glyph->type == CHAR_GLYPH
18802 && glyph->u.ch == ' '))
18803 && trailing_whitespace_p (glyph->charpos))
18805 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
18806 if (face_id < 0)
18807 return;
18809 if (!row->reversed_p)
18811 while (glyph >= start
18812 && BUFFERP (glyph->object)
18813 && (glyph->type == STRETCH_GLYPH
18814 || (glyph->type == CHAR_GLYPH
18815 && glyph->u.ch == ' ')))
18816 (glyph--)->face_id = face_id;
18818 else
18820 while (glyph <= start
18821 && BUFFERP (glyph->object)
18822 && (glyph->type == STRETCH_GLYPH
18823 || (glyph->type == CHAR_GLYPH
18824 && glyph->u.ch == ' ')))
18825 (glyph++)->face_id = face_id;
18832 /* Value is non-zero if glyph row ROW should be
18833 considered to hold the buffer position CHARPOS. */
18835 static int
18836 row_for_charpos_p (struct glyph_row *row, ptrdiff_t charpos)
18838 int result = 1;
18840 if (charpos == CHARPOS (row->end.pos)
18841 || charpos == MATRIX_ROW_END_CHARPOS (row))
18843 /* Suppose the row ends on a string.
18844 Unless the row is continued, that means it ends on a newline
18845 in the string. If it's anything other than a display string
18846 (e.g., a before-string from an overlay), we don't want the
18847 cursor there. (This heuristic seems to give the optimal
18848 behavior for the various types of multi-line strings.)
18849 One exception: if the string has `cursor' property on one of
18850 its characters, we _do_ want the cursor there. */
18851 if (CHARPOS (row->end.string_pos) >= 0)
18853 if (row->continued_p)
18854 result = 1;
18855 else
18857 /* Check for `display' property. */
18858 struct glyph *beg = row->glyphs[TEXT_AREA];
18859 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
18860 struct glyph *glyph;
18862 result = 0;
18863 for (glyph = end; glyph >= beg; --glyph)
18864 if (STRINGP (glyph->object))
18866 Lisp_Object prop
18867 = Fget_char_property (make_number (charpos),
18868 Qdisplay, Qnil);
18869 result =
18870 (!NILP (prop)
18871 && display_prop_string_p (prop, glyph->object));
18872 /* If there's a `cursor' property on one of the
18873 string's characters, this row is a cursor row,
18874 even though this is not a display string. */
18875 if (!result)
18877 Lisp_Object s = glyph->object;
18879 for ( ; glyph >= beg && EQ (glyph->object, s); --glyph)
18881 ptrdiff_t gpos = glyph->charpos;
18883 if (!NILP (Fget_char_property (make_number (gpos),
18884 Qcursor, s)))
18886 result = 1;
18887 break;
18891 break;
18895 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
18897 /* If the row ends in middle of a real character,
18898 and the line is continued, we want the cursor here.
18899 That's because CHARPOS (ROW->end.pos) would equal
18900 PT if PT is before the character. */
18901 if (!row->ends_in_ellipsis_p)
18902 result = row->continued_p;
18903 else
18904 /* If the row ends in an ellipsis, then
18905 CHARPOS (ROW->end.pos) will equal point after the
18906 invisible text. We want that position to be displayed
18907 after the ellipsis. */
18908 result = 0;
18910 /* If the row ends at ZV, display the cursor at the end of that
18911 row instead of at the start of the row below. */
18912 else if (row->ends_at_zv_p)
18913 result = 1;
18914 else
18915 result = 0;
18918 return result;
18921 /* Value is non-zero if glyph row ROW should be
18922 used to hold the cursor. */
18924 static int
18925 cursor_row_p (struct glyph_row *row)
18927 return row_for_charpos_p (row, PT);
18932 /* Push the property PROP so that it will be rendered at the current
18933 position in IT. Return 1 if PROP was successfully pushed, 0
18934 otherwise. Called from handle_line_prefix to handle the
18935 `line-prefix' and `wrap-prefix' properties. */
18937 static int
18938 push_prefix_prop (struct it *it, Lisp_Object prop)
18940 struct text_pos pos =
18941 STRINGP (it->string) ? it->current.string_pos : it->current.pos;
18943 eassert (it->method == GET_FROM_BUFFER
18944 || it->method == GET_FROM_DISPLAY_VECTOR
18945 || it->method == GET_FROM_STRING);
18947 /* We need to save the current buffer/string position, so it will be
18948 restored by pop_it, because iterate_out_of_display_property
18949 depends on that being set correctly, but some situations leave
18950 it->position not yet set when this function is called. */
18951 push_it (it, &pos);
18953 if (STRINGP (prop))
18955 if (SCHARS (prop) == 0)
18957 pop_it (it);
18958 return 0;
18961 it->string = prop;
18962 it->string_from_prefix_prop_p = 1;
18963 it->multibyte_p = STRING_MULTIBYTE (it->string);
18964 it->current.overlay_string_index = -1;
18965 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
18966 it->end_charpos = it->string_nchars = SCHARS (it->string);
18967 it->method = GET_FROM_STRING;
18968 it->stop_charpos = 0;
18969 it->prev_stop = 0;
18970 it->base_level_stop = 0;
18972 /* Force paragraph direction to be that of the parent
18973 buffer/string. */
18974 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
18975 it->paragraph_embedding = it->bidi_it.paragraph_dir;
18976 else
18977 it->paragraph_embedding = L2R;
18979 /* Set up the bidi iterator for this display string. */
18980 if (it->bidi_p)
18982 it->bidi_it.string.lstring = it->string;
18983 it->bidi_it.string.s = NULL;
18984 it->bidi_it.string.schars = it->end_charpos;
18985 it->bidi_it.string.bufpos = IT_CHARPOS (*it);
18986 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
18987 it->bidi_it.string.unibyte = !it->multibyte_p;
18988 it->bidi_it.w = it->w;
18989 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
18992 else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
18994 it->method = GET_FROM_STRETCH;
18995 it->object = prop;
18997 #ifdef HAVE_WINDOW_SYSTEM
18998 else if (IMAGEP (prop))
19000 it->what = IT_IMAGE;
19001 it->image_id = lookup_image (it->f, prop);
19002 it->method = GET_FROM_IMAGE;
19004 #endif /* HAVE_WINDOW_SYSTEM */
19005 else
19007 pop_it (it); /* bogus display property, give up */
19008 return 0;
19011 return 1;
19014 /* Return the character-property PROP at the current position in IT. */
19016 static Lisp_Object
19017 get_it_property (struct it *it, Lisp_Object prop)
19019 Lisp_Object position, object = it->object;
19021 if (STRINGP (object))
19022 position = make_number (IT_STRING_CHARPOS (*it));
19023 else if (BUFFERP (object))
19025 position = make_number (IT_CHARPOS (*it));
19026 object = it->window;
19028 else
19029 return Qnil;
19031 return Fget_char_property (position, prop, object);
19034 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
19036 static void
19037 handle_line_prefix (struct it *it)
19039 Lisp_Object prefix;
19041 if (it->continuation_lines_width > 0)
19043 prefix = get_it_property (it, Qwrap_prefix);
19044 if (NILP (prefix))
19045 prefix = Vwrap_prefix;
19047 else
19049 prefix = get_it_property (it, Qline_prefix);
19050 if (NILP (prefix))
19051 prefix = Vline_prefix;
19053 if (! NILP (prefix) && push_prefix_prop (it, prefix))
19055 /* If the prefix is wider than the window, and we try to wrap
19056 it, it would acquire its own wrap prefix, and so on till the
19057 iterator stack overflows. So, don't wrap the prefix. */
19058 it->line_wrap = TRUNCATE;
19059 it->avoid_cursor_p = 1;
19065 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
19066 only for R2L lines from display_line and display_string, when they
19067 decide that too many glyphs were produced by PRODUCE_GLYPHS, and
19068 the line/string needs to be continued on the next glyph row. */
19069 static void
19070 unproduce_glyphs (struct it *it, int n)
19072 struct glyph *glyph, *end;
19074 eassert (it->glyph_row);
19075 eassert (it->glyph_row->reversed_p);
19076 eassert (it->area == TEXT_AREA);
19077 eassert (n <= it->glyph_row->used[TEXT_AREA]);
19079 if (n > it->glyph_row->used[TEXT_AREA])
19080 n = it->glyph_row->used[TEXT_AREA];
19081 glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
19082 end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
19083 for ( ; glyph < end; glyph++)
19084 glyph[-n] = *glyph;
19087 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
19088 and ROW->maxpos. */
19089 static void
19090 find_row_edges (struct it *it, struct glyph_row *row,
19091 ptrdiff_t min_pos, ptrdiff_t min_bpos,
19092 ptrdiff_t max_pos, ptrdiff_t max_bpos)
19094 /* FIXME: Revisit this when glyph ``spilling'' in continuation
19095 lines' rows is implemented for bidi-reordered rows. */
19097 /* ROW->minpos is the value of min_pos, the minimal buffer position
19098 we have in ROW, or ROW->start.pos if that is smaller. */
19099 if (min_pos <= ZV && min_pos < row->start.pos.charpos)
19100 SET_TEXT_POS (row->minpos, min_pos, min_bpos);
19101 else
19102 /* We didn't find buffer positions smaller than ROW->start, or
19103 didn't find _any_ valid buffer positions in any of the glyphs,
19104 so we must trust the iterator's computed positions. */
19105 row->minpos = row->start.pos;
19106 if (max_pos <= 0)
19108 max_pos = CHARPOS (it->current.pos);
19109 max_bpos = BYTEPOS (it->current.pos);
19112 /* Here are the various use-cases for ending the row, and the
19113 corresponding values for ROW->maxpos:
19115 Line ends in a newline from buffer eol_pos + 1
19116 Line is continued from buffer max_pos + 1
19117 Line is truncated on right it->current.pos
19118 Line ends in a newline from string max_pos + 1(*)
19119 (*) + 1 only when line ends in a forward scan
19120 Line is continued from string max_pos
19121 Line is continued from display vector max_pos
19122 Line is entirely from a string min_pos == max_pos
19123 Line is entirely from a display vector min_pos == max_pos
19124 Line that ends at ZV ZV
19126 If you discover other use-cases, please add them here as
19127 appropriate. */
19128 if (row->ends_at_zv_p)
19129 row->maxpos = it->current.pos;
19130 else if (row->used[TEXT_AREA])
19132 int seen_this_string = 0;
19133 struct glyph_row *r1 = row - 1;
19135 /* Did we see the same display string on the previous row? */
19136 if (STRINGP (it->object)
19137 /* this is not the first row */
19138 && row > it->w->desired_matrix->rows
19139 /* previous row is not the header line */
19140 && !r1->mode_line_p
19141 /* previous row also ends in a newline from a string */
19142 && r1->ends_in_newline_from_string_p)
19144 struct glyph *start, *end;
19146 /* Search for the last glyph of the previous row that came
19147 from buffer or string. Depending on whether the row is
19148 L2R or R2L, we need to process it front to back or the
19149 other way round. */
19150 if (!r1->reversed_p)
19152 start = r1->glyphs[TEXT_AREA];
19153 end = start + r1->used[TEXT_AREA];
19154 /* Glyphs inserted by redisplay have an integer (zero)
19155 as their object. */
19156 while (end > start
19157 && INTEGERP ((end - 1)->object)
19158 && (end - 1)->charpos <= 0)
19159 --end;
19160 if (end > start)
19162 if (EQ ((end - 1)->object, it->object))
19163 seen_this_string = 1;
19165 else
19166 /* If all the glyphs of the previous row were inserted
19167 by redisplay, it means the previous row was
19168 produced from a single newline, which is only
19169 possible if that newline came from the same string
19170 as the one which produced this ROW. */
19171 seen_this_string = 1;
19173 else
19175 end = r1->glyphs[TEXT_AREA] - 1;
19176 start = end + r1->used[TEXT_AREA];
19177 while (end < start
19178 && INTEGERP ((end + 1)->object)
19179 && (end + 1)->charpos <= 0)
19180 ++end;
19181 if (end < start)
19183 if (EQ ((end + 1)->object, it->object))
19184 seen_this_string = 1;
19186 else
19187 seen_this_string = 1;
19190 /* Take note of each display string that covers a newline only
19191 once, the first time we see it. This is for when a display
19192 string includes more than one newline in it. */
19193 if (row->ends_in_newline_from_string_p && !seen_this_string)
19195 /* If we were scanning the buffer forward when we displayed
19196 the string, we want to account for at least one buffer
19197 position that belongs to this row (position covered by
19198 the display string), so that cursor positioning will
19199 consider this row as a candidate when point is at the end
19200 of the visual line represented by this row. This is not
19201 required when scanning back, because max_pos will already
19202 have a much larger value. */
19203 if (CHARPOS (row->end.pos) > max_pos)
19204 INC_BOTH (max_pos, max_bpos);
19205 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19207 else if (CHARPOS (it->eol_pos) > 0)
19208 SET_TEXT_POS (row->maxpos,
19209 CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
19210 else if (row->continued_p)
19212 /* If max_pos is different from IT's current position, it
19213 means IT->method does not belong to the display element
19214 at max_pos. However, it also means that the display
19215 element at max_pos was displayed in its entirety on this
19216 line, which is equivalent to saying that the next line
19217 starts at the next buffer position. */
19218 if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
19219 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19220 else
19222 INC_BOTH (max_pos, max_bpos);
19223 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19226 else if (row->truncated_on_right_p)
19227 /* display_line already called reseat_at_next_visible_line_start,
19228 which puts the iterator at the beginning of the next line, in
19229 the logical order. */
19230 row->maxpos = it->current.pos;
19231 else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
19232 /* A line that is entirely from a string/image/stretch... */
19233 row->maxpos = row->minpos;
19234 else
19235 emacs_abort ();
19237 else
19238 row->maxpos = it->current.pos;
19241 /* Construct the glyph row IT->glyph_row in the desired matrix of
19242 IT->w from text at the current position of IT. See dispextern.h
19243 for an overview of struct it. Value is non-zero if
19244 IT->glyph_row displays text, as opposed to a line displaying ZV
19245 only. */
19247 static int
19248 display_line (struct it *it)
19250 struct glyph_row *row = it->glyph_row;
19251 Lisp_Object overlay_arrow_string;
19252 struct it wrap_it;
19253 void *wrap_data = NULL;
19254 int may_wrap = 0, wrap_x IF_LINT (= 0);
19255 int wrap_row_used = -1;
19256 int wrap_row_ascent IF_LINT (= 0), wrap_row_height IF_LINT (= 0);
19257 int wrap_row_phys_ascent IF_LINT (= 0), wrap_row_phys_height IF_LINT (= 0);
19258 int wrap_row_extra_line_spacing IF_LINT (= 0);
19259 ptrdiff_t wrap_row_min_pos IF_LINT (= 0), wrap_row_min_bpos IF_LINT (= 0);
19260 ptrdiff_t wrap_row_max_pos IF_LINT (= 0), wrap_row_max_bpos IF_LINT (= 0);
19261 int cvpos;
19262 ptrdiff_t min_pos = ZV + 1, max_pos = 0;
19263 ptrdiff_t min_bpos IF_LINT (= 0), max_bpos IF_LINT (= 0);
19265 /* We always start displaying at hpos zero even if hscrolled. */
19266 eassert (it->hpos == 0 && it->current_x == 0);
19268 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
19269 >= it->w->desired_matrix->nrows)
19271 it->w->nrows_scale_factor++;
19272 fonts_changed_p = 1;
19273 return 0;
19276 /* Is IT->w showing the region? */
19277 it->w->region_showing = it->region_beg_charpos > 0 ? it->region_beg_charpos : 0;
19279 /* Clear the result glyph row and enable it. */
19280 prepare_desired_row (row);
19282 row->y = it->current_y;
19283 row->start = it->start;
19284 row->continuation_lines_width = it->continuation_lines_width;
19285 row->displays_text_p = 1;
19286 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
19287 it->starts_in_middle_of_char_p = 0;
19289 /* Arrange the overlays nicely for our purposes. Usually, we call
19290 display_line on only one line at a time, in which case this
19291 can't really hurt too much, or we call it on lines which appear
19292 one after another in the buffer, in which case all calls to
19293 recenter_overlay_lists but the first will be pretty cheap. */
19294 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
19296 /* Move over display elements that are not visible because we are
19297 hscrolled. This may stop at an x-position < IT->first_visible_x
19298 if the first glyph is partially visible or if we hit a line end. */
19299 if (it->current_x < it->first_visible_x)
19301 enum move_it_result move_result;
19303 this_line_min_pos = row->start.pos;
19304 move_result = move_it_in_display_line_to (it, ZV, it->first_visible_x,
19305 MOVE_TO_POS | MOVE_TO_X);
19306 /* If we are under a large hscroll, move_it_in_display_line_to
19307 could hit the end of the line without reaching
19308 it->first_visible_x. Pretend that we did reach it. This is
19309 especially important on a TTY, where we will call
19310 extend_face_to_end_of_line, which needs to know how many
19311 blank glyphs to produce. */
19312 if (it->current_x < it->first_visible_x
19313 && (move_result == MOVE_NEWLINE_OR_CR
19314 || move_result == MOVE_POS_MATCH_OR_ZV))
19315 it->current_x = it->first_visible_x;
19317 /* Record the smallest positions seen while we moved over
19318 display elements that are not visible. This is needed by
19319 redisplay_internal for optimizing the case where the cursor
19320 stays inside the same line. The rest of this function only
19321 considers positions that are actually displayed, so
19322 RECORD_MAX_MIN_POS will not otherwise record positions that
19323 are hscrolled to the left of the left edge of the window. */
19324 min_pos = CHARPOS (this_line_min_pos);
19325 min_bpos = BYTEPOS (this_line_min_pos);
19327 else
19329 /* We only do this when not calling `move_it_in_display_line_to'
19330 above, because move_it_in_display_line_to calls
19331 handle_line_prefix itself. */
19332 handle_line_prefix (it);
19335 /* Get the initial row height. This is either the height of the
19336 text hscrolled, if there is any, or zero. */
19337 row->ascent = it->max_ascent;
19338 row->height = it->max_ascent + it->max_descent;
19339 row->phys_ascent = it->max_phys_ascent;
19340 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
19341 row->extra_line_spacing = it->max_extra_line_spacing;
19343 /* Utility macro to record max and min buffer positions seen until now. */
19344 #define RECORD_MAX_MIN_POS(IT) \
19345 do \
19347 int composition_p = !STRINGP ((IT)->string) \
19348 && ((IT)->what == IT_COMPOSITION); \
19349 ptrdiff_t current_pos = \
19350 composition_p ? (IT)->cmp_it.charpos \
19351 : IT_CHARPOS (*(IT)); \
19352 ptrdiff_t current_bpos = \
19353 composition_p ? CHAR_TO_BYTE (current_pos) \
19354 : IT_BYTEPOS (*(IT)); \
19355 if (current_pos < min_pos) \
19357 min_pos = current_pos; \
19358 min_bpos = current_bpos; \
19360 if (IT_CHARPOS (*it) > max_pos) \
19362 max_pos = IT_CHARPOS (*it); \
19363 max_bpos = IT_BYTEPOS (*it); \
19366 while (0)
19368 /* Loop generating characters. The loop is left with IT on the next
19369 character to display. */
19370 while (1)
19372 int n_glyphs_before, hpos_before, x_before;
19373 int x, nglyphs;
19374 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
19376 /* Retrieve the next thing to display. Value is zero if end of
19377 buffer reached. */
19378 if (!get_next_display_element (it))
19380 /* Maybe add a space at the end of this line that is used to
19381 display the cursor there under X. Set the charpos of the
19382 first glyph of blank lines not corresponding to any text
19383 to -1. */
19384 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19385 row->exact_window_width_line_p = 1;
19386 else if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
19387 || row->used[TEXT_AREA] == 0)
19389 row->glyphs[TEXT_AREA]->charpos = -1;
19390 row->displays_text_p = 0;
19392 if (!NILP (BVAR (XBUFFER (it->w->contents), indicate_empty_lines))
19393 && (!MINI_WINDOW_P (it->w)
19394 || (minibuf_level && EQ (it->window, minibuf_window))))
19395 row->indicate_empty_line_p = 1;
19398 it->continuation_lines_width = 0;
19399 row->ends_at_zv_p = 1;
19400 /* A row that displays right-to-left text must always have
19401 its last face extended all the way to the end of line,
19402 even if this row ends in ZV, because we still write to
19403 the screen left to right. We also need to extend the
19404 last face if the default face is remapped to some
19405 different face, otherwise the functions that clear
19406 portions of the screen will clear with the default face's
19407 background color. */
19408 if (row->reversed_p
19409 || lookup_basic_face (it->f, DEFAULT_FACE_ID) != DEFAULT_FACE_ID)
19410 extend_face_to_end_of_line (it);
19411 break;
19414 /* Now, get the metrics of what we want to display. This also
19415 generates glyphs in `row' (which is IT->glyph_row). */
19416 n_glyphs_before = row->used[TEXT_AREA];
19417 x = it->current_x;
19419 /* Remember the line height so far in case the next element doesn't
19420 fit on the line. */
19421 if (it->line_wrap != TRUNCATE)
19423 ascent = it->max_ascent;
19424 descent = it->max_descent;
19425 phys_ascent = it->max_phys_ascent;
19426 phys_descent = it->max_phys_descent;
19428 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
19430 if (IT_DISPLAYING_WHITESPACE (it))
19431 may_wrap = 1;
19432 else if (may_wrap)
19434 SAVE_IT (wrap_it, *it, wrap_data);
19435 wrap_x = x;
19436 wrap_row_used = row->used[TEXT_AREA];
19437 wrap_row_ascent = row->ascent;
19438 wrap_row_height = row->height;
19439 wrap_row_phys_ascent = row->phys_ascent;
19440 wrap_row_phys_height = row->phys_height;
19441 wrap_row_extra_line_spacing = row->extra_line_spacing;
19442 wrap_row_min_pos = min_pos;
19443 wrap_row_min_bpos = min_bpos;
19444 wrap_row_max_pos = max_pos;
19445 wrap_row_max_bpos = max_bpos;
19446 may_wrap = 0;
19451 PRODUCE_GLYPHS (it);
19453 /* If this display element was in marginal areas, continue with
19454 the next one. */
19455 if (it->area != TEXT_AREA)
19457 row->ascent = max (row->ascent, it->max_ascent);
19458 row->height = max (row->height, it->max_ascent + it->max_descent);
19459 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19460 row->phys_height = max (row->phys_height,
19461 it->max_phys_ascent + it->max_phys_descent);
19462 row->extra_line_spacing = max (row->extra_line_spacing,
19463 it->max_extra_line_spacing);
19464 set_iterator_to_next (it, 1);
19465 continue;
19468 /* Does the display element fit on the line? If we truncate
19469 lines, we should draw past the right edge of the window. If
19470 we don't truncate, we want to stop so that we can display the
19471 continuation glyph before the right margin. If lines are
19472 continued, there are two possible strategies for characters
19473 resulting in more than 1 glyph (e.g. tabs): Display as many
19474 glyphs as possible in this line and leave the rest for the
19475 continuation line, or display the whole element in the next
19476 line. Original redisplay did the former, so we do it also. */
19477 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
19478 hpos_before = it->hpos;
19479 x_before = x;
19481 if (/* Not a newline. */
19482 nglyphs > 0
19483 /* Glyphs produced fit entirely in the line. */
19484 && it->current_x < it->last_visible_x)
19486 it->hpos += nglyphs;
19487 row->ascent = max (row->ascent, it->max_ascent);
19488 row->height = max (row->height, it->max_ascent + it->max_descent);
19489 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19490 row->phys_height = max (row->phys_height,
19491 it->max_phys_ascent + it->max_phys_descent);
19492 row->extra_line_spacing = max (row->extra_line_spacing,
19493 it->max_extra_line_spacing);
19494 if (it->current_x - it->pixel_width < it->first_visible_x)
19495 row->x = x - it->first_visible_x;
19496 /* Record the maximum and minimum buffer positions seen so
19497 far in glyphs that will be displayed by this row. */
19498 if (it->bidi_p)
19499 RECORD_MAX_MIN_POS (it);
19501 else
19503 int i, new_x;
19504 struct glyph *glyph;
19506 for (i = 0; i < nglyphs; ++i, x = new_x)
19508 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
19509 new_x = x + glyph->pixel_width;
19511 if (/* Lines are continued. */
19512 it->line_wrap != TRUNCATE
19513 && (/* Glyph doesn't fit on the line. */
19514 new_x > it->last_visible_x
19515 /* Or it fits exactly on a window system frame. */
19516 || (new_x == it->last_visible_x
19517 && FRAME_WINDOW_P (it->f)
19518 && (row->reversed_p
19519 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19520 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
19522 /* End of a continued line. */
19524 if (it->hpos == 0
19525 || (new_x == it->last_visible_x
19526 && FRAME_WINDOW_P (it->f)
19527 && (row->reversed_p
19528 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19529 : WINDOW_RIGHT_FRINGE_WIDTH (it->w))))
19531 /* Current glyph is the only one on the line or
19532 fits exactly on the line. We must continue
19533 the line because we can't draw the cursor
19534 after the glyph. */
19535 row->continued_p = 1;
19536 it->current_x = new_x;
19537 it->continuation_lines_width += new_x;
19538 ++it->hpos;
19539 if (i == nglyphs - 1)
19541 /* If line-wrap is on, check if a previous
19542 wrap point was found. */
19543 if (wrap_row_used > 0
19544 /* Even if there is a previous wrap
19545 point, continue the line here as
19546 usual, if (i) the previous character
19547 was a space or tab AND (ii) the
19548 current character is not. */
19549 && (!may_wrap
19550 || IT_DISPLAYING_WHITESPACE (it)))
19551 goto back_to_wrap;
19553 /* Record the maximum and minimum buffer
19554 positions seen so far in glyphs that will be
19555 displayed by this row. */
19556 if (it->bidi_p)
19557 RECORD_MAX_MIN_POS (it);
19558 set_iterator_to_next (it, 1);
19559 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19561 if (!get_next_display_element (it))
19563 row->exact_window_width_line_p = 1;
19564 it->continuation_lines_width = 0;
19565 row->continued_p = 0;
19566 row->ends_at_zv_p = 1;
19568 else if (ITERATOR_AT_END_OF_LINE_P (it))
19570 row->continued_p = 0;
19571 row->exact_window_width_line_p = 1;
19575 else if (it->bidi_p)
19576 RECORD_MAX_MIN_POS (it);
19578 else if (CHAR_GLYPH_PADDING_P (*glyph)
19579 && !FRAME_WINDOW_P (it->f))
19581 /* A padding glyph that doesn't fit on this line.
19582 This means the whole character doesn't fit
19583 on the line. */
19584 if (row->reversed_p)
19585 unproduce_glyphs (it, row->used[TEXT_AREA]
19586 - n_glyphs_before);
19587 row->used[TEXT_AREA] = n_glyphs_before;
19589 /* Fill the rest of the row with continuation
19590 glyphs like in 20.x. */
19591 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
19592 < row->glyphs[1 + TEXT_AREA])
19593 produce_special_glyphs (it, IT_CONTINUATION);
19595 row->continued_p = 1;
19596 it->current_x = x_before;
19597 it->continuation_lines_width += x_before;
19599 /* Restore the height to what it was before the
19600 element not fitting on the line. */
19601 it->max_ascent = ascent;
19602 it->max_descent = descent;
19603 it->max_phys_ascent = phys_ascent;
19604 it->max_phys_descent = phys_descent;
19606 else if (wrap_row_used > 0)
19608 back_to_wrap:
19609 if (row->reversed_p)
19610 unproduce_glyphs (it,
19611 row->used[TEXT_AREA] - wrap_row_used);
19612 RESTORE_IT (it, &wrap_it, wrap_data);
19613 it->continuation_lines_width += wrap_x;
19614 row->used[TEXT_AREA] = wrap_row_used;
19615 row->ascent = wrap_row_ascent;
19616 row->height = wrap_row_height;
19617 row->phys_ascent = wrap_row_phys_ascent;
19618 row->phys_height = wrap_row_phys_height;
19619 row->extra_line_spacing = wrap_row_extra_line_spacing;
19620 min_pos = wrap_row_min_pos;
19621 min_bpos = wrap_row_min_bpos;
19622 max_pos = wrap_row_max_pos;
19623 max_bpos = wrap_row_max_bpos;
19624 row->continued_p = 1;
19625 row->ends_at_zv_p = 0;
19626 row->exact_window_width_line_p = 0;
19627 it->continuation_lines_width += x;
19629 /* Make sure that a non-default face is extended
19630 up to the right margin of the window. */
19631 extend_face_to_end_of_line (it);
19633 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
19635 /* A TAB that extends past the right edge of the
19636 window. This produces a single glyph on
19637 window system frames. We leave the glyph in
19638 this row and let it fill the row, but don't
19639 consume the TAB. */
19640 if ((row->reversed_p
19641 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19642 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
19643 produce_special_glyphs (it, IT_CONTINUATION);
19644 it->continuation_lines_width += it->last_visible_x;
19645 row->ends_in_middle_of_char_p = 1;
19646 row->continued_p = 1;
19647 glyph->pixel_width = it->last_visible_x - x;
19648 it->starts_in_middle_of_char_p = 1;
19650 else
19652 /* Something other than a TAB that draws past
19653 the right edge of the window. Restore
19654 positions to values before the element. */
19655 if (row->reversed_p)
19656 unproduce_glyphs (it, row->used[TEXT_AREA]
19657 - (n_glyphs_before + i));
19658 row->used[TEXT_AREA] = n_glyphs_before + i;
19660 /* Display continuation glyphs. */
19661 it->current_x = x_before;
19662 it->continuation_lines_width += x;
19663 if (!FRAME_WINDOW_P (it->f)
19664 || (row->reversed_p
19665 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19666 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
19667 produce_special_glyphs (it, IT_CONTINUATION);
19668 row->continued_p = 1;
19670 extend_face_to_end_of_line (it);
19672 if (nglyphs > 1 && i > 0)
19674 row->ends_in_middle_of_char_p = 1;
19675 it->starts_in_middle_of_char_p = 1;
19678 /* Restore the height to what it was before the
19679 element not fitting on the line. */
19680 it->max_ascent = ascent;
19681 it->max_descent = descent;
19682 it->max_phys_ascent = phys_ascent;
19683 it->max_phys_descent = phys_descent;
19686 break;
19688 else if (new_x > it->first_visible_x)
19690 /* Increment number of glyphs actually displayed. */
19691 ++it->hpos;
19693 /* Record the maximum and minimum buffer positions
19694 seen so far in glyphs that will be displayed by
19695 this row. */
19696 if (it->bidi_p)
19697 RECORD_MAX_MIN_POS (it);
19699 if (x < it->first_visible_x)
19700 /* Glyph is partially visible, i.e. row starts at
19701 negative X position. */
19702 row->x = x - it->first_visible_x;
19704 else
19706 /* Glyph is completely off the left margin of the
19707 window. This should not happen because of the
19708 move_it_in_display_line at the start of this
19709 function, unless the text display area of the
19710 window is empty. */
19711 eassert (it->first_visible_x <= it->last_visible_x);
19714 /* Even if this display element produced no glyphs at all,
19715 we want to record its position. */
19716 if (it->bidi_p && nglyphs == 0)
19717 RECORD_MAX_MIN_POS (it);
19719 row->ascent = max (row->ascent, it->max_ascent);
19720 row->height = max (row->height, it->max_ascent + it->max_descent);
19721 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19722 row->phys_height = max (row->phys_height,
19723 it->max_phys_ascent + it->max_phys_descent);
19724 row->extra_line_spacing = max (row->extra_line_spacing,
19725 it->max_extra_line_spacing);
19727 /* End of this display line if row is continued. */
19728 if (row->continued_p || row->ends_at_zv_p)
19729 break;
19732 at_end_of_line:
19733 /* Is this a line end? If yes, we're also done, after making
19734 sure that a non-default face is extended up to the right
19735 margin of the window. */
19736 if (ITERATOR_AT_END_OF_LINE_P (it))
19738 int used_before = row->used[TEXT_AREA];
19740 row->ends_in_newline_from_string_p = STRINGP (it->object);
19742 /* Add a space at the end of the line that is used to
19743 display the cursor there. */
19744 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19745 append_space_for_newline (it, 0);
19747 /* Extend the face to the end of the line. */
19748 extend_face_to_end_of_line (it);
19750 /* Make sure we have the position. */
19751 if (used_before == 0)
19752 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
19754 /* Record the position of the newline, for use in
19755 find_row_edges. */
19756 it->eol_pos = it->current.pos;
19758 /* Consume the line end. This skips over invisible lines. */
19759 set_iterator_to_next (it, 1);
19760 it->continuation_lines_width = 0;
19761 break;
19764 /* Proceed with next display element. Note that this skips
19765 over lines invisible because of selective display. */
19766 set_iterator_to_next (it, 1);
19768 /* If we truncate lines, we are done when the last displayed
19769 glyphs reach past the right margin of the window. */
19770 if (it->line_wrap == TRUNCATE
19771 && (FRAME_WINDOW_P (it->f) && WINDOW_RIGHT_FRINGE_WIDTH (it->w)
19772 ? (it->current_x >= it->last_visible_x)
19773 : (it->current_x > it->last_visible_x)))
19775 /* Maybe add truncation glyphs. */
19776 if (!FRAME_WINDOW_P (it->f)
19777 || (row->reversed_p
19778 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19779 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
19781 int i, n;
19783 if (!row->reversed_p)
19785 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
19786 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
19787 break;
19789 else
19791 for (i = 0; i < row->used[TEXT_AREA]; i++)
19792 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
19793 break;
19794 /* Remove any padding glyphs at the front of ROW, to
19795 make room for the truncation glyphs we will be
19796 adding below. The loop below always inserts at
19797 least one truncation glyph, so also remove the
19798 last glyph added to ROW. */
19799 unproduce_glyphs (it, i + 1);
19800 /* Adjust i for the loop below. */
19801 i = row->used[TEXT_AREA] - (i + 1);
19804 it->current_x = x_before;
19805 if (!FRAME_WINDOW_P (it->f))
19807 for (n = row->used[TEXT_AREA]; i < n; ++i)
19809 row->used[TEXT_AREA] = i;
19810 produce_special_glyphs (it, IT_TRUNCATION);
19813 else
19815 row->used[TEXT_AREA] = i;
19816 produce_special_glyphs (it, IT_TRUNCATION);
19819 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19821 /* Don't truncate if we can overflow newline into fringe. */
19822 if (!get_next_display_element (it))
19824 it->continuation_lines_width = 0;
19825 row->ends_at_zv_p = 1;
19826 row->exact_window_width_line_p = 1;
19827 break;
19829 if (ITERATOR_AT_END_OF_LINE_P (it))
19831 row->exact_window_width_line_p = 1;
19832 goto at_end_of_line;
19834 it->current_x = x_before;
19837 row->truncated_on_right_p = 1;
19838 it->continuation_lines_width = 0;
19839 reseat_at_next_visible_line_start (it, 0);
19840 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
19841 it->hpos = hpos_before;
19842 break;
19846 if (wrap_data)
19847 bidi_unshelve_cache (wrap_data, 1);
19849 /* If line is not empty and hscrolled, maybe insert truncation glyphs
19850 at the left window margin. */
19851 if (it->first_visible_x
19852 && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
19854 if (!FRAME_WINDOW_P (it->f)
19855 || (row->reversed_p
19856 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
19857 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
19858 insert_left_trunc_glyphs (it);
19859 row->truncated_on_left_p = 1;
19862 /* Remember the position at which this line ends.
19864 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
19865 cannot be before the call to find_row_edges below, since that is
19866 where these positions are determined. */
19867 row->end = it->current;
19868 if (!it->bidi_p)
19870 row->minpos = row->start.pos;
19871 row->maxpos = row->end.pos;
19873 else
19875 /* ROW->minpos and ROW->maxpos must be the smallest and
19876 `1 + the largest' buffer positions in ROW. But if ROW was
19877 bidi-reordered, these two positions can be anywhere in the
19878 row, so we must determine them now. */
19879 find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
19882 /* If the start of this line is the overlay arrow-position, then
19883 mark this glyph row as the one containing the overlay arrow.
19884 This is clearly a mess with variable size fonts. It would be
19885 better to let it be displayed like cursors under X. */
19886 if ((MATRIX_ROW_DISPLAYS_TEXT_P (row) || !overlay_arrow_seen)
19887 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
19888 !NILP (overlay_arrow_string)))
19890 /* Overlay arrow in window redisplay is a fringe bitmap. */
19891 if (STRINGP (overlay_arrow_string))
19893 struct glyph_row *arrow_row
19894 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
19895 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
19896 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
19897 struct glyph *p = row->glyphs[TEXT_AREA];
19898 struct glyph *p2, *end;
19900 /* Copy the arrow glyphs. */
19901 while (glyph < arrow_end)
19902 *p++ = *glyph++;
19904 /* Throw away padding glyphs. */
19905 p2 = p;
19906 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
19907 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
19908 ++p2;
19909 if (p2 > p)
19911 while (p2 < end)
19912 *p++ = *p2++;
19913 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
19916 else
19918 eassert (INTEGERP (overlay_arrow_string));
19919 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
19921 overlay_arrow_seen = 1;
19924 /* Highlight trailing whitespace. */
19925 if (!NILP (Vshow_trailing_whitespace))
19926 highlight_trailing_whitespace (it->f, it->glyph_row);
19928 /* Compute pixel dimensions of this line. */
19929 compute_line_metrics (it);
19931 /* Implementation note: No changes in the glyphs of ROW or in their
19932 faces can be done past this point, because compute_line_metrics
19933 computes ROW's hash value and stores it within the glyph_row
19934 structure. */
19936 /* Record whether this row ends inside an ellipsis. */
19937 row->ends_in_ellipsis_p
19938 = (it->method == GET_FROM_DISPLAY_VECTOR
19939 && it->ellipsis_p);
19941 /* Save fringe bitmaps in this row. */
19942 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
19943 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
19944 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
19945 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
19947 it->left_user_fringe_bitmap = 0;
19948 it->left_user_fringe_face_id = 0;
19949 it->right_user_fringe_bitmap = 0;
19950 it->right_user_fringe_face_id = 0;
19952 /* Maybe set the cursor. */
19953 cvpos = it->w->cursor.vpos;
19954 if ((cvpos < 0
19955 /* In bidi-reordered rows, keep checking for proper cursor
19956 position even if one has been found already, because buffer
19957 positions in such rows change non-linearly with ROW->VPOS,
19958 when a line is continued. One exception: when we are at ZV,
19959 display cursor on the first suitable glyph row, since all
19960 the empty rows after that also have their position set to ZV. */
19961 /* FIXME: Revisit this when glyph ``spilling'' in continuation
19962 lines' rows is implemented for bidi-reordered rows. */
19963 || (it->bidi_p
19964 && !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
19965 && PT >= MATRIX_ROW_START_CHARPOS (row)
19966 && PT <= MATRIX_ROW_END_CHARPOS (row)
19967 && cursor_row_p (row))
19968 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
19970 /* Prepare for the next line. This line starts horizontally at (X
19971 HPOS) = (0 0). Vertical positions are incremented. As a
19972 convenience for the caller, IT->glyph_row is set to the next
19973 row to be used. */
19974 it->current_x = it->hpos = 0;
19975 it->current_y += row->height;
19976 SET_TEXT_POS (it->eol_pos, 0, 0);
19977 ++it->vpos;
19978 ++it->glyph_row;
19979 /* The next row should by default use the same value of the
19980 reversed_p flag as this one. set_iterator_to_next decides when
19981 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
19982 the flag accordingly. */
19983 if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
19984 it->glyph_row->reversed_p = row->reversed_p;
19985 it->start = row->end;
19986 return MATRIX_ROW_DISPLAYS_TEXT_P (row);
19988 #undef RECORD_MAX_MIN_POS
19991 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,
19992 Scurrent_bidi_paragraph_direction, 0, 1, 0,
19993 doc: /* Return paragraph direction at point in BUFFER.
19994 Value is either `left-to-right' or `right-to-left'.
19995 If BUFFER is omitted or nil, it defaults to the current buffer.
19997 Paragraph direction determines how the text in the paragraph is displayed.
19998 In left-to-right paragraphs, text begins at the left margin of the window
19999 and the reading direction is generally left to right. In right-to-left
20000 paragraphs, text begins at the right margin and is read from right to left.
20002 See also `bidi-paragraph-direction'. */)
20003 (Lisp_Object buffer)
20005 struct buffer *buf = current_buffer;
20006 struct buffer *old = buf;
20008 if (! NILP (buffer))
20010 CHECK_BUFFER (buffer);
20011 buf = XBUFFER (buffer);
20014 if (NILP (BVAR (buf, bidi_display_reordering))
20015 || NILP (BVAR (buf, enable_multibyte_characters))
20016 /* When we are loading loadup.el, the character property tables
20017 needed for bidi iteration are not yet available. */
20018 || !NILP (Vpurify_flag))
20019 return Qleft_to_right;
20020 else if (!NILP (BVAR (buf, bidi_paragraph_direction)))
20021 return BVAR (buf, bidi_paragraph_direction);
20022 else
20024 /* Determine the direction from buffer text. We could try to
20025 use current_matrix if it is up to date, but this seems fast
20026 enough as it is. */
20027 struct bidi_it itb;
20028 ptrdiff_t pos = BUF_PT (buf);
20029 ptrdiff_t bytepos = BUF_PT_BYTE (buf);
20030 int c;
20031 void *itb_data = bidi_shelve_cache ();
20033 set_buffer_temp (buf);
20034 /* bidi_paragraph_init finds the base direction of the paragraph
20035 by searching forward from paragraph start. We need the base
20036 direction of the current or _previous_ paragraph, so we need
20037 to make sure we are within that paragraph. To that end, find
20038 the previous non-empty line. */
20039 if (pos >= ZV && pos > BEGV)
20040 DEC_BOTH (pos, bytepos);
20041 if (fast_looking_at (build_string ("[\f\t ]*\n"),
20042 pos, bytepos, ZV, ZV_BYTE, Qnil) > 0)
20044 while ((c = FETCH_BYTE (bytepos)) == '\n'
20045 || c == ' ' || c == '\t' || c == '\f')
20047 if (bytepos <= BEGV_BYTE)
20048 break;
20049 bytepos--;
20050 pos--;
20052 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos)))
20053 bytepos--;
20055 bidi_init_it (pos, bytepos, FRAME_WINDOW_P (SELECTED_FRAME ()), &itb);
20056 itb.paragraph_dir = NEUTRAL_DIR;
20057 itb.string.s = NULL;
20058 itb.string.lstring = Qnil;
20059 itb.string.bufpos = 0;
20060 itb.string.unibyte = 0;
20061 /* We have no window to use here for ignoring window-specific
20062 overlays. Using NULL for window pointer will cause
20063 compute_display_string_pos to use the current buffer. */
20064 itb.w = NULL;
20065 bidi_paragraph_init (NEUTRAL_DIR, &itb, 1);
20066 bidi_unshelve_cache (itb_data, 0);
20067 set_buffer_temp (old);
20068 switch (itb.paragraph_dir)
20070 case L2R:
20071 return Qleft_to_right;
20072 break;
20073 case R2L:
20074 return Qright_to_left;
20075 break;
20076 default:
20077 emacs_abort ();
20082 DEFUN ("move-point-visually", Fmove_point_visually,
20083 Smove_point_visually, 1, 1, 0,
20084 doc: /* Move point in the visual order in the specified DIRECTION.
20085 DIRECTION can be 1, meaning move to the right, or -1, which moves to the
20086 left.
20088 Value is the new character position of point. */)
20089 (Lisp_Object direction)
20091 struct window *w = XWINDOW (selected_window);
20092 struct buffer *b = XBUFFER (w->contents);
20093 struct glyph_row *row;
20094 int dir;
20095 Lisp_Object paragraph_dir;
20097 #define ROW_GLYPH_NEWLINE_P(ROW,GLYPH) \
20098 (!(ROW)->continued_p \
20099 && INTEGERP ((GLYPH)->object) \
20100 && (GLYPH)->type == CHAR_GLYPH \
20101 && (GLYPH)->u.ch == ' ' \
20102 && (GLYPH)->charpos >= 0 \
20103 && !(GLYPH)->avoid_cursor_p)
20105 CHECK_NUMBER (direction);
20106 dir = XINT (direction);
20107 if (dir > 0)
20108 dir = 1;
20109 else
20110 dir = -1;
20112 /* If current matrix is up-to-date, we can use the information
20113 recorded in the glyphs, at least as long as the goal is on the
20114 screen. */
20115 if (w->window_end_valid
20116 && !windows_or_buffers_changed
20117 && b
20118 && !b->clip_changed
20119 && !b->prevent_redisplay_optimizations_p
20120 && !window_outdated (w)
20121 && w->cursor.vpos >= 0
20122 && w->cursor.vpos < w->current_matrix->nrows
20123 && (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos))->enabled_p)
20125 struct glyph *g = row->glyphs[TEXT_AREA];
20126 struct glyph *e = dir > 0 ? g + row->used[TEXT_AREA] : g - 1;
20127 struct glyph *gpt = g + w->cursor.hpos;
20129 for (g = gpt + dir; (dir > 0 ? g < e : g > e); g += dir)
20131 if (BUFFERP (g->object) && g->charpos != PT)
20133 SET_PT (g->charpos);
20134 w->cursor.vpos = -1;
20135 return make_number (PT);
20137 else if (!INTEGERP (g->object) && !EQ (g->object, gpt->object))
20139 ptrdiff_t new_pos;
20141 if (BUFFERP (gpt->object))
20143 new_pos = PT;
20144 if ((gpt->resolved_level - row->reversed_p) % 2 == 0)
20145 new_pos += (row->reversed_p ? -dir : dir);
20146 else
20147 new_pos -= (row->reversed_p ? -dir : dir);;
20149 else if (BUFFERP (g->object))
20150 new_pos = g->charpos;
20151 else
20152 break;
20153 SET_PT (new_pos);
20154 w->cursor.vpos = -1;
20155 return make_number (PT);
20157 else if (ROW_GLYPH_NEWLINE_P (row, g))
20159 /* Glyphs inserted at the end of a non-empty line for
20160 positioning the cursor have zero charpos, so we must
20161 deduce the value of point by other means. */
20162 if (g->charpos > 0)
20163 SET_PT (g->charpos);
20164 else if (row->ends_at_zv_p && PT != ZV)
20165 SET_PT (ZV);
20166 else if (PT != MATRIX_ROW_END_CHARPOS (row) - 1)
20167 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
20168 else
20169 break;
20170 w->cursor.vpos = -1;
20171 return make_number (PT);
20174 if (g == e || INTEGERP (g->object))
20176 if (row->truncated_on_left_p || row->truncated_on_right_p)
20177 goto simulate_display;
20178 if (!row->reversed_p)
20179 row += dir;
20180 else
20181 row -= dir;
20182 if (row < MATRIX_FIRST_TEXT_ROW (w->current_matrix)
20183 || row > MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
20184 goto simulate_display;
20186 if (dir > 0)
20188 if (row->reversed_p && !row->continued_p)
20190 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
20191 w->cursor.vpos = -1;
20192 return make_number (PT);
20194 g = row->glyphs[TEXT_AREA];
20195 e = g + row->used[TEXT_AREA];
20196 for ( ; g < e; g++)
20198 if (BUFFERP (g->object)
20199 /* Empty lines have only one glyph, which stands
20200 for the newline, and whose charpos is the
20201 buffer position of the newline. */
20202 || ROW_GLYPH_NEWLINE_P (row, g)
20203 /* When the buffer ends in a newline, the line at
20204 EOB also has one glyph, but its charpos is -1. */
20205 || (row->ends_at_zv_p
20206 && !row->reversed_p
20207 && INTEGERP (g->object)
20208 && g->type == CHAR_GLYPH
20209 && g->u.ch == ' '))
20211 if (g->charpos > 0)
20212 SET_PT (g->charpos);
20213 else if (!row->reversed_p
20214 && row->ends_at_zv_p
20215 && PT != ZV)
20216 SET_PT (ZV);
20217 else
20218 continue;
20219 w->cursor.vpos = -1;
20220 return make_number (PT);
20224 else
20226 if (!row->reversed_p && !row->continued_p)
20228 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
20229 w->cursor.vpos = -1;
20230 return make_number (PT);
20232 e = row->glyphs[TEXT_AREA];
20233 g = e + row->used[TEXT_AREA] - 1;
20234 for ( ; g >= e; g--)
20236 if (BUFFERP (g->object)
20237 || (ROW_GLYPH_NEWLINE_P (row, g)
20238 && g->charpos > 0)
20239 /* Empty R2L lines on GUI frames have the buffer
20240 position of the newline stored in the stretch
20241 glyph. */
20242 || g->type == STRETCH_GLYPH
20243 || (row->ends_at_zv_p
20244 && row->reversed_p
20245 && INTEGERP (g->object)
20246 && g->type == CHAR_GLYPH
20247 && g->u.ch == ' '))
20249 if (g->charpos > 0)
20250 SET_PT (g->charpos);
20251 else if (row->reversed_p
20252 && row->ends_at_zv_p
20253 && PT != ZV)
20254 SET_PT (ZV);
20255 else
20256 continue;
20257 w->cursor.vpos = -1;
20258 return make_number (PT);
20265 simulate_display:
20267 /* If we wind up here, we failed to move by using the glyphs, so we
20268 need to simulate display instead. */
20270 if (b)
20271 paragraph_dir = Fcurrent_bidi_paragraph_direction (w->contents);
20272 else
20273 paragraph_dir = Qleft_to_right;
20274 if (EQ (paragraph_dir, Qright_to_left))
20275 dir = -dir;
20276 if (PT <= BEGV && dir < 0)
20277 xsignal0 (Qbeginning_of_buffer);
20278 else if (PT >= ZV && dir > 0)
20279 xsignal0 (Qend_of_buffer);
20280 else
20282 struct text_pos pt;
20283 struct it it;
20284 int pt_x, target_x, pixel_width, pt_vpos;
20285 bool at_eol_p;
20286 bool overshoot_expected = false;
20287 bool target_is_eol_p = false;
20289 /* Setup the arena. */
20290 SET_TEXT_POS (pt, PT, PT_BYTE);
20291 start_display (&it, w, pt);
20293 if (it.cmp_it.id < 0
20294 && it.method == GET_FROM_STRING
20295 && it.area == TEXT_AREA
20296 && it.string_from_display_prop_p
20297 && (it.sp > 0 && it.stack[it.sp - 1].method == GET_FROM_BUFFER))
20298 overshoot_expected = true;
20300 /* Find the X coordinate of point. We start from the beginning
20301 of this or previous line to make sure we are before point in
20302 the logical order (since the move_it_* functions can only
20303 move forward). */
20304 reseat_at_previous_visible_line_start (&it);
20305 it.current_x = it.hpos = it.current_y = it.vpos = 0;
20306 if (IT_CHARPOS (it) != PT)
20307 move_it_to (&it, overshoot_expected ? PT - 1 : PT,
20308 -1, -1, -1, MOVE_TO_POS);
20309 pt_x = it.current_x;
20310 pt_vpos = it.vpos;
20311 if (dir > 0 || overshoot_expected)
20313 struct glyph_row *row = it.glyph_row;
20315 /* When point is at beginning of line, we don't have
20316 information about the glyph there loaded into struct
20317 it. Calling get_next_display_element fixes that. */
20318 if (pt_x == 0)
20319 get_next_display_element (&it);
20320 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
20321 it.glyph_row = NULL;
20322 PRODUCE_GLYPHS (&it); /* compute it.pixel_width */
20323 it.glyph_row = row;
20324 /* PRODUCE_GLYPHS advances it.current_x, so we must restore
20325 it, lest it will become out of sync with it's buffer
20326 position. */
20327 it.current_x = pt_x;
20329 else
20330 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
20331 pixel_width = it.pixel_width;
20332 if (overshoot_expected && at_eol_p)
20333 pixel_width = 0;
20334 else if (pixel_width <= 0)
20335 pixel_width = 1;
20337 /* If there's a display string at point, we are actually at the
20338 glyph to the left of point, so we need to correct the X
20339 coordinate. */
20340 if (overshoot_expected)
20341 pt_x += pixel_width;
20343 /* Compute target X coordinate, either to the left or to the
20344 right of point. On TTY frames, all characters have the same
20345 pixel width of 1, so we can use that. On GUI frames we don't
20346 have an easy way of getting at the pixel width of the
20347 character to the left of point, so we use a different method
20348 of getting to that place. */
20349 if (dir > 0)
20350 target_x = pt_x + pixel_width;
20351 else
20352 target_x = pt_x - (!FRAME_WINDOW_P (it.f)) * pixel_width;
20354 /* Target X coordinate could be one line above or below the line
20355 of point, in which case we need to adjust the target X
20356 coordinate. Also, if moving to the left, we need to begin at
20357 the left edge of the point's screen line. */
20358 if (dir < 0)
20360 if (pt_x > 0)
20362 start_display (&it, w, pt);
20363 reseat_at_previous_visible_line_start (&it);
20364 it.current_x = it.current_y = it.hpos = 0;
20365 if (pt_vpos != 0)
20366 move_it_by_lines (&it, pt_vpos);
20368 else
20370 move_it_by_lines (&it, -1);
20371 target_x = it.last_visible_x - !FRAME_WINDOW_P (it.f);
20372 target_is_eol_p = true;
20375 else
20377 if (at_eol_p
20378 || (target_x >= it.last_visible_x
20379 && it.line_wrap != TRUNCATE))
20381 if (pt_x > 0)
20382 move_it_by_lines (&it, 0);
20383 move_it_by_lines (&it, 1);
20384 target_x = 0;
20388 /* Move to the target X coordinate. */
20389 #ifdef HAVE_WINDOW_SYSTEM
20390 /* On GUI frames, as we don't know the X coordinate of the
20391 character to the left of point, moving point to the left
20392 requires walking, one grapheme cluster at a time, until we
20393 find ourself at a place immediately to the left of the
20394 character at point. */
20395 if (FRAME_WINDOW_P (it.f) && dir < 0)
20397 struct text_pos new_pos = it.current.pos;
20398 enum move_it_result rc = MOVE_X_REACHED;
20400 while (it.current_x + it.pixel_width <= target_x
20401 && rc == MOVE_X_REACHED)
20403 int new_x = it.current_x + it.pixel_width;
20405 new_pos = it.current.pos;
20406 if (new_x == it.current_x)
20407 new_x++;
20408 rc = move_it_in_display_line_to (&it, ZV, new_x,
20409 MOVE_TO_POS | MOVE_TO_X);
20410 if (ITERATOR_AT_END_OF_LINE_P (&it) && !target_is_eol_p)
20411 break;
20413 /* If we ended up on a composed character inside
20414 bidi-reordered text (e.g., Hebrew text with diacritics),
20415 the iterator gives us the buffer position of the last (in
20416 logical order) character of the composed grapheme cluster,
20417 which is not what we want. So we cheat: we compute the
20418 character position of the character that follows (in the
20419 logical order) the one where the above loop stopped. That
20420 character will appear on display to the left of point. */
20421 if (it.bidi_p
20422 && it.bidi_it.scan_dir == -1
20423 && new_pos.charpos - IT_CHARPOS (it) > 1)
20425 new_pos.charpos = IT_CHARPOS (it) + 1;
20426 new_pos.bytepos = CHAR_TO_BYTE (new_pos.charpos);
20428 it.current.pos = new_pos;
20430 else
20431 #endif
20432 if (it.current_x != target_x)
20433 move_it_in_display_line_to (&it, ZV, target_x, MOVE_TO_POS | MOVE_TO_X);
20435 /* When lines are truncated, the above loop will stop at the
20436 window edge. But we want to get to the end of line, even if
20437 it is beyond the window edge; automatic hscroll will then
20438 scroll the window to show point as appropriate. */
20439 if (target_is_eol_p && it.line_wrap == TRUNCATE
20440 && get_next_display_element (&it))
20442 struct text_pos new_pos = it.current.pos;
20444 while (!ITERATOR_AT_END_OF_LINE_P (&it))
20446 set_iterator_to_next (&it, 0);
20447 if (it.method == GET_FROM_BUFFER)
20448 new_pos = it.current.pos;
20449 if (!get_next_display_element (&it))
20450 break;
20453 it.current.pos = new_pos;
20456 /* If we ended up in a display string that covers point, move to
20457 buffer position to the right in the visual order. */
20458 if (dir > 0)
20460 while (IT_CHARPOS (it) == PT)
20462 set_iterator_to_next (&it, 0);
20463 if (!get_next_display_element (&it))
20464 break;
20468 /* Move point to that position. */
20469 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
20472 return make_number (PT);
20474 #undef ROW_GLYPH_NEWLINE_P
20478 /***********************************************************************
20479 Menu Bar
20480 ***********************************************************************/
20482 /* Redisplay the menu bar in the frame for window W.
20484 The menu bar of X frames that don't have X toolkit support is
20485 displayed in a special window W->frame->menu_bar_window.
20487 The menu bar of terminal frames is treated specially as far as
20488 glyph matrices are concerned. Menu bar lines are not part of
20489 windows, so the update is done directly on the frame matrix rows
20490 for the menu bar. */
20492 static void
20493 display_menu_bar (struct window *w)
20495 struct frame *f = XFRAME (WINDOW_FRAME (w));
20496 struct it it;
20497 Lisp_Object items;
20498 int i;
20500 /* Don't do all this for graphical frames. */
20501 #ifdef HAVE_NTGUI
20502 if (FRAME_W32_P (f))
20503 return;
20504 #endif
20505 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
20506 if (FRAME_X_P (f))
20507 return;
20508 #endif
20510 #ifdef HAVE_NS
20511 if (FRAME_NS_P (f))
20512 return;
20513 #endif /* HAVE_NS */
20515 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
20516 eassert (!FRAME_WINDOW_P (f));
20517 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
20518 it.first_visible_x = 0;
20519 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
20520 #elif defined (HAVE_X_WINDOWS) /* X without toolkit. */
20521 if (FRAME_WINDOW_P (f))
20523 /* Menu bar lines are displayed in the desired matrix of the
20524 dummy window menu_bar_window. */
20525 struct window *menu_w;
20526 menu_w = XWINDOW (f->menu_bar_window);
20527 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
20528 MENU_FACE_ID);
20529 it.first_visible_x = 0;
20530 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
20532 else
20533 #endif /* not USE_X_TOOLKIT and not USE_GTK */
20535 /* This is a TTY frame, i.e. character hpos/vpos are used as
20536 pixel x/y. */
20537 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
20538 MENU_FACE_ID);
20539 it.first_visible_x = 0;
20540 it.last_visible_x = FRAME_COLS (f);
20543 /* FIXME: This should be controlled by a user option. See the
20544 comments in redisplay_tool_bar and display_mode_line about
20545 this. */
20546 it.paragraph_embedding = L2R;
20548 /* Clear all rows of the menu bar. */
20549 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
20551 struct glyph_row *row = it.glyph_row + i;
20552 clear_glyph_row (row);
20553 row->enabled_p = 1;
20554 row->full_width_p = 1;
20557 /* Display all items of the menu bar. */
20558 items = FRAME_MENU_BAR_ITEMS (it.f);
20559 for (i = 0; i < ASIZE (items); i += 4)
20561 Lisp_Object string;
20563 /* Stop at nil string. */
20564 string = AREF (items, i + 1);
20565 if (NILP (string))
20566 break;
20568 /* Remember where item was displayed. */
20569 ASET (items, i + 3, make_number (it.hpos));
20571 /* Display the item, pad with one space. */
20572 if (it.current_x < it.last_visible_x)
20573 display_string (NULL, string, Qnil, 0, 0, &it,
20574 SCHARS (string) + 1, 0, 0, -1);
20577 /* Fill out the line with spaces. */
20578 if (it.current_x < it.last_visible_x)
20579 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
20581 /* Compute the total height of the lines. */
20582 compute_line_metrics (&it);
20587 /***********************************************************************
20588 Mode Line
20589 ***********************************************************************/
20591 /* Redisplay mode lines in the window tree whose root is WINDOW. If
20592 FORCE is non-zero, redisplay mode lines unconditionally.
20593 Otherwise, redisplay only mode lines that are garbaged. Value is
20594 the number of windows whose mode lines were redisplayed. */
20596 static int
20597 redisplay_mode_lines (Lisp_Object window, int force)
20599 int nwindows = 0;
20601 while (!NILP (window))
20603 struct window *w = XWINDOW (window);
20605 if (WINDOWP (w->contents))
20606 nwindows += redisplay_mode_lines (w->contents, force);
20607 else if (force
20608 || FRAME_GARBAGED_P (XFRAME (w->frame))
20609 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
20611 struct text_pos lpoint;
20612 struct buffer *old = current_buffer;
20614 /* Set the window's buffer for the mode line display. */
20615 SET_TEXT_POS (lpoint, PT, PT_BYTE);
20616 set_buffer_internal_1 (XBUFFER (w->contents));
20618 /* Point refers normally to the selected window. For any
20619 other window, set up appropriate value. */
20620 if (!EQ (window, selected_window))
20622 struct text_pos pt;
20624 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
20625 if (CHARPOS (pt) < BEGV)
20626 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
20627 else if (CHARPOS (pt) > (ZV - 1))
20628 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
20629 else
20630 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
20633 /* Display mode lines. */
20634 clear_glyph_matrix (w->desired_matrix);
20635 if (display_mode_lines (w))
20637 ++nwindows;
20638 w->must_be_updated_p = 1;
20641 /* Restore old settings. */
20642 set_buffer_internal_1 (old);
20643 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
20646 window = w->next;
20649 return nwindows;
20653 /* Display the mode and/or header line of window W. Value is the
20654 sum number of mode lines and header lines displayed. */
20656 static int
20657 display_mode_lines (struct window *w)
20659 Lisp_Object old_selected_window = selected_window;
20660 Lisp_Object old_selected_frame = selected_frame;
20661 Lisp_Object new_frame = w->frame;
20662 Lisp_Object old_frame_selected_window = XFRAME (new_frame)->selected_window;
20663 int n = 0;
20665 selected_frame = new_frame;
20666 /* FIXME: If we were to allow the mode-line's computation changing the buffer
20667 or window's point, then we'd need select_window_1 here as well. */
20668 XSETWINDOW (selected_window, w);
20669 XFRAME (new_frame)->selected_window = selected_window;
20671 /* These will be set while the mode line specs are processed. */
20672 line_number_displayed = 0;
20673 w->column_number_displayed = -1;
20675 if (WINDOW_WANTS_MODELINE_P (w))
20677 struct window *sel_w = XWINDOW (old_selected_window);
20679 /* Select mode line face based on the real selected window. */
20680 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
20681 BVAR (current_buffer, mode_line_format));
20682 ++n;
20685 if (WINDOW_WANTS_HEADER_LINE_P (w))
20687 display_mode_line (w, HEADER_LINE_FACE_ID,
20688 BVAR (current_buffer, header_line_format));
20689 ++n;
20692 XFRAME (new_frame)->selected_window = old_frame_selected_window;
20693 selected_frame = old_selected_frame;
20694 selected_window = old_selected_window;
20695 return n;
20699 /* Display mode or header line of window W. FACE_ID specifies which
20700 line to display; it is either MODE_LINE_FACE_ID or
20701 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
20702 display. Value is the pixel height of the mode/header line
20703 displayed. */
20705 static int
20706 display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
20708 struct it it;
20709 struct face *face;
20710 ptrdiff_t count = SPECPDL_INDEX ();
20712 init_iterator (&it, w, -1, -1, NULL, face_id);
20713 /* Don't extend on a previously drawn mode-line.
20714 This may happen if called from pos_visible_p. */
20715 it.glyph_row->enabled_p = 0;
20716 prepare_desired_row (it.glyph_row);
20718 it.glyph_row->mode_line_p = 1;
20720 /* FIXME: This should be controlled by a user option. But
20721 supporting such an option is not trivial, since the mode line is
20722 made up of many separate strings. */
20723 it.paragraph_embedding = L2R;
20725 record_unwind_protect (unwind_format_mode_line,
20726 format_mode_line_unwind_data (NULL, NULL, Qnil, 0));
20728 mode_line_target = MODE_LINE_DISPLAY;
20730 /* Temporarily make frame's keyboard the current kboard so that
20731 kboard-local variables in the mode_line_format will get the right
20732 values. */
20733 push_kboard (FRAME_KBOARD (it.f));
20734 record_unwind_save_match_data ();
20735 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
20736 pop_kboard ();
20738 unbind_to (count, Qnil);
20740 /* Fill up with spaces. */
20741 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
20743 compute_line_metrics (&it);
20744 it.glyph_row->full_width_p = 1;
20745 it.glyph_row->continued_p = 0;
20746 it.glyph_row->truncated_on_left_p = 0;
20747 it.glyph_row->truncated_on_right_p = 0;
20749 /* Make a 3D mode-line have a shadow at its right end. */
20750 face = FACE_FROM_ID (it.f, face_id);
20751 extend_face_to_end_of_line (&it);
20752 if (face->box != FACE_NO_BOX)
20754 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
20755 + it.glyph_row->used[TEXT_AREA] - 1);
20756 last->right_box_line_p = 1;
20759 return it.glyph_row->height;
20762 /* Move element ELT in LIST to the front of LIST.
20763 Return the updated list. */
20765 static Lisp_Object
20766 move_elt_to_front (Lisp_Object elt, Lisp_Object list)
20768 register Lisp_Object tail, prev;
20769 register Lisp_Object tem;
20771 tail = list;
20772 prev = Qnil;
20773 while (CONSP (tail))
20775 tem = XCAR (tail);
20777 if (EQ (elt, tem))
20779 /* Splice out the link TAIL. */
20780 if (NILP (prev))
20781 list = XCDR (tail);
20782 else
20783 Fsetcdr (prev, XCDR (tail));
20785 /* Now make it the first. */
20786 Fsetcdr (tail, list);
20787 return tail;
20789 else
20790 prev = tail;
20791 tail = XCDR (tail);
20792 QUIT;
20795 /* Not found--return unchanged LIST. */
20796 return list;
20799 /* Contribute ELT to the mode line for window IT->w. How it
20800 translates into text depends on its data type.
20802 IT describes the display environment in which we display, as usual.
20804 DEPTH is the depth in recursion. It is used to prevent
20805 infinite recursion here.
20807 FIELD_WIDTH is the number of characters the display of ELT should
20808 occupy in the mode line, and PRECISION is the maximum number of
20809 characters to display from ELT's representation. See
20810 display_string for details.
20812 Returns the hpos of the end of the text generated by ELT.
20814 PROPS is a property list to add to any string we encounter.
20816 If RISKY is nonzero, remove (disregard) any properties in any string
20817 we encounter, and ignore :eval and :propertize.
20819 The global variable `mode_line_target' determines whether the
20820 output is passed to `store_mode_line_noprop',
20821 `store_mode_line_string', or `display_string'. */
20823 static int
20824 display_mode_element (struct it *it, int depth, int field_width, int precision,
20825 Lisp_Object elt, Lisp_Object props, int risky)
20827 int n = 0, field, prec;
20828 int literal = 0;
20830 tail_recurse:
20831 if (depth > 100)
20832 elt = build_string ("*too-deep*");
20834 depth++;
20836 switch (XTYPE (elt))
20838 case Lisp_String:
20840 /* A string: output it and check for %-constructs within it. */
20841 unsigned char c;
20842 ptrdiff_t offset = 0;
20844 if (SCHARS (elt) > 0
20845 && (!NILP (props) || risky))
20847 Lisp_Object oprops, aelt;
20848 oprops = Ftext_properties_at (make_number (0), elt);
20850 /* If the starting string's properties are not what
20851 we want, translate the string. Also, if the string
20852 is risky, do that anyway. */
20854 if (NILP (Fequal (props, oprops)) || risky)
20856 /* If the starting string has properties,
20857 merge the specified ones onto the existing ones. */
20858 if (! NILP (oprops) && !risky)
20860 Lisp_Object tem;
20862 oprops = Fcopy_sequence (oprops);
20863 tem = props;
20864 while (CONSP (tem))
20866 oprops = Fplist_put (oprops, XCAR (tem),
20867 XCAR (XCDR (tem)));
20868 tem = XCDR (XCDR (tem));
20870 props = oprops;
20873 aelt = Fassoc (elt, mode_line_proptrans_alist);
20874 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
20876 /* AELT is what we want. Move it to the front
20877 without consing. */
20878 elt = XCAR (aelt);
20879 mode_line_proptrans_alist
20880 = move_elt_to_front (aelt, mode_line_proptrans_alist);
20882 else
20884 Lisp_Object tem;
20886 /* If AELT has the wrong props, it is useless.
20887 so get rid of it. */
20888 if (! NILP (aelt))
20889 mode_line_proptrans_alist
20890 = Fdelq (aelt, mode_line_proptrans_alist);
20892 elt = Fcopy_sequence (elt);
20893 Fset_text_properties (make_number (0), Flength (elt),
20894 props, elt);
20895 /* Add this item to mode_line_proptrans_alist. */
20896 mode_line_proptrans_alist
20897 = Fcons (Fcons (elt, props),
20898 mode_line_proptrans_alist);
20899 /* Truncate mode_line_proptrans_alist
20900 to at most 50 elements. */
20901 tem = Fnthcdr (make_number (50),
20902 mode_line_proptrans_alist);
20903 if (! NILP (tem))
20904 XSETCDR (tem, Qnil);
20909 offset = 0;
20911 if (literal)
20913 prec = precision - n;
20914 switch (mode_line_target)
20916 case MODE_LINE_NOPROP:
20917 case MODE_LINE_TITLE:
20918 n += store_mode_line_noprop (SSDATA (elt), -1, prec);
20919 break;
20920 case MODE_LINE_STRING:
20921 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
20922 break;
20923 case MODE_LINE_DISPLAY:
20924 n += display_string (NULL, elt, Qnil, 0, 0, it,
20925 0, prec, 0, STRING_MULTIBYTE (elt));
20926 break;
20929 break;
20932 /* Handle the non-literal case. */
20934 while ((precision <= 0 || n < precision)
20935 && SREF (elt, offset) != 0
20936 && (mode_line_target != MODE_LINE_DISPLAY
20937 || it->current_x < it->last_visible_x))
20939 ptrdiff_t last_offset = offset;
20941 /* Advance to end of string or next format specifier. */
20942 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
20945 if (offset - 1 != last_offset)
20947 ptrdiff_t nchars, nbytes;
20949 /* Output to end of string or up to '%'. Field width
20950 is length of string. Don't output more than
20951 PRECISION allows us. */
20952 offset--;
20954 prec = c_string_width (SDATA (elt) + last_offset,
20955 offset - last_offset, precision - n,
20956 &nchars, &nbytes);
20958 switch (mode_line_target)
20960 case MODE_LINE_NOPROP:
20961 case MODE_LINE_TITLE:
20962 n += store_mode_line_noprop (SSDATA (elt) + last_offset, 0, prec);
20963 break;
20964 case MODE_LINE_STRING:
20966 ptrdiff_t bytepos = last_offset;
20967 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
20968 ptrdiff_t endpos = (precision <= 0
20969 ? string_byte_to_char (elt, offset)
20970 : charpos + nchars);
20972 n += store_mode_line_string (NULL,
20973 Fsubstring (elt, make_number (charpos),
20974 make_number (endpos)),
20975 0, 0, 0, Qnil);
20977 break;
20978 case MODE_LINE_DISPLAY:
20980 ptrdiff_t bytepos = last_offset;
20981 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
20983 if (precision <= 0)
20984 nchars = string_byte_to_char (elt, offset) - charpos;
20985 n += display_string (NULL, elt, Qnil, 0, charpos,
20986 it, 0, nchars, 0,
20987 STRING_MULTIBYTE (elt));
20989 break;
20992 else /* c == '%' */
20994 ptrdiff_t percent_position = offset;
20996 /* Get the specified minimum width. Zero means
20997 don't pad. */
20998 field = 0;
20999 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
21000 field = field * 10 + c - '0';
21002 /* Don't pad beyond the total padding allowed. */
21003 if (field_width - n > 0 && field > field_width - n)
21004 field = field_width - n;
21006 /* Note that either PRECISION <= 0 or N < PRECISION. */
21007 prec = precision - n;
21009 if (c == 'M')
21010 n += display_mode_element (it, depth, field, prec,
21011 Vglobal_mode_string, props,
21012 risky);
21013 else if (c != 0)
21015 bool multibyte;
21016 ptrdiff_t bytepos, charpos;
21017 const char *spec;
21018 Lisp_Object string;
21020 bytepos = percent_position;
21021 charpos = (STRING_MULTIBYTE (elt)
21022 ? string_byte_to_char (elt, bytepos)
21023 : bytepos);
21024 spec = decode_mode_spec (it->w, c, field, &string);
21025 multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
21027 switch (mode_line_target)
21029 case MODE_LINE_NOPROP:
21030 case MODE_LINE_TITLE:
21031 n += store_mode_line_noprop (spec, field, prec);
21032 break;
21033 case MODE_LINE_STRING:
21035 Lisp_Object tem = build_string (spec);
21036 props = Ftext_properties_at (make_number (charpos), elt);
21037 /* Should only keep face property in props */
21038 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
21040 break;
21041 case MODE_LINE_DISPLAY:
21043 int nglyphs_before, nwritten;
21045 nglyphs_before = it->glyph_row->used[TEXT_AREA];
21046 nwritten = display_string (spec, string, elt,
21047 charpos, 0, it,
21048 field, prec, 0,
21049 multibyte);
21051 /* Assign to the glyphs written above the
21052 string where the `%x' came from, position
21053 of the `%'. */
21054 if (nwritten > 0)
21056 struct glyph *glyph
21057 = (it->glyph_row->glyphs[TEXT_AREA]
21058 + nglyphs_before);
21059 int i;
21061 for (i = 0; i < nwritten; ++i)
21063 glyph[i].object = elt;
21064 glyph[i].charpos = charpos;
21067 n += nwritten;
21070 break;
21073 else /* c == 0 */
21074 break;
21078 break;
21080 case Lisp_Symbol:
21081 /* A symbol: process the value of the symbol recursively
21082 as if it appeared here directly. Avoid error if symbol void.
21083 Special case: if value of symbol is a string, output the string
21084 literally. */
21086 register Lisp_Object tem;
21088 /* If the variable is not marked as risky to set
21089 then its contents are risky to use. */
21090 if (NILP (Fget (elt, Qrisky_local_variable)))
21091 risky = 1;
21093 tem = Fboundp (elt);
21094 if (!NILP (tem))
21096 tem = Fsymbol_value (elt);
21097 /* If value is a string, output that string literally:
21098 don't check for % within it. */
21099 if (STRINGP (tem))
21100 literal = 1;
21102 if (!EQ (tem, elt))
21104 /* Give up right away for nil or t. */
21105 elt = tem;
21106 goto tail_recurse;
21110 break;
21112 case Lisp_Cons:
21114 register Lisp_Object car, tem;
21116 /* A cons cell: five distinct cases.
21117 If first element is :eval or :propertize, do something special.
21118 If first element is a string or a cons, process all the elements
21119 and effectively concatenate them.
21120 If first element is a negative number, truncate displaying cdr to
21121 at most that many characters. If positive, pad (with spaces)
21122 to at least that many characters.
21123 If first element is a symbol, process the cadr or caddr recursively
21124 according to whether the symbol's value is non-nil or nil. */
21125 car = XCAR (elt);
21126 if (EQ (car, QCeval))
21128 /* An element of the form (:eval FORM) means evaluate FORM
21129 and use the result as mode line elements. */
21131 if (risky)
21132 break;
21134 if (CONSP (XCDR (elt)))
21136 Lisp_Object spec;
21137 spec = safe_eval (XCAR (XCDR (elt)));
21138 n += display_mode_element (it, depth, field_width - n,
21139 precision - n, spec, props,
21140 risky);
21143 else if (EQ (car, QCpropertize))
21145 /* An element of the form (:propertize ELT PROPS...)
21146 means display ELT but applying properties PROPS. */
21148 if (risky)
21149 break;
21151 if (CONSP (XCDR (elt)))
21152 n += display_mode_element (it, depth, field_width - n,
21153 precision - n, XCAR (XCDR (elt)),
21154 XCDR (XCDR (elt)), risky);
21156 else if (SYMBOLP (car))
21158 tem = Fboundp (car);
21159 elt = XCDR (elt);
21160 if (!CONSP (elt))
21161 goto invalid;
21162 /* elt is now the cdr, and we know it is a cons cell.
21163 Use its car if CAR has a non-nil value. */
21164 if (!NILP (tem))
21166 tem = Fsymbol_value (car);
21167 if (!NILP (tem))
21169 elt = XCAR (elt);
21170 goto tail_recurse;
21173 /* Symbol's value is nil (or symbol is unbound)
21174 Get the cddr of the original list
21175 and if possible find the caddr and use that. */
21176 elt = XCDR (elt);
21177 if (NILP (elt))
21178 break;
21179 else if (!CONSP (elt))
21180 goto invalid;
21181 elt = XCAR (elt);
21182 goto tail_recurse;
21184 else if (INTEGERP (car))
21186 register int lim = XINT (car);
21187 elt = XCDR (elt);
21188 if (lim < 0)
21190 /* Negative int means reduce maximum width. */
21191 if (precision <= 0)
21192 precision = -lim;
21193 else
21194 precision = min (precision, -lim);
21196 else if (lim > 0)
21198 /* Padding specified. Don't let it be more than
21199 current maximum. */
21200 if (precision > 0)
21201 lim = min (precision, lim);
21203 /* If that's more padding than already wanted, queue it.
21204 But don't reduce padding already specified even if
21205 that is beyond the current truncation point. */
21206 field_width = max (lim, field_width);
21208 goto tail_recurse;
21210 else if (STRINGP (car) || CONSP (car))
21212 Lisp_Object halftail = elt;
21213 int len = 0;
21215 while (CONSP (elt)
21216 && (precision <= 0 || n < precision))
21218 n += display_mode_element (it, depth,
21219 /* Do padding only after the last
21220 element in the list. */
21221 (! CONSP (XCDR (elt))
21222 ? field_width - n
21223 : 0),
21224 precision - n, XCAR (elt),
21225 props, risky);
21226 elt = XCDR (elt);
21227 len++;
21228 if ((len & 1) == 0)
21229 halftail = XCDR (halftail);
21230 /* Check for cycle. */
21231 if (EQ (halftail, elt))
21232 break;
21236 break;
21238 default:
21239 invalid:
21240 elt = build_string ("*invalid*");
21241 goto tail_recurse;
21244 /* Pad to FIELD_WIDTH. */
21245 if (field_width > 0 && n < field_width)
21247 switch (mode_line_target)
21249 case MODE_LINE_NOPROP:
21250 case MODE_LINE_TITLE:
21251 n += store_mode_line_noprop ("", field_width - n, 0);
21252 break;
21253 case MODE_LINE_STRING:
21254 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
21255 break;
21256 case MODE_LINE_DISPLAY:
21257 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
21258 0, 0, 0);
21259 break;
21263 return n;
21266 /* Store a mode-line string element in mode_line_string_list.
21268 If STRING is non-null, display that C string. Otherwise, the Lisp
21269 string LISP_STRING is displayed.
21271 FIELD_WIDTH is the minimum number of output glyphs to produce.
21272 If STRING has fewer characters than FIELD_WIDTH, pad to the right
21273 with spaces. FIELD_WIDTH <= 0 means don't pad.
21275 PRECISION is the maximum number of characters to output from
21276 STRING. PRECISION <= 0 means don't truncate the string.
21278 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
21279 properties to the string.
21281 PROPS are the properties to add to the string.
21282 The mode_line_string_face face property is always added to the string.
21285 static int
21286 store_mode_line_string (const char *string, Lisp_Object lisp_string, int copy_string,
21287 int field_width, int precision, Lisp_Object props)
21289 ptrdiff_t len;
21290 int n = 0;
21292 if (string != NULL)
21294 len = strlen (string);
21295 if (precision > 0 && len > precision)
21296 len = precision;
21297 lisp_string = make_string (string, len);
21298 if (NILP (props))
21299 props = mode_line_string_face_prop;
21300 else if (!NILP (mode_line_string_face))
21302 Lisp_Object face = Fplist_get (props, Qface);
21303 props = Fcopy_sequence (props);
21304 if (NILP (face))
21305 face = mode_line_string_face;
21306 else
21307 face = list2 (face, mode_line_string_face);
21308 props = Fplist_put (props, Qface, face);
21310 Fadd_text_properties (make_number (0), make_number (len),
21311 props, lisp_string);
21313 else
21315 len = XFASTINT (Flength (lisp_string));
21316 if (precision > 0 && len > precision)
21318 len = precision;
21319 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
21320 precision = -1;
21322 if (!NILP (mode_line_string_face))
21324 Lisp_Object face;
21325 if (NILP (props))
21326 props = Ftext_properties_at (make_number (0), lisp_string);
21327 face = Fplist_get (props, Qface);
21328 if (NILP (face))
21329 face = mode_line_string_face;
21330 else
21331 face = list2 (face, mode_line_string_face);
21332 props = list2 (Qface, face);
21333 if (copy_string)
21334 lisp_string = Fcopy_sequence (lisp_string);
21336 if (!NILP (props))
21337 Fadd_text_properties (make_number (0), make_number (len),
21338 props, lisp_string);
21341 if (len > 0)
21343 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
21344 n += len;
21347 if (field_width > len)
21349 field_width -= len;
21350 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
21351 if (!NILP (props))
21352 Fadd_text_properties (make_number (0), make_number (field_width),
21353 props, lisp_string);
21354 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
21355 n += field_width;
21358 return n;
21362 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
21363 1, 4, 0,
21364 doc: /* Format a string out of a mode line format specification.
21365 First arg FORMAT specifies the mode line format (see `mode-line-format'
21366 for details) to use.
21368 By default, the format is evaluated for the currently selected window.
21370 Optional second arg FACE specifies the face property to put on all
21371 characters for which no face is specified. The value nil means the
21372 default face. The value t means whatever face the window's mode line
21373 currently uses (either `mode-line' or `mode-line-inactive',
21374 depending on whether the window is the selected window or not).
21375 An integer value means the value string has no text
21376 properties.
21378 Optional third and fourth args WINDOW and BUFFER specify the window
21379 and buffer to use as the context for the formatting (defaults
21380 are the selected window and the WINDOW's buffer). */)
21381 (Lisp_Object format, Lisp_Object face,
21382 Lisp_Object window, Lisp_Object buffer)
21384 struct it it;
21385 int len;
21386 struct window *w;
21387 struct buffer *old_buffer = NULL;
21388 int face_id;
21389 int no_props = INTEGERP (face);
21390 ptrdiff_t count = SPECPDL_INDEX ();
21391 Lisp_Object str;
21392 int string_start = 0;
21394 w = decode_any_window (window);
21395 XSETWINDOW (window, w);
21397 if (NILP (buffer))
21398 buffer = w->contents;
21399 CHECK_BUFFER (buffer);
21401 /* Make formatting the modeline a non-op when noninteractive, otherwise
21402 there will be problems later caused by a partially initialized frame. */
21403 if (NILP (format) || noninteractive)
21404 return empty_unibyte_string;
21406 if (no_props)
21407 face = Qnil;
21409 face_id = (NILP (face) || EQ (face, Qdefault)) ? DEFAULT_FACE_ID
21410 : EQ (face, Qt) ? (EQ (window, selected_window)
21411 ? MODE_LINE_FACE_ID : MODE_LINE_INACTIVE_FACE_ID)
21412 : EQ (face, Qmode_line) ? MODE_LINE_FACE_ID
21413 : EQ (face, Qmode_line_inactive) ? MODE_LINE_INACTIVE_FACE_ID
21414 : EQ (face, Qheader_line) ? HEADER_LINE_FACE_ID
21415 : EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID
21416 : DEFAULT_FACE_ID;
21418 old_buffer = current_buffer;
21420 /* Save things including mode_line_proptrans_alist,
21421 and set that to nil so that we don't alter the outer value. */
21422 record_unwind_protect (unwind_format_mode_line,
21423 format_mode_line_unwind_data
21424 (XFRAME (WINDOW_FRAME (w)),
21425 old_buffer, selected_window, 1));
21426 mode_line_proptrans_alist = Qnil;
21428 Fselect_window (window, Qt);
21429 set_buffer_internal_1 (XBUFFER (buffer));
21431 init_iterator (&it, w, -1, -1, NULL, face_id);
21433 if (no_props)
21435 mode_line_target = MODE_LINE_NOPROP;
21436 mode_line_string_face_prop = Qnil;
21437 mode_line_string_list = Qnil;
21438 string_start = MODE_LINE_NOPROP_LEN (0);
21440 else
21442 mode_line_target = MODE_LINE_STRING;
21443 mode_line_string_list = Qnil;
21444 mode_line_string_face = face;
21445 mode_line_string_face_prop
21446 = NILP (face) ? Qnil : list2 (Qface, face);
21449 push_kboard (FRAME_KBOARD (it.f));
21450 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
21451 pop_kboard ();
21453 if (no_props)
21455 len = MODE_LINE_NOPROP_LEN (string_start);
21456 str = make_string (mode_line_noprop_buf + string_start, len);
21458 else
21460 mode_line_string_list = Fnreverse (mode_line_string_list);
21461 str = Fmapconcat (intern ("identity"), mode_line_string_list,
21462 empty_unibyte_string);
21465 unbind_to (count, Qnil);
21466 return str;
21469 /* Write a null-terminated, right justified decimal representation of
21470 the positive integer D to BUF using a minimal field width WIDTH. */
21472 static void
21473 pint2str (register char *buf, register int width, register ptrdiff_t d)
21475 register char *p = buf;
21477 if (d <= 0)
21478 *p++ = '0';
21479 else
21481 while (d > 0)
21483 *p++ = d % 10 + '0';
21484 d /= 10;
21488 for (width -= (int) (p - buf); width > 0; --width)
21489 *p++ = ' ';
21490 *p-- = '\0';
21491 while (p > buf)
21493 d = *buf;
21494 *buf++ = *p;
21495 *p-- = d;
21499 /* Write a null-terminated, right justified decimal and "human
21500 readable" representation of the nonnegative integer D to BUF using
21501 a minimal field width WIDTH. D should be smaller than 999.5e24. */
21503 static const char power_letter[] =
21505 0, /* no letter */
21506 'k', /* kilo */
21507 'M', /* mega */
21508 'G', /* giga */
21509 'T', /* tera */
21510 'P', /* peta */
21511 'E', /* exa */
21512 'Z', /* zetta */
21513 'Y' /* yotta */
21516 static void
21517 pint2hrstr (char *buf, int width, ptrdiff_t d)
21519 /* We aim to represent the nonnegative integer D as
21520 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
21521 ptrdiff_t quotient = d;
21522 int remainder = 0;
21523 /* -1 means: do not use TENTHS. */
21524 int tenths = -1;
21525 int exponent = 0;
21527 /* Length of QUOTIENT.TENTHS as a string. */
21528 int length;
21530 char * psuffix;
21531 char * p;
21533 if (quotient >= 1000)
21535 /* Scale to the appropriate EXPONENT. */
21538 remainder = quotient % 1000;
21539 quotient /= 1000;
21540 exponent++;
21542 while (quotient >= 1000);
21544 /* Round to nearest and decide whether to use TENTHS or not. */
21545 if (quotient <= 9)
21547 tenths = remainder / 100;
21548 if (remainder % 100 >= 50)
21550 if (tenths < 9)
21551 tenths++;
21552 else
21554 quotient++;
21555 if (quotient == 10)
21556 tenths = -1;
21557 else
21558 tenths = 0;
21562 else
21563 if (remainder >= 500)
21565 if (quotient < 999)
21566 quotient++;
21567 else
21569 quotient = 1;
21570 exponent++;
21571 tenths = 0;
21576 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
21577 if (tenths == -1 && quotient <= 99)
21578 if (quotient <= 9)
21579 length = 1;
21580 else
21581 length = 2;
21582 else
21583 length = 3;
21584 p = psuffix = buf + max (width, length);
21586 /* Print EXPONENT. */
21587 *psuffix++ = power_letter[exponent];
21588 *psuffix = '\0';
21590 /* Print TENTHS. */
21591 if (tenths >= 0)
21593 *--p = '0' + tenths;
21594 *--p = '.';
21597 /* Print QUOTIENT. */
21600 int digit = quotient % 10;
21601 *--p = '0' + digit;
21603 while ((quotient /= 10) != 0);
21605 /* Print leading spaces. */
21606 while (buf < p)
21607 *--p = ' ';
21610 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
21611 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
21612 type of CODING_SYSTEM. Return updated pointer into BUF. */
21614 static unsigned char invalid_eol_type[] = "(*invalid*)";
21616 static char *
21617 decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_flag)
21619 Lisp_Object val;
21620 bool multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
21621 const unsigned char *eol_str;
21622 int eol_str_len;
21623 /* The EOL conversion we are using. */
21624 Lisp_Object eoltype;
21626 val = CODING_SYSTEM_SPEC (coding_system);
21627 eoltype = Qnil;
21629 if (!VECTORP (val)) /* Not yet decided. */
21631 *buf++ = multibyte ? '-' : ' ';
21632 if (eol_flag)
21633 eoltype = eol_mnemonic_undecided;
21634 /* Don't mention EOL conversion if it isn't decided. */
21636 else
21638 Lisp_Object attrs;
21639 Lisp_Object eolvalue;
21641 attrs = AREF (val, 0);
21642 eolvalue = AREF (val, 2);
21644 *buf++ = multibyte
21645 ? XFASTINT (CODING_ATTR_MNEMONIC (attrs))
21646 : ' ';
21648 if (eol_flag)
21650 /* The EOL conversion that is normal on this system. */
21652 if (NILP (eolvalue)) /* Not yet decided. */
21653 eoltype = eol_mnemonic_undecided;
21654 else if (VECTORP (eolvalue)) /* Not yet decided. */
21655 eoltype = eol_mnemonic_undecided;
21656 else /* eolvalue is Qunix, Qdos, or Qmac. */
21657 eoltype = (EQ (eolvalue, Qunix)
21658 ? eol_mnemonic_unix
21659 : (EQ (eolvalue, Qdos) == 1
21660 ? eol_mnemonic_dos : eol_mnemonic_mac));
21664 if (eol_flag)
21666 /* Mention the EOL conversion if it is not the usual one. */
21667 if (STRINGP (eoltype))
21669 eol_str = SDATA (eoltype);
21670 eol_str_len = SBYTES (eoltype);
21672 else if (CHARACTERP (eoltype))
21674 unsigned char *tmp = alloca (MAX_MULTIBYTE_LENGTH);
21675 int c = XFASTINT (eoltype);
21676 eol_str_len = CHAR_STRING (c, tmp);
21677 eol_str = tmp;
21679 else
21681 eol_str = invalid_eol_type;
21682 eol_str_len = sizeof (invalid_eol_type) - 1;
21684 memcpy (buf, eol_str, eol_str_len);
21685 buf += eol_str_len;
21688 return buf;
21691 /* Return a string for the output of a mode line %-spec for window W,
21692 generated by character C. FIELD_WIDTH > 0 means pad the string
21693 returned with spaces to that value. Return a Lisp string in
21694 *STRING if the resulting string is taken from that Lisp string.
21696 Note we operate on the current buffer for most purposes. */
21698 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
21700 static const char *
21701 decode_mode_spec (struct window *w, register int c, int field_width,
21702 Lisp_Object *string)
21704 Lisp_Object obj;
21705 struct frame *f = XFRAME (WINDOW_FRAME (w));
21706 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
21707 /* We are going to use f->decode_mode_spec_buffer as the buffer to
21708 produce strings from numerical values, so limit preposterously
21709 large values of FIELD_WIDTH to avoid overrunning the buffer's
21710 end. The size of the buffer is enough for FRAME_MESSAGE_BUF_SIZE
21711 bytes plus the terminating null. */
21712 int width = min (field_width, FRAME_MESSAGE_BUF_SIZE (f));
21713 struct buffer *b = current_buffer;
21715 obj = Qnil;
21716 *string = Qnil;
21718 switch (c)
21720 case '*':
21721 if (!NILP (BVAR (b, read_only)))
21722 return "%";
21723 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21724 return "*";
21725 return "-";
21727 case '+':
21728 /* This differs from %* only for a modified read-only buffer. */
21729 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21730 return "*";
21731 if (!NILP (BVAR (b, read_only)))
21732 return "%";
21733 return "-";
21735 case '&':
21736 /* This differs from %* in ignoring read-only-ness. */
21737 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21738 return "*";
21739 return "-";
21741 case '%':
21742 return "%";
21744 case '[':
21746 int i;
21747 char *p;
21749 if (command_loop_level > 5)
21750 return "[[[... ";
21751 p = decode_mode_spec_buf;
21752 for (i = 0; i < command_loop_level; i++)
21753 *p++ = '[';
21754 *p = 0;
21755 return decode_mode_spec_buf;
21758 case ']':
21760 int i;
21761 char *p;
21763 if (command_loop_level > 5)
21764 return " ...]]]";
21765 p = decode_mode_spec_buf;
21766 for (i = 0; i < command_loop_level; i++)
21767 *p++ = ']';
21768 *p = 0;
21769 return decode_mode_spec_buf;
21772 case '-':
21774 register int i;
21776 /* Let lots_of_dashes be a string of infinite length. */
21777 if (mode_line_target == MODE_LINE_NOPROP
21778 || mode_line_target == MODE_LINE_STRING)
21779 return "--";
21780 if (field_width <= 0
21781 || field_width > sizeof (lots_of_dashes))
21783 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
21784 decode_mode_spec_buf[i] = '-';
21785 decode_mode_spec_buf[i] = '\0';
21786 return decode_mode_spec_buf;
21788 else
21789 return lots_of_dashes;
21792 case 'b':
21793 obj = BVAR (b, name);
21794 break;
21796 case 'c':
21797 /* %c and %l are ignored in `frame-title-format'.
21798 (In redisplay_internal, the frame title is drawn _before_ the
21799 windows are updated, so the stuff which depends on actual
21800 window contents (such as %l) may fail to render properly, or
21801 even crash emacs.) */
21802 if (mode_line_target == MODE_LINE_TITLE)
21803 return "";
21804 else
21806 ptrdiff_t col = current_column ();
21807 w->column_number_displayed = col;
21808 pint2str (decode_mode_spec_buf, width, col);
21809 return decode_mode_spec_buf;
21812 case 'e':
21813 #ifndef SYSTEM_MALLOC
21815 if (NILP (Vmemory_full))
21816 return "";
21817 else
21818 return "!MEM FULL! ";
21820 #else
21821 return "";
21822 #endif
21824 case 'F':
21825 /* %F displays the frame name. */
21826 if (!NILP (f->title))
21827 return SSDATA (f->title);
21828 if (f->explicit_name || ! FRAME_WINDOW_P (f))
21829 return SSDATA (f->name);
21830 return "Emacs";
21832 case 'f':
21833 obj = BVAR (b, filename);
21834 break;
21836 case 'i':
21838 ptrdiff_t size = ZV - BEGV;
21839 pint2str (decode_mode_spec_buf, width, size);
21840 return decode_mode_spec_buf;
21843 case 'I':
21845 ptrdiff_t size = ZV - BEGV;
21846 pint2hrstr (decode_mode_spec_buf, width, size);
21847 return decode_mode_spec_buf;
21850 case 'l':
21852 ptrdiff_t startpos, startpos_byte, line, linepos, linepos_byte;
21853 ptrdiff_t topline, nlines, height;
21854 ptrdiff_t junk;
21856 /* %c and %l are ignored in `frame-title-format'. */
21857 if (mode_line_target == MODE_LINE_TITLE)
21858 return "";
21860 startpos = marker_position (w->start);
21861 startpos_byte = marker_byte_position (w->start);
21862 height = WINDOW_TOTAL_LINES (w);
21864 /* If we decided that this buffer isn't suitable for line numbers,
21865 don't forget that too fast. */
21866 if (w->base_line_pos == -1)
21867 goto no_value;
21869 /* If the buffer is very big, don't waste time. */
21870 if (INTEGERP (Vline_number_display_limit)
21871 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
21873 w->base_line_pos = 0;
21874 w->base_line_number = 0;
21875 goto no_value;
21878 if (w->base_line_number > 0
21879 && w->base_line_pos > 0
21880 && w->base_line_pos <= startpos)
21882 line = w->base_line_number;
21883 linepos = w->base_line_pos;
21884 linepos_byte = buf_charpos_to_bytepos (b, linepos);
21886 else
21888 line = 1;
21889 linepos = BUF_BEGV (b);
21890 linepos_byte = BUF_BEGV_BYTE (b);
21893 /* Count lines from base line to window start position. */
21894 nlines = display_count_lines (linepos_byte,
21895 startpos_byte,
21896 startpos, &junk);
21898 topline = nlines + line;
21900 /* Determine a new base line, if the old one is too close
21901 or too far away, or if we did not have one.
21902 "Too close" means it's plausible a scroll-down would
21903 go back past it. */
21904 if (startpos == BUF_BEGV (b))
21906 w->base_line_number = topline;
21907 w->base_line_pos = BUF_BEGV (b);
21909 else if (nlines < height + 25 || nlines > height * 3 + 50
21910 || linepos == BUF_BEGV (b))
21912 ptrdiff_t limit = BUF_BEGV (b);
21913 ptrdiff_t limit_byte = BUF_BEGV_BYTE (b);
21914 ptrdiff_t position;
21915 ptrdiff_t distance =
21916 (height * 2 + 30) * line_number_display_limit_width;
21918 if (startpos - distance > limit)
21920 limit = startpos - distance;
21921 limit_byte = CHAR_TO_BYTE (limit);
21924 nlines = display_count_lines (startpos_byte,
21925 limit_byte,
21926 - (height * 2 + 30),
21927 &position);
21928 /* If we couldn't find the lines we wanted within
21929 line_number_display_limit_width chars per line,
21930 give up on line numbers for this window. */
21931 if (position == limit_byte && limit == startpos - distance)
21933 w->base_line_pos = -1;
21934 w->base_line_number = 0;
21935 goto no_value;
21938 w->base_line_number = topline - nlines;
21939 w->base_line_pos = BYTE_TO_CHAR (position);
21942 /* Now count lines from the start pos to point. */
21943 nlines = display_count_lines (startpos_byte,
21944 PT_BYTE, PT, &junk);
21946 /* Record that we did display the line number. */
21947 line_number_displayed = 1;
21949 /* Make the string to show. */
21950 pint2str (decode_mode_spec_buf, width, topline + nlines);
21951 return decode_mode_spec_buf;
21952 no_value:
21954 char* p = decode_mode_spec_buf;
21955 int pad = width - 2;
21956 while (pad-- > 0)
21957 *p++ = ' ';
21958 *p++ = '?';
21959 *p++ = '?';
21960 *p = '\0';
21961 return decode_mode_spec_buf;
21964 break;
21966 case 'm':
21967 obj = BVAR (b, mode_name);
21968 break;
21970 case 'n':
21971 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
21972 return " Narrow";
21973 break;
21975 case 'p':
21977 ptrdiff_t pos = marker_position (w->start);
21978 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
21980 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
21982 if (pos <= BUF_BEGV (b))
21983 return "All";
21984 else
21985 return "Bottom";
21987 else if (pos <= BUF_BEGV (b))
21988 return "Top";
21989 else
21991 if (total > 1000000)
21992 /* Do it differently for a large value, to avoid overflow. */
21993 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
21994 else
21995 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
21996 /* We can't normally display a 3-digit number,
21997 so get us a 2-digit number that is close. */
21998 if (total == 100)
21999 total = 99;
22000 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
22001 return decode_mode_spec_buf;
22005 /* Display percentage of size above the bottom of the screen. */
22006 case 'P':
22008 ptrdiff_t toppos = marker_position (w->start);
22009 ptrdiff_t botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
22010 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
22012 if (botpos >= BUF_ZV (b))
22014 if (toppos <= BUF_BEGV (b))
22015 return "All";
22016 else
22017 return "Bottom";
22019 else
22021 if (total > 1000000)
22022 /* Do it differently for a large value, to avoid overflow. */
22023 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
22024 else
22025 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
22026 /* We can't normally display a 3-digit number,
22027 so get us a 2-digit number that is close. */
22028 if (total == 100)
22029 total = 99;
22030 if (toppos <= BUF_BEGV (b))
22031 sprintf (decode_mode_spec_buf, "Top%2"pD"d%%", total);
22032 else
22033 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
22034 return decode_mode_spec_buf;
22038 case 's':
22039 /* status of process */
22040 obj = Fget_buffer_process (Fcurrent_buffer ());
22041 if (NILP (obj))
22042 return "no process";
22043 #ifndef MSDOS
22044 obj = Fsymbol_name (Fprocess_status (obj));
22045 #endif
22046 break;
22048 case '@':
22050 ptrdiff_t count = inhibit_garbage_collection ();
22051 Lisp_Object val = call1 (intern ("file-remote-p"),
22052 BVAR (current_buffer, directory));
22053 unbind_to (count, Qnil);
22055 if (NILP (val))
22056 return "-";
22057 else
22058 return "@";
22061 case 'z':
22062 /* coding-system (not including end-of-line format) */
22063 case 'Z':
22064 /* coding-system (including end-of-line type) */
22066 int eol_flag = (c == 'Z');
22067 char *p = decode_mode_spec_buf;
22069 if (! FRAME_WINDOW_P (f))
22071 /* No need to mention EOL here--the terminal never needs
22072 to do EOL conversion. */
22073 p = decode_mode_spec_coding (CODING_ID_NAME
22074 (FRAME_KEYBOARD_CODING (f)->id),
22075 p, 0);
22076 p = decode_mode_spec_coding (CODING_ID_NAME
22077 (FRAME_TERMINAL_CODING (f)->id),
22078 p, 0);
22080 p = decode_mode_spec_coding (BVAR (b, buffer_file_coding_system),
22081 p, eol_flag);
22083 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
22084 #ifdef subprocesses
22085 obj = Fget_buffer_process (Fcurrent_buffer ());
22086 if (PROCESSP (obj))
22088 p = decode_mode_spec_coding
22089 (XPROCESS (obj)->decode_coding_system, p, eol_flag);
22090 p = decode_mode_spec_coding
22091 (XPROCESS (obj)->encode_coding_system, p, eol_flag);
22093 #endif /* subprocesses */
22094 #endif /* 0 */
22095 *p = 0;
22096 return decode_mode_spec_buf;
22100 if (STRINGP (obj))
22102 *string = obj;
22103 return SSDATA (obj);
22105 else
22106 return "";
22110 /* Count up to COUNT lines starting from START_BYTE. COUNT negative
22111 means count lines back from START_BYTE. But don't go beyond
22112 LIMIT_BYTE. Return the number of lines thus found (always
22113 nonnegative).
22115 Set *BYTE_POS_PTR to the byte position where we stopped. This is
22116 either the position COUNT lines after/before START_BYTE, if we
22117 found COUNT lines, or LIMIT_BYTE if we hit the limit before finding
22118 COUNT lines. */
22120 static ptrdiff_t
22121 display_count_lines (ptrdiff_t start_byte,
22122 ptrdiff_t limit_byte, ptrdiff_t count,
22123 ptrdiff_t *byte_pos_ptr)
22125 register unsigned char *cursor;
22126 unsigned char *base;
22128 register ptrdiff_t ceiling;
22129 register unsigned char *ceiling_addr;
22130 ptrdiff_t orig_count = count;
22132 /* If we are not in selective display mode,
22133 check only for newlines. */
22134 int selective_display = (!NILP (BVAR (current_buffer, selective_display))
22135 && !INTEGERP (BVAR (current_buffer, selective_display)));
22137 if (count > 0)
22139 while (start_byte < limit_byte)
22141 ceiling = BUFFER_CEILING_OF (start_byte);
22142 ceiling = min (limit_byte - 1, ceiling);
22143 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
22144 base = (cursor = BYTE_POS_ADDR (start_byte));
22148 if (selective_display)
22150 while (*cursor != '\n' && *cursor != 015
22151 && ++cursor != ceiling_addr)
22152 continue;
22153 if (cursor == ceiling_addr)
22154 break;
22156 else
22158 cursor = memchr (cursor, '\n', ceiling_addr - cursor);
22159 if (! cursor)
22160 break;
22163 cursor++;
22165 if (--count == 0)
22167 start_byte += cursor - base;
22168 *byte_pos_ptr = start_byte;
22169 return orig_count;
22172 while (cursor < ceiling_addr);
22174 start_byte += ceiling_addr - base;
22177 else
22179 while (start_byte > limit_byte)
22181 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
22182 ceiling = max (limit_byte, ceiling);
22183 ceiling_addr = BYTE_POS_ADDR (ceiling);
22184 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
22185 while (1)
22187 if (selective_display)
22189 while (--cursor >= ceiling_addr
22190 && *cursor != '\n' && *cursor != 015)
22191 continue;
22192 if (cursor < ceiling_addr)
22193 break;
22195 else
22197 cursor = memrchr (ceiling_addr, '\n', cursor - ceiling_addr);
22198 if (! cursor)
22199 break;
22202 if (++count == 0)
22204 start_byte += cursor - base + 1;
22205 *byte_pos_ptr = start_byte;
22206 /* When scanning backwards, we should
22207 not count the newline posterior to which we stop. */
22208 return - orig_count - 1;
22211 start_byte += ceiling_addr - base;
22215 *byte_pos_ptr = limit_byte;
22217 if (count < 0)
22218 return - orig_count + count;
22219 return orig_count - count;
22225 /***********************************************************************
22226 Displaying strings
22227 ***********************************************************************/
22229 /* Display a NUL-terminated string, starting with index START.
22231 If STRING is non-null, display that C string. Otherwise, the Lisp
22232 string LISP_STRING is displayed. There's a case that STRING is
22233 non-null and LISP_STRING is not nil. It means STRING is a string
22234 data of LISP_STRING. In that case, we display LISP_STRING while
22235 ignoring its text properties.
22237 If FACE_STRING is not nil, FACE_STRING_POS is a position in
22238 FACE_STRING. Display STRING or LISP_STRING with the face at
22239 FACE_STRING_POS in FACE_STRING:
22241 Display the string in the environment given by IT, but use the
22242 standard display table, temporarily.
22244 FIELD_WIDTH is the minimum number of output glyphs to produce.
22245 If STRING has fewer characters than FIELD_WIDTH, pad to the right
22246 with spaces. If STRING has more characters, more than FIELD_WIDTH
22247 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
22249 PRECISION is the maximum number of characters to output from
22250 STRING. PRECISION < 0 means don't truncate the string.
22252 This is roughly equivalent to printf format specifiers:
22254 FIELD_WIDTH PRECISION PRINTF
22255 ----------------------------------------
22256 -1 -1 %s
22257 -1 10 %.10s
22258 10 -1 %10s
22259 20 10 %20.10s
22261 MULTIBYTE zero means do not display multibyte chars, > 0 means do
22262 display them, and < 0 means obey the current buffer's value of
22263 enable_multibyte_characters.
22265 Value is the number of columns displayed. */
22267 static int
22268 display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_string,
22269 ptrdiff_t face_string_pos, ptrdiff_t start, struct it *it,
22270 int field_width, int precision, int max_x, int multibyte)
22272 int hpos_at_start = it->hpos;
22273 int saved_face_id = it->face_id;
22274 struct glyph_row *row = it->glyph_row;
22275 ptrdiff_t it_charpos;
22277 /* Initialize the iterator IT for iteration over STRING beginning
22278 with index START. */
22279 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
22280 precision, field_width, multibyte);
22281 if (string && STRINGP (lisp_string))
22282 /* LISP_STRING is the one returned by decode_mode_spec. We should
22283 ignore its text properties. */
22284 it->stop_charpos = it->end_charpos;
22286 /* If displaying STRING, set up the face of the iterator from
22287 FACE_STRING, if that's given. */
22288 if (STRINGP (face_string))
22290 ptrdiff_t endptr;
22291 struct face *face;
22293 it->face_id
22294 = face_at_string_position (it->w, face_string, face_string_pos,
22295 0, it->region_beg_charpos,
22296 it->region_end_charpos,
22297 &endptr, it->base_face_id, 0);
22298 face = FACE_FROM_ID (it->f, it->face_id);
22299 it->face_box_p = face->box != FACE_NO_BOX;
22302 /* Set max_x to the maximum allowed X position. Don't let it go
22303 beyond the right edge of the window. */
22304 if (max_x <= 0)
22305 max_x = it->last_visible_x;
22306 else
22307 max_x = min (max_x, it->last_visible_x);
22309 /* Skip over display elements that are not visible. because IT->w is
22310 hscrolled. */
22311 if (it->current_x < it->first_visible_x)
22312 move_it_in_display_line_to (it, 100000, it->first_visible_x,
22313 MOVE_TO_POS | MOVE_TO_X);
22315 row->ascent = it->max_ascent;
22316 row->height = it->max_ascent + it->max_descent;
22317 row->phys_ascent = it->max_phys_ascent;
22318 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
22319 row->extra_line_spacing = it->max_extra_line_spacing;
22321 if (STRINGP (it->string))
22322 it_charpos = IT_STRING_CHARPOS (*it);
22323 else
22324 it_charpos = IT_CHARPOS (*it);
22326 /* This condition is for the case that we are called with current_x
22327 past last_visible_x. */
22328 while (it->current_x < max_x)
22330 int x_before, x, n_glyphs_before, i, nglyphs;
22332 /* Get the next display element. */
22333 if (!get_next_display_element (it))
22334 break;
22336 /* Produce glyphs. */
22337 x_before = it->current_x;
22338 n_glyphs_before = row->used[TEXT_AREA];
22339 PRODUCE_GLYPHS (it);
22341 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
22342 i = 0;
22343 x = x_before;
22344 while (i < nglyphs)
22346 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
22348 if (it->line_wrap != TRUNCATE
22349 && x + glyph->pixel_width > max_x)
22351 /* End of continued line or max_x reached. */
22352 if (CHAR_GLYPH_PADDING_P (*glyph))
22354 /* A wide character is unbreakable. */
22355 if (row->reversed_p)
22356 unproduce_glyphs (it, row->used[TEXT_AREA]
22357 - n_glyphs_before);
22358 row->used[TEXT_AREA] = n_glyphs_before;
22359 it->current_x = x_before;
22361 else
22363 if (row->reversed_p)
22364 unproduce_glyphs (it, row->used[TEXT_AREA]
22365 - (n_glyphs_before + i));
22366 row->used[TEXT_AREA] = n_glyphs_before + i;
22367 it->current_x = x;
22369 break;
22371 else if (x + glyph->pixel_width >= it->first_visible_x)
22373 /* Glyph is at least partially visible. */
22374 ++it->hpos;
22375 if (x < it->first_visible_x)
22376 row->x = x - it->first_visible_x;
22378 else
22380 /* Glyph is off the left margin of the display area.
22381 Should not happen. */
22382 emacs_abort ();
22385 row->ascent = max (row->ascent, it->max_ascent);
22386 row->height = max (row->height, it->max_ascent + it->max_descent);
22387 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
22388 row->phys_height = max (row->phys_height,
22389 it->max_phys_ascent + it->max_phys_descent);
22390 row->extra_line_spacing = max (row->extra_line_spacing,
22391 it->max_extra_line_spacing);
22392 x += glyph->pixel_width;
22393 ++i;
22396 /* Stop if max_x reached. */
22397 if (i < nglyphs)
22398 break;
22400 /* Stop at line ends. */
22401 if (ITERATOR_AT_END_OF_LINE_P (it))
22403 it->continuation_lines_width = 0;
22404 break;
22407 set_iterator_to_next (it, 1);
22408 if (STRINGP (it->string))
22409 it_charpos = IT_STRING_CHARPOS (*it);
22410 else
22411 it_charpos = IT_CHARPOS (*it);
22413 /* Stop if truncating at the right edge. */
22414 if (it->line_wrap == TRUNCATE
22415 && it->current_x >= it->last_visible_x)
22417 /* Add truncation mark, but don't do it if the line is
22418 truncated at a padding space. */
22419 if (it_charpos < it->string_nchars)
22421 if (!FRAME_WINDOW_P (it->f))
22423 int ii, n;
22425 if (it->current_x > it->last_visible_x)
22427 if (!row->reversed_p)
22429 for (ii = row->used[TEXT_AREA] - 1; ii > 0; --ii)
22430 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
22431 break;
22433 else
22435 for (ii = 0; ii < row->used[TEXT_AREA]; ii++)
22436 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
22437 break;
22438 unproduce_glyphs (it, ii + 1);
22439 ii = row->used[TEXT_AREA] - (ii + 1);
22441 for (n = row->used[TEXT_AREA]; ii < n; ++ii)
22443 row->used[TEXT_AREA] = ii;
22444 produce_special_glyphs (it, IT_TRUNCATION);
22447 produce_special_glyphs (it, IT_TRUNCATION);
22449 row->truncated_on_right_p = 1;
22451 break;
22455 /* Maybe insert a truncation at the left. */
22456 if (it->first_visible_x
22457 && it_charpos > 0)
22459 if (!FRAME_WINDOW_P (it->f)
22460 || (row->reversed_p
22461 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
22462 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
22463 insert_left_trunc_glyphs (it);
22464 row->truncated_on_left_p = 1;
22467 it->face_id = saved_face_id;
22469 /* Value is number of columns displayed. */
22470 return it->hpos - hpos_at_start;
22475 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
22476 appears as an element of LIST or as the car of an element of LIST.
22477 If PROPVAL is a list, compare each element against LIST in that
22478 way, and return 1/2 if any element of PROPVAL is found in LIST.
22479 Otherwise return 0. This function cannot quit.
22480 The return value is 2 if the text is invisible but with an ellipsis
22481 and 1 if it's invisible and without an ellipsis. */
22484 invisible_p (register Lisp_Object propval, Lisp_Object list)
22486 register Lisp_Object tail, proptail;
22488 for (tail = list; CONSP (tail); tail = XCDR (tail))
22490 register Lisp_Object tem;
22491 tem = XCAR (tail);
22492 if (EQ (propval, tem))
22493 return 1;
22494 if (CONSP (tem) && EQ (propval, XCAR (tem)))
22495 return NILP (XCDR (tem)) ? 1 : 2;
22498 if (CONSP (propval))
22500 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
22502 Lisp_Object propelt;
22503 propelt = XCAR (proptail);
22504 for (tail = list; CONSP (tail); tail = XCDR (tail))
22506 register Lisp_Object tem;
22507 tem = XCAR (tail);
22508 if (EQ (propelt, tem))
22509 return 1;
22510 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
22511 return NILP (XCDR (tem)) ? 1 : 2;
22516 return 0;
22519 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
22520 doc: /* Non-nil if the property makes the text invisible.
22521 POS-OR-PROP can be a marker or number, in which case it is taken to be
22522 a position in the current buffer and the value of the `invisible' property
22523 is checked; or it can be some other value, which is then presumed to be the
22524 value of the `invisible' property of the text of interest.
22525 The non-nil value returned can be t for truly invisible text or something
22526 else if the text is replaced by an ellipsis. */)
22527 (Lisp_Object pos_or_prop)
22529 Lisp_Object prop
22530 = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
22531 ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
22532 : pos_or_prop);
22533 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
22534 return (invis == 0 ? Qnil
22535 : invis == 1 ? Qt
22536 : make_number (invis));
22539 /* Calculate a width or height in pixels from a specification using
22540 the following elements:
22542 SPEC ::=
22543 NUM - a (fractional) multiple of the default font width/height
22544 (NUM) - specifies exactly NUM pixels
22545 UNIT - a fixed number of pixels, see below.
22546 ELEMENT - size of a display element in pixels, see below.
22547 (NUM . SPEC) - equals NUM * SPEC
22548 (+ SPEC SPEC ...) - add pixel values
22549 (- SPEC SPEC ...) - subtract pixel values
22550 (- SPEC) - negate pixel value
22552 NUM ::=
22553 INT or FLOAT - a number constant
22554 SYMBOL - use symbol's (buffer local) variable binding.
22556 UNIT ::=
22557 in - pixels per inch *)
22558 mm - pixels per 1/1000 meter *)
22559 cm - pixels per 1/100 meter *)
22560 width - width of current font in pixels.
22561 height - height of current font in pixels.
22563 *) using the ratio(s) defined in display-pixels-per-inch.
22565 ELEMENT ::=
22567 left-fringe - left fringe width in pixels
22568 right-fringe - right fringe width in pixels
22570 left-margin - left margin width in pixels
22571 right-margin - right margin width in pixels
22573 scroll-bar - scroll-bar area width in pixels
22575 Examples:
22577 Pixels corresponding to 5 inches:
22578 (5 . in)
22580 Total width of non-text areas on left side of window (if scroll-bar is on left):
22581 '(space :width (+ left-fringe left-margin scroll-bar))
22583 Align to first text column (in header line):
22584 '(space :align-to 0)
22586 Align to middle of text area minus half the width of variable `my-image'
22587 containing a loaded image:
22588 '(space :align-to (0.5 . (- text my-image)))
22590 Width of left margin minus width of 1 character in the default font:
22591 '(space :width (- left-margin 1))
22593 Width of left margin minus width of 2 characters in the current font:
22594 '(space :width (- left-margin (2 . width)))
22596 Center 1 character over left-margin (in header line):
22597 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
22599 Different ways to express width of left fringe plus left margin minus one pixel:
22600 '(space :width (- (+ left-fringe left-margin) (1)))
22601 '(space :width (+ left-fringe left-margin (- (1))))
22602 '(space :width (+ left-fringe left-margin (-1)))
22606 static int
22607 calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
22608 struct font *font, int width_p, int *align_to)
22610 double pixels;
22612 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
22613 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
22615 if (NILP (prop))
22616 return OK_PIXELS (0);
22618 eassert (FRAME_LIVE_P (it->f));
22620 if (SYMBOLP (prop))
22622 if (SCHARS (SYMBOL_NAME (prop)) == 2)
22624 char *unit = SSDATA (SYMBOL_NAME (prop));
22626 if (unit[0] == 'i' && unit[1] == 'n')
22627 pixels = 1.0;
22628 else if (unit[0] == 'm' && unit[1] == 'm')
22629 pixels = 25.4;
22630 else if (unit[0] == 'c' && unit[1] == 'm')
22631 pixels = 2.54;
22632 else
22633 pixels = 0;
22634 if (pixels > 0)
22636 double ppi = (width_p ? FRAME_RES_X (it->f)
22637 : FRAME_RES_Y (it->f));
22639 if (ppi > 0)
22640 return OK_PIXELS (ppi / pixels);
22641 return 0;
22645 #ifdef HAVE_WINDOW_SYSTEM
22646 if (EQ (prop, Qheight))
22647 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
22648 if (EQ (prop, Qwidth))
22649 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
22650 #else
22651 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
22652 return OK_PIXELS (1);
22653 #endif
22655 if (EQ (prop, Qtext))
22656 return OK_PIXELS (width_p
22657 ? window_box_width (it->w, TEXT_AREA)
22658 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
22660 if (align_to && *align_to < 0)
22662 *res = 0;
22663 if (EQ (prop, Qleft))
22664 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
22665 if (EQ (prop, Qright))
22666 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
22667 if (EQ (prop, Qcenter))
22668 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
22669 + window_box_width (it->w, TEXT_AREA) / 2);
22670 if (EQ (prop, Qleft_fringe))
22671 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22672 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
22673 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
22674 if (EQ (prop, Qright_fringe))
22675 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22676 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
22677 : window_box_right_offset (it->w, TEXT_AREA));
22678 if (EQ (prop, Qleft_margin))
22679 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
22680 if (EQ (prop, Qright_margin))
22681 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
22682 if (EQ (prop, Qscroll_bar))
22683 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
22685 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
22686 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22687 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
22688 : 0)));
22690 else
22692 if (EQ (prop, Qleft_fringe))
22693 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
22694 if (EQ (prop, Qright_fringe))
22695 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
22696 if (EQ (prop, Qleft_margin))
22697 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
22698 if (EQ (prop, Qright_margin))
22699 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
22700 if (EQ (prop, Qscroll_bar))
22701 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
22704 prop = buffer_local_value_1 (prop, it->w->contents);
22705 if (EQ (prop, Qunbound))
22706 prop = Qnil;
22709 if (INTEGERP (prop) || FLOATP (prop))
22711 int base_unit = (width_p
22712 ? FRAME_COLUMN_WIDTH (it->f)
22713 : FRAME_LINE_HEIGHT (it->f));
22714 return OK_PIXELS (XFLOATINT (prop) * base_unit);
22717 if (CONSP (prop))
22719 Lisp_Object car = XCAR (prop);
22720 Lisp_Object cdr = XCDR (prop);
22722 if (SYMBOLP (car))
22724 #ifdef HAVE_WINDOW_SYSTEM
22725 if (FRAME_WINDOW_P (it->f)
22726 && valid_image_p (prop))
22728 ptrdiff_t id = lookup_image (it->f, prop);
22729 struct image *img = IMAGE_FROM_ID (it->f, id);
22731 return OK_PIXELS (width_p ? img->width : img->height);
22733 #endif
22734 if (EQ (car, Qplus) || EQ (car, Qminus))
22736 int first = 1;
22737 double px;
22739 pixels = 0;
22740 while (CONSP (cdr))
22742 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
22743 font, width_p, align_to))
22744 return 0;
22745 if (first)
22746 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
22747 else
22748 pixels += px;
22749 cdr = XCDR (cdr);
22751 if (EQ (car, Qminus))
22752 pixels = -pixels;
22753 return OK_PIXELS (pixels);
22756 car = buffer_local_value_1 (car, it->w->contents);
22757 if (EQ (car, Qunbound))
22758 car = Qnil;
22761 if (INTEGERP (car) || FLOATP (car))
22763 double fact;
22764 pixels = XFLOATINT (car);
22765 if (NILP (cdr))
22766 return OK_PIXELS (pixels);
22767 if (calc_pixel_width_or_height (&fact, it, cdr,
22768 font, width_p, align_to))
22769 return OK_PIXELS (pixels * fact);
22770 return 0;
22773 return 0;
22776 return 0;
22780 /***********************************************************************
22781 Glyph Display
22782 ***********************************************************************/
22784 #ifdef HAVE_WINDOW_SYSTEM
22786 #ifdef GLYPH_DEBUG
22788 void
22789 dump_glyph_string (struct glyph_string *s)
22791 fprintf (stderr, "glyph string\n");
22792 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
22793 s->x, s->y, s->width, s->height);
22794 fprintf (stderr, " ybase = %d\n", s->ybase);
22795 fprintf (stderr, " hl = %d\n", s->hl);
22796 fprintf (stderr, " left overhang = %d, right = %d\n",
22797 s->left_overhang, s->right_overhang);
22798 fprintf (stderr, " nchars = %d\n", s->nchars);
22799 fprintf (stderr, " extends to end of line = %d\n",
22800 s->extends_to_end_of_line_p);
22801 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
22802 fprintf (stderr, " bg width = %d\n", s->background_width);
22805 #endif /* GLYPH_DEBUG */
22807 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
22808 of XChar2b structures for S; it can't be allocated in
22809 init_glyph_string because it must be allocated via `alloca'. W
22810 is the window on which S is drawn. ROW and AREA are the glyph row
22811 and area within the row from which S is constructed. START is the
22812 index of the first glyph structure covered by S. HL is a
22813 face-override for drawing S. */
22815 #ifdef HAVE_NTGUI
22816 #define OPTIONAL_HDC(hdc) HDC hdc,
22817 #define DECLARE_HDC(hdc) HDC hdc;
22818 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
22819 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
22820 #endif
22822 #ifndef OPTIONAL_HDC
22823 #define OPTIONAL_HDC(hdc)
22824 #define DECLARE_HDC(hdc)
22825 #define ALLOCATE_HDC(hdc, f)
22826 #define RELEASE_HDC(hdc, f)
22827 #endif
22829 static void
22830 init_glyph_string (struct glyph_string *s,
22831 OPTIONAL_HDC (hdc)
22832 XChar2b *char2b, struct window *w, struct glyph_row *row,
22833 enum glyph_row_area area, int start, enum draw_glyphs_face hl)
22835 memset (s, 0, sizeof *s);
22836 s->w = w;
22837 s->f = XFRAME (w->frame);
22838 #ifdef HAVE_NTGUI
22839 s->hdc = hdc;
22840 #endif
22841 s->display = FRAME_X_DISPLAY (s->f);
22842 s->window = FRAME_X_WINDOW (s->f);
22843 s->char2b = char2b;
22844 s->hl = hl;
22845 s->row = row;
22846 s->area = area;
22847 s->first_glyph = row->glyphs[area] + start;
22848 s->height = row->height;
22849 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
22850 s->ybase = s->y + row->ascent;
22854 /* Append the list of glyph strings with head H and tail T to the list
22855 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
22857 static void
22858 append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
22859 struct glyph_string *h, struct glyph_string *t)
22861 if (h)
22863 if (*head)
22864 (*tail)->next = h;
22865 else
22866 *head = h;
22867 h->prev = *tail;
22868 *tail = t;
22873 /* Prepend the list of glyph strings with head H and tail T to the
22874 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
22875 result. */
22877 static void
22878 prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
22879 struct glyph_string *h, struct glyph_string *t)
22881 if (h)
22883 if (*head)
22884 (*head)->prev = t;
22885 else
22886 *tail = t;
22887 t->next = *head;
22888 *head = h;
22893 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
22894 Set *HEAD and *TAIL to the resulting list. */
22896 static void
22897 append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
22898 struct glyph_string *s)
22900 s->next = s->prev = NULL;
22901 append_glyph_string_lists (head, tail, s, s);
22905 /* Get face and two-byte form of character C in face FACE_ID on frame F.
22906 The encoding of C is returned in *CHAR2B. DISPLAY_P non-zero means
22907 make sure that X resources for the face returned are allocated.
22908 Value is a pointer to a realized face that is ready for display if
22909 DISPLAY_P is non-zero. */
22911 static struct face *
22912 get_char_face_and_encoding (struct frame *f, int c, int face_id,
22913 XChar2b *char2b, int display_p)
22915 struct face *face = FACE_FROM_ID (f, face_id);
22916 unsigned code = 0;
22918 if (face->font)
22920 code = face->font->driver->encode_char (face->font, c);
22922 if (code == FONT_INVALID_CODE)
22923 code = 0;
22925 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
22927 /* Make sure X resources of the face are allocated. */
22928 #ifdef HAVE_X_WINDOWS
22929 if (display_p)
22930 #endif
22932 eassert (face != NULL);
22933 PREPARE_FACE_FOR_DISPLAY (f, face);
22936 return face;
22940 /* Get face and two-byte form of character glyph GLYPH on frame F.
22941 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
22942 a pointer to a realized face that is ready for display. */
22944 static struct face *
22945 get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
22946 XChar2b *char2b, int *two_byte_p)
22948 struct face *face;
22949 unsigned code = 0;
22951 eassert (glyph->type == CHAR_GLYPH);
22952 face = FACE_FROM_ID (f, glyph->face_id);
22954 /* Make sure X resources of the face are allocated. */
22955 eassert (face != NULL);
22956 PREPARE_FACE_FOR_DISPLAY (f, face);
22958 if (two_byte_p)
22959 *two_byte_p = 0;
22961 if (face->font)
22963 if (CHAR_BYTE8_P (glyph->u.ch))
22964 code = CHAR_TO_BYTE8 (glyph->u.ch);
22965 else
22966 code = face->font->driver->encode_char (face->font, glyph->u.ch);
22968 if (code == FONT_INVALID_CODE)
22969 code = 0;
22972 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
22973 return face;
22977 /* Get glyph code of character C in FONT in the two-byte form CHAR2B.
22978 Return 1 if FONT has a glyph for C, otherwise return 0. */
22980 static int
22981 get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
22983 unsigned code;
22985 if (CHAR_BYTE8_P (c))
22986 code = CHAR_TO_BYTE8 (c);
22987 else
22988 code = font->driver->encode_char (font, c);
22990 if (code == FONT_INVALID_CODE)
22991 return 0;
22992 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
22993 return 1;
22997 /* Fill glyph string S with composition components specified by S->cmp.
22999 BASE_FACE is the base face of the composition.
23000 S->cmp_from is the index of the first component for S.
23002 OVERLAPS non-zero means S should draw the foreground only, and use
23003 its physical height for clipping. See also draw_glyphs.
23005 Value is the index of a component not in S. */
23007 static int
23008 fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
23009 int overlaps)
23011 int i;
23012 /* For all glyphs of this composition, starting at the offset
23013 S->cmp_from, until we reach the end of the definition or encounter a
23014 glyph that requires the different face, add it to S. */
23015 struct face *face;
23017 eassert (s);
23019 s->for_overlaps = overlaps;
23020 s->face = NULL;
23021 s->font = NULL;
23022 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
23024 int c = COMPOSITION_GLYPH (s->cmp, i);
23026 /* TAB in a composition means display glyphs with padding space
23027 on the left or right. */
23028 if (c != '\t')
23030 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
23031 -1, Qnil);
23033 face = get_char_face_and_encoding (s->f, c, face_id,
23034 s->char2b + i, 1);
23035 if (face)
23037 if (! s->face)
23039 s->face = face;
23040 s->font = s->face->font;
23042 else if (s->face != face)
23043 break;
23046 ++s->nchars;
23048 s->cmp_to = i;
23050 if (s->face == NULL)
23052 s->face = base_face->ascii_face;
23053 s->font = s->face->font;
23056 /* All glyph strings for the same composition has the same width,
23057 i.e. the width set for the first component of the composition. */
23058 s->width = s->first_glyph->pixel_width;
23060 /* If the specified font could not be loaded, use the frame's
23061 default font, but record the fact that we couldn't load it in
23062 the glyph string so that we can draw rectangles for the
23063 characters of the glyph string. */
23064 if (s->font == NULL)
23066 s->font_not_found_p = 1;
23067 s->font = FRAME_FONT (s->f);
23070 /* Adjust base line for subscript/superscript text. */
23071 s->ybase += s->first_glyph->voffset;
23073 /* This glyph string must always be drawn with 16-bit functions. */
23074 s->two_byte_p = 1;
23076 return s->cmp_to;
23079 static int
23080 fill_gstring_glyph_string (struct glyph_string *s, int face_id,
23081 int start, int end, int overlaps)
23083 struct glyph *glyph, *last;
23084 Lisp_Object lgstring;
23085 int i;
23087 s->for_overlaps = overlaps;
23088 glyph = s->row->glyphs[s->area] + start;
23089 last = s->row->glyphs[s->area] + end;
23090 s->cmp_id = glyph->u.cmp.id;
23091 s->cmp_from = glyph->slice.cmp.from;
23092 s->cmp_to = glyph->slice.cmp.to + 1;
23093 s->face = FACE_FROM_ID (s->f, face_id);
23094 lgstring = composition_gstring_from_id (s->cmp_id);
23095 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
23096 glyph++;
23097 while (glyph < last
23098 && glyph->u.cmp.automatic
23099 && glyph->u.cmp.id == s->cmp_id
23100 && s->cmp_to == glyph->slice.cmp.from)
23101 s->cmp_to = (glyph++)->slice.cmp.to + 1;
23103 for (i = s->cmp_from; i < s->cmp_to; i++)
23105 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
23106 unsigned code = LGLYPH_CODE (lglyph);
23108 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
23110 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
23111 return glyph - s->row->glyphs[s->area];
23115 /* Fill glyph string S from a sequence glyphs for glyphless characters.
23116 See the comment of fill_glyph_string for arguments.
23117 Value is the index of the first glyph not in S. */
23120 static int
23121 fill_glyphless_glyph_string (struct glyph_string *s, int face_id,
23122 int start, int end, int overlaps)
23124 struct glyph *glyph, *last;
23125 int voffset;
23127 eassert (s->first_glyph->type == GLYPHLESS_GLYPH);
23128 s->for_overlaps = overlaps;
23129 glyph = s->row->glyphs[s->area] + start;
23130 last = s->row->glyphs[s->area] + end;
23131 voffset = glyph->voffset;
23132 s->face = FACE_FROM_ID (s->f, face_id);
23133 s->font = s->face->font ? s->face->font : FRAME_FONT (s->f);
23134 s->nchars = 1;
23135 s->width = glyph->pixel_width;
23136 glyph++;
23137 while (glyph < last
23138 && glyph->type == GLYPHLESS_GLYPH
23139 && glyph->voffset == voffset
23140 && glyph->face_id == face_id)
23142 s->nchars++;
23143 s->width += glyph->pixel_width;
23144 glyph++;
23146 s->ybase += voffset;
23147 return glyph - s->row->glyphs[s->area];
23151 /* Fill glyph string S from a sequence of character glyphs.
23153 FACE_ID is the face id of the string. START is the index of the
23154 first glyph to consider, END is the index of the last + 1.
23155 OVERLAPS non-zero means S should draw the foreground only, and use
23156 its physical height for clipping. See also draw_glyphs.
23158 Value is the index of the first glyph not in S. */
23160 static int
23161 fill_glyph_string (struct glyph_string *s, int face_id,
23162 int start, int end, int overlaps)
23164 struct glyph *glyph, *last;
23165 int voffset;
23166 int glyph_not_available_p;
23168 eassert (s->f == XFRAME (s->w->frame));
23169 eassert (s->nchars == 0);
23170 eassert (start >= 0 && end > start);
23172 s->for_overlaps = overlaps;
23173 glyph = s->row->glyphs[s->area] + start;
23174 last = s->row->glyphs[s->area] + end;
23175 voffset = glyph->voffset;
23176 s->padding_p = glyph->padding_p;
23177 glyph_not_available_p = glyph->glyph_not_available_p;
23179 while (glyph < last
23180 && glyph->type == CHAR_GLYPH
23181 && glyph->voffset == voffset
23182 /* Same face id implies same font, nowadays. */
23183 && glyph->face_id == face_id
23184 && glyph->glyph_not_available_p == glyph_not_available_p)
23186 int two_byte_p;
23188 s->face = get_glyph_face_and_encoding (s->f, glyph,
23189 s->char2b + s->nchars,
23190 &two_byte_p);
23191 s->two_byte_p = two_byte_p;
23192 ++s->nchars;
23193 eassert (s->nchars <= end - start);
23194 s->width += glyph->pixel_width;
23195 if (glyph++->padding_p != s->padding_p)
23196 break;
23199 s->font = s->face->font;
23201 /* If the specified font could not be loaded, use the frame's font,
23202 but record the fact that we couldn't load it in
23203 S->font_not_found_p so that we can draw rectangles for the
23204 characters of the glyph string. */
23205 if (s->font == NULL || glyph_not_available_p)
23207 s->font_not_found_p = 1;
23208 s->font = FRAME_FONT (s->f);
23211 /* Adjust base line for subscript/superscript text. */
23212 s->ybase += voffset;
23214 eassert (s->face && s->face->gc);
23215 return glyph - s->row->glyphs[s->area];
23219 /* Fill glyph string S from image glyph S->first_glyph. */
23221 static void
23222 fill_image_glyph_string (struct glyph_string *s)
23224 eassert (s->first_glyph->type == IMAGE_GLYPH);
23225 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
23226 eassert (s->img);
23227 s->slice = s->first_glyph->slice.img;
23228 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
23229 s->font = s->face->font;
23230 s->width = s->first_glyph->pixel_width;
23232 /* Adjust base line for subscript/superscript text. */
23233 s->ybase += s->first_glyph->voffset;
23237 /* Fill glyph string S from a sequence of stretch glyphs.
23239 START is the index of the first glyph to consider,
23240 END is the index of the last + 1.
23242 Value is the index of the first glyph not in S. */
23244 static int
23245 fill_stretch_glyph_string (struct glyph_string *s, int start, int end)
23247 struct glyph *glyph, *last;
23248 int voffset, face_id;
23250 eassert (s->first_glyph->type == STRETCH_GLYPH);
23252 glyph = s->row->glyphs[s->area] + start;
23253 last = s->row->glyphs[s->area] + end;
23254 face_id = glyph->face_id;
23255 s->face = FACE_FROM_ID (s->f, face_id);
23256 s->font = s->face->font;
23257 s->width = glyph->pixel_width;
23258 s->nchars = 1;
23259 voffset = glyph->voffset;
23261 for (++glyph;
23262 (glyph < last
23263 && glyph->type == STRETCH_GLYPH
23264 && glyph->voffset == voffset
23265 && glyph->face_id == face_id);
23266 ++glyph)
23267 s->width += glyph->pixel_width;
23269 /* Adjust base line for subscript/superscript text. */
23270 s->ybase += voffset;
23272 /* The case that face->gc == 0 is handled when drawing the glyph
23273 string by calling PREPARE_FACE_FOR_DISPLAY. */
23274 eassert (s->face);
23275 return glyph - s->row->glyphs[s->area];
23278 static struct font_metrics *
23279 get_per_char_metric (struct font *font, XChar2b *char2b)
23281 static struct font_metrics metrics;
23282 unsigned code;
23284 if (! font)
23285 return NULL;
23286 code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
23287 if (code == FONT_INVALID_CODE)
23288 return NULL;
23289 font->driver->text_extents (font, &code, 1, &metrics);
23290 return &metrics;
23293 /* EXPORT for RIF:
23294 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
23295 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
23296 assumed to be zero. */
23298 void
23299 x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *right)
23301 *left = *right = 0;
23303 if (glyph->type == CHAR_GLYPH)
23305 struct face *face;
23306 XChar2b char2b;
23307 struct font_metrics *pcm;
23309 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
23310 if (face->font && (pcm = get_per_char_metric (face->font, &char2b)))
23312 if (pcm->rbearing > pcm->width)
23313 *right = pcm->rbearing - pcm->width;
23314 if (pcm->lbearing < 0)
23315 *left = -pcm->lbearing;
23318 else if (glyph->type == COMPOSITE_GLYPH)
23320 if (! glyph->u.cmp.automatic)
23322 struct composition *cmp = composition_table[glyph->u.cmp.id];
23324 if (cmp->rbearing > cmp->pixel_width)
23325 *right = cmp->rbearing - cmp->pixel_width;
23326 if (cmp->lbearing < 0)
23327 *left = - cmp->lbearing;
23329 else
23331 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
23332 struct font_metrics metrics;
23334 composition_gstring_width (gstring, glyph->slice.cmp.from,
23335 glyph->slice.cmp.to + 1, &metrics);
23336 if (metrics.rbearing > metrics.width)
23337 *right = metrics.rbearing - metrics.width;
23338 if (metrics.lbearing < 0)
23339 *left = - metrics.lbearing;
23345 /* Return the index of the first glyph preceding glyph string S that
23346 is overwritten by S because of S's left overhang. Value is -1
23347 if no glyphs are overwritten. */
23349 static int
23350 left_overwritten (struct glyph_string *s)
23352 int k;
23354 if (s->left_overhang)
23356 int x = 0, i;
23357 struct glyph *glyphs = s->row->glyphs[s->area];
23358 int first = s->first_glyph - glyphs;
23360 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
23361 x -= glyphs[i].pixel_width;
23363 k = i + 1;
23365 else
23366 k = -1;
23368 return k;
23372 /* Return the index of the first glyph preceding glyph string S that
23373 is overwriting S because of its right overhang. Value is -1 if no
23374 glyph in front of S overwrites S. */
23376 static int
23377 left_overwriting (struct glyph_string *s)
23379 int i, k, x;
23380 struct glyph *glyphs = s->row->glyphs[s->area];
23381 int first = s->first_glyph - glyphs;
23383 k = -1;
23384 x = 0;
23385 for (i = first - 1; i >= 0; --i)
23387 int left, right;
23388 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
23389 if (x + right > 0)
23390 k = i;
23391 x -= glyphs[i].pixel_width;
23394 return k;
23398 /* Return the index of the last glyph following glyph string S that is
23399 overwritten by S because of S's right overhang. Value is -1 if
23400 no such glyph is found. */
23402 static int
23403 right_overwritten (struct glyph_string *s)
23405 int k = -1;
23407 if (s->right_overhang)
23409 int x = 0, i;
23410 struct glyph *glyphs = s->row->glyphs[s->area];
23411 int first = (s->first_glyph - glyphs
23412 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
23413 int end = s->row->used[s->area];
23415 for (i = first; i < end && s->right_overhang > x; ++i)
23416 x += glyphs[i].pixel_width;
23418 k = i;
23421 return k;
23425 /* Return the index of the last glyph following glyph string S that
23426 overwrites S because of its left overhang. Value is negative
23427 if no such glyph is found. */
23429 static int
23430 right_overwriting (struct glyph_string *s)
23432 int i, k, x;
23433 int end = s->row->used[s->area];
23434 struct glyph *glyphs = s->row->glyphs[s->area];
23435 int first = (s->first_glyph - glyphs
23436 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
23438 k = -1;
23439 x = 0;
23440 for (i = first; i < end; ++i)
23442 int left, right;
23443 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
23444 if (x - left < 0)
23445 k = i;
23446 x += glyphs[i].pixel_width;
23449 return k;
23453 /* Set background width of glyph string S. START is the index of the
23454 first glyph following S. LAST_X is the right-most x-position + 1
23455 in the drawing area. */
23457 static void
23458 set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
23460 /* If the face of this glyph string has to be drawn to the end of
23461 the drawing area, set S->extends_to_end_of_line_p. */
23463 if (start == s->row->used[s->area]
23464 && s->area == TEXT_AREA
23465 && ((s->row->fill_line_p
23466 && (s->hl == DRAW_NORMAL_TEXT
23467 || s->hl == DRAW_IMAGE_RAISED
23468 || s->hl == DRAW_IMAGE_SUNKEN))
23469 || s->hl == DRAW_MOUSE_FACE))
23470 s->extends_to_end_of_line_p = 1;
23472 /* If S extends its face to the end of the line, set its
23473 background_width to the distance to the right edge of the drawing
23474 area. */
23475 if (s->extends_to_end_of_line_p)
23476 s->background_width = last_x - s->x + 1;
23477 else
23478 s->background_width = s->width;
23482 /* Compute overhangs and x-positions for glyph string S and its
23483 predecessors, or successors. X is the starting x-position for S.
23484 BACKWARD_P non-zero means process predecessors. */
23486 static void
23487 compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
23489 if (backward_p)
23491 while (s)
23493 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
23494 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
23495 x -= s->width;
23496 s->x = x;
23497 s = s->prev;
23500 else
23502 while (s)
23504 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
23505 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
23506 s->x = x;
23507 x += s->width;
23508 s = s->next;
23515 /* The following macros are only called from draw_glyphs below.
23516 They reference the following parameters of that function directly:
23517 `w', `row', `area', and `overlap_p'
23518 as well as the following local variables:
23519 `s', `f', and `hdc' (in W32) */
23521 #ifdef HAVE_NTGUI
23522 /* On W32, silently add local `hdc' variable to argument list of
23523 init_glyph_string. */
23524 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
23525 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
23526 #else
23527 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
23528 init_glyph_string (s, char2b, w, row, area, start, hl)
23529 #endif
23531 /* Add a glyph string for a stretch glyph to the list of strings
23532 between HEAD and TAIL. START is the index of the stretch glyph in
23533 row area AREA of glyph row ROW. END is the index of the last glyph
23534 in that glyph row area. X is the current output position assigned
23535 to the new glyph string constructed. HL overrides that face of the
23536 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
23537 is the right-most x-position of the drawing area. */
23539 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
23540 and below -- keep them on one line. */
23541 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23542 do \
23544 s = alloca (sizeof *s); \
23545 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23546 START = fill_stretch_glyph_string (s, START, END); \
23547 append_glyph_string (&HEAD, &TAIL, s); \
23548 s->x = (X); \
23550 while (0)
23553 /* Add a glyph string for an image glyph to the list of strings
23554 between HEAD and TAIL. START is the index of the image glyph in
23555 row area AREA of glyph row ROW. END is the index of the last glyph
23556 in that glyph row area. X is the current output position assigned
23557 to the new glyph string constructed. HL overrides that face of the
23558 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
23559 is the right-most x-position of the drawing area. */
23561 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23562 do \
23564 s = alloca (sizeof *s); \
23565 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23566 fill_image_glyph_string (s); \
23567 append_glyph_string (&HEAD, &TAIL, s); \
23568 ++START; \
23569 s->x = (X); \
23571 while (0)
23574 /* Add a glyph string for a sequence of character glyphs to the list
23575 of strings between HEAD and TAIL. START is the index of the first
23576 glyph in row area AREA of glyph row ROW that is part of the new
23577 glyph string. END is the index of the last glyph in that glyph row
23578 area. X is the current output position assigned to the new glyph
23579 string constructed. HL overrides that face of the glyph; e.g. it
23580 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
23581 right-most x-position of the drawing area. */
23583 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
23584 do \
23586 int face_id; \
23587 XChar2b *char2b; \
23589 face_id = (row)->glyphs[area][START].face_id; \
23591 s = alloca (sizeof *s); \
23592 char2b = alloca ((END - START) * sizeof *char2b); \
23593 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23594 append_glyph_string (&HEAD, &TAIL, s); \
23595 s->x = (X); \
23596 START = fill_glyph_string (s, face_id, START, END, overlaps); \
23598 while (0)
23601 /* Add a glyph string for a composite sequence to the list of strings
23602 between HEAD and TAIL. START is the index of the first glyph in
23603 row area AREA of glyph row ROW that is part of the new glyph
23604 string. END is the index of the last glyph in that glyph row area.
23605 X is the current output position assigned to the new glyph string
23606 constructed. HL overrides that face of the glyph; e.g. it is
23607 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
23608 x-position of the drawing area. */
23610 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23611 do { \
23612 int face_id = (row)->glyphs[area][START].face_id; \
23613 struct face *base_face = FACE_FROM_ID (f, face_id); \
23614 ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \
23615 struct composition *cmp = composition_table[cmp_id]; \
23616 XChar2b *char2b; \
23617 struct glyph_string *first_s = NULL; \
23618 int n; \
23620 char2b = alloca (cmp->glyph_len * sizeof *char2b); \
23622 /* Make glyph_strings for each glyph sequence that is drawable by \
23623 the same face, and append them to HEAD/TAIL. */ \
23624 for (n = 0; n < cmp->glyph_len;) \
23626 s = alloca (sizeof *s); \
23627 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23628 append_glyph_string (&(HEAD), &(TAIL), s); \
23629 s->cmp = cmp; \
23630 s->cmp_from = n; \
23631 s->x = (X); \
23632 if (n == 0) \
23633 first_s = s; \
23634 n = fill_composite_glyph_string (s, base_face, overlaps); \
23637 ++START; \
23638 s = first_s; \
23639 } while (0)
23642 /* Add a glyph string for a glyph-string sequence to the list of strings
23643 between HEAD and TAIL. */
23645 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23646 do { \
23647 int face_id; \
23648 XChar2b *char2b; \
23649 Lisp_Object gstring; \
23651 face_id = (row)->glyphs[area][START].face_id; \
23652 gstring = (composition_gstring_from_id \
23653 ((row)->glyphs[area][START].u.cmp.id)); \
23654 s = alloca (sizeof *s); \
23655 char2b = alloca (LGSTRING_GLYPH_LEN (gstring) * sizeof *char2b); \
23656 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23657 append_glyph_string (&(HEAD), &(TAIL), s); \
23658 s->x = (X); \
23659 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
23660 } while (0)
23663 /* Add a glyph string for a sequence of glyphless character's glyphs
23664 to the list of strings between HEAD and TAIL. The meanings of
23665 arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */
23667 #define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23668 do \
23670 int face_id; \
23672 face_id = (row)->glyphs[area][START].face_id; \
23674 s = alloca (sizeof *s); \
23675 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23676 append_glyph_string (&HEAD, &TAIL, s); \
23677 s->x = (X); \
23678 START = fill_glyphless_glyph_string (s, face_id, START, END, \
23679 overlaps); \
23681 while (0)
23684 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
23685 of AREA of glyph row ROW on window W between indices START and END.
23686 HL overrides the face for drawing glyph strings, e.g. it is
23687 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
23688 x-positions of the drawing area.
23690 This is an ugly monster macro construct because we must use alloca
23691 to allocate glyph strings (because draw_glyphs can be called
23692 asynchronously). */
23694 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
23695 do \
23697 HEAD = TAIL = NULL; \
23698 while (START < END) \
23700 struct glyph *first_glyph = (row)->glyphs[area] + START; \
23701 switch (first_glyph->type) \
23703 case CHAR_GLYPH: \
23704 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
23705 HL, X, LAST_X); \
23706 break; \
23708 case COMPOSITE_GLYPH: \
23709 if (first_glyph->u.cmp.automatic) \
23710 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
23711 HL, X, LAST_X); \
23712 else \
23713 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
23714 HL, X, LAST_X); \
23715 break; \
23717 case STRETCH_GLYPH: \
23718 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
23719 HL, X, LAST_X); \
23720 break; \
23722 case IMAGE_GLYPH: \
23723 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
23724 HL, X, LAST_X); \
23725 break; \
23727 case GLYPHLESS_GLYPH: \
23728 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
23729 HL, X, LAST_X); \
23730 break; \
23732 default: \
23733 emacs_abort (); \
23736 if (s) \
23738 set_glyph_string_background_width (s, START, LAST_X); \
23739 (X) += s->width; \
23742 } while (0)
23745 /* Draw glyphs between START and END in AREA of ROW on window W,
23746 starting at x-position X. X is relative to AREA in W. HL is a
23747 face-override with the following meaning:
23749 DRAW_NORMAL_TEXT draw normally
23750 DRAW_CURSOR draw in cursor face
23751 DRAW_MOUSE_FACE draw in mouse face.
23752 DRAW_INVERSE_VIDEO draw in mode line face
23753 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
23754 DRAW_IMAGE_RAISED draw an image with a raised relief around it
23756 If OVERLAPS is non-zero, draw only the foreground of characters and
23757 clip to the physical height of ROW. Non-zero value also defines
23758 the overlapping part to be drawn:
23760 OVERLAPS_PRED overlap with preceding rows
23761 OVERLAPS_SUCC overlap with succeeding rows
23762 OVERLAPS_BOTH overlap with both preceding/succeeding rows
23763 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
23765 Value is the x-position reached, relative to AREA of W. */
23767 static int
23768 draw_glyphs (struct window *w, int x, struct glyph_row *row,
23769 enum glyph_row_area area, ptrdiff_t start, ptrdiff_t end,
23770 enum draw_glyphs_face hl, int overlaps)
23772 struct glyph_string *head, *tail;
23773 struct glyph_string *s;
23774 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
23775 int i, j, x_reached, last_x, area_left = 0;
23776 struct frame *f = XFRAME (WINDOW_FRAME (w));
23777 DECLARE_HDC (hdc);
23779 ALLOCATE_HDC (hdc, f);
23781 /* Let's rather be paranoid than getting a SEGV. */
23782 end = min (end, row->used[area]);
23783 start = clip_to_bounds (0, start, end);
23785 /* Translate X to frame coordinates. Set last_x to the right
23786 end of the drawing area. */
23787 if (row->full_width_p)
23789 /* X is relative to the left edge of W, without scroll bars
23790 or fringes. */
23791 area_left = WINDOW_LEFT_EDGE_X (w);
23792 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
23794 else
23796 area_left = window_box_left (w, area);
23797 last_x = area_left + window_box_width (w, area);
23799 x += area_left;
23801 /* Build a doubly-linked list of glyph_string structures between
23802 head and tail from what we have to draw. Note that the macro
23803 BUILD_GLYPH_STRINGS will modify its start parameter. That's
23804 the reason we use a separate variable `i'. */
23805 i = start;
23806 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
23807 if (tail)
23808 x_reached = tail->x + tail->background_width;
23809 else
23810 x_reached = x;
23812 /* If there are any glyphs with lbearing < 0 or rbearing > width in
23813 the row, redraw some glyphs in front or following the glyph
23814 strings built above. */
23815 if (head && !overlaps && row->contains_overlapping_glyphs_p)
23817 struct glyph_string *h, *t;
23818 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
23819 int mouse_beg_col IF_LINT (= 0), mouse_end_col IF_LINT (= 0);
23820 int check_mouse_face = 0;
23821 int dummy_x = 0;
23823 /* If mouse highlighting is on, we may need to draw adjacent
23824 glyphs using mouse-face highlighting. */
23825 if (area == TEXT_AREA && row->mouse_face_p
23826 && hlinfo->mouse_face_beg_row >= 0
23827 && hlinfo->mouse_face_end_row >= 0)
23829 ptrdiff_t row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
23831 if (row_vpos >= hlinfo->mouse_face_beg_row
23832 && row_vpos <= hlinfo->mouse_face_end_row)
23834 check_mouse_face = 1;
23835 mouse_beg_col = (row_vpos == hlinfo->mouse_face_beg_row)
23836 ? hlinfo->mouse_face_beg_col : 0;
23837 mouse_end_col = (row_vpos == hlinfo->mouse_face_end_row)
23838 ? hlinfo->mouse_face_end_col
23839 : row->used[TEXT_AREA];
23843 /* Compute overhangs for all glyph strings. */
23844 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
23845 for (s = head; s; s = s->next)
23846 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
23848 /* Prepend glyph strings for glyphs in front of the first glyph
23849 string that are overwritten because of the first glyph
23850 string's left overhang. The background of all strings
23851 prepended must be drawn because the first glyph string
23852 draws over it. */
23853 i = left_overwritten (head);
23854 if (i >= 0)
23856 enum draw_glyphs_face overlap_hl;
23858 /* If this row contains mouse highlighting, attempt to draw
23859 the overlapped glyphs with the correct highlight. This
23860 code fails if the overlap encompasses more than one glyph
23861 and mouse-highlight spans only some of these glyphs.
23862 However, making it work perfectly involves a lot more
23863 code, and I don't know if the pathological case occurs in
23864 practice, so we'll stick to this for now. --- cyd */
23865 if (check_mouse_face
23866 && mouse_beg_col < start && mouse_end_col > i)
23867 overlap_hl = DRAW_MOUSE_FACE;
23868 else
23869 overlap_hl = DRAW_NORMAL_TEXT;
23871 j = i;
23872 BUILD_GLYPH_STRINGS (j, start, h, t,
23873 overlap_hl, dummy_x, last_x);
23874 start = i;
23875 compute_overhangs_and_x (t, head->x, 1);
23876 prepend_glyph_string_lists (&head, &tail, h, t);
23877 clip_head = head;
23880 /* Prepend glyph strings for glyphs in front of the first glyph
23881 string that overwrite that glyph string because of their
23882 right overhang. For these strings, only the foreground must
23883 be drawn, because it draws over the glyph string at `head'.
23884 The background must not be drawn because this would overwrite
23885 right overhangs of preceding glyphs for which no glyph
23886 strings exist. */
23887 i = left_overwriting (head);
23888 if (i >= 0)
23890 enum draw_glyphs_face overlap_hl;
23892 if (check_mouse_face
23893 && mouse_beg_col < start && mouse_end_col > i)
23894 overlap_hl = DRAW_MOUSE_FACE;
23895 else
23896 overlap_hl = DRAW_NORMAL_TEXT;
23898 clip_head = head;
23899 BUILD_GLYPH_STRINGS (i, start, h, t,
23900 overlap_hl, dummy_x, last_x);
23901 for (s = h; s; s = s->next)
23902 s->background_filled_p = 1;
23903 compute_overhangs_and_x (t, head->x, 1);
23904 prepend_glyph_string_lists (&head, &tail, h, t);
23907 /* Append glyphs strings for glyphs following the last glyph
23908 string tail that are overwritten by tail. The background of
23909 these strings has to be drawn because tail's foreground draws
23910 over it. */
23911 i = right_overwritten (tail);
23912 if (i >= 0)
23914 enum draw_glyphs_face overlap_hl;
23916 if (check_mouse_face
23917 && mouse_beg_col < i && mouse_end_col > end)
23918 overlap_hl = DRAW_MOUSE_FACE;
23919 else
23920 overlap_hl = DRAW_NORMAL_TEXT;
23922 BUILD_GLYPH_STRINGS (end, i, h, t,
23923 overlap_hl, x, last_x);
23924 /* Because BUILD_GLYPH_STRINGS updates the first argument,
23925 we don't have `end = i;' here. */
23926 compute_overhangs_and_x (h, tail->x + tail->width, 0);
23927 append_glyph_string_lists (&head, &tail, h, t);
23928 clip_tail = tail;
23931 /* Append glyph strings for glyphs following the last glyph
23932 string tail that overwrite tail. The foreground of such
23933 glyphs has to be drawn because it writes into the background
23934 of tail. The background must not be drawn because it could
23935 paint over the foreground of following glyphs. */
23936 i = right_overwriting (tail);
23937 if (i >= 0)
23939 enum draw_glyphs_face overlap_hl;
23940 if (check_mouse_face
23941 && mouse_beg_col < i && mouse_end_col > end)
23942 overlap_hl = DRAW_MOUSE_FACE;
23943 else
23944 overlap_hl = DRAW_NORMAL_TEXT;
23946 clip_tail = tail;
23947 i++; /* We must include the Ith glyph. */
23948 BUILD_GLYPH_STRINGS (end, i, h, t,
23949 overlap_hl, x, last_x);
23950 for (s = h; s; s = s->next)
23951 s->background_filled_p = 1;
23952 compute_overhangs_and_x (h, tail->x + tail->width, 0);
23953 append_glyph_string_lists (&head, &tail, h, t);
23955 if (clip_head || clip_tail)
23956 for (s = head; s; s = s->next)
23958 s->clip_head = clip_head;
23959 s->clip_tail = clip_tail;
23963 /* Draw all strings. */
23964 for (s = head; s; s = s->next)
23965 FRAME_RIF (f)->draw_glyph_string (s);
23967 #ifndef HAVE_NS
23968 /* When focus a sole frame and move horizontally, this sets on_p to 0
23969 causing a failure to erase prev cursor position. */
23970 if (area == TEXT_AREA
23971 && !row->full_width_p
23972 /* When drawing overlapping rows, only the glyph strings'
23973 foreground is drawn, which doesn't erase a cursor
23974 completely. */
23975 && !overlaps)
23977 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
23978 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
23979 : (tail ? tail->x + tail->background_width : x));
23980 x0 -= area_left;
23981 x1 -= area_left;
23983 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
23984 row->y, MATRIX_ROW_BOTTOM_Y (row));
23986 #endif
23988 /* Value is the x-position up to which drawn, relative to AREA of W.
23989 This doesn't include parts drawn because of overhangs. */
23990 if (row->full_width_p)
23991 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
23992 else
23993 x_reached -= area_left;
23995 RELEASE_HDC (hdc, f);
23997 return x_reached;
24000 /* Expand row matrix if too narrow. Don't expand if area
24001 is not present. */
24003 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
24005 if (!fonts_changed_p \
24006 && (it->glyph_row->glyphs[area] \
24007 < it->glyph_row->glyphs[area + 1])) \
24009 it->w->ncols_scale_factor++; \
24010 fonts_changed_p = 1; \
24014 /* Store one glyph for IT->char_to_display in IT->glyph_row.
24015 Called from x_produce_glyphs when IT->glyph_row is non-null. */
24017 static void
24018 append_glyph (struct it *it)
24020 struct glyph *glyph;
24021 enum glyph_row_area area = it->area;
24023 eassert (it->glyph_row);
24024 eassert (it->char_to_display != '\n' && it->char_to_display != '\t');
24026 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24027 if (glyph < it->glyph_row->glyphs[area + 1])
24029 /* If the glyph row is reversed, we need to prepend the glyph
24030 rather than append it. */
24031 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24033 struct glyph *g;
24035 /* Make room for the additional glyph. */
24036 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
24037 g[1] = *g;
24038 glyph = it->glyph_row->glyphs[area];
24040 glyph->charpos = CHARPOS (it->position);
24041 glyph->object = it->object;
24042 if (it->pixel_width > 0)
24044 glyph->pixel_width = it->pixel_width;
24045 glyph->padding_p = 0;
24047 else
24049 /* Assure at least 1-pixel width. Otherwise, cursor can't
24050 be displayed correctly. */
24051 glyph->pixel_width = 1;
24052 glyph->padding_p = 1;
24054 glyph->ascent = it->ascent;
24055 glyph->descent = it->descent;
24056 glyph->voffset = it->voffset;
24057 glyph->type = CHAR_GLYPH;
24058 glyph->avoid_cursor_p = it->avoid_cursor_p;
24059 glyph->multibyte_p = it->multibyte_p;
24060 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24062 /* In R2L rows, the left and the right box edges need to be
24063 drawn in reverse direction. */
24064 glyph->right_box_line_p = it->start_of_box_run_p;
24065 glyph->left_box_line_p = it->end_of_box_run_p;
24067 else
24069 glyph->left_box_line_p = it->start_of_box_run_p;
24070 glyph->right_box_line_p = it->end_of_box_run_p;
24072 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
24073 || it->phys_descent > it->descent);
24074 glyph->glyph_not_available_p = it->glyph_not_available_p;
24075 glyph->face_id = it->face_id;
24076 glyph->u.ch = it->char_to_display;
24077 glyph->slice.img = null_glyph_slice;
24078 glyph->font_type = FONT_TYPE_UNKNOWN;
24079 if (it->bidi_p)
24081 glyph->resolved_level = it->bidi_it.resolved_level;
24082 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24083 emacs_abort ();
24084 glyph->bidi_type = it->bidi_it.type;
24086 else
24088 glyph->resolved_level = 0;
24089 glyph->bidi_type = UNKNOWN_BT;
24091 ++it->glyph_row->used[area];
24093 else
24094 IT_EXPAND_MATRIX_WIDTH (it, area);
24097 /* Store one glyph for the composition IT->cmp_it.id in
24098 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
24099 non-null. */
24101 static void
24102 append_composite_glyph (struct it *it)
24104 struct glyph *glyph;
24105 enum glyph_row_area area = it->area;
24107 eassert (it->glyph_row);
24109 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24110 if (glyph < it->glyph_row->glyphs[area + 1])
24112 /* If the glyph row is reversed, we need to prepend the glyph
24113 rather than append it. */
24114 if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
24116 struct glyph *g;
24118 /* Make room for the new glyph. */
24119 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
24120 g[1] = *g;
24121 glyph = it->glyph_row->glyphs[it->area];
24123 glyph->charpos = it->cmp_it.charpos;
24124 glyph->object = it->object;
24125 glyph->pixel_width = it->pixel_width;
24126 glyph->ascent = it->ascent;
24127 glyph->descent = it->descent;
24128 glyph->voffset = it->voffset;
24129 glyph->type = COMPOSITE_GLYPH;
24130 if (it->cmp_it.ch < 0)
24132 glyph->u.cmp.automatic = 0;
24133 glyph->u.cmp.id = it->cmp_it.id;
24134 glyph->slice.cmp.from = glyph->slice.cmp.to = 0;
24136 else
24138 glyph->u.cmp.automatic = 1;
24139 glyph->u.cmp.id = it->cmp_it.id;
24140 glyph->slice.cmp.from = it->cmp_it.from;
24141 glyph->slice.cmp.to = it->cmp_it.to - 1;
24143 glyph->avoid_cursor_p = it->avoid_cursor_p;
24144 glyph->multibyte_p = it->multibyte_p;
24145 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24147 /* In R2L rows, the left and the right box edges need to be
24148 drawn in reverse direction. */
24149 glyph->right_box_line_p = it->start_of_box_run_p;
24150 glyph->left_box_line_p = it->end_of_box_run_p;
24152 else
24154 glyph->left_box_line_p = it->start_of_box_run_p;
24155 glyph->right_box_line_p = it->end_of_box_run_p;
24157 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
24158 || it->phys_descent > it->descent);
24159 glyph->padding_p = 0;
24160 glyph->glyph_not_available_p = 0;
24161 glyph->face_id = it->face_id;
24162 glyph->font_type = FONT_TYPE_UNKNOWN;
24163 if (it->bidi_p)
24165 glyph->resolved_level = it->bidi_it.resolved_level;
24166 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24167 emacs_abort ();
24168 glyph->bidi_type = it->bidi_it.type;
24170 ++it->glyph_row->used[area];
24172 else
24173 IT_EXPAND_MATRIX_WIDTH (it, area);
24177 /* Change IT->ascent and IT->height according to the setting of
24178 IT->voffset. */
24180 static void
24181 take_vertical_position_into_account (struct it *it)
24183 if (it->voffset)
24185 if (it->voffset < 0)
24186 /* Increase the ascent so that we can display the text higher
24187 in the line. */
24188 it->ascent -= it->voffset;
24189 else
24190 /* Increase the descent so that we can display the text lower
24191 in the line. */
24192 it->descent += it->voffset;
24197 /* Produce glyphs/get display metrics for the image IT is loaded with.
24198 See the description of struct display_iterator in dispextern.h for
24199 an overview of struct display_iterator. */
24201 static void
24202 produce_image_glyph (struct it *it)
24204 struct image *img;
24205 struct face *face;
24206 int glyph_ascent, crop;
24207 struct glyph_slice slice;
24209 eassert (it->what == IT_IMAGE);
24211 face = FACE_FROM_ID (it->f, it->face_id);
24212 eassert (face);
24213 /* Make sure X resources of the face is loaded. */
24214 PREPARE_FACE_FOR_DISPLAY (it->f, face);
24216 if (it->image_id < 0)
24218 /* Fringe bitmap. */
24219 it->ascent = it->phys_ascent = 0;
24220 it->descent = it->phys_descent = 0;
24221 it->pixel_width = 0;
24222 it->nglyphs = 0;
24223 return;
24226 img = IMAGE_FROM_ID (it->f, it->image_id);
24227 eassert (img);
24228 /* Make sure X resources of the image is loaded. */
24229 prepare_image_for_display (it->f, img);
24231 slice.x = slice.y = 0;
24232 slice.width = img->width;
24233 slice.height = img->height;
24235 if (INTEGERP (it->slice.x))
24236 slice.x = XINT (it->slice.x);
24237 else if (FLOATP (it->slice.x))
24238 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
24240 if (INTEGERP (it->slice.y))
24241 slice.y = XINT (it->slice.y);
24242 else if (FLOATP (it->slice.y))
24243 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
24245 if (INTEGERP (it->slice.width))
24246 slice.width = XINT (it->slice.width);
24247 else if (FLOATP (it->slice.width))
24248 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
24250 if (INTEGERP (it->slice.height))
24251 slice.height = XINT (it->slice.height);
24252 else if (FLOATP (it->slice.height))
24253 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
24255 if (slice.x >= img->width)
24256 slice.x = img->width;
24257 if (slice.y >= img->height)
24258 slice.y = img->height;
24259 if (slice.x + slice.width >= img->width)
24260 slice.width = img->width - slice.x;
24261 if (slice.y + slice.height > img->height)
24262 slice.height = img->height - slice.y;
24264 if (slice.width == 0 || slice.height == 0)
24265 return;
24267 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
24269 it->descent = slice.height - glyph_ascent;
24270 if (slice.y == 0)
24271 it->descent += img->vmargin;
24272 if (slice.y + slice.height == img->height)
24273 it->descent += img->vmargin;
24274 it->phys_descent = it->descent;
24276 it->pixel_width = slice.width;
24277 if (slice.x == 0)
24278 it->pixel_width += img->hmargin;
24279 if (slice.x + slice.width == img->width)
24280 it->pixel_width += img->hmargin;
24282 /* It's quite possible for images to have an ascent greater than
24283 their height, so don't get confused in that case. */
24284 if (it->descent < 0)
24285 it->descent = 0;
24287 it->nglyphs = 1;
24289 if (face->box != FACE_NO_BOX)
24291 if (face->box_line_width > 0)
24293 if (slice.y == 0)
24294 it->ascent += face->box_line_width;
24295 if (slice.y + slice.height == img->height)
24296 it->descent += face->box_line_width;
24299 if (it->start_of_box_run_p && slice.x == 0)
24300 it->pixel_width += eabs (face->box_line_width);
24301 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
24302 it->pixel_width += eabs (face->box_line_width);
24305 take_vertical_position_into_account (it);
24307 /* Automatically crop wide image glyphs at right edge so we can
24308 draw the cursor on same display row. */
24309 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
24310 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
24312 it->pixel_width -= crop;
24313 slice.width -= crop;
24316 if (it->glyph_row)
24318 struct glyph *glyph;
24319 enum glyph_row_area area = it->area;
24321 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24322 if (glyph < it->glyph_row->glyphs[area + 1])
24324 glyph->charpos = CHARPOS (it->position);
24325 glyph->object = it->object;
24326 glyph->pixel_width = it->pixel_width;
24327 glyph->ascent = glyph_ascent;
24328 glyph->descent = it->descent;
24329 glyph->voffset = it->voffset;
24330 glyph->type = IMAGE_GLYPH;
24331 glyph->avoid_cursor_p = it->avoid_cursor_p;
24332 glyph->multibyte_p = it->multibyte_p;
24333 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24335 /* In R2L rows, the left and the right box edges need to be
24336 drawn in reverse direction. */
24337 glyph->right_box_line_p = it->start_of_box_run_p;
24338 glyph->left_box_line_p = it->end_of_box_run_p;
24340 else
24342 glyph->left_box_line_p = it->start_of_box_run_p;
24343 glyph->right_box_line_p = it->end_of_box_run_p;
24345 glyph->overlaps_vertically_p = 0;
24346 glyph->padding_p = 0;
24347 glyph->glyph_not_available_p = 0;
24348 glyph->face_id = it->face_id;
24349 glyph->u.img_id = img->id;
24350 glyph->slice.img = slice;
24351 glyph->font_type = FONT_TYPE_UNKNOWN;
24352 if (it->bidi_p)
24354 glyph->resolved_level = it->bidi_it.resolved_level;
24355 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24356 emacs_abort ();
24357 glyph->bidi_type = it->bidi_it.type;
24359 ++it->glyph_row->used[area];
24361 else
24362 IT_EXPAND_MATRIX_WIDTH (it, area);
24367 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
24368 of the glyph, WIDTH and HEIGHT are the width and height of the
24369 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
24371 static void
24372 append_stretch_glyph (struct it *it, Lisp_Object object,
24373 int width, int height, int ascent)
24375 struct glyph *glyph;
24376 enum glyph_row_area area = it->area;
24378 eassert (ascent >= 0 && ascent <= height);
24380 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24381 if (glyph < it->glyph_row->glyphs[area + 1])
24383 /* If the glyph row is reversed, we need to prepend the glyph
24384 rather than append it. */
24385 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24387 struct glyph *g;
24389 /* Make room for the additional glyph. */
24390 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
24391 g[1] = *g;
24392 glyph = it->glyph_row->glyphs[area];
24394 glyph->charpos = CHARPOS (it->position);
24395 glyph->object = object;
24396 glyph->pixel_width = width;
24397 glyph->ascent = ascent;
24398 glyph->descent = height - ascent;
24399 glyph->voffset = it->voffset;
24400 glyph->type = STRETCH_GLYPH;
24401 glyph->avoid_cursor_p = it->avoid_cursor_p;
24402 glyph->multibyte_p = it->multibyte_p;
24403 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24405 /* In R2L rows, the left and the right box edges need to be
24406 drawn in reverse direction. */
24407 glyph->right_box_line_p = it->start_of_box_run_p;
24408 glyph->left_box_line_p = it->end_of_box_run_p;
24410 else
24412 glyph->left_box_line_p = it->start_of_box_run_p;
24413 glyph->right_box_line_p = it->end_of_box_run_p;
24415 glyph->overlaps_vertically_p = 0;
24416 glyph->padding_p = 0;
24417 glyph->glyph_not_available_p = 0;
24418 glyph->face_id = it->face_id;
24419 glyph->u.stretch.ascent = ascent;
24420 glyph->u.stretch.height = height;
24421 glyph->slice.img = null_glyph_slice;
24422 glyph->font_type = FONT_TYPE_UNKNOWN;
24423 if (it->bidi_p)
24425 glyph->resolved_level = it->bidi_it.resolved_level;
24426 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24427 emacs_abort ();
24428 glyph->bidi_type = it->bidi_it.type;
24430 else
24432 glyph->resolved_level = 0;
24433 glyph->bidi_type = UNKNOWN_BT;
24435 ++it->glyph_row->used[area];
24437 else
24438 IT_EXPAND_MATRIX_WIDTH (it, area);
24441 #endif /* HAVE_WINDOW_SYSTEM */
24443 /* Produce a stretch glyph for iterator IT. IT->object is the value
24444 of the glyph property displayed. The value must be a list
24445 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
24446 being recognized:
24448 1. `:width WIDTH' specifies that the space should be WIDTH *
24449 canonical char width wide. WIDTH may be an integer or floating
24450 point number.
24452 2. `:relative-width FACTOR' specifies that the width of the stretch
24453 should be computed from the width of the first character having the
24454 `glyph' property, and should be FACTOR times that width.
24456 3. `:align-to HPOS' specifies that the space should be wide enough
24457 to reach HPOS, a value in canonical character units.
24459 Exactly one of the above pairs must be present.
24461 4. `:height HEIGHT' specifies that the height of the stretch produced
24462 should be HEIGHT, measured in canonical character units.
24464 5. `:relative-height FACTOR' specifies that the height of the
24465 stretch should be FACTOR times the height of the characters having
24466 the glyph property.
24468 Either none or exactly one of 4 or 5 must be present.
24470 6. `:ascent ASCENT' specifies that ASCENT percent of the height
24471 of the stretch should be used for the ascent of the stretch.
24472 ASCENT must be in the range 0 <= ASCENT <= 100. */
24474 void
24475 produce_stretch_glyph (struct it *it)
24477 /* (space :width WIDTH :height HEIGHT ...) */
24478 Lisp_Object prop, plist;
24479 int width = 0, height = 0, align_to = -1;
24480 int zero_width_ok_p = 0;
24481 double tem;
24482 struct font *font = NULL;
24484 #ifdef HAVE_WINDOW_SYSTEM
24485 int ascent = 0;
24486 int zero_height_ok_p = 0;
24488 if (FRAME_WINDOW_P (it->f))
24490 struct face *face = FACE_FROM_ID (it->f, it->face_id);
24491 font = face->font ? face->font : FRAME_FONT (it->f);
24492 PREPARE_FACE_FOR_DISPLAY (it->f, face);
24494 #endif
24496 /* List should start with `space'. */
24497 eassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
24498 plist = XCDR (it->object);
24500 /* Compute the width of the stretch. */
24501 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
24502 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
24504 /* Absolute width `:width WIDTH' specified and valid. */
24505 zero_width_ok_p = 1;
24506 width = (int)tem;
24508 #ifdef HAVE_WINDOW_SYSTEM
24509 else if (FRAME_WINDOW_P (it->f)
24510 && (prop = Fplist_get (plist, QCrelative_width), NUMVAL (prop) > 0))
24512 /* Relative width `:relative-width FACTOR' specified and valid.
24513 Compute the width of the characters having the `glyph'
24514 property. */
24515 struct it it2;
24516 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
24518 it2 = *it;
24519 if (it->multibyte_p)
24520 it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
24521 else
24523 it2.c = it2.char_to_display = *p, it2.len = 1;
24524 if (! ASCII_CHAR_P (it2.c))
24525 it2.char_to_display = BYTE8_TO_CHAR (it2.c);
24528 it2.glyph_row = NULL;
24529 it2.what = IT_CHARACTER;
24530 x_produce_glyphs (&it2);
24531 width = NUMVAL (prop) * it2.pixel_width;
24533 #endif /* HAVE_WINDOW_SYSTEM */
24534 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
24535 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
24537 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
24538 align_to = (align_to < 0
24540 : align_to - window_box_left_offset (it->w, TEXT_AREA));
24541 else if (align_to < 0)
24542 align_to = window_box_left_offset (it->w, TEXT_AREA);
24543 width = max (0, (int)tem + align_to - it->current_x);
24544 zero_width_ok_p = 1;
24546 else
24547 /* Nothing specified -> width defaults to canonical char width. */
24548 width = FRAME_COLUMN_WIDTH (it->f);
24550 if (width <= 0 && (width < 0 || !zero_width_ok_p))
24551 width = 1;
24553 #ifdef HAVE_WINDOW_SYSTEM
24554 /* Compute height. */
24555 if (FRAME_WINDOW_P (it->f))
24557 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
24558 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
24560 height = (int)tem;
24561 zero_height_ok_p = 1;
24563 else if (prop = Fplist_get (plist, QCrelative_height),
24564 NUMVAL (prop) > 0)
24565 height = FONT_HEIGHT (font) * NUMVAL (prop);
24566 else
24567 height = FONT_HEIGHT (font);
24569 if (height <= 0 && (height < 0 || !zero_height_ok_p))
24570 height = 1;
24572 /* Compute percentage of height used for ascent. If
24573 `:ascent ASCENT' is present and valid, use that. Otherwise,
24574 derive the ascent from the font in use. */
24575 if (prop = Fplist_get (plist, QCascent),
24576 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
24577 ascent = height * NUMVAL (prop) / 100.0;
24578 else if (!NILP (prop)
24579 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
24580 ascent = min (max (0, (int)tem), height);
24581 else
24582 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
24584 else
24585 #endif /* HAVE_WINDOW_SYSTEM */
24586 height = 1;
24588 if (width > 0 && it->line_wrap != TRUNCATE
24589 && it->current_x + width > it->last_visible_x)
24591 width = it->last_visible_x - it->current_x;
24592 #ifdef HAVE_WINDOW_SYSTEM
24593 /* Subtract one more pixel from the stretch width, but only on
24594 GUI frames, since on a TTY each glyph is one "pixel" wide. */
24595 width -= FRAME_WINDOW_P (it->f);
24596 #endif
24599 if (width > 0 && height > 0 && it->glyph_row)
24601 Lisp_Object o_object = it->object;
24602 Lisp_Object object = it->stack[it->sp - 1].string;
24603 int n = width;
24605 if (!STRINGP (object))
24606 object = it->w->contents;
24607 #ifdef HAVE_WINDOW_SYSTEM
24608 if (FRAME_WINDOW_P (it->f))
24609 append_stretch_glyph (it, object, width, height, ascent);
24610 else
24611 #endif
24613 it->object = object;
24614 it->char_to_display = ' ';
24615 it->pixel_width = it->len = 1;
24616 while (n--)
24617 tty_append_glyph (it);
24618 it->object = o_object;
24622 it->pixel_width = width;
24623 #ifdef HAVE_WINDOW_SYSTEM
24624 if (FRAME_WINDOW_P (it->f))
24626 it->ascent = it->phys_ascent = ascent;
24627 it->descent = it->phys_descent = height - it->ascent;
24628 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
24629 take_vertical_position_into_account (it);
24631 else
24632 #endif
24633 it->nglyphs = width;
24636 /* Get information about special display element WHAT in an
24637 environment described by IT. WHAT is one of IT_TRUNCATION or
24638 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
24639 non-null glyph_row member. This function ensures that fields like
24640 face_id, c, len of IT are left untouched. */
24642 static void
24643 produce_special_glyphs (struct it *it, enum display_element_type what)
24645 struct it temp_it;
24646 Lisp_Object gc;
24647 GLYPH glyph;
24649 temp_it = *it;
24650 temp_it.object = make_number (0);
24651 memset (&temp_it.current, 0, sizeof temp_it.current);
24653 if (what == IT_CONTINUATION)
24655 /* Continuation glyph. For R2L lines, we mirror it by hand. */
24656 if (it->bidi_it.paragraph_dir == R2L)
24657 SET_GLYPH_FROM_CHAR (glyph, '/');
24658 else
24659 SET_GLYPH_FROM_CHAR (glyph, '\\');
24660 if (it->dp
24661 && (gc = DISP_CONTINUE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
24663 /* FIXME: Should we mirror GC for R2L lines? */
24664 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
24665 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
24668 else if (what == IT_TRUNCATION)
24670 /* Truncation glyph. */
24671 SET_GLYPH_FROM_CHAR (glyph, '$');
24672 if (it->dp
24673 && (gc = DISP_TRUNC_GLYPH (it->dp), GLYPH_CODE_P (gc)))
24675 /* FIXME: Should we mirror GC for R2L lines? */
24676 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
24677 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
24680 else
24681 emacs_abort ();
24683 #ifdef HAVE_WINDOW_SYSTEM
24684 /* On a GUI frame, when the right fringe (left fringe for R2L rows)
24685 is turned off, we precede the truncation/continuation glyphs by a
24686 stretch glyph whose width is computed such that these special
24687 glyphs are aligned at the window margin, even when very different
24688 fonts are used in different glyph rows. */
24689 if (FRAME_WINDOW_P (temp_it.f)
24690 /* init_iterator calls this with it->glyph_row == NULL, and it
24691 wants only the pixel width of the truncation/continuation
24692 glyphs. */
24693 && temp_it.glyph_row
24694 /* insert_left_trunc_glyphs calls us at the beginning of the
24695 row, and it has its own calculation of the stretch glyph
24696 width. */
24697 && temp_it.glyph_row->used[TEXT_AREA] > 0
24698 && (temp_it.glyph_row->reversed_p
24699 ? WINDOW_LEFT_FRINGE_WIDTH (temp_it.w)
24700 : WINDOW_RIGHT_FRINGE_WIDTH (temp_it.w)) == 0)
24702 int stretch_width = temp_it.last_visible_x - temp_it.current_x;
24704 if (stretch_width > 0)
24706 struct face *face = FACE_FROM_ID (temp_it.f, temp_it.face_id);
24707 struct font *font =
24708 face->font ? face->font : FRAME_FONT (temp_it.f);
24709 int stretch_ascent =
24710 (((temp_it.ascent + temp_it.descent)
24711 * FONT_BASE (font)) / FONT_HEIGHT (font));
24713 append_stretch_glyph (&temp_it, make_number (0), stretch_width,
24714 temp_it.ascent + temp_it.descent,
24715 stretch_ascent);
24718 #endif
24720 temp_it.dp = NULL;
24721 temp_it.what = IT_CHARACTER;
24722 temp_it.len = 1;
24723 temp_it.c = temp_it.char_to_display = GLYPH_CHAR (glyph);
24724 temp_it.face_id = GLYPH_FACE (glyph);
24725 temp_it.len = CHAR_BYTES (temp_it.c);
24727 PRODUCE_GLYPHS (&temp_it);
24728 it->pixel_width = temp_it.pixel_width;
24729 it->nglyphs = temp_it.pixel_width;
24732 #ifdef HAVE_WINDOW_SYSTEM
24734 /* Calculate line-height and line-spacing properties.
24735 An integer value specifies explicit pixel value.
24736 A float value specifies relative value to current face height.
24737 A cons (float . face-name) specifies relative value to
24738 height of specified face font.
24740 Returns height in pixels, or nil. */
24743 static Lisp_Object
24744 calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
24745 int boff, int override)
24747 Lisp_Object face_name = Qnil;
24748 int ascent, descent, height;
24750 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
24751 return val;
24753 if (CONSP (val))
24755 face_name = XCAR (val);
24756 val = XCDR (val);
24757 if (!NUMBERP (val))
24758 val = make_number (1);
24759 if (NILP (face_name))
24761 height = it->ascent + it->descent;
24762 goto scale;
24766 if (NILP (face_name))
24768 font = FRAME_FONT (it->f);
24769 boff = FRAME_BASELINE_OFFSET (it->f);
24771 else if (EQ (face_name, Qt))
24773 override = 0;
24775 else
24777 int face_id;
24778 struct face *face;
24780 face_id = lookup_named_face (it->f, face_name, 0);
24781 if (face_id < 0)
24782 return make_number (-1);
24784 face = FACE_FROM_ID (it->f, face_id);
24785 font = face->font;
24786 if (font == NULL)
24787 return make_number (-1);
24788 boff = font->baseline_offset;
24789 if (font->vertical_centering)
24790 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
24793 ascent = FONT_BASE (font) + boff;
24794 descent = FONT_DESCENT (font) - boff;
24796 if (override)
24798 it->override_ascent = ascent;
24799 it->override_descent = descent;
24800 it->override_boff = boff;
24803 height = ascent + descent;
24805 scale:
24806 if (FLOATP (val))
24807 height = (int)(XFLOAT_DATA (val) * height);
24808 else if (INTEGERP (val))
24809 height *= XINT (val);
24811 return make_number (height);
24815 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
24816 is a face ID to be used for the glyph. FOR_NO_FONT is nonzero if
24817 and only if this is for a character for which no font was found.
24819 If the display method (it->glyphless_method) is
24820 GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
24821 length of the acronym or the hexadecimal string, UPPER_XOFF and
24822 UPPER_YOFF are pixel offsets for the upper part of the string,
24823 LOWER_XOFF and LOWER_YOFF are for the lower part.
24825 For the other display methods, LEN through LOWER_YOFF are zero. */
24827 static void
24828 append_glyphless_glyph (struct it *it, int face_id, int for_no_font, int len,
24829 short upper_xoff, short upper_yoff,
24830 short lower_xoff, short lower_yoff)
24832 struct glyph *glyph;
24833 enum glyph_row_area area = it->area;
24835 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24836 if (glyph < it->glyph_row->glyphs[area + 1])
24838 /* If the glyph row is reversed, we need to prepend the glyph
24839 rather than append it. */
24840 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24842 struct glyph *g;
24844 /* Make room for the additional glyph. */
24845 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
24846 g[1] = *g;
24847 glyph = it->glyph_row->glyphs[area];
24849 glyph->charpos = CHARPOS (it->position);
24850 glyph->object = it->object;
24851 glyph->pixel_width = it->pixel_width;
24852 glyph->ascent = it->ascent;
24853 glyph->descent = it->descent;
24854 glyph->voffset = it->voffset;
24855 glyph->type = GLYPHLESS_GLYPH;
24856 glyph->u.glyphless.method = it->glyphless_method;
24857 glyph->u.glyphless.for_no_font = for_no_font;
24858 glyph->u.glyphless.len = len;
24859 glyph->u.glyphless.ch = it->c;
24860 glyph->slice.glyphless.upper_xoff = upper_xoff;
24861 glyph->slice.glyphless.upper_yoff = upper_yoff;
24862 glyph->slice.glyphless.lower_xoff = lower_xoff;
24863 glyph->slice.glyphless.lower_yoff = lower_yoff;
24864 glyph->avoid_cursor_p = it->avoid_cursor_p;
24865 glyph->multibyte_p = it->multibyte_p;
24866 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24868 /* In R2L rows, the left and the right box edges need to be
24869 drawn in reverse direction. */
24870 glyph->right_box_line_p = it->start_of_box_run_p;
24871 glyph->left_box_line_p = it->end_of_box_run_p;
24873 else
24875 glyph->left_box_line_p = it->start_of_box_run_p;
24876 glyph->right_box_line_p = it->end_of_box_run_p;
24878 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
24879 || it->phys_descent > it->descent);
24880 glyph->padding_p = 0;
24881 glyph->glyph_not_available_p = 0;
24882 glyph->face_id = face_id;
24883 glyph->font_type = FONT_TYPE_UNKNOWN;
24884 if (it->bidi_p)
24886 glyph->resolved_level = it->bidi_it.resolved_level;
24887 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24888 emacs_abort ();
24889 glyph->bidi_type = it->bidi_it.type;
24891 ++it->glyph_row->used[area];
24893 else
24894 IT_EXPAND_MATRIX_WIDTH (it, area);
24898 /* Produce a glyph for a glyphless character for iterator IT.
24899 IT->glyphless_method specifies which method to use for displaying
24900 the character. See the description of enum
24901 glyphless_display_method in dispextern.h for the detail.
24903 FOR_NO_FONT is nonzero if and only if this is for a character for
24904 which no font was found. ACRONYM, if non-nil, is an acronym string
24905 for the character. */
24907 static void
24908 produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
24910 int face_id;
24911 struct face *face;
24912 struct font *font;
24913 int base_width, base_height, width, height;
24914 short upper_xoff, upper_yoff, lower_xoff, lower_yoff;
24915 int len;
24917 /* Get the metrics of the base font. We always refer to the current
24918 ASCII face. */
24919 face = FACE_FROM_ID (it->f, it->face_id)->ascii_face;
24920 font = face->font ? face->font : FRAME_FONT (it->f);
24921 it->ascent = FONT_BASE (font) + font->baseline_offset;
24922 it->descent = FONT_DESCENT (font) - font->baseline_offset;
24923 base_height = it->ascent + it->descent;
24924 base_width = font->average_width;
24926 /* Get a face ID for the glyph by utilizing a cache (the same way as
24927 done for `escape-glyph' in get_next_display_element). */
24928 if (it->f == last_glyphless_glyph_frame
24929 && it->face_id == last_glyphless_glyph_face_id)
24931 face_id = last_glyphless_glyph_merged_face_id;
24933 else
24935 /* Merge the `glyphless-char' face into the current face. */
24936 face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
24937 last_glyphless_glyph_frame = it->f;
24938 last_glyphless_glyph_face_id = it->face_id;
24939 last_glyphless_glyph_merged_face_id = face_id;
24942 if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
24944 it->pixel_width = THIN_SPACE_WIDTH;
24945 len = 0;
24946 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
24948 else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX)
24950 width = CHAR_WIDTH (it->c);
24951 if (width == 0)
24952 width = 1;
24953 else if (width > 4)
24954 width = 4;
24955 it->pixel_width = base_width * width;
24956 len = 0;
24957 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
24959 else
24961 char buf[7];
24962 const char *str;
24963 unsigned int code[6];
24964 int upper_len;
24965 int ascent, descent;
24966 struct font_metrics metrics_upper, metrics_lower;
24968 face = FACE_FROM_ID (it->f, face_id);
24969 font = face->font ? face->font : FRAME_FONT (it->f);
24970 PREPARE_FACE_FOR_DISPLAY (it->f, face);
24972 if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM)
24974 if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
24975 acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
24976 if (CONSP (acronym))
24977 acronym = XCAR (acronym);
24978 str = STRINGP (acronym) ? SSDATA (acronym) : "";
24980 else
24982 eassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
24983 sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c);
24984 str = buf;
24986 for (len = 0; str[len] && ASCII_BYTE_P (str[len]) && len < 6; len++)
24987 code[len] = font->driver->encode_char (font, str[len]);
24988 upper_len = (len + 1) / 2;
24989 font->driver->text_extents (font, code, upper_len,
24990 &metrics_upper);
24991 font->driver->text_extents (font, code + upper_len, len - upper_len,
24992 &metrics_lower);
24996 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
24997 width = max (metrics_upper.width, metrics_lower.width) + 4;
24998 upper_xoff = upper_yoff = 2; /* the typical case */
24999 if (base_width >= width)
25001 /* Align the upper to the left, the lower to the right. */
25002 it->pixel_width = base_width;
25003 lower_xoff = base_width - 2 - metrics_lower.width;
25005 else
25007 /* Center the shorter one. */
25008 it->pixel_width = width;
25009 if (metrics_upper.width >= metrics_lower.width)
25010 lower_xoff = (width - metrics_lower.width) / 2;
25011 else
25013 /* FIXME: This code doesn't look right. It formerly was
25014 missing the "lower_xoff = 0;", which couldn't have
25015 been right since it left lower_xoff uninitialized. */
25016 lower_xoff = 0;
25017 upper_xoff = (width - metrics_upper.width) / 2;
25021 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
25022 top, bottom, and between upper and lower strings. */
25023 height = (metrics_upper.ascent + metrics_upper.descent
25024 + metrics_lower.ascent + metrics_lower.descent) + 5;
25025 /* Center vertically.
25026 H:base_height, D:base_descent
25027 h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent
25029 ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up
25030 descent = D - H/2 + h/2;
25031 lower_yoff = descent - 2 - ld;
25032 upper_yoff = lower_yoff - la - 1 - ud; */
25033 ascent = - (it->descent - (base_height + height + 1) / 2);
25034 descent = it->descent - (base_height - height) / 2;
25035 lower_yoff = descent - 2 - metrics_lower.descent;
25036 upper_yoff = (lower_yoff - metrics_lower.ascent - 1
25037 - metrics_upper.descent);
25038 /* Don't make the height shorter than the base height. */
25039 if (height > base_height)
25041 it->ascent = ascent;
25042 it->descent = descent;
25046 it->phys_ascent = it->ascent;
25047 it->phys_descent = it->descent;
25048 if (it->glyph_row)
25049 append_glyphless_glyph (it, face_id, for_no_font, len,
25050 upper_xoff, upper_yoff,
25051 lower_xoff, lower_yoff);
25052 it->nglyphs = 1;
25053 take_vertical_position_into_account (it);
25057 /* RIF:
25058 Produce glyphs/get display metrics for the display element IT is
25059 loaded with. See the description of struct it in dispextern.h
25060 for an overview of struct it. */
25062 void
25063 x_produce_glyphs (struct it *it)
25065 int extra_line_spacing = it->extra_line_spacing;
25067 it->glyph_not_available_p = 0;
25069 if (it->what == IT_CHARACTER)
25071 XChar2b char2b;
25072 struct face *face = FACE_FROM_ID (it->f, it->face_id);
25073 struct font *font = face->font;
25074 struct font_metrics *pcm = NULL;
25075 int boff; /* baseline offset */
25077 if (font == NULL)
25079 /* When no suitable font is found, display this character by
25080 the method specified in the first extra slot of
25081 Vglyphless_char_display. */
25082 Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
25084 eassert (it->what == IT_GLYPHLESS);
25085 produce_glyphless_glyph (it, 1, STRINGP (acronym) ? acronym : Qnil);
25086 goto done;
25089 boff = font->baseline_offset;
25090 if (font->vertical_centering)
25091 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
25093 if (it->char_to_display != '\n' && it->char_to_display != '\t')
25095 int stretched_p;
25097 it->nglyphs = 1;
25099 if (it->override_ascent >= 0)
25101 it->ascent = it->override_ascent;
25102 it->descent = it->override_descent;
25103 boff = it->override_boff;
25105 else
25107 it->ascent = FONT_BASE (font) + boff;
25108 it->descent = FONT_DESCENT (font) - boff;
25111 if (get_char_glyph_code (it->char_to_display, font, &char2b))
25113 pcm = get_per_char_metric (font, &char2b);
25114 if (pcm->width == 0
25115 && pcm->rbearing == 0 && pcm->lbearing == 0)
25116 pcm = NULL;
25119 if (pcm)
25121 it->phys_ascent = pcm->ascent + boff;
25122 it->phys_descent = pcm->descent - boff;
25123 it->pixel_width = pcm->width;
25125 else
25127 it->glyph_not_available_p = 1;
25128 it->phys_ascent = it->ascent;
25129 it->phys_descent = it->descent;
25130 it->pixel_width = font->space_width;
25133 if (it->constrain_row_ascent_descent_p)
25135 if (it->descent > it->max_descent)
25137 it->ascent += it->descent - it->max_descent;
25138 it->descent = it->max_descent;
25140 if (it->ascent > it->max_ascent)
25142 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
25143 it->ascent = it->max_ascent;
25145 it->phys_ascent = min (it->phys_ascent, it->ascent);
25146 it->phys_descent = min (it->phys_descent, it->descent);
25147 extra_line_spacing = 0;
25150 /* If this is a space inside a region of text with
25151 `space-width' property, change its width. */
25152 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
25153 if (stretched_p)
25154 it->pixel_width *= XFLOATINT (it->space_width);
25156 /* If face has a box, add the box thickness to the character
25157 height. If character has a box line to the left and/or
25158 right, add the box line width to the character's width. */
25159 if (face->box != FACE_NO_BOX)
25161 int thick = face->box_line_width;
25163 if (thick > 0)
25165 it->ascent += thick;
25166 it->descent += thick;
25168 else
25169 thick = -thick;
25171 if (it->start_of_box_run_p)
25172 it->pixel_width += thick;
25173 if (it->end_of_box_run_p)
25174 it->pixel_width += thick;
25177 /* If face has an overline, add the height of the overline
25178 (1 pixel) and a 1 pixel margin to the character height. */
25179 if (face->overline_p)
25180 it->ascent += overline_margin;
25182 if (it->constrain_row_ascent_descent_p)
25184 if (it->ascent > it->max_ascent)
25185 it->ascent = it->max_ascent;
25186 if (it->descent > it->max_descent)
25187 it->descent = it->max_descent;
25190 take_vertical_position_into_account (it);
25192 /* If we have to actually produce glyphs, do it. */
25193 if (it->glyph_row)
25195 if (stretched_p)
25197 /* Translate a space with a `space-width' property
25198 into a stretch glyph. */
25199 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
25200 / FONT_HEIGHT (font));
25201 append_stretch_glyph (it, it->object, it->pixel_width,
25202 it->ascent + it->descent, ascent);
25204 else
25205 append_glyph (it);
25207 /* If characters with lbearing or rbearing are displayed
25208 in this line, record that fact in a flag of the
25209 glyph row. This is used to optimize X output code. */
25210 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
25211 it->glyph_row->contains_overlapping_glyphs_p = 1;
25213 if (! stretched_p && it->pixel_width == 0)
25214 /* We assure that all visible glyphs have at least 1-pixel
25215 width. */
25216 it->pixel_width = 1;
25218 else if (it->char_to_display == '\n')
25220 /* A newline has no width, but we need the height of the
25221 line. But if previous part of the line sets a height,
25222 don't increase that height */
25224 Lisp_Object height;
25225 Lisp_Object total_height = Qnil;
25227 it->override_ascent = -1;
25228 it->pixel_width = 0;
25229 it->nglyphs = 0;
25231 height = get_it_property (it, Qline_height);
25232 /* Split (line-height total-height) list */
25233 if (CONSP (height)
25234 && CONSP (XCDR (height))
25235 && NILP (XCDR (XCDR (height))))
25237 total_height = XCAR (XCDR (height));
25238 height = XCAR (height);
25240 height = calc_line_height_property (it, height, font, boff, 1);
25242 if (it->override_ascent >= 0)
25244 it->ascent = it->override_ascent;
25245 it->descent = it->override_descent;
25246 boff = it->override_boff;
25248 else
25250 it->ascent = FONT_BASE (font) + boff;
25251 it->descent = FONT_DESCENT (font) - boff;
25254 if (EQ (height, Qt))
25256 if (it->descent > it->max_descent)
25258 it->ascent += it->descent - it->max_descent;
25259 it->descent = it->max_descent;
25261 if (it->ascent > it->max_ascent)
25263 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
25264 it->ascent = it->max_ascent;
25266 it->phys_ascent = min (it->phys_ascent, it->ascent);
25267 it->phys_descent = min (it->phys_descent, it->descent);
25268 it->constrain_row_ascent_descent_p = 1;
25269 extra_line_spacing = 0;
25271 else
25273 Lisp_Object spacing;
25275 it->phys_ascent = it->ascent;
25276 it->phys_descent = it->descent;
25278 if ((it->max_ascent > 0 || it->max_descent > 0)
25279 && face->box != FACE_NO_BOX
25280 && face->box_line_width > 0)
25282 it->ascent += face->box_line_width;
25283 it->descent += face->box_line_width;
25285 if (!NILP (height)
25286 && XINT (height) > it->ascent + it->descent)
25287 it->ascent = XINT (height) - it->descent;
25289 if (!NILP (total_height))
25290 spacing = calc_line_height_property (it, total_height, font, boff, 0);
25291 else
25293 spacing = get_it_property (it, Qline_spacing);
25294 spacing = calc_line_height_property (it, spacing, font, boff, 0);
25296 if (INTEGERP (spacing))
25298 extra_line_spacing = XINT (spacing);
25299 if (!NILP (total_height))
25300 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
25304 else /* i.e. (it->char_to_display == '\t') */
25306 if (font->space_width > 0)
25308 int tab_width = it->tab_width * font->space_width;
25309 int x = it->current_x + it->continuation_lines_width;
25310 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
25312 /* If the distance from the current position to the next tab
25313 stop is less than a space character width, use the
25314 tab stop after that. */
25315 if (next_tab_x - x < font->space_width)
25316 next_tab_x += tab_width;
25318 it->pixel_width = next_tab_x - x;
25319 it->nglyphs = 1;
25320 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
25321 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
25323 if (it->glyph_row)
25325 append_stretch_glyph (it, it->object, it->pixel_width,
25326 it->ascent + it->descent, it->ascent);
25329 else
25331 it->pixel_width = 0;
25332 it->nglyphs = 1;
25336 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
25338 /* A static composition.
25340 Note: A composition is represented as one glyph in the
25341 glyph matrix. There are no padding glyphs.
25343 Important note: pixel_width, ascent, and descent are the
25344 values of what is drawn by draw_glyphs (i.e. the values of
25345 the overall glyphs composed). */
25346 struct face *face = FACE_FROM_ID (it->f, it->face_id);
25347 int boff; /* baseline offset */
25348 struct composition *cmp = composition_table[it->cmp_it.id];
25349 int glyph_len = cmp->glyph_len;
25350 struct font *font = face->font;
25352 it->nglyphs = 1;
25354 /* If we have not yet calculated pixel size data of glyphs of
25355 the composition for the current face font, calculate them
25356 now. Theoretically, we have to check all fonts for the
25357 glyphs, but that requires much time and memory space. So,
25358 here we check only the font of the first glyph. This may
25359 lead to incorrect display, but it's very rare, and C-l
25360 (recenter-top-bottom) can correct the display anyway. */
25361 if (! cmp->font || cmp->font != font)
25363 /* Ascent and descent of the font of the first character
25364 of this composition (adjusted by baseline offset).
25365 Ascent and descent of overall glyphs should not be less
25366 than these, respectively. */
25367 int font_ascent, font_descent, font_height;
25368 /* Bounding box of the overall glyphs. */
25369 int leftmost, rightmost, lowest, highest;
25370 int lbearing, rbearing;
25371 int i, width, ascent, descent;
25372 int left_padded = 0, right_padded = 0;
25373 int c IF_LINT (= 0); /* cmp->glyph_len can't be zero; see Bug#8512 */
25374 XChar2b char2b;
25375 struct font_metrics *pcm;
25376 int font_not_found_p;
25377 ptrdiff_t pos;
25379 for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
25380 if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
25381 break;
25382 if (glyph_len < cmp->glyph_len)
25383 right_padded = 1;
25384 for (i = 0; i < glyph_len; i++)
25386 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
25387 break;
25388 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
25390 if (i > 0)
25391 left_padded = 1;
25393 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
25394 : IT_CHARPOS (*it));
25395 /* If no suitable font is found, use the default font. */
25396 font_not_found_p = font == NULL;
25397 if (font_not_found_p)
25399 face = face->ascii_face;
25400 font = face->font;
25402 boff = font->baseline_offset;
25403 if (font->vertical_centering)
25404 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
25405 font_ascent = FONT_BASE (font) + boff;
25406 font_descent = FONT_DESCENT (font) - boff;
25407 font_height = FONT_HEIGHT (font);
25409 cmp->font = font;
25411 pcm = NULL;
25412 if (! font_not_found_p)
25414 get_char_face_and_encoding (it->f, c, it->face_id,
25415 &char2b, 0);
25416 pcm = get_per_char_metric (font, &char2b);
25419 /* Initialize the bounding box. */
25420 if (pcm)
25422 width = cmp->glyph_len > 0 ? pcm->width : 0;
25423 ascent = pcm->ascent;
25424 descent = pcm->descent;
25425 lbearing = pcm->lbearing;
25426 rbearing = pcm->rbearing;
25428 else
25430 width = cmp->glyph_len > 0 ? font->space_width : 0;
25431 ascent = FONT_BASE (font);
25432 descent = FONT_DESCENT (font);
25433 lbearing = 0;
25434 rbearing = width;
25437 rightmost = width;
25438 leftmost = 0;
25439 lowest = - descent + boff;
25440 highest = ascent + boff;
25442 if (! font_not_found_p
25443 && font->default_ascent
25444 && CHAR_TABLE_P (Vuse_default_ascent)
25445 && !NILP (Faref (Vuse_default_ascent,
25446 make_number (it->char_to_display))))
25447 highest = font->default_ascent + boff;
25449 /* Draw the first glyph at the normal position. It may be
25450 shifted to right later if some other glyphs are drawn
25451 at the left. */
25452 cmp->offsets[i * 2] = 0;
25453 cmp->offsets[i * 2 + 1] = boff;
25454 cmp->lbearing = lbearing;
25455 cmp->rbearing = rbearing;
25457 /* Set cmp->offsets for the remaining glyphs. */
25458 for (i++; i < glyph_len; i++)
25460 int left, right, btm, top;
25461 int ch = COMPOSITION_GLYPH (cmp, i);
25462 int face_id;
25463 struct face *this_face;
25465 if (ch == '\t')
25466 ch = ' ';
25467 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
25468 this_face = FACE_FROM_ID (it->f, face_id);
25469 font = this_face->font;
25471 if (font == NULL)
25472 pcm = NULL;
25473 else
25475 get_char_face_and_encoding (it->f, ch, face_id,
25476 &char2b, 0);
25477 pcm = get_per_char_metric (font, &char2b);
25479 if (! pcm)
25480 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
25481 else
25483 width = pcm->width;
25484 ascent = pcm->ascent;
25485 descent = pcm->descent;
25486 lbearing = pcm->lbearing;
25487 rbearing = pcm->rbearing;
25488 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
25490 /* Relative composition with or without
25491 alternate chars. */
25492 left = (leftmost + rightmost - width) / 2;
25493 btm = - descent + boff;
25494 if (font->relative_compose
25495 && (! CHAR_TABLE_P (Vignore_relative_composition)
25496 || NILP (Faref (Vignore_relative_composition,
25497 make_number (ch)))))
25500 if (- descent >= font->relative_compose)
25501 /* One extra pixel between two glyphs. */
25502 btm = highest + 1;
25503 else if (ascent <= 0)
25504 /* One extra pixel between two glyphs. */
25505 btm = lowest - 1 - ascent - descent;
25508 else
25510 /* A composition rule is specified by an integer
25511 value that encodes global and new reference
25512 points (GREF and NREF). GREF and NREF are
25513 specified by numbers as below:
25515 0---1---2 -- ascent
25519 9--10--11 -- center
25521 ---3---4---5--- baseline
25523 6---7---8 -- descent
25525 int rule = COMPOSITION_RULE (cmp, i);
25526 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
25528 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
25529 grefx = gref % 3, nrefx = nref % 3;
25530 grefy = gref / 3, nrefy = nref / 3;
25531 if (xoff)
25532 xoff = font_height * (xoff - 128) / 256;
25533 if (yoff)
25534 yoff = font_height * (yoff - 128) / 256;
25536 left = (leftmost
25537 + grefx * (rightmost - leftmost) / 2
25538 - nrefx * width / 2
25539 + xoff);
25541 btm = ((grefy == 0 ? highest
25542 : grefy == 1 ? 0
25543 : grefy == 2 ? lowest
25544 : (highest + lowest) / 2)
25545 - (nrefy == 0 ? ascent + descent
25546 : nrefy == 1 ? descent - boff
25547 : nrefy == 2 ? 0
25548 : (ascent + descent) / 2)
25549 + yoff);
25552 cmp->offsets[i * 2] = left;
25553 cmp->offsets[i * 2 + 1] = btm + descent;
25555 /* Update the bounding box of the overall glyphs. */
25556 if (width > 0)
25558 right = left + width;
25559 if (left < leftmost)
25560 leftmost = left;
25561 if (right > rightmost)
25562 rightmost = right;
25564 top = btm + descent + ascent;
25565 if (top > highest)
25566 highest = top;
25567 if (btm < lowest)
25568 lowest = btm;
25570 if (cmp->lbearing > left + lbearing)
25571 cmp->lbearing = left + lbearing;
25572 if (cmp->rbearing < left + rbearing)
25573 cmp->rbearing = left + rbearing;
25577 /* If there are glyphs whose x-offsets are negative,
25578 shift all glyphs to the right and make all x-offsets
25579 non-negative. */
25580 if (leftmost < 0)
25582 for (i = 0; i < cmp->glyph_len; i++)
25583 cmp->offsets[i * 2] -= leftmost;
25584 rightmost -= leftmost;
25585 cmp->lbearing -= leftmost;
25586 cmp->rbearing -= leftmost;
25589 if (left_padded && cmp->lbearing < 0)
25591 for (i = 0; i < cmp->glyph_len; i++)
25592 cmp->offsets[i * 2] -= cmp->lbearing;
25593 rightmost -= cmp->lbearing;
25594 cmp->rbearing -= cmp->lbearing;
25595 cmp->lbearing = 0;
25597 if (right_padded && rightmost < cmp->rbearing)
25599 rightmost = cmp->rbearing;
25602 cmp->pixel_width = rightmost;
25603 cmp->ascent = highest;
25604 cmp->descent = - lowest;
25605 if (cmp->ascent < font_ascent)
25606 cmp->ascent = font_ascent;
25607 if (cmp->descent < font_descent)
25608 cmp->descent = font_descent;
25611 if (it->glyph_row
25612 && (cmp->lbearing < 0
25613 || cmp->rbearing > cmp->pixel_width))
25614 it->glyph_row->contains_overlapping_glyphs_p = 1;
25616 it->pixel_width = cmp->pixel_width;
25617 it->ascent = it->phys_ascent = cmp->ascent;
25618 it->descent = it->phys_descent = cmp->descent;
25619 if (face->box != FACE_NO_BOX)
25621 int thick = face->box_line_width;
25623 if (thick > 0)
25625 it->ascent += thick;
25626 it->descent += thick;
25628 else
25629 thick = - thick;
25631 if (it->start_of_box_run_p)
25632 it->pixel_width += thick;
25633 if (it->end_of_box_run_p)
25634 it->pixel_width += thick;
25637 /* If face has an overline, add the height of the overline
25638 (1 pixel) and a 1 pixel margin to the character height. */
25639 if (face->overline_p)
25640 it->ascent += overline_margin;
25642 take_vertical_position_into_account (it);
25643 if (it->ascent < 0)
25644 it->ascent = 0;
25645 if (it->descent < 0)
25646 it->descent = 0;
25648 if (it->glyph_row && cmp->glyph_len > 0)
25649 append_composite_glyph (it);
25651 else if (it->what == IT_COMPOSITION)
25653 /* A dynamic (automatic) composition. */
25654 struct face *face = FACE_FROM_ID (it->f, it->face_id);
25655 Lisp_Object gstring;
25656 struct font_metrics metrics;
25658 it->nglyphs = 1;
25660 gstring = composition_gstring_from_id (it->cmp_it.id);
25661 it->pixel_width
25662 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
25663 &metrics);
25664 if (it->glyph_row
25665 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
25666 it->glyph_row->contains_overlapping_glyphs_p = 1;
25667 it->ascent = it->phys_ascent = metrics.ascent;
25668 it->descent = it->phys_descent = metrics.descent;
25669 if (face->box != FACE_NO_BOX)
25671 int thick = face->box_line_width;
25673 if (thick > 0)
25675 it->ascent += thick;
25676 it->descent += thick;
25678 else
25679 thick = - thick;
25681 if (it->start_of_box_run_p)
25682 it->pixel_width += thick;
25683 if (it->end_of_box_run_p)
25684 it->pixel_width += thick;
25686 /* If face has an overline, add the height of the overline
25687 (1 pixel) and a 1 pixel margin to the character height. */
25688 if (face->overline_p)
25689 it->ascent += overline_margin;
25690 take_vertical_position_into_account (it);
25691 if (it->ascent < 0)
25692 it->ascent = 0;
25693 if (it->descent < 0)
25694 it->descent = 0;
25696 if (it->glyph_row)
25697 append_composite_glyph (it);
25699 else if (it->what == IT_GLYPHLESS)
25700 produce_glyphless_glyph (it, 0, Qnil);
25701 else if (it->what == IT_IMAGE)
25702 produce_image_glyph (it);
25703 else if (it->what == IT_STRETCH)
25704 produce_stretch_glyph (it);
25706 done:
25707 /* Accumulate dimensions. Note: can't assume that it->descent > 0
25708 because this isn't true for images with `:ascent 100'. */
25709 eassert (it->ascent >= 0 && it->descent >= 0);
25710 if (it->area == TEXT_AREA)
25711 it->current_x += it->pixel_width;
25713 if (extra_line_spacing > 0)
25715 it->descent += extra_line_spacing;
25716 if (extra_line_spacing > it->max_extra_line_spacing)
25717 it->max_extra_line_spacing = extra_line_spacing;
25720 it->max_ascent = max (it->max_ascent, it->ascent);
25721 it->max_descent = max (it->max_descent, it->descent);
25722 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
25723 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
25726 /* EXPORT for RIF:
25727 Output LEN glyphs starting at START at the nominal cursor position.
25728 Advance the nominal cursor over the text. The global variable
25729 updated_row is the glyph row being updated, and updated_area is the
25730 area of that row being updated. */
25732 void
25733 x_write_glyphs (struct window *w, struct glyph *start, int len)
25735 int x, hpos, chpos = w->phys_cursor.hpos;
25737 eassert (updated_row);
25738 /* When the window is hscrolled, cursor hpos can legitimately be out
25739 of bounds, but we draw the cursor at the corresponding window
25740 margin in that case. */
25741 if (!updated_row->reversed_p && chpos < 0)
25742 chpos = 0;
25743 if (updated_row->reversed_p && chpos >= updated_row->used[TEXT_AREA])
25744 chpos = updated_row->used[TEXT_AREA] - 1;
25746 block_input ();
25748 /* Write glyphs. */
25750 hpos = start - updated_row->glyphs[updated_area];
25751 x = draw_glyphs (w, output_cursor.x,
25752 updated_row, updated_area,
25753 hpos, hpos + len,
25754 DRAW_NORMAL_TEXT, 0);
25756 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
25757 if (updated_area == TEXT_AREA
25758 && w->phys_cursor_on_p
25759 && w->phys_cursor.vpos == output_cursor.vpos
25760 && chpos >= hpos
25761 && chpos < hpos + len)
25762 w->phys_cursor_on_p = 0;
25764 unblock_input ();
25766 /* Advance the output cursor. */
25767 output_cursor.hpos += len;
25768 output_cursor.x = x;
25772 /* EXPORT for RIF:
25773 Insert LEN glyphs from START at the nominal cursor position. */
25775 void
25776 x_insert_glyphs (struct window *w, struct glyph *start, int len)
25778 struct frame *f;
25779 int line_height, shift_by_width, shifted_region_width;
25780 struct glyph_row *row;
25781 struct glyph *glyph;
25782 int frame_x, frame_y;
25783 ptrdiff_t hpos;
25785 eassert (updated_row);
25786 block_input ();
25787 f = XFRAME (WINDOW_FRAME (w));
25789 /* Get the height of the line we are in. */
25790 row = updated_row;
25791 line_height = row->height;
25793 /* Get the width of the glyphs to insert. */
25794 shift_by_width = 0;
25795 for (glyph = start; glyph < start + len; ++glyph)
25796 shift_by_width += glyph->pixel_width;
25798 /* Get the width of the region to shift right. */
25799 shifted_region_width = (window_box_width (w, updated_area)
25800 - output_cursor.x
25801 - shift_by_width);
25803 /* Shift right. */
25804 frame_x = window_box_left (w, updated_area) + output_cursor.x;
25805 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
25807 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
25808 line_height, shift_by_width);
25810 /* Write the glyphs. */
25811 hpos = start - row->glyphs[updated_area];
25812 draw_glyphs (w, output_cursor.x, row, updated_area,
25813 hpos, hpos + len,
25814 DRAW_NORMAL_TEXT, 0);
25816 /* Advance the output cursor. */
25817 output_cursor.hpos += len;
25818 output_cursor.x += shift_by_width;
25819 unblock_input ();
25823 /* EXPORT for RIF:
25824 Erase the current text line from the nominal cursor position
25825 (inclusive) to pixel column TO_X (exclusive). The idea is that
25826 everything from TO_X onward is already erased.
25828 TO_X is a pixel position relative to updated_area of currently
25829 updated window W. TO_X == -1 means clear to the end of this area. */
25831 void
25832 x_clear_end_of_line (struct window *w, int to_x)
25834 struct frame *f;
25835 int max_x, min_y, max_y;
25836 int from_x, from_y, to_y;
25838 eassert (updated_row);
25839 f = XFRAME (w->frame);
25841 if (updated_row->full_width_p)
25842 max_x = WINDOW_TOTAL_WIDTH (w);
25843 else
25844 max_x = window_box_width (w, updated_area);
25845 max_y = window_text_bottom_y (w);
25847 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
25848 of window. For TO_X > 0, truncate to end of drawing area. */
25849 if (to_x == 0)
25850 return;
25851 else if (to_x < 0)
25852 to_x = max_x;
25853 else
25854 to_x = min (to_x, max_x);
25856 to_y = min (max_y, output_cursor.y + updated_row->height);
25858 /* Notice if the cursor will be cleared by this operation. */
25859 if (!updated_row->full_width_p)
25860 notice_overwritten_cursor (w, updated_area,
25861 output_cursor.x, -1,
25862 updated_row->y,
25863 MATRIX_ROW_BOTTOM_Y (updated_row));
25865 from_x = output_cursor.x;
25867 /* Translate to frame coordinates. */
25868 if (updated_row->full_width_p)
25870 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
25871 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
25873 else
25875 int area_left = window_box_left (w, updated_area);
25876 from_x += area_left;
25877 to_x += area_left;
25880 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
25881 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
25882 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
25884 /* Prevent inadvertently clearing to end of the X window. */
25885 if (to_x > from_x && to_y > from_y)
25887 block_input ();
25888 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
25889 to_x - from_x, to_y - from_y);
25890 unblock_input ();
25894 #endif /* HAVE_WINDOW_SYSTEM */
25898 /***********************************************************************
25899 Cursor types
25900 ***********************************************************************/
25902 /* Value is the internal representation of the specified cursor type
25903 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
25904 of the bar cursor. */
25906 static enum text_cursor_kinds
25907 get_specified_cursor_type (Lisp_Object arg, int *width)
25909 enum text_cursor_kinds type;
25911 if (NILP (arg))
25912 return NO_CURSOR;
25914 if (EQ (arg, Qbox))
25915 return FILLED_BOX_CURSOR;
25917 if (EQ (arg, Qhollow))
25918 return HOLLOW_BOX_CURSOR;
25920 if (EQ (arg, Qbar))
25922 *width = 2;
25923 return BAR_CURSOR;
25926 if (CONSP (arg)
25927 && EQ (XCAR (arg), Qbar)
25928 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
25930 *width = XINT (XCDR (arg));
25931 return BAR_CURSOR;
25934 if (EQ (arg, Qhbar))
25936 *width = 2;
25937 return HBAR_CURSOR;
25940 if (CONSP (arg)
25941 && EQ (XCAR (arg), Qhbar)
25942 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
25944 *width = XINT (XCDR (arg));
25945 return HBAR_CURSOR;
25948 /* Treat anything unknown as "hollow box cursor".
25949 It was bad to signal an error; people have trouble fixing
25950 .Xdefaults with Emacs, when it has something bad in it. */
25951 type = HOLLOW_BOX_CURSOR;
25953 return type;
25956 /* Set the default cursor types for specified frame. */
25957 void
25958 set_frame_cursor_types (struct frame *f, Lisp_Object arg)
25960 int width = 1;
25961 Lisp_Object tem;
25963 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
25964 FRAME_CURSOR_WIDTH (f) = width;
25966 /* By default, set up the blink-off state depending on the on-state. */
25968 tem = Fassoc (arg, Vblink_cursor_alist);
25969 if (!NILP (tem))
25971 FRAME_BLINK_OFF_CURSOR (f)
25972 = get_specified_cursor_type (XCDR (tem), &width);
25973 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
25975 else
25976 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
25980 #ifdef HAVE_WINDOW_SYSTEM
25982 /* Return the cursor we want to be displayed in window W. Return
25983 width of bar/hbar cursor through WIDTH arg. Return with
25984 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
25985 (i.e. if the `system caret' should track this cursor).
25987 In a mini-buffer window, we want the cursor only to appear if we
25988 are reading input from this window. For the selected window, we
25989 want the cursor type given by the frame parameter or buffer local
25990 setting of cursor-type. If explicitly marked off, draw no cursor.
25991 In all other cases, we want a hollow box cursor. */
25993 static enum text_cursor_kinds
25994 get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
25995 int *active_cursor)
25997 struct frame *f = XFRAME (w->frame);
25998 struct buffer *b = XBUFFER (w->contents);
25999 int cursor_type = DEFAULT_CURSOR;
26000 Lisp_Object alt_cursor;
26001 int non_selected = 0;
26003 *active_cursor = 1;
26005 /* Echo area */
26006 if (cursor_in_echo_area
26007 && FRAME_HAS_MINIBUF_P (f)
26008 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
26010 if (w == XWINDOW (echo_area_window))
26012 if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
26014 *width = FRAME_CURSOR_WIDTH (f);
26015 return FRAME_DESIRED_CURSOR (f);
26017 else
26018 return get_specified_cursor_type (BVAR (b, cursor_type), width);
26021 *active_cursor = 0;
26022 non_selected = 1;
26025 /* Detect a nonselected window or nonselected frame. */
26026 else if (w != XWINDOW (f->selected_window)
26027 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame)
26029 *active_cursor = 0;
26031 if (MINI_WINDOW_P (w) && minibuf_level == 0)
26032 return NO_CURSOR;
26034 non_selected = 1;
26037 /* Never display a cursor in a window in which cursor-type is nil. */
26038 if (NILP (BVAR (b, cursor_type)))
26039 return NO_CURSOR;
26041 /* Get the normal cursor type for this window. */
26042 if (EQ (BVAR (b, cursor_type), Qt))
26044 cursor_type = FRAME_DESIRED_CURSOR (f);
26045 *width = FRAME_CURSOR_WIDTH (f);
26047 else
26048 cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
26050 /* Use cursor-in-non-selected-windows instead
26051 for non-selected window or frame. */
26052 if (non_selected)
26054 alt_cursor = BVAR (b, cursor_in_non_selected_windows);
26055 if (!EQ (Qt, alt_cursor))
26056 return get_specified_cursor_type (alt_cursor, width);
26057 /* t means modify the normal cursor type. */
26058 if (cursor_type == FILLED_BOX_CURSOR)
26059 cursor_type = HOLLOW_BOX_CURSOR;
26060 else if (cursor_type == BAR_CURSOR && *width > 1)
26061 --*width;
26062 return cursor_type;
26065 /* Use normal cursor if not blinked off. */
26066 if (!w->cursor_off_p)
26068 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
26070 if (cursor_type == FILLED_BOX_CURSOR)
26072 /* Using a block cursor on large images can be very annoying.
26073 So use a hollow cursor for "large" images.
26074 If image is not transparent (no mask), also use hollow cursor. */
26075 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
26076 if (img != NULL && IMAGEP (img->spec))
26078 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
26079 where N = size of default frame font size.
26080 This should cover most of the "tiny" icons people may use. */
26081 if (!img->mask
26082 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
26083 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
26084 cursor_type = HOLLOW_BOX_CURSOR;
26087 else if (cursor_type != NO_CURSOR)
26089 /* Display current only supports BOX and HOLLOW cursors for images.
26090 So for now, unconditionally use a HOLLOW cursor when cursor is
26091 not a solid box cursor. */
26092 cursor_type = HOLLOW_BOX_CURSOR;
26095 return cursor_type;
26098 /* Cursor is blinked off, so determine how to "toggle" it. */
26100 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
26101 if ((alt_cursor = Fassoc (BVAR (b, cursor_type), Vblink_cursor_alist), !NILP (alt_cursor)))
26102 return get_specified_cursor_type (XCDR (alt_cursor), width);
26104 /* Then see if frame has specified a specific blink off cursor type. */
26105 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
26107 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
26108 return FRAME_BLINK_OFF_CURSOR (f);
26111 #if 0
26112 /* Some people liked having a permanently visible blinking cursor,
26113 while others had very strong opinions against it. So it was
26114 decided to remove it. KFS 2003-09-03 */
26116 /* Finally perform built-in cursor blinking:
26117 filled box <-> hollow box
26118 wide [h]bar <-> narrow [h]bar
26119 narrow [h]bar <-> no cursor
26120 other type <-> no cursor */
26122 if (cursor_type == FILLED_BOX_CURSOR)
26123 return HOLLOW_BOX_CURSOR;
26125 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
26127 *width = 1;
26128 return cursor_type;
26130 #endif
26132 return NO_CURSOR;
26136 /* Notice when the text cursor of window W has been completely
26137 overwritten by a drawing operation that outputs glyphs in AREA
26138 starting at X0 and ending at X1 in the line starting at Y0 and
26139 ending at Y1. X coordinates are area-relative. X1 < 0 means all
26140 the rest of the line after X0 has been written. Y coordinates
26141 are window-relative. */
26143 static void
26144 notice_overwritten_cursor (struct window *w, enum glyph_row_area area,
26145 int x0, int x1, int y0, int y1)
26147 int cx0, cx1, cy0, cy1;
26148 struct glyph_row *row;
26150 if (!w->phys_cursor_on_p)
26151 return;
26152 if (area != TEXT_AREA)
26153 return;
26155 if (w->phys_cursor.vpos < 0
26156 || w->phys_cursor.vpos >= w->current_matrix->nrows
26157 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
26158 !(row->enabled_p && MATRIX_ROW_DISPLAYS_TEXT_P (row))))
26159 return;
26161 if (row->cursor_in_fringe_p)
26163 row->cursor_in_fringe_p = 0;
26164 draw_fringe_bitmap (w, row, row->reversed_p);
26165 w->phys_cursor_on_p = 0;
26166 return;
26169 cx0 = w->phys_cursor.x;
26170 cx1 = cx0 + w->phys_cursor_width;
26171 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
26172 return;
26174 /* The cursor image will be completely removed from the
26175 screen if the output area intersects the cursor area in
26176 y-direction. When we draw in [y0 y1[, and some part of
26177 the cursor is at y < y0, that part must have been drawn
26178 before. When scrolling, the cursor is erased before
26179 actually scrolling, so we don't come here. When not
26180 scrolling, the rows above the old cursor row must have
26181 changed, and in this case these rows must have written
26182 over the cursor image.
26184 Likewise if part of the cursor is below y1, with the
26185 exception of the cursor being in the first blank row at
26186 the buffer and window end because update_text_area
26187 doesn't draw that row. (Except when it does, but
26188 that's handled in update_text_area.) */
26190 cy0 = w->phys_cursor.y;
26191 cy1 = cy0 + w->phys_cursor_height;
26192 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
26193 return;
26195 w->phys_cursor_on_p = 0;
26198 #endif /* HAVE_WINDOW_SYSTEM */
26201 /************************************************************************
26202 Mouse Face
26203 ************************************************************************/
26205 #ifdef HAVE_WINDOW_SYSTEM
26207 /* EXPORT for RIF:
26208 Fix the display of area AREA of overlapping row ROW in window W
26209 with respect to the overlapping part OVERLAPS. */
26211 void
26212 x_fix_overlapping_area (struct window *w, struct glyph_row *row,
26213 enum glyph_row_area area, int overlaps)
26215 int i, x;
26217 block_input ();
26219 x = 0;
26220 for (i = 0; i < row->used[area];)
26222 if (row->glyphs[area][i].overlaps_vertically_p)
26224 int start = i, start_x = x;
26228 x += row->glyphs[area][i].pixel_width;
26229 ++i;
26231 while (i < row->used[area]
26232 && row->glyphs[area][i].overlaps_vertically_p);
26234 draw_glyphs (w, start_x, row, area,
26235 start, i,
26236 DRAW_NORMAL_TEXT, overlaps);
26238 else
26240 x += row->glyphs[area][i].pixel_width;
26241 ++i;
26245 unblock_input ();
26249 /* EXPORT:
26250 Draw the cursor glyph of window W in glyph row ROW. See the
26251 comment of draw_glyphs for the meaning of HL. */
26253 void
26254 draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
26255 enum draw_glyphs_face hl)
26257 /* If cursor hpos is out of bounds, don't draw garbage. This can
26258 happen in mini-buffer windows when switching between echo area
26259 glyphs and mini-buffer. */
26260 if ((row->reversed_p
26261 ? (w->phys_cursor.hpos >= 0)
26262 : (w->phys_cursor.hpos < row->used[TEXT_AREA])))
26264 int on_p = w->phys_cursor_on_p;
26265 int x1;
26266 int hpos = w->phys_cursor.hpos;
26268 /* When the window is hscrolled, cursor hpos can legitimately be
26269 out of bounds, but we draw the cursor at the corresponding
26270 window margin in that case. */
26271 if (!row->reversed_p && hpos < 0)
26272 hpos = 0;
26273 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26274 hpos = row->used[TEXT_AREA] - 1;
26276 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA, hpos, hpos + 1,
26277 hl, 0);
26278 w->phys_cursor_on_p = on_p;
26280 if (hl == DRAW_CURSOR)
26281 w->phys_cursor_width = x1 - w->phys_cursor.x;
26282 /* When we erase the cursor, and ROW is overlapped by other
26283 rows, make sure that these overlapping parts of other rows
26284 are redrawn. */
26285 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
26287 w->phys_cursor_width = x1 - w->phys_cursor.x;
26289 if (row > w->current_matrix->rows
26290 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
26291 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
26292 OVERLAPS_ERASED_CURSOR);
26294 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
26295 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
26296 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
26297 OVERLAPS_ERASED_CURSOR);
26303 /* EXPORT:
26304 Erase the image of a cursor of window W from the screen. */
26306 void
26307 erase_phys_cursor (struct window *w)
26309 struct frame *f = XFRAME (w->frame);
26310 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
26311 int hpos = w->phys_cursor.hpos;
26312 int vpos = w->phys_cursor.vpos;
26313 int mouse_face_here_p = 0;
26314 struct glyph_matrix *active_glyphs = w->current_matrix;
26315 struct glyph_row *cursor_row;
26316 struct glyph *cursor_glyph;
26317 enum draw_glyphs_face hl;
26319 /* No cursor displayed or row invalidated => nothing to do on the
26320 screen. */
26321 if (w->phys_cursor_type == NO_CURSOR)
26322 goto mark_cursor_off;
26324 /* VPOS >= active_glyphs->nrows means that window has been resized.
26325 Don't bother to erase the cursor. */
26326 if (vpos >= active_glyphs->nrows)
26327 goto mark_cursor_off;
26329 /* If row containing cursor is marked invalid, there is nothing we
26330 can do. */
26331 cursor_row = MATRIX_ROW (active_glyphs, vpos);
26332 if (!cursor_row->enabled_p)
26333 goto mark_cursor_off;
26335 /* If line spacing is > 0, old cursor may only be partially visible in
26336 window after split-window. So adjust visible height. */
26337 cursor_row->visible_height = min (cursor_row->visible_height,
26338 window_text_bottom_y (w) - cursor_row->y);
26340 /* If row is completely invisible, don't attempt to delete a cursor which
26341 isn't there. This can happen if cursor is at top of a window, and
26342 we switch to a buffer with a header line in that window. */
26343 if (cursor_row->visible_height <= 0)
26344 goto mark_cursor_off;
26346 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
26347 if (cursor_row->cursor_in_fringe_p)
26349 cursor_row->cursor_in_fringe_p = 0;
26350 draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
26351 goto mark_cursor_off;
26354 /* This can happen when the new row is shorter than the old one.
26355 In this case, either draw_glyphs or clear_end_of_line
26356 should have cleared the cursor. Note that we wouldn't be
26357 able to erase the cursor in this case because we don't have a
26358 cursor glyph at hand. */
26359 if ((cursor_row->reversed_p
26360 ? (w->phys_cursor.hpos < 0)
26361 : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
26362 goto mark_cursor_off;
26364 /* When the window is hscrolled, cursor hpos can legitimately be out
26365 of bounds, but we draw the cursor at the corresponding window
26366 margin in that case. */
26367 if (!cursor_row->reversed_p && hpos < 0)
26368 hpos = 0;
26369 if (cursor_row->reversed_p && hpos >= cursor_row->used[TEXT_AREA])
26370 hpos = cursor_row->used[TEXT_AREA] - 1;
26372 /* If the cursor is in the mouse face area, redisplay that when
26373 we clear the cursor. */
26374 if (! NILP (hlinfo->mouse_face_window)
26375 && coords_in_mouse_face_p (w, hpos, vpos)
26376 /* Don't redraw the cursor's spot in mouse face if it is at the
26377 end of a line (on a newline). The cursor appears there, but
26378 mouse highlighting does not. */
26379 && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
26380 mouse_face_here_p = 1;
26382 /* Maybe clear the display under the cursor. */
26383 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
26385 int x, y, left_x;
26386 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
26387 int width;
26389 cursor_glyph = get_phys_cursor_glyph (w);
26390 if (cursor_glyph == NULL)
26391 goto mark_cursor_off;
26393 width = cursor_glyph->pixel_width;
26394 left_x = window_box_left_offset (w, TEXT_AREA);
26395 x = w->phys_cursor.x;
26396 if (x < left_x)
26397 width -= left_x - x;
26398 width = min (width, window_box_width (w, TEXT_AREA) - x);
26399 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
26400 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
26402 if (width > 0)
26403 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
26406 /* Erase the cursor by redrawing the character underneath it. */
26407 if (mouse_face_here_p)
26408 hl = DRAW_MOUSE_FACE;
26409 else
26410 hl = DRAW_NORMAL_TEXT;
26411 draw_phys_cursor_glyph (w, cursor_row, hl);
26413 mark_cursor_off:
26414 w->phys_cursor_on_p = 0;
26415 w->phys_cursor_type = NO_CURSOR;
26419 /* EXPORT:
26420 Display or clear cursor of window W. If ON is zero, clear the
26421 cursor. If it is non-zero, display the cursor. If ON is nonzero,
26422 where to put the cursor is specified by HPOS, VPOS, X and Y. */
26424 void
26425 display_and_set_cursor (struct window *w, int on,
26426 int hpos, int vpos, int x, int y)
26428 struct frame *f = XFRAME (w->frame);
26429 int new_cursor_type;
26430 int new_cursor_width;
26431 int active_cursor;
26432 struct glyph_row *glyph_row;
26433 struct glyph *glyph;
26435 /* This is pointless on invisible frames, and dangerous on garbaged
26436 windows and frames; in the latter case, the frame or window may
26437 be in the midst of changing its size, and x and y may be off the
26438 window. */
26439 if (! FRAME_VISIBLE_P (f)
26440 || FRAME_GARBAGED_P (f)
26441 || vpos >= w->current_matrix->nrows
26442 || hpos >= w->current_matrix->matrix_w)
26443 return;
26445 /* If cursor is off and we want it off, return quickly. */
26446 if (!on && !w->phys_cursor_on_p)
26447 return;
26449 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
26450 /* If cursor row is not enabled, we don't really know where to
26451 display the cursor. */
26452 if (!glyph_row->enabled_p)
26454 w->phys_cursor_on_p = 0;
26455 return;
26458 glyph = NULL;
26459 if (!glyph_row->exact_window_width_line_p
26460 || (0 <= hpos && hpos < glyph_row->used[TEXT_AREA]))
26461 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
26463 eassert (input_blocked_p ());
26465 /* Set new_cursor_type to the cursor we want to be displayed. */
26466 new_cursor_type = get_window_cursor_type (w, glyph,
26467 &new_cursor_width, &active_cursor);
26469 /* If cursor is currently being shown and we don't want it to be or
26470 it is in the wrong place, or the cursor type is not what we want,
26471 erase it. */
26472 if (w->phys_cursor_on_p
26473 && (!on
26474 || w->phys_cursor.x != x
26475 || w->phys_cursor.y != y
26476 || new_cursor_type != w->phys_cursor_type
26477 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
26478 && new_cursor_width != w->phys_cursor_width)))
26479 erase_phys_cursor (w);
26481 /* Don't check phys_cursor_on_p here because that flag is only set
26482 to zero in some cases where we know that the cursor has been
26483 completely erased, to avoid the extra work of erasing the cursor
26484 twice. In other words, phys_cursor_on_p can be 1 and the cursor
26485 still not be visible, or it has only been partly erased. */
26486 if (on)
26488 w->phys_cursor_ascent = glyph_row->ascent;
26489 w->phys_cursor_height = glyph_row->height;
26491 /* Set phys_cursor_.* before x_draw_.* is called because some
26492 of them may need the information. */
26493 w->phys_cursor.x = x;
26494 w->phys_cursor.y = glyph_row->y;
26495 w->phys_cursor.hpos = hpos;
26496 w->phys_cursor.vpos = vpos;
26499 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
26500 new_cursor_type, new_cursor_width,
26501 on, active_cursor);
26505 /* Switch the display of W's cursor on or off, according to the value
26506 of ON. */
26508 static void
26509 update_window_cursor (struct window *w, int on)
26511 /* Don't update cursor in windows whose frame is in the process
26512 of being deleted. */
26513 if (w->current_matrix)
26515 int hpos = w->phys_cursor.hpos;
26516 int vpos = w->phys_cursor.vpos;
26517 struct glyph_row *row;
26519 if (vpos >= w->current_matrix->nrows
26520 || hpos >= w->current_matrix->matrix_w)
26521 return;
26523 row = MATRIX_ROW (w->current_matrix, vpos);
26525 /* When the window is hscrolled, cursor hpos can legitimately be
26526 out of bounds, but we draw the cursor at the corresponding
26527 window margin in that case. */
26528 if (!row->reversed_p && hpos < 0)
26529 hpos = 0;
26530 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26531 hpos = row->used[TEXT_AREA] - 1;
26533 block_input ();
26534 display_and_set_cursor (w, on, hpos, vpos,
26535 w->phys_cursor.x, w->phys_cursor.y);
26536 unblock_input ();
26541 /* Call update_window_cursor with parameter ON_P on all leaf windows
26542 in the window tree rooted at W. */
26544 static void
26545 update_cursor_in_window_tree (struct window *w, int on_p)
26547 while (w)
26549 if (WINDOWP (w->contents))
26550 update_cursor_in_window_tree (XWINDOW (w->contents), on_p);
26551 else
26552 update_window_cursor (w, on_p);
26554 w = NILP (w->next) ? 0 : XWINDOW (w->next);
26559 /* EXPORT:
26560 Display the cursor on window W, or clear it, according to ON_P.
26561 Don't change the cursor's position. */
26563 void
26564 x_update_cursor (struct frame *f, int on_p)
26566 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
26570 /* EXPORT:
26571 Clear the cursor of window W to background color, and mark the
26572 cursor as not shown. This is used when the text where the cursor
26573 is about to be rewritten. */
26575 void
26576 x_clear_cursor (struct window *w)
26578 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
26579 update_window_cursor (w, 0);
26582 #endif /* HAVE_WINDOW_SYSTEM */
26584 /* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
26585 and MSDOS. */
26586 static void
26587 draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
26588 int start_hpos, int end_hpos,
26589 enum draw_glyphs_face draw)
26591 #ifdef HAVE_WINDOW_SYSTEM
26592 if (FRAME_WINDOW_P (XFRAME (w->frame)))
26594 draw_glyphs (w, start_x, row, TEXT_AREA, start_hpos, end_hpos, draw, 0);
26595 return;
26597 #endif
26598 #if defined (HAVE_GPM) || defined (MSDOS) || defined (WINDOWSNT)
26599 tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
26600 #endif
26603 /* Display the active region described by mouse_face_* according to DRAW. */
26605 static void
26606 show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
26608 struct window *w = XWINDOW (hlinfo->mouse_face_window);
26609 struct frame *f = XFRAME (WINDOW_FRAME (w));
26611 if (/* If window is in the process of being destroyed, don't bother
26612 to do anything. */
26613 w->current_matrix != NULL
26614 /* Don't update mouse highlight if hidden */
26615 && (draw != DRAW_MOUSE_FACE || !hlinfo->mouse_face_hidden)
26616 /* Recognize when we are called to operate on rows that don't exist
26617 anymore. This can happen when a window is split. */
26618 && hlinfo->mouse_face_end_row < w->current_matrix->nrows)
26620 int phys_cursor_on_p = w->phys_cursor_on_p;
26621 struct glyph_row *row, *first, *last;
26623 first = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
26624 last = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
26626 for (row = first; row <= last && row->enabled_p; ++row)
26628 int start_hpos, end_hpos, start_x;
26630 /* For all but the first row, the highlight starts at column 0. */
26631 if (row == first)
26633 /* R2L rows have BEG and END in reversed order, but the
26634 screen drawing geometry is always left to right. So
26635 we need to mirror the beginning and end of the
26636 highlighted area in R2L rows. */
26637 if (!row->reversed_p)
26639 start_hpos = hlinfo->mouse_face_beg_col;
26640 start_x = hlinfo->mouse_face_beg_x;
26642 else if (row == last)
26644 start_hpos = hlinfo->mouse_face_end_col;
26645 start_x = hlinfo->mouse_face_end_x;
26647 else
26649 start_hpos = 0;
26650 start_x = 0;
26653 else if (row->reversed_p && row == last)
26655 start_hpos = hlinfo->mouse_face_end_col;
26656 start_x = hlinfo->mouse_face_end_x;
26658 else
26660 start_hpos = 0;
26661 start_x = 0;
26664 if (row == last)
26666 if (!row->reversed_p)
26667 end_hpos = hlinfo->mouse_face_end_col;
26668 else if (row == first)
26669 end_hpos = hlinfo->mouse_face_beg_col;
26670 else
26672 end_hpos = row->used[TEXT_AREA];
26673 if (draw == DRAW_NORMAL_TEXT)
26674 row->fill_line_p = 1; /* Clear to end of line */
26677 else if (row->reversed_p && row == first)
26678 end_hpos = hlinfo->mouse_face_beg_col;
26679 else
26681 end_hpos = row->used[TEXT_AREA];
26682 if (draw == DRAW_NORMAL_TEXT)
26683 row->fill_line_p = 1; /* Clear to end of line */
26686 if (end_hpos > start_hpos)
26688 draw_row_with_mouse_face (w, start_x, row,
26689 start_hpos, end_hpos, draw);
26691 row->mouse_face_p
26692 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
26696 #ifdef HAVE_WINDOW_SYSTEM
26697 /* When we've written over the cursor, arrange for it to
26698 be displayed again. */
26699 if (FRAME_WINDOW_P (f)
26700 && phys_cursor_on_p && !w->phys_cursor_on_p)
26702 int hpos = w->phys_cursor.hpos;
26704 /* When the window is hscrolled, cursor hpos can legitimately be
26705 out of bounds, but we draw the cursor at the corresponding
26706 window margin in that case. */
26707 if (!row->reversed_p && hpos < 0)
26708 hpos = 0;
26709 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26710 hpos = row->used[TEXT_AREA] - 1;
26712 block_input ();
26713 display_and_set_cursor (w, 1, hpos, w->phys_cursor.vpos,
26714 w->phys_cursor.x, w->phys_cursor.y);
26715 unblock_input ();
26717 #endif /* HAVE_WINDOW_SYSTEM */
26720 #ifdef HAVE_WINDOW_SYSTEM
26721 /* Change the mouse cursor. */
26722 if (FRAME_WINDOW_P (f))
26724 if (draw == DRAW_NORMAL_TEXT
26725 && !EQ (hlinfo->mouse_face_window, f->tool_bar_window))
26726 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
26727 else if (draw == DRAW_MOUSE_FACE)
26728 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
26729 else
26730 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
26732 #endif /* HAVE_WINDOW_SYSTEM */
26735 /* EXPORT:
26736 Clear out the mouse-highlighted active region.
26737 Redraw it un-highlighted first. Value is non-zero if mouse
26738 face was actually drawn unhighlighted. */
26741 clear_mouse_face (Mouse_HLInfo *hlinfo)
26743 int cleared = 0;
26745 if (!hlinfo->mouse_face_hidden && !NILP (hlinfo->mouse_face_window))
26747 show_mouse_face (hlinfo, DRAW_NORMAL_TEXT);
26748 cleared = 1;
26751 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
26752 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
26753 hlinfo->mouse_face_window = Qnil;
26754 hlinfo->mouse_face_overlay = Qnil;
26755 return cleared;
26758 /* Return non-zero if the coordinates HPOS and VPOS on windows W are
26759 within the mouse face on that window. */
26760 static int
26761 coords_in_mouse_face_p (struct window *w, int hpos, int vpos)
26763 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
26765 /* Quickly resolve the easy cases. */
26766 if (!(WINDOWP (hlinfo->mouse_face_window)
26767 && XWINDOW (hlinfo->mouse_face_window) == w))
26768 return 0;
26769 if (vpos < hlinfo->mouse_face_beg_row
26770 || vpos > hlinfo->mouse_face_end_row)
26771 return 0;
26772 if (vpos > hlinfo->mouse_face_beg_row
26773 && vpos < hlinfo->mouse_face_end_row)
26774 return 1;
26776 if (!MATRIX_ROW (w->current_matrix, vpos)->reversed_p)
26778 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
26780 if (hlinfo->mouse_face_beg_col <= hpos && hpos < hlinfo->mouse_face_end_col)
26781 return 1;
26783 else if ((vpos == hlinfo->mouse_face_beg_row
26784 && hpos >= hlinfo->mouse_face_beg_col)
26785 || (vpos == hlinfo->mouse_face_end_row
26786 && hpos < hlinfo->mouse_face_end_col))
26787 return 1;
26789 else
26791 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
26793 if (hlinfo->mouse_face_end_col < hpos && hpos <= hlinfo->mouse_face_beg_col)
26794 return 1;
26796 else if ((vpos == hlinfo->mouse_face_beg_row
26797 && hpos <= hlinfo->mouse_face_beg_col)
26798 || (vpos == hlinfo->mouse_face_end_row
26799 && hpos > hlinfo->mouse_face_end_col))
26800 return 1;
26802 return 0;
26806 /* EXPORT:
26807 Non-zero if physical cursor of window W is within mouse face. */
26810 cursor_in_mouse_face_p (struct window *w)
26812 int hpos = w->phys_cursor.hpos;
26813 int vpos = w->phys_cursor.vpos;
26814 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
26816 /* When the window is hscrolled, cursor hpos can legitimately be out
26817 of bounds, but we draw the cursor at the corresponding window
26818 margin in that case. */
26819 if (!row->reversed_p && hpos < 0)
26820 hpos = 0;
26821 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26822 hpos = row->used[TEXT_AREA] - 1;
26824 return coords_in_mouse_face_p (w, hpos, vpos);
26829 /* Find the glyph rows START_ROW and END_ROW of window W that display
26830 characters between buffer positions START_CHARPOS and END_CHARPOS
26831 (excluding END_CHARPOS). DISP_STRING is a display string that
26832 covers these buffer positions. This is similar to
26833 row_containing_pos, but is more accurate when bidi reordering makes
26834 buffer positions change non-linearly with glyph rows. */
26835 static void
26836 rows_from_pos_range (struct window *w,
26837 ptrdiff_t start_charpos, ptrdiff_t end_charpos,
26838 Lisp_Object disp_string,
26839 struct glyph_row **start, struct glyph_row **end)
26841 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
26842 int last_y = window_text_bottom_y (w);
26843 struct glyph_row *row;
26845 *start = NULL;
26846 *end = NULL;
26848 while (!first->enabled_p
26849 && first < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
26850 first++;
26852 /* Find the START row. */
26853 for (row = first;
26854 row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y;
26855 row++)
26857 /* A row can potentially be the START row if the range of the
26858 characters it displays intersects the range
26859 [START_CHARPOS..END_CHARPOS). */
26860 if (! ((start_charpos < MATRIX_ROW_START_CHARPOS (row)
26861 && end_charpos < MATRIX_ROW_START_CHARPOS (row))
26862 /* See the commentary in row_containing_pos, for the
26863 explanation of the complicated way to check whether
26864 some position is beyond the end of the characters
26865 displayed by a row. */
26866 || ((start_charpos > MATRIX_ROW_END_CHARPOS (row)
26867 || (start_charpos == MATRIX_ROW_END_CHARPOS (row)
26868 && !row->ends_at_zv_p
26869 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
26870 && (end_charpos > MATRIX_ROW_END_CHARPOS (row)
26871 || (end_charpos == MATRIX_ROW_END_CHARPOS (row)
26872 && !row->ends_at_zv_p
26873 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))))))
26875 /* Found a candidate row. Now make sure at least one of the
26876 glyphs it displays has a charpos from the range
26877 [START_CHARPOS..END_CHARPOS).
26879 This is not obvious because bidi reordering could make
26880 buffer positions of a row be 1,2,3,102,101,100, and if we
26881 want to highlight characters in [50..60), we don't want
26882 this row, even though [50..60) does intersect [1..103),
26883 the range of character positions given by the row's start
26884 and end positions. */
26885 struct glyph *g = row->glyphs[TEXT_AREA];
26886 struct glyph *e = g + row->used[TEXT_AREA];
26888 while (g < e)
26890 if (((BUFFERP (g->object) || INTEGERP (g->object))
26891 && start_charpos <= g->charpos && g->charpos < end_charpos)
26892 /* A glyph that comes from DISP_STRING is by
26893 definition to be highlighted. */
26894 || EQ (g->object, disp_string))
26895 *start = row;
26896 g++;
26898 if (*start)
26899 break;
26903 /* Find the END row. */
26904 if (!*start
26905 /* If the last row is partially visible, start looking for END
26906 from that row, instead of starting from FIRST. */
26907 && !(row->enabled_p
26908 && row->y < last_y && MATRIX_ROW_BOTTOM_Y (row) > last_y))
26909 row = first;
26910 for ( ; row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y; row++)
26912 struct glyph_row *next = row + 1;
26913 ptrdiff_t next_start = MATRIX_ROW_START_CHARPOS (next);
26915 if (!next->enabled_p
26916 || next >= MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)
26917 /* The first row >= START whose range of displayed characters
26918 does NOT intersect the range [START_CHARPOS..END_CHARPOS]
26919 is the row END + 1. */
26920 || (start_charpos < next_start
26921 && end_charpos < next_start)
26922 || ((start_charpos > MATRIX_ROW_END_CHARPOS (next)
26923 || (start_charpos == MATRIX_ROW_END_CHARPOS (next)
26924 && !next->ends_at_zv_p
26925 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))
26926 && (end_charpos > MATRIX_ROW_END_CHARPOS (next)
26927 || (end_charpos == MATRIX_ROW_END_CHARPOS (next)
26928 && !next->ends_at_zv_p
26929 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))))
26931 *end = row;
26932 break;
26934 else
26936 /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
26937 but none of the characters it displays are in the range, it is
26938 also END + 1. */
26939 struct glyph *g = next->glyphs[TEXT_AREA];
26940 struct glyph *s = g;
26941 struct glyph *e = g + next->used[TEXT_AREA];
26943 while (g < e)
26945 if (((BUFFERP (g->object) || INTEGERP (g->object))
26946 && ((start_charpos <= g->charpos && g->charpos < end_charpos)
26947 /* If the buffer position of the first glyph in
26948 the row is equal to END_CHARPOS, it means
26949 the last character to be highlighted is the
26950 newline of ROW, and we must consider NEXT as
26951 END, not END+1. */
26952 || (((!next->reversed_p && g == s)
26953 || (next->reversed_p && g == e - 1))
26954 && (g->charpos == end_charpos
26955 /* Special case for when NEXT is an
26956 empty line at ZV. */
26957 || (g->charpos == -1
26958 && !row->ends_at_zv_p
26959 && next_start == end_charpos)))))
26960 /* A glyph that comes from DISP_STRING is by
26961 definition to be highlighted. */
26962 || EQ (g->object, disp_string))
26963 break;
26964 g++;
26966 if (g == e)
26968 *end = row;
26969 break;
26971 /* The first row that ends at ZV must be the last to be
26972 highlighted. */
26973 else if (next->ends_at_zv_p)
26975 *end = next;
26976 break;
26982 /* This function sets the mouse_face_* elements of HLINFO, assuming
26983 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
26984 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
26985 for the overlay or run of text properties specifying the mouse
26986 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
26987 before-string and after-string that must also be highlighted.
26988 DISP_STRING, if non-nil, is a display string that may cover some
26989 or all of the highlighted text. */
26991 static void
26992 mouse_face_from_buffer_pos (Lisp_Object window,
26993 Mouse_HLInfo *hlinfo,
26994 ptrdiff_t mouse_charpos,
26995 ptrdiff_t start_charpos,
26996 ptrdiff_t end_charpos,
26997 Lisp_Object before_string,
26998 Lisp_Object after_string,
26999 Lisp_Object disp_string)
27001 struct window *w = XWINDOW (window);
27002 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
27003 struct glyph_row *r1, *r2;
27004 struct glyph *glyph, *end;
27005 ptrdiff_t ignore, pos;
27006 int x;
27008 eassert (NILP (disp_string) || STRINGP (disp_string));
27009 eassert (NILP (before_string) || STRINGP (before_string));
27010 eassert (NILP (after_string) || STRINGP (after_string));
27012 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
27013 rows_from_pos_range (w, start_charpos, end_charpos, disp_string, &r1, &r2);
27014 if (r1 == NULL)
27015 r1 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
27016 /* If the before-string or display-string contains newlines,
27017 rows_from_pos_range skips to its last row. Move back. */
27018 if (!NILP (before_string) || !NILP (disp_string))
27020 struct glyph_row *prev;
27021 while ((prev = r1 - 1, prev >= first)
27022 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
27023 && prev->used[TEXT_AREA] > 0)
27025 struct glyph *beg = prev->glyphs[TEXT_AREA];
27026 glyph = beg + prev->used[TEXT_AREA];
27027 while (--glyph >= beg && INTEGERP (glyph->object));
27028 if (glyph < beg
27029 || !(EQ (glyph->object, before_string)
27030 || EQ (glyph->object, disp_string)))
27031 break;
27032 r1 = prev;
27035 if (r2 == NULL)
27037 r2 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
27038 hlinfo->mouse_face_past_end = 1;
27040 else if (!NILP (after_string))
27042 /* If the after-string has newlines, advance to its last row. */
27043 struct glyph_row *next;
27044 struct glyph_row *last
27045 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
27047 for (next = r2 + 1;
27048 next <= last
27049 && next->used[TEXT_AREA] > 0
27050 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
27051 ++next)
27052 r2 = next;
27054 /* The rest of the display engine assumes that mouse_face_beg_row is
27055 either above mouse_face_end_row or identical to it. But with
27056 bidi-reordered continued lines, the row for START_CHARPOS could
27057 be below the row for END_CHARPOS. If so, swap the rows and store
27058 them in correct order. */
27059 if (r1->y > r2->y)
27061 struct glyph_row *tem = r2;
27063 r2 = r1;
27064 r1 = tem;
27067 hlinfo->mouse_face_beg_y = r1->y;
27068 hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
27069 hlinfo->mouse_face_end_y = r2->y;
27070 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
27072 /* For a bidi-reordered row, the positions of BEFORE_STRING,
27073 AFTER_STRING, DISP_STRING, START_CHARPOS, and END_CHARPOS
27074 could be anywhere in the row and in any order. The strategy
27075 below is to find the leftmost and the rightmost glyph that
27076 belongs to either of these 3 strings, or whose position is
27077 between START_CHARPOS and END_CHARPOS, and highlight all the
27078 glyphs between those two. This may cover more than just the text
27079 between START_CHARPOS and END_CHARPOS if the range of characters
27080 strides the bidi level boundary, e.g. if the beginning is in R2L
27081 text while the end is in L2R text or vice versa. */
27082 if (!r1->reversed_p)
27084 /* This row is in a left to right paragraph. Scan it left to
27085 right. */
27086 glyph = r1->glyphs[TEXT_AREA];
27087 end = glyph + r1->used[TEXT_AREA];
27088 x = r1->x;
27090 /* Skip truncation glyphs at the start of the glyph row. */
27091 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
27092 for (; glyph < end
27093 && INTEGERP (glyph->object)
27094 && glyph->charpos < 0;
27095 ++glyph)
27096 x += glyph->pixel_width;
27098 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
27099 or DISP_STRING, and the first glyph from buffer whose
27100 position is between START_CHARPOS and END_CHARPOS. */
27101 for (; glyph < end
27102 && !INTEGERP (glyph->object)
27103 && !EQ (glyph->object, disp_string)
27104 && !(BUFFERP (glyph->object)
27105 && (glyph->charpos >= start_charpos
27106 && glyph->charpos < end_charpos));
27107 ++glyph)
27109 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27110 are present at buffer positions between START_CHARPOS and
27111 END_CHARPOS, or if they come from an overlay. */
27112 if (EQ (glyph->object, before_string))
27114 pos = string_buffer_position (before_string,
27115 start_charpos);
27116 /* If pos == 0, it means before_string came from an
27117 overlay, not from a buffer position. */
27118 if (!pos || (pos >= start_charpos && pos < end_charpos))
27119 break;
27121 else if (EQ (glyph->object, after_string))
27123 pos = string_buffer_position (after_string, end_charpos);
27124 if (!pos || (pos >= start_charpos && pos < end_charpos))
27125 break;
27127 x += glyph->pixel_width;
27129 hlinfo->mouse_face_beg_x = x;
27130 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
27132 else
27134 /* This row is in a right to left paragraph. Scan it right to
27135 left. */
27136 struct glyph *g;
27138 end = r1->glyphs[TEXT_AREA] - 1;
27139 glyph = end + r1->used[TEXT_AREA];
27141 /* Skip truncation glyphs at the start of the glyph row. */
27142 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
27143 for (; glyph > end
27144 && INTEGERP (glyph->object)
27145 && glyph->charpos < 0;
27146 --glyph)
27149 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
27150 or DISP_STRING, and the first glyph from buffer whose
27151 position is between START_CHARPOS and END_CHARPOS. */
27152 for (; glyph > end
27153 && !INTEGERP (glyph->object)
27154 && !EQ (glyph->object, disp_string)
27155 && !(BUFFERP (glyph->object)
27156 && (glyph->charpos >= start_charpos
27157 && glyph->charpos < end_charpos));
27158 --glyph)
27160 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27161 are present at buffer positions between START_CHARPOS and
27162 END_CHARPOS, or if they come from an overlay. */
27163 if (EQ (glyph->object, before_string))
27165 pos = string_buffer_position (before_string, start_charpos);
27166 /* If pos == 0, it means before_string came from an
27167 overlay, not from a buffer position. */
27168 if (!pos || (pos >= start_charpos && pos < end_charpos))
27169 break;
27171 else if (EQ (glyph->object, after_string))
27173 pos = string_buffer_position (after_string, end_charpos);
27174 if (!pos || (pos >= start_charpos && pos < end_charpos))
27175 break;
27179 glyph++; /* first glyph to the right of the highlighted area */
27180 for (g = r1->glyphs[TEXT_AREA], x = r1->x; g < glyph; g++)
27181 x += g->pixel_width;
27182 hlinfo->mouse_face_beg_x = x;
27183 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
27186 /* If the highlight ends in a different row, compute GLYPH and END
27187 for the end row. Otherwise, reuse the values computed above for
27188 the row where the highlight begins. */
27189 if (r2 != r1)
27191 if (!r2->reversed_p)
27193 glyph = r2->glyphs[TEXT_AREA];
27194 end = glyph + r2->used[TEXT_AREA];
27195 x = r2->x;
27197 else
27199 end = r2->glyphs[TEXT_AREA] - 1;
27200 glyph = end + r2->used[TEXT_AREA];
27204 if (!r2->reversed_p)
27206 /* Skip truncation and continuation glyphs near the end of the
27207 row, and also blanks and stretch glyphs inserted by
27208 extend_face_to_end_of_line. */
27209 while (end > glyph
27210 && INTEGERP ((end - 1)->object))
27211 --end;
27212 /* Scan the rest of the glyph row from the end, looking for the
27213 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
27214 DISP_STRING, or whose position is between START_CHARPOS
27215 and END_CHARPOS */
27216 for (--end;
27217 end > glyph
27218 && !INTEGERP (end->object)
27219 && !EQ (end->object, disp_string)
27220 && !(BUFFERP (end->object)
27221 && (end->charpos >= start_charpos
27222 && end->charpos < end_charpos));
27223 --end)
27225 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27226 are present at buffer positions between START_CHARPOS and
27227 END_CHARPOS, or if they come from an overlay. */
27228 if (EQ (end->object, before_string))
27230 pos = string_buffer_position (before_string, start_charpos);
27231 if (!pos || (pos >= start_charpos && pos < end_charpos))
27232 break;
27234 else if (EQ (end->object, after_string))
27236 pos = string_buffer_position (after_string, end_charpos);
27237 if (!pos || (pos >= start_charpos && pos < end_charpos))
27238 break;
27241 /* Find the X coordinate of the last glyph to be highlighted. */
27242 for (; glyph <= end; ++glyph)
27243 x += glyph->pixel_width;
27245 hlinfo->mouse_face_end_x = x;
27246 hlinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
27248 else
27250 /* Skip truncation and continuation glyphs near the end of the
27251 row, and also blanks and stretch glyphs inserted by
27252 extend_face_to_end_of_line. */
27253 x = r2->x;
27254 end++;
27255 while (end < glyph
27256 && INTEGERP (end->object))
27258 x += end->pixel_width;
27259 ++end;
27261 /* Scan the rest of the glyph row from the end, looking for the
27262 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
27263 DISP_STRING, or whose position is between START_CHARPOS
27264 and END_CHARPOS */
27265 for ( ;
27266 end < glyph
27267 && !INTEGERP (end->object)
27268 && !EQ (end->object, disp_string)
27269 && !(BUFFERP (end->object)
27270 && (end->charpos >= start_charpos
27271 && end->charpos < end_charpos));
27272 ++end)
27274 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27275 are present at buffer positions between START_CHARPOS and
27276 END_CHARPOS, or if they come from an overlay. */
27277 if (EQ (end->object, before_string))
27279 pos = string_buffer_position (before_string, start_charpos);
27280 if (!pos || (pos >= start_charpos && pos < end_charpos))
27281 break;
27283 else if (EQ (end->object, after_string))
27285 pos = string_buffer_position (after_string, end_charpos);
27286 if (!pos || (pos >= start_charpos && pos < end_charpos))
27287 break;
27289 x += end->pixel_width;
27291 /* If we exited the above loop because we arrived at the last
27292 glyph of the row, and its buffer position is still not in
27293 range, it means the last character in range is the preceding
27294 newline. Bump the end column and x values to get past the
27295 last glyph. */
27296 if (end == glyph
27297 && BUFFERP (end->object)
27298 && (end->charpos < start_charpos
27299 || end->charpos >= end_charpos))
27301 x += end->pixel_width;
27302 ++end;
27304 hlinfo->mouse_face_end_x = x;
27305 hlinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
27308 hlinfo->mouse_face_window = window;
27309 hlinfo->mouse_face_face_id
27310 = face_at_buffer_position (w, mouse_charpos, 0, 0, &ignore,
27311 mouse_charpos + 1,
27312 !hlinfo->mouse_face_hidden, -1);
27313 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
27316 /* The following function is not used anymore (replaced with
27317 mouse_face_from_string_pos), but I leave it here for the time
27318 being, in case someone would. */
27320 #if 0 /* not used */
27322 /* Find the position of the glyph for position POS in OBJECT in
27323 window W's current matrix, and return in *X, *Y the pixel
27324 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
27326 RIGHT_P non-zero means return the position of the right edge of the
27327 glyph, RIGHT_P zero means return the left edge position.
27329 If no glyph for POS exists in the matrix, return the position of
27330 the glyph with the next smaller position that is in the matrix, if
27331 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
27332 exists in the matrix, return the position of the glyph with the
27333 next larger position in OBJECT.
27335 Value is non-zero if a glyph was found. */
27337 static int
27338 fast_find_string_pos (struct window *w, ptrdiff_t pos, Lisp_Object object,
27339 int *hpos, int *vpos, int *x, int *y, int right_p)
27341 int yb = window_text_bottom_y (w);
27342 struct glyph_row *r;
27343 struct glyph *best_glyph = NULL;
27344 struct glyph_row *best_row = NULL;
27345 int best_x = 0;
27347 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
27348 r->enabled_p && r->y < yb;
27349 ++r)
27351 struct glyph *g = r->glyphs[TEXT_AREA];
27352 struct glyph *e = g + r->used[TEXT_AREA];
27353 int gx;
27355 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
27356 if (EQ (g->object, object))
27358 if (g->charpos == pos)
27360 best_glyph = g;
27361 best_x = gx;
27362 best_row = r;
27363 goto found;
27365 else if (best_glyph == NULL
27366 || ((eabs (g->charpos - pos)
27367 < eabs (best_glyph->charpos - pos))
27368 && (right_p
27369 ? g->charpos < pos
27370 : g->charpos > pos)))
27372 best_glyph = g;
27373 best_x = gx;
27374 best_row = r;
27379 found:
27381 if (best_glyph)
27383 *x = best_x;
27384 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
27386 if (right_p)
27388 *x += best_glyph->pixel_width;
27389 ++*hpos;
27392 *y = best_row->y;
27393 *vpos = MATRIX_ROW_VPOS (best_row, w->current_matrix);
27396 return best_glyph != NULL;
27398 #endif /* not used */
27400 /* Find the positions of the first and the last glyphs in window W's
27401 current matrix that occlude positions [STARTPOS..ENDPOS] in OBJECT
27402 (assumed to be a string), and return in HLINFO's mouse_face_*
27403 members the pixel and column/row coordinates of those glyphs. */
27405 static void
27406 mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
27407 Lisp_Object object,
27408 ptrdiff_t startpos, ptrdiff_t endpos)
27410 int yb = window_text_bottom_y (w);
27411 struct glyph_row *r;
27412 struct glyph *g, *e;
27413 int gx;
27414 int found = 0;
27416 /* Find the glyph row with at least one position in the range
27417 [STARTPOS..ENDPOS], and the first glyph in that row whose
27418 position belongs to that range. */
27419 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
27420 r->enabled_p && r->y < yb;
27421 ++r)
27423 if (!r->reversed_p)
27425 g = r->glyphs[TEXT_AREA];
27426 e = g + r->used[TEXT_AREA];
27427 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
27428 if (EQ (g->object, object)
27429 && startpos <= g->charpos && g->charpos <= endpos)
27431 hlinfo->mouse_face_beg_row
27432 = MATRIX_ROW_VPOS (r, w->current_matrix);
27433 hlinfo->mouse_face_beg_y = r->y;
27434 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
27435 hlinfo->mouse_face_beg_x = gx;
27436 found = 1;
27437 break;
27440 else
27442 struct glyph *g1;
27444 e = r->glyphs[TEXT_AREA];
27445 g = e + r->used[TEXT_AREA];
27446 for ( ; g > e; --g)
27447 if (EQ ((g-1)->object, object)
27448 && startpos <= (g-1)->charpos && (g-1)->charpos <= endpos)
27450 hlinfo->mouse_face_beg_row
27451 = MATRIX_ROW_VPOS (r, w->current_matrix);
27452 hlinfo->mouse_face_beg_y = r->y;
27453 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
27454 for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
27455 gx += g1->pixel_width;
27456 hlinfo->mouse_face_beg_x = gx;
27457 found = 1;
27458 break;
27461 if (found)
27462 break;
27465 if (!found)
27466 return;
27468 /* Starting with the next row, look for the first row which does NOT
27469 include any glyphs whose positions are in the range. */
27470 for (++r; r->enabled_p && r->y < yb; ++r)
27472 g = r->glyphs[TEXT_AREA];
27473 e = g + r->used[TEXT_AREA];
27474 found = 0;
27475 for ( ; g < e; ++g)
27476 if (EQ (g->object, object)
27477 && startpos <= g->charpos && g->charpos <= endpos)
27479 found = 1;
27480 break;
27482 if (!found)
27483 break;
27486 /* The highlighted region ends on the previous row. */
27487 r--;
27489 /* Set the end row and its vertical pixel coordinate. */
27490 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r, w->current_matrix);
27491 hlinfo->mouse_face_end_y = r->y;
27493 /* Compute and set the end column and the end column's horizontal
27494 pixel coordinate. */
27495 if (!r->reversed_p)
27497 g = r->glyphs[TEXT_AREA];
27498 e = g + r->used[TEXT_AREA];
27499 for ( ; e > g; --e)
27500 if (EQ ((e-1)->object, object)
27501 && startpos <= (e-1)->charpos && (e-1)->charpos <= endpos)
27502 break;
27503 hlinfo->mouse_face_end_col = e - g;
27505 for (gx = r->x; g < e; ++g)
27506 gx += g->pixel_width;
27507 hlinfo->mouse_face_end_x = gx;
27509 else
27511 e = r->glyphs[TEXT_AREA];
27512 g = e + r->used[TEXT_AREA];
27513 for (gx = r->x ; e < g; ++e)
27515 if (EQ (e->object, object)
27516 && startpos <= e->charpos && e->charpos <= endpos)
27517 break;
27518 gx += e->pixel_width;
27520 hlinfo->mouse_face_end_col = e - r->glyphs[TEXT_AREA];
27521 hlinfo->mouse_face_end_x = gx;
27525 #ifdef HAVE_WINDOW_SYSTEM
27527 /* See if position X, Y is within a hot-spot of an image. */
27529 static int
27530 on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
27532 if (!CONSP (hot_spot))
27533 return 0;
27535 if (EQ (XCAR (hot_spot), Qrect))
27537 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
27538 Lisp_Object rect = XCDR (hot_spot);
27539 Lisp_Object tem;
27540 if (!CONSP (rect))
27541 return 0;
27542 if (!CONSP (XCAR (rect)))
27543 return 0;
27544 if (!CONSP (XCDR (rect)))
27545 return 0;
27546 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
27547 return 0;
27548 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
27549 return 0;
27550 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
27551 return 0;
27552 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
27553 return 0;
27554 return 1;
27556 else if (EQ (XCAR (hot_spot), Qcircle))
27558 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
27559 Lisp_Object circ = XCDR (hot_spot);
27560 Lisp_Object lr, lx0, ly0;
27561 if (CONSP (circ)
27562 && CONSP (XCAR (circ))
27563 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
27564 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
27565 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
27567 double r = XFLOATINT (lr);
27568 double dx = XINT (lx0) - x;
27569 double dy = XINT (ly0) - y;
27570 return (dx * dx + dy * dy <= r * r);
27573 else if (EQ (XCAR (hot_spot), Qpoly))
27575 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
27576 if (VECTORP (XCDR (hot_spot)))
27578 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
27579 Lisp_Object *poly = v->contents;
27580 ptrdiff_t n = v->header.size;
27581 ptrdiff_t i;
27582 int inside = 0;
27583 Lisp_Object lx, ly;
27584 int x0, y0;
27586 /* Need an even number of coordinates, and at least 3 edges. */
27587 if (n < 6 || n & 1)
27588 return 0;
27590 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
27591 If count is odd, we are inside polygon. Pixels on edges
27592 may or may not be included depending on actual geometry of the
27593 polygon. */
27594 if ((lx = poly[n-2], !INTEGERP (lx))
27595 || (ly = poly[n-1], !INTEGERP (lx)))
27596 return 0;
27597 x0 = XINT (lx), y0 = XINT (ly);
27598 for (i = 0; i < n; i += 2)
27600 int x1 = x0, y1 = y0;
27601 if ((lx = poly[i], !INTEGERP (lx))
27602 || (ly = poly[i+1], !INTEGERP (ly)))
27603 return 0;
27604 x0 = XINT (lx), y0 = XINT (ly);
27606 /* Does this segment cross the X line? */
27607 if (x0 >= x)
27609 if (x1 >= x)
27610 continue;
27612 else if (x1 < x)
27613 continue;
27614 if (y > y0 && y > y1)
27615 continue;
27616 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
27617 inside = !inside;
27619 return inside;
27622 return 0;
27625 Lisp_Object
27626 find_hot_spot (Lisp_Object map, int x, int y)
27628 while (CONSP (map))
27630 if (CONSP (XCAR (map))
27631 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
27632 return XCAR (map);
27633 map = XCDR (map);
27636 return Qnil;
27639 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
27640 3, 3, 0,
27641 doc: /* Lookup in image map MAP coordinates X and Y.
27642 An image map is an alist where each element has the format (AREA ID PLIST).
27643 An AREA is specified as either a rectangle, a circle, or a polygon:
27644 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
27645 pixel coordinates of the upper left and bottom right corners.
27646 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
27647 and the radius of the circle; r may be a float or integer.
27648 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
27649 vector describes one corner in the polygon.
27650 Returns the alist element for the first matching AREA in MAP. */)
27651 (Lisp_Object map, Lisp_Object x, Lisp_Object y)
27653 if (NILP (map))
27654 return Qnil;
27656 CHECK_NUMBER (x);
27657 CHECK_NUMBER (y);
27659 return find_hot_spot (map,
27660 clip_to_bounds (INT_MIN, XINT (x), INT_MAX),
27661 clip_to_bounds (INT_MIN, XINT (y), INT_MAX));
27665 /* Display frame CURSOR, optionally using shape defined by POINTER. */
27666 static void
27667 define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
27669 /* Do not change cursor shape while dragging mouse. */
27670 if (!NILP (do_mouse_tracking))
27671 return;
27673 if (!NILP (pointer))
27675 if (EQ (pointer, Qarrow))
27676 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27677 else if (EQ (pointer, Qhand))
27678 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
27679 else if (EQ (pointer, Qtext))
27680 cursor = FRAME_X_OUTPUT (f)->text_cursor;
27681 else if (EQ (pointer, intern ("hdrag")))
27682 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
27683 #ifdef HAVE_X_WINDOWS
27684 else if (EQ (pointer, intern ("vdrag")))
27685 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
27686 #endif
27687 else if (EQ (pointer, intern ("hourglass")))
27688 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
27689 else if (EQ (pointer, Qmodeline))
27690 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
27691 else
27692 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27695 if (cursor != No_Cursor)
27696 FRAME_RIF (f)->define_frame_cursor (f, cursor);
27699 #endif /* HAVE_WINDOW_SYSTEM */
27701 /* Take proper action when mouse has moved to the mode or header line
27702 or marginal area AREA of window W, x-position X and y-position Y.
27703 X is relative to the start of the text display area of W, so the
27704 width of bitmap areas and scroll bars must be subtracted to get a
27705 position relative to the start of the mode line. */
27707 static void
27708 note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
27709 enum window_part area)
27711 struct window *w = XWINDOW (window);
27712 struct frame *f = XFRAME (w->frame);
27713 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
27714 #ifdef HAVE_WINDOW_SYSTEM
27715 Display_Info *dpyinfo;
27716 #endif
27717 Cursor cursor = No_Cursor;
27718 Lisp_Object pointer = Qnil;
27719 int dx, dy, width, height;
27720 ptrdiff_t charpos;
27721 Lisp_Object string, object = Qnil;
27722 Lisp_Object pos IF_LINT (= Qnil), help;
27724 Lisp_Object mouse_face;
27725 int original_x_pixel = x;
27726 struct glyph * glyph = NULL, * row_start_glyph = NULL;
27727 struct glyph_row *row IF_LINT (= 0);
27729 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
27731 int x0;
27732 struct glyph *end;
27734 /* Kludge alert: mode_line_string takes X/Y in pixels, but
27735 returns them in row/column units! */
27736 string = mode_line_string (w, area, &x, &y, &charpos,
27737 &object, &dx, &dy, &width, &height);
27739 row = (area == ON_MODE_LINE
27740 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
27741 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
27743 /* Find the glyph under the mouse pointer. */
27744 if (row->mode_line_p && row->enabled_p)
27746 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
27747 end = glyph + row->used[TEXT_AREA];
27749 for (x0 = original_x_pixel;
27750 glyph < end && x0 >= glyph->pixel_width;
27751 ++glyph)
27752 x0 -= glyph->pixel_width;
27754 if (glyph >= end)
27755 glyph = NULL;
27758 else
27760 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
27761 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
27762 returns them in row/column units! */
27763 string = marginal_area_string (w, area, &x, &y, &charpos,
27764 &object, &dx, &dy, &width, &height);
27767 help = Qnil;
27769 #ifdef HAVE_WINDOW_SYSTEM
27770 if (IMAGEP (object))
27772 Lisp_Object image_map, hotspot;
27773 if ((image_map = Fplist_get (XCDR (object), QCmap),
27774 !NILP (image_map))
27775 && (hotspot = find_hot_spot (image_map, dx, dy),
27776 CONSP (hotspot))
27777 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
27779 Lisp_Object plist;
27781 /* Could check XCAR (hotspot) to see if we enter/leave this hot-spot.
27782 If so, we could look for mouse-enter, mouse-leave
27783 properties in PLIST (and do something...). */
27784 hotspot = XCDR (hotspot);
27785 if (CONSP (hotspot)
27786 && (plist = XCAR (hotspot), CONSP (plist)))
27788 pointer = Fplist_get (plist, Qpointer);
27789 if (NILP (pointer))
27790 pointer = Qhand;
27791 help = Fplist_get (plist, Qhelp_echo);
27792 if (!NILP (help))
27794 help_echo_string = help;
27795 XSETWINDOW (help_echo_window, w);
27796 help_echo_object = w->contents;
27797 help_echo_pos = charpos;
27801 if (NILP (pointer))
27802 pointer = Fplist_get (XCDR (object), QCpointer);
27804 #endif /* HAVE_WINDOW_SYSTEM */
27806 if (STRINGP (string))
27807 pos = make_number (charpos);
27809 /* Set the help text and mouse pointer. If the mouse is on a part
27810 of the mode line without any text (e.g. past the right edge of
27811 the mode line text), use the default help text and pointer. */
27812 if (STRINGP (string) || area == ON_MODE_LINE)
27814 /* Arrange to display the help by setting the global variables
27815 help_echo_string, help_echo_object, and help_echo_pos. */
27816 if (NILP (help))
27818 if (STRINGP (string))
27819 help = Fget_text_property (pos, Qhelp_echo, string);
27821 if (!NILP (help))
27823 help_echo_string = help;
27824 XSETWINDOW (help_echo_window, w);
27825 help_echo_object = string;
27826 help_echo_pos = charpos;
27828 else if (area == ON_MODE_LINE)
27830 Lisp_Object default_help
27831 = buffer_local_value_1 (Qmode_line_default_help_echo,
27832 w->contents);
27834 if (STRINGP (default_help))
27836 help_echo_string = default_help;
27837 XSETWINDOW (help_echo_window, w);
27838 help_echo_object = Qnil;
27839 help_echo_pos = -1;
27844 #ifdef HAVE_WINDOW_SYSTEM
27845 /* Change the mouse pointer according to what is under it. */
27846 if (FRAME_WINDOW_P (f))
27848 dpyinfo = FRAME_X_DISPLAY_INFO (f);
27849 if (STRINGP (string))
27851 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27853 if (NILP (pointer))
27854 pointer = Fget_text_property (pos, Qpointer, string);
27856 /* Change the mouse pointer according to what is under X/Y. */
27857 if (NILP (pointer)
27858 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
27860 Lisp_Object map;
27861 map = Fget_text_property (pos, Qlocal_map, string);
27862 if (!KEYMAPP (map))
27863 map = Fget_text_property (pos, Qkeymap, string);
27864 if (!KEYMAPP (map))
27865 cursor = dpyinfo->vertical_scroll_bar_cursor;
27868 else
27869 /* Default mode-line pointer. */
27870 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
27872 #endif
27875 /* Change the mouse face according to what is under X/Y. */
27876 if (STRINGP (string))
27878 mouse_face = Fget_text_property (pos, Qmouse_face, string);
27879 if (!NILP (Vmouse_highlight) && !NILP (mouse_face)
27880 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
27881 && glyph)
27883 Lisp_Object b, e;
27885 struct glyph * tmp_glyph;
27887 int gpos;
27888 int gseq_length;
27889 int total_pixel_width;
27890 ptrdiff_t begpos, endpos, ignore;
27892 int vpos, hpos;
27894 b = Fprevious_single_property_change (make_number (charpos + 1),
27895 Qmouse_face, string, Qnil);
27896 if (NILP (b))
27897 begpos = 0;
27898 else
27899 begpos = XINT (b);
27901 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
27902 if (NILP (e))
27903 endpos = SCHARS (string);
27904 else
27905 endpos = XINT (e);
27907 /* Calculate the glyph position GPOS of GLYPH in the
27908 displayed string, relative to the beginning of the
27909 highlighted part of the string.
27911 Note: GPOS is different from CHARPOS. CHARPOS is the
27912 position of GLYPH in the internal string object. A mode
27913 line string format has structures which are converted to
27914 a flattened string by the Emacs Lisp interpreter. The
27915 internal string is an element of those structures. The
27916 displayed string is the flattened string. */
27917 tmp_glyph = row_start_glyph;
27918 while (tmp_glyph < glyph
27919 && (!(EQ (tmp_glyph->object, glyph->object)
27920 && begpos <= tmp_glyph->charpos
27921 && tmp_glyph->charpos < endpos)))
27922 tmp_glyph++;
27923 gpos = glyph - tmp_glyph;
27925 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
27926 the highlighted part of the displayed string to which
27927 GLYPH belongs. Note: GSEQ_LENGTH is different from
27928 SCHARS (STRING), because the latter returns the length of
27929 the internal string. */
27930 for (tmp_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
27931 tmp_glyph > glyph
27932 && (!(EQ (tmp_glyph->object, glyph->object)
27933 && begpos <= tmp_glyph->charpos
27934 && tmp_glyph->charpos < endpos));
27935 tmp_glyph--)
27937 gseq_length = gpos + (tmp_glyph - glyph) + 1;
27939 /* Calculate the total pixel width of all the glyphs between
27940 the beginning of the highlighted area and GLYPH. */
27941 total_pixel_width = 0;
27942 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
27943 total_pixel_width += tmp_glyph->pixel_width;
27945 /* Pre calculation of re-rendering position. Note: X is in
27946 column units here, after the call to mode_line_string or
27947 marginal_area_string. */
27948 hpos = x - gpos;
27949 vpos = (area == ON_MODE_LINE
27950 ? (w->current_matrix)->nrows - 1
27951 : 0);
27953 /* If GLYPH's position is included in the region that is
27954 already drawn in mouse face, we have nothing to do. */
27955 if ( EQ (window, hlinfo->mouse_face_window)
27956 && (!row->reversed_p
27957 ? (hlinfo->mouse_face_beg_col <= hpos
27958 && hpos < hlinfo->mouse_face_end_col)
27959 /* In R2L rows we swap BEG and END, see below. */
27960 : (hlinfo->mouse_face_end_col <= hpos
27961 && hpos < hlinfo->mouse_face_beg_col))
27962 && hlinfo->mouse_face_beg_row == vpos )
27963 return;
27965 if (clear_mouse_face (hlinfo))
27966 cursor = No_Cursor;
27968 if (!row->reversed_p)
27970 hlinfo->mouse_face_beg_col = hpos;
27971 hlinfo->mouse_face_beg_x = original_x_pixel
27972 - (total_pixel_width + dx);
27973 hlinfo->mouse_face_end_col = hpos + gseq_length;
27974 hlinfo->mouse_face_end_x = 0;
27976 else
27978 /* In R2L rows, show_mouse_face expects BEG and END
27979 coordinates to be swapped. */
27980 hlinfo->mouse_face_end_col = hpos;
27981 hlinfo->mouse_face_end_x = original_x_pixel
27982 - (total_pixel_width + dx);
27983 hlinfo->mouse_face_beg_col = hpos + gseq_length;
27984 hlinfo->mouse_face_beg_x = 0;
27987 hlinfo->mouse_face_beg_row = vpos;
27988 hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row;
27989 hlinfo->mouse_face_beg_y = 0;
27990 hlinfo->mouse_face_end_y = 0;
27991 hlinfo->mouse_face_past_end = 0;
27992 hlinfo->mouse_face_window = window;
27994 hlinfo->mouse_face_face_id = face_at_string_position (w, string,
27995 charpos,
27996 0, 0, 0,
27997 &ignore,
27998 glyph->face_id,
28000 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
28002 if (NILP (pointer))
28003 pointer = Qhand;
28005 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
28006 clear_mouse_face (hlinfo);
28008 #ifdef HAVE_WINDOW_SYSTEM
28009 if (FRAME_WINDOW_P (f))
28010 define_frame_cursor1 (f, cursor, pointer);
28011 #endif
28015 /* EXPORT:
28016 Take proper action when the mouse has moved to position X, Y on
28017 frame F with regards to highlighting portions of display that have
28018 mouse-face properties. Also de-highlight portions of display where
28019 the mouse was before, set the mouse pointer shape as appropriate
28020 for the mouse coordinates, and activate help echo (tooltips).
28021 X and Y can be negative or out of range. */
28023 void
28024 note_mouse_highlight (struct frame *f, int x, int y)
28026 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
28027 enum window_part part = ON_NOTHING;
28028 Lisp_Object window;
28029 struct window *w;
28030 Cursor cursor = No_Cursor;
28031 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
28032 struct buffer *b;
28034 /* When a menu is active, don't highlight because this looks odd. */
28035 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
28036 if (popup_activated ())
28037 return;
28038 #endif
28040 if (!f->glyphs_initialized_p
28041 || f->pointer_invisible)
28042 return;
28044 hlinfo->mouse_face_mouse_x = x;
28045 hlinfo->mouse_face_mouse_y = y;
28046 hlinfo->mouse_face_mouse_frame = f;
28048 if (hlinfo->mouse_face_defer)
28049 return;
28051 /* Which window is that in? */
28052 window = window_from_coordinates (f, x, y, &part, 1);
28054 /* If displaying active text in another window, clear that. */
28055 if (! EQ (window, hlinfo->mouse_face_window)
28056 /* Also clear if we move out of text area in same window. */
28057 || (!NILP (hlinfo->mouse_face_window)
28058 && !NILP (window)
28059 && part != ON_TEXT
28060 && part != ON_MODE_LINE
28061 && part != ON_HEADER_LINE))
28062 clear_mouse_face (hlinfo);
28064 /* Not on a window -> return. */
28065 if (!WINDOWP (window))
28066 return;
28068 /* Reset help_echo_string. It will get recomputed below. */
28069 help_echo_string = Qnil;
28071 /* Convert to window-relative pixel coordinates. */
28072 w = XWINDOW (window);
28073 frame_to_window_pixel_xy (w, &x, &y);
28075 #ifdef HAVE_WINDOW_SYSTEM
28076 /* Handle tool-bar window differently since it doesn't display a
28077 buffer. */
28078 if (EQ (window, f->tool_bar_window))
28080 note_tool_bar_highlight (f, x, y);
28081 return;
28083 #endif
28085 /* Mouse is on the mode, header line or margin? */
28086 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
28087 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
28089 note_mode_line_or_margin_highlight (window, x, y, part);
28090 return;
28093 #ifdef HAVE_WINDOW_SYSTEM
28094 if (part == ON_VERTICAL_BORDER)
28096 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
28097 help_echo_string = build_string ("drag-mouse-1: resize");
28099 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
28100 || part == ON_SCROLL_BAR)
28101 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
28102 else
28103 cursor = FRAME_X_OUTPUT (f)->text_cursor;
28104 #endif
28106 /* Are we in a window whose display is up to date?
28107 And verify the buffer's text has not changed. */
28108 b = XBUFFER (w->contents);
28109 if (part == ON_TEXT && w->window_end_valid && !window_outdated (w))
28111 int hpos, vpos, dx, dy, area = LAST_AREA;
28112 ptrdiff_t pos;
28113 struct glyph *glyph;
28114 Lisp_Object object;
28115 Lisp_Object mouse_face = Qnil, position;
28116 Lisp_Object *overlay_vec = NULL;
28117 ptrdiff_t i, noverlays;
28118 struct buffer *obuf;
28119 ptrdiff_t obegv, ozv;
28120 int same_region;
28122 /* Find the glyph under X/Y. */
28123 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
28125 #ifdef HAVE_WINDOW_SYSTEM
28126 /* Look for :pointer property on image. */
28127 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
28129 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
28130 if (img != NULL && IMAGEP (img->spec))
28132 Lisp_Object image_map, hotspot;
28133 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
28134 !NILP (image_map))
28135 && (hotspot = find_hot_spot (image_map,
28136 glyph->slice.img.x + dx,
28137 glyph->slice.img.y + dy),
28138 CONSP (hotspot))
28139 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
28141 Lisp_Object plist;
28143 /* Could check XCAR (hotspot) to see if we enter/leave
28144 this hot-spot.
28145 If so, we could look for mouse-enter, mouse-leave
28146 properties in PLIST (and do something...). */
28147 hotspot = XCDR (hotspot);
28148 if (CONSP (hotspot)
28149 && (plist = XCAR (hotspot), CONSP (plist)))
28151 pointer = Fplist_get (plist, Qpointer);
28152 if (NILP (pointer))
28153 pointer = Qhand;
28154 help_echo_string = Fplist_get (plist, Qhelp_echo);
28155 if (!NILP (help_echo_string))
28157 help_echo_window = window;
28158 help_echo_object = glyph->object;
28159 help_echo_pos = glyph->charpos;
28163 if (NILP (pointer))
28164 pointer = Fplist_get (XCDR (img->spec), QCpointer);
28167 #endif /* HAVE_WINDOW_SYSTEM */
28169 /* Clear mouse face if X/Y not over text. */
28170 if (glyph == NULL
28171 || area != TEXT_AREA
28172 || !MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->current_matrix, vpos))
28173 /* Glyph's OBJECT is an integer for glyphs inserted by the
28174 display engine for its internal purposes, like truncation
28175 and continuation glyphs and blanks beyond the end of
28176 line's text on text terminals. If we are over such a
28177 glyph, we are not over any text. */
28178 || INTEGERP (glyph->object)
28179 /* R2L rows have a stretch glyph at their front, which
28180 stands for no text, whereas L2R rows have no glyphs at
28181 all beyond the end of text. Treat such stretch glyphs
28182 like we do with NULL glyphs in L2R rows. */
28183 || (MATRIX_ROW (w->current_matrix, vpos)->reversed_p
28184 && glyph == MATRIX_ROW_GLYPH_START (w->current_matrix, vpos)
28185 && glyph->type == STRETCH_GLYPH
28186 && glyph->avoid_cursor_p))
28188 if (clear_mouse_face (hlinfo))
28189 cursor = No_Cursor;
28190 #ifdef HAVE_WINDOW_SYSTEM
28191 if (FRAME_WINDOW_P (f) && NILP (pointer))
28193 if (area != TEXT_AREA)
28194 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
28195 else
28196 pointer = Vvoid_text_area_pointer;
28198 #endif
28199 goto set_cursor;
28202 pos = glyph->charpos;
28203 object = glyph->object;
28204 if (!STRINGP (object) && !BUFFERP (object))
28205 goto set_cursor;
28207 /* If we get an out-of-range value, return now; avoid an error. */
28208 if (BUFFERP (object) && pos > BUF_Z (b))
28209 goto set_cursor;
28211 /* Make the window's buffer temporarily current for
28212 overlays_at and compute_char_face. */
28213 obuf = current_buffer;
28214 current_buffer = b;
28215 obegv = BEGV;
28216 ozv = ZV;
28217 BEGV = BEG;
28218 ZV = Z;
28220 /* Is this char mouse-active or does it have help-echo? */
28221 position = make_number (pos);
28223 if (BUFFERP (object))
28225 /* Put all the overlays we want in a vector in overlay_vec. */
28226 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
28227 /* Sort overlays into increasing priority order. */
28228 noverlays = sort_overlays (overlay_vec, noverlays, w);
28230 else
28231 noverlays = 0;
28233 if (NILP (Vmouse_highlight))
28235 clear_mouse_face (hlinfo);
28236 goto check_help_echo;
28239 same_region = coords_in_mouse_face_p (w, hpos, vpos);
28241 if (same_region)
28242 cursor = No_Cursor;
28244 /* Check mouse-face highlighting. */
28245 if (! same_region
28246 /* If there exists an overlay with mouse-face overlapping
28247 the one we are currently highlighting, we have to
28248 check if we enter the overlapping overlay, and then
28249 highlight only that. */
28250 || (OVERLAYP (hlinfo->mouse_face_overlay)
28251 && mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
28253 /* Find the highest priority overlay with a mouse-face. */
28254 Lisp_Object overlay = Qnil;
28255 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
28257 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
28258 if (!NILP (mouse_face))
28259 overlay = overlay_vec[i];
28262 /* If we're highlighting the same overlay as before, there's
28263 no need to do that again. */
28264 if (!NILP (overlay) && EQ (overlay, hlinfo->mouse_face_overlay))
28265 goto check_help_echo;
28266 hlinfo->mouse_face_overlay = overlay;
28268 /* Clear the display of the old active region, if any. */
28269 if (clear_mouse_face (hlinfo))
28270 cursor = No_Cursor;
28272 /* If no overlay applies, get a text property. */
28273 if (NILP (overlay))
28274 mouse_face = Fget_text_property (position, Qmouse_face, object);
28276 /* Next, compute the bounds of the mouse highlighting and
28277 display it. */
28278 if (!NILP (mouse_face) && STRINGP (object))
28280 /* The mouse-highlighting comes from a display string
28281 with a mouse-face. */
28282 Lisp_Object s, e;
28283 ptrdiff_t ignore;
28285 s = Fprevious_single_property_change
28286 (make_number (pos + 1), Qmouse_face, object, Qnil);
28287 e = Fnext_single_property_change
28288 (position, Qmouse_face, object, Qnil);
28289 if (NILP (s))
28290 s = make_number (0);
28291 if (NILP (e))
28292 e = make_number (SCHARS (object) - 1);
28293 mouse_face_from_string_pos (w, hlinfo, object,
28294 XINT (s), XINT (e));
28295 hlinfo->mouse_face_past_end = 0;
28296 hlinfo->mouse_face_window = window;
28297 hlinfo->mouse_face_face_id
28298 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
28299 glyph->face_id, 1);
28300 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
28301 cursor = No_Cursor;
28303 else
28305 /* The mouse-highlighting, if any, comes from an overlay
28306 or text property in the buffer. */
28307 Lisp_Object buffer IF_LINT (= Qnil);
28308 Lisp_Object disp_string IF_LINT (= Qnil);
28310 if (STRINGP (object))
28312 /* If we are on a display string with no mouse-face,
28313 check if the text under it has one. */
28314 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
28315 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
28316 pos = string_buffer_position (object, start);
28317 if (pos > 0)
28319 mouse_face = get_char_property_and_overlay
28320 (make_number (pos), Qmouse_face, w->contents, &overlay);
28321 buffer = w->contents;
28322 disp_string = object;
28325 else
28327 buffer = object;
28328 disp_string = Qnil;
28331 if (!NILP (mouse_face))
28333 Lisp_Object before, after;
28334 Lisp_Object before_string, after_string;
28335 /* To correctly find the limits of mouse highlight
28336 in a bidi-reordered buffer, we must not use the
28337 optimization of limiting the search in
28338 previous-single-property-change and
28339 next-single-property-change, because
28340 rows_from_pos_range needs the real start and end
28341 positions to DTRT in this case. That's because
28342 the first row visible in a window does not
28343 necessarily display the character whose position
28344 is the smallest. */
28345 Lisp_Object lim1 =
28346 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
28347 ? Fmarker_position (w->start)
28348 : Qnil;
28349 Lisp_Object lim2 =
28350 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
28351 ? make_number (BUF_Z (XBUFFER (buffer))
28352 - XFASTINT (w->window_end_pos))
28353 : Qnil;
28355 if (NILP (overlay))
28357 /* Handle the text property case. */
28358 before = Fprevious_single_property_change
28359 (make_number (pos + 1), Qmouse_face, buffer, lim1);
28360 after = Fnext_single_property_change
28361 (make_number (pos), Qmouse_face, buffer, lim2);
28362 before_string = after_string = Qnil;
28364 else
28366 /* Handle the overlay case. */
28367 before = Foverlay_start (overlay);
28368 after = Foverlay_end (overlay);
28369 before_string = Foverlay_get (overlay, Qbefore_string);
28370 after_string = Foverlay_get (overlay, Qafter_string);
28372 if (!STRINGP (before_string)) before_string = Qnil;
28373 if (!STRINGP (after_string)) after_string = Qnil;
28376 mouse_face_from_buffer_pos (window, hlinfo, pos,
28377 NILP (before)
28379 : XFASTINT (before),
28380 NILP (after)
28381 ? BUF_Z (XBUFFER (buffer))
28382 : XFASTINT (after),
28383 before_string, after_string,
28384 disp_string);
28385 cursor = No_Cursor;
28390 check_help_echo:
28392 /* Look for a `help-echo' property. */
28393 if (NILP (help_echo_string)) {
28394 Lisp_Object help, overlay;
28396 /* Check overlays first. */
28397 help = overlay = Qnil;
28398 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
28400 overlay = overlay_vec[i];
28401 help = Foverlay_get (overlay, Qhelp_echo);
28404 if (!NILP (help))
28406 help_echo_string = help;
28407 help_echo_window = window;
28408 help_echo_object = overlay;
28409 help_echo_pos = pos;
28411 else
28413 Lisp_Object obj = glyph->object;
28414 ptrdiff_t charpos = glyph->charpos;
28416 /* Try text properties. */
28417 if (STRINGP (obj)
28418 && charpos >= 0
28419 && charpos < SCHARS (obj))
28421 help = Fget_text_property (make_number (charpos),
28422 Qhelp_echo, obj);
28423 if (NILP (help))
28425 /* If the string itself doesn't specify a help-echo,
28426 see if the buffer text ``under'' it does. */
28427 struct glyph_row *r
28428 = MATRIX_ROW (w->current_matrix, vpos);
28429 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
28430 ptrdiff_t p = string_buffer_position (obj, start);
28431 if (p > 0)
28433 help = Fget_char_property (make_number (p),
28434 Qhelp_echo, w->contents);
28435 if (!NILP (help))
28437 charpos = p;
28438 obj = w->contents;
28443 else if (BUFFERP (obj)
28444 && charpos >= BEGV
28445 && charpos < ZV)
28446 help = Fget_text_property (make_number (charpos), Qhelp_echo,
28447 obj);
28449 if (!NILP (help))
28451 help_echo_string = help;
28452 help_echo_window = window;
28453 help_echo_object = obj;
28454 help_echo_pos = charpos;
28459 #ifdef HAVE_WINDOW_SYSTEM
28460 /* Look for a `pointer' property. */
28461 if (FRAME_WINDOW_P (f) && NILP (pointer))
28463 /* Check overlays first. */
28464 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
28465 pointer = Foverlay_get (overlay_vec[i], Qpointer);
28467 if (NILP (pointer))
28469 Lisp_Object obj = glyph->object;
28470 ptrdiff_t charpos = glyph->charpos;
28472 /* Try text properties. */
28473 if (STRINGP (obj)
28474 && charpos >= 0
28475 && charpos < SCHARS (obj))
28477 pointer = Fget_text_property (make_number (charpos),
28478 Qpointer, obj);
28479 if (NILP (pointer))
28481 /* If the string itself doesn't specify a pointer,
28482 see if the buffer text ``under'' it does. */
28483 struct glyph_row *r
28484 = MATRIX_ROW (w->current_matrix, vpos);
28485 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
28486 ptrdiff_t p = string_buffer_position (obj, start);
28487 if (p > 0)
28488 pointer = Fget_char_property (make_number (p),
28489 Qpointer, w->contents);
28492 else if (BUFFERP (obj)
28493 && charpos >= BEGV
28494 && charpos < ZV)
28495 pointer = Fget_text_property (make_number (charpos),
28496 Qpointer, obj);
28499 #endif /* HAVE_WINDOW_SYSTEM */
28501 BEGV = obegv;
28502 ZV = ozv;
28503 current_buffer = obuf;
28506 set_cursor:
28508 #ifdef HAVE_WINDOW_SYSTEM
28509 if (FRAME_WINDOW_P (f))
28510 define_frame_cursor1 (f, cursor, pointer);
28511 #else
28512 /* This is here to prevent a compiler error, about "label at end of
28513 compound statement". */
28514 return;
28515 #endif
28519 /* EXPORT for RIF:
28520 Clear any mouse-face on window W. This function is part of the
28521 redisplay interface, and is called from try_window_id and similar
28522 functions to ensure the mouse-highlight is off. */
28524 void
28525 x_clear_window_mouse_face (struct window *w)
28527 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
28528 Lisp_Object window;
28530 block_input ();
28531 XSETWINDOW (window, w);
28532 if (EQ (window, hlinfo->mouse_face_window))
28533 clear_mouse_face (hlinfo);
28534 unblock_input ();
28538 /* EXPORT:
28539 Just discard the mouse face information for frame F, if any.
28540 This is used when the size of F is changed. */
28542 void
28543 cancel_mouse_face (struct frame *f)
28545 Lisp_Object window;
28546 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
28548 window = hlinfo->mouse_face_window;
28549 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
28551 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
28552 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
28553 hlinfo->mouse_face_window = Qnil;
28559 /***********************************************************************
28560 Exposure Events
28561 ***********************************************************************/
28563 #ifdef HAVE_WINDOW_SYSTEM
28565 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
28566 which intersects rectangle R. R is in window-relative coordinates. */
28568 static void
28569 expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
28570 enum glyph_row_area area)
28572 struct glyph *first = row->glyphs[area];
28573 struct glyph *end = row->glyphs[area] + row->used[area];
28574 struct glyph *last;
28575 int first_x, start_x, x;
28577 if (area == TEXT_AREA && row->fill_line_p)
28578 /* If row extends face to end of line write the whole line. */
28579 draw_glyphs (w, 0, row, area,
28580 0, row->used[area],
28581 DRAW_NORMAL_TEXT, 0);
28582 else
28584 /* Set START_X to the window-relative start position for drawing glyphs of
28585 AREA. The first glyph of the text area can be partially visible.
28586 The first glyphs of other areas cannot. */
28587 start_x = window_box_left_offset (w, area);
28588 x = start_x;
28589 if (area == TEXT_AREA)
28590 x += row->x;
28592 /* Find the first glyph that must be redrawn. */
28593 while (first < end
28594 && x + first->pixel_width < r->x)
28596 x += first->pixel_width;
28597 ++first;
28600 /* Find the last one. */
28601 last = first;
28602 first_x = x;
28603 while (last < end
28604 && x < r->x + r->width)
28606 x += last->pixel_width;
28607 ++last;
28610 /* Repaint. */
28611 if (last > first)
28612 draw_glyphs (w, first_x - start_x, row, area,
28613 first - row->glyphs[area], last - row->glyphs[area],
28614 DRAW_NORMAL_TEXT, 0);
28619 /* Redraw the parts of the glyph row ROW on window W intersecting
28620 rectangle R. R is in window-relative coordinates. Value is
28621 non-zero if mouse-face was overwritten. */
28623 static int
28624 expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
28626 eassert (row->enabled_p);
28628 if (row->mode_line_p || w->pseudo_window_p)
28629 draw_glyphs (w, 0, row, TEXT_AREA,
28630 0, row->used[TEXT_AREA],
28631 DRAW_NORMAL_TEXT, 0);
28632 else
28634 if (row->used[LEFT_MARGIN_AREA])
28635 expose_area (w, row, r, LEFT_MARGIN_AREA);
28636 if (row->used[TEXT_AREA])
28637 expose_area (w, row, r, TEXT_AREA);
28638 if (row->used[RIGHT_MARGIN_AREA])
28639 expose_area (w, row, r, RIGHT_MARGIN_AREA);
28640 draw_row_fringe_bitmaps (w, row);
28643 return row->mouse_face_p;
28647 /* Redraw those parts of glyphs rows during expose event handling that
28648 overlap other rows. Redrawing of an exposed line writes over parts
28649 of lines overlapping that exposed line; this function fixes that.
28651 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
28652 row in W's current matrix that is exposed and overlaps other rows.
28653 LAST_OVERLAPPING_ROW is the last such row. */
28655 static void
28656 expose_overlaps (struct window *w,
28657 struct glyph_row *first_overlapping_row,
28658 struct glyph_row *last_overlapping_row,
28659 XRectangle *r)
28661 struct glyph_row *row;
28663 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
28664 if (row->overlapping_p)
28666 eassert (row->enabled_p && !row->mode_line_p);
28668 row->clip = r;
28669 if (row->used[LEFT_MARGIN_AREA])
28670 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
28672 if (row->used[TEXT_AREA])
28673 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
28675 if (row->used[RIGHT_MARGIN_AREA])
28676 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
28677 row->clip = NULL;
28682 /* Return non-zero if W's cursor intersects rectangle R. */
28684 static int
28685 phys_cursor_in_rect_p (struct window *w, XRectangle *r)
28687 XRectangle cr, result;
28688 struct glyph *cursor_glyph;
28689 struct glyph_row *row;
28691 if (w->phys_cursor.vpos >= 0
28692 && w->phys_cursor.vpos < w->current_matrix->nrows
28693 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
28694 row->enabled_p)
28695 && row->cursor_in_fringe_p)
28697 /* Cursor is in the fringe. */
28698 cr.x = window_box_right_offset (w,
28699 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
28700 ? RIGHT_MARGIN_AREA
28701 : TEXT_AREA));
28702 cr.y = row->y;
28703 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
28704 cr.height = row->height;
28705 return x_intersect_rectangles (&cr, r, &result);
28708 cursor_glyph = get_phys_cursor_glyph (w);
28709 if (cursor_glyph)
28711 /* r is relative to W's box, but w->phys_cursor.x is relative
28712 to left edge of W's TEXT area. Adjust it. */
28713 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
28714 cr.y = w->phys_cursor.y;
28715 cr.width = cursor_glyph->pixel_width;
28716 cr.height = w->phys_cursor_height;
28717 /* ++KFS: W32 version used W32-specific IntersectRect here, but
28718 I assume the effect is the same -- and this is portable. */
28719 return x_intersect_rectangles (&cr, r, &result);
28721 /* If we don't understand the format, pretend we're not in the hot-spot. */
28722 return 0;
28726 /* EXPORT:
28727 Draw a vertical window border to the right of window W if W doesn't
28728 have vertical scroll bars. */
28730 void
28731 x_draw_vertical_border (struct window *w)
28733 struct frame *f = XFRAME (WINDOW_FRAME (w));
28735 /* We could do better, if we knew what type of scroll-bar the adjacent
28736 windows (on either side) have... But we don't :-(
28737 However, I think this works ok. ++KFS 2003-04-25 */
28739 /* Redraw borders between horizontally adjacent windows. Don't
28740 do it for frames with vertical scroll bars because either the
28741 right scroll bar of a window, or the left scroll bar of its
28742 neighbor will suffice as a border. */
28743 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
28744 return;
28746 /* Note: It is necessary to redraw both the left and the right
28747 borders, for when only this single window W is being
28748 redisplayed. */
28749 if (!WINDOW_RIGHTMOST_P (w)
28750 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
28752 int x0, x1, y0, y1;
28754 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
28755 y1 -= 1;
28757 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
28758 x1 -= 1;
28760 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
28762 if (!WINDOW_LEFTMOST_P (w)
28763 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
28765 int x0, x1, y0, y1;
28767 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
28768 y1 -= 1;
28770 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
28771 x0 -= 1;
28773 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
28778 /* Redraw the part of window W intersection rectangle FR. Pixel
28779 coordinates in FR are frame-relative. Call this function with
28780 input blocked. Value is non-zero if the exposure overwrites
28781 mouse-face. */
28783 static int
28784 expose_window (struct window *w, XRectangle *fr)
28786 struct frame *f = XFRAME (w->frame);
28787 XRectangle wr, r;
28788 int mouse_face_overwritten_p = 0;
28790 /* If window is not yet fully initialized, do nothing. This can
28791 happen when toolkit scroll bars are used and a window is split.
28792 Reconfiguring the scroll bar will generate an expose for a newly
28793 created window. */
28794 if (w->current_matrix == NULL)
28795 return 0;
28797 /* When we're currently updating the window, display and current
28798 matrix usually don't agree. Arrange for a thorough display
28799 later. */
28800 if (w->must_be_updated_p)
28802 SET_FRAME_GARBAGED (f);
28803 return 0;
28806 /* Frame-relative pixel rectangle of W. */
28807 wr.x = WINDOW_LEFT_EDGE_X (w);
28808 wr.y = WINDOW_TOP_EDGE_Y (w);
28809 wr.width = WINDOW_TOTAL_WIDTH (w);
28810 wr.height = WINDOW_TOTAL_HEIGHT (w);
28812 if (x_intersect_rectangles (fr, &wr, &r))
28814 int yb = window_text_bottom_y (w);
28815 struct glyph_row *row;
28816 int cursor_cleared_p, phys_cursor_on_p;
28817 struct glyph_row *first_overlapping_row, *last_overlapping_row;
28819 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
28820 r.x, r.y, r.width, r.height));
28822 /* Convert to window coordinates. */
28823 r.x -= WINDOW_LEFT_EDGE_X (w);
28824 r.y -= WINDOW_TOP_EDGE_Y (w);
28826 /* Turn off the cursor. */
28827 if (!w->pseudo_window_p
28828 && phys_cursor_in_rect_p (w, &r))
28830 x_clear_cursor (w);
28831 cursor_cleared_p = 1;
28833 else
28834 cursor_cleared_p = 0;
28836 /* If the row containing the cursor extends face to end of line,
28837 then expose_area might overwrite the cursor outside the
28838 rectangle and thus notice_overwritten_cursor might clear
28839 w->phys_cursor_on_p. We remember the original value and
28840 check later if it is changed. */
28841 phys_cursor_on_p = w->phys_cursor_on_p;
28843 /* Update lines intersecting rectangle R. */
28844 first_overlapping_row = last_overlapping_row = NULL;
28845 for (row = w->current_matrix->rows;
28846 row->enabled_p;
28847 ++row)
28849 int y0 = row->y;
28850 int y1 = MATRIX_ROW_BOTTOM_Y (row);
28852 if ((y0 >= r.y && y0 < r.y + r.height)
28853 || (y1 > r.y && y1 < r.y + r.height)
28854 || (r.y >= y0 && r.y < y1)
28855 || (r.y + r.height > y0 && r.y + r.height < y1))
28857 /* A header line may be overlapping, but there is no need
28858 to fix overlapping areas for them. KFS 2005-02-12 */
28859 if (row->overlapping_p && !row->mode_line_p)
28861 if (first_overlapping_row == NULL)
28862 first_overlapping_row = row;
28863 last_overlapping_row = row;
28866 row->clip = fr;
28867 if (expose_line (w, row, &r))
28868 mouse_face_overwritten_p = 1;
28869 row->clip = NULL;
28871 else if (row->overlapping_p)
28873 /* We must redraw a row overlapping the exposed area. */
28874 if (y0 < r.y
28875 ? y0 + row->phys_height > r.y
28876 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
28878 if (first_overlapping_row == NULL)
28879 first_overlapping_row = row;
28880 last_overlapping_row = row;
28884 if (y1 >= yb)
28885 break;
28888 /* Display the mode line if there is one. */
28889 if (WINDOW_WANTS_MODELINE_P (w)
28890 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
28891 row->enabled_p)
28892 && row->y < r.y + r.height)
28894 if (expose_line (w, row, &r))
28895 mouse_face_overwritten_p = 1;
28898 if (!w->pseudo_window_p)
28900 /* Fix the display of overlapping rows. */
28901 if (first_overlapping_row)
28902 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
28903 fr);
28905 /* Draw border between windows. */
28906 x_draw_vertical_border (w);
28908 /* Turn the cursor on again. */
28909 if (cursor_cleared_p
28910 || (phys_cursor_on_p && !w->phys_cursor_on_p))
28911 update_window_cursor (w, 1);
28915 return mouse_face_overwritten_p;
28920 /* Redraw (parts) of all windows in the window tree rooted at W that
28921 intersect R. R contains frame pixel coordinates. Value is
28922 non-zero if the exposure overwrites mouse-face. */
28924 static int
28925 expose_window_tree (struct window *w, XRectangle *r)
28927 struct frame *f = XFRAME (w->frame);
28928 int mouse_face_overwritten_p = 0;
28930 while (w && !FRAME_GARBAGED_P (f))
28932 if (WINDOWP (w->contents))
28933 mouse_face_overwritten_p
28934 |= expose_window_tree (XWINDOW (w->contents), r);
28935 else
28936 mouse_face_overwritten_p |= expose_window (w, r);
28938 w = NILP (w->next) ? NULL : XWINDOW (w->next);
28941 return mouse_face_overwritten_p;
28945 /* EXPORT:
28946 Redisplay an exposed area of frame F. X and Y are the upper-left
28947 corner of the exposed rectangle. W and H are width and height of
28948 the exposed area. All are pixel values. W or H zero means redraw
28949 the entire frame. */
28951 void
28952 expose_frame (struct frame *f, int x, int y, int w, int h)
28954 XRectangle r;
28955 int mouse_face_overwritten_p = 0;
28957 TRACE ((stderr, "expose_frame "));
28959 /* No need to redraw if frame will be redrawn soon. */
28960 if (FRAME_GARBAGED_P (f))
28962 TRACE ((stderr, " garbaged\n"));
28963 return;
28966 /* If basic faces haven't been realized yet, there is no point in
28967 trying to redraw anything. This can happen when we get an expose
28968 event while Emacs is starting, e.g. by moving another window. */
28969 if (FRAME_FACE_CACHE (f) == NULL
28970 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
28972 TRACE ((stderr, " no faces\n"));
28973 return;
28976 if (w == 0 || h == 0)
28978 r.x = r.y = 0;
28979 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
28980 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
28982 else
28984 r.x = x;
28985 r.y = y;
28986 r.width = w;
28987 r.height = h;
28990 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
28991 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
28993 if (WINDOWP (f->tool_bar_window))
28994 mouse_face_overwritten_p
28995 |= expose_window (XWINDOW (f->tool_bar_window), &r);
28997 #ifdef HAVE_X_WINDOWS
28998 #ifndef MSDOS
28999 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
29000 if (WINDOWP (f->menu_bar_window))
29001 mouse_face_overwritten_p
29002 |= expose_window (XWINDOW (f->menu_bar_window), &r);
29003 #endif /* not USE_X_TOOLKIT and not USE_GTK */
29004 #endif
29005 #endif
29007 /* Some window managers support a focus-follows-mouse style with
29008 delayed raising of frames. Imagine a partially obscured frame,
29009 and moving the mouse into partially obscured mouse-face on that
29010 frame. The visible part of the mouse-face will be highlighted,
29011 then the WM raises the obscured frame. With at least one WM, KDE
29012 2.1, Emacs is not getting any event for the raising of the frame
29013 (even tried with SubstructureRedirectMask), only Expose events.
29014 These expose events will draw text normally, i.e. not
29015 highlighted. Which means we must redo the highlight here.
29016 Subsume it under ``we love X''. --gerd 2001-08-15 */
29017 /* Included in Windows version because Windows most likely does not
29018 do the right thing if any third party tool offers
29019 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
29020 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
29022 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
29023 if (f == hlinfo->mouse_face_mouse_frame)
29025 int mouse_x = hlinfo->mouse_face_mouse_x;
29026 int mouse_y = hlinfo->mouse_face_mouse_y;
29027 clear_mouse_face (hlinfo);
29028 note_mouse_highlight (f, mouse_x, mouse_y);
29034 /* EXPORT:
29035 Determine the intersection of two rectangles R1 and R2. Return
29036 the intersection in *RESULT. Value is non-zero if RESULT is not
29037 empty. */
29040 x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
29042 XRectangle *left, *right;
29043 XRectangle *upper, *lower;
29044 int intersection_p = 0;
29046 /* Rearrange so that R1 is the left-most rectangle. */
29047 if (r1->x < r2->x)
29048 left = r1, right = r2;
29049 else
29050 left = r2, right = r1;
29052 /* X0 of the intersection is right.x0, if this is inside R1,
29053 otherwise there is no intersection. */
29054 if (right->x <= left->x + left->width)
29056 result->x = right->x;
29058 /* The right end of the intersection is the minimum of
29059 the right ends of left and right. */
29060 result->width = (min (left->x + left->width, right->x + right->width)
29061 - result->x);
29063 /* Same game for Y. */
29064 if (r1->y < r2->y)
29065 upper = r1, lower = r2;
29066 else
29067 upper = r2, lower = r1;
29069 /* The upper end of the intersection is lower.y0, if this is inside
29070 of upper. Otherwise, there is no intersection. */
29071 if (lower->y <= upper->y + upper->height)
29073 result->y = lower->y;
29075 /* The lower end of the intersection is the minimum of the lower
29076 ends of upper and lower. */
29077 result->height = (min (lower->y + lower->height,
29078 upper->y + upper->height)
29079 - result->y);
29080 intersection_p = 1;
29084 return intersection_p;
29087 #endif /* HAVE_WINDOW_SYSTEM */
29090 /***********************************************************************
29091 Initialization
29092 ***********************************************************************/
29094 void
29095 syms_of_xdisp (void)
29097 Vwith_echo_area_save_vector = Qnil;
29098 staticpro (&Vwith_echo_area_save_vector);
29100 Vmessage_stack = Qnil;
29101 staticpro (&Vmessage_stack);
29103 DEFSYM (Qinhibit_redisplay, "inhibit-redisplay");
29104 DEFSYM (Qredisplay_internal, "redisplay_internal (C function)");
29106 message_dolog_marker1 = Fmake_marker ();
29107 staticpro (&message_dolog_marker1);
29108 message_dolog_marker2 = Fmake_marker ();
29109 staticpro (&message_dolog_marker2);
29110 message_dolog_marker3 = Fmake_marker ();
29111 staticpro (&message_dolog_marker3);
29113 #ifdef GLYPH_DEBUG
29114 defsubr (&Sdump_frame_glyph_matrix);
29115 defsubr (&Sdump_glyph_matrix);
29116 defsubr (&Sdump_glyph_row);
29117 defsubr (&Sdump_tool_bar_row);
29118 defsubr (&Strace_redisplay);
29119 defsubr (&Strace_to_stderr);
29120 #endif
29121 #ifdef HAVE_WINDOW_SYSTEM
29122 defsubr (&Stool_bar_lines_needed);
29123 defsubr (&Slookup_image_map);
29124 #endif
29125 defsubr (&Sline_pixel_height);
29126 defsubr (&Sformat_mode_line);
29127 defsubr (&Sinvisible_p);
29128 defsubr (&Scurrent_bidi_paragraph_direction);
29129 defsubr (&Smove_point_visually);
29131 DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook");
29132 DEFSYM (Qoverriding_terminal_local_map, "overriding-terminal-local-map");
29133 DEFSYM (Qoverriding_local_map, "overriding-local-map");
29134 DEFSYM (Qwindow_scroll_functions, "window-scroll-functions");
29135 DEFSYM (Qwindow_text_change_functions, "window-text-change-functions");
29136 DEFSYM (Qredisplay_end_trigger_functions, "redisplay-end-trigger-functions");
29137 DEFSYM (Qinhibit_point_motion_hooks, "inhibit-point-motion-hooks");
29138 DEFSYM (Qeval, "eval");
29139 DEFSYM (QCdata, ":data");
29140 DEFSYM (Qdisplay, "display");
29141 DEFSYM (Qspace_width, "space-width");
29142 DEFSYM (Qraise, "raise");
29143 DEFSYM (Qslice, "slice");
29144 DEFSYM (Qspace, "space");
29145 DEFSYM (Qmargin, "margin");
29146 DEFSYM (Qpointer, "pointer");
29147 DEFSYM (Qleft_margin, "left-margin");
29148 DEFSYM (Qright_margin, "right-margin");
29149 DEFSYM (Qcenter, "center");
29150 DEFSYM (Qline_height, "line-height");
29151 DEFSYM (QCalign_to, ":align-to");
29152 DEFSYM (QCrelative_width, ":relative-width");
29153 DEFSYM (QCrelative_height, ":relative-height");
29154 DEFSYM (QCeval, ":eval");
29155 DEFSYM (QCpropertize, ":propertize");
29156 DEFSYM (QCfile, ":file");
29157 DEFSYM (Qfontified, "fontified");
29158 DEFSYM (Qfontification_functions, "fontification-functions");
29159 DEFSYM (Qtrailing_whitespace, "trailing-whitespace");
29160 DEFSYM (Qescape_glyph, "escape-glyph");
29161 DEFSYM (Qnobreak_space, "nobreak-space");
29162 DEFSYM (Qimage, "image");
29163 DEFSYM (Qtext, "text");
29164 DEFSYM (Qboth, "both");
29165 DEFSYM (Qboth_horiz, "both-horiz");
29166 DEFSYM (Qtext_image_horiz, "text-image-horiz");
29167 DEFSYM (QCmap, ":map");
29168 DEFSYM (QCpointer, ":pointer");
29169 DEFSYM (Qrect, "rect");
29170 DEFSYM (Qcircle, "circle");
29171 DEFSYM (Qpoly, "poly");
29172 DEFSYM (Qmessage_truncate_lines, "message-truncate-lines");
29173 DEFSYM (Qgrow_only, "grow-only");
29174 DEFSYM (Qinhibit_menubar_update, "inhibit-menubar-update");
29175 DEFSYM (Qinhibit_eval_during_redisplay, "inhibit-eval-during-redisplay");
29176 DEFSYM (Qposition, "position");
29177 DEFSYM (Qbuffer_position, "buffer-position");
29178 DEFSYM (Qobject, "object");
29179 DEFSYM (Qbar, "bar");
29180 DEFSYM (Qhbar, "hbar");
29181 DEFSYM (Qbox, "box");
29182 DEFSYM (Qhollow, "hollow");
29183 DEFSYM (Qhand, "hand");
29184 DEFSYM (Qarrow, "arrow");
29185 DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces");
29187 list_of_error = list1 (list2 (intern_c_string ("error"),
29188 intern_c_string ("void-variable")));
29189 staticpro (&list_of_error);
29191 DEFSYM (Qlast_arrow_position, "last-arrow-position");
29192 DEFSYM (Qlast_arrow_string, "last-arrow-string");
29193 DEFSYM (Qoverlay_arrow_string, "overlay-arrow-string");
29194 DEFSYM (Qoverlay_arrow_bitmap, "overlay-arrow-bitmap");
29196 echo_buffer[0] = echo_buffer[1] = Qnil;
29197 staticpro (&echo_buffer[0]);
29198 staticpro (&echo_buffer[1]);
29200 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
29201 staticpro (&echo_area_buffer[0]);
29202 staticpro (&echo_area_buffer[1]);
29204 Vmessages_buffer_name = build_pure_c_string ("*Messages*");
29205 staticpro (&Vmessages_buffer_name);
29207 mode_line_proptrans_alist = Qnil;
29208 staticpro (&mode_line_proptrans_alist);
29209 mode_line_string_list = Qnil;
29210 staticpro (&mode_line_string_list);
29211 mode_line_string_face = Qnil;
29212 staticpro (&mode_line_string_face);
29213 mode_line_string_face_prop = Qnil;
29214 staticpro (&mode_line_string_face_prop);
29215 Vmode_line_unwind_vector = Qnil;
29216 staticpro (&Vmode_line_unwind_vector);
29218 DEFSYM (Qmode_line_default_help_echo, "mode-line-default-help-echo");
29220 help_echo_string = Qnil;
29221 staticpro (&help_echo_string);
29222 help_echo_object = Qnil;
29223 staticpro (&help_echo_object);
29224 help_echo_window = Qnil;
29225 staticpro (&help_echo_window);
29226 previous_help_echo_string = Qnil;
29227 staticpro (&previous_help_echo_string);
29228 help_echo_pos = -1;
29230 DEFSYM (Qright_to_left, "right-to-left");
29231 DEFSYM (Qleft_to_right, "left-to-right");
29233 #ifdef HAVE_WINDOW_SYSTEM
29234 DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p,
29235 doc: /* Non-nil means draw block cursor as wide as the glyph under it.
29236 For example, if a block cursor is over a tab, it will be drawn as
29237 wide as that tab on the display. */);
29238 x_stretch_cursor_p = 0;
29239 #endif
29241 DEFVAR_LISP ("show-trailing-whitespace", Vshow_trailing_whitespace,
29242 doc: /* Non-nil means highlight trailing whitespace.
29243 The face used for trailing whitespace is `trailing-whitespace'. */);
29244 Vshow_trailing_whitespace = Qnil;
29246 DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display,
29247 doc: /* Control highlighting of non-ASCII space and hyphen chars.
29248 If the value is t, Emacs highlights non-ASCII chars which have the
29249 same appearance as an ASCII space or hyphen, using the `nobreak-space'
29250 or `escape-glyph' face respectively.
29252 U+00A0 (no-break space), U+00AD (soft hyphen), U+2010 (hyphen), and
29253 U+2011 (non-breaking hyphen) are affected.
29255 Any other non-nil value means to display these characters as a escape
29256 glyph followed by an ordinary space or hyphen.
29258 A value of nil means no special handling of these characters. */);
29259 Vnobreak_char_display = Qt;
29261 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer,
29262 doc: /* The pointer shape to show in void text areas.
29263 A value of nil means to show the text pointer. Other options are `arrow',
29264 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
29265 Vvoid_text_area_pointer = Qarrow;
29267 DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay,
29268 doc: /* Non-nil means don't actually do any redisplay.
29269 This is used for internal purposes. */);
29270 Vinhibit_redisplay = Qnil;
29272 DEFVAR_LISP ("global-mode-string", Vglobal_mode_string,
29273 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
29274 Vglobal_mode_string = Qnil;
29276 DEFVAR_LISP ("overlay-arrow-position", Voverlay_arrow_position,
29277 doc: /* Marker for where to display an arrow on top of the buffer text.
29278 This must be the beginning of a line in order to work.
29279 See also `overlay-arrow-string'. */);
29280 Voverlay_arrow_position = Qnil;
29282 DEFVAR_LISP ("overlay-arrow-string", Voverlay_arrow_string,
29283 doc: /* String to display as an arrow in non-window frames.
29284 See also `overlay-arrow-position'. */);
29285 Voverlay_arrow_string = build_pure_c_string ("=>");
29287 DEFVAR_LISP ("overlay-arrow-variable-list", Voverlay_arrow_variable_list,
29288 doc: /* List of variables (symbols) which hold markers for overlay arrows.
29289 The symbols on this list are examined during redisplay to determine
29290 where to display overlay arrows. */);
29291 Voverlay_arrow_variable_list
29292 = list1 (intern_c_string ("overlay-arrow-position"));
29294 DEFVAR_INT ("scroll-step", emacs_scroll_step,
29295 doc: /* The number of lines to try scrolling a window by when point moves out.
29296 If that fails to bring point back on frame, point is centered instead.
29297 If this is zero, point is always centered after it moves off frame.
29298 If you want scrolling to always be a line at a time, you should set
29299 `scroll-conservatively' to a large value rather than set this to 1. */);
29301 DEFVAR_INT ("scroll-conservatively", scroll_conservatively,
29302 doc: /* Scroll up to this many lines, to bring point back on screen.
29303 If point moves off-screen, redisplay will scroll by up to
29304 `scroll-conservatively' lines in order to bring point just barely
29305 onto the screen again. If that cannot be done, then redisplay
29306 recenters point as usual.
29308 If the value is greater than 100, redisplay will never recenter point,
29309 but will always scroll just enough text to bring point into view, even
29310 if you move far away.
29312 A value of zero means always recenter point if it moves off screen. */);
29313 scroll_conservatively = 0;
29315 DEFVAR_INT ("scroll-margin", scroll_margin,
29316 doc: /* Number of lines of margin at the top and bottom of a window.
29317 Recenter the window whenever point gets within this many lines
29318 of the top or bottom of the window. */);
29319 scroll_margin = 0;
29321 DEFVAR_LISP ("display-pixels-per-inch", Vdisplay_pixels_per_inch,
29322 doc: /* Pixels per inch value for non-window system displays.
29323 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
29324 Vdisplay_pixels_per_inch = make_float (72.0);
29326 #ifdef GLYPH_DEBUG
29327 DEFVAR_INT ("debug-end-pos", debug_end_pos, doc: /* Don't ask. */);
29328 #endif
29330 DEFVAR_LISP ("truncate-partial-width-windows",
29331 Vtruncate_partial_width_windows,
29332 doc: /* Non-nil means truncate lines in windows narrower than the frame.
29333 For an integer value, truncate lines in each window narrower than the
29334 full frame width, provided the window width is less than that integer;
29335 otherwise, respect the value of `truncate-lines'.
29337 For any other non-nil value, truncate lines in all windows that do
29338 not span the full frame width.
29340 A value of nil means to respect the value of `truncate-lines'.
29342 If `word-wrap' is enabled, you might want to reduce this. */);
29343 Vtruncate_partial_width_windows = make_number (50);
29345 DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit,
29346 doc: /* Maximum buffer size for which line number should be displayed.
29347 If the buffer is bigger than this, the line number does not appear
29348 in the mode line. A value of nil means no limit. */);
29349 Vline_number_display_limit = Qnil;
29351 DEFVAR_INT ("line-number-display-limit-width",
29352 line_number_display_limit_width,
29353 doc: /* Maximum line width (in characters) for line number display.
29354 If the average length of the lines near point is bigger than this, then the
29355 line number may be omitted from the mode line. */);
29356 line_number_display_limit_width = 200;
29358 DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows,
29359 doc: /* Non-nil means highlight region even in nonselected windows. */);
29360 highlight_nonselected_windows = 0;
29362 DEFVAR_BOOL ("multiple-frames", multiple_frames,
29363 doc: /* Non-nil if more than one frame is visible on this display.
29364 Minibuffer-only frames don't count, but iconified frames do.
29365 This variable is not guaranteed to be accurate except while processing
29366 `frame-title-format' and `icon-title-format'. */);
29368 DEFVAR_LISP ("frame-title-format", Vframe_title_format,
29369 doc: /* Template for displaying the title bar of visible frames.
29370 \(Assuming the window manager supports this feature.)
29372 This variable has the same structure as `mode-line-format', except that
29373 the %c and %l constructs are ignored. It is used only on frames for
29374 which no explicit name has been set \(see `modify-frame-parameters'). */);
29376 DEFVAR_LISP ("icon-title-format", Vicon_title_format,
29377 doc: /* Template for displaying the title bar of an iconified frame.
29378 \(Assuming the window manager supports this feature.)
29379 This variable has the same structure as `mode-line-format' (which see),
29380 and is used only on frames for which no explicit name has been set
29381 \(see `modify-frame-parameters'). */);
29382 Vicon_title_format
29383 = Vframe_title_format
29384 = listn (CONSTYPE_PURE, 3,
29385 intern_c_string ("multiple-frames"),
29386 build_pure_c_string ("%b"),
29387 listn (CONSTYPE_PURE, 4,
29388 empty_unibyte_string,
29389 intern_c_string ("invocation-name"),
29390 build_pure_c_string ("@"),
29391 intern_c_string ("system-name")));
29393 DEFVAR_LISP ("message-log-max", Vmessage_log_max,
29394 doc: /* Maximum number of lines to keep in the message log buffer.
29395 If nil, disable message logging. If t, log messages but don't truncate
29396 the buffer when it becomes large. */);
29397 Vmessage_log_max = make_number (1000);
29399 DEFVAR_LISP ("window-size-change-functions", Vwindow_size_change_functions,
29400 doc: /* Functions called before redisplay, if window sizes have changed.
29401 The value should be a list of functions that take one argument.
29402 Just before redisplay, for each frame, if any of its windows have changed
29403 size since the last redisplay, or have been split or deleted,
29404 all the functions in the list are called, with the frame as argument. */);
29405 Vwindow_size_change_functions = Qnil;
29407 DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions,
29408 doc: /* List of functions to call before redisplaying a window with scrolling.
29409 Each function is called with two arguments, the window and its new
29410 display-start position. Note that these functions are also called by
29411 `set-window-buffer'. Also note that the value of `window-end' is not
29412 valid when these functions are called.
29414 Warning: Do not use this feature to alter the way the window
29415 is scrolled. It is not designed for that, and such use probably won't
29416 work. */);
29417 Vwindow_scroll_functions = Qnil;
29419 DEFVAR_LISP ("window-text-change-functions",
29420 Vwindow_text_change_functions,
29421 doc: /* Functions to call in redisplay when text in the window might change. */);
29422 Vwindow_text_change_functions = Qnil;
29424 DEFVAR_LISP ("redisplay-end-trigger-functions", Vredisplay_end_trigger_functions,
29425 doc: /* Functions called when redisplay of a window reaches the end trigger.
29426 Each function is called with two arguments, the window and the end trigger value.
29427 See `set-window-redisplay-end-trigger'. */);
29428 Vredisplay_end_trigger_functions = Qnil;
29430 DEFVAR_LISP ("mouse-autoselect-window", Vmouse_autoselect_window,
29431 doc: /* Non-nil means autoselect window with mouse pointer.
29432 If nil, do not autoselect windows.
29433 A positive number means delay autoselection by that many seconds: a
29434 window is autoselected only after the mouse has remained in that
29435 window for the duration of the delay.
29436 A negative number has a similar effect, but causes windows to be
29437 autoselected only after the mouse has stopped moving. \(Because of
29438 the way Emacs compares mouse events, you will occasionally wait twice
29439 that time before the window gets selected.\)
29440 Any other value means to autoselect window instantaneously when the
29441 mouse pointer enters it.
29443 Autoselection selects the minibuffer only if it is active, and never
29444 unselects the minibuffer if it is active.
29446 When customizing this variable make sure that the actual value of
29447 `focus-follows-mouse' matches the behavior of your window manager. */);
29448 Vmouse_autoselect_window = Qnil;
29450 DEFVAR_LISP ("auto-resize-tool-bars", Vauto_resize_tool_bars,
29451 doc: /* Non-nil means automatically resize tool-bars.
29452 This dynamically changes the tool-bar's height to the minimum height
29453 that is needed to make all tool-bar items visible.
29454 If value is `grow-only', the tool-bar's height is only increased
29455 automatically; to decrease the tool-bar height, use \\[recenter]. */);
29456 Vauto_resize_tool_bars = Qt;
29458 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p,
29459 doc: /* Non-nil means raise tool-bar buttons when the mouse moves over them. */);
29460 auto_raise_tool_bar_buttons_p = 1;
29462 DEFVAR_BOOL ("make-cursor-line-fully-visible", make_cursor_line_fully_visible_p,
29463 doc: /* Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
29464 make_cursor_line_fully_visible_p = 1;
29466 DEFVAR_LISP ("tool-bar-border", Vtool_bar_border,
29467 doc: /* Border below tool-bar in pixels.
29468 If an integer, use it as the height of the border.
29469 If it is one of `internal-border-width' or `border-width', use the
29470 value of the corresponding frame parameter.
29471 Otherwise, no border is added below the tool-bar. */);
29472 Vtool_bar_border = Qinternal_border_width;
29474 DEFVAR_LISP ("tool-bar-button-margin", Vtool_bar_button_margin,
29475 doc: /* Margin around tool-bar buttons in pixels.
29476 If an integer, use that for both horizontal and vertical margins.
29477 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
29478 HORZ specifying the horizontal margin, and VERT specifying the
29479 vertical margin. */);
29480 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
29482 DEFVAR_INT ("tool-bar-button-relief", tool_bar_button_relief,
29483 doc: /* Relief thickness of tool-bar buttons. */);
29484 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
29486 DEFVAR_LISP ("tool-bar-style", Vtool_bar_style,
29487 doc: /* Tool bar style to use.
29488 It can be one of
29489 image - show images only
29490 text - show text only
29491 both - show both, text below image
29492 both-horiz - show text to the right of the image
29493 text-image-horiz - show text to the left of the image
29494 any other - use system default or image if no system default.
29496 This variable only affects the GTK+ toolkit version of Emacs. */);
29497 Vtool_bar_style = Qnil;
29499 DEFVAR_INT ("tool-bar-max-label-size", tool_bar_max_label_size,
29500 doc: /* Maximum number of characters a label can have to be shown.
29501 The tool bar style must also show labels for this to have any effect, see
29502 `tool-bar-style'. */);
29503 tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
29505 DEFVAR_LISP ("fontification-functions", Vfontification_functions,
29506 doc: /* List of functions to call to fontify regions of text.
29507 Each function is called with one argument POS. Functions must
29508 fontify a region starting at POS in the current buffer, and give
29509 fontified regions the property `fontified'. */);
29510 Vfontification_functions = Qnil;
29511 Fmake_variable_buffer_local (Qfontification_functions);
29513 DEFVAR_BOOL ("unibyte-display-via-language-environment",
29514 unibyte_display_via_language_environment,
29515 doc: /* Non-nil means display unibyte text according to language environment.
29516 Specifically, this means that raw bytes in the range 160-255 decimal
29517 are displayed by converting them to the equivalent multibyte characters
29518 according to the current language environment. As a result, they are
29519 displayed according to the current fontset.
29521 Note that this variable affects only how these bytes are displayed,
29522 but does not change the fact they are interpreted as raw bytes. */);
29523 unibyte_display_via_language_environment = 0;
29525 DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height,
29526 doc: /* Maximum height for resizing mini-windows (the minibuffer and the echo area).
29527 If a float, it specifies a fraction of the mini-window frame's height.
29528 If an integer, it specifies a number of lines. */);
29529 Vmax_mini_window_height = make_float (0.25);
29531 DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows,
29532 doc: /* How to resize mini-windows (the minibuffer and the echo area).
29533 A value of nil means don't automatically resize mini-windows.
29534 A value of t means resize them to fit the text displayed in them.
29535 A value of `grow-only', the default, means let mini-windows grow only;
29536 they return to their normal size when the minibuffer is closed, or the
29537 echo area becomes empty. */);
29538 Vresize_mini_windows = Qgrow_only;
29540 DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist,
29541 doc: /* Alist specifying how to blink the cursor off.
29542 Each element has the form (ON-STATE . OFF-STATE). Whenever the
29543 `cursor-type' frame-parameter or variable equals ON-STATE,
29544 comparing using `equal', Emacs uses OFF-STATE to specify
29545 how to blink it off. ON-STATE and OFF-STATE are values for
29546 the `cursor-type' frame parameter.
29548 If a frame's ON-STATE has no entry in this list,
29549 the frame's other specifications determine how to blink the cursor off. */);
29550 Vblink_cursor_alist = Qnil;
29552 DEFVAR_BOOL ("auto-hscroll-mode", automatic_hscrolling_p,
29553 doc: /* Allow or disallow automatic horizontal scrolling of windows.
29554 If non-nil, windows are automatically scrolled horizontally to make
29555 point visible. */);
29556 automatic_hscrolling_p = 1;
29557 DEFSYM (Qauto_hscroll_mode, "auto-hscroll-mode");
29559 DEFVAR_INT ("hscroll-margin", hscroll_margin,
29560 doc: /* How many columns away from the window edge point is allowed to get
29561 before automatic hscrolling will horizontally scroll the window. */);
29562 hscroll_margin = 5;
29564 DEFVAR_LISP ("hscroll-step", Vhscroll_step,
29565 doc: /* How many columns to scroll the window when point gets too close to the edge.
29566 When point is less than `hscroll-margin' columns from the window
29567 edge, automatic hscrolling will scroll the window by the amount of columns
29568 determined by this variable. If its value is a positive integer, scroll that
29569 many columns. If it's a positive floating-point number, it specifies the
29570 fraction of the window's width to scroll. If it's nil or zero, point will be
29571 centered horizontally after the scroll. Any other value, including negative
29572 numbers, are treated as if the value were zero.
29574 Automatic hscrolling always moves point outside the scroll margin, so if
29575 point was more than scroll step columns inside the margin, the window will
29576 scroll more than the value given by the scroll step.
29578 Note that the lower bound for automatic hscrolling specified by `scroll-left'
29579 and `scroll-right' overrides this variable's effect. */);
29580 Vhscroll_step = make_number (0);
29582 DEFVAR_BOOL ("message-truncate-lines", message_truncate_lines,
29583 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
29584 Bind this around calls to `message' to let it take effect. */);
29585 message_truncate_lines = 0;
29587 DEFVAR_LISP ("menu-bar-update-hook", Vmenu_bar_update_hook,
29588 doc: /* Normal hook run to update the menu bar definitions.
29589 Redisplay runs this hook before it redisplays the menu bar.
29590 This is used to update submenus such as Buffers,
29591 whose contents depend on various data. */);
29592 Vmenu_bar_update_hook = Qnil;
29594 DEFVAR_LISP ("menu-updating-frame", Vmenu_updating_frame,
29595 doc: /* Frame for which we are updating a menu.
29596 The enable predicate for a menu binding should check this variable. */);
29597 Vmenu_updating_frame = Qnil;
29599 DEFVAR_BOOL ("inhibit-menubar-update", inhibit_menubar_update,
29600 doc: /* Non-nil means don't update menu bars. Internal use only. */);
29601 inhibit_menubar_update = 0;
29603 DEFVAR_LISP ("wrap-prefix", Vwrap_prefix,
29604 doc: /* Prefix prepended to all continuation lines at display time.
29605 The value may be a string, an image, or a stretch-glyph; it is
29606 interpreted in the same way as the value of a `display' text property.
29608 This variable is overridden by any `wrap-prefix' text or overlay
29609 property.
29611 To add a prefix to non-continuation lines, use `line-prefix'. */);
29612 Vwrap_prefix = Qnil;
29613 DEFSYM (Qwrap_prefix, "wrap-prefix");
29614 Fmake_variable_buffer_local (Qwrap_prefix);
29616 DEFVAR_LISP ("line-prefix", Vline_prefix,
29617 doc: /* Prefix prepended to all non-continuation lines at display time.
29618 The value may be a string, an image, or a stretch-glyph; it is
29619 interpreted in the same way as the value of a `display' text property.
29621 This variable is overridden by any `line-prefix' text or overlay
29622 property.
29624 To add a prefix to continuation lines, use `wrap-prefix'. */);
29625 Vline_prefix = Qnil;
29626 DEFSYM (Qline_prefix, "line-prefix");
29627 Fmake_variable_buffer_local (Qline_prefix);
29629 DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay,
29630 doc: /* Non-nil means don't eval Lisp during redisplay. */);
29631 inhibit_eval_during_redisplay = 0;
29633 DEFVAR_BOOL ("inhibit-free-realized-faces", inhibit_free_realized_faces,
29634 doc: /* Non-nil means don't free realized faces. Internal use only. */);
29635 inhibit_free_realized_faces = 0;
29637 #ifdef GLYPH_DEBUG
29638 DEFVAR_BOOL ("inhibit-try-window-id", inhibit_try_window_id,
29639 doc: /* Inhibit try_window_id display optimization. */);
29640 inhibit_try_window_id = 0;
29642 DEFVAR_BOOL ("inhibit-try-window-reusing", inhibit_try_window_reusing,
29643 doc: /* Inhibit try_window_reusing display optimization. */);
29644 inhibit_try_window_reusing = 0;
29646 DEFVAR_BOOL ("inhibit-try-cursor-movement", inhibit_try_cursor_movement,
29647 doc: /* Inhibit try_cursor_movement display optimization. */);
29648 inhibit_try_cursor_movement = 0;
29649 #endif /* GLYPH_DEBUG */
29651 DEFVAR_INT ("overline-margin", overline_margin,
29652 doc: /* Space between overline and text, in pixels.
29653 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
29654 margin to the character height. */);
29655 overline_margin = 2;
29657 DEFVAR_INT ("underline-minimum-offset",
29658 underline_minimum_offset,
29659 doc: /* Minimum distance between baseline and underline.
29660 This can improve legibility of underlined text at small font sizes,
29661 particularly when using variable `x-use-underline-position-properties'
29662 with fonts that specify an UNDERLINE_POSITION relatively close to the
29663 baseline. The default value is 1. */);
29664 underline_minimum_offset = 1;
29666 DEFVAR_BOOL ("display-hourglass", display_hourglass_p,
29667 doc: /* Non-nil means show an hourglass pointer, when Emacs is busy.
29668 This feature only works when on a window system that can change
29669 cursor shapes. */);
29670 display_hourglass_p = 1;
29672 DEFVAR_LISP ("hourglass-delay", Vhourglass_delay,
29673 doc: /* Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
29674 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
29676 hourglass_atimer = NULL;
29677 hourglass_shown_p = 0;
29679 DEFSYM (Qglyphless_char, "glyphless-char");
29680 DEFSYM (Qhex_code, "hex-code");
29681 DEFSYM (Qempty_box, "empty-box");
29682 DEFSYM (Qthin_space, "thin-space");
29683 DEFSYM (Qzero_width, "zero-width");
29685 DEFSYM (Qglyphless_char_display, "glyphless-char-display");
29686 /* Intern this now in case it isn't already done.
29687 Setting this variable twice is harmless.
29688 But don't staticpro it here--that is done in alloc.c. */
29689 Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots");
29690 Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
29692 DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display,
29693 doc: /* Char-table defining glyphless characters.
29694 Each element, if non-nil, should be one of the following:
29695 an ASCII acronym string: display this string in a box
29696 `hex-code': display the hexadecimal code of a character in a box
29697 `empty-box': display as an empty box
29698 `thin-space': display as 1-pixel width space
29699 `zero-width': don't display
29700 An element may also be a cons cell (GRAPHICAL . TEXT), which specifies the
29701 display method for graphical terminals and text terminals respectively.
29702 GRAPHICAL and TEXT should each have one of the values listed above.
29704 The char-table has one extra slot to control the display of a character for
29705 which no font is found. This slot only takes effect on graphical terminals.
29706 Its value should be an ASCII acronym string, `hex-code', `empty-box', or
29707 `thin-space'. The default is `empty-box'. */);
29708 Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
29709 Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
29710 Qempty_box);
29712 DEFVAR_LISP ("debug-on-message", Vdebug_on_message,
29713 doc: /* If non-nil, debug if a message matching this regexp is displayed. */);
29714 Vdebug_on_message = Qnil;
29718 /* Initialize this module when Emacs starts. */
29720 void
29721 init_xdisp (void)
29723 current_header_line_height = current_mode_line_height = -1;
29725 CHARPOS (this_line_start_pos) = 0;
29727 if (!noninteractive)
29729 struct window *m = XWINDOW (minibuf_window);
29730 Lisp_Object frame = m->frame;
29731 struct frame *f = XFRAME (frame);
29732 Lisp_Object root = FRAME_ROOT_WINDOW (f);
29733 struct window *r = XWINDOW (root);
29734 int i;
29736 echo_area_window = minibuf_window;
29738 r->top_line = FRAME_TOP_MARGIN (f);
29739 r->total_lines = FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f);
29740 r->total_cols = FRAME_COLS (f);
29742 m->top_line = FRAME_LINES (f) - 1;
29743 m->total_lines = 1;
29744 m->total_cols = FRAME_COLS (f);
29746 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
29747 scratch_glyph_row.glyphs[TEXT_AREA + 1]
29748 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
29750 /* The default ellipsis glyphs `...'. */
29751 for (i = 0; i < 3; ++i)
29752 default_invis_vector[i] = make_number ('.');
29756 /* Allocate the buffer for frame titles.
29757 Also used for `format-mode-line'. */
29758 int size = 100;
29759 mode_line_noprop_buf = xmalloc (size);
29760 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
29761 mode_line_noprop_ptr = mode_line_noprop_buf;
29762 mode_line_target = MODE_LINE_DISPLAY;
29765 help_echo_showing_p = 0;
29768 /* Platform-independent portion of hourglass implementation. */
29770 /* Cancel a currently active hourglass timer, and start a new one. */
29771 void
29772 start_hourglass (void)
29774 #if defined (HAVE_WINDOW_SYSTEM)
29775 EMACS_TIME delay;
29777 cancel_hourglass ();
29779 if (INTEGERP (Vhourglass_delay)
29780 && XINT (Vhourglass_delay) > 0)
29781 delay = make_emacs_time (min (XINT (Vhourglass_delay),
29782 TYPE_MAXIMUM (time_t)),
29784 else if (FLOATP (Vhourglass_delay)
29785 && XFLOAT_DATA (Vhourglass_delay) > 0)
29786 delay = EMACS_TIME_FROM_DOUBLE (XFLOAT_DATA (Vhourglass_delay));
29787 else
29788 delay = make_emacs_time (DEFAULT_HOURGLASS_DELAY, 0);
29790 #ifdef HAVE_NTGUI
29792 extern void w32_note_current_window (void);
29793 w32_note_current_window ();
29795 #endif /* HAVE_NTGUI */
29797 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
29798 show_hourglass, NULL);
29799 #endif
29803 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
29804 shown. */
29805 void
29806 cancel_hourglass (void)
29808 #if defined (HAVE_WINDOW_SYSTEM)
29809 if (hourglass_atimer)
29811 cancel_atimer (hourglass_atimer);
29812 hourglass_atimer = NULL;
29815 if (hourglass_shown_p)
29816 hide_hourglass ();
29817 #endif