* window.h (struct window): Replace last_cursor with last_cursor_vpos
[emacs.git] / src / xdisp.c
blobcbb70a22bfb82fe53279bd6a77591214ad1cc88e
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 static 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 cols -= max (0, w->left_margin_cols);
986 cols -= max (0, w->right_margin_cols);
987 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
989 else if (area == LEFT_MARGIN_AREA)
991 cols = max (0, w->left_margin_cols);
992 pixels = 0;
994 else if (area == RIGHT_MARGIN_AREA)
996 cols = max (0, w->right_margin_cols);
997 pixels = 0;
1001 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1005 /* Return the pixel height of the display area of window W, not
1006 including mode lines of W, if any. */
1009 window_box_height (struct window *w)
1011 struct frame *f = XFRAME (w->frame);
1012 int height = WINDOW_TOTAL_HEIGHT (w);
1014 eassert (height >= 0);
1016 /* Note: the code below that determines the mode-line/header-line
1017 height is essentially the same as that contained in the macro
1018 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1019 the appropriate glyph row has its `mode_line_p' flag set,
1020 and if it doesn't, uses estimate_mode_line_height instead. */
1022 if (WINDOW_WANTS_MODELINE_P (w))
1024 struct glyph_row *ml_row
1025 = (w->current_matrix && w->current_matrix->rows
1026 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1027 : 0);
1028 if (ml_row && ml_row->mode_line_p)
1029 height -= ml_row->height;
1030 else
1031 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1034 if (WINDOW_WANTS_HEADER_LINE_P (w))
1036 struct glyph_row *hl_row
1037 = (w->current_matrix && w->current_matrix->rows
1038 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1039 : 0);
1040 if (hl_row && hl_row->mode_line_p)
1041 height -= hl_row->height;
1042 else
1043 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1046 /* With a very small font and a mode-line that's taller than
1047 default, we might end up with a negative height. */
1048 return max (0, height);
1051 /* Return the window-relative coordinate of the left edge of display
1052 area AREA of window W. AREA < 0 means return the left edge of the
1053 whole window, to the right of the left fringe of W. */
1056 window_box_left_offset (struct window *w, int area)
1058 int x;
1060 if (w->pseudo_window_p)
1061 return 0;
1063 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1065 if (area == TEXT_AREA)
1066 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1067 + window_box_width (w, LEFT_MARGIN_AREA));
1068 else if (area == RIGHT_MARGIN_AREA)
1069 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1070 + window_box_width (w, LEFT_MARGIN_AREA)
1071 + window_box_width (w, TEXT_AREA)
1072 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1074 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1075 else if (area == LEFT_MARGIN_AREA
1076 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1077 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1079 return x;
1083 /* Return the window-relative coordinate of the right edge of display
1084 area AREA of window W. AREA < 0 means return the right edge of the
1085 whole window, to the left of the right fringe of W. */
1088 window_box_right_offset (struct window *w, int area)
1090 return window_box_left_offset (w, area) + window_box_width (w, area);
1093 /* Return the frame-relative coordinate of the left edge of display
1094 area AREA of window W. AREA < 0 means return the left edge of the
1095 whole window, to the right of the left fringe of W. */
1098 window_box_left (struct window *w, int area)
1100 struct frame *f = XFRAME (w->frame);
1101 int x;
1103 if (w->pseudo_window_p)
1104 return FRAME_INTERNAL_BORDER_WIDTH (f);
1106 x = (WINDOW_LEFT_EDGE_X (w)
1107 + window_box_left_offset (w, area));
1109 return x;
1113 /* Return the frame-relative coordinate of the right edge of display
1114 area AREA of window W. AREA < 0 means return the right edge of the
1115 whole window, to the left of the right fringe of W. */
1118 window_box_right (struct window *w, int area)
1120 return window_box_left (w, area) + window_box_width (w, area);
1123 /* Get the bounding box of the display area AREA of window W, without
1124 mode lines, in frame-relative coordinates. AREA < 0 means the
1125 whole window, not including the left and right fringes of
1126 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1127 coordinates of the upper-left corner of the box. Return in
1128 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1130 void
1131 window_box (struct window *w, int area, int *box_x, int *box_y,
1132 int *box_width, int *box_height)
1134 if (box_width)
1135 *box_width = window_box_width (w, area);
1136 if (box_height)
1137 *box_height = window_box_height (w);
1138 if (box_x)
1139 *box_x = window_box_left (w, area);
1140 if (box_y)
1142 *box_y = WINDOW_TOP_EDGE_Y (w);
1143 if (WINDOW_WANTS_HEADER_LINE_P (w))
1144 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1149 /* Get the bounding box of the display area AREA of window W, without
1150 mode lines. AREA < 0 means the whole window, not including the
1151 left and right fringe of the window. Return in *TOP_LEFT_X
1152 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1153 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1154 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1155 box. */
1157 static void
1158 window_box_edges (struct window *w, int area, int *top_left_x, int *top_left_y,
1159 int *bottom_right_x, int *bottom_right_y)
1161 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1162 bottom_right_y);
1163 *bottom_right_x += *top_left_x;
1164 *bottom_right_y += *top_left_y;
1169 /***********************************************************************
1170 Utilities
1171 ***********************************************************************/
1173 /* Return the bottom y-position of the line the iterator IT is in.
1174 This can modify IT's settings. */
1177 line_bottom_y (struct it *it)
1179 int line_height = it->max_ascent + it->max_descent;
1180 int line_top_y = it->current_y;
1182 if (line_height == 0)
1184 if (last_height)
1185 line_height = last_height;
1186 else if (IT_CHARPOS (*it) < ZV)
1188 move_it_by_lines (it, 1);
1189 line_height = (it->max_ascent || it->max_descent
1190 ? it->max_ascent + it->max_descent
1191 : last_height);
1193 else
1195 struct glyph_row *row = it->glyph_row;
1197 /* Use the default character height. */
1198 it->glyph_row = NULL;
1199 it->what = IT_CHARACTER;
1200 it->c = ' ';
1201 it->len = 1;
1202 PRODUCE_GLYPHS (it);
1203 line_height = it->ascent + it->descent;
1204 it->glyph_row = row;
1208 return line_top_y + line_height;
1211 DEFUN ("line-pixel-height", Fline_pixel_height,
1212 Sline_pixel_height, 0, 0, 0,
1213 doc: /* Return height in pixels of text line in the selected window.
1215 Value is the height in pixels of the line at point. */)
1216 (void)
1218 struct it it;
1219 struct text_pos pt;
1220 struct window *w = XWINDOW (selected_window);
1222 SET_TEXT_POS (pt, PT, PT_BYTE);
1223 start_display (&it, w, pt);
1224 it.vpos = it.current_y = 0;
1225 last_height = 0;
1226 return make_number (line_bottom_y (&it));
1229 /* Return the default pixel height of text lines in window W. The
1230 value is the canonical height of the W frame's default font, plus
1231 any extra space required by the line-spacing variable or frame
1232 parameter.
1234 Implementation note: this ignores any line-spacing text properties
1235 put on the newline characters. This is because those properties
1236 only affect the _screen_ line ending in the newline (i.e., in a
1237 continued line, only the last screen line will be affected), which
1238 means only a small number of lines in a buffer can ever use this
1239 feature. Since this function is used to compute the default pixel
1240 equivalent of text lines in a window, we can safely ignore those
1241 few lines. For the same reasons, we ignore the line-height
1242 properties. */
1244 default_line_pixel_height (struct window *w)
1246 struct frame *f = WINDOW_XFRAME (w);
1247 int height = FRAME_LINE_HEIGHT (f);
1249 if (!FRAME_INITIAL_P (f) && BUFFERP (w->contents))
1251 struct buffer *b = XBUFFER (w->contents);
1252 Lisp_Object val = BVAR (b, extra_line_spacing);
1254 if (NILP (val))
1255 val = BVAR (&buffer_defaults, extra_line_spacing);
1256 if (!NILP (val))
1258 if (RANGED_INTEGERP (0, val, INT_MAX))
1259 height += XFASTINT (val);
1260 else if (FLOATP (val))
1262 int addon = XFLOAT_DATA (val) * height + 0.5;
1264 if (addon >= 0)
1265 height += addon;
1268 else
1269 height += f->extra_line_spacing;
1272 return height;
1275 /* Subroutine of pos_visible_p below. Extracts a display string, if
1276 any, from the display spec given as its argument. */
1277 static Lisp_Object
1278 string_from_display_spec (Lisp_Object spec)
1280 if (CONSP (spec))
1282 while (CONSP (spec))
1284 if (STRINGP (XCAR (spec)))
1285 return XCAR (spec);
1286 spec = XCDR (spec);
1289 else if (VECTORP (spec))
1291 ptrdiff_t i;
1293 for (i = 0; i < ASIZE (spec); i++)
1295 if (STRINGP (AREF (spec, i)))
1296 return AREF (spec, i);
1298 return Qnil;
1301 return spec;
1305 /* Limit insanely large values of W->hscroll on frame F to the largest
1306 value that will still prevent first_visible_x and last_visible_x of
1307 'struct it' from overflowing an int. */
1308 static int
1309 window_hscroll_limited (struct window *w, struct frame *f)
1311 ptrdiff_t window_hscroll = w->hscroll;
1312 int window_text_width = window_box_width (w, TEXT_AREA);
1313 int colwidth = FRAME_COLUMN_WIDTH (f);
1315 if (window_hscroll > (INT_MAX - window_text_width) / colwidth - 1)
1316 window_hscroll = (INT_MAX - window_text_width) / colwidth - 1;
1318 return window_hscroll;
1321 /* Return 1 if position CHARPOS is visible in window W.
1322 CHARPOS < 0 means return info about WINDOW_END position.
1323 If visible, set *X and *Y to pixel coordinates of top left corner.
1324 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1325 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1328 pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
1329 int *rtop, int *rbot, int *rowh, int *vpos)
1331 struct it it;
1332 void *itdata = bidi_shelve_cache ();
1333 struct text_pos top;
1334 int visible_p = 0;
1335 struct buffer *old_buffer = NULL;
1337 if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w))))
1338 return visible_p;
1340 if (XBUFFER (w->contents) != current_buffer)
1342 old_buffer = current_buffer;
1343 set_buffer_internal_1 (XBUFFER (w->contents));
1346 SET_TEXT_POS_FROM_MARKER (top, w->start);
1347 /* Scrolling a minibuffer window via scroll bar when the echo area
1348 shows long text sometimes resets the minibuffer contents behind
1349 our backs. */
1350 if (CHARPOS (top) > ZV)
1351 SET_TEXT_POS (top, BEGV, BEGV_BYTE);
1353 /* Compute exact mode line heights. */
1354 if (WINDOW_WANTS_MODELINE_P (w))
1355 current_mode_line_height
1356 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1357 BVAR (current_buffer, mode_line_format));
1359 if (WINDOW_WANTS_HEADER_LINE_P (w))
1360 current_header_line_height
1361 = display_mode_line (w, HEADER_LINE_FACE_ID,
1362 BVAR (current_buffer, header_line_format));
1364 start_display (&it, w, top);
1365 move_it_to (&it, charpos, -1, it.last_visible_y - 1, -1,
1366 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
1368 if (charpos >= 0
1369 && (((!it.bidi_p || it.bidi_it.scan_dir == 1)
1370 && IT_CHARPOS (it) >= charpos)
1371 /* When scanning backwards under bidi iteration, move_it_to
1372 stops at or _before_ CHARPOS, because it stops at or to
1373 the _right_ of the character at CHARPOS. */
1374 || (it.bidi_p && it.bidi_it.scan_dir == -1
1375 && IT_CHARPOS (it) <= charpos)))
1377 /* We have reached CHARPOS, or passed it. How the call to
1378 move_it_to can overshoot: (i) If CHARPOS is on invisible text
1379 or covered by a display property, move_it_to stops at the end
1380 of the invisible text, to the right of CHARPOS. (ii) If
1381 CHARPOS is in a display vector, move_it_to stops on its last
1382 glyph. */
1383 int top_x = it.current_x;
1384 int top_y = it.current_y;
1385 /* Calling line_bottom_y may change it.method, it.position, etc. */
1386 enum it_method it_method = it.method;
1387 int bottom_y = (last_height = 0, line_bottom_y (&it));
1388 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1390 if (top_y < window_top_y)
1391 visible_p = bottom_y > window_top_y;
1392 else if (top_y < it.last_visible_y)
1393 visible_p = 1;
1394 if (bottom_y >= it.last_visible_y
1395 && it.bidi_p && it.bidi_it.scan_dir == -1
1396 && IT_CHARPOS (it) < charpos)
1398 /* When the last line of the window is scanned backwards
1399 under bidi iteration, we could be duped into thinking
1400 that we have passed CHARPOS, when in fact move_it_to
1401 simply stopped short of CHARPOS because it reached
1402 last_visible_y. To see if that's what happened, we call
1403 move_it_to again with a slightly larger vertical limit,
1404 and see if it actually moved vertically; if it did, we
1405 didn't really reach CHARPOS, which is beyond window end. */
1406 struct it save_it = it;
1407 /* Why 10? because we don't know how many canonical lines
1408 will the height of the next line(s) be. So we guess. */
1409 int ten_more_lines = 10 * default_line_pixel_height (w);
1411 move_it_to (&it, charpos, -1, bottom_y + ten_more_lines, -1,
1412 MOVE_TO_POS | MOVE_TO_Y);
1413 if (it.current_y > top_y)
1414 visible_p = 0;
1416 it = save_it;
1418 if (visible_p)
1420 if (it_method == GET_FROM_DISPLAY_VECTOR)
1422 /* We stopped on the last glyph of a display vector.
1423 Try and recompute. Hack alert! */
1424 if (charpos < 2 || top.charpos >= charpos)
1425 top_x = it.glyph_row->x;
1426 else
1428 struct it it2, it2_prev;
1429 /* The idea is to get to the previous buffer
1430 position, consume the character there, and use
1431 the pixel coordinates we get after that. But if
1432 the previous buffer position is also displayed
1433 from a display vector, we need to consume all of
1434 the glyphs from that display vector. */
1435 start_display (&it2, w, top);
1436 move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS);
1437 /* If we didn't get to CHARPOS - 1, there's some
1438 replacing display property at that position, and
1439 we stopped after it. That is exactly the place
1440 whose coordinates we want. */
1441 if (IT_CHARPOS (it2) != charpos - 1)
1442 it2_prev = it2;
1443 else
1445 /* Iterate until we get out of the display
1446 vector that displays the character at
1447 CHARPOS - 1. */
1448 do {
1449 get_next_display_element (&it2);
1450 PRODUCE_GLYPHS (&it2);
1451 it2_prev = it2;
1452 set_iterator_to_next (&it2, 1);
1453 } while (it2.method == GET_FROM_DISPLAY_VECTOR
1454 && IT_CHARPOS (it2) < charpos);
1456 if (ITERATOR_AT_END_OF_LINE_P (&it2_prev)
1457 || it2_prev.current_x > it2_prev.last_visible_x)
1458 top_x = it.glyph_row->x;
1459 else
1461 top_x = it2_prev.current_x;
1462 top_y = it2_prev.current_y;
1466 else if (IT_CHARPOS (it) != charpos)
1468 Lisp_Object cpos = make_number (charpos);
1469 Lisp_Object spec = Fget_char_property (cpos, Qdisplay, Qnil);
1470 Lisp_Object string = string_from_display_spec (spec);
1471 struct text_pos tpos;
1472 int replacing_spec_p;
1473 bool newline_in_string
1474 = (STRINGP (string)
1475 && memchr (SDATA (string), '\n', SBYTES (string)));
1477 SET_TEXT_POS (tpos, charpos, CHAR_TO_BYTE (charpos));
1478 replacing_spec_p
1479 = (!NILP (spec)
1480 && handle_display_spec (NULL, spec, Qnil, Qnil, &tpos,
1481 charpos, FRAME_WINDOW_P (it.f)));
1482 /* The tricky code below is needed because there's a
1483 discrepancy between move_it_to and how we set cursor
1484 when PT is at the beginning of a portion of text
1485 covered by a display property or an overlay with a
1486 display property, or the display line ends in a
1487 newline from a display string. move_it_to will stop
1488 _after_ such display strings, whereas
1489 set_cursor_from_row conspires with cursor_row_p to
1490 place the cursor on the first glyph produced from the
1491 display string. */
1493 /* We have overshoot PT because it is covered by a
1494 display property that replaces the text it covers.
1495 If the string includes embedded newlines, we are also
1496 in the wrong display line. Backtrack to the correct
1497 line, where the display property begins. */
1498 if (replacing_spec_p)
1500 Lisp_Object startpos, endpos;
1501 EMACS_INT start, end;
1502 struct it it3;
1503 int it3_moved;
1505 /* Find the first and the last buffer positions
1506 covered by the display string. */
1507 endpos =
1508 Fnext_single_char_property_change (cpos, Qdisplay,
1509 Qnil, Qnil);
1510 startpos =
1511 Fprevious_single_char_property_change (endpos, Qdisplay,
1512 Qnil, Qnil);
1513 start = XFASTINT (startpos);
1514 end = XFASTINT (endpos);
1515 /* Move to the last buffer position before the
1516 display property. */
1517 start_display (&it3, w, top);
1518 move_it_to (&it3, start - 1, -1, -1, -1, MOVE_TO_POS);
1519 /* Move forward one more line if the position before
1520 the display string is a newline or if it is the
1521 rightmost character on a line that is
1522 continued or word-wrapped. */
1523 if (it3.method == GET_FROM_BUFFER
1524 && (it3.c == '\n'
1525 || FETCH_BYTE (IT_BYTEPOS (it3)) == '\n'))
1526 move_it_by_lines (&it3, 1);
1527 else if (move_it_in_display_line_to (&it3, -1,
1528 it3.current_x
1529 + it3.pixel_width,
1530 MOVE_TO_X)
1531 == MOVE_LINE_CONTINUED)
1533 move_it_by_lines (&it3, 1);
1534 /* When we are under word-wrap, the #$@%!
1535 move_it_by_lines moves 2 lines, so we need to
1536 fix that up. */
1537 if (it3.line_wrap == WORD_WRAP)
1538 move_it_by_lines (&it3, -1);
1541 /* Record the vertical coordinate of the display
1542 line where we wound up. */
1543 top_y = it3.current_y;
1544 if (it3.bidi_p)
1546 /* When characters are reordered for display,
1547 the character displayed to the left of the
1548 display string could be _after_ the display
1549 property in the logical order. Use the
1550 smallest vertical position of these two. */
1551 start_display (&it3, w, top);
1552 move_it_to (&it3, end + 1, -1, -1, -1, MOVE_TO_POS);
1553 if (it3.current_y < top_y)
1554 top_y = it3.current_y;
1556 /* Move from the top of the window to the beginning
1557 of the display line where the display string
1558 begins. */
1559 start_display (&it3, w, top);
1560 move_it_to (&it3, -1, 0, top_y, -1, MOVE_TO_X | MOVE_TO_Y);
1561 /* If it3_moved stays zero after the 'while' loop
1562 below, that means we already were at a newline
1563 before the loop (e.g., the display string begins
1564 with a newline), so we don't need to (and cannot)
1565 inspect the glyphs of it3.glyph_row, because
1566 PRODUCE_GLYPHS will not produce anything for a
1567 newline, and thus it3.glyph_row stays at its
1568 stale content it got at top of the window. */
1569 it3_moved = 0;
1570 /* Finally, advance the iterator until we hit the
1571 first display element whose character position is
1572 CHARPOS, or until the first newline from the
1573 display string, which signals the end of the
1574 display line. */
1575 while (get_next_display_element (&it3))
1577 PRODUCE_GLYPHS (&it3);
1578 if (IT_CHARPOS (it3) == charpos
1579 || ITERATOR_AT_END_OF_LINE_P (&it3))
1580 break;
1581 it3_moved = 1;
1582 set_iterator_to_next (&it3, 0);
1584 top_x = it3.current_x - it3.pixel_width;
1585 /* Normally, we would exit the above loop because we
1586 found the display element whose character
1587 position is CHARPOS. For the contingency that we
1588 didn't, and stopped at the first newline from the
1589 display string, move back over the glyphs
1590 produced from the string, until we find the
1591 rightmost glyph not from the string. */
1592 if (it3_moved
1593 && newline_in_string
1594 && IT_CHARPOS (it3) != charpos && EQ (it3.object, string))
1596 struct glyph *g = it3.glyph_row->glyphs[TEXT_AREA]
1597 + it3.glyph_row->used[TEXT_AREA];
1599 while (EQ ((g - 1)->object, string))
1601 --g;
1602 top_x -= g->pixel_width;
1604 eassert (g < it3.glyph_row->glyphs[TEXT_AREA]
1605 + it3.glyph_row->used[TEXT_AREA]);
1610 *x = top_x;
1611 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1612 *rtop = max (0, window_top_y - top_y);
1613 *rbot = max (0, bottom_y - it.last_visible_y);
1614 *rowh = max (0, (min (bottom_y, it.last_visible_y)
1615 - max (top_y, window_top_y)));
1616 *vpos = it.vpos;
1619 else
1621 /* We were asked to provide info about WINDOW_END. */
1622 struct it it2;
1623 void *it2data = NULL;
1625 SAVE_IT (it2, it, it2data);
1626 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1627 move_it_by_lines (&it, 1);
1628 if (charpos < IT_CHARPOS (it)
1629 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1631 visible_p = 1;
1632 RESTORE_IT (&it2, &it2, it2data);
1633 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1634 *x = it2.current_x;
1635 *y = it2.current_y + it2.max_ascent - it2.ascent;
1636 *rtop = max (0, -it2.current_y);
1637 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1638 - it.last_visible_y));
1639 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
1640 it.last_visible_y)
1641 - max (it2.current_y,
1642 WINDOW_HEADER_LINE_HEIGHT (w))));
1643 *vpos = it2.vpos;
1645 else
1646 bidi_unshelve_cache (it2data, 1);
1648 bidi_unshelve_cache (itdata, 0);
1650 if (old_buffer)
1651 set_buffer_internal_1 (old_buffer);
1653 current_header_line_height = current_mode_line_height = -1;
1655 if (visible_p && w->hscroll > 0)
1656 *x -=
1657 window_hscroll_limited (w, WINDOW_XFRAME (w))
1658 * WINDOW_FRAME_COLUMN_WIDTH (w);
1660 #if 0
1661 /* Debugging code. */
1662 if (visible_p)
1663 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1664 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
1665 else
1666 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
1667 #endif
1669 return visible_p;
1673 /* Return the next character from STR. Return in *LEN the length of
1674 the character. This is like STRING_CHAR_AND_LENGTH but never
1675 returns an invalid character. If we find one, we return a `?', but
1676 with the length of the invalid character. */
1678 static int
1679 string_char_and_length (const unsigned char *str, int *len)
1681 int c;
1683 c = STRING_CHAR_AND_LENGTH (str, *len);
1684 if (!CHAR_VALID_P (c))
1685 /* We may not change the length here because other places in Emacs
1686 don't use this function, i.e. they silently accept invalid
1687 characters. */
1688 c = '?';
1690 return c;
1695 /* Given a position POS containing a valid character and byte position
1696 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1698 static struct text_pos
1699 string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, ptrdiff_t nchars)
1701 eassert (STRINGP (string) && nchars >= 0);
1703 if (STRING_MULTIBYTE (string))
1705 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1706 int len;
1708 while (nchars--)
1710 string_char_and_length (p, &len);
1711 p += len;
1712 CHARPOS (pos) += 1;
1713 BYTEPOS (pos) += len;
1716 else
1717 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1719 return pos;
1723 /* Value is the text position, i.e. character and byte position,
1724 for character position CHARPOS in STRING. */
1726 static struct text_pos
1727 string_pos (ptrdiff_t charpos, Lisp_Object string)
1729 struct text_pos pos;
1730 eassert (STRINGP (string));
1731 eassert (charpos >= 0);
1732 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1733 return pos;
1737 /* Value is a text position, i.e. character and byte position, for
1738 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1739 means recognize multibyte characters. */
1741 static struct text_pos
1742 c_string_pos (ptrdiff_t charpos, const char *s, bool multibyte_p)
1744 struct text_pos pos;
1746 eassert (s != NULL);
1747 eassert (charpos >= 0);
1749 if (multibyte_p)
1751 int len;
1753 SET_TEXT_POS (pos, 0, 0);
1754 while (charpos--)
1756 string_char_and_length ((const unsigned char *) s, &len);
1757 s += len;
1758 CHARPOS (pos) += 1;
1759 BYTEPOS (pos) += len;
1762 else
1763 SET_TEXT_POS (pos, charpos, charpos);
1765 return pos;
1769 /* Value is the number of characters in C string S. MULTIBYTE_P
1770 non-zero means recognize multibyte characters. */
1772 static ptrdiff_t
1773 number_of_chars (const char *s, bool multibyte_p)
1775 ptrdiff_t nchars;
1777 if (multibyte_p)
1779 ptrdiff_t rest = strlen (s);
1780 int len;
1781 const unsigned char *p = (const unsigned char *) s;
1783 for (nchars = 0; rest > 0; ++nchars)
1785 string_char_and_length (p, &len);
1786 rest -= len, p += len;
1789 else
1790 nchars = strlen (s);
1792 return nchars;
1796 /* Compute byte position NEWPOS->bytepos corresponding to
1797 NEWPOS->charpos. POS is a known position in string STRING.
1798 NEWPOS->charpos must be >= POS.charpos. */
1800 static void
1801 compute_string_pos (struct text_pos *newpos, struct text_pos pos, Lisp_Object string)
1803 eassert (STRINGP (string));
1804 eassert (CHARPOS (*newpos) >= CHARPOS (pos));
1806 if (STRING_MULTIBYTE (string))
1807 *newpos = string_pos_nchars_ahead (pos, string,
1808 CHARPOS (*newpos) - CHARPOS (pos));
1809 else
1810 BYTEPOS (*newpos) = CHARPOS (*newpos);
1813 /* EXPORT:
1814 Return an estimation of the pixel height of mode or header lines on
1815 frame F. FACE_ID specifies what line's height to estimate. */
1818 estimate_mode_line_height (struct frame *f, enum face_id face_id)
1820 #ifdef HAVE_WINDOW_SYSTEM
1821 if (FRAME_WINDOW_P (f))
1823 int height = FONT_HEIGHT (FRAME_FONT (f));
1825 /* This function is called so early when Emacs starts that the face
1826 cache and mode line face are not yet initialized. */
1827 if (FRAME_FACE_CACHE (f))
1829 struct face *face = FACE_FROM_ID (f, face_id);
1830 if (face)
1832 if (face->font)
1833 height = FONT_HEIGHT (face->font);
1834 if (face->box_line_width > 0)
1835 height += 2 * face->box_line_width;
1839 return height;
1841 #endif
1843 return 1;
1846 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1847 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1848 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1849 not force the value into range. */
1851 void
1852 pixel_to_glyph_coords (struct frame *f, register int pix_x, register int pix_y,
1853 int *x, int *y, NativeRectangle *bounds, int noclip)
1856 #ifdef HAVE_WINDOW_SYSTEM
1857 if (FRAME_WINDOW_P (f))
1859 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1860 even for negative values. */
1861 if (pix_x < 0)
1862 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1863 if (pix_y < 0)
1864 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1866 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1867 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1869 if (bounds)
1870 STORE_NATIVE_RECT (*bounds,
1871 FRAME_COL_TO_PIXEL_X (f, pix_x),
1872 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1873 FRAME_COLUMN_WIDTH (f) - 1,
1874 FRAME_LINE_HEIGHT (f) - 1);
1876 if (!noclip)
1878 if (pix_x < 0)
1879 pix_x = 0;
1880 else if (pix_x > FRAME_TOTAL_COLS (f))
1881 pix_x = FRAME_TOTAL_COLS (f);
1883 if (pix_y < 0)
1884 pix_y = 0;
1885 else if (pix_y > FRAME_LINES (f))
1886 pix_y = FRAME_LINES (f);
1889 #endif
1891 *x = pix_x;
1892 *y = pix_y;
1896 /* Find the glyph under window-relative coordinates X/Y in window W.
1897 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1898 strings. Return in *HPOS and *VPOS the row and column number of
1899 the glyph found. Return in *AREA the glyph area containing X.
1900 Value is a pointer to the glyph found or null if X/Y is not on
1901 text, or we can't tell because W's current matrix is not up to
1902 date. */
1904 static
1905 struct glyph *
1906 x_y_to_hpos_vpos (struct window *w, int x, int y, int *hpos, int *vpos,
1907 int *dx, int *dy, int *area)
1909 struct glyph *glyph, *end;
1910 struct glyph_row *row = NULL;
1911 int x0, i;
1913 /* Find row containing Y. Give up if some row is not enabled. */
1914 for (i = 0; i < w->current_matrix->nrows; ++i)
1916 row = MATRIX_ROW (w->current_matrix, i);
1917 if (!row->enabled_p)
1918 return NULL;
1919 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1920 break;
1923 *vpos = i;
1924 *hpos = 0;
1926 /* Give up if Y is not in the window. */
1927 if (i == w->current_matrix->nrows)
1928 return NULL;
1930 /* Get the glyph area containing X. */
1931 if (w->pseudo_window_p)
1933 *area = TEXT_AREA;
1934 x0 = 0;
1936 else
1938 if (x < window_box_left_offset (w, TEXT_AREA))
1940 *area = LEFT_MARGIN_AREA;
1941 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1943 else if (x < window_box_right_offset (w, TEXT_AREA))
1945 *area = TEXT_AREA;
1946 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1948 else
1950 *area = RIGHT_MARGIN_AREA;
1951 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1955 /* Find glyph containing X. */
1956 glyph = row->glyphs[*area];
1957 end = glyph + row->used[*area];
1958 x -= x0;
1959 while (glyph < end && x >= glyph->pixel_width)
1961 x -= glyph->pixel_width;
1962 ++glyph;
1965 if (glyph == end)
1966 return NULL;
1968 if (dx)
1970 *dx = x;
1971 *dy = y - (row->y + row->ascent - glyph->ascent);
1974 *hpos = glyph - row->glyphs[*area];
1975 return glyph;
1978 /* Convert frame-relative x/y to coordinates relative to window W.
1979 Takes pseudo-windows into account. */
1981 static void
1982 frame_to_window_pixel_xy (struct window *w, int *x, int *y)
1984 if (w->pseudo_window_p)
1986 /* A pseudo-window is always full-width, and starts at the
1987 left edge of the frame, plus a frame border. */
1988 struct frame *f = XFRAME (w->frame);
1989 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1990 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1992 else
1994 *x -= WINDOW_LEFT_EDGE_X (w);
1995 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1999 #ifdef HAVE_WINDOW_SYSTEM
2001 /* EXPORT:
2002 Return in RECTS[] at most N clipping rectangles for glyph string S.
2003 Return the number of stored rectangles. */
2006 get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int n)
2008 XRectangle r;
2010 if (n <= 0)
2011 return 0;
2013 if (s->row->full_width_p)
2015 /* Draw full-width. X coordinates are relative to S->w->left_col. */
2016 r.x = WINDOW_LEFT_EDGE_X (s->w);
2017 r.width = WINDOW_TOTAL_WIDTH (s->w);
2019 /* Unless displaying a mode or menu bar line, which are always
2020 fully visible, clip to the visible part of the row. */
2021 if (s->w->pseudo_window_p)
2022 r.height = s->row->visible_height;
2023 else
2024 r.height = s->height;
2026 else
2028 /* This is a text line that may be partially visible. */
2029 r.x = window_box_left (s->w, s->area);
2030 r.width = window_box_width (s->w, s->area);
2031 r.height = s->row->visible_height;
2034 if (s->clip_head)
2035 if (r.x < s->clip_head->x)
2037 if (r.width >= s->clip_head->x - r.x)
2038 r.width -= s->clip_head->x - r.x;
2039 else
2040 r.width = 0;
2041 r.x = s->clip_head->x;
2043 if (s->clip_tail)
2044 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
2046 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
2047 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
2048 else
2049 r.width = 0;
2052 /* If S draws overlapping rows, it's sufficient to use the top and
2053 bottom of the window for clipping because this glyph string
2054 intentionally draws over other lines. */
2055 if (s->for_overlaps)
2057 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2058 r.height = window_text_bottom_y (s->w) - r.y;
2060 /* Alas, the above simple strategy does not work for the
2061 environments with anti-aliased text: if the same text is
2062 drawn onto the same place multiple times, it gets thicker.
2063 If the overlap we are processing is for the erased cursor, we
2064 take the intersection with the rectangle of the cursor. */
2065 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
2067 XRectangle rc, r_save = r;
2069 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
2070 rc.y = s->w->phys_cursor.y;
2071 rc.width = s->w->phys_cursor_width;
2072 rc.height = s->w->phys_cursor_height;
2074 x_intersect_rectangles (&r_save, &rc, &r);
2077 else
2079 /* Don't use S->y for clipping because it doesn't take partially
2080 visible lines into account. For example, it can be negative for
2081 partially visible lines at the top of a window. */
2082 if (!s->row->full_width_p
2083 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
2084 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2085 else
2086 r.y = max (0, s->row->y);
2089 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
2091 /* If drawing the cursor, don't let glyph draw outside its
2092 advertised boundaries. Cleartype does this under some circumstances. */
2093 if (s->hl == DRAW_CURSOR)
2095 struct glyph *glyph = s->first_glyph;
2096 int height, max_y;
2098 if (s->x > r.x)
2100 r.width -= s->x - r.x;
2101 r.x = s->x;
2103 r.width = min (r.width, glyph->pixel_width);
2105 /* If r.y is below window bottom, ensure that we still see a cursor. */
2106 height = min (glyph->ascent + glyph->descent,
2107 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
2108 max_y = window_text_bottom_y (s->w) - height;
2109 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
2110 if (s->ybase - glyph->ascent > max_y)
2112 r.y = max_y;
2113 r.height = height;
2115 else
2117 /* Don't draw cursor glyph taller than our actual glyph. */
2118 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
2119 if (height < r.height)
2121 max_y = r.y + r.height;
2122 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
2123 r.height = min (max_y - r.y, height);
2128 if (s->row->clip)
2130 XRectangle r_save = r;
2132 if (! x_intersect_rectangles (&r_save, s->row->clip, &r))
2133 r.width = 0;
2136 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
2137 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
2139 #ifdef CONVERT_FROM_XRECT
2140 CONVERT_FROM_XRECT (r, *rects);
2141 #else
2142 *rects = r;
2143 #endif
2144 return 1;
2146 else
2148 /* If we are processing overlapping and allowed to return
2149 multiple clipping rectangles, we exclude the row of the glyph
2150 string from the clipping rectangle. This is to avoid drawing
2151 the same text on the environment with anti-aliasing. */
2152 #ifdef CONVERT_FROM_XRECT
2153 XRectangle rs[2];
2154 #else
2155 XRectangle *rs = rects;
2156 #endif
2157 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
2159 if (s->for_overlaps & OVERLAPS_PRED)
2161 rs[i] = r;
2162 if (r.y + r.height > row_y)
2164 if (r.y < row_y)
2165 rs[i].height = row_y - r.y;
2166 else
2167 rs[i].height = 0;
2169 i++;
2171 if (s->for_overlaps & OVERLAPS_SUCC)
2173 rs[i] = r;
2174 if (r.y < row_y + s->row->visible_height)
2176 if (r.y + r.height > row_y + s->row->visible_height)
2178 rs[i].y = row_y + s->row->visible_height;
2179 rs[i].height = r.y + r.height - rs[i].y;
2181 else
2182 rs[i].height = 0;
2184 i++;
2187 n = i;
2188 #ifdef CONVERT_FROM_XRECT
2189 for (i = 0; i < n; i++)
2190 CONVERT_FROM_XRECT (rs[i], rects[i]);
2191 #endif
2192 return n;
2196 /* EXPORT:
2197 Return in *NR the clipping rectangle for glyph string S. */
2199 void
2200 get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr)
2202 get_glyph_string_clip_rects (s, nr, 1);
2206 /* EXPORT:
2207 Return the position and height of the phys cursor in window W.
2208 Set w->phys_cursor_width to width of phys cursor.
2211 void
2212 get_phys_cursor_geometry (struct window *w, struct glyph_row *row,
2213 struct glyph *glyph, int *xp, int *yp, int *heightp)
2215 struct frame *f = XFRAME (WINDOW_FRAME (w));
2216 int x, y, wd, h, h0, y0;
2218 /* Compute the width of the rectangle to draw. If on a stretch
2219 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2220 rectangle as wide as the glyph, but use a canonical character
2221 width instead. */
2222 wd = glyph->pixel_width - 1;
2223 #if defined (HAVE_NTGUI) || defined (HAVE_NS)
2224 wd++; /* Why? */
2225 #endif
2227 x = w->phys_cursor.x;
2228 if (x < 0)
2230 wd += x;
2231 x = 0;
2234 if (glyph->type == STRETCH_GLYPH
2235 && !x_stretch_cursor_p)
2236 wd = min (FRAME_COLUMN_WIDTH (f), wd);
2237 w->phys_cursor_width = wd;
2239 y = w->phys_cursor.y + row->ascent - glyph->ascent;
2241 /* If y is below window bottom, ensure that we still see a cursor. */
2242 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
2244 h = max (h0, glyph->ascent + glyph->descent);
2245 h0 = min (h0, glyph->ascent + glyph->descent);
2247 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
2248 if (y < y0)
2250 h = max (h - (y0 - y) + 1, h0);
2251 y = y0 - 1;
2253 else
2255 y0 = window_text_bottom_y (w) - h0;
2256 if (y > y0)
2258 h += y - y0;
2259 y = y0;
2263 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
2264 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
2265 *heightp = h;
2269 * Remember which glyph the mouse is over.
2272 void
2273 remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
2275 Lisp_Object window;
2276 struct window *w;
2277 struct glyph_row *r, *gr, *end_row;
2278 enum window_part part;
2279 enum glyph_row_area area;
2280 int x, y, width, height;
2282 /* Try to determine frame pixel position and size of the glyph under
2283 frame pixel coordinates X/Y on frame F. */
2285 if (!f->glyphs_initialized_p
2286 || (window = window_from_coordinates (f, gx, gy, &part, 0),
2287 NILP (window)))
2289 width = FRAME_SMALLEST_CHAR_WIDTH (f);
2290 height = FRAME_SMALLEST_FONT_HEIGHT (f);
2291 goto virtual_glyph;
2294 w = XWINDOW (window);
2295 width = WINDOW_FRAME_COLUMN_WIDTH (w);
2296 height = WINDOW_FRAME_LINE_HEIGHT (w);
2298 x = window_relative_x_coord (w, part, gx);
2299 y = gy - WINDOW_TOP_EDGE_Y (w);
2301 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
2302 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
2304 if (w->pseudo_window_p)
2306 area = TEXT_AREA;
2307 part = ON_MODE_LINE; /* Don't adjust margin. */
2308 goto text_glyph;
2311 switch (part)
2313 case ON_LEFT_MARGIN:
2314 area = LEFT_MARGIN_AREA;
2315 goto text_glyph;
2317 case ON_RIGHT_MARGIN:
2318 area = RIGHT_MARGIN_AREA;
2319 goto text_glyph;
2321 case ON_HEADER_LINE:
2322 case ON_MODE_LINE:
2323 gr = (part == ON_HEADER_LINE
2324 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
2325 : MATRIX_MODE_LINE_ROW (w->current_matrix));
2326 gy = gr->y;
2327 area = TEXT_AREA;
2328 goto text_glyph_row_found;
2330 case ON_TEXT:
2331 area = TEXT_AREA;
2333 text_glyph:
2334 gr = 0; gy = 0;
2335 for (; r <= end_row && r->enabled_p; ++r)
2336 if (r->y + r->height > y)
2338 gr = r; gy = r->y;
2339 break;
2342 text_glyph_row_found:
2343 if (gr && gy <= y)
2345 struct glyph *g = gr->glyphs[area];
2346 struct glyph *end = g + gr->used[area];
2348 height = gr->height;
2349 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2350 if (gx + g->pixel_width > x)
2351 break;
2353 if (g < end)
2355 if (g->type == IMAGE_GLYPH)
2357 /* Don't remember when mouse is over image, as
2358 image may have hot-spots. */
2359 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2360 return;
2362 width = g->pixel_width;
2364 else
2366 /* Use nominal char spacing at end of line. */
2367 x -= gx;
2368 gx += (x / width) * width;
2371 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2372 gx += window_box_left_offset (w, area);
2374 else
2376 /* Use nominal line height at end of window. */
2377 gx = (x / width) * width;
2378 y -= gy;
2379 gy += (y / height) * height;
2381 break;
2383 case ON_LEFT_FRINGE:
2384 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2385 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2386 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2387 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2388 goto row_glyph;
2390 case ON_RIGHT_FRINGE:
2391 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2392 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2393 : window_box_right_offset (w, TEXT_AREA));
2394 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2395 goto row_glyph;
2397 case ON_SCROLL_BAR:
2398 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2400 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2401 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2402 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2403 : 0)));
2404 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2406 row_glyph:
2407 gr = 0, gy = 0;
2408 for (; r <= end_row && r->enabled_p; ++r)
2409 if (r->y + r->height > y)
2411 gr = r; gy = r->y;
2412 break;
2415 if (gr && gy <= y)
2416 height = gr->height;
2417 else
2419 /* Use nominal line height at end of window. */
2420 y -= gy;
2421 gy += (y / height) * height;
2423 break;
2425 default:
2427 virtual_glyph:
2428 /* If there is no glyph under the mouse, then we divide the screen
2429 into a grid of the smallest glyph in the frame, and use that
2430 as our "glyph". */
2432 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2433 round down even for negative values. */
2434 if (gx < 0)
2435 gx -= width - 1;
2436 if (gy < 0)
2437 gy -= height - 1;
2439 gx = (gx / width) * width;
2440 gy = (gy / height) * height;
2442 goto store_rect;
2445 gx += WINDOW_LEFT_EDGE_X (w);
2446 gy += WINDOW_TOP_EDGE_Y (w);
2448 store_rect:
2449 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2451 /* Visible feedback for debugging. */
2452 #if 0
2453 #if HAVE_X_WINDOWS
2454 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2455 f->output_data.x->normal_gc,
2456 gx, gy, width, height);
2457 #endif
2458 #endif
2462 #endif /* HAVE_WINDOW_SYSTEM */
2464 static void
2465 adjust_window_ends (struct window *w, struct glyph_row *row, bool current)
2467 eassert (w);
2468 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
2469 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
2470 w->window_end_vpos
2471 = MATRIX_ROW_VPOS (row, current ? w->current_matrix : w->desired_matrix);
2474 /***********************************************************************
2475 Lisp form evaluation
2476 ***********************************************************************/
2478 /* Error handler for safe_eval and safe_call. */
2480 static Lisp_Object
2481 safe_eval_handler (Lisp_Object arg, ptrdiff_t nargs, Lisp_Object *args)
2483 add_to_log ("Error during redisplay: %S signaled %S",
2484 Flist (nargs, args), arg);
2485 return Qnil;
2488 /* Call function FUNC with the rest of NARGS - 1 arguments
2489 following. Return the result, or nil if something went
2490 wrong. Prevent redisplay during the evaluation. */
2492 Lisp_Object
2493 safe_call (ptrdiff_t nargs, Lisp_Object func, ...)
2495 Lisp_Object val;
2497 if (inhibit_eval_during_redisplay)
2498 val = Qnil;
2499 else
2501 va_list ap;
2502 ptrdiff_t i;
2503 ptrdiff_t count = SPECPDL_INDEX ();
2504 struct gcpro gcpro1;
2505 Lisp_Object *args = alloca (nargs * word_size);
2507 args[0] = func;
2508 va_start (ap, func);
2509 for (i = 1; i < nargs; i++)
2510 args[i] = va_arg (ap, Lisp_Object);
2511 va_end (ap);
2513 GCPRO1 (args[0]);
2514 gcpro1.nvars = nargs;
2515 specbind (Qinhibit_redisplay, Qt);
2516 /* Use Qt to ensure debugger does not run,
2517 so there is no possibility of wanting to redisplay. */
2518 val = internal_condition_case_n (Ffuncall, nargs, args, Qt,
2519 safe_eval_handler);
2520 UNGCPRO;
2521 val = unbind_to (count, val);
2524 return val;
2528 /* Call function FN with one argument ARG.
2529 Return the result, or nil if something went wrong. */
2531 Lisp_Object
2532 safe_call1 (Lisp_Object fn, Lisp_Object arg)
2534 return safe_call (2, fn, arg);
2537 static Lisp_Object Qeval;
2539 Lisp_Object
2540 safe_eval (Lisp_Object sexpr)
2542 return safe_call1 (Qeval, sexpr);
2545 /* Call function FN with two arguments ARG1 and ARG2.
2546 Return the result, or nil if something went wrong. */
2548 Lisp_Object
2549 safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
2551 return safe_call (3, fn, arg1, arg2);
2556 /***********************************************************************
2557 Debugging
2558 ***********************************************************************/
2560 #if 0
2562 /* Define CHECK_IT to perform sanity checks on iterators.
2563 This is for debugging. It is too slow to do unconditionally. */
2565 static void
2566 check_it (struct it *it)
2568 if (it->method == GET_FROM_STRING)
2570 eassert (STRINGP (it->string));
2571 eassert (IT_STRING_CHARPOS (*it) >= 0);
2573 else
2575 eassert (IT_STRING_CHARPOS (*it) < 0);
2576 if (it->method == GET_FROM_BUFFER)
2578 /* Check that character and byte positions agree. */
2579 eassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2583 if (it->dpvec)
2584 eassert (it->current.dpvec_index >= 0);
2585 else
2586 eassert (it->current.dpvec_index < 0);
2589 #define CHECK_IT(IT) check_it ((IT))
2591 #else /* not 0 */
2593 #define CHECK_IT(IT) (void) 0
2595 #endif /* not 0 */
2598 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2600 /* Check that the window end of window W is what we expect it
2601 to be---the last row in the current matrix displaying text. */
2603 static void
2604 check_window_end (struct window *w)
2606 if (!MINI_WINDOW_P (w) && w->window_end_valid)
2608 struct glyph_row *row;
2609 eassert ((row = MATRIX_ROW (w->current_matrix, w->window_end_vpos),
2610 !row->enabled_p
2611 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2612 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2616 #define CHECK_WINDOW_END(W) check_window_end ((W))
2618 #else
2620 #define CHECK_WINDOW_END(W) (void) 0
2622 #endif /* GLYPH_DEBUG and ENABLE_CHECKING */
2624 /* Return mark position if current buffer has the region of non-zero length,
2625 or -1 otherwise. */
2627 static ptrdiff_t
2628 markpos_of_region (void)
2630 if (!NILP (Vtransient_mark_mode)
2631 && !NILP (BVAR (current_buffer, mark_active))
2632 && XMARKER (BVAR (current_buffer, mark))->buffer != NULL)
2634 ptrdiff_t markpos = XMARKER (BVAR (current_buffer, mark))->charpos;
2636 if (markpos != PT)
2637 return markpos;
2639 return -1;
2642 /***********************************************************************
2643 Iterator initialization
2644 ***********************************************************************/
2646 /* Initialize IT for displaying current_buffer in window W, starting
2647 at character position CHARPOS. CHARPOS < 0 means that no buffer
2648 position is specified which is useful when the iterator is assigned
2649 a position later. BYTEPOS is the byte position corresponding to
2650 CHARPOS.
2652 If ROW is not null, calls to produce_glyphs with IT as parameter
2653 will produce glyphs in that row.
2655 BASE_FACE_ID is the id of a base face to use. It must be one of
2656 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2657 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2658 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2660 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2661 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2662 will be initialized to use the corresponding mode line glyph row of
2663 the desired matrix of W. */
2665 void
2666 init_iterator (struct it *it, struct window *w,
2667 ptrdiff_t charpos, ptrdiff_t bytepos,
2668 struct glyph_row *row, enum face_id base_face_id)
2670 ptrdiff_t markpos;
2671 enum face_id remapped_base_face_id = base_face_id;
2673 /* Some precondition checks. */
2674 eassert (w != NULL && it != NULL);
2675 eassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2676 && charpos <= ZV));
2678 /* If face attributes have been changed since the last redisplay,
2679 free realized faces now because they depend on face definitions
2680 that might have changed. Don't free faces while there might be
2681 desired matrices pending which reference these faces. */
2682 if (face_change_count && !inhibit_free_realized_faces)
2684 face_change_count = 0;
2685 free_all_realized_faces (Qnil);
2688 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
2689 if (! NILP (Vface_remapping_alist))
2690 remapped_base_face_id
2691 = lookup_basic_face (XFRAME (w->frame), base_face_id);
2693 /* Use one of the mode line rows of W's desired matrix if
2694 appropriate. */
2695 if (row == NULL)
2697 if (base_face_id == MODE_LINE_FACE_ID
2698 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2699 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2700 else if (base_face_id == HEADER_LINE_FACE_ID)
2701 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2704 /* Clear IT. */
2705 memset (it, 0, sizeof *it);
2706 it->current.overlay_string_index = -1;
2707 it->current.dpvec_index = -1;
2708 it->base_face_id = remapped_base_face_id;
2709 it->string = Qnil;
2710 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2711 it->paragraph_embedding = L2R;
2712 it->bidi_it.string.lstring = Qnil;
2713 it->bidi_it.string.s = NULL;
2714 it->bidi_it.string.bufpos = 0;
2715 it->bidi_it.w = w;
2717 /* The window in which we iterate over current_buffer: */
2718 XSETWINDOW (it->window, w);
2719 it->w = w;
2720 it->f = XFRAME (w->frame);
2722 it->cmp_it.id = -1;
2724 /* Extra space between lines (on window systems only). */
2725 if (base_face_id == DEFAULT_FACE_ID
2726 && FRAME_WINDOW_P (it->f))
2728 if (NATNUMP (BVAR (current_buffer, extra_line_spacing)))
2729 it->extra_line_spacing = XFASTINT (BVAR (current_buffer, extra_line_spacing));
2730 else if (FLOATP (BVAR (current_buffer, extra_line_spacing)))
2731 it->extra_line_spacing = (XFLOAT_DATA (BVAR (current_buffer, extra_line_spacing))
2732 * FRAME_LINE_HEIGHT (it->f));
2733 else if (it->f->extra_line_spacing > 0)
2734 it->extra_line_spacing = it->f->extra_line_spacing;
2735 it->max_extra_line_spacing = 0;
2738 /* If realized faces have been removed, e.g. because of face
2739 attribute changes of named faces, recompute them. When running
2740 in batch mode, the face cache of the initial frame is null. If
2741 we happen to get called, make a dummy face cache. */
2742 if (FRAME_FACE_CACHE (it->f) == NULL)
2743 init_frame_faces (it->f);
2744 if (FRAME_FACE_CACHE (it->f)->used == 0)
2745 recompute_basic_faces (it->f);
2747 /* Current value of the `slice', `space-width', and 'height' properties. */
2748 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2749 it->space_width = Qnil;
2750 it->font_height = Qnil;
2751 it->override_ascent = -1;
2753 /* Are control characters displayed as `^C'? */
2754 it->ctl_arrow_p = !NILP (BVAR (current_buffer, ctl_arrow));
2756 /* -1 means everything between a CR and the following line end
2757 is invisible. >0 means lines indented more than this value are
2758 invisible. */
2759 it->selective = (INTEGERP (BVAR (current_buffer, selective_display))
2760 ? (clip_to_bounds
2761 (-1, XINT (BVAR (current_buffer, selective_display)),
2762 PTRDIFF_MAX))
2763 : (!NILP (BVAR (current_buffer, selective_display))
2764 ? -1 : 0));
2765 it->selective_display_ellipsis_p
2766 = !NILP (BVAR (current_buffer, selective_display_ellipses));
2768 /* Display table to use. */
2769 it->dp = window_display_table (w);
2771 /* Are multibyte characters enabled in current_buffer? */
2772 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
2774 /* If visible region is of non-zero length, set IT->region_beg_charpos
2775 and IT->region_end_charpos to the start and end of a visible region
2776 in window IT->w. Set both to -1 to indicate no region. */
2777 markpos = markpos_of_region ();
2778 if (markpos >= 0
2779 /* Maybe highlight only in selected window. */
2780 && (/* Either show region everywhere. */
2781 highlight_nonselected_windows
2782 /* Or show region in the selected window. */
2783 || w == XWINDOW (selected_window)
2784 /* Or show the region if we are in the mini-buffer and W is
2785 the window the mini-buffer refers to. */
2786 || (MINI_WINDOW_P (XWINDOW (selected_window))
2787 && WINDOWP (minibuf_selected_window)
2788 && w == XWINDOW (minibuf_selected_window))))
2790 it->region_beg_charpos = min (PT, markpos);
2791 it->region_end_charpos = max (PT, markpos);
2793 else
2794 it->region_beg_charpos = it->region_end_charpos = -1;
2796 /* Get the position at which the redisplay_end_trigger hook should
2797 be run, if it is to be run at all. */
2798 if (MARKERP (w->redisplay_end_trigger)
2799 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2800 it->redisplay_end_trigger_charpos
2801 = marker_position (w->redisplay_end_trigger);
2802 else if (INTEGERP (w->redisplay_end_trigger))
2803 it->redisplay_end_trigger_charpos =
2804 clip_to_bounds (PTRDIFF_MIN, XINT (w->redisplay_end_trigger), PTRDIFF_MAX);
2806 it->tab_width = SANE_TAB_WIDTH (current_buffer);
2808 /* Are lines in the display truncated? */
2809 if (base_face_id != DEFAULT_FACE_ID
2810 || it->w->hscroll
2811 || (! WINDOW_FULL_WIDTH_P (it->w)
2812 && ((!NILP (Vtruncate_partial_width_windows)
2813 && !INTEGERP (Vtruncate_partial_width_windows))
2814 || (INTEGERP (Vtruncate_partial_width_windows)
2815 && (WINDOW_TOTAL_COLS (it->w)
2816 < XINT (Vtruncate_partial_width_windows))))))
2817 it->line_wrap = TRUNCATE;
2818 else if (NILP (BVAR (current_buffer, truncate_lines)))
2819 it->line_wrap = NILP (BVAR (current_buffer, word_wrap))
2820 ? WINDOW_WRAP : WORD_WRAP;
2821 else
2822 it->line_wrap = TRUNCATE;
2824 /* Get dimensions of truncation and continuation glyphs. These are
2825 displayed as fringe bitmaps under X, but we need them for such
2826 frames when the fringes are turned off. But leave the dimensions
2827 zero for tooltip frames, as these glyphs look ugly there and also
2828 sabotage calculations of tooltip dimensions in x-show-tip. */
2829 #ifdef HAVE_WINDOW_SYSTEM
2830 if (!(FRAME_WINDOW_P (it->f)
2831 && FRAMEP (tip_frame)
2832 && it->f == XFRAME (tip_frame)))
2833 #endif
2835 if (it->line_wrap == TRUNCATE)
2837 /* We will need the truncation glyph. */
2838 eassert (it->glyph_row == NULL);
2839 produce_special_glyphs (it, IT_TRUNCATION);
2840 it->truncation_pixel_width = it->pixel_width;
2842 else
2844 /* We will need the continuation glyph. */
2845 eassert (it->glyph_row == NULL);
2846 produce_special_glyphs (it, IT_CONTINUATION);
2847 it->continuation_pixel_width = it->pixel_width;
2851 /* Reset these values to zero because the produce_special_glyphs
2852 above has changed them. */
2853 it->pixel_width = it->ascent = it->descent = 0;
2854 it->phys_ascent = it->phys_descent = 0;
2856 /* Set this after getting the dimensions of truncation and
2857 continuation glyphs, so that we don't produce glyphs when calling
2858 produce_special_glyphs, above. */
2859 it->glyph_row = row;
2860 it->area = TEXT_AREA;
2862 /* Forget any previous info about this row being reversed. */
2863 if (it->glyph_row)
2864 it->glyph_row->reversed_p = 0;
2866 /* Get the dimensions of the display area. The display area
2867 consists of the visible window area plus a horizontally scrolled
2868 part to the left of the window. All x-values are relative to the
2869 start of this total display area. */
2870 if (base_face_id != DEFAULT_FACE_ID)
2872 /* Mode lines, menu bar in terminal frames. */
2873 it->first_visible_x = 0;
2874 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2876 else
2878 it->first_visible_x =
2879 window_hscroll_limited (it->w, it->f) * FRAME_COLUMN_WIDTH (it->f);
2880 it->last_visible_x = (it->first_visible_x
2881 + window_box_width (w, TEXT_AREA));
2883 /* If we truncate lines, leave room for the truncation glyph(s) at
2884 the right margin. Otherwise, leave room for the continuation
2885 glyph(s). Done only if the window has no fringes. Since we
2886 don't know at this point whether there will be any R2L lines in
2887 the window, we reserve space for truncation/continuation glyphs
2888 even if only one of the fringes is absent. */
2889 if (WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
2890 || (it->bidi_p && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0))
2892 if (it->line_wrap == TRUNCATE)
2893 it->last_visible_x -= it->truncation_pixel_width;
2894 else
2895 it->last_visible_x -= it->continuation_pixel_width;
2898 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2899 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2902 /* Leave room for a border glyph. */
2903 if (!FRAME_WINDOW_P (it->f)
2904 && !WINDOW_RIGHTMOST_P (it->w))
2905 it->last_visible_x -= 1;
2907 it->last_visible_y = window_text_bottom_y (w);
2909 /* For mode lines and alike, arrange for the first glyph having a
2910 left box line if the face specifies a box. */
2911 if (base_face_id != DEFAULT_FACE_ID)
2913 struct face *face;
2915 it->face_id = remapped_base_face_id;
2917 /* If we have a boxed mode line, make the first character appear
2918 with a left box line. */
2919 face = FACE_FROM_ID (it->f, remapped_base_face_id);
2920 if (face->box != FACE_NO_BOX)
2921 it->start_of_box_run_p = 1;
2924 /* If a buffer position was specified, set the iterator there,
2925 getting overlays and face properties from that position. */
2926 if (charpos >= BUF_BEG (current_buffer))
2928 it->end_charpos = ZV;
2929 eassert (charpos == BYTE_TO_CHAR (bytepos));
2930 IT_CHARPOS (*it) = charpos;
2931 IT_BYTEPOS (*it) = bytepos;
2933 /* We will rely on `reseat' to set this up properly, via
2934 handle_face_prop. */
2935 it->face_id = it->base_face_id;
2937 it->start = it->current;
2938 /* Do we need to reorder bidirectional text? Not if this is a
2939 unibyte buffer: by definition, none of the single-byte
2940 characters are strong R2L, so no reordering is needed. And
2941 bidi.c doesn't support unibyte buffers anyway. Also, don't
2942 reorder while we are loading loadup.el, since the tables of
2943 character properties needed for reordering are not yet
2944 available. */
2945 it->bidi_p =
2946 NILP (Vpurify_flag)
2947 && !NILP (BVAR (current_buffer, bidi_display_reordering))
2948 && it->multibyte_p;
2950 /* If we are to reorder bidirectional text, init the bidi
2951 iterator. */
2952 if (it->bidi_p)
2954 /* Note the paragraph direction that this buffer wants to
2955 use. */
2956 if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
2957 Qleft_to_right))
2958 it->paragraph_embedding = L2R;
2959 else if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
2960 Qright_to_left))
2961 it->paragraph_embedding = R2L;
2962 else
2963 it->paragraph_embedding = NEUTRAL_DIR;
2964 bidi_unshelve_cache (NULL, 0);
2965 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
2966 &it->bidi_it);
2969 /* Compute faces etc. */
2970 reseat (it, it->current.pos, 1);
2973 CHECK_IT (it);
2977 /* Initialize IT for the display of window W with window start POS. */
2979 void
2980 start_display (struct it *it, struct window *w, struct text_pos pos)
2982 struct glyph_row *row;
2983 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2985 row = w->desired_matrix->rows + first_vpos;
2986 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2987 it->first_vpos = first_vpos;
2989 /* Don't reseat to previous visible line start if current start
2990 position is in a string or image. */
2991 if (it->method == GET_FROM_BUFFER && it->line_wrap != TRUNCATE)
2993 int start_at_line_beg_p;
2994 int first_y = it->current_y;
2996 /* If window start is not at a line start, skip forward to POS to
2997 get the correct continuation lines width. */
2998 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2999 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
3000 if (!start_at_line_beg_p)
3002 int new_x;
3004 reseat_at_previous_visible_line_start (it);
3005 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
3007 new_x = it->current_x + it->pixel_width;
3009 /* If lines are continued, this line may end in the middle
3010 of a multi-glyph character (e.g. a control character
3011 displayed as \003, or in the middle of an overlay
3012 string). In this case move_it_to above will not have
3013 taken us to the start of the continuation line but to the
3014 end of the continued line. */
3015 if (it->current_x > 0
3016 && it->line_wrap != TRUNCATE /* Lines are continued. */
3017 && (/* And glyph doesn't fit on the line. */
3018 new_x > it->last_visible_x
3019 /* Or it fits exactly and we're on a window
3020 system frame. */
3021 || (new_x == it->last_visible_x
3022 && FRAME_WINDOW_P (it->f)
3023 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
3024 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
3025 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
3027 if ((it->current.dpvec_index >= 0
3028 || it->current.overlay_string_index >= 0)
3029 /* If we are on a newline from a display vector or
3030 overlay string, then we are already at the end of
3031 a screen line; no need to go to the next line in
3032 that case, as this line is not really continued.
3033 (If we do go to the next line, C-e will not DTRT.) */
3034 && it->c != '\n')
3036 set_iterator_to_next (it, 1);
3037 move_it_in_display_line_to (it, -1, -1, 0);
3040 it->continuation_lines_width += it->current_x;
3042 /* If the character at POS is displayed via a display
3043 vector, move_it_to above stops at the final glyph of
3044 IT->dpvec. To make the caller redisplay that character
3045 again (a.k.a. start at POS), we need to reset the
3046 dpvec_index to the beginning of IT->dpvec. */
3047 else if (it->current.dpvec_index >= 0)
3048 it->current.dpvec_index = 0;
3050 /* We're starting a new display line, not affected by the
3051 height of the continued line, so clear the appropriate
3052 fields in the iterator structure. */
3053 it->max_ascent = it->max_descent = 0;
3054 it->max_phys_ascent = it->max_phys_descent = 0;
3056 it->current_y = first_y;
3057 it->vpos = 0;
3058 it->current_x = it->hpos = 0;
3064 /* Return 1 if POS is a position in ellipses displayed for invisible
3065 text. W is the window we display, for text property lookup. */
3067 static int
3068 in_ellipses_for_invisible_text_p (struct display_pos *pos, struct window *w)
3070 Lisp_Object prop, window;
3071 int ellipses_p = 0;
3072 ptrdiff_t charpos = CHARPOS (pos->pos);
3074 /* If POS specifies a position in a display vector, this might
3075 be for an ellipsis displayed for invisible text. We won't
3076 get the iterator set up for delivering that ellipsis unless
3077 we make sure that it gets aware of the invisible text. */
3078 if (pos->dpvec_index >= 0
3079 && pos->overlay_string_index < 0
3080 && CHARPOS (pos->string_pos) < 0
3081 && charpos > BEGV
3082 && (XSETWINDOW (window, w),
3083 prop = Fget_char_property (make_number (charpos),
3084 Qinvisible, window),
3085 !TEXT_PROP_MEANS_INVISIBLE (prop)))
3087 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
3088 window);
3089 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
3092 return ellipses_p;
3096 /* Initialize IT for stepping through current_buffer in window W,
3097 starting at position POS that includes overlay string and display
3098 vector/ control character translation position information. Value
3099 is zero if there are overlay strings with newlines at POS. */
3101 static int
3102 init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos)
3104 ptrdiff_t charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
3105 int i, overlay_strings_with_newlines = 0;
3107 /* If POS specifies a position in a display vector, this might
3108 be for an ellipsis displayed for invisible text. We won't
3109 get the iterator set up for delivering that ellipsis unless
3110 we make sure that it gets aware of the invisible text. */
3111 if (in_ellipses_for_invisible_text_p (pos, w))
3113 --charpos;
3114 bytepos = 0;
3117 /* Keep in mind: the call to reseat in init_iterator skips invisible
3118 text, so we might end up at a position different from POS. This
3119 is only a problem when POS is a row start after a newline and an
3120 overlay starts there with an after-string, and the overlay has an
3121 invisible property. Since we don't skip invisible text in
3122 display_line and elsewhere immediately after consuming the
3123 newline before the row start, such a POS will not be in a string,
3124 but the call to init_iterator below will move us to the
3125 after-string. */
3126 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
3128 /* This only scans the current chunk -- it should scan all chunks.
3129 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
3130 to 16 in 22.1 to make this a lesser problem. */
3131 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
3133 const char *s = SSDATA (it->overlay_strings[i]);
3134 const char *e = s + SBYTES (it->overlay_strings[i]);
3136 while (s < e && *s != '\n')
3137 ++s;
3139 if (s < e)
3141 overlay_strings_with_newlines = 1;
3142 break;
3146 /* If position is within an overlay string, set up IT to the right
3147 overlay string. */
3148 if (pos->overlay_string_index >= 0)
3150 int relative_index;
3152 /* If the first overlay string happens to have a `display'
3153 property for an image, the iterator will be set up for that
3154 image, and we have to undo that setup first before we can
3155 correct the overlay string index. */
3156 if (it->method == GET_FROM_IMAGE)
3157 pop_it (it);
3159 /* We already have the first chunk of overlay strings in
3160 IT->overlay_strings. Load more until the one for
3161 pos->overlay_string_index is in IT->overlay_strings. */
3162 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
3164 ptrdiff_t n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
3165 it->current.overlay_string_index = 0;
3166 while (n--)
3168 load_overlay_strings (it, 0);
3169 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
3173 it->current.overlay_string_index = pos->overlay_string_index;
3174 relative_index = (it->current.overlay_string_index
3175 % OVERLAY_STRING_CHUNK_SIZE);
3176 it->string = it->overlay_strings[relative_index];
3177 eassert (STRINGP (it->string));
3178 it->current.string_pos = pos->string_pos;
3179 it->method = GET_FROM_STRING;
3180 it->end_charpos = SCHARS (it->string);
3181 /* Set up the bidi iterator for this overlay string. */
3182 if (it->bidi_p)
3184 it->bidi_it.string.lstring = it->string;
3185 it->bidi_it.string.s = NULL;
3186 it->bidi_it.string.schars = SCHARS (it->string);
3187 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
3188 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
3189 it->bidi_it.string.unibyte = !it->multibyte_p;
3190 it->bidi_it.w = it->w;
3191 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3192 FRAME_WINDOW_P (it->f), &it->bidi_it);
3194 /* Synchronize the state of the bidi iterator with
3195 pos->string_pos. For any string position other than
3196 zero, this will be done automagically when we resume
3197 iteration over the string and get_visually_first_element
3198 is called. But if string_pos is zero, and the string is
3199 to be reordered for display, we need to resync manually,
3200 since it could be that the iteration state recorded in
3201 pos ended at string_pos of 0 moving backwards in string. */
3202 if (CHARPOS (pos->string_pos) == 0)
3204 get_visually_first_element (it);
3205 if (IT_STRING_CHARPOS (*it) != 0)
3206 do {
3207 /* Paranoia. */
3208 eassert (it->bidi_it.charpos < it->bidi_it.string.schars);
3209 bidi_move_to_visually_next (&it->bidi_it);
3210 } while (it->bidi_it.charpos != 0);
3212 eassert (IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
3213 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos);
3217 if (CHARPOS (pos->string_pos) >= 0)
3219 /* Recorded position is not in an overlay string, but in another
3220 string. This can only be a string from a `display' property.
3221 IT should already be filled with that string. */
3222 it->current.string_pos = pos->string_pos;
3223 eassert (STRINGP (it->string));
3224 if (it->bidi_p)
3225 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3226 FRAME_WINDOW_P (it->f), &it->bidi_it);
3229 /* Restore position in display vector translations, control
3230 character translations or ellipses. */
3231 if (pos->dpvec_index >= 0)
3233 if (it->dpvec == NULL)
3234 get_next_display_element (it);
3235 eassert (it->dpvec && it->current.dpvec_index == 0);
3236 it->current.dpvec_index = pos->dpvec_index;
3239 CHECK_IT (it);
3240 return !overlay_strings_with_newlines;
3244 /* Initialize IT for stepping through current_buffer in window W
3245 starting at ROW->start. */
3247 static void
3248 init_to_row_start (struct it *it, struct window *w, struct glyph_row *row)
3250 init_from_display_pos (it, w, &row->start);
3251 it->start = row->start;
3252 it->continuation_lines_width = row->continuation_lines_width;
3253 CHECK_IT (it);
3257 /* Initialize IT for stepping through current_buffer in window W
3258 starting in the line following ROW, i.e. starting at ROW->end.
3259 Value is zero if there are overlay strings with newlines at ROW's
3260 end position. */
3262 static int
3263 init_to_row_end (struct it *it, struct window *w, struct glyph_row *row)
3265 int success = 0;
3267 if (init_from_display_pos (it, w, &row->end))
3269 if (row->continued_p)
3270 it->continuation_lines_width
3271 = row->continuation_lines_width + row->pixel_width;
3272 CHECK_IT (it);
3273 success = 1;
3276 return success;
3282 /***********************************************************************
3283 Text properties
3284 ***********************************************************************/
3286 /* Called when IT reaches IT->stop_charpos. Handle text property and
3287 overlay changes. Set IT->stop_charpos to the next position where
3288 to stop. */
3290 static void
3291 handle_stop (struct it *it)
3293 enum prop_handled handled;
3294 int handle_overlay_change_p;
3295 struct props *p;
3297 it->dpvec = NULL;
3298 it->current.dpvec_index = -1;
3299 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
3300 it->ignore_overlay_strings_at_pos_p = 0;
3301 it->ellipsis_p = 0;
3303 /* Use face of preceding text for ellipsis (if invisible) */
3304 if (it->selective_display_ellipsis_p)
3305 it->saved_face_id = it->face_id;
3309 handled = HANDLED_NORMALLY;
3311 /* Call text property handlers. */
3312 for (p = it_props; p->handler; ++p)
3314 handled = p->handler (it);
3316 if (handled == HANDLED_RECOMPUTE_PROPS)
3317 break;
3318 else if (handled == HANDLED_RETURN)
3320 /* We still want to show before and after strings from
3321 overlays even if the actual buffer text is replaced. */
3322 if (!handle_overlay_change_p
3323 || it->sp > 1
3324 /* Don't call get_overlay_strings_1 if we already
3325 have overlay strings loaded, because doing so
3326 will load them again and push the iterator state
3327 onto the stack one more time, which is not
3328 expected by the rest of the code that processes
3329 overlay strings. */
3330 || (it->current.overlay_string_index < 0
3331 ? !get_overlay_strings_1 (it, 0, 0)
3332 : 0))
3334 if (it->ellipsis_p)
3335 setup_for_ellipsis (it, 0);
3336 /* When handling a display spec, we might load an
3337 empty string. In that case, discard it here. We
3338 used to discard it in handle_single_display_spec,
3339 but that causes get_overlay_strings_1, above, to
3340 ignore overlay strings that we must check. */
3341 if (STRINGP (it->string) && !SCHARS (it->string))
3342 pop_it (it);
3343 return;
3345 else if (STRINGP (it->string) && !SCHARS (it->string))
3346 pop_it (it);
3347 else
3349 it->ignore_overlay_strings_at_pos_p = 1;
3350 it->string_from_display_prop_p = 0;
3351 it->from_disp_prop_p = 0;
3352 handle_overlay_change_p = 0;
3354 handled = HANDLED_RECOMPUTE_PROPS;
3355 break;
3357 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
3358 handle_overlay_change_p = 0;
3361 if (handled != HANDLED_RECOMPUTE_PROPS)
3363 /* Don't check for overlay strings below when set to deliver
3364 characters from a display vector. */
3365 if (it->method == GET_FROM_DISPLAY_VECTOR)
3366 handle_overlay_change_p = 0;
3368 /* Handle overlay changes.
3369 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
3370 if it finds overlays. */
3371 if (handle_overlay_change_p)
3372 handled = handle_overlay_change (it);
3375 if (it->ellipsis_p)
3377 setup_for_ellipsis (it, 0);
3378 break;
3381 while (handled == HANDLED_RECOMPUTE_PROPS);
3383 /* Determine where to stop next. */
3384 if (handled == HANDLED_NORMALLY)
3385 compute_stop_pos (it);
3389 /* Compute IT->stop_charpos from text property and overlay change
3390 information for IT's current position. */
3392 static void
3393 compute_stop_pos (struct it *it)
3395 register INTERVAL iv, next_iv;
3396 Lisp_Object object, limit, position;
3397 ptrdiff_t charpos, bytepos;
3399 if (STRINGP (it->string))
3401 /* Strings are usually short, so don't limit the search for
3402 properties. */
3403 it->stop_charpos = it->end_charpos;
3404 object = it->string;
3405 limit = Qnil;
3406 charpos = IT_STRING_CHARPOS (*it);
3407 bytepos = IT_STRING_BYTEPOS (*it);
3409 else
3411 ptrdiff_t pos;
3413 /* If end_charpos is out of range for some reason, such as a
3414 misbehaving display function, rationalize it (Bug#5984). */
3415 if (it->end_charpos > ZV)
3416 it->end_charpos = ZV;
3417 it->stop_charpos = it->end_charpos;
3419 /* If next overlay change is in front of the current stop pos
3420 (which is IT->end_charpos), stop there. Note: value of
3421 next_overlay_change is point-max if no overlay change
3422 follows. */
3423 charpos = IT_CHARPOS (*it);
3424 bytepos = IT_BYTEPOS (*it);
3425 pos = next_overlay_change (charpos);
3426 if (pos < it->stop_charpos)
3427 it->stop_charpos = pos;
3429 /* If showing the region, we have to stop at the region
3430 start or end because the face might change there. */
3431 if (it->region_beg_charpos > 0)
3433 if (IT_CHARPOS (*it) < it->region_beg_charpos)
3434 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
3435 else if (IT_CHARPOS (*it) < it->region_end_charpos)
3436 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
3439 /* Set up variables for computing the stop position from text
3440 property changes. */
3441 XSETBUFFER (object, current_buffer);
3442 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3445 /* Get the interval containing IT's position. Value is a null
3446 interval if there isn't such an interval. */
3447 position = make_number (charpos);
3448 iv = validate_interval_range (object, &position, &position, 0);
3449 if (iv)
3451 Lisp_Object values_here[LAST_PROP_IDX];
3452 struct props *p;
3454 /* Get properties here. */
3455 for (p = it_props; p->handler; ++p)
3456 values_here[p->idx] = textget (iv->plist, *p->name);
3458 /* Look for an interval following iv that has different
3459 properties. */
3460 for (next_iv = next_interval (iv);
3461 (next_iv
3462 && (NILP (limit)
3463 || XFASTINT (limit) > next_iv->position));
3464 next_iv = next_interval (next_iv))
3466 for (p = it_props; p->handler; ++p)
3468 Lisp_Object new_value;
3470 new_value = textget (next_iv->plist, *p->name);
3471 if (!EQ (values_here[p->idx], new_value))
3472 break;
3475 if (p->handler)
3476 break;
3479 if (next_iv)
3481 if (INTEGERP (limit)
3482 && next_iv->position >= XFASTINT (limit))
3483 /* No text property change up to limit. */
3484 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3485 else
3486 /* Text properties change in next_iv. */
3487 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3491 if (it->cmp_it.id < 0)
3493 ptrdiff_t stoppos = it->end_charpos;
3495 if (it->bidi_p && it->bidi_it.scan_dir < 0)
3496 stoppos = -1;
3497 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
3498 stoppos, it->string);
3501 eassert (STRINGP (it->string)
3502 || (it->stop_charpos >= BEGV
3503 && it->stop_charpos >= IT_CHARPOS (*it)));
3507 /* Return the position of the next overlay change after POS in
3508 current_buffer. Value is point-max if no overlay change
3509 follows. This is like `next-overlay-change' but doesn't use
3510 xmalloc. */
3512 static ptrdiff_t
3513 next_overlay_change (ptrdiff_t pos)
3515 ptrdiff_t i, noverlays;
3516 ptrdiff_t endpos;
3517 Lisp_Object *overlays;
3519 /* Get all overlays at the given position. */
3520 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
3522 /* If any of these overlays ends before endpos,
3523 use its ending point instead. */
3524 for (i = 0; i < noverlays; ++i)
3526 Lisp_Object oend;
3527 ptrdiff_t oendpos;
3529 oend = OVERLAY_END (overlays[i]);
3530 oendpos = OVERLAY_POSITION (oend);
3531 endpos = min (endpos, oendpos);
3534 return endpos;
3537 /* How many characters forward to search for a display property or
3538 display string. Searching too far forward makes the bidi display
3539 sluggish, especially in small windows. */
3540 #define MAX_DISP_SCAN 250
3542 /* Return the character position of a display string at or after
3543 position specified by POSITION. If no display string exists at or
3544 after POSITION, return ZV. A display string is either an overlay
3545 with `display' property whose value is a string, or a `display'
3546 text property whose value is a string. STRING is data about the
3547 string to iterate; if STRING->lstring is nil, we are iterating a
3548 buffer. FRAME_WINDOW_P is non-zero when we are displaying a window
3549 on a GUI frame. DISP_PROP is set to zero if we searched
3550 MAX_DISP_SCAN characters forward without finding any display
3551 strings, non-zero otherwise. It is set to 2 if the display string
3552 uses any kind of `(space ...)' spec that will produce a stretch of
3553 white space in the text area. */
3554 ptrdiff_t
3555 compute_display_string_pos (struct text_pos *position,
3556 struct bidi_string_data *string,
3557 struct window *w,
3558 int frame_window_p, int *disp_prop)
3560 /* OBJECT = nil means current buffer. */
3561 Lisp_Object object, object1;
3562 Lisp_Object pos, spec, limpos;
3563 int string_p = (string && (STRINGP (string->lstring) || string->s));
3564 ptrdiff_t eob = string_p ? string->schars : ZV;
3565 ptrdiff_t begb = string_p ? 0 : BEGV;
3566 ptrdiff_t bufpos, charpos = CHARPOS (*position);
3567 ptrdiff_t lim =
3568 (charpos < eob - MAX_DISP_SCAN) ? charpos + MAX_DISP_SCAN : eob;
3569 struct text_pos tpos;
3570 int rv = 0;
3572 if (string && STRINGP (string->lstring))
3573 object1 = object = string->lstring;
3574 else if (w && !string_p)
3576 XSETWINDOW (object, w);
3577 object1 = Qnil;
3579 else
3580 object1 = object = Qnil;
3582 *disp_prop = 1;
3584 if (charpos >= eob
3585 /* We don't support display properties whose values are strings
3586 that have display string properties. */
3587 || string->from_disp_str
3588 /* C strings cannot have display properties. */
3589 || (string->s && !STRINGP (object)))
3591 *disp_prop = 0;
3592 return eob;
3595 /* If the character at CHARPOS is where the display string begins,
3596 return CHARPOS. */
3597 pos = make_number (charpos);
3598 if (STRINGP (object))
3599 bufpos = string->bufpos;
3600 else
3601 bufpos = charpos;
3602 tpos = *position;
3603 if (!NILP (spec = Fget_char_property (pos, Qdisplay, object))
3604 && (charpos <= begb
3605 || !EQ (Fget_char_property (make_number (charpos - 1), Qdisplay,
3606 object),
3607 spec))
3608 && (rv = handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
3609 frame_window_p)))
3611 if (rv == 2)
3612 *disp_prop = 2;
3613 return charpos;
3616 /* Look forward for the first character with a `display' property
3617 that will replace the underlying text when displayed. */
3618 limpos = make_number (lim);
3619 do {
3620 pos = Fnext_single_char_property_change (pos, Qdisplay, object1, limpos);
3621 CHARPOS (tpos) = XFASTINT (pos);
3622 if (CHARPOS (tpos) >= lim)
3624 *disp_prop = 0;
3625 break;
3627 if (STRINGP (object))
3628 BYTEPOS (tpos) = string_char_to_byte (object, CHARPOS (tpos));
3629 else
3630 BYTEPOS (tpos) = CHAR_TO_BYTE (CHARPOS (tpos));
3631 spec = Fget_char_property (pos, Qdisplay, object);
3632 if (!STRINGP (object))
3633 bufpos = CHARPOS (tpos);
3634 } while (NILP (spec)
3635 || !(rv = handle_display_spec (NULL, spec, object, Qnil, &tpos,
3636 bufpos, frame_window_p)));
3637 if (rv == 2)
3638 *disp_prop = 2;
3640 return CHARPOS (tpos);
3643 /* Return the character position of the end of the display string that
3644 started at CHARPOS. If there's no display string at CHARPOS,
3645 return -1. A display string is either an overlay with `display'
3646 property whose value is a string or a `display' text property whose
3647 value is a string. */
3648 ptrdiff_t
3649 compute_display_string_end (ptrdiff_t charpos, struct bidi_string_data *string)
3651 /* OBJECT = nil means current buffer. */
3652 Lisp_Object object =
3653 (string && STRINGP (string->lstring)) ? string->lstring : Qnil;
3654 Lisp_Object pos = make_number (charpos);
3655 ptrdiff_t eob =
3656 (STRINGP (object) || (string && string->s)) ? string->schars : ZV;
3658 if (charpos >= eob || (string->s && !STRINGP (object)))
3659 return eob;
3661 /* It could happen that the display property or overlay was removed
3662 since we found it in compute_display_string_pos above. One way
3663 this can happen is if JIT font-lock was called (through
3664 handle_fontified_prop), and jit-lock-functions remove text
3665 properties or overlays from the portion of buffer that includes
3666 CHARPOS. Muse mode is known to do that, for example. In this
3667 case, we return -1 to the caller, to signal that no display
3668 string is actually present at CHARPOS. See bidi_fetch_char for
3669 how this is handled.
3671 An alternative would be to never look for display properties past
3672 it->stop_charpos. But neither compute_display_string_pos nor
3673 bidi_fetch_char that calls it know or care where the next
3674 stop_charpos is. */
3675 if (NILP (Fget_char_property (pos, Qdisplay, object)))
3676 return -1;
3678 /* Look forward for the first character where the `display' property
3679 changes. */
3680 pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil);
3682 return XFASTINT (pos);
3687 /***********************************************************************
3688 Fontification
3689 ***********************************************************************/
3691 /* Handle changes in the `fontified' property of the current buffer by
3692 calling hook functions from Qfontification_functions to fontify
3693 regions of text. */
3695 static enum prop_handled
3696 handle_fontified_prop (struct it *it)
3698 Lisp_Object prop, pos;
3699 enum prop_handled handled = HANDLED_NORMALLY;
3701 if (!NILP (Vmemory_full))
3702 return handled;
3704 /* Get the value of the `fontified' property at IT's current buffer
3705 position. (The `fontified' property doesn't have a special
3706 meaning in strings.) If the value is nil, call functions from
3707 Qfontification_functions. */
3708 if (!STRINGP (it->string)
3709 && it->s == NULL
3710 && !NILP (Vfontification_functions)
3711 && !NILP (Vrun_hooks)
3712 && (pos = make_number (IT_CHARPOS (*it)),
3713 prop = Fget_char_property (pos, Qfontified, Qnil),
3714 /* Ignore the special cased nil value always present at EOB since
3715 no amount of fontifying will be able to change it. */
3716 NILP (prop) && IT_CHARPOS (*it) < Z))
3718 ptrdiff_t count = SPECPDL_INDEX ();
3719 Lisp_Object val;
3720 struct buffer *obuf = current_buffer;
3721 int begv = BEGV, zv = ZV;
3722 int old_clip_changed = current_buffer->clip_changed;
3724 val = Vfontification_functions;
3725 specbind (Qfontification_functions, Qnil);
3727 eassert (it->end_charpos == ZV);
3729 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3730 safe_call1 (val, pos);
3731 else
3733 Lisp_Object fns, fn;
3734 struct gcpro gcpro1, gcpro2;
3736 fns = Qnil;
3737 GCPRO2 (val, fns);
3739 for (; CONSP (val); val = XCDR (val))
3741 fn = XCAR (val);
3743 if (EQ (fn, Qt))
3745 /* A value of t indicates this hook has a local
3746 binding; it means to run the global binding too.
3747 In a global value, t should not occur. If it
3748 does, we must ignore it to avoid an endless
3749 loop. */
3750 for (fns = Fdefault_value (Qfontification_functions);
3751 CONSP (fns);
3752 fns = XCDR (fns))
3754 fn = XCAR (fns);
3755 if (!EQ (fn, Qt))
3756 safe_call1 (fn, pos);
3759 else
3760 safe_call1 (fn, pos);
3763 UNGCPRO;
3766 unbind_to (count, Qnil);
3768 /* Fontification functions routinely call `save-restriction'.
3769 Normally, this tags clip_changed, which can confuse redisplay
3770 (see discussion in Bug#6671). Since we don't perform any
3771 special handling of fontification changes in the case where
3772 `save-restriction' isn't called, there's no point doing so in
3773 this case either. So, if the buffer's restrictions are
3774 actually left unchanged, reset clip_changed. */
3775 if (obuf == current_buffer)
3777 if (begv == BEGV && zv == ZV)
3778 current_buffer->clip_changed = old_clip_changed;
3780 /* There isn't much we can reasonably do to protect against
3781 misbehaving fontification, but here's a fig leaf. */
3782 else if (BUFFER_LIVE_P (obuf))
3783 set_buffer_internal_1 (obuf);
3785 /* The fontification code may have added/removed text.
3786 It could do even a lot worse, but let's at least protect against
3787 the most obvious case where only the text past `pos' gets changed',
3788 as is/was done in grep.el where some escapes sequences are turned
3789 into face properties (bug#7876). */
3790 it->end_charpos = ZV;
3792 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3793 something. This avoids an endless loop if they failed to
3794 fontify the text for which reason ever. */
3795 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3796 handled = HANDLED_RECOMPUTE_PROPS;
3799 return handled;
3804 /***********************************************************************
3805 Faces
3806 ***********************************************************************/
3808 /* Set up iterator IT from face properties at its current position.
3809 Called from handle_stop. */
3811 static enum prop_handled
3812 handle_face_prop (struct it *it)
3814 int new_face_id;
3815 ptrdiff_t next_stop;
3817 if (!STRINGP (it->string))
3819 new_face_id
3820 = face_at_buffer_position (it->w,
3821 IT_CHARPOS (*it),
3822 it->region_beg_charpos,
3823 it->region_end_charpos,
3824 &next_stop,
3825 (IT_CHARPOS (*it)
3826 + TEXT_PROP_DISTANCE_LIMIT),
3827 0, it->base_face_id);
3829 /* Is this a start of a run of characters with box face?
3830 Caveat: this can be called for a freshly initialized
3831 iterator; face_id is -1 in this case. We know that the new
3832 face will not change until limit, i.e. if the new face has a
3833 box, all characters up to limit will have one. But, as
3834 usual, we don't know whether limit is really the end. */
3835 if (new_face_id != it->face_id)
3837 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3838 /* If it->face_id is -1, old_face below will be NULL, see
3839 the definition of FACE_FROM_ID. This will happen if this
3840 is the initial call that gets the face. */
3841 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3843 /* If the value of face_id of the iterator is -1, we have to
3844 look in front of IT's position and see whether there is a
3845 face there that's different from new_face_id. */
3846 if (!old_face && IT_CHARPOS (*it) > BEG)
3848 int prev_face_id = face_before_it_pos (it);
3850 old_face = FACE_FROM_ID (it->f, prev_face_id);
3853 /* If the new face has a box, but the old face does not,
3854 this is the start of a run of characters with box face,
3855 i.e. this character has a shadow on the left side. */
3856 it->start_of_box_run_p = (new_face->box != FACE_NO_BOX
3857 && (old_face == NULL || !old_face->box));
3858 it->face_box_p = new_face->box != FACE_NO_BOX;
3861 else
3863 int base_face_id;
3864 ptrdiff_t bufpos;
3865 int i;
3866 Lisp_Object from_overlay
3867 = (it->current.overlay_string_index >= 0
3868 ? it->string_overlays[it->current.overlay_string_index
3869 % OVERLAY_STRING_CHUNK_SIZE]
3870 : Qnil);
3872 /* See if we got to this string directly or indirectly from
3873 an overlay property. That includes the before-string or
3874 after-string of an overlay, strings in display properties
3875 provided by an overlay, their text properties, etc.
3877 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
3878 if (! NILP (from_overlay))
3879 for (i = it->sp - 1; i >= 0; i--)
3881 if (it->stack[i].current.overlay_string_index >= 0)
3882 from_overlay
3883 = it->string_overlays[it->stack[i].current.overlay_string_index
3884 % OVERLAY_STRING_CHUNK_SIZE];
3885 else if (! NILP (it->stack[i].from_overlay))
3886 from_overlay = it->stack[i].from_overlay;
3888 if (!NILP (from_overlay))
3889 break;
3892 if (! NILP (from_overlay))
3894 bufpos = IT_CHARPOS (*it);
3895 /* For a string from an overlay, the base face depends
3896 only on text properties and ignores overlays. */
3897 base_face_id
3898 = face_for_overlay_string (it->w,
3899 IT_CHARPOS (*it),
3900 it->region_beg_charpos,
3901 it->region_end_charpos,
3902 &next_stop,
3903 (IT_CHARPOS (*it)
3904 + TEXT_PROP_DISTANCE_LIMIT),
3906 from_overlay);
3908 else
3910 bufpos = 0;
3912 /* For strings from a `display' property, use the face at
3913 IT's current buffer position as the base face to merge
3914 with, so that overlay strings appear in the same face as
3915 surrounding text, unless they specify their own faces.
3916 For strings from wrap-prefix and line-prefix properties,
3917 use the default face, possibly remapped via
3918 Vface_remapping_alist. */
3919 base_face_id = it->string_from_prefix_prop_p
3920 ? (!NILP (Vface_remapping_alist)
3921 ? lookup_basic_face (it->f, DEFAULT_FACE_ID)
3922 : DEFAULT_FACE_ID)
3923 : underlying_face_id (it);
3926 new_face_id = face_at_string_position (it->w,
3927 it->string,
3928 IT_STRING_CHARPOS (*it),
3929 bufpos,
3930 it->region_beg_charpos,
3931 it->region_end_charpos,
3932 &next_stop,
3933 base_face_id, 0);
3935 /* Is this a start of a run of characters with box? Caveat:
3936 this can be called for a freshly allocated iterator; face_id
3937 is -1 is this case. We know that the new face will not
3938 change until the next check pos, i.e. if the new face has a
3939 box, all characters up to that position will have a
3940 box. But, as usual, we don't know whether that position
3941 is really the end. */
3942 if (new_face_id != it->face_id)
3944 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3945 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3947 /* If new face has a box but old face hasn't, this is the
3948 start of a run of characters with box, i.e. it has a
3949 shadow on the left side. */
3950 it->start_of_box_run_p
3951 = new_face->box && (old_face == NULL || !old_face->box);
3952 it->face_box_p = new_face->box != FACE_NO_BOX;
3956 it->face_id = new_face_id;
3957 return HANDLED_NORMALLY;
3961 /* Return the ID of the face ``underlying'' IT's current position,
3962 which is in a string. If the iterator is associated with a
3963 buffer, return the face at IT's current buffer position.
3964 Otherwise, use the iterator's base_face_id. */
3966 static int
3967 underlying_face_id (struct it *it)
3969 int face_id = it->base_face_id, i;
3971 eassert (STRINGP (it->string));
3973 for (i = it->sp - 1; i >= 0; --i)
3974 if (NILP (it->stack[i].string))
3975 face_id = it->stack[i].face_id;
3977 return face_id;
3981 /* Compute the face one character before or after the current position
3982 of IT, in the visual order. BEFORE_P non-zero means get the face
3983 in front (to the left in L2R paragraphs, to the right in R2L
3984 paragraphs) of IT's screen position. Value is the ID of the face. */
3986 static int
3987 face_before_or_after_it_pos (struct it *it, int before_p)
3989 int face_id, limit;
3990 ptrdiff_t next_check_charpos;
3991 struct it it_copy;
3992 void *it_copy_data = NULL;
3994 eassert (it->s == NULL);
3996 if (STRINGP (it->string))
3998 ptrdiff_t bufpos, charpos;
3999 int base_face_id;
4001 /* No face change past the end of the string (for the case
4002 we are padding with spaces). No face change before the
4003 string start. */
4004 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
4005 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
4006 return it->face_id;
4008 if (!it->bidi_p)
4010 /* Set charpos to the position before or after IT's current
4011 position, in the logical order, which in the non-bidi
4012 case is the same as the visual order. */
4013 if (before_p)
4014 charpos = IT_STRING_CHARPOS (*it) - 1;
4015 else if (it->what == IT_COMPOSITION)
4016 /* For composition, we must check the character after the
4017 composition. */
4018 charpos = IT_STRING_CHARPOS (*it) + it->cmp_it.nchars;
4019 else
4020 charpos = IT_STRING_CHARPOS (*it) + 1;
4022 else
4024 if (before_p)
4026 /* With bidi iteration, the character before the current
4027 in the visual order cannot be found by simple
4028 iteration, because "reverse" reordering is not
4029 supported. Instead, we need to use the move_it_*
4030 family of functions. */
4031 /* Ignore face changes before the first visible
4032 character on this display line. */
4033 if (it->current_x <= it->first_visible_x)
4034 return it->face_id;
4035 SAVE_IT (it_copy, *it, it_copy_data);
4036 /* Implementation note: Since move_it_in_display_line
4037 works in the iterator geometry, and thinks the first
4038 character is always the leftmost, even in R2L lines,
4039 we don't need to distinguish between the R2L and L2R
4040 cases here. */
4041 move_it_in_display_line (&it_copy, SCHARS (it_copy.string),
4042 it_copy.current_x - 1, MOVE_TO_X);
4043 charpos = IT_STRING_CHARPOS (it_copy);
4044 RESTORE_IT (it, it, it_copy_data);
4046 else
4048 /* Set charpos to the string position of the character
4049 that comes after IT's current position in the visual
4050 order. */
4051 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
4053 it_copy = *it;
4054 while (n--)
4055 bidi_move_to_visually_next (&it_copy.bidi_it);
4057 charpos = it_copy.bidi_it.charpos;
4060 eassert (0 <= charpos && charpos <= SCHARS (it->string));
4062 if (it->current.overlay_string_index >= 0)
4063 bufpos = IT_CHARPOS (*it);
4064 else
4065 bufpos = 0;
4067 base_face_id = underlying_face_id (it);
4069 /* Get the face for ASCII, or unibyte. */
4070 face_id = face_at_string_position (it->w,
4071 it->string,
4072 charpos,
4073 bufpos,
4074 it->region_beg_charpos,
4075 it->region_end_charpos,
4076 &next_check_charpos,
4077 base_face_id, 0);
4079 /* Correct the face for charsets different from ASCII. Do it
4080 for the multibyte case only. The face returned above is
4081 suitable for unibyte text if IT->string is unibyte. */
4082 if (STRING_MULTIBYTE (it->string))
4084 struct text_pos pos1 = string_pos (charpos, it->string);
4085 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos1);
4086 int c, len;
4087 struct face *face = FACE_FROM_ID (it->f, face_id);
4089 c = string_char_and_length (p, &len);
4090 face_id = FACE_FOR_CHAR (it->f, face, c, charpos, it->string);
4093 else
4095 struct text_pos pos;
4097 if ((IT_CHARPOS (*it) >= ZV && !before_p)
4098 || (IT_CHARPOS (*it) <= BEGV && before_p))
4099 return it->face_id;
4101 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
4102 pos = it->current.pos;
4104 if (!it->bidi_p)
4106 if (before_p)
4107 DEC_TEXT_POS (pos, it->multibyte_p);
4108 else
4110 if (it->what == IT_COMPOSITION)
4112 /* For composition, we must check the position after
4113 the composition. */
4114 pos.charpos += it->cmp_it.nchars;
4115 pos.bytepos += it->len;
4117 else
4118 INC_TEXT_POS (pos, it->multibyte_p);
4121 else
4123 if (before_p)
4125 /* With bidi iteration, the character before the current
4126 in the visual order cannot be found by simple
4127 iteration, because "reverse" reordering is not
4128 supported. Instead, we need to use the move_it_*
4129 family of functions. */
4130 /* Ignore face changes before the first visible
4131 character on this display line. */
4132 if (it->current_x <= it->first_visible_x)
4133 return it->face_id;
4134 SAVE_IT (it_copy, *it, it_copy_data);
4135 /* Implementation note: Since move_it_in_display_line
4136 works in the iterator geometry, and thinks the first
4137 character is always the leftmost, even in R2L lines,
4138 we don't need to distinguish between the R2L and L2R
4139 cases here. */
4140 move_it_in_display_line (&it_copy, ZV,
4141 it_copy.current_x - 1, MOVE_TO_X);
4142 pos = it_copy.current.pos;
4143 RESTORE_IT (it, it, it_copy_data);
4145 else
4147 /* Set charpos to the buffer position of the character
4148 that comes after IT's current position in the visual
4149 order. */
4150 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
4152 it_copy = *it;
4153 while (n--)
4154 bidi_move_to_visually_next (&it_copy.bidi_it);
4156 SET_TEXT_POS (pos,
4157 it_copy.bidi_it.charpos, it_copy.bidi_it.bytepos);
4160 eassert (BEGV <= CHARPOS (pos) && CHARPOS (pos) <= ZV);
4162 /* Determine face for CHARSET_ASCII, or unibyte. */
4163 face_id = face_at_buffer_position (it->w,
4164 CHARPOS (pos),
4165 it->region_beg_charpos,
4166 it->region_end_charpos,
4167 &next_check_charpos,
4168 limit, 0, -1);
4170 /* Correct the face for charsets different from ASCII. Do it
4171 for the multibyte case only. The face returned above is
4172 suitable for unibyte text if current_buffer is unibyte. */
4173 if (it->multibyte_p)
4175 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
4176 struct face *face = FACE_FROM_ID (it->f, face_id);
4177 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
4181 return face_id;
4186 /***********************************************************************
4187 Invisible text
4188 ***********************************************************************/
4190 /* Set up iterator IT from invisible properties at its current
4191 position. Called from handle_stop. */
4193 static enum prop_handled
4194 handle_invisible_prop (struct it *it)
4196 enum prop_handled handled = HANDLED_NORMALLY;
4197 int invis_p;
4198 Lisp_Object prop;
4200 if (STRINGP (it->string))
4202 Lisp_Object end_charpos, limit, charpos;
4204 /* Get the value of the invisible text property at the
4205 current position. Value will be nil if there is no such
4206 property. */
4207 charpos = make_number (IT_STRING_CHARPOS (*it));
4208 prop = Fget_text_property (charpos, Qinvisible, it->string);
4209 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4211 if (invis_p && IT_STRING_CHARPOS (*it) < it->end_charpos)
4213 /* Record whether we have to display an ellipsis for the
4214 invisible text. */
4215 int display_ellipsis_p = (invis_p == 2);
4216 ptrdiff_t len, endpos;
4218 handled = HANDLED_RECOMPUTE_PROPS;
4220 /* Get the position at which the next visible text can be
4221 found in IT->string, if any. */
4222 endpos = len = SCHARS (it->string);
4223 XSETINT (limit, len);
4226 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
4227 it->string, limit);
4228 if (INTEGERP (end_charpos))
4230 endpos = XFASTINT (end_charpos);
4231 prop = Fget_text_property (end_charpos, Qinvisible, it->string);
4232 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4233 if (invis_p == 2)
4234 display_ellipsis_p = 1;
4237 while (invis_p && endpos < len);
4239 if (display_ellipsis_p)
4240 it->ellipsis_p = 1;
4242 if (endpos < len)
4244 /* Text at END_CHARPOS is visible. Move IT there. */
4245 struct text_pos old;
4246 ptrdiff_t oldpos;
4248 old = it->current.string_pos;
4249 oldpos = CHARPOS (old);
4250 if (it->bidi_p)
4252 if (it->bidi_it.first_elt
4253 && it->bidi_it.charpos < SCHARS (it->string))
4254 bidi_paragraph_init (it->paragraph_embedding,
4255 &it->bidi_it, 1);
4256 /* Bidi-iterate out of the invisible text. */
4259 bidi_move_to_visually_next (&it->bidi_it);
4261 while (oldpos <= it->bidi_it.charpos
4262 && it->bidi_it.charpos < endpos);
4264 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
4265 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
4266 if (IT_CHARPOS (*it) >= endpos)
4267 it->prev_stop = endpos;
4269 else
4271 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
4272 compute_string_pos (&it->current.string_pos, old, it->string);
4275 else
4277 /* The rest of the string is invisible. If this is an
4278 overlay string, proceed with the next overlay string
4279 or whatever comes and return a character from there. */
4280 if (it->current.overlay_string_index >= 0
4281 && !display_ellipsis_p)
4283 next_overlay_string (it);
4284 /* Don't check for overlay strings when we just
4285 finished processing them. */
4286 handled = HANDLED_OVERLAY_STRING_CONSUMED;
4288 else
4290 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
4291 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
4296 else
4298 ptrdiff_t newpos, next_stop, start_charpos, tem;
4299 Lisp_Object pos, overlay;
4301 /* First of all, is there invisible text at this position? */
4302 tem = start_charpos = IT_CHARPOS (*it);
4303 pos = make_number (tem);
4304 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
4305 &overlay);
4306 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4308 /* If we are on invisible text, skip over it. */
4309 if (invis_p && start_charpos < it->end_charpos)
4311 /* Record whether we have to display an ellipsis for the
4312 invisible text. */
4313 int display_ellipsis_p = invis_p == 2;
4315 handled = HANDLED_RECOMPUTE_PROPS;
4317 /* Loop skipping over invisible text. The loop is left at
4318 ZV or with IT on the first char being visible again. */
4321 /* Try to skip some invisible text. Return value is the
4322 position reached which can be equal to where we start
4323 if there is nothing invisible there. This skips both
4324 over invisible text properties and overlays with
4325 invisible property. */
4326 newpos = skip_invisible (tem, &next_stop, ZV, it->window);
4328 /* If we skipped nothing at all we weren't at invisible
4329 text in the first place. If everything to the end of
4330 the buffer was skipped, end the loop. */
4331 if (newpos == tem || newpos >= ZV)
4332 invis_p = 0;
4333 else
4335 /* We skipped some characters but not necessarily
4336 all there are. Check if we ended up on visible
4337 text. Fget_char_property returns the property of
4338 the char before the given position, i.e. if we
4339 get invis_p = 0, this means that the char at
4340 newpos is visible. */
4341 pos = make_number (newpos);
4342 prop = Fget_char_property (pos, Qinvisible, it->window);
4343 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4346 /* If we ended up on invisible text, proceed to
4347 skip starting with next_stop. */
4348 if (invis_p)
4349 tem = next_stop;
4351 /* If there are adjacent invisible texts, don't lose the
4352 second one's ellipsis. */
4353 if (invis_p == 2)
4354 display_ellipsis_p = 1;
4356 while (invis_p);
4358 /* The position newpos is now either ZV or on visible text. */
4359 if (it->bidi_p)
4361 ptrdiff_t bpos = CHAR_TO_BYTE (newpos);
4362 int on_newline =
4363 bpos == ZV_BYTE || FETCH_BYTE (bpos) == '\n';
4364 int after_newline =
4365 newpos <= BEGV || FETCH_BYTE (bpos - 1) == '\n';
4367 /* If the invisible text ends on a newline or on a
4368 character after a newline, we can avoid the costly,
4369 character by character, bidi iteration to NEWPOS, and
4370 instead simply reseat the iterator there. That's
4371 because all bidi reordering information is tossed at
4372 the newline. This is a big win for modes that hide
4373 complete lines, like Outline, Org, etc. */
4374 if (on_newline || after_newline)
4376 struct text_pos tpos;
4377 bidi_dir_t pdir = it->bidi_it.paragraph_dir;
4379 SET_TEXT_POS (tpos, newpos, bpos);
4380 reseat_1 (it, tpos, 0);
4381 /* If we reseat on a newline/ZV, we need to prep the
4382 bidi iterator for advancing to the next character
4383 after the newline/EOB, keeping the current paragraph
4384 direction (so that PRODUCE_GLYPHS does TRT wrt
4385 prepending/appending glyphs to a glyph row). */
4386 if (on_newline)
4388 it->bidi_it.first_elt = 0;
4389 it->bidi_it.paragraph_dir = pdir;
4390 it->bidi_it.ch = (bpos == ZV_BYTE) ? -1 : '\n';
4391 it->bidi_it.nchars = 1;
4392 it->bidi_it.ch_len = 1;
4395 else /* Must use the slow method. */
4397 /* With bidi iteration, the region of invisible text
4398 could start and/or end in the middle of a
4399 non-base embedding level. Therefore, we need to
4400 skip invisible text using the bidi iterator,
4401 starting at IT's current position, until we find
4402 ourselves outside of the invisible text.
4403 Skipping invisible text _after_ bidi iteration
4404 avoids affecting the visual order of the
4405 displayed text when invisible properties are
4406 added or removed. */
4407 if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV)
4409 /* If we were `reseat'ed to a new paragraph,
4410 determine the paragraph base direction. We
4411 need to do it now because
4412 next_element_from_buffer may not have a
4413 chance to do it, if we are going to skip any
4414 text at the beginning, which resets the
4415 FIRST_ELT flag. */
4416 bidi_paragraph_init (it->paragraph_embedding,
4417 &it->bidi_it, 1);
4421 bidi_move_to_visually_next (&it->bidi_it);
4423 while (it->stop_charpos <= it->bidi_it.charpos
4424 && it->bidi_it.charpos < newpos);
4425 IT_CHARPOS (*it) = it->bidi_it.charpos;
4426 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
4427 /* If we overstepped NEWPOS, record its position in
4428 the iterator, so that we skip invisible text if
4429 later the bidi iteration lands us in the
4430 invisible region again. */
4431 if (IT_CHARPOS (*it) >= newpos)
4432 it->prev_stop = newpos;
4435 else
4437 IT_CHARPOS (*it) = newpos;
4438 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
4441 /* If there are before-strings at the start of invisible
4442 text, and the text is invisible because of a text
4443 property, arrange to show before-strings because 20.x did
4444 it that way. (If the text is invisible because of an
4445 overlay property instead of a text property, this is
4446 already handled in the overlay code.) */
4447 if (NILP (overlay)
4448 && get_overlay_strings (it, it->stop_charpos))
4450 handled = HANDLED_RECOMPUTE_PROPS;
4451 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
4453 else if (display_ellipsis_p)
4455 /* Make sure that the glyphs of the ellipsis will get
4456 correct `charpos' values. If we would not update
4457 it->position here, the glyphs would belong to the
4458 last visible character _before_ the invisible
4459 text, which confuses `set_cursor_from_row'.
4461 We use the last invisible position instead of the
4462 first because this way the cursor is always drawn on
4463 the first "." of the ellipsis, whenever PT is inside
4464 the invisible text. Otherwise the cursor would be
4465 placed _after_ the ellipsis when the point is after the
4466 first invisible character. */
4467 if (!STRINGP (it->object))
4469 it->position.charpos = newpos - 1;
4470 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
4472 it->ellipsis_p = 1;
4473 /* Let the ellipsis display before
4474 considering any properties of the following char.
4475 Fixes jasonr@gnu.org 01 Oct 07 bug. */
4476 handled = HANDLED_RETURN;
4481 return handled;
4485 /* Make iterator IT return `...' next.
4486 Replaces LEN characters from buffer. */
4488 static void
4489 setup_for_ellipsis (struct it *it, int len)
4491 /* Use the display table definition for `...'. Invalid glyphs
4492 will be handled by the method returning elements from dpvec. */
4493 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
4495 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
4496 it->dpvec = v->contents;
4497 it->dpend = v->contents + v->header.size;
4499 else
4501 /* Default `...'. */
4502 it->dpvec = default_invis_vector;
4503 it->dpend = default_invis_vector + 3;
4506 it->dpvec_char_len = len;
4507 it->current.dpvec_index = 0;
4508 it->dpvec_face_id = -1;
4510 /* Remember the current face id in case glyphs specify faces.
4511 IT's face is restored in set_iterator_to_next.
4512 saved_face_id was set to preceding char's face in handle_stop. */
4513 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
4514 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
4516 it->method = GET_FROM_DISPLAY_VECTOR;
4517 it->ellipsis_p = 1;
4522 /***********************************************************************
4523 'display' property
4524 ***********************************************************************/
4526 /* Set up iterator IT from `display' property at its current position.
4527 Called from handle_stop.
4528 We return HANDLED_RETURN if some part of the display property
4529 overrides the display of the buffer text itself.
4530 Otherwise we return HANDLED_NORMALLY. */
4532 static enum prop_handled
4533 handle_display_prop (struct it *it)
4535 Lisp_Object propval, object, overlay;
4536 struct text_pos *position;
4537 ptrdiff_t bufpos;
4538 /* Nonzero if some property replaces the display of the text itself. */
4539 int display_replaced_p = 0;
4541 if (STRINGP (it->string))
4543 object = it->string;
4544 position = &it->current.string_pos;
4545 bufpos = CHARPOS (it->current.pos);
4547 else
4549 XSETWINDOW (object, it->w);
4550 position = &it->current.pos;
4551 bufpos = CHARPOS (*position);
4554 /* Reset those iterator values set from display property values. */
4555 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
4556 it->space_width = Qnil;
4557 it->font_height = Qnil;
4558 it->voffset = 0;
4560 /* We don't support recursive `display' properties, i.e. string
4561 values that have a string `display' property, that have a string
4562 `display' property etc. */
4563 if (!it->string_from_display_prop_p)
4564 it->area = TEXT_AREA;
4566 propval = get_char_property_and_overlay (make_number (position->charpos),
4567 Qdisplay, object, &overlay);
4568 if (NILP (propval))
4569 return HANDLED_NORMALLY;
4570 /* Now OVERLAY is the overlay that gave us this property, or nil
4571 if it was a text property. */
4573 if (!STRINGP (it->string))
4574 object = it->w->contents;
4576 display_replaced_p = handle_display_spec (it, propval, object, overlay,
4577 position, bufpos,
4578 FRAME_WINDOW_P (it->f));
4580 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
4583 /* Subroutine of handle_display_prop. Returns non-zero if the display
4584 specification in SPEC is a replacing specification, i.e. it would
4585 replace the text covered by `display' property with something else,
4586 such as an image or a display string. If SPEC includes any kind or
4587 `(space ...) specification, the value is 2; this is used by
4588 compute_display_string_pos, which see.
4590 See handle_single_display_spec for documentation of arguments.
4591 frame_window_p is non-zero if the window being redisplayed is on a
4592 GUI frame; this argument is used only if IT is NULL, see below.
4594 IT can be NULL, if this is called by the bidi reordering code
4595 through compute_display_string_pos, which see. In that case, this
4596 function only examines SPEC, but does not otherwise "handle" it, in
4597 the sense that it doesn't set up members of IT from the display
4598 spec. */
4599 static int
4600 handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4601 Lisp_Object overlay, struct text_pos *position,
4602 ptrdiff_t bufpos, int frame_window_p)
4604 int replacing_p = 0;
4605 int rv;
4607 if (CONSP (spec)
4608 /* Simple specifications. */
4609 && !EQ (XCAR (spec), Qimage)
4610 && !EQ (XCAR (spec), Qspace)
4611 && !EQ (XCAR (spec), Qwhen)
4612 && !EQ (XCAR (spec), Qslice)
4613 && !EQ (XCAR (spec), Qspace_width)
4614 && !EQ (XCAR (spec), Qheight)
4615 && !EQ (XCAR (spec), Qraise)
4616 /* Marginal area specifications. */
4617 && !(CONSP (XCAR (spec)) && EQ (XCAR (XCAR (spec)), Qmargin))
4618 && !EQ (XCAR (spec), Qleft_fringe)
4619 && !EQ (XCAR (spec), Qright_fringe)
4620 && !NILP (XCAR (spec)))
4622 for (; CONSP (spec); spec = XCDR (spec))
4624 if ((rv = handle_single_display_spec (it, XCAR (spec), object,
4625 overlay, position, bufpos,
4626 replacing_p, frame_window_p)))
4628 replacing_p = rv;
4629 /* If some text in a string is replaced, `position' no
4630 longer points to the position of `object'. */
4631 if (!it || STRINGP (object))
4632 break;
4636 else if (VECTORP (spec))
4638 ptrdiff_t i;
4639 for (i = 0; i < ASIZE (spec); ++i)
4640 if ((rv = handle_single_display_spec (it, AREF (spec, i), object,
4641 overlay, position, bufpos,
4642 replacing_p, frame_window_p)))
4644 replacing_p = rv;
4645 /* If some text in a string is replaced, `position' no
4646 longer points to the position of `object'. */
4647 if (!it || STRINGP (object))
4648 break;
4651 else
4653 if ((rv = handle_single_display_spec (it, spec, object, overlay,
4654 position, bufpos, 0,
4655 frame_window_p)))
4656 replacing_p = rv;
4659 return replacing_p;
4662 /* Value is the position of the end of the `display' property starting
4663 at START_POS in OBJECT. */
4665 static struct text_pos
4666 display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
4668 Lisp_Object end;
4669 struct text_pos end_pos;
4671 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
4672 Qdisplay, object, Qnil);
4673 CHARPOS (end_pos) = XFASTINT (end);
4674 if (STRINGP (object))
4675 compute_string_pos (&end_pos, start_pos, it->string);
4676 else
4677 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
4679 return end_pos;
4683 /* Set up IT from a single `display' property specification SPEC. OBJECT
4684 is the object in which the `display' property was found. *POSITION
4685 is the position in OBJECT at which the `display' property was found.
4686 BUFPOS is the buffer position of OBJECT (different from POSITION if
4687 OBJECT is not a buffer). DISPLAY_REPLACED_P non-zero means that we
4688 previously saw a display specification which already replaced text
4689 display with something else, for example an image; we ignore such
4690 properties after the first one has been processed.
4692 OVERLAY is the overlay this `display' property came from,
4693 or nil if it was a text property.
4695 If SPEC is a `space' or `image' specification, and in some other
4696 cases too, set *POSITION to the position where the `display'
4697 property ends.
4699 If IT is NULL, only examine the property specification in SPEC, but
4700 don't set up IT. In that case, FRAME_WINDOW_P non-zero means SPEC
4701 is intended to be displayed in a window on a GUI frame.
4703 Value is non-zero if something was found which replaces the display
4704 of buffer or string text. */
4706 static int
4707 handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4708 Lisp_Object overlay, struct text_pos *position,
4709 ptrdiff_t bufpos, int display_replaced_p,
4710 int frame_window_p)
4712 Lisp_Object form;
4713 Lisp_Object location, value;
4714 struct text_pos start_pos = *position;
4715 int valid_p;
4717 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4718 If the result is non-nil, use VALUE instead of SPEC. */
4719 form = Qt;
4720 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
4722 spec = XCDR (spec);
4723 if (!CONSP (spec))
4724 return 0;
4725 form = XCAR (spec);
4726 spec = XCDR (spec);
4729 if (!NILP (form) && !EQ (form, Qt))
4731 ptrdiff_t count = SPECPDL_INDEX ();
4732 struct gcpro gcpro1;
4734 /* Bind `object' to the object having the `display' property, a
4735 buffer or string. Bind `position' to the position in the
4736 object where the property was found, and `buffer-position'
4737 to the current position in the buffer. */
4739 if (NILP (object))
4740 XSETBUFFER (object, current_buffer);
4741 specbind (Qobject, object);
4742 specbind (Qposition, make_number (CHARPOS (*position)));
4743 specbind (Qbuffer_position, make_number (bufpos));
4744 GCPRO1 (form);
4745 form = safe_eval (form);
4746 UNGCPRO;
4747 unbind_to (count, Qnil);
4750 if (NILP (form))
4751 return 0;
4753 /* Handle `(height HEIGHT)' specifications. */
4754 if (CONSP (spec)
4755 && EQ (XCAR (spec), Qheight)
4756 && CONSP (XCDR (spec)))
4758 if (it)
4760 if (!FRAME_WINDOW_P (it->f))
4761 return 0;
4763 it->font_height = XCAR (XCDR (spec));
4764 if (!NILP (it->font_height))
4766 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4767 int new_height = -1;
4769 if (CONSP (it->font_height)
4770 && (EQ (XCAR (it->font_height), Qplus)
4771 || EQ (XCAR (it->font_height), Qminus))
4772 && CONSP (XCDR (it->font_height))
4773 && RANGED_INTEGERP (0, XCAR (XCDR (it->font_height)), INT_MAX))
4775 /* `(+ N)' or `(- N)' where N is an integer. */
4776 int steps = XINT (XCAR (XCDR (it->font_height)));
4777 if (EQ (XCAR (it->font_height), Qplus))
4778 steps = - steps;
4779 it->face_id = smaller_face (it->f, it->face_id, steps);
4781 else if (FUNCTIONP (it->font_height))
4783 /* Call function with current height as argument.
4784 Value is the new height. */
4785 Lisp_Object height;
4786 height = safe_call1 (it->font_height,
4787 face->lface[LFACE_HEIGHT_INDEX]);
4788 if (NUMBERP (height))
4789 new_height = XFLOATINT (height);
4791 else if (NUMBERP (it->font_height))
4793 /* Value is a multiple of the canonical char height. */
4794 struct face *f;
4796 f = FACE_FROM_ID (it->f,
4797 lookup_basic_face (it->f, DEFAULT_FACE_ID));
4798 new_height = (XFLOATINT (it->font_height)
4799 * XINT (f->lface[LFACE_HEIGHT_INDEX]));
4801 else
4803 /* Evaluate IT->font_height with `height' bound to the
4804 current specified height to get the new height. */
4805 ptrdiff_t count = SPECPDL_INDEX ();
4807 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
4808 value = safe_eval (it->font_height);
4809 unbind_to (count, Qnil);
4811 if (NUMBERP (value))
4812 new_height = XFLOATINT (value);
4815 if (new_height > 0)
4816 it->face_id = face_with_height (it->f, it->face_id, new_height);
4820 return 0;
4823 /* Handle `(space-width WIDTH)'. */
4824 if (CONSP (spec)
4825 && EQ (XCAR (spec), Qspace_width)
4826 && CONSP (XCDR (spec)))
4828 if (it)
4830 if (!FRAME_WINDOW_P (it->f))
4831 return 0;
4833 value = XCAR (XCDR (spec));
4834 if (NUMBERP (value) && XFLOATINT (value) > 0)
4835 it->space_width = value;
4838 return 0;
4841 /* Handle `(slice X Y WIDTH HEIGHT)'. */
4842 if (CONSP (spec)
4843 && EQ (XCAR (spec), Qslice))
4845 Lisp_Object tem;
4847 if (it)
4849 if (!FRAME_WINDOW_P (it->f))
4850 return 0;
4852 if (tem = XCDR (spec), CONSP (tem))
4854 it->slice.x = XCAR (tem);
4855 if (tem = XCDR (tem), CONSP (tem))
4857 it->slice.y = XCAR (tem);
4858 if (tem = XCDR (tem), CONSP (tem))
4860 it->slice.width = XCAR (tem);
4861 if (tem = XCDR (tem), CONSP (tem))
4862 it->slice.height = XCAR (tem);
4868 return 0;
4871 /* Handle `(raise FACTOR)'. */
4872 if (CONSP (spec)
4873 && EQ (XCAR (spec), Qraise)
4874 && CONSP (XCDR (spec)))
4876 if (it)
4878 if (!FRAME_WINDOW_P (it->f))
4879 return 0;
4881 #ifdef HAVE_WINDOW_SYSTEM
4882 value = XCAR (XCDR (spec));
4883 if (NUMBERP (value))
4885 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4886 it->voffset = - (XFLOATINT (value)
4887 * (FONT_HEIGHT (face->font)));
4889 #endif /* HAVE_WINDOW_SYSTEM */
4892 return 0;
4895 /* Don't handle the other kinds of display specifications
4896 inside a string that we got from a `display' property. */
4897 if (it && it->string_from_display_prop_p)
4898 return 0;
4900 /* Characters having this form of property are not displayed, so
4901 we have to find the end of the property. */
4902 if (it)
4904 start_pos = *position;
4905 *position = display_prop_end (it, object, start_pos);
4907 value = Qnil;
4909 /* Stop the scan at that end position--we assume that all
4910 text properties change there. */
4911 if (it)
4912 it->stop_charpos = position->charpos;
4914 /* Handle `(left-fringe BITMAP [FACE])'
4915 and `(right-fringe BITMAP [FACE])'. */
4916 if (CONSP (spec)
4917 && (EQ (XCAR (spec), Qleft_fringe)
4918 || EQ (XCAR (spec), Qright_fringe))
4919 && CONSP (XCDR (spec)))
4921 int fringe_bitmap;
4923 if (it)
4925 if (!FRAME_WINDOW_P (it->f))
4926 /* If we return here, POSITION has been advanced
4927 across the text with this property. */
4929 /* Synchronize the bidi iterator with POSITION. This is
4930 needed because we are not going to push the iterator
4931 on behalf of this display property, so there will be
4932 no pop_it call to do this synchronization for us. */
4933 if (it->bidi_p)
4935 it->position = *position;
4936 iterate_out_of_display_property (it);
4937 *position = it->position;
4939 return 1;
4942 else if (!frame_window_p)
4943 return 1;
4945 #ifdef HAVE_WINDOW_SYSTEM
4946 value = XCAR (XCDR (spec));
4947 if (!SYMBOLP (value)
4948 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
4949 /* If we return here, POSITION has been advanced
4950 across the text with this property. */
4952 if (it && it->bidi_p)
4954 it->position = *position;
4955 iterate_out_of_display_property (it);
4956 *position = it->position;
4958 return 1;
4961 if (it)
4963 int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);;
4965 if (CONSP (XCDR (XCDR (spec))))
4967 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
4968 int face_id2 = lookup_derived_face (it->f, face_name,
4969 FRINGE_FACE_ID, 0);
4970 if (face_id2 >= 0)
4971 face_id = face_id2;
4974 /* Save current settings of IT so that we can restore them
4975 when we are finished with the glyph property value. */
4976 push_it (it, position);
4978 it->area = TEXT_AREA;
4979 it->what = IT_IMAGE;
4980 it->image_id = -1; /* no image */
4981 it->position = start_pos;
4982 it->object = NILP (object) ? it->w->contents : object;
4983 it->method = GET_FROM_IMAGE;
4984 it->from_overlay = Qnil;
4985 it->face_id = face_id;
4986 it->from_disp_prop_p = 1;
4988 /* Say that we haven't consumed the characters with
4989 `display' property yet. The call to pop_it in
4990 set_iterator_to_next will clean this up. */
4991 *position = start_pos;
4993 if (EQ (XCAR (spec), Qleft_fringe))
4995 it->left_user_fringe_bitmap = fringe_bitmap;
4996 it->left_user_fringe_face_id = face_id;
4998 else
5000 it->right_user_fringe_bitmap = fringe_bitmap;
5001 it->right_user_fringe_face_id = face_id;
5004 #endif /* HAVE_WINDOW_SYSTEM */
5005 return 1;
5008 /* Prepare to handle `((margin left-margin) ...)',
5009 `((margin right-margin) ...)' and `((margin nil) ...)'
5010 prefixes for display specifications. */
5011 location = Qunbound;
5012 if (CONSP (spec) && CONSP (XCAR (spec)))
5014 Lisp_Object tem;
5016 value = XCDR (spec);
5017 if (CONSP (value))
5018 value = XCAR (value);
5020 tem = XCAR (spec);
5021 if (EQ (XCAR (tem), Qmargin)
5022 && (tem = XCDR (tem),
5023 tem = CONSP (tem) ? XCAR (tem) : Qnil,
5024 (NILP (tem)
5025 || EQ (tem, Qleft_margin)
5026 || EQ (tem, Qright_margin))))
5027 location = tem;
5030 if (EQ (location, Qunbound))
5032 location = Qnil;
5033 value = spec;
5036 /* After this point, VALUE is the property after any
5037 margin prefix has been stripped. It must be a string,
5038 an image specification, or `(space ...)'.
5040 LOCATION specifies where to display: `left-margin',
5041 `right-margin' or nil. */
5043 valid_p = (STRINGP (value)
5044 #ifdef HAVE_WINDOW_SYSTEM
5045 || ((it ? FRAME_WINDOW_P (it->f) : frame_window_p)
5046 && valid_image_p (value))
5047 #endif /* not HAVE_WINDOW_SYSTEM */
5048 || (CONSP (value) && EQ (XCAR (value), Qspace)));
5050 if (valid_p && !display_replaced_p)
5052 int retval = 1;
5054 if (!it)
5056 /* Callers need to know whether the display spec is any kind
5057 of `(space ...)' spec that is about to affect text-area
5058 display. */
5059 if (CONSP (value) && EQ (XCAR (value), Qspace) && NILP (location))
5060 retval = 2;
5061 return retval;
5064 /* Save current settings of IT so that we can restore them
5065 when we are finished with the glyph property value. */
5066 push_it (it, position);
5067 it->from_overlay = overlay;
5068 it->from_disp_prop_p = 1;
5070 if (NILP (location))
5071 it->area = TEXT_AREA;
5072 else if (EQ (location, Qleft_margin))
5073 it->area = LEFT_MARGIN_AREA;
5074 else
5075 it->area = RIGHT_MARGIN_AREA;
5077 if (STRINGP (value))
5079 it->string = value;
5080 it->multibyte_p = STRING_MULTIBYTE (it->string);
5081 it->current.overlay_string_index = -1;
5082 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5083 it->end_charpos = it->string_nchars = SCHARS (it->string);
5084 it->method = GET_FROM_STRING;
5085 it->stop_charpos = 0;
5086 it->prev_stop = 0;
5087 it->base_level_stop = 0;
5088 it->string_from_display_prop_p = 1;
5089 /* Say that we haven't consumed the characters with
5090 `display' property yet. The call to pop_it in
5091 set_iterator_to_next will clean this up. */
5092 if (BUFFERP (object))
5093 *position = start_pos;
5095 /* Force paragraph direction to be that of the parent
5096 object. If the parent object's paragraph direction is
5097 not yet determined, default to L2R. */
5098 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
5099 it->paragraph_embedding = it->bidi_it.paragraph_dir;
5100 else
5101 it->paragraph_embedding = L2R;
5103 /* Set up the bidi iterator for this display string. */
5104 if (it->bidi_p)
5106 it->bidi_it.string.lstring = it->string;
5107 it->bidi_it.string.s = NULL;
5108 it->bidi_it.string.schars = it->end_charpos;
5109 it->bidi_it.string.bufpos = bufpos;
5110 it->bidi_it.string.from_disp_str = 1;
5111 it->bidi_it.string.unibyte = !it->multibyte_p;
5112 it->bidi_it.w = it->w;
5113 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5116 else if (CONSP (value) && EQ (XCAR (value), Qspace))
5118 it->method = GET_FROM_STRETCH;
5119 it->object = value;
5120 *position = it->position = start_pos;
5121 retval = 1 + (it->area == TEXT_AREA);
5123 #ifdef HAVE_WINDOW_SYSTEM
5124 else
5126 it->what = IT_IMAGE;
5127 it->image_id = lookup_image (it->f, value);
5128 it->position = start_pos;
5129 it->object = NILP (object) ? it->w->contents : object;
5130 it->method = GET_FROM_IMAGE;
5132 /* Say that we haven't consumed the characters with
5133 `display' property yet. The call to pop_it in
5134 set_iterator_to_next will clean this up. */
5135 *position = start_pos;
5137 #endif /* HAVE_WINDOW_SYSTEM */
5139 return retval;
5142 /* Invalid property or property not supported. Restore
5143 POSITION to what it was before. */
5144 *position = start_pos;
5145 return 0;
5148 /* Check if PROP is a display property value whose text should be
5149 treated as intangible. OVERLAY is the overlay from which PROP
5150 came, or nil if it came from a text property. CHARPOS and BYTEPOS
5151 specify the buffer position covered by PROP. */
5154 display_prop_intangible_p (Lisp_Object prop, Lisp_Object overlay,
5155 ptrdiff_t charpos, ptrdiff_t bytepos)
5157 int frame_window_p = FRAME_WINDOW_P (XFRAME (selected_frame));
5158 struct text_pos position;
5160 SET_TEXT_POS (position, charpos, bytepos);
5161 return handle_display_spec (NULL, prop, Qnil, overlay,
5162 &position, charpos, frame_window_p);
5166 /* Return 1 if PROP is a display sub-property value containing STRING.
5168 Implementation note: this and the following function are really
5169 special cases of handle_display_spec and
5170 handle_single_display_spec, and should ideally use the same code.
5171 Until they do, these two pairs must be consistent and must be
5172 modified in sync. */
5174 static int
5175 single_display_spec_string_p (Lisp_Object prop, Lisp_Object string)
5177 if (EQ (string, prop))
5178 return 1;
5180 /* Skip over `when FORM'. */
5181 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
5183 prop = XCDR (prop);
5184 if (!CONSP (prop))
5185 return 0;
5186 /* Actually, the condition following `when' should be eval'ed,
5187 like handle_single_display_spec does, and we should return
5188 zero if it evaluates to nil. However, this function is
5189 called only when the buffer was already displayed and some
5190 glyph in the glyph matrix was found to come from a display
5191 string. Therefore, the condition was already evaluated, and
5192 the result was non-nil, otherwise the display string wouldn't
5193 have been displayed and we would have never been called for
5194 this property. Thus, we can skip the evaluation and assume
5195 its result is non-nil. */
5196 prop = XCDR (prop);
5199 if (CONSP (prop))
5200 /* Skip over `margin LOCATION'. */
5201 if (EQ (XCAR (prop), Qmargin))
5203 prop = XCDR (prop);
5204 if (!CONSP (prop))
5205 return 0;
5207 prop = XCDR (prop);
5208 if (!CONSP (prop))
5209 return 0;
5212 return EQ (prop, string) || (CONSP (prop) && EQ (XCAR (prop), string));
5216 /* Return 1 if STRING appears in the `display' property PROP. */
5218 static int
5219 display_prop_string_p (Lisp_Object prop, Lisp_Object string)
5221 if (CONSP (prop)
5222 && !EQ (XCAR (prop), Qwhen)
5223 && !(CONSP (XCAR (prop)) && EQ (Qmargin, XCAR (XCAR (prop)))))
5225 /* A list of sub-properties. */
5226 while (CONSP (prop))
5228 if (single_display_spec_string_p (XCAR (prop), string))
5229 return 1;
5230 prop = XCDR (prop);
5233 else if (VECTORP (prop))
5235 /* A vector of sub-properties. */
5236 ptrdiff_t i;
5237 for (i = 0; i < ASIZE (prop); ++i)
5238 if (single_display_spec_string_p (AREF (prop, i), string))
5239 return 1;
5241 else
5242 return single_display_spec_string_p (prop, string);
5244 return 0;
5247 /* Look for STRING in overlays and text properties in the current
5248 buffer, between character positions FROM and TO (excluding TO).
5249 BACK_P non-zero means look back (in this case, TO is supposed to be
5250 less than FROM).
5251 Value is the first character position where STRING was found, or
5252 zero if it wasn't found before hitting TO.
5254 This function may only use code that doesn't eval because it is
5255 called asynchronously from note_mouse_highlight. */
5257 static ptrdiff_t
5258 string_buffer_position_lim (Lisp_Object string,
5259 ptrdiff_t from, ptrdiff_t to, int back_p)
5261 Lisp_Object limit, prop, pos;
5262 int found = 0;
5264 pos = make_number (max (from, BEGV));
5266 if (!back_p) /* looking forward */
5268 limit = make_number (min (to, ZV));
5269 while (!found && !EQ (pos, limit))
5271 prop = Fget_char_property (pos, Qdisplay, Qnil);
5272 if (!NILP (prop) && display_prop_string_p (prop, string))
5273 found = 1;
5274 else
5275 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil,
5276 limit);
5279 else /* looking back */
5281 limit = make_number (max (to, BEGV));
5282 while (!found && !EQ (pos, limit))
5284 prop = Fget_char_property (pos, Qdisplay, Qnil);
5285 if (!NILP (prop) && display_prop_string_p (prop, string))
5286 found = 1;
5287 else
5288 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
5289 limit);
5293 return found ? XINT (pos) : 0;
5296 /* Determine which buffer position in current buffer STRING comes from.
5297 AROUND_CHARPOS is an approximate position where it could come from.
5298 Value is the buffer position or 0 if it couldn't be determined.
5300 This function is necessary because we don't record buffer positions
5301 in glyphs generated from strings (to keep struct glyph small).
5302 This function may only use code that doesn't eval because it is
5303 called asynchronously from note_mouse_highlight. */
5305 static ptrdiff_t
5306 string_buffer_position (Lisp_Object string, ptrdiff_t around_charpos)
5308 const int MAX_DISTANCE = 1000;
5309 ptrdiff_t found = string_buffer_position_lim (string, around_charpos,
5310 around_charpos + MAX_DISTANCE,
5313 if (!found)
5314 found = string_buffer_position_lim (string, around_charpos,
5315 around_charpos - MAX_DISTANCE, 1);
5316 return found;
5321 /***********************************************************************
5322 `composition' property
5323 ***********************************************************************/
5325 /* Set up iterator IT from `composition' property at its current
5326 position. Called from handle_stop. */
5328 static enum prop_handled
5329 handle_composition_prop (struct it *it)
5331 Lisp_Object prop, string;
5332 ptrdiff_t pos, pos_byte, start, end;
5334 if (STRINGP (it->string))
5336 unsigned char *s;
5338 pos = IT_STRING_CHARPOS (*it);
5339 pos_byte = IT_STRING_BYTEPOS (*it);
5340 string = it->string;
5341 s = SDATA (string) + pos_byte;
5342 it->c = STRING_CHAR (s);
5344 else
5346 pos = IT_CHARPOS (*it);
5347 pos_byte = IT_BYTEPOS (*it);
5348 string = Qnil;
5349 it->c = FETCH_CHAR (pos_byte);
5352 /* If there's a valid composition and point is not inside of the
5353 composition (in the case that the composition is from the current
5354 buffer), draw a glyph composed from the composition components. */
5355 if (find_composition (pos, -1, &start, &end, &prop, string)
5356 && composition_valid_p (start, end, prop)
5357 && (STRINGP (it->string) || (PT <= start || PT >= end)))
5359 if (start < pos)
5360 /* As we can't handle this situation (perhaps font-lock added
5361 a new composition), we just return here hoping that next
5362 redisplay will detect this composition much earlier. */
5363 return HANDLED_NORMALLY;
5364 if (start != pos)
5366 if (STRINGP (it->string))
5367 pos_byte = string_char_to_byte (it->string, start);
5368 else
5369 pos_byte = CHAR_TO_BYTE (start);
5371 it->cmp_it.id = get_composition_id (start, pos_byte, end - start,
5372 prop, string);
5374 if (it->cmp_it.id >= 0)
5376 it->cmp_it.ch = -1;
5377 it->cmp_it.nchars = COMPOSITION_LENGTH (prop);
5378 it->cmp_it.nglyphs = -1;
5382 return HANDLED_NORMALLY;
5387 /***********************************************************************
5388 Overlay strings
5389 ***********************************************************************/
5391 /* The following structure is used to record overlay strings for
5392 later sorting in load_overlay_strings. */
5394 struct overlay_entry
5396 Lisp_Object overlay;
5397 Lisp_Object string;
5398 EMACS_INT priority;
5399 int after_string_p;
5403 /* Set up iterator IT from overlay strings at its current position.
5404 Called from handle_stop. */
5406 static enum prop_handled
5407 handle_overlay_change (struct it *it)
5409 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
5410 return HANDLED_RECOMPUTE_PROPS;
5411 else
5412 return HANDLED_NORMALLY;
5416 /* Set up the next overlay string for delivery by IT, if there is an
5417 overlay string to deliver. Called by set_iterator_to_next when the
5418 end of the current overlay string is reached. If there are more
5419 overlay strings to display, IT->string and
5420 IT->current.overlay_string_index are set appropriately here.
5421 Otherwise IT->string is set to nil. */
5423 static void
5424 next_overlay_string (struct it *it)
5426 ++it->current.overlay_string_index;
5427 if (it->current.overlay_string_index == it->n_overlay_strings)
5429 /* No more overlay strings. Restore IT's settings to what
5430 they were before overlay strings were processed, and
5431 continue to deliver from current_buffer. */
5433 it->ellipsis_p = (it->stack[it->sp - 1].display_ellipsis_p != 0);
5434 pop_it (it);
5435 eassert (it->sp > 0
5436 || (NILP (it->string)
5437 && it->method == GET_FROM_BUFFER
5438 && it->stop_charpos >= BEGV
5439 && it->stop_charpos <= it->end_charpos));
5440 it->current.overlay_string_index = -1;
5441 it->n_overlay_strings = 0;
5442 it->overlay_strings_charpos = -1;
5443 /* If there's an empty display string on the stack, pop the
5444 stack, to resync the bidi iterator with IT's position. Such
5445 empty strings are pushed onto the stack in
5446 get_overlay_strings_1. */
5447 if (it->sp > 0 && STRINGP (it->string) && !SCHARS (it->string))
5448 pop_it (it);
5450 /* If we're at the end of the buffer, record that we have
5451 processed the overlay strings there already, so that
5452 next_element_from_buffer doesn't try it again. */
5453 if (NILP (it->string) && IT_CHARPOS (*it) >= it->end_charpos)
5454 it->overlay_strings_at_end_processed_p = 1;
5456 else
5458 /* There are more overlay strings to process. If
5459 IT->current.overlay_string_index has advanced to a position
5460 where we must load IT->overlay_strings with more strings, do
5461 it. We must load at the IT->overlay_strings_charpos where
5462 IT->n_overlay_strings was originally computed; when invisible
5463 text is present, this might not be IT_CHARPOS (Bug#7016). */
5464 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
5466 if (it->current.overlay_string_index && i == 0)
5467 load_overlay_strings (it, it->overlay_strings_charpos);
5469 /* Initialize IT to deliver display elements from the overlay
5470 string. */
5471 it->string = it->overlay_strings[i];
5472 it->multibyte_p = STRING_MULTIBYTE (it->string);
5473 SET_TEXT_POS (it->current.string_pos, 0, 0);
5474 it->method = GET_FROM_STRING;
5475 it->stop_charpos = 0;
5476 it->end_charpos = SCHARS (it->string);
5477 if (it->cmp_it.stop_pos >= 0)
5478 it->cmp_it.stop_pos = 0;
5479 it->prev_stop = 0;
5480 it->base_level_stop = 0;
5482 /* Set up the bidi iterator for this overlay string. */
5483 if (it->bidi_p)
5485 it->bidi_it.string.lstring = it->string;
5486 it->bidi_it.string.s = NULL;
5487 it->bidi_it.string.schars = SCHARS (it->string);
5488 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
5489 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5490 it->bidi_it.string.unibyte = !it->multibyte_p;
5491 it->bidi_it.w = it->w;
5492 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5496 CHECK_IT (it);
5500 /* Compare two overlay_entry structures E1 and E2. Used as a
5501 comparison function for qsort in load_overlay_strings. Overlay
5502 strings for the same position are sorted so that
5504 1. All after-strings come in front of before-strings, except
5505 when they come from the same overlay.
5507 2. Within after-strings, strings are sorted so that overlay strings
5508 from overlays with higher priorities come first.
5510 2. Within before-strings, strings are sorted so that overlay
5511 strings from overlays with higher priorities come last.
5513 Value is analogous to strcmp. */
5516 static int
5517 compare_overlay_entries (const void *e1, const void *e2)
5519 struct overlay_entry const *entry1 = e1;
5520 struct overlay_entry const *entry2 = e2;
5521 int result;
5523 if (entry1->after_string_p != entry2->after_string_p)
5525 /* Let after-strings appear in front of before-strings if
5526 they come from different overlays. */
5527 if (EQ (entry1->overlay, entry2->overlay))
5528 result = entry1->after_string_p ? 1 : -1;
5529 else
5530 result = entry1->after_string_p ? -1 : 1;
5532 else if (entry1->priority != entry2->priority)
5534 if (entry1->after_string_p)
5535 /* After-strings sorted in order of decreasing priority. */
5536 result = entry2->priority < entry1->priority ? -1 : 1;
5537 else
5538 /* Before-strings sorted in order of increasing priority. */
5539 result = entry1->priority < entry2->priority ? -1 : 1;
5541 else
5542 result = 0;
5544 return result;
5548 /* Load the vector IT->overlay_strings with overlay strings from IT's
5549 current buffer position, or from CHARPOS if that is > 0. Set
5550 IT->n_overlays to the total number of overlay strings found.
5552 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
5553 a time. On entry into load_overlay_strings,
5554 IT->current.overlay_string_index gives the number of overlay
5555 strings that have already been loaded by previous calls to this
5556 function.
5558 IT->add_overlay_start contains an additional overlay start
5559 position to consider for taking overlay strings from, if non-zero.
5560 This position comes into play when the overlay has an `invisible'
5561 property, and both before and after-strings. When we've skipped to
5562 the end of the overlay, because of its `invisible' property, we
5563 nevertheless want its before-string to appear.
5564 IT->add_overlay_start will contain the overlay start position
5565 in this case.
5567 Overlay strings are sorted so that after-string strings come in
5568 front of before-string strings. Within before and after-strings,
5569 strings are sorted by overlay priority. See also function
5570 compare_overlay_entries. */
5572 static void
5573 load_overlay_strings (struct it *it, ptrdiff_t charpos)
5575 Lisp_Object overlay, window, str, invisible;
5576 struct Lisp_Overlay *ov;
5577 ptrdiff_t start, end;
5578 ptrdiff_t size = 20;
5579 ptrdiff_t n = 0, i, j;
5580 int invis_p;
5581 struct overlay_entry *entries = alloca (size * sizeof *entries);
5582 USE_SAFE_ALLOCA;
5584 if (charpos <= 0)
5585 charpos = IT_CHARPOS (*it);
5587 /* Append the overlay string STRING of overlay OVERLAY to vector
5588 `entries' which has size `size' and currently contains `n'
5589 elements. AFTER_P non-zero means STRING is an after-string of
5590 OVERLAY. */
5591 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
5592 do \
5594 Lisp_Object priority; \
5596 if (n == size) \
5598 struct overlay_entry *old = entries; \
5599 SAFE_NALLOCA (entries, 2, size); \
5600 memcpy (entries, old, size * sizeof *entries); \
5601 size *= 2; \
5604 entries[n].string = (STRING); \
5605 entries[n].overlay = (OVERLAY); \
5606 priority = Foverlay_get ((OVERLAY), Qpriority); \
5607 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
5608 entries[n].after_string_p = (AFTER_P); \
5609 ++n; \
5611 while (0)
5613 /* Process overlay before the overlay center. */
5614 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
5616 XSETMISC (overlay, ov);
5617 eassert (OVERLAYP (overlay));
5618 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5619 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5621 if (end < charpos)
5622 break;
5624 /* Skip this overlay if it doesn't start or end at IT's current
5625 position. */
5626 if (end != charpos && start != charpos)
5627 continue;
5629 /* Skip this overlay if it doesn't apply to IT->w. */
5630 window = Foverlay_get (overlay, Qwindow);
5631 if (WINDOWP (window) && XWINDOW (window) != it->w)
5632 continue;
5634 /* If the text ``under'' the overlay is invisible, both before-
5635 and after-strings from this overlay are visible; start and
5636 end position are indistinguishable. */
5637 invisible = Foverlay_get (overlay, Qinvisible);
5638 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5640 /* If overlay has a non-empty before-string, record it. */
5641 if ((start == charpos || (end == charpos && invis_p))
5642 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5643 && SCHARS (str))
5644 RECORD_OVERLAY_STRING (overlay, str, 0);
5646 /* If overlay has a non-empty after-string, record it. */
5647 if ((end == charpos || (start == charpos && invis_p))
5648 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5649 && SCHARS (str))
5650 RECORD_OVERLAY_STRING (overlay, str, 1);
5653 /* Process overlays after the overlay center. */
5654 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
5656 XSETMISC (overlay, ov);
5657 eassert (OVERLAYP (overlay));
5658 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5659 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5661 if (start > charpos)
5662 break;
5664 /* Skip this overlay if it doesn't start or end at IT's current
5665 position. */
5666 if (end != charpos && start != charpos)
5667 continue;
5669 /* Skip this overlay if it doesn't apply to IT->w. */
5670 window = Foverlay_get (overlay, Qwindow);
5671 if (WINDOWP (window) && XWINDOW (window) != it->w)
5672 continue;
5674 /* If the text ``under'' the overlay is invisible, it has a zero
5675 dimension, and both before- and after-strings apply. */
5676 invisible = Foverlay_get (overlay, Qinvisible);
5677 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5679 /* If overlay has a non-empty before-string, record it. */
5680 if ((start == charpos || (end == charpos && invis_p))
5681 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5682 && SCHARS (str))
5683 RECORD_OVERLAY_STRING (overlay, str, 0);
5685 /* If overlay has a non-empty after-string, record it. */
5686 if ((end == charpos || (start == charpos && invis_p))
5687 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5688 && SCHARS (str))
5689 RECORD_OVERLAY_STRING (overlay, str, 1);
5692 #undef RECORD_OVERLAY_STRING
5694 /* Sort entries. */
5695 if (n > 1)
5696 qsort (entries, n, sizeof *entries, compare_overlay_entries);
5698 /* Record number of overlay strings, and where we computed it. */
5699 it->n_overlay_strings = n;
5700 it->overlay_strings_charpos = charpos;
5702 /* IT->current.overlay_string_index is the number of overlay strings
5703 that have already been consumed by IT. Copy some of the
5704 remaining overlay strings to IT->overlay_strings. */
5705 i = 0;
5706 j = it->current.overlay_string_index;
5707 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
5709 it->overlay_strings[i] = entries[j].string;
5710 it->string_overlays[i++] = entries[j++].overlay;
5713 CHECK_IT (it);
5714 SAFE_FREE ();
5718 /* Get the first chunk of overlay strings at IT's current buffer
5719 position, or at CHARPOS if that is > 0. Value is non-zero if at
5720 least one overlay string was found. */
5722 static int
5723 get_overlay_strings_1 (struct it *it, ptrdiff_t charpos, int compute_stop_p)
5725 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
5726 process. This fills IT->overlay_strings with strings, and sets
5727 IT->n_overlay_strings to the total number of strings to process.
5728 IT->pos.overlay_string_index has to be set temporarily to zero
5729 because load_overlay_strings needs this; it must be set to -1
5730 when no overlay strings are found because a zero value would
5731 indicate a position in the first overlay string. */
5732 it->current.overlay_string_index = 0;
5733 load_overlay_strings (it, charpos);
5735 /* If we found overlay strings, set up IT to deliver display
5736 elements from the first one. Otherwise set up IT to deliver
5737 from current_buffer. */
5738 if (it->n_overlay_strings)
5740 /* Make sure we know settings in current_buffer, so that we can
5741 restore meaningful values when we're done with the overlay
5742 strings. */
5743 if (compute_stop_p)
5744 compute_stop_pos (it);
5745 eassert (it->face_id >= 0);
5747 /* Save IT's settings. They are restored after all overlay
5748 strings have been processed. */
5749 eassert (!compute_stop_p || it->sp == 0);
5751 /* When called from handle_stop, there might be an empty display
5752 string loaded. In that case, don't bother saving it. But
5753 don't use this optimization with the bidi iterator, since we
5754 need the corresponding pop_it call to resync the bidi
5755 iterator's position with IT's position, after we are done
5756 with the overlay strings. (The corresponding call to pop_it
5757 in case of an empty display string is in
5758 next_overlay_string.) */
5759 if (!(!it->bidi_p
5760 && STRINGP (it->string) && !SCHARS (it->string)))
5761 push_it (it, NULL);
5763 /* Set up IT to deliver display elements from the first overlay
5764 string. */
5765 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5766 it->string = it->overlay_strings[0];
5767 it->from_overlay = Qnil;
5768 it->stop_charpos = 0;
5769 eassert (STRINGP (it->string));
5770 it->end_charpos = SCHARS (it->string);
5771 it->prev_stop = 0;
5772 it->base_level_stop = 0;
5773 it->multibyte_p = STRING_MULTIBYTE (it->string);
5774 it->method = GET_FROM_STRING;
5775 it->from_disp_prop_p = 0;
5777 /* Force paragraph direction to be that of the parent
5778 buffer. */
5779 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
5780 it->paragraph_embedding = it->bidi_it.paragraph_dir;
5781 else
5782 it->paragraph_embedding = L2R;
5784 /* Set up the bidi iterator for this overlay string. */
5785 if (it->bidi_p)
5787 ptrdiff_t pos = (charpos > 0 ? charpos : IT_CHARPOS (*it));
5789 it->bidi_it.string.lstring = it->string;
5790 it->bidi_it.string.s = NULL;
5791 it->bidi_it.string.schars = SCHARS (it->string);
5792 it->bidi_it.string.bufpos = pos;
5793 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5794 it->bidi_it.string.unibyte = !it->multibyte_p;
5795 it->bidi_it.w = it->w;
5796 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5798 return 1;
5801 it->current.overlay_string_index = -1;
5802 return 0;
5805 static int
5806 get_overlay_strings (struct it *it, ptrdiff_t charpos)
5808 it->string = Qnil;
5809 it->method = GET_FROM_BUFFER;
5811 (void) get_overlay_strings_1 (it, charpos, 1);
5813 CHECK_IT (it);
5815 /* Value is non-zero if we found at least one overlay string. */
5816 return STRINGP (it->string);
5821 /***********************************************************************
5822 Saving and restoring state
5823 ***********************************************************************/
5825 /* Save current settings of IT on IT->stack. Called, for example,
5826 before setting up IT for an overlay string, to be able to restore
5827 IT's settings to what they were after the overlay string has been
5828 processed. If POSITION is non-NULL, it is the position to save on
5829 the stack instead of IT->position. */
5831 static void
5832 push_it (struct it *it, struct text_pos *position)
5834 struct iterator_stack_entry *p;
5836 eassert (it->sp < IT_STACK_SIZE);
5837 p = it->stack + it->sp;
5839 p->stop_charpos = it->stop_charpos;
5840 p->prev_stop = it->prev_stop;
5841 p->base_level_stop = it->base_level_stop;
5842 p->cmp_it = it->cmp_it;
5843 eassert (it->face_id >= 0);
5844 p->face_id = it->face_id;
5845 p->string = it->string;
5846 p->method = it->method;
5847 p->from_overlay = it->from_overlay;
5848 switch (p->method)
5850 case GET_FROM_IMAGE:
5851 p->u.image.object = it->object;
5852 p->u.image.image_id = it->image_id;
5853 p->u.image.slice = it->slice;
5854 break;
5855 case GET_FROM_STRETCH:
5856 p->u.stretch.object = it->object;
5857 break;
5859 p->position = position ? *position : it->position;
5860 p->current = it->current;
5861 p->end_charpos = it->end_charpos;
5862 p->string_nchars = it->string_nchars;
5863 p->area = it->area;
5864 p->multibyte_p = it->multibyte_p;
5865 p->avoid_cursor_p = it->avoid_cursor_p;
5866 p->space_width = it->space_width;
5867 p->font_height = it->font_height;
5868 p->voffset = it->voffset;
5869 p->string_from_display_prop_p = it->string_from_display_prop_p;
5870 p->string_from_prefix_prop_p = it->string_from_prefix_prop_p;
5871 p->display_ellipsis_p = 0;
5872 p->line_wrap = it->line_wrap;
5873 p->bidi_p = it->bidi_p;
5874 p->paragraph_embedding = it->paragraph_embedding;
5875 p->from_disp_prop_p = it->from_disp_prop_p;
5876 ++it->sp;
5878 /* Save the state of the bidi iterator as well. */
5879 if (it->bidi_p)
5880 bidi_push_it (&it->bidi_it);
5883 static void
5884 iterate_out_of_display_property (struct it *it)
5886 int buffer_p = !STRINGP (it->string);
5887 ptrdiff_t eob = (buffer_p ? ZV : it->end_charpos);
5888 ptrdiff_t bob = (buffer_p ? BEGV : 0);
5890 eassert (eob >= CHARPOS (it->position) && CHARPOS (it->position) >= bob);
5892 /* Maybe initialize paragraph direction. If we are at the beginning
5893 of a new paragraph, next_element_from_buffer may not have a
5894 chance to do that. */
5895 if (it->bidi_it.first_elt && it->bidi_it.charpos < eob)
5896 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
5897 /* prev_stop can be zero, so check against BEGV as well. */
5898 while (it->bidi_it.charpos >= bob
5899 && it->prev_stop <= it->bidi_it.charpos
5900 && it->bidi_it.charpos < CHARPOS (it->position)
5901 && it->bidi_it.charpos < eob)
5902 bidi_move_to_visually_next (&it->bidi_it);
5903 /* Record the stop_pos we just crossed, for when we cross it
5904 back, maybe. */
5905 if (it->bidi_it.charpos > CHARPOS (it->position))
5906 it->prev_stop = CHARPOS (it->position);
5907 /* If we ended up not where pop_it put us, resync IT's
5908 positional members with the bidi iterator. */
5909 if (it->bidi_it.charpos != CHARPOS (it->position))
5910 SET_TEXT_POS (it->position, it->bidi_it.charpos, it->bidi_it.bytepos);
5911 if (buffer_p)
5912 it->current.pos = it->position;
5913 else
5914 it->current.string_pos = it->position;
5917 /* Restore IT's settings from IT->stack. Called, for example, when no
5918 more overlay strings must be processed, and we return to delivering
5919 display elements from a buffer, or when the end of a string from a
5920 `display' property is reached and we return to delivering display
5921 elements from an overlay string, or from a buffer. */
5923 static void
5924 pop_it (struct it *it)
5926 struct iterator_stack_entry *p;
5927 int from_display_prop = it->from_disp_prop_p;
5929 eassert (it->sp > 0);
5930 --it->sp;
5931 p = it->stack + it->sp;
5932 it->stop_charpos = p->stop_charpos;
5933 it->prev_stop = p->prev_stop;
5934 it->base_level_stop = p->base_level_stop;
5935 it->cmp_it = p->cmp_it;
5936 it->face_id = p->face_id;
5937 it->current = p->current;
5938 it->position = p->position;
5939 it->string = p->string;
5940 it->from_overlay = p->from_overlay;
5941 if (NILP (it->string))
5942 SET_TEXT_POS (it->current.string_pos, -1, -1);
5943 it->method = p->method;
5944 switch (it->method)
5946 case GET_FROM_IMAGE:
5947 it->image_id = p->u.image.image_id;
5948 it->object = p->u.image.object;
5949 it->slice = p->u.image.slice;
5950 break;
5951 case GET_FROM_STRETCH:
5952 it->object = p->u.stretch.object;
5953 break;
5954 case GET_FROM_BUFFER:
5955 it->object = it->w->contents;
5956 break;
5957 case GET_FROM_STRING:
5958 it->object = it->string;
5959 break;
5960 case GET_FROM_DISPLAY_VECTOR:
5961 if (it->s)
5962 it->method = GET_FROM_C_STRING;
5963 else if (STRINGP (it->string))
5964 it->method = GET_FROM_STRING;
5965 else
5967 it->method = GET_FROM_BUFFER;
5968 it->object = it->w->contents;
5971 it->end_charpos = p->end_charpos;
5972 it->string_nchars = p->string_nchars;
5973 it->area = p->area;
5974 it->multibyte_p = p->multibyte_p;
5975 it->avoid_cursor_p = p->avoid_cursor_p;
5976 it->space_width = p->space_width;
5977 it->font_height = p->font_height;
5978 it->voffset = p->voffset;
5979 it->string_from_display_prop_p = p->string_from_display_prop_p;
5980 it->string_from_prefix_prop_p = p->string_from_prefix_prop_p;
5981 it->line_wrap = p->line_wrap;
5982 it->bidi_p = p->bidi_p;
5983 it->paragraph_embedding = p->paragraph_embedding;
5984 it->from_disp_prop_p = p->from_disp_prop_p;
5985 if (it->bidi_p)
5987 bidi_pop_it (&it->bidi_it);
5988 /* Bidi-iterate until we get out of the portion of text, if any,
5989 covered by a `display' text property or by an overlay with
5990 `display' property. (We cannot just jump there, because the
5991 internal coherency of the bidi iterator state can not be
5992 preserved across such jumps.) We also must determine the
5993 paragraph base direction if the overlay we just processed is
5994 at the beginning of a new paragraph. */
5995 if (from_display_prop
5996 && (it->method == GET_FROM_BUFFER || it->method == GET_FROM_STRING))
5997 iterate_out_of_display_property (it);
5999 eassert ((BUFFERP (it->object)
6000 && IT_CHARPOS (*it) == it->bidi_it.charpos
6001 && IT_BYTEPOS (*it) == it->bidi_it.bytepos)
6002 || (STRINGP (it->object)
6003 && IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
6004 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos)
6005 || (CONSP (it->object) && it->method == GET_FROM_STRETCH));
6011 /***********************************************************************
6012 Moving over lines
6013 ***********************************************************************/
6015 /* Set IT's current position to the previous line start. */
6017 static void
6018 back_to_previous_line_start (struct it *it)
6020 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
6022 DEC_BOTH (cp, bp);
6023 IT_CHARPOS (*it) = find_newline_no_quit (cp, bp, -1, &IT_BYTEPOS (*it));
6027 /* Move IT to the next line start.
6029 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
6030 we skipped over part of the text (as opposed to moving the iterator
6031 continuously over the text). Otherwise, don't change the value
6032 of *SKIPPED_P.
6034 If BIDI_IT_PREV is non-NULL, store into it the state of the bidi
6035 iterator on the newline, if it was found.
6037 Newlines may come from buffer text, overlay strings, or strings
6038 displayed via the `display' property. That's the reason we can't
6039 simply use find_newline_no_quit.
6041 Note that this function may not skip over invisible text that is so
6042 because of text properties and immediately follows a newline. If
6043 it would, function reseat_at_next_visible_line_start, when called
6044 from set_iterator_to_next, would effectively make invisible
6045 characters following a newline part of the wrong glyph row, which
6046 leads to wrong cursor motion. */
6048 static int
6049 forward_to_next_line_start (struct it *it, int *skipped_p,
6050 struct bidi_it *bidi_it_prev)
6052 ptrdiff_t old_selective;
6053 int newline_found_p, n;
6054 const int MAX_NEWLINE_DISTANCE = 500;
6056 /* If already on a newline, just consume it to avoid unintended
6057 skipping over invisible text below. */
6058 if (it->what == IT_CHARACTER
6059 && it->c == '\n'
6060 && CHARPOS (it->position) == IT_CHARPOS (*it))
6062 if (it->bidi_p && bidi_it_prev)
6063 *bidi_it_prev = it->bidi_it;
6064 set_iterator_to_next (it, 0);
6065 it->c = 0;
6066 return 1;
6069 /* Don't handle selective display in the following. It's (a)
6070 unnecessary because it's done by the caller, and (b) leads to an
6071 infinite recursion because next_element_from_ellipsis indirectly
6072 calls this function. */
6073 old_selective = it->selective;
6074 it->selective = 0;
6076 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
6077 from buffer text. */
6078 for (n = newline_found_p = 0;
6079 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
6080 n += STRINGP (it->string) ? 0 : 1)
6082 if (!get_next_display_element (it))
6083 return 0;
6084 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
6085 if (newline_found_p && it->bidi_p && bidi_it_prev)
6086 *bidi_it_prev = it->bidi_it;
6087 set_iterator_to_next (it, 0);
6090 /* If we didn't find a newline near enough, see if we can use a
6091 short-cut. */
6092 if (!newline_found_p)
6094 ptrdiff_t bytepos, start = IT_CHARPOS (*it);
6095 ptrdiff_t limit = find_newline_no_quit (start, IT_BYTEPOS (*it),
6096 1, &bytepos);
6097 Lisp_Object pos;
6099 eassert (!STRINGP (it->string));
6101 /* If there isn't any `display' property in sight, and no
6102 overlays, we can just use the position of the newline in
6103 buffer text. */
6104 if (it->stop_charpos >= limit
6105 || ((pos = Fnext_single_property_change (make_number (start),
6106 Qdisplay, Qnil,
6107 make_number (limit)),
6108 NILP (pos))
6109 && next_overlay_change (start) == ZV))
6111 if (!it->bidi_p)
6113 IT_CHARPOS (*it) = limit;
6114 IT_BYTEPOS (*it) = bytepos;
6116 else
6118 struct bidi_it bprev;
6120 /* Help bidi.c avoid expensive searches for display
6121 properties and overlays, by telling it that there are
6122 none up to `limit'. */
6123 if (it->bidi_it.disp_pos < limit)
6125 it->bidi_it.disp_pos = limit;
6126 it->bidi_it.disp_prop = 0;
6128 do {
6129 bprev = it->bidi_it;
6130 bidi_move_to_visually_next (&it->bidi_it);
6131 } while (it->bidi_it.charpos != limit);
6132 IT_CHARPOS (*it) = limit;
6133 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6134 if (bidi_it_prev)
6135 *bidi_it_prev = bprev;
6137 *skipped_p = newline_found_p = 1;
6139 else
6141 while (get_next_display_element (it)
6142 && !newline_found_p)
6144 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
6145 if (newline_found_p && it->bidi_p && bidi_it_prev)
6146 *bidi_it_prev = it->bidi_it;
6147 set_iterator_to_next (it, 0);
6152 it->selective = old_selective;
6153 return newline_found_p;
6157 /* Set IT's current position to the previous visible line start. Skip
6158 invisible text that is so either due to text properties or due to
6159 selective display. Caution: this does not change IT->current_x and
6160 IT->hpos. */
6162 static void
6163 back_to_previous_visible_line_start (struct it *it)
6165 while (IT_CHARPOS (*it) > BEGV)
6167 back_to_previous_line_start (it);
6169 if (IT_CHARPOS (*it) <= BEGV)
6170 break;
6172 /* If selective > 0, then lines indented more than its value are
6173 invisible. */
6174 if (it->selective > 0
6175 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6176 it->selective))
6177 continue;
6179 /* Check the newline before point for invisibility. */
6181 Lisp_Object prop;
6182 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
6183 Qinvisible, it->window);
6184 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6185 continue;
6188 if (IT_CHARPOS (*it) <= BEGV)
6189 break;
6192 struct it it2;
6193 void *it2data = NULL;
6194 ptrdiff_t pos;
6195 ptrdiff_t beg, end;
6196 Lisp_Object val, overlay;
6198 SAVE_IT (it2, *it, it2data);
6200 /* If newline is part of a composition, continue from start of composition */
6201 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
6202 && beg < IT_CHARPOS (*it))
6203 goto replaced;
6205 /* If newline is replaced by a display property, find start of overlay
6206 or interval and continue search from that point. */
6207 pos = --IT_CHARPOS (it2);
6208 --IT_BYTEPOS (it2);
6209 it2.sp = 0;
6210 bidi_unshelve_cache (NULL, 0);
6211 it2.string_from_display_prop_p = 0;
6212 it2.from_disp_prop_p = 0;
6213 if (handle_display_prop (&it2) == HANDLED_RETURN
6214 && !NILP (val = get_char_property_and_overlay
6215 (make_number (pos), Qdisplay, Qnil, &overlay))
6216 && (OVERLAYP (overlay)
6217 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
6218 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
6220 RESTORE_IT (it, it, it2data);
6221 goto replaced;
6224 /* Newline is not replaced by anything -- so we are done. */
6225 RESTORE_IT (it, it, it2data);
6226 break;
6228 replaced:
6229 if (beg < BEGV)
6230 beg = BEGV;
6231 IT_CHARPOS (*it) = beg;
6232 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
6236 it->continuation_lines_width = 0;
6238 eassert (IT_CHARPOS (*it) >= BEGV);
6239 eassert (IT_CHARPOS (*it) == BEGV
6240 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6241 CHECK_IT (it);
6245 /* Reseat iterator IT at the previous visible line start. Skip
6246 invisible text that is so either due to text properties or due to
6247 selective display. At the end, update IT's overlay information,
6248 face information etc. */
6250 void
6251 reseat_at_previous_visible_line_start (struct it *it)
6253 back_to_previous_visible_line_start (it);
6254 reseat (it, it->current.pos, 1);
6255 CHECK_IT (it);
6259 /* Reseat iterator IT on the next visible line start in the current
6260 buffer. ON_NEWLINE_P non-zero means position IT on the newline
6261 preceding the line start. Skip over invisible text that is so
6262 because of selective display. Compute faces, overlays etc at the
6263 new position. Note that this function does not skip over text that
6264 is invisible because of text properties. */
6266 static void
6267 reseat_at_next_visible_line_start (struct it *it, int on_newline_p)
6269 int newline_found_p, skipped_p = 0;
6270 struct bidi_it bidi_it_prev;
6272 newline_found_p = forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6274 /* Skip over lines that are invisible because they are indented
6275 more than the value of IT->selective. */
6276 if (it->selective > 0)
6277 while (IT_CHARPOS (*it) < ZV
6278 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6279 it->selective))
6281 eassert (IT_BYTEPOS (*it) == BEGV
6282 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6283 newline_found_p =
6284 forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6287 /* Position on the newline if that's what's requested. */
6288 if (on_newline_p && newline_found_p)
6290 if (STRINGP (it->string))
6292 if (IT_STRING_CHARPOS (*it) > 0)
6294 if (!it->bidi_p)
6296 --IT_STRING_CHARPOS (*it);
6297 --IT_STRING_BYTEPOS (*it);
6299 else
6301 /* We need to restore the bidi iterator to the state
6302 it had on the newline, and resync the IT's
6303 position with that. */
6304 it->bidi_it = bidi_it_prev;
6305 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
6306 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
6310 else if (IT_CHARPOS (*it) > BEGV)
6312 if (!it->bidi_p)
6314 --IT_CHARPOS (*it);
6315 --IT_BYTEPOS (*it);
6317 else
6319 /* We need to restore the bidi iterator to the state it
6320 had on the newline and resync IT with that. */
6321 it->bidi_it = bidi_it_prev;
6322 IT_CHARPOS (*it) = it->bidi_it.charpos;
6323 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6325 reseat (it, it->current.pos, 0);
6328 else if (skipped_p)
6329 reseat (it, it->current.pos, 0);
6331 CHECK_IT (it);
6336 /***********************************************************************
6337 Changing an iterator's position
6338 ***********************************************************************/
6340 /* Change IT's current position to POS in current_buffer. If FORCE_P
6341 is non-zero, always check for text properties at the new position.
6342 Otherwise, text properties are only looked up if POS >=
6343 IT->check_charpos of a property. */
6345 static void
6346 reseat (struct it *it, struct text_pos pos, int force_p)
6348 ptrdiff_t original_pos = IT_CHARPOS (*it);
6350 reseat_1 (it, pos, 0);
6352 /* Determine where to check text properties. Avoid doing it
6353 where possible because text property lookup is very expensive. */
6354 if (force_p
6355 || CHARPOS (pos) > it->stop_charpos
6356 || CHARPOS (pos) < original_pos)
6358 if (it->bidi_p)
6360 /* For bidi iteration, we need to prime prev_stop and
6361 base_level_stop with our best estimations. */
6362 /* Implementation note: Of course, POS is not necessarily a
6363 stop position, so assigning prev_pos to it is a lie; we
6364 should have called compute_stop_backwards. However, if
6365 the current buffer does not include any R2L characters,
6366 that call would be a waste of cycles, because the
6367 iterator will never move back, and thus never cross this
6368 "fake" stop position. So we delay that backward search
6369 until the time we really need it, in next_element_from_buffer. */
6370 if (CHARPOS (pos) != it->prev_stop)
6371 it->prev_stop = CHARPOS (pos);
6372 if (CHARPOS (pos) < it->base_level_stop)
6373 it->base_level_stop = 0; /* meaning it's unknown */
6374 handle_stop (it);
6376 else
6378 handle_stop (it);
6379 it->prev_stop = it->base_level_stop = 0;
6384 CHECK_IT (it);
6388 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
6389 IT->stop_pos to POS, also. */
6391 static void
6392 reseat_1 (struct it *it, struct text_pos pos, int set_stop_p)
6394 /* Don't call this function when scanning a C string. */
6395 eassert (it->s == NULL);
6397 /* POS must be a reasonable value. */
6398 eassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
6400 it->current.pos = it->position = pos;
6401 it->end_charpos = ZV;
6402 it->dpvec = NULL;
6403 it->current.dpvec_index = -1;
6404 it->current.overlay_string_index = -1;
6405 IT_STRING_CHARPOS (*it) = -1;
6406 IT_STRING_BYTEPOS (*it) = -1;
6407 it->string = Qnil;
6408 it->method = GET_FROM_BUFFER;
6409 it->object = it->w->contents;
6410 it->area = TEXT_AREA;
6411 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
6412 it->sp = 0;
6413 it->string_from_display_prop_p = 0;
6414 it->string_from_prefix_prop_p = 0;
6416 it->from_disp_prop_p = 0;
6417 it->face_before_selective_p = 0;
6418 if (it->bidi_p)
6420 bidi_init_it (IT_CHARPOS (*it), IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6421 &it->bidi_it);
6422 bidi_unshelve_cache (NULL, 0);
6423 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6424 it->bidi_it.string.s = NULL;
6425 it->bidi_it.string.lstring = Qnil;
6426 it->bidi_it.string.bufpos = 0;
6427 it->bidi_it.string.unibyte = 0;
6428 it->bidi_it.w = it->w;
6431 if (set_stop_p)
6433 it->stop_charpos = CHARPOS (pos);
6434 it->base_level_stop = CHARPOS (pos);
6436 /* This make the information stored in it->cmp_it invalidate. */
6437 it->cmp_it.id = -1;
6441 /* Set up IT for displaying a string, starting at CHARPOS in window W.
6442 If S is non-null, it is a C string to iterate over. Otherwise,
6443 STRING gives a Lisp string to iterate over.
6445 If PRECISION > 0, don't return more then PRECISION number of
6446 characters from the string.
6448 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
6449 characters have been returned. FIELD_WIDTH < 0 means an infinite
6450 field width.
6452 MULTIBYTE = 0 means disable processing of multibyte characters,
6453 MULTIBYTE > 0 means enable it,
6454 MULTIBYTE < 0 means use IT->multibyte_p.
6456 IT must be initialized via a prior call to init_iterator before
6457 calling this function. */
6459 static void
6460 reseat_to_string (struct it *it, const char *s, Lisp_Object string,
6461 ptrdiff_t charpos, ptrdiff_t precision, int field_width,
6462 int multibyte)
6464 /* No region in strings. */
6465 it->region_beg_charpos = it->region_end_charpos = -1;
6467 /* No text property checks performed by default, but see below. */
6468 it->stop_charpos = -1;
6470 /* Set iterator position and end position. */
6471 memset (&it->current, 0, sizeof it->current);
6472 it->current.overlay_string_index = -1;
6473 it->current.dpvec_index = -1;
6474 eassert (charpos >= 0);
6476 /* If STRING is specified, use its multibyteness, otherwise use the
6477 setting of MULTIBYTE, if specified. */
6478 if (multibyte >= 0)
6479 it->multibyte_p = multibyte > 0;
6481 /* Bidirectional reordering of strings is controlled by the default
6482 value of bidi-display-reordering. Don't try to reorder while
6483 loading loadup.el, as the necessary character property tables are
6484 not yet available. */
6485 it->bidi_p =
6486 NILP (Vpurify_flag)
6487 && !NILP (BVAR (&buffer_defaults, bidi_display_reordering));
6489 if (s == NULL)
6491 eassert (STRINGP (string));
6492 it->string = string;
6493 it->s = NULL;
6494 it->end_charpos = it->string_nchars = SCHARS (string);
6495 it->method = GET_FROM_STRING;
6496 it->current.string_pos = string_pos (charpos, string);
6498 if (it->bidi_p)
6500 it->bidi_it.string.lstring = string;
6501 it->bidi_it.string.s = NULL;
6502 it->bidi_it.string.schars = it->end_charpos;
6503 it->bidi_it.string.bufpos = 0;
6504 it->bidi_it.string.from_disp_str = 0;
6505 it->bidi_it.string.unibyte = !it->multibyte_p;
6506 it->bidi_it.w = it->w;
6507 bidi_init_it (charpos, IT_STRING_BYTEPOS (*it),
6508 FRAME_WINDOW_P (it->f), &it->bidi_it);
6511 else
6513 it->s = (const unsigned char *) s;
6514 it->string = Qnil;
6516 /* Note that we use IT->current.pos, not it->current.string_pos,
6517 for displaying C strings. */
6518 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
6519 if (it->multibyte_p)
6521 it->current.pos = c_string_pos (charpos, s, 1);
6522 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
6524 else
6526 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
6527 it->end_charpos = it->string_nchars = strlen (s);
6530 if (it->bidi_p)
6532 it->bidi_it.string.lstring = Qnil;
6533 it->bidi_it.string.s = (const unsigned char *) s;
6534 it->bidi_it.string.schars = it->end_charpos;
6535 it->bidi_it.string.bufpos = 0;
6536 it->bidi_it.string.from_disp_str = 0;
6537 it->bidi_it.string.unibyte = !it->multibyte_p;
6538 it->bidi_it.w = it->w;
6539 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6540 &it->bidi_it);
6542 it->method = GET_FROM_C_STRING;
6545 /* PRECISION > 0 means don't return more than PRECISION characters
6546 from the string. */
6547 if (precision > 0 && it->end_charpos - charpos > precision)
6549 it->end_charpos = it->string_nchars = charpos + precision;
6550 if (it->bidi_p)
6551 it->bidi_it.string.schars = it->end_charpos;
6554 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
6555 characters have been returned. FIELD_WIDTH == 0 means don't pad,
6556 FIELD_WIDTH < 0 means infinite field width. This is useful for
6557 padding with `-' at the end of a mode line. */
6558 if (field_width < 0)
6559 field_width = INFINITY;
6560 /* Implementation note: We deliberately don't enlarge
6561 it->bidi_it.string.schars here to fit it->end_charpos, because
6562 the bidi iterator cannot produce characters out of thin air. */
6563 if (field_width > it->end_charpos - charpos)
6564 it->end_charpos = charpos + field_width;
6566 /* Use the standard display table for displaying strings. */
6567 if (DISP_TABLE_P (Vstandard_display_table))
6568 it->dp = XCHAR_TABLE (Vstandard_display_table);
6570 it->stop_charpos = charpos;
6571 it->prev_stop = charpos;
6572 it->base_level_stop = 0;
6573 if (it->bidi_p)
6575 it->bidi_it.first_elt = 1;
6576 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6577 it->bidi_it.disp_pos = -1;
6579 if (s == NULL && it->multibyte_p)
6581 ptrdiff_t endpos = SCHARS (it->string);
6582 if (endpos > it->end_charpos)
6583 endpos = it->end_charpos;
6584 composition_compute_stop_pos (&it->cmp_it, charpos, -1, endpos,
6585 it->string);
6587 CHECK_IT (it);
6592 /***********************************************************************
6593 Iteration
6594 ***********************************************************************/
6596 /* Map enum it_method value to corresponding next_element_from_* function. */
6598 static int (* get_next_element[NUM_IT_METHODS]) (struct it *it) =
6600 next_element_from_buffer,
6601 next_element_from_display_vector,
6602 next_element_from_string,
6603 next_element_from_c_string,
6604 next_element_from_image,
6605 next_element_from_stretch
6608 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
6611 /* Return 1 iff a character at CHARPOS (and BYTEPOS) is composed
6612 (possibly with the following characters). */
6614 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS) \
6615 ((IT)->cmp_it.id >= 0 \
6616 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
6617 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
6618 END_CHARPOS, (IT)->w, \
6619 FACE_FROM_ID ((IT)->f, (IT)->face_id), \
6620 (IT)->string)))
6623 /* Lookup the char-table Vglyphless_char_display for character C (-1
6624 if we want information for no-font case), and return the display
6625 method symbol. By side-effect, update it->what and
6626 it->glyphless_method. This function is called from
6627 get_next_display_element for each character element, and from
6628 x_produce_glyphs when no suitable font was found. */
6630 Lisp_Object
6631 lookup_glyphless_char_display (int c, struct it *it)
6633 Lisp_Object glyphless_method = Qnil;
6635 if (CHAR_TABLE_P (Vglyphless_char_display)
6636 && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display)) >= 1)
6638 if (c >= 0)
6640 glyphless_method = CHAR_TABLE_REF (Vglyphless_char_display, c);
6641 if (CONSP (glyphless_method))
6642 glyphless_method = FRAME_WINDOW_P (it->f)
6643 ? XCAR (glyphless_method)
6644 : XCDR (glyphless_method);
6646 else
6647 glyphless_method = XCHAR_TABLE (Vglyphless_char_display)->extras[0];
6650 retry:
6651 if (NILP (glyphless_method))
6653 if (c >= 0)
6654 /* The default is to display the character by a proper font. */
6655 return Qnil;
6656 /* The default for the no-font case is to display an empty box. */
6657 glyphless_method = Qempty_box;
6659 if (EQ (glyphless_method, Qzero_width))
6661 if (c >= 0)
6662 return glyphless_method;
6663 /* This method can't be used for the no-font case. */
6664 glyphless_method = Qempty_box;
6666 if (EQ (glyphless_method, Qthin_space))
6667 it->glyphless_method = GLYPHLESS_DISPLAY_THIN_SPACE;
6668 else if (EQ (glyphless_method, Qempty_box))
6669 it->glyphless_method = GLYPHLESS_DISPLAY_EMPTY_BOX;
6670 else if (EQ (glyphless_method, Qhex_code))
6671 it->glyphless_method = GLYPHLESS_DISPLAY_HEX_CODE;
6672 else if (STRINGP (glyphless_method))
6673 it->glyphless_method = GLYPHLESS_DISPLAY_ACRONYM;
6674 else
6676 /* Invalid value. We use the default method. */
6677 glyphless_method = Qnil;
6678 goto retry;
6680 it->what = IT_GLYPHLESS;
6681 return glyphless_method;
6684 /* Load IT's display element fields with information about the next
6685 display element from the current position of IT. Value is zero if
6686 end of buffer (or C string) is reached. */
6688 static struct frame *last_escape_glyph_frame = NULL;
6689 static int last_escape_glyph_face_id = (1 << FACE_ID_BITS);
6690 static int last_escape_glyph_merged_face_id = 0;
6692 struct frame *last_glyphless_glyph_frame = NULL;
6693 int last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
6694 int last_glyphless_glyph_merged_face_id = 0;
6696 static int
6697 get_next_display_element (struct it *it)
6699 /* Non-zero means that we found a display element. Zero means that
6700 we hit the end of what we iterate over. Performance note: the
6701 function pointer `method' used here turns out to be faster than
6702 using a sequence of if-statements. */
6703 int success_p;
6705 get_next:
6706 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
6708 if (it->what == IT_CHARACTER)
6710 /* UAX#9, L4: "A character is depicted by a mirrored glyph if
6711 and only if (a) the resolved directionality of that character
6712 is R..." */
6713 /* FIXME: Do we need an exception for characters from display
6714 tables? */
6715 if (it->bidi_p && it->bidi_it.type == STRONG_R)
6716 it->c = bidi_mirror_char (it->c);
6717 /* Map via display table or translate control characters.
6718 IT->c, IT->len etc. have been set to the next character by
6719 the function call above. If we have a display table, and it
6720 contains an entry for IT->c, translate it. Don't do this if
6721 IT->c itself comes from a display table, otherwise we could
6722 end up in an infinite recursion. (An alternative could be to
6723 count the recursion depth of this function and signal an
6724 error when a certain maximum depth is reached.) Is it worth
6725 it? */
6726 if (success_p && it->dpvec == NULL)
6728 Lisp_Object dv;
6729 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
6730 int nonascii_space_p = 0;
6731 int nonascii_hyphen_p = 0;
6732 int c = it->c; /* This is the character to display. */
6734 if (! it->multibyte_p && ! ASCII_CHAR_P (c))
6736 eassert (SINGLE_BYTE_CHAR_P (c));
6737 if (unibyte_display_via_language_environment)
6739 c = DECODE_CHAR (unibyte, c);
6740 if (c < 0)
6741 c = BYTE8_TO_CHAR (it->c);
6743 else
6744 c = BYTE8_TO_CHAR (it->c);
6747 if (it->dp
6748 && (dv = DISP_CHAR_VECTOR (it->dp, c),
6749 VECTORP (dv)))
6751 struct Lisp_Vector *v = XVECTOR (dv);
6753 /* Return the first character from the display table
6754 entry, if not empty. If empty, don't display the
6755 current character. */
6756 if (v->header.size)
6758 it->dpvec_char_len = it->len;
6759 it->dpvec = v->contents;
6760 it->dpend = v->contents + v->header.size;
6761 it->current.dpvec_index = 0;
6762 it->dpvec_face_id = -1;
6763 it->saved_face_id = it->face_id;
6764 it->method = GET_FROM_DISPLAY_VECTOR;
6765 it->ellipsis_p = 0;
6767 else
6769 set_iterator_to_next (it, 0);
6771 goto get_next;
6774 if (! NILP (lookup_glyphless_char_display (c, it)))
6776 if (it->what == IT_GLYPHLESS)
6777 goto done;
6778 /* Don't display this character. */
6779 set_iterator_to_next (it, 0);
6780 goto get_next;
6783 /* If `nobreak-char-display' is non-nil, we display
6784 non-ASCII spaces and hyphens specially. */
6785 if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
6787 if (c == 0xA0)
6788 nonascii_space_p = 1;
6789 else if (c == 0xAD || c == 0x2010 || c == 0x2011)
6790 nonascii_hyphen_p = 1;
6793 /* Translate control characters into `\003' or `^C' form.
6794 Control characters coming from a display table entry are
6795 currently not translated because we use IT->dpvec to hold
6796 the translation. This could easily be changed but I
6797 don't believe that it is worth doing.
6799 The characters handled by `nobreak-char-display' must be
6800 translated too.
6802 Non-printable characters and raw-byte characters are also
6803 translated to octal form. */
6804 if (((c < ' ' || c == 127) /* ASCII control chars */
6805 ? (it->area != TEXT_AREA
6806 /* In mode line, treat \n, \t like other crl chars. */
6807 || (c != '\t'
6808 && it->glyph_row
6809 && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
6810 || (c != '\n' && c != '\t'))
6811 : (nonascii_space_p
6812 || nonascii_hyphen_p
6813 || CHAR_BYTE8_P (c)
6814 || ! CHAR_PRINTABLE_P (c))))
6816 /* C is a control character, non-ASCII space/hyphen,
6817 raw-byte, or a non-printable character which must be
6818 displayed either as '\003' or as `^C' where the '\\'
6819 and '^' can be defined in the display table. Fill
6820 IT->ctl_chars with glyphs for what we have to
6821 display. Then, set IT->dpvec to these glyphs. */
6822 Lisp_Object gc;
6823 int ctl_len;
6824 int face_id;
6825 int lface_id = 0;
6826 int escape_glyph;
6828 /* Handle control characters with ^. */
6830 if (ASCII_CHAR_P (c) && it->ctl_arrow_p)
6832 int g;
6834 g = '^'; /* default glyph for Control */
6835 /* Set IT->ctl_chars[0] to the glyph for `^'. */
6836 if (it->dp
6837 && (gc = DISP_CTRL_GLYPH (it->dp), GLYPH_CODE_P (gc)))
6839 g = GLYPH_CODE_CHAR (gc);
6840 lface_id = GLYPH_CODE_FACE (gc);
6842 if (lface_id)
6844 face_id = merge_faces (it->f, Qt, lface_id, it->face_id);
6846 else if (it->f == last_escape_glyph_frame
6847 && it->face_id == last_escape_glyph_face_id)
6849 face_id = last_escape_glyph_merged_face_id;
6851 else
6853 /* Merge the escape-glyph face into the current face. */
6854 face_id = merge_faces (it->f, Qescape_glyph, 0,
6855 it->face_id);
6856 last_escape_glyph_frame = it->f;
6857 last_escape_glyph_face_id = it->face_id;
6858 last_escape_glyph_merged_face_id = face_id;
6861 XSETINT (it->ctl_chars[0], g);
6862 XSETINT (it->ctl_chars[1], c ^ 0100);
6863 ctl_len = 2;
6864 goto display_control;
6867 /* Handle non-ascii space in the mode where it only gets
6868 highlighting. */
6870 if (nonascii_space_p && EQ (Vnobreak_char_display, Qt))
6872 /* Merge `nobreak-space' into the current face. */
6873 face_id = merge_faces (it->f, Qnobreak_space, 0,
6874 it->face_id);
6875 XSETINT (it->ctl_chars[0], ' ');
6876 ctl_len = 1;
6877 goto display_control;
6880 /* Handle sequences that start with the "escape glyph". */
6882 /* the default escape glyph is \. */
6883 escape_glyph = '\\';
6885 if (it->dp
6886 && (gc = DISP_ESCAPE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
6888 escape_glyph = GLYPH_CODE_CHAR (gc);
6889 lface_id = GLYPH_CODE_FACE (gc);
6891 if (lface_id)
6893 /* The display table specified a face.
6894 Merge it into face_id and also into escape_glyph. */
6895 face_id = merge_faces (it->f, Qt, lface_id,
6896 it->face_id);
6898 else if (it->f == last_escape_glyph_frame
6899 && it->face_id == last_escape_glyph_face_id)
6901 face_id = last_escape_glyph_merged_face_id;
6903 else
6905 /* Merge the escape-glyph face into the current face. */
6906 face_id = merge_faces (it->f, Qescape_glyph, 0,
6907 it->face_id);
6908 last_escape_glyph_frame = it->f;
6909 last_escape_glyph_face_id = it->face_id;
6910 last_escape_glyph_merged_face_id = face_id;
6913 /* Draw non-ASCII hyphen with just highlighting: */
6915 if (nonascii_hyphen_p && EQ (Vnobreak_char_display, Qt))
6917 XSETINT (it->ctl_chars[0], '-');
6918 ctl_len = 1;
6919 goto display_control;
6922 /* Draw non-ASCII space/hyphen with escape glyph: */
6924 if (nonascii_space_p || nonascii_hyphen_p)
6926 XSETINT (it->ctl_chars[0], escape_glyph);
6927 XSETINT (it->ctl_chars[1], nonascii_space_p ? ' ' : '-');
6928 ctl_len = 2;
6929 goto display_control;
6933 char str[10];
6934 int len, i;
6936 if (CHAR_BYTE8_P (c))
6937 /* Display \200 instead of \17777600. */
6938 c = CHAR_TO_BYTE8 (c);
6939 len = sprintf (str, "%03o", c);
6941 XSETINT (it->ctl_chars[0], escape_glyph);
6942 for (i = 0; i < len; i++)
6943 XSETINT (it->ctl_chars[i + 1], str[i]);
6944 ctl_len = len + 1;
6947 display_control:
6948 /* Set up IT->dpvec and return first character from it. */
6949 it->dpvec_char_len = it->len;
6950 it->dpvec = it->ctl_chars;
6951 it->dpend = it->dpvec + ctl_len;
6952 it->current.dpvec_index = 0;
6953 it->dpvec_face_id = face_id;
6954 it->saved_face_id = it->face_id;
6955 it->method = GET_FROM_DISPLAY_VECTOR;
6956 it->ellipsis_p = 0;
6957 goto get_next;
6959 it->char_to_display = c;
6961 else if (success_p)
6963 it->char_to_display = it->c;
6967 /* Adjust face id for a multibyte character. There are no multibyte
6968 character in unibyte text. */
6969 if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
6970 && it->multibyte_p
6971 && success_p
6972 && FRAME_WINDOW_P (it->f))
6974 struct face *face = FACE_FROM_ID (it->f, it->face_id);
6976 if (it->what == IT_COMPOSITION && it->cmp_it.ch >= 0)
6978 /* Automatic composition with glyph-string. */
6979 Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id);
6981 it->face_id = face_for_font (it->f, LGSTRING_FONT (gstring), face);
6983 else
6985 ptrdiff_t pos = (it->s ? -1
6986 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
6987 : IT_CHARPOS (*it));
6988 int c;
6990 if (it->what == IT_CHARACTER)
6991 c = it->char_to_display;
6992 else
6994 struct composition *cmp = composition_table[it->cmp_it.id];
6995 int i;
6997 c = ' ';
6998 for (i = 0; i < cmp->glyph_len; i++)
6999 /* TAB in a composition means display glyphs with
7000 padding space on the left or right. */
7001 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
7002 break;
7004 it->face_id = FACE_FOR_CHAR (it->f, face, c, pos, it->string);
7008 done:
7009 /* Is this character the last one of a run of characters with
7010 box? If yes, set IT->end_of_box_run_p to 1. */
7011 if (it->face_box_p
7012 && it->s == NULL)
7014 if (it->method == GET_FROM_STRING && it->sp)
7016 int face_id = underlying_face_id (it);
7017 struct face *face = FACE_FROM_ID (it->f, face_id);
7019 if (face)
7021 if (face->box == FACE_NO_BOX)
7023 /* If the box comes from face properties in a
7024 display string, check faces in that string. */
7025 int string_face_id = face_after_it_pos (it);
7026 it->end_of_box_run_p
7027 = (FACE_FROM_ID (it->f, string_face_id)->box
7028 == FACE_NO_BOX);
7030 /* Otherwise, the box comes from the underlying face.
7031 If this is the last string character displayed, check
7032 the next buffer location. */
7033 else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1)
7034 && (it->current.overlay_string_index
7035 == it->n_overlay_strings - 1))
7037 ptrdiff_t ignore;
7038 int next_face_id;
7039 struct text_pos pos = it->current.pos;
7040 INC_TEXT_POS (pos, it->multibyte_p);
7042 next_face_id = face_at_buffer_position
7043 (it->w, CHARPOS (pos), it->region_beg_charpos,
7044 it->region_end_charpos, &ignore,
7045 (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT), 0,
7046 -1);
7047 it->end_of_box_run_p
7048 = (FACE_FROM_ID (it->f, next_face_id)->box
7049 == FACE_NO_BOX);
7053 /* next_element_from_display_vector sets this flag according to
7054 faces of the display vector glyphs, see there. */
7055 else if (it->method != GET_FROM_DISPLAY_VECTOR)
7057 int face_id = face_after_it_pos (it);
7058 it->end_of_box_run_p
7059 = (face_id != it->face_id
7060 && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX);
7063 /* If we reached the end of the object we've been iterating (e.g., a
7064 display string or an overlay string), and there's something on
7065 IT->stack, proceed with what's on the stack. It doesn't make
7066 sense to return zero if there's unprocessed stuff on the stack,
7067 because otherwise that stuff will never be displayed. */
7068 if (!success_p && it->sp > 0)
7070 set_iterator_to_next (it, 0);
7071 success_p = get_next_display_element (it);
7074 /* Value is 0 if end of buffer or string reached. */
7075 return success_p;
7079 /* Move IT to the next display element.
7081 RESEAT_P non-zero means if called on a newline in buffer text,
7082 skip to the next visible line start.
7084 Functions get_next_display_element and set_iterator_to_next are
7085 separate because I find this arrangement easier to handle than a
7086 get_next_display_element function that also increments IT's
7087 position. The way it is we can first look at an iterator's current
7088 display element, decide whether it fits on a line, and if it does,
7089 increment the iterator position. The other way around we probably
7090 would either need a flag indicating whether the iterator has to be
7091 incremented the next time, or we would have to implement a
7092 decrement position function which would not be easy to write. */
7094 void
7095 set_iterator_to_next (struct it *it, int reseat_p)
7097 /* Reset flags indicating start and end of a sequence of characters
7098 with box. Reset them at the start of this function because
7099 moving the iterator to a new position might set them. */
7100 it->start_of_box_run_p = it->end_of_box_run_p = 0;
7102 switch (it->method)
7104 case GET_FROM_BUFFER:
7105 /* The current display element of IT is a character from
7106 current_buffer. Advance in the buffer, and maybe skip over
7107 invisible lines that are so because of selective display. */
7108 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
7109 reseat_at_next_visible_line_start (it, 0);
7110 else if (it->cmp_it.id >= 0)
7112 /* We are currently getting glyphs from a composition. */
7113 int i;
7115 if (! it->bidi_p)
7117 IT_CHARPOS (*it) += it->cmp_it.nchars;
7118 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
7119 if (it->cmp_it.to < it->cmp_it.nglyphs)
7121 it->cmp_it.from = it->cmp_it.to;
7123 else
7125 it->cmp_it.id = -1;
7126 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7127 IT_BYTEPOS (*it),
7128 it->end_charpos, Qnil);
7131 else if (! it->cmp_it.reversed_p)
7133 /* Composition created while scanning forward. */
7134 /* Update IT's char/byte positions to point to the first
7135 character of the next grapheme cluster, or to the
7136 character visually after the current composition. */
7137 for (i = 0; i < it->cmp_it.nchars; i++)
7138 bidi_move_to_visually_next (&it->bidi_it);
7139 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7140 IT_CHARPOS (*it) = it->bidi_it.charpos;
7142 if (it->cmp_it.to < it->cmp_it.nglyphs)
7144 /* Proceed to the next grapheme cluster. */
7145 it->cmp_it.from = it->cmp_it.to;
7147 else
7149 /* No more grapheme clusters in this composition.
7150 Find the next stop position. */
7151 ptrdiff_t stop = it->end_charpos;
7152 if (it->bidi_it.scan_dir < 0)
7153 /* Now we are scanning backward and don't know
7154 where to stop. */
7155 stop = -1;
7156 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7157 IT_BYTEPOS (*it), stop, Qnil);
7160 else
7162 /* Composition created while scanning backward. */
7163 /* Update IT's char/byte positions to point to the last
7164 character of the previous grapheme cluster, or the
7165 character visually after the current composition. */
7166 for (i = 0; i < it->cmp_it.nchars; i++)
7167 bidi_move_to_visually_next (&it->bidi_it);
7168 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7169 IT_CHARPOS (*it) = it->bidi_it.charpos;
7170 if (it->cmp_it.from > 0)
7172 /* Proceed to the previous grapheme cluster. */
7173 it->cmp_it.to = it->cmp_it.from;
7175 else
7177 /* No more grapheme clusters in this composition.
7178 Find the next stop position. */
7179 ptrdiff_t stop = it->end_charpos;
7180 if (it->bidi_it.scan_dir < 0)
7181 /* Now we are scanning backward and don't know
7182 where to stop. */
7183 stop = -1;
7184 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7185 IT_BYTEPOS (*it), stop, Qnil);
7189 else
7191 eassert (it->len != 0);
7193 if (!it->bidi_p)
7195 IT_BYTEPOS (*it) += it->len;
7196 IT_CHARPOS (*it) += 1;
7198 else
7200 int prev_scan_dir = it->bidi_it.scan_dir;
7201 /* If this is a new paragraph, determine its base
7202 direction (a.k.a. its base embedding level). */
7203 if (it->bidi_it.new_paragraph)
7204 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
7205 bidi_move_to_visually_next (&it->bidi_it);
7206 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7207 IT_CHARPOS (*it) = it->bidi_it.charpos;
7208 if (prev_scan_dir != it->bidi_it.scan_dir)
7210 /* As the scan direction was changed, we must
7211 re-compute the stop position for composition. */
7212 ptrdiff_t stop = it->end_charpos;
7213 if (it->bidi_it.scan_dir < 0)
7214 stop = -1;
7215 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7216 IT_BYTEPOS (*it), stop, Qnil);
7219 eassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
7221 break;
7223 case GET_FROM_C_STRING:
7224 /* Current display element of IT is from a C string. */
7225 if (!it->bidi_p
7226 /* If the string position is beyond string's end, it means
7227 next_element_from_c_string is padding the string with
7228 blanks, in which case we bypass the bidi iterator,
7229 because it cannot deal with such virtual characters. */
7230 || IT_CHARPOS (*it) >= it->bidi_it.string.schars)
7232 IT_BYTEPOS (*it) += it->len;
7233 IT_CHARPOS (*it) += 1;
7235 else
7237 bidi_move_to_visually_next (&it->bidi_it);
7238 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7239 IT_CHARPOS (*it) = it->bidi_it.charpos;
7241 break;
7243 case GET_FROM_DISPLAY_VECTOR:
7244 /* Current display element of IT is from a display table entry.
7245 Advance in the display table definition. Reset it to null if
7246 end reached, and continue with characters from buffers/
7247 strings. */
7248 ++it->current.dpvec_index;
7250 /* Restore face of the iterator to what they were before the
7251 display vector entry (these entries may contain faces). */
7252 it->face_id = it->saved_face_id;
7254 if (it->dpvec + it->current.dpvec_index >= it->dpend)
7256 int recheck_faces = it->ellipsis_p;
7258 if (it->s)
7259 it->method = GET_FROM_C_STRING;
7260 else if (STRINGP (it->string))
7261 it->method = GET_FROM_STRING;
7262 else
7264 it->method = GET_FROM_BUFFER;
7265 it->object = it->w->contents;
7268 it->dpvec = NULL;
7269 it->current.dpvec_index = -1;
7271 /* Skip over characters which were displayed via IT->dpvec. */
7272 if (it->dpvec_char_len < 0)
7273 reseat_at_next_visible_line_start (it, 1);
7274 else if (it->dpvec_char_len > 0)
7276 if (it->method == GET_FROM_STRING
7277 && it->current.overlay_string_index >= 0
7278 && it->n_overlay_strings > 0)
7279 it->ignore_overlay_strings_at_pos_p = 1;
7280 it->len = it->dpvec_char_len;
7281 set_iterator_to_next (it, reseat_p);
7284 /* Maybe recheck faces after display vector */
7285 if (recheck_faces)
7286 it->stop_charpos = IT_CHARPOS (*it);
7288 break;
7290 case GET_FROM_STRING:
7291 /* Current display element is a character from a Lisp string. */
7292 eassert (it->s == NULL && STRINGP (it->string));
7293 /* Don't advance past string end. These conditions are true
7294 when set_iterator_to_next is called at the end of
7295 get_next_display_element, in which case the Lisp string is
7296 already exhausted, and all we want is pop the iterator
7297 stack. */
7298 if (it->current.overlay_string_index >= 0)
7300 /* This is an overlay string, so there's no padding with
7301 spaces, and the number of characters in the string is
7302 where the string ends. */
7303 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7304 goto consider_string_end;
7306 else
7308 /* Not an overlay string. There could be padding, so test
7309 against it->end_charpos . */
7310 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7311 goto consider_string_end;
7313 if (it->cmp_it.id >= 0)
7315 int i;
7317 if (! it->bidi_p)
7319 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
7320 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
7321 if (it->cmp_it.to < it->cmp_it.nglyphs)
7322 it->cmp_it.from = it->cmp_it.to;
7323 else
7325 it->cmp_it.id = -1;
7326 composition_compute_stop_pos (&it->cmp_it,
7327 IT_STRING_CHARPOS (*it),
7328 IT_STRING_BYTEPOS (*it),
7329 it->end_charpos, it->string);
7332 else if (! it->cmp_it.reversed_p)
7334 for (i = 0; i < it->cmp_it.nchars; i++)
7335 bidi_move_to_visually_next (&it->bidi_it);
7336 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7337 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7339 if (it->cmp_it.to < it->cmp_it.nglyphs)
7340 it->cmp_it.from = it->cmp_it.to;
7341 else
7343 ptrdiff_t stop = it->end_charpos;
7344 if (it->bidi_it.scan_dir < 0)
7345 stop = -1;
7346 composition_compute_stop_pos (&it->cmp_it,
7347 IT_STRING_CHARPOS (*it),
7348 IT_STRING_BYTEPOS (*it), stop,
7349 it->string);
7352 else
7354 for (i = 0; i < it->cmp_it.nchars; i++)
7355 bidi_move_to_visually_next (&it->bidi_it);
7356 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7357 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7358 if (it->cmp_it.from > 0)
7359 it->cmp_it.to = it->cmp_it.from;
7360 else
7362 ptrdiff_t stop = it->end_charpos;
7363 if (it->bidi_it.scan_dir < 0)
7364 stop = -1;
7365 composition_compute_stop_pos (&it->cmp_it,
7366 IT_STRING_CHARPOS (*it),
7367 IT_STRING_BYTEPOS (*it), stop,
7368 it->string);
7372 else
7374 if (!it->bidi_p
7375 /* If the string position is beyond string's end, it
7376 means next_element_from_string is padding the string
7377 with blanks, in which case we bypass the bidi
7378 iterator, because it cannot deal with such virtual
7379 characters. */
7380 || IT_STRING_CHARPOS (*it) >= it->bidi_it.string.schars)
7382 IT_STRING_BYTEPOS (*it) += it->len;
7383 IT_STRING_CHARPOS (*it) += 1;
7385 else
7387 int prev_scan_dir = it->bidi_it.scan_dir;
7389 bidi_move_to_visually_next (&it->bidi_it);
7390 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7391 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7392 if (prev_scan_dir != it->bidi_it.scan_dir)
7394 ptrdiff_t stop = it->end_charpos;
7396 if (it->bidi_it.scan_dir < 0)
7397 stop = -1;
7398 composition_compute_stop_pos (&it->cmp_it,
7399 IT_STRING_CHARPOS (*it),
7400 IT_STRING_BYTEPOS (*it), stop,
7401 it->string);
7406 consider_string_end:
7408 if (it->current.overlay_string_index >= 0)
7410 /* IT->string is an overlay string. Advance to the
7411 next, if there is one. */
7412 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7414 it->ellipsis_p = 0;
7415 next_overlay_string (it);
7416 if (it->ellipsis_p)
7417 setup_for_ellipsis (it, 0);
7420 else
7422 /* IT->string is not an overlay string. If we reached
7423 its end, and there is something on IT->stack, proceed
7424 with what is on the stack. This can be either another
7425 string, this time an overlay string, or a buffer. */
7426 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
7427 && it->sp > 0)
7429 pop_it (it);
7430 if (it->method == GET_FROM_STRING)
7431 goto consider_string_end;
7434 break;
7436 case GET_FROM_IMAGE:
7437 case GET_FROM_STRETCH:
7438 /* The position etc with which we have to proceed are on
7439 the stack. The position may be at the end of a string,
7440 if the `display' property takes up the whole string. */
7441 eassert (it->sp > 0);
7442 pop_it (it);
7443 if (it->method == GET_FROM_STRING)
7444 goto consider_string_end;
7445 break;
7447 default:
7448 /* There are no other methods defined, so this should be a bug. */
7449 emacs_abort ();
7452 eassert (it->method != GET_FROM_STRING
7453 || (STRINGP (it->string)
7454 && IT_STRING_CHARPOS (*it) >= 0));
7457 /* Load IT's display element fields with information about the next
7458 display element which comes from a display table entry or from the
7459 result of translating a control character to one of the forms `^C'
7460 or `\003'.
7462 IT->dpvec holds the glyphs to return as characters.
7463 IT->saved_face_id holds the face id before the display vector--it
7464 is restored into IT->face_id in set_iterator_to_next. */
7466 static int
7467 next_element_from_display_vector (struct it *it)
7469 Lisp_Object gc;
7470 int prev_face_id = it->face_id;
7471 int next_face_id;
7473 /* Precondition. */
7474 eassert (it->dpvec && it->current.dpvec_index >= 0);
7476 it->face_id = it->saved_face_id;
7478 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
7479 That seemed totally bogus - so I changed it... */
7480 gc = it->dpvec[it->current.dpvec_index];
7482 if (GLYPH_CODE_P (gc))
7484 struct face *this_face, *prev_face, *next_face;
7486 it->c = GLYPH_CODE_CHAR (gc);
7487 it->len = CHAR_BYTES (it->c);
7489 /* The entry may contain a face id to use. Such a face id is
7490 the id of a Lisp face, not a realized face. A face id of
7491 zero means no face is specified. */
7492 if (it->dpvec_face_id >= 0)
7493 it->face_id = it->dpvec_face_id;
7494 else
7496 int lface_id = GLYPH_CODE_FACE (gc);
7497 if (lface_id > 0)
7498 it->face_id = merge_faces (it->f, Qt, lface_id,
7499 it->saved_face_id);
7502 /* Glyphs in the display vector could have the box face, so we
7503 need to set the related flags in the iterator, as
7504 appropriate. */
7505 this_face = FACE_FROM_ID (it->f, it->face_id);
7506 prev_face = FACE_FROM_ID (it->f, prev_face_id);
7508 /* Is this character the first character of a box-face run? */
7509 it->start_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX
7510 && (!prev_face
7511 || prev_face->box == FACE_NO_BOX));
7513 /* For the last character of the box-face run, we need to look
7514 either at the next glyph from the display vector, or at the
7515 face we saw before the display vector. */
7516 next_face_id = it->saved_face_id;
7517 if (it->current.dpvec_index < it->dpend - it->dpvec - 1)
7519 if (it->dpvec_face_id >= 0)
7520 next_face_id = it->dpvec_face_id;
7521 else
7523 int lface_id =
7524 GLYPH_CODE_FACE (it->dpvec[it->current.dpvec_index + 1]);
7526 if (lface_id > 0)
7527 next_face_id = merge_faces (it->f, Qt, lface_id,
7528 it->saved_face_id);
7531 next_face = FACE_FROM_ID (it->f, next_face_id);
7532 it->end_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX
7533 && (!next_face
7534 || next_face->box == FACE_NO_BOX));
7535 it->face_box_p = this_face && this_face->box != FACE_NO_BOX;
7537 else
7538 /* Display table entry is invalid. Return a space. */
7539 it->c = ' ', it->len = 1;
7541 /* Don't change position and object of the iterator here. They are
7542 still the values of the character that had this display table
7543 entry or was translated, and that's what we want. */
7544 it->what = IT_CHARACTER;
7545 return 1;
7548 /* Get the first element of string/buffer in the visual order, after
7549 being reseated to a new position in a string or a buffer. */
7550 static void
7551 get_visually_first_element (struct it *it)
7553 int string_p = STRINGP (it->string) || it->s;
7554 ptrdiff_t eob = (string_p ? it->bidi_it.string.schars : ZV);
7555 ptrdiff_t bob = (string_p ? 0 : BEGV);
7557 if (STRINGP (it->string))
7559 it->bidi_it.charpos = IT_STRING_CHARPOS (*it);
7560 it->bidi_it.bytepos = IT_STRING_BYTEPOS (*it);
7562 else
7564 it->bidi_it.charpos = IT_CHARPOS (*it);
7565 it->bidi_it.bytepos = IT_BYTEPOS (*it);
7568 if (it->bidi_it.charpos == eob)
7570 /* Nothing to do, but reset the FIRST_ELT flag, like
7571 bidi_paragraph_init does, because we are not going to
7572 call it. */
7573 it->bidi_it.first_elt = 0;
7575 else if (it->bidi_it.charpos == bob
7576 || (!string_p
7577 && (FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n'
7578 || FETCH_CHAR (it->bidi_it.bytepos) == '\n')))
7580 /* If we are at the beginning of a line/string, we can produce
7581 the next element right away. */
7582 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
7583 bidi_move_to_visually_next (&it->bidi_it);
7585 else
7587 ptrdiff_t orig_bytepos = it->bidi_it.bytepos;
7589 /* We need to prime the bidi iterator starting at the line's or
7590 string's beginning, before we will be able to produce the
7591 next element. */
7592 if (string_p)
7593 it->bidi_it.charpos = it->bidi_it.bytepos = 0;
7594 else
7595 it->bidi_it.charpos = find_newline_no_quit (IT_CHARPOS (*it),
7596 IT_BYTEPOS (*it), -1,
7597 &it->bidi_it.bytepos);
7598 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
7601 /* Now return to buffer/string position where we were asked
7602 to get the next display element, and produce that. */
7603 bidi_move_to_visually_next (&it->bidi_it);
7605 while (it->bidi_it.bytepos != orig_bytepos
7606 && it->bidi_it.charpos < eob);
7609 /* Adjust IT's position information to where we ended up. */
7610 if (STRINGP (it->string))
7612 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7613 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7615 else
7617 IT_CHARPOS (*it) = it->bidi_it.charpos;
7618 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7621 if (STRINGP (it->string) || !it->s)
7623 ptrdiff_t stop, charpos, bytepos;
7625 if (STRINGP (it->string))
7627 eassert (!it->s);
7628 stop = SCHARS (it->string);
7629 if (stop > it->end_charpos)
7630 stop = it->end_charpos;
7631 charpos = IT_STRING_CHARPOS (*it);
7632 bytepos = IT_STRING_BYTEPOS (*it);
7634 else
7636 stop = it->end_charpos;
7637 charpos = IT_CHARPOS (*it);
7638 bytepos = IT_BYTEPOS (*it);
7640 if (it->bidi_it.scan_dir < 0)
7641 stop = -1;
7642 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos, stop,
7643 it->string);
7647 /* Load IT with the next display element from Lisp string IT->string.
7648 IT->current.string_pos is the current position within the string.
7649 If IT->current.overlay_string_index >= 0, the Lisp string is an
7650 overlay string. */
7652 static int
7653 next_element_from_string (struct it *it)
7655 struct text_pos position;
7657 eassert (STRINGP (it->string));
7658 eassert (!it->bidi_p || EQ (it->string, it->bidi_it.string.lstring));
7659 eassert (IT_STRING_CHARPOS (*it) >= 0);
7660 position = it->current.string_pos;
7662 /* With bidi reordering, the character to display might not be the
7663 character at IT_STRING_CHARPOS. BIDI_IT.FIRST_ELT non-zero means
7664 that we were reseat()ed to a new string, whose paragraph
7665 direction is not known. */
7666 if (it->bidi_p && it->bidi_it.first_elt)
7668 get_visually_first_element (it);
7669 SET_TEXT_POS (position, IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it));
7672 /* Time to check for invisible text? */
7673 if (IT_STRING_CHARPOS (*it) < it->end_charpos)
7675 if (IT_STRING_CHARPOS (*it) >= it->stop_charpos)
7677 if (!(!it->bidi_p
7678 || BIDI_AT_BASE_LEVEL (it->bidi_it)
7679 || IT_STRING_CHARPOS (*it) == it->stop_charpos))
7681 /* With bidi non-linear iteration, we could find
7682 ourselves far beyond the last computed stop_charpos,
7683 with several other stop positions in between that we
7684 missed. Scan them all now, in buffer's logical
7685 order, until we find and handle the last stop_charpos
7686 that precedes our current position. */
7687 handle_stop_backwards (it, it->stop_charpos);
7688 return GET_NEXT_DISPLAY_ELEMENT (it);
7690 else
7692 if (it->bidi_p)
7694 /* Take note of the stop position we just moved
7695 across, for when we will move back across it. */
7696 it->prev_stop = it->stop_charpos;
7697 /* If we are at base paragraph embedding level, take
7698 note of the last stop position seen at this
7699 level. */
7700 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
7701 it->base_level_stop = it->stop_charpos;
7703 handle_stop (it);
7705 /* Since a handler may have changed IT->method, we must
7706 recurse here. */
7707 return GET_NEXT_DISPLAY_ELEMENT (it);
7710 else if (it->bidi_p
7711 /* If we are before prev_stop, we may have overstepped
7712 on our way backwards a stop_pos, and if so, we need
7713 to handle that stop_pos. */
7714 && IT_STRING_CHARPOS (*it) < it->prev_stop
7715 /* We can sometimes back up for reasons that have nothing
7716 to do with bidi reordering. E.g., compositions. The
7717 code below is only needed when we are above the base
7718 embedding level, so test for that explicitly. */
7719 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
7721 /* If we lost track of base_level_stop, we have no better
7722 place for handle_stop_backwards to start from than string
7723 beginning. This happens, e.g., when we were reseated to
7724 the previous screenful of text by vertical-motion. */
7725 if (it->base_level_stop <= 0
7726 || IT_STRING_CHARPOS (*it) < it->base_level_stop)
7727 it->base_level_stop = 0;
7728 handle_stop_backwards (it, it->base_level_stop);
7729 return GET_NEXT_DISPLAY_ELEMENT (it);
7733 if (it->current.overlay_string_index >= 0)
7735 /* Get the next character from an overlay string. In overlay
7736 strings, there is no field width or padding with spaces to
7737 do. */
7738 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7740 it->what = IT_EOB;
7741 return 0;
7743 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
7744 IT_STRING_BYTEPOS (*it),
7745 it->bidi_it.scan_dir < 0
7746 ? -1
7747 : SCHARS (it->string))
7748 && next_element_from_composition (it))
7750 return 1;
7752 else if (STRING_MULTIBYTE (it->string))
7754 const unsigned char *s = (SDATA (it->string)
7755 + IT_STRING_BYTEPOS (*it));
7756 it->c = string_char_and_length (s, &it->len);
7758 else
7760 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
7761 it->len = 1;
7764 else
7766 /* Get the next character from a Lisp string that is not an
7767 overlay string. Such strings come from the mode line, for
7768 example. We may have to pad with spaces, or truncate the
7769 string. See also next_element_from_c_string. */
7770 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7772 it->what = IT_EOB;
7773 return 0;
7775 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
7777 /* Pad with spaces. */
7778 it->c = ' ', it->len = 1;
7779 CHARPOS (position) = BYTEPOS (position) = -1;
7781 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
7782 IT_STRING_BYTEPOS (*it),
7783 it->bidi_it.scan_dir < 0
7784 ? -1
7785 : it->string_nchars)
7786 && next_element_from_composition (it))
7788 return 1;
7790 else if (STRING_MULTIBYTE (it->string))
7792 const unsigned char *s = (SDATA (it->string)
7793 + IT_STRING_BYTEPOS (*it));
7794 it->c = string_char_and_length (s, &it->len);
7796 else
7798 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
7799 it->len = 1;
7803 /* Record what we have and where it came from. */
7804 it->what = IT_CHARACTER;
7805 it->object = it->string;
7806 it->position = position;
7807 return 1;
7811 /* Load IT with next display element from C string IT->s.
7812 IT->string_nchars is the maximum number of characters to return
7813 from the string. IT->end_charpos may be greater than
7814 IT->string_nchars when this function is called, in which case we
7815 may have to return padding spaces. Value is zero if end of string
7816 reached, including padding spaces. */
7818 static int
7819 next_element_from_c_string (struct it *it)
7821 int success_p = 1;
7823 eassert (it->s);
7824 eassert (!it->bidi_p || it->s == it->bidi_it.string.s);
7825 it->what = IT_CHARACTER;
7826 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
7827 it->object = Qnil;
7829 /* With bidi reordering, the character to display might not be the
7830 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
7831 we were reseated to a new string, whose paragraph direction is
7832 not known. */
7833 if (it->bidi_p && it->bidi_it.first_elt)
7834 get_visually_first_element (it);
7836 /* IT's position can be greater than IT->string_nchars in case a
7837 field width or precision has been specified when the iterator was
7838 initialized. */
7839 if (IT_CHARPOS (*it) >= it->end_charpos)
7841 /* End of the game. */
7842 it->what = IT_EOB;
7843 success_p = 0;
7845 else if (IT_CHARPOS (*it) >= it->string_nchars)
7847 /* Pad with spaces. */
7848 it->c = ' ', it->len = 1;
7849 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
7851 else if (it->multibyte_p)
7852 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), &it->len);
7853 else
7854 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
7856 return success_p;
7860 /* Set up IT to return characters from an ellipsis, if appropriate.
7861 The definition of the ellipsis glyphs may come from a display table
7862 entry. This function fills IT with the first glyph from the
7863 ellipsis if an ellipsis is to be displayed. */
7865 static int
7866 next_element_from_ellipsis (struct it *it)
7868 if (it->selective_display_ellipsis_p)
7869 setup_for_ellipsis (it, it->len);
7870 else
7872 /* The face at the current position may be different from the
7873 face we find after the invisible text. Remember what it
7874 was in IT->saved_face_id, and signal that it's there by
7875 setting face_before_selective_p. */
7876 it->saved_face_id = it->face_id;
7877 it->method = GET_FROM_BUFFER;
7878 it->object = it->w->contents;
7879 reseat_at_next_visible_line_start (it, 1);
7880 it->face_before_selective_p = 1;
7883 return GET_NEXT_DISPLAY_ELEMENT (it);
7887 /* Deliver an image display element. The iterator IT is already
7888 filled with image information (done in handle_display_prop). Value
7889 is always 1. */
7892 static int
7893 next_element_from_image (struct it *it)
7895 it->what = IT_IMAGE;
7896 it->ignore_overlay_strings_at_pos_p = 0;
7897 return 1;
7901 /* Fill iterator IT with next display element from a stretch glyph
7902 property. IT->object is the value of the text property. Value is
7903 always 1. */
7905 static int
7906 next_element_from_stretch (struct it *it)
7908 it->what = IT_STRETCH;
7909 return 1;
7912 /* Scan backwards from IT's current position until we find a stop
7913 position, or until BEGV. This is called when we find ourself
7914 before both the last known prev_stop and base_level_stop while
7915 reordering bidirectional text. */
7917 static void
7918 compute_stop_pos_backwards (struct it *it)
7920 const int SCAN_BACK_LIMIT = 1000;
7921 struct text_pos pos;
7922 struct display_pos save_current = it->current;
7923 struct text_pos save_position = it->position;
7924 ptrdiff_t charpos = IT_CHARPOS (*it);
7925 ptrdiff_t where_we_are = charpos;
7926 ptrdiff_t save_stop_pos = it->stop_charpos;
7927 ptrdiff_t save_end_pos = it->end_charpos;
7929 eassert (NILP (it->string) && !it->s);
7930 eassert (it->bidi_p);
7931 it->bidi_p = 0;
7934 it->end_charpos = min (charpos + 1, ZV);
7935 charpos = max (charpos - SCAN_BACK_LIMIT, BEGV);
7936 SET_TEXT_POS (pos, charpos, CHAR_TO_BYTE (charpos));
7937 reseat_1 (it, pos, 0);
7938 compute_stop_pos (it);
7939 /* We must advance forward, right? */
7940 if (it->stop_charpos <= charpos)
7941 emacs_abort ();
7943 while (charpos > BEGV && it->stop_charpos >= it->end_charpos);
7945 if (it->stop_charpos <= where_we_are)
7946 it->prev_stop = it->stop_charpos;
7947 else
7948 it->prev_stop = BEGV;
7949 it->bidi_p = 1;
7950 it->current = save_current;
7951 it->position = save_position;
7952 it->stop_charpos = save_stop_pos;
7953 it->end_charpos = save_end_pos;
7956 /* Scan forward from CHARPOS in the current buffer/string, until we
7957 find a stop position > current IT's position. Then handle the stop
7958 position before that. This is called when we bump into a stop
7959 position while reordering bidirectional text. CHARPOS should be
7960 the last previously processed stop_pos (or BEGV/0, if none were
7961 processed yet) whose position is less that IT's current
7962 position. */
7964 static void
7965 handle_stop_backwards (struct it *it, ptrdiff_t charpos)
7967 int bufp = !STRINGP (it->string);
7968 ptrdiff_t where_we_are = (bufp ? IT_CHARPOS (*it) : IT_STRING_CHARPOS (*it));
7969 struct display_pos save_current = it->current;
7970 struct text_pos save_position = it->position;
7971 struct text_pos pos1;
7972 ptrdiff_t next_stop;
7974 /* Scan in strict logical order. */
7975 eassert (it->bidi_p);
7976 it->bidi_p = 0;
7979 it->prev_stop = charpos;
7980 if (bufp)
7982 SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos));
7983 reseat_1 (it, pos1, 0);
7985 else
7986 it->current.string_pos = string_pos (charpos, it->string);
7987 compute_stop_pos (it);
7988 /* We must advance forward, right? */
7989 if (it->stop_charpos <= it->prev_stop)
7990 emacs_abort ();
7991 charpos = it->stop_charpos;
7993 while (charpos <= where_we_are);
7995 it->bidi_p = 1;
7996 it->current = save_current;
7997 it->position = save_position;
7998 next_stop = it->stop_charpos;
7999 it->stop_charpos = it->prev_stop;
8000 handle_stop (it);
8001 it->stop_charpos = next_stop;
8004 /* Load IT with the next display element from current_buffer. Value
8005 is zero if end of buffer reached. IT->stop_charpos is the next
8006 position at which to stop and check for text properties or buffer
8007 end. */
8009 static int
8010 next_element_from_buffer (struct it *it)
8012 int success_p = 1;
8014 eassert (IT_CHARPOS (*it) >= BEGV);
8015 eassert (NILP (it->string) && !it->s);
8016 eassert (!it->bidi_p
8017 || (EQ (it->bidi_it.string.lstring, Qnil)
8018 && it->bidi_it.string.s == NULL));
8020 /* With bidi reordering, the character to display might not be the
8021 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
8022 we were reseat()ed to a new buffer position, which is potentially
8023 a different paragraph. */
8024 if (it->bidi_p && it->bidi_it.first_elt)
8026 get_visually_first_element (it);
8027 SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8030 if (IT_CHARPOS (*it) >= it->stop_charpos)
8032 if (IT_CHARPOS (*it) >= it->end_charpos)
8034 int overlay_strings_follow_p;
8036 /* End of the game, except when overlay strings follow that
8037 haven't been returned yet. */
8038 if (it->overlay_strings_at_end_processed_p)
8039 overlay_strings_follow_p = 0;
8040 else
8042 it->overlay_strings_at_end_processed_p = 1;
8043 overlay_strings_follow_p = get_overlay_strings (it, 0);
8046 if (overlay_strings_follow_p)
8047 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
8048 else
8050 it->what = IT_EOB;
8051 it->position = it->current.pos;
8052 success_p = 0;
8055 else if (!(!it->bidi_p
8056 || BIDI_AT_BASE_LEVEL (it->bidi_it)
8057 || IT_CHARPOS (*it) == it->stop_charpos))
8059 /* With bidi non-linear iteration, we could find ourselves
8060 far beyond the last computed stop_charpos, with several
8061 other stop positions in between that we missed. Scan
8062 them all now, in buffer's logical order, until we find
8063 and handle the last stop_charpos that precedes our
8064 current position. */
8065 handle_stop_backwards (it, it->stop_charpos);
8066 return GET_NEXT_DISPLAY_ELEMENT (it);
8068 else
8070 if (it->bidi_p)
8072 /* Take note of the stop position we just moved across,
8073 for when we will move back across it. */
8074 it->prev_stop = it->stop_charpos;
8075 /* If we are at base paragraph embedding level, take
8076 note of the last stop position seen at this
8077 level. */
8078 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
8079 it->base_level_stop = it->stop_charpos;
8081 handle_stop (it);
8082 return GET_NEXT_DISPLAY_ELEMENT (it);
8085 else if (it->bidi_p
8086 /* If we are before prev_stop, we may have overstepped on
8087 our way backwards a stop_pos, and if so, we need to
8088 handle that stop_pos. */
8089 && IT_CHARPOS (*it) < it->prev_stop
8090 /* We can sometimes back up for reasons that have nothing
8091 to do with bidi reordering. E.g., compositions. The
8092 code below is only needed when we are above the base
8093 embedding level, so test for that explicitly. */
8094 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
8096 if (it->base_level_stop <= 0
8097 || IT_CHARPOS (*it) < it->base_level_stop)
8099 /* If we lost track of base_level_stop, we need to find
8100 prev_stop by looking backwards. This happens, e.g., when
8101 we were reseated to the previous screenful of text by
8102 vertical-motion. */
8103 it->base_level_stop = BEGV;
8104 compute_stop_pos_backwards (it);
8105 handle_stop_backwards (it, it->prev_stop);
8107 else
8108 handle_stop_backwards (it, it->base_level_stop);
8109 return GET_NEXT_DISPLAY_ELEMENT (it);
8111 else
8113 /* No face changes, overlays etc. in sight, so just return a
8114 character from current_buffer. */
8115 unsigned char *p;
8116 ptrdiff_t stop;
8118 /* Maybe run the redisplay end trigger hook. Performance note:
8119 This doesn't seem to cost measurable time. */
8120 if (it->redisplay_end_trigger_charpos
8121 && it->glyph_row
8122 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
8123 run_redisplay_end_trigger_hook (it);
8125 stop = it->bidi_it.scan_dir < 0 ? -1 : it->end_charpos;
8126 if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it),
8127 stop)
8128 && next_element_from_composition (it))
8130 return 1;
8133 /* Get the next character, maybe multibyte. */
8134 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
8135 if (it->multibyte_p && !ASCII_BYTE_P (*p))
8136 it->c = STRING_CHAR_AND_LENGTH (p, it->len);
8137 else
8138 it->c = *p, it->len = 1;
8140 /* Record what we have and where it came from. */
8141 it->what = IT_CHARACTER;
8142 it->object = it->w->contents;
8143 it->position = it->current.pos;
8145 /* Normally we return the character found above, except when we
8146 really want to return an ellipsis for selective display. */
8147 if (it->selective)
8149 if (it->c == '\n')
8151 /* A value of selective > 0 means hide lines indented more
8152 than that number of columns. */
8153 if (it->selective > 0
8154 && IT_CHARPOS (*it) + 1 < ZV
8155 && indented_beyond_p (IT_CHARPOS (*it) + 1,
8156 IT_BYTEPOS (*it) + 1,
8157 it->selective))
8159 success_p = next_element_from_ellipsis (it);
8160 it->dpvec_char_len = -1;
8163 else if (it->c == '\r' && it->selective == -1)
8165 /* A value of selective == -1 means that everything from the
8166 CR to the end of the line is invisible, with maybe an
8167 ellipsis displayed for it. */
8168 success_p = next_element_from_ellipsis (it);
8169 it->dpvec_char_len = -1;
8174 /* Value is zero if end of buffer reached. */
8175 eassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
8176 return success_p;
8180 /* Run the redisplay end trigger hook for IT. */
8182 static void
8183 run_redisplay_end_trigger_hook (struct it *it)
8185 Lisp_Object args[3];
8187 /* IT->glyph_row should be non-null, i.e. we should be actually
8188 displaying something, or otherwise we should not run the hook. */
8189 eassert (it->glyph_row);
8191 /* Set up hook arguments. */
8192 args[0] = Qredisplay_end_trigger_functions;
8193 args[1] = it->window;
8194 XSETINT (args[2], it->redisplay_end_trigger_charpos);
8195 it->redisplay_end_trigger_charpos = 0;
8197 /* Since we are *trying* to run these functions, don't try to run
8198 them again, even if they get an error. */
8199 wset_redisplay_end_trigger (it->w, Qnil);
8200 Frun_hook_with_args (3, args);
8202 /* Notice if it changed the face of the character we are on. */
8203 handle_face_prop (it);
8207 /* Deliver a composition display element. Unlike the other
8208 next_element_from_XXX, this function is not registered in the array
8209 get_next_element[]. It is called from next_element_from_buffer and
8210 next_element_from_string when necessary. */
8212 static int
8213 next_element_from_composition (struct it *it)
8215 it->what = IT_COMPOSITION;
8216 it->len = it->cmp_it.nbytes;
8217 if (STRINGP (it->string))
8219 if (it->c < 0)
8221 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
8222 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
8223 return 0;
8225 it->position = it->current.string_pos;
8226 it->object = it->string;
8227 it->c = composition_update_it (&it->cmp_it, IT_STRING_CHARPOS (*it),
8228 IT_STRING_BYTEPOS (*it), it->string);
8230 else
8232 if (it->c < 0)
8234 IT_CHARPOS (*it) += it->cmp_it.nchars;
8235 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
8236 if (it->bidi_p)
8238 if (it->bidi_it.new_paragraph)
8239 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
8240 /* Resync the bidi iterator with IT's new position.
8241 FIXME: this doesn't support bidirectional text. */
8242 while (it->bidi_it.charpos < IT_CHARPOS (*it))
8243 bidi_move_to_visually_next (&it->bidi_it);
8245 return 0;
8247 it->position = it->current.pos;
8248 it->object = it->w->contents;
8249 it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
8250 IT_BYTEPOS (*it), Qnil);
8252 return 1;
8257 /***********************************************************************
8258 Moving an iterator without producing glyphs
8259 ***********************************************************************/
8261 /* Check if iterator is at a position corresponding to a valid buffer
8262 position after some move_it_ call. */
8264 #define IT_POS_VALID_AFTER_MOVE_P(it) \
8265 ((it)->method == GET_FROM_STRING \
8266 ? IT_STRING_CHARPOS (*it) == 0 \
8267 : 1)
8270 /* Move iterator IT to a specified buffer or X position within one
8271 line on the display without producing glyphs.
8273 OP should be a bit mask including some or all of these bits:
8274 MOVE_TO_X: Stop upon reaching x-position TO_X.
8275 MOVE_TO_POS: Stop upon reaching buffer or string position TO_CHARPOS.
8276 Regardless of OP's value, stop upon reaching the end of the display line.
8278 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
8279 This means, in particular, that TO_X includes window's horizontal
8280 scroll amount.
8282 The return value has several possible values that
8283 say what condition caused the scan to stop:
8285 MOVE_POS_MATCH_OR_ZV
8286 - when TO_POS or ZV was reached.
8288 MOVE_X_REACHED
8289 -when TO_X was reached before TO_POS or ZV were reached.
8291 MOVE_LINE_CONTINUED
8292 - when we reached the end of the display area and the line must
8293 be continued.
8295 MOVE_LINE_TRUNCATED
8296 - when we reached the end of the display area and the line is
8297 truncated.
8299 MOVE_NEWLINE_OR_CR
8300 - when we stopped at a line end, i.e. a newline or a CR and selective
8301 display is on. */
8303 static enum move_it_result
8304 move_it_in_display_line_to (struct it *it,
8305 ptrdiff_t to_charpos, int to_x,
8306 enum move_operation_enum op)
8308 enum move_it_result result = MOVE_UNDEFINED;
8309 struct glyph_row *saved_glyph_row;
8310 struct it wrap_it, atpos_it, atx_it, ppos_it;
8311 void *wrap_data = NULL, *atpos_data = NULL, *atx_data = NULL;
8312 void *ppos_data = NULL;
8313 int may_wrap = 0;
8314 enum it_method prev_method = it->method;
8315 ptrdiff_t prev_pos = IT_CHARPOS (*it);
8316 int saw_smaller_pos = prev_pos < to_charpos;
8318 /* Don't produce glyphs in produce_glyphs. */
8319 saved_glyph_row = it->glyph_row;
8320 it->glyph_row = NULL;
8322 /* Use wrap_it to save a copy of IT wherever a word wrap could
8323 occur. Use atpos_it to save a copy of IT at the desired buffer
8324 position, if found, so that we can scan ahead and check if the
8325 word later overshoots the window edge. Use atx_it similarly, for
8326 pixel positions. */
8327 wrap_it.sp = -1;
8328 atpos_it.sp = -1;
8329 atx_it.sp = -1;
8331 /* Use ppos_it under bidi reordering to save a copy of IT for the
8332 position > CHARPOS that is the closest to CHARPOS. We restore
8333 that position in IT when we have scanned the entire display line
8334 without finding a match for CHARPOS and all the character
8335 positions are greater than CHARPOS. */
8336 if (it->bidi_p)
8338 SAVE_IT (ppos_it, *it, ppos_data);
8339 SET_TEXT_POS (ppos_it.current.pos, ZV, ZV_BYTE);
8340 if ((op & MOVE_TO_POS) && IT_CHARPOS (*it) >= to_charpos)
8341 SAVE_IT (ppos_it, *it, ppos_data);
8344 #define BUFFER_POS_REACHED_P() \
8345 ((op & MOVE_TO_POS) != 0 \
8346 && BUFFERP (it->object) \
8347 && (IT_CHARPOS (*it) == to_charpos \
8348 || ((!it->bidi_p \
8349 || BIDI_AT_BASE_LEVEL (it->bidi_it)) \
8350 && IT_CHARPOS (*it) > to_charpos) \
8351 || (it->what == IT_COMPOSITION \
8352 && ((IT_CHARPOS (*it) > to_charpos \
8353 && to_charpos >= it->cmp_it.charpos) \
8354 || (IT_CHARPOS (*it) < to_charpos \
8355 && to_charpos <= it->cmp_it.charpos)))) \
8356 && (it->method == GET_FROM_BUFFER \
8357 || (it->method == GET_FROM_DISPLAY_VECTOR \
8358 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
8360 /* If there's a line-/wrap-prefix, handle it. */
8361 if (it->hpos == 0 && it->method == GET_FROM_BUFFER
8362 && it->current_y < it->last_visible_y)
8363 handle_line_prefix (it);
8365 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8366 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8368 while (1)
8370 int x, i, ascent = 0, descent = 0;
8372 /* Utility macro to reset an iterator with x, ascent, and descent. */
8373 #define IT_RESET_X_ASCENT_DESCENT(IT) \
8374 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
8375 (IT)->max_descent = descent)
8377 /* Stop if we move beyond TO_CHARPOS (after an image or a
8378 display string or stretch glyph). */
8379 if ((op & MOVE_TO_POS) != 0
8380 && BUFFERP (it->object)
8381 && it->method == GET_FROM_BUFFER
8382 && (((!it->bidi_p
8383 /* When the iterator is at base embedding level, we
8384 are guaranteed that characters are delivered for
8385 display in strictly increasing order of their
8386 buffer positions. */
8387 || BIDI_AT_BASE_LEVEL (it->bidi_it))
8388 && IT_CHARPOS (*it) > to_charpos)
8389 || (it->bidi_p
8390 && (prev_method == GET_FROM_IMAGE
8391 || prev_method == GET_FROM_STRETCH
8392 || prev_method == GET_FROM_STRING)
8393 /* Passed TO_CHARPOS from left to right. */
8394 && ((prev_pos < to_charpos
8395 && IT_CHARPOS (*it) > to_charpos)
8396 /* Passed TO_CHARPOS from right to left. */
8397 || (prev_pos > to_charpos
8398 && IT_CHARPOS (*it) < to_charpos)))))
8400 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8402 result = MOVE_POS_MATCH_OR_ZV;
8403 break;
8405 else if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8406 /* If wrap_it is valid, the current position might be in a
8407 word that is wrapped. So, save the iterator in
8408 atpos_it and continue to see if wrapping happens. */
8409 SAVE_IT (atpos_it, *it, atpos_data);
8412 /* Stop when ZV reached.
8413 We used to stop here when TO_CHARPOS reached as well, but that is
8414 too soon if this glyph does not fit on this line. So we handle it
8415 explicitly below. */
8416 if (!get_next_display_element (it))
8418 result = MOVE_POS_MATCH_OR_ZV;
8419 break;
8422 if (it->line_wrap == TRUNCATE)
8424 if (BUFFER_POS_REACHED_P ())
8426 result = MOVE_POS_MATCH_OR_ZV;
8427 break;
8430 else
8432 if (it->line_wrap == WORD_WRAP)
8434 if (IT_DISPLAYING_WHITESPACE (it))
8435 may_wrap = 1;
8436 else if (may_wrap)
8438 /* We have reached a glyph that follows one or more
8439 whitespace characters. If the position is
8440 already found, we are done. */
8441 if (atpos_it.sp >= 0)
8443 RESTORE_IT (it, &atpos_it, atpos_data);
8444 result = MOVE_POS_MATCH_OR_ZV;
8445 goto done;
8447 if (atx_it.sp >= 0)
8449 RESTORE_IT (it, &atx_it, atx_data);
8450 result = MOVE_X_REACHED;
8451 goto done;
8453 /* Otherwise, we can wrap here. */
8454 SAVE_IT (wrap_it, *it, wrap_data);
8455 may_wrap = 0;
8460 /* Remember the line height for the current line, in case
8461 the next element doesn't fit on the line. */
8462 ascent = it->max_ascent;
8463 descent = it->max_descent;
8465 /* The call to produce_glyphs will get the metrics of the
8466 display element IT is loaded with. Record the x-position
8467 before this display element, in case it doesn't fit on the
8468 line. */
8469 x = it->current_x;
8471 PRODUCE_GLYPHS (it);
8473 if (it->area != TEXT_AREA)
8475 prev_method = it->method;
8476 if (it->method == GET_FROM_BUFFER)
8477 prev_pos = IT_CHARPOS (*it);
8478 set_iterator_to_next (it, 1);
8479 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8480 SET_TEXT_POS (this_line_min_pos,
8481 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8482 if (it->bidi_p
8483 && (op & MOVE_TO_POS)
8484 && IT_CHARPOS (*it) > to_charpos
8485 && IT_CHARPOS (*it) < IT_CHARPOS (ppos_it))
8486 SAVE_IT (ppos_it, *it, ppos_data);
8487 continue;
8490 /* The number of glyphs we get back in IT->nglyphs will normally
8491 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
8492 character on a terminal frame, or (iii) a line end. For the
8493 second case, IT->nglyphs - 1 padding glyphs will be present.
8494 (On X frames, there is only one glyph produced for a
8495 composite character.)
8497 The behavior implemented below means, for continuation lines,
8498 that as many spaces of a TAB as fit on the current line are
8499 displayed there. For terminal frames, as many glyphs of a
8500 multi-glyph character are displayed in the current line, too.
8501 This is what the old redisplay code did, and we keep it that
8502 way. Under X, the whole shape of a complex character must
8503 fit on the line or it will be completely displayed in the
8504 next line.
8506 Note that both for tabs and padding glyphs, all glyphs have
8507 the same width. */
8508 if (it->nglyphs)
8510 /* More than one glyph or glyph doesn't fit on line. All
8511 glyphs have the same width. */
8512 int single_glyph_width = it->pixel_width / it->nglyphs;
8513 int new_x;
8514 int x_before_this_char = x;
8515 int hpos_before_this_char = it->hpos;
8517 for (i = 0; i < it->nglyphs; ++i, x = new_x)
8519 new_x = x + single_glyph_width;
8521 /* We want to leave anything reaching TO_X to the caller. */
8522 if ((op & MOVE_TO_X) && new_x > to_x)
8524 if (BUFFER_POS_REACHED_P ())
8526 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8527 goto buffer_pos_reached;
8528 if (atpos_it.sp < 0)
8530 SAVE_IT (atpos_it, *it, atpos_data);
8531 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8534 else
8536 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8538 it->current_x = x;
8539 result = MOVE_X_REACHED;
8540 break;
8542 if (atx_it.sp < 0)
8544 SAVE_IT (atx_it, *it, atx_data);
8545 IT_RESET_X_ASCENT_DESCENT (&atx_it);
8550 if (/* Lines are continued. */
8551 it->line_wrap != TRUNCATE
8552 && (/* And glyph doesn't fit on the line. */
8553 new_x > it->last_visible_x
8554 /* Or it fits exactly and we're on a window
8555 system frame. */
8556 || (new_x == it->last_visible_x
8557 && FRAME_WINDOW_P (it->f)
8558 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
8559 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8560 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
8562 if (/* IT->hpos == 0 means the very first glyph
8563 doesn't fit on the line, e.g. a wide image. */
8564 it->hpos == 0
8565 || (new_x == it->last_visible_x
8566 && FRAME_WINDOW_P (it->f)))
8568 ++it->hpos;
8569 it->current_x = new_x;
8571 /* The character's last glyph just barely fits
8572 in this row. */
8573 if (i == it->nglyphs - 1)
8575 /* If this is the destination position,
8576 return a position *before* it in this row,
8577 now that we know it fits in this row. */
8578 if (BUFFER_POS_REACHED_P ())
8580 if (it->line_wrap != WORD_WRAP
8581 || wrap_it.sp < 0)
8583 it->hpos = hpos_before_this_char;
8584 it->current_x = x_before_this_char;
8585 result = MOVE_POS_MATCH_OR_ZV;
8586 break;
8588 if (it->line_wrap == WORD_WRAP
8589 && atpos_it.sp < 0)
8591 SAVE_IT (atpos_it, *it, atpos_data);
8592 atpos_it.current_x = x_before_this_char;
8593 atpos_it.hpos = hpos_before_this_char;
8597 prev_method = it->method;
8598 if (it->method == GET_FROM_BUFFER)
8599 prev_pos = IT_CHARPOS (*it);
8600 set_iterator_to_next (it, 1);
8601 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8602 SET_TEXT_POS (this_line_min_pos,
8603 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8604 /* On graphical terminals, newlines may
8605 "overflow" into the fringe if
8606 overflow-newline-into-fringe is non-nil.
8607 On text terminals, and on graphical
8608 terminals with no right margin, newlines
8609 may overflow into the last glyph on the
8610 display line.*/
8611 if (!FRAME_WINDOW_P (it->f)
8612 || ((it->bidi_p
8613 && it->bidi_it.paragraph_dir == R2L)
8614 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8615 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
8616 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8618 if (!get_next_display_element (it))
8620 result = MOVE_POS_MATCH_OR_ZV;
8621 break;
8623 if (BUFFER_POS_REACHED_P ())
8625 if (ITERATOR_AT_END_OF_LINE_P (it))
8626 result = MOVE_POS_MATCH_OR_ZV;
8627 else
8628 result = MOVE_LINE_CONTINUED;
8629 break;
8631 if (ITERATOR_AT_END_OF_LINE_P (it)
8632 && (it->line_wrap != WORD_WRAP
8633 || wrap_it.sp < 0))
8635 result = MOVE_NEWLINE_OR_CR;
8636 break;
8641 else
8642 IT_RESET_X_ASCENT_DESCENT (it);
8644 if (wrap_it.sp >= 0)
8646 RESTORE_IT (it, &wrap_it, wrap_data);
8647 atpos_it.sp = -1;
8648 atx_it.sp = -1;
8651 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
8652 IT_CHARPOS (*it)));
8653 result = MOVE_LINE_CONTINUED;
8654 break;
8657 if (BUFFER_POS_REACHED_P ())
8659 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8660 goto buffer_pos_reached;
8661 if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8663 SAVE_IT (atpos_it, *it, atpos_data);
8664 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8668 if (new_x > it->first_visible_x)
8670 /* Glyph is visible. Increment number of glyphs that
8671 would be displayed. */
8672 ++it->hpos;
8676 if (result != MOVE_UNDEFINED)
8677 break;
8679 else if (BUFFER_POS_REACHED_P ())
8681 buffer_pos_reached:
8682 IT_RESET_X_ASCENT_DESCENT (it);
8683 result = MOVE_POS_MATCH_OR_ZV;
8684 break;
8686 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
8688 /* Stop when TO_X specified and reached. This check is
8689 necessary here because of lines consisting of a line end,
8690 only. The line end will not produce any glyphs and we
8691 would never get MOVE_X_REACHED. */
8692 eassert (it->nglyphs == 0);
8693 result = MOVE_X_REACHED;
8694 break;
8697 /* Is this a line end? If yes, we're done. */
8698 if (ITERATOR_AT_END_OF_LINE_P (it))
8700 /* If we are past TO_CHARPOS, but never saw any character
8701 positions smaller than TO_CHARPOS, return
8702 MOVE_POS_MATCH_OR_ZV, like the unidirectional display
8703 did. */
8704 if (it->bidi_p && (op & MOVE_TO_POS) != 0)
8706 if (!saw_smaller_pos && IT_CHARPOS (*it) > to_charpos)
8708 if (IT_CHARPOS (ppos_it) < ZV)
8710 RESTORE_IT (it, &ppos_it, ppos_data);
8711 result = MOVE_POS_MATCH_OR_ZV;
8713 else
8714 goto buffer_pos_reached;
8716 else if (it->line_wrap == WORD_WRAP && atpos_it.sp >= 0
8717 && IT_CHARPOS (*it) > to_charpos)
8718 goto buffer_pos_reached;
8719 else
8720 result = MOVE_NEWLINE_OR_CR;
8722 else
8723 result = MOVE_NEWLINE_OR_CR;
8724 break;
8727 prev_method = it->method;
8728 if (it->method == GET_FROM_BUFFER)
8729 prev_pos = IT_CHARPOS (*it);
8730 /* The current display element has been consumed. Advance
8731 to the next. */
8732 set_iterator_to_next (it, 1);
8733 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8734 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8735 if (IT_CHARPOS (*it) < to_charpos)
8736 saw_smaller_pos = 1;
8737 if (it->bidi_p
8738 && (op & MOVE_TO_POS)
8739 && IT_CHARPOS (*it) >= to_charpos
8740 && IT_CHARPOS (*it) < IT_CHARPOS (ppos_it))
8741 SAVE_IT (ppos_it, *it, ppos_data);
8743 /* Stop if lines are truncated and IT's current x-position is
8744 past the right edge of the window now. */
8745 if (it->line_wrap == TRUNCATE
8746 && it->current_x >= it->last_visible_x)
8748 if (!FRAME_WINDOW_P (it->f)
8749 || ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
8750 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8751 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
8752 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8754 int at_eob_p = 0;
8756 if ((at_eob_p = !get_next_display_element (it))
8757 || BUFFER_POS_REACHED_P ()
8758 /* If we are past TO_CHARPOS, but never saw any
8759 character positions smaller than TO_CHARPOS,
8760 return MOVE_POS_MATCH_OR_ZV, like the
8761 unidirectional display did. */
8762 || (it->bidi_p && (op & MOVE_TO_POS) != 0
8763 && !saw_smaller_pos
8764 && IT_CHARPOS (*it) > to_charpos))
8766 if (it->bidi_p
8767 && !at_eob_p && IT_CHARPOS (ppos_it) < ZV)
8768 RESTORE_IT (it, &ppos_it, ppos_data);
8769 result = MOVE_POS_MATCH_OR_ZV;
8770 break;
8772 if (ITERATOR_AT_END_OF_LINE_P (it))
8774 result = MOVE_NEWLINE_OR_CR;
8775 break;
8778 else if (it->bidi_p && (op & MOVE_TO_POS) != 0
8779 && !saw_smaller_pos
8780 && IT_CHARPOS (*it) > to_charpos)
8782 if (IT_CHARPOS (ppos_it) < ZV)
8783 RESTORE_IT (it, &ppos_it, ppos_data);
8784 result = MOVE_POS_MATCH_OR_ZV;
8785 break;
8787 result = MOVE_LINE_TRUNCATED;
8788 break;
8790 #undef IT_RESET_X_ASCENT_DESCENT
8793 #undef BUFFER_POS_REACHED_P
8795 /* If we scanned beyond to_pos and didn't find a point to wrap at,
8796 restore the saved iterator. */
8797 if (atpos_it.sp >= 0)
8798 RESTORE_IT (it, &atpos_it, atpos_data);
8799 else if (atx_it.sp >= 0)
8800 RESTORE_IT (it, &atx_it, atx_data);
8802 done:
8804 if (atpos_data)
8805 bidi_unshelve_cache (atpos_data, 1);
8806 if (atx_data)
8807 bidi_unshelve_cache (atx_data, 1);
8808 if (wrap_data)
8809 bidi_unshelve_cache (wrap_data, 1);
8810 if (ppos_data)
8811 bidi_unshelve_cache (ppos_data, 1);
8813 /* Restore the iterator settings altered at the beginning of this
8814 function. */
8815 it->glyph_row = saved_glyph_row;
8816 return result;
8819 /* For external use. */
8820 void
8821 move_it_in_display_line (struct it *it,
8822 ptrdiff_t to_charpos, int to_x,
8823 enum move_operation_enum op)
8825 if (it->line_wrap == WORD_WRAP
8826 && (op & MOVE_TO_X))
8828 struct it save_it;
8829 void *save_data = NULL;
8830 int skip;
8832 SAVE_IT (save_it, *it, save_data);
8833 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
8834 /* When word-wrap is on, TO_X may lie past the end
8835 of a wrapped line. Then it->current is the
8836 character on the next line, so backtrack to the
8837 space before the wrap point. */
8838 if (skip == MOVE_LINE_CONTINUED)
8840 int prev_x = max (it->current_x - 1, 0);
8841 RESTORE_IT (it, &save_it, save_data);
8842 move_it_in_display_line_to
8843 (it, -1, prev_x, MOVE_TO_X);
8845 else
8846 bidi_unshelve_cache (save_data, 1);
8848 else
8849 move_it_in_display_line_to (it, to_charpos, to_x, op);
8853 /* Move IT forward until it satisfies one or more of the criteria in
8854 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
8856 OP is a bit-mask that specifies where to stop, and in particular,
8857 which of those four position arguments makes a difference. See the
8858 description of enum move_operation_enum.
8860 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
8861 screen line, this function will set IT to the next position that is
8862 displayed to the right of TO_CHARPOS on the screen. */
8864 void
8865 move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos, int op)
8867 enum move_it_result skip, skip2 = MOVE_X_REACHED;
8868 int line_height, line_start_x = 0, reached = 0;
8869 void *backup_data = NULL;
8871 for (;;)
8873 if (op & MOVE_TO_VPOS)
8875 /* If no TO_CHARPOS and no TO_X specified, stop at the
8876 start of the line TO_VPOS. */
8877 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
8879 if (it->vpos == to_vpos)
8881 reached = 1;
8882 break;
8884 else
8885 skip = move_it_in_display_line_to (it, -1, -1, 0);
8887 else
8889 /* TO_VPOS >= 0 means stop at TO_X in the line at
8890 TO_VPOS, or at TO_POS, whichever comes first. */
8891 if (it->vpos == to_vpos)
8893 reached = 2;
8894 break;
8897 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
8899 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
8901 reached = 3;
8902 break;
8904 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
8906 /* We have reached TO_X but not in the line we want. */
8907 skip = move_it_in_display_line_to (it, to_charpos,
8908 -1, MOVE_TO_POS);
8909 if (skip == MOVE_POS_MATCH_OR_ZV)
8911 reached = 4;
8912 break;
8917 else if (op & MOVE_TO_Y)
8919 struct it it_backup;
8921 if (it->line_wrap == WORD_WRAP)
8922 SAVE_IT (it_backup, *it, backup_data);
8924 /* TO_Y specified means stop at TO_X in the line containing
8925 TO_Y---or at TO_CHARPOS if this is reached first. The
8926 problem is that we can't really tell whether the line
8927 contains TO_Y before we have completely scanned it, and
8928 this may skip past TO_X. What we do is to first scan to
8929 TO_X.
8931 If TO_X is not specified, use a TO_X of zero. The reason
8932 is to make the outcome of this function more predictable.
8933 If we didn't use TO_X == 0, we would stop at the end of
8934 the line which is probably not what a caller would expect
8935 to happen. */
8936 skip = move_it_in_display_line_to
8937 (it, to_charpos, ((op & MOVE_TO_X) ? to_x : 0),
8938 (MOVE_TO_X | (op & MOVE_TO_POS)));
8940 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
8941 if (skip == MOVE_POS_MATCH_OR_ZV)
8942 reached = 5;
8943 else if (skip == MOVE_X_REACHED)
8945 /* If TO_X was reached, we want to know whether TO_Y is
8946 in the line. We know this is the case if the already
8947 scanned glyphs make the line tall enough. Otherwise,
8948 we must check by scanning the rest of the line. */
8949 line_height = it->max_ascent + it->max_descent;
8950 if (to_y >= it->current_y
8951 && to_y < it->current_y + line_height)
8953 reached = 6;
8954 break;
8956 SAVE_IT (it_backup, *it, backup_data);
8957 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
8958 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
8959 op & MOVE_TO_POS);
8960 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
8961 line_height = it->max_ascent + it->max_descent;
8962 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
8964 if (to_y >= it->current_y
8965 && to_y < it->current_y + line_height)
8967 /* If TO_Y is in this line and TO_X was reached
8968 above, we scanned too far. We have to restore
8969 IT's settings to the ones before skipping. But
8970 keep the more accurate values of max_ascent and
8971 max_descent we've found while skipping the rest
8972 of the line, for the sake of callers, such as
8973 pos_visible_p, that need to know the line
8974 height. */
8975 int max_ascent = it->max_ascent;
8976 int max_descent = it->max_descent;
8978 RESTORE_IT (it, &it_backup, backup_data);
8979 it->max_ascent = max_ascent;
8980 it->max_descent = max_descent;
8981 reached = 6;
8983 else
8985 skip = skip2;
8986 if (skip == MOVE_POS_MATCH_OR_ZV)
8987 reached = 7;
8990 else
8992 /* Check whether TO_Y is in this line. */
8993 line_height = it->max_ascent + it->max_descent;
8994 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
8996 if (to_y >= it->current_y
8997 && to_y < it->current_y + line_height)
8999 /* When word-wrap is on, TO_X may lie past the end
9000 of a wrapped line. Then it->current is the
9001 character on the next line, so backtrack to the
9002 space before the wrap point. */
9003 if (skip == MOVE_LINE_CONTINUED
9004 && it->line_wrap == WORD_WRAP)
9006 int prev_x = max (it->current_x - 1, 0);
9007 RESTORE_IT (it, &it_backup, backup_data);
9008 skip = move_it_in_display_line_to
9009 (it, -1, prev_x, MOVE_TO_X);
9011 reached = 6;
9015 if (reached)
9016 break;
9018 else if (BUFFERP (it->object)
9019 && (it->method == GET_FROM_BUFFER
9020 || it->method == GET_FROM_STRETCH)
9021 && IT_CHARPOS (*it) >= to_charpos
9022 /* Under bidi iteration, a call to set_iterator_to_next
9023 can scan far beyond to_charpos if the initial
9024 portion of the next line needs to be reordered. In
9025 that case, give move_it_in_display_line_to another
9026 chance below. */
9027 && !(it->bidi_p
9028 && it->bidi_it.scan_dir == -1))
9029 skip = MOVE_POS_MATCH_OR_ZV;
9030 else
9031 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
9033 switch (skip)
9035 case MOVE_POS_MATCH_OR_ZV:
9036 reached = 8;
9037 goto out;
9039 case MOVE_NEWLINE_OR_CR:
9040 set_iterator_to_next (it, 1);
9041 it->continuation_lines_width = 0;
9042 break;
9044 case MOVE_LINE_TRUNCATED:
9045 it->continuation_lines_width = 0;
9046 reseat_at_next_visible_line_start (it, 0);
9047 if ((op & MOVE_TO_POS) != 0
9048 && IT_CHARPOS (*it) > to_charpos)
9050 reached = 9;
9051 goto out;
9053 break;
9055 case MOVE_LINE_CONTINUED:
9056 /* For continued lines ending in a tab, some of the glyphs
9057 associated with the tab are displayed on the current
9058 line. Since it->current_x does not include these glyphs,
9059 we use it->last_visible_x instead. */
9060 if (it->c == '\t')
9062 it->continuation_lines_width += it->last_visible_x;
9063 /* When moving by vpos, ensure that the iterator really
9064 advances to the next line (bug#847, bug#969). Fixme:
9065 do we need to do this in other circumstances? */
9066 if (it->current_x != it->last_visible_x
9067 && (op & MOVE_TO_VPOS)
9068 && !(op & (MOVE_TO_X | MOVE_TO_POS)))
9070 line_start_x = it->current_x + it->pixel_width
9071 - it->last_visible_x;
9072 set_iterator_to_next (it, 0);
9075 else
9076 it->continuation_lines_width += it->current_x;
9077 break;
9079 default:
9080 emacs_abort ();
9083 /* Reset/increment for the next run. */
9084 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
9085 it->current_x = line_start_x;
9086 line_start_x = 0;
9087 it->hpos = 0;
9088 it->current_y += it->max_ascent + it->max_descent;
9089 ++it->vpos;
9090 last_height = it->max_ascent + it->max_descent;
9091 it->max_ascent = it->max_descent = 0;
9094 out:
9096 /* On text terminals, we may stop at the end of a line in the middle
9097 of a multi-character glyph. If the glyph itself is continued,
9098 i.e. it is actually displayed on the next line, don't treat this
9099 stopping point as valid; move to the next line instead (unless
9100 that brings us offscreen). */
9101 if (!FRAME_WINDOW_P (it->f)
9102 && op & MOVE_TO_POS
9103 && IT_CHARPOS (*it) == to_charpos
9104 && it->what == IT_CHARACTER
9105 && it->nglyphs > 1
9106 && it->line_wrap == WINDOW_WRAP
9107 && it->current_x == it->last_visible_x - 1
9108 && it->c != '\n'
9109 && it->c != '\t'
9110 && it->vpos < it->w->window_end_vpos)
9112 it->continuation_lines_width += it->current_x;
9113 it->current_x = it->hpos = it->max_ascent = it->max_descent = 0;
9114 it->current_y += it->max_ascent + it->max_descent;
9115 ++it->vpos;
9116 last_height = it->max_ascent + it->max_descent;
9119 if (backup_data)
9120 bidi_unshelve_cache (backup_data, 1);
9122 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
9126 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
9128 If DY > 0, move IT backward at least that many pixels. DY = 0
9129 means move IT backward to the preceding line start or BEGV. This
9130 function may move over more than DY pixels if IT->current_y - DY
9131 ends up in the middle of a line; in this case IT->current_y will be
9132 set to the top of the line moved to. */
9134 void
9135 move_it_vertically_backward (struct it *it, int dy)
9137 int nlines, h;
9138 struct it it2, it3;
9139 void *it2data = NULL, *it3data = NULL;
9140 ptrdiff_t start_pos;
9141 int nchars_per_row
9142 = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
9143 ptrdiff_t pos_limit;
9145 move_further_back:
9146 eassert (dy >= 0);
9148 start_pos = IT_CHARPOS (*it);
9150 /* Estimate how many newlines we must move back. */
9151 nlines = max (1, dy / default_line_pixel_height (it->w));
9152 if (it->line_wrap == TRUNCATE)
9153 pos_limit = BEGV;
9154 else
9155 pos_limit = max (start_pos - nlines * nchars_per_row, BEGV);
9157 /* Set the iterator's position that many lines back. But don't go
9158 back more than NLINES full screen lines -- this wins a day with
9159 buffers which have very long lines. */
9160 while (nlines-- && IT_CHARPOS (*it) > pos_limit)
9161 back_to_previous_visible_line_start (it);
9163 /* Reseat the iterator here. When moving backward, we don't want
9164 reseat to skip forward over invisible text, set up the iterator
9165 to deliver from overlay strings at the new position etc. So,
9166 use reseat_1 here. */
9167 reseat_1 (it, it->current.pos, 1);
9169 /* We are now surely at a line start. */
9170 it->current_x = it->hpos = 0; /* FIXME: this is incorrect when bidi
9171 reordering is in effect. */
9172 it->continuation_lines_width = 0;
9174 /* Move forward and see what y-distance we moved. First move to the
9175 start of the next line so that we get its height. We need this
9176 height to be able to tell whether we reached the specified
9177 y-distance. */
9178 SAVE_IT (it2, *it, it2data);
9179 it2.max_ascent = it2.max_descent = 0;
9182 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
9183 MOVE_TO_POS | MOVE_TO_VPOS);
9185 while (!(IT_POS_VALID_AFTER_MOVE_P (&it2)
9186 /* If we are in a display string which starts at START_POS,
9187 and that display string includes a newline, and we are
9188 right after that newline (i.e. at the beginning of a
9189 display line), exit the loop, because otherwise we will
9190 infloop, since move_it_to will see that it is already at
9191 START_POS and will not move. */
9192 || (it2.method == GET_FROM_STRING
9193 && IT_CHARPOS (it2) == start_pos
9194 && SREF (it2.string, IT_STRING_BYTEPOS (it2) - 1) == '\n')));
9195 eassert (IT_CHARPOS (*it) >= BEGV);
9196 SAVE_IT (it3, it2, it3data);
9198 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
9199 eassert (IT_CHARPOS (*it) >= BEGV);
9200 /* H is the actual vertical distance from the position in *IT
9201 and the starting position. */
9202 h = it2.current_y - it->current_y;
9203 /* NLINES is the distance in number of lines. */
9204 nlines = it2.vpos - it->vpos;
9206 /* Correct IT's y and vpos position
9207 so that they are relative to the starting point. */
9208 it->vpos -= nlines;
9209 it->current_y -= h;
9211 if (dy == 0)
9213 /* DY == 0 means move to the start of the screen line. The
9214 value of nlines is > 0 if continuation lines were involved,
9215 or if the original IT position was at start of a line. */
9216 RESTORE_IT (it, it, it2data);
9217 if (nlines > 0)
9218 move_it_by_lines (it, nlines);
9219 /* The above code moves us to some position NLINES down,
9220 usually to its first glyph (leftmost in an L2R line), but
9221 that's not necessarily the start of the line, under bidi
9222 reordering. We want to get to the character position
9223 that is immediately after the newline of the previous
9224 line. */
9225 if (it->bidi_p
9226 && !it->continuation_lines_width
9227 && !STRINGP (it->string)
9228 && IT_CHARPOS (*it) > BEGV
9229 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9231 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
9233 DEC_BOTH (cp, bp);
9234 cp = find_newline_no_quit (cp, bp, -1, NULL);
9235 move_it_to (it, cp, -1, -1, -1, MOVE_TO_POS);
9237 bidi_unshelve_cache (it3data, 1);
9239 else
9241 /* The y-position we try to reach, relative to *IT.
9242 Note that H has been subtracted in front of the if-statement. */
9243 int target_y = it->current_y + h - dy;
9244 int y0 = it3.current_y;
9245 int y1;
9246 int line_height;
9248 RESTORE_IT (&it3, &it3, it3data);
9249 y1 = line_bottom_y (&it3);
9250 line_height = y1 - y0;
9251 RESTORE_IT (it, it, it2data);
9252 /* If we did not reach target_y, try to move further backward if
9253 we can. If we moved too far backward, try to move forward. */
9254 if (target_y < it->current_y
9255 /* This is heuristic. In a window that's 3 lines high, with
9256 a line height of 13 pixels each, recentering with point
9257 on the bottom line will try to move -39/2 = 19 pixels
9258 backward. Try to avoid moving into the first line. */
9259 && (it->current_y - target_y
9260 > min (window_box_height (it->w), line_height * 2 / 3))
9261 && IT_CHARPOS (*it) > BEGV)
9263 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
9264 target_y - it->current_y));
9265 dy = it->current_y - target_y;
9266 goto move_further_back;
9268 else if (target_y >= it->current_y + line_height
9269 && IT_CHARPOS (*it) < ZV)
9271 /* Should move forward by at least one line, maybe more.
9273 Note: Calling move_it_by_lines can be expensive on
9274 terminal frames, where compute_motion is used (via
9275 vmotion) to do the job, when there are very long lines
9276 and truncate-lines is nil. That's the reason for
9277 treating terminal frames specially here. */
9279 if (!FRAME_WINDOW_P (it->f))
9280 move_it_vertically (it, target_y - (it->current_y + line_height));
9281 else
9285 move_it_by_lines (it, 1);
9287 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
9294 /* Move IT by a specified amount of pixel lines DY. DY negative means
9295 move backwards. DY = 0 means move to start of screen line. At the
9296 end, IT will be on the start of a screen line. */
9298 void
9299 move_it_vertically (struct it *it, int dy)
9301 if (dy <= 0)
9302 move_it_vertically_backward (it, -dy);
9303 else
9305 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
9306 move_it_to (it, ZV, -1, it->current_y + dy, -1,
9307 MOVE_TO_POS | MOVE_TO_Y);
9308 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
9310 /* If buffer ends in ZV without a newline, move to the start of
9311 the line to satisfy the post-condition. */
9312 if (IT_CHARPOS (*it) == ZV
9313 && ZV > BEGV
9314 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9315 move_it_by_lines (it, 0);
9320 /* Move iterator IT past the end of the text line it is in. */
9322 void
9323 move_it_past_eol (struct it *it)
9325 enum move_it_result rc;
9327 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
9328 if (rc == MOVE_NEWLINE_OR_CR)
9329 set_iterator_to_next (it, 0);
9333 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
9334 negative means move up. DVPOS == 0 means move to the start of the
9335 screen line.
9337 Optimization idea: If we would know that IT->f doesn't use
9338 a face with proportional font, we could be faster for
9339 truncate-lines nil. */
9341 void
9342 move_it_by_lines (struct it *it, ptrdiff_t dvpos)
9345 /* The commented-out optimization uses vmotion on terminals. This
9346 gives bad results, because elements like it->what, on which
9347 callers such as pos_visible_p rely, aren't updated. */
9348 /* struct position pos;
9349 if (!FRAME_WINDOW_P (it->f))
9351 struct text_pos textpos;
9353 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
9354 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
9355 reseat (it, textpos, 1);
9356 it->vpos += pos.vpos;
9357 it->current_y += pos.vpos;
9359 else */
9361 if (dvpos == 0)
9363 /* DVPOS == 0 means move to the start of the screen line. */
9364 move_it_vertically_backward (it, 0);
9365 /* Let next call to line_bottom_y calculate real line height */
9366 last_height = 0;
9368 else if (dvpos > 0)
9370 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
9371 if (!IT_POS_VALID_AFTER_MOVE_P (it))
9373 /* Only move to the next buffer position if we ended up in a
9374 string from display property, not in an overlay string
9375 (before-string or after-string). That is because the
9376 latter don't conceal the underlying buffer position, so
9377 we can ask to move the iterator to the exact position we
9378 are interested in. Note that, even if we are already at
9379 IT_CHARPOS (*it), the call below is not a no-op, as it
9380 will detect that we are at the end of the string, pop the
9381 iterator, and compute it->current_x and it->hpos
9382 correctly. */
9383 move_it_to (it, IT_CHARPOS (*it) + it->string_from_display_prop_p,
9384 -1, -1, -1, MOVE_TO_POS);
9387 else
9389 struct it it2;
9390 void *it2data = NULL;
9391 ptrdiff_t start_charpos, i;
9392 int nchars_per_row
9393 = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
9394 ptrdiff_t pos_limit;
9396 /* Start at the beginning of the screen line containing IT's
9397 position. This may actually move vertically backwards,
9398 in case of overlays, so adjust dvpos accordingly. */
9399 dvpos += it->vpos;
9400 move_it_vertically_backward (it, 0);
9401 dvpos -= it->vpos;
9403 /* Go back -DVPOS buffer lines, but no farther than -DVPOS full
9404 screen lines, and reseat the iterator there. */
9405 start_charpos = IT_CHARPOS (*it);
9406 if (it->line_wrap == TRUNCATE)
9407 pos_limit = BEGV;
9408 else
9409 pos_limit = max (start_charpos + dvpos * nchars_per_row, BEGV);
9410 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > pos_limit; --i)
9411 back_to_previous_visible_line_start (it);
9412 reseat (it, it->current.pos, 1);
9414 /* Move further back if we end up in a string or an image. */
9415 while (!IT_POS_VALID_AFTER_MOVE_P (it))
9417 /* First try to move to start of display line. */
9418 dvpos += it->vpos;
9419 move_it_vertically_backward (it, 0);
9420 dvpos -= it->vpos;
9421 if (IT_POS_VALID_AFTER_MOVE_P (it))
9422 break;
9423 /* If start of line is still in string or image,
9424 move further back. */
9425 back_to_previous_visible_line_start (it);
9426 reseat (it, it->current.pos, 1);
9427 dvpos--;
9430 it->current_x = it->hpos = 0;
9432 /* Above call may have moved too far if continuation lines
9433 are involved. Scan forward and see if it did. */
9434 SAVE_IT (it2, *it, it2data);
9435 it2.vpos = it2.current_y = 0;
9436 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
9437 it->vpos -= it2.vpos;
9438 it->current_y -= it2.current_y;
9439 it->current_x = it->hpos = 0;
9441 /* If we moved too far back, move IT some lines forward. */
9442 if (it2.vpos > -dvpos)
9444 int delta = it2.vpos + dvpos;
9446 RESTORE_IT (&it2, &it2, it2data);
9447 SAVE_IT (it2, *it, it2data);
9448 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
9449 /* Move back again if we got too far ahead. */
9450 if (IT_CHARPOS (*it) >= start_charpos)
9451 RESTORE_IT (it, &it2, it2data);
9452 else
9453 bidi_unshelve_cache (it2data, 1);
9455 else
9456 RESTORE_IT (it, it, it2data);
9460 /* Return 1 if IT points into the middle of a display vector. */
9463 in_display_vector_p (struct it *it)
9465 return (it->method == GET_FROM_DISPLAY_VECTOR
9466 && it->current.dpvec_index > 0
9467 && it->dpvec + it->current.dpvec_index != it->dpend);
9471 /***********************************************************************
9472 Messages
9473 ***********************************************************************/
9476 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
9477 to *Messages*. */
9479 void
9480 add_to_log (const char *format, Lisp_Object arg1, Lisp_Object arg2)
9482 Lisp_Object args[3];
9483 Lisp_Object msg, fmt;
9484 char *buffer;
9485 ptrdiff_t len;
9486 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
9487 USE_SAFE_ALLOCA;
9489 fmt = msg = Qnil;
9490 GCPRO4 (fmt, msg, arg1, arg2);
9492 args[0] = fmt = build_string (format);
9493 args[1] = arg1;
9494 args[2] = arg2;
9495 msg = Fformat (3, args);
9497 len = SBYTES (msg) + 1;
9498 buffer = SAFE_ALLOCA (len);
9499 memcpy (buffer, SDATA (msg), len);
9501 message_dolog (buffer, len - 1, 1, 0);
9502 SAFE_FREE ();
9504 UNGCPRO;
9508 /* Output a newline in the *Messages* buffer if "needs" one. */
9510 void
9511 message_log_maybe_newline (void)
9513 if (message_log_need_newline)
9514 message_dolog ("", 0, 1, 0);
9518 /* Add a string M of length NBYTES to the message log, optionally
9519 terminated with a newline when NLFLAG is true. MULTIBYTE, if
9520 true, means interpret the contents of M as multibyte. This
9521 function calls low-level routines in order to bypass text property
9522 hooks, etc. which might not be safe to run.
9524 This may GC (insert may run before/after change hooks),
9525 so the buffer M must NOT point to a Lisp string. */
9527 void
9528 message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte)
9530 const unsigned char *msg = (const unsigned char *) m;
9532 if (!NILP (Vmemory_full))
9533 return;
9535 if (!NILP (Vmessage_log_max))
9537 struct buffer *oldbuf;
9538 Lisp_Object oldpoint, oldbegv, oldzv;
9539 int old_windows_or_buffers_changed = windows_or_buffers_changed;
9540 ptrdiff_t point_at_end = 0;
9541 ptrdiff_t zv_at_end = 0;
9542 Lisp_Object old_deactivate_mark;
9543 bool shown;
9544 struct gcpro gcpro1;
9546 old_deactivate_mark = Vdeactivate_mark;
9547 oldbuf = current_buffer;
9548 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
9549 bset_undo_list (current_buffer, Qt);
9551 oldpoint = message_dolog_marker1;
9552 set_marker_restricted_both (oldpoint, Qnil, PT, PT_BYTE);
9553 oldbegv = message_dolog_marker2;
9554 set_marker_restricted_both (oldbegv, Qnil, BEGV, BEGV_BYTE);
9555 oldzv = message_dolog_marker3;
9556 set_marker_restricted_both (oldzv, Qnil, ZV, ZV_BYTE);
9557 GCPRO1 (old_deactivate_mark);
9559 if (PT == Z)
9560 point_at_end = 1;
9561 if (ZV == Z)
9562 zv_at_end = 1;
9564 BEGV = BEG;
9565 BEGV_BYTE = BEG_BYTE;
9566 ZV = Z;
9567 ZV_BYTE = Z_BYTE;
9568 TEMP_SET_PT_BOTH (Z, Z_BYTE);
9570 /* Insert the string--maybe converting multibyte to single byte
9571 or vice versa, so that all the text fits the buffer. */
9572 if (multibyte
9573 && NILP (BVAR (current_buffer, enable_multibyte_characters)))
9575 ptrdiff_t i;
9576 int c, char_bytes;
9577 char work[1];
9579 /* Convert a multibyte string to single-byte
9580 for the *Message* buffer. */
9581 for (i = 0; i < nbytes; i += char_bytes)
9583 c = string_char_and_length (msg + i, &char_bytes);
9584 work[0] = (ASCII_CHAR_P (c)
9586 : multibyte_char_to_unibyte (c));
9587 insert_1_both (work, 1, 1, 1, 0, 0);
9590 else if (! multibyte
9591 && ! NILP (BVAR (current_buffer, enable_multibyte_characters)))
9593 ptrdiff_t i;
9594 int c, char_bytes;
9595 unsigned char str[MAX_MULTIBYTE_LENGTH];
9596 /* Convert a single-byte string to multibyte
9597 for the *Message* buffer. */
9598 for (i = 0; i < nbytes; i++)
9600 c = msg[i];
9601 MAKE_CHAR_MULTIBYTE (c);
9602 char_bytes = CHAR_STRING (c, str);
9603 insert_1_both ((char *) str, 1, char_bytes, 1, 0, 0);
9606 else if (nbytes)
9607 insert_1_both (m, chars_in_text (msg, nbytes), nbytes, 1, 0, 0);
9609 if (nlflag)
9611 ptrdiff_t this_bol, this_bol_byte, prev_bol, prev_bol_byte;
9612 printmax_t dups;
9614 insert_1_both ("\n", 1, 1, 1, 0, 0);
9616 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
9617 this_bol = PT;
9618 this_bol_byte = PT_BYTE;
9620 /* See if this line duplicates the previous one.
9621 If so, combine duplicates. */
9622 if (this_bol > BEG)
9624 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
9625 prev_bol = PT;
9626 prev_bol_byte = PT_BYTE;
9628 dups = message_log_check_duplicate (prev_bol_byte,
9629 this_bol_byte);
9630 if (dups)
9632 del_range_both (prev_bol, prev_bol_byte,
9633 this_bol, this_bol_byte, 0);
9634 if (dups > 1)
9636 char dupstr[sizeof " [ times]"
9637 + INT_STRLEN_BOUND (printmax_t)];
9639 /* If you change this format, don't forget to also
9640 change message_log_check_duplicate. */
9641 int duplen = sprintf (dupstr, " [%"pMd" times]", dups);
9642 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
9643 insert_1_both (dupstr, duplen, duplen, 1, 0, 1);
9648 /* If we have more than the desired maximum number of lines
9649 in the *Messages* buffer now, delete the oldest ones.
9650 This is safe because we don't have undo in this buffer. */
9652 if (NATNUMP (Vmessage_log_max))
9654 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
9655 -XFASTINT (Vmessage_log_max) - 1, 0);
9656 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
9659 BEGV = marker_position (oldbegv);
9660 BEGV_BYTE = marker_byte_position (oldbegv);
9662 if (zv_at_end)
9664 ZV = Z;
9665 ZV_BYTE = Z_BYTE;
9667 else
9669 ZV = marker_position (oldzv);
9670 ZV_BYTE = marker_byte_position (oldzv);
9673 if (point_at_end)
9674 TEMP_SET_PT_BOTH (Z, Z_BYTE);
9675 else
9676 /* We can't do Fgoto_char (oldpoint) because it will run some
9677 Lisp code. */
9678 TEMP_SET_PT_BOTH (marker_position (oldpoint),
9679 marker_byte_position (oldpoint));
9681 UNGCPRO;
9682 unchain_marker (XMARKER (oldpoint));
9683 unchain_marker (XMARKER (oldbegv));
9684 unchain_marker (XMARKER (oldzv));
9686 shown = buffer_window_count (current_buffer) > 0;
9687 set_buffer_internal (oldbuf);
9688 /* We called insert_1_both above with its 5th argument (PREPARE)
9689 zero, which prevents insert_1_both from calling
9690 prepare_to_modify_buffer, which in turns prevents us from
9691 incrementing windows_or_buffers_changed even if *Messages* is
9692 shown in some window. So we must manually incrementing
9693 windows_or_buffers_changed here to make up for that. */
9694 if (shown)
9695 windows_or_buffers_changed++;
9696 else
9697 windows_or_buffers_changed = old_windows_or_buffers_changed;
9698 message_log_need_newline = !nlflag;
9699 Vdeactivate_mark = old_deactivate_mark;
9704 /* We are at the end of the buffer after just having inserted a newline.
9705 (Note: We depend on the fact we won't be crossing the gap.)
9706 Check to see if the most recent message looks a lot like the previous one.
9707 Return 0 if different, 1 if the new one should just replace it, or a
9708 value N > 1 if we should also append " [N times]". */
9710 static intmax_t
9711 message_log_check_duplicate (ptrdiff_t prev_bol_byte, ptrdiff_t this_bol_byte)
9713 ptrdiff_t i;
9714 ptrdiff_t len = Z_BYTE - 1 - this_bol_byte;
9715 int seen_dots = 0;
9716 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
9717 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
9719 for (i = 0; i < len; i++)
9721 if (i >= 3 && p1[i - 3] == '.' && p1[i - 2] == '.' && p1[i - 1] == '.')
9722 seen_dots = 1;
9723 if (p1[i] != p2[i])
9724 return seen_dots;
9726 p1 += len;
9727 if (*p1 == '\n')
9728 return 2;
9729 if (*p1++ == ' ' && *p1++ == '[')
9731 char *pend;
9732 intmax_t n = strtoimax ((char *) p1, &pend, 10);
9733 if (0 < n && n < INTMAX_MAX && strncmp (pend, " times]\n", 8) == 0)
9734 return n + 1;
9736 return 0;
9740 /* Display an echo area message M with a specified length of NBYTES
9741 bytes. The string may include null characters. If M is not a
9742 string, clear out any existing message, and let the mini-buffer
9743 text show through.
9745 This function cancels echoing. */
9747 void
9748 message3 (Lisp_Object m)
9750 struct gcpro gcpro1;
9752 GCPRO1 (m);
9753 clear_message (1,1);
9754 cancel_echoing ();
9756 /* First flush out any partial line written with print. */
9757 message_log_maybe_newline ();
9758 if (STRINGP (m))
9760 ptrdiff_t nbytes = SBYTES (m);
9761 bool multibyte = STRING_MULTIBYTE (m);
9762 USE_SAFE_ALLOCA;
9763 char *buffer = SAFE_ALLOCA (nbytes);
9764 memcpy (buffer, SDATA (m), nbytes);
9765 message_dolog (buffer, nbytes, 1, multibyte);
9766 SAFE_FREE ();
9768 message3_nolog (m);
9770 UNGCPRO;
9774 /* The non-logging version of message3.
9775 This does not cancel echoing, because it is used for echoing.
9776 Perhaps we need to make a separate function for echoing
9777 and make this cancel echoing. */
9779 void
9780 message3_nolog (Lisp_Object m)
9782 struct frame *sf = SELECTED_FRAME ();
9784 if (FRAME_INITIAL_P (sf))
9786 if (noninteractive_need_newline)
9787 putc ('\n', stderr);
9788 noninteractive_need_newline = 0;
9789 if (STRINGP (m))
9790 fwrite (SDATA (m), SBYTES (m), 1, stderr);
9791 if (cursor_in_echo_area == 0)
9792 fprintf (stderr, "\n");
9793 fflush (stderr);
9795 /* Error messages get reported properly by cmd_error, so this must be just an
9796 informative message; if the frame hasn't really been initialized yet, just
9797 toss it. */
9798 else if (INTERACTIVE && sf->glyphs_initialized_p)
9800 /* Get the frame containing the mini-buffer
9801 that the selected frame is using. */
9802 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
9803 Lisp_Object frame = XWINDOW (mini_window)->frame;
9804 struct frame *f = XFRAME (frame);
9806 if (FRAME_VISIBLE_P (sf) && !FRAME_VISIBLE_P (f))
9807 Fmake_frame_visible (frame);
9809 if (STRINGP (m) && SCHARS (m) > 0)
9811 set_message (m);
9812 if (minibuffer_auto_raise)
9813 Fraise_frame (frame);
9814 /* Assume we are not echoing.
9815 (If we are, echo_now will override this.) */
9816 echo_message_buffer = Qnil;
9818 else
9819 clear_message (1, 1);
9821 do_pending_window_change (0);
9822 echo_area_display (1);
9823 do_pending_window_change (0);
9824 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
9825 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
9830 /* Display a null-terminated echo area message M. If M is 0, clear
9831 out any existing message, and let the mini-buffer text show through.
9833 The buffer M must continue to exist until after the echo area gets
9834 cleared or some other message gets displayed there. Do not pass
9835 text that is stored in a Lisp string. Do not pass text in a buffer
9836 that was alloca'd. */
9838 void
9839 message1 (const char *m)
9841 message3 (m ? build_unibyte_string (m) : Qnil);
9845 /* The non-logging counterpart of message1. */
9847 void
9848 message1_nolog (const char *m)
9850 message3_nolog (m ? build_unibyte_string (m) : Qnil);
9853 /* Display a message M which contains a single %s
9854 which gets replaced with STRING. */
9856 void
9857 message_with_string (const char *m, Lisp_Object string, int log)
9859 CHECK_STRING (string);
9861 if (noninteractive)
9863 if (m)
9865 if (noninteractive_need_newline)
9866 putc ('\n', stderr);
9867 noninteractive_need_newline = 0;
9868 fprintf (stderr, m, SDATA (string));
9869 if (!cursor_in_echo_area)
9870 fprintf (stderr, "\n");
9871 fflush (stderr);
9874 else if (INTERACTIVE)
9876 /* The frame whose minibuffer we're going to display the message on.
9877 It may be larger than the selected frame, so we need
9878 to use its buffer, not the selected frame's buffer. */
9879 Lisp_Object mini_window;
9880 struct frame *f, *sf = SELECTED_FRAME ();
9882 /* Get the frame containing the minibuffer
9883 that the selected frame is using. */
9884 mini_window = FRAME_MINIBUF_WINDOW (sf);
9885 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
9887 /* Error messages get reported properly by cmd_error, so this must be
9888 just an informative message; if the frame hasn't really been
9889 initialized yet, just toss it. */
9890 if (f->glyphs_initialized_p)
9892 Lisp_Object args[2], msg;
9893 struct gcpro gcpro1, gcpro2;
9895 args[0] = build_string (m);
9896 args[1] = msg = string;
9897 GCPRO2 (args[0], msg);
9898 gcpro1.nvars = 2;
9900 msg = Fformat (2, args);
9902 if (log)
9903 message3 (msg);
9904 else
9905 message3_nolog (msg);
9907 UNGCPRO;
9909 /* Print should start at the beginning of the message
9910 buffer next time. */
9911 message_buf_print = 0;
9917 /* Dump an informative message to the minibuf. If M is 0, clear out
9918 any existing message, and let the mini-buffer text show through. */
9920 static void
9921 vmessage (const char *m, va_list ap)
9923 if (noninteractive)
9925 if (m)
9927 if (noninteractive_need_newline)
9928 putc ('\n', stderr);
9929 noninteractive_need_newline = 0;
9930 vfprintf (stderr, m, ap);
9931 if (cursor_in_echo_area == 0)
9932 fprintf (stderr, "\n");
9933 fflush (stderr);
9936 else if (INTERACTIVE)
9938 /* The frame whose mini-buffer we're going to display the message
9939 on. It may be larger than the selected frame, so we need to
9940 use its buffer, not the selected frame's buffer. */
9941 Lisp_Object mini_window;
9942 struct frame *f, *sf = SELECTED_FRAME ();
9944 /* Get the frame containing the mini-buffer
9945 that the selected frame is using. */
9946 mini_window = FRAME_MINIBUF_WINDOW (sf);
9947 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
9949 /* Error messages get reported properly by cmd_error, so this must be
9950 just an informative message; if the frame hasn't really been
9951 initialized yet, just toss it. */
9952 if (f->glyphs_initialized_p)
9954 if (m)
9956 ptrdiff_t len;
9957 ptrdiff_t maxsize = FRAME_MESSAGE_BUF_SIZE (f);
9958 char *message_buf = alloca (maxsize + 1);
9960 len = doprnt (message_buf, maxsize, m, 0, ap);
9962 message3 (make_string (message_buf, len));
9964 else
9965 message1 (0);
9967 /* Print should start at the beginning of the message
9968 buffer next time. */
9969 message_buf_print = 0;
9974 void
9975 message (const char *m, ...)
9977 va_list ap;
9978 va_start (ap, m);
9979 vmessage (m, ap);
9980 va_end (ap);
9984 #if 0
9985 /* The non-logging version of message. */
9987 void
9988 message_nolog (const char *m, ...)
9990 Lisp_Object old_log_max;
9991 va_list ap;
9992 va_start (ap, m);
9993 old_log_max = Vmessage_log_max;
9994 Vmessage_log_max = Qnil;
9995 vmessage (m, ap);
9996 Vmessage_log_max = old_log_max;
9997 va_end (ap);
9999 #endif
10002 /* Display the current message in the current mini-buffer. This is
10003 only called from error handlers in process.c, and is not time
10004 critical. */
10006 void
10007 update_echo_area (void)
10009 if (!NILP (echo_area_buffer[0]))
10011 Lisp_Object string;
10012 string = Fcurrent_message ();
10013 message3 (string);
10018 /* Make sure echo area buffers in `echo_buffers' are live.
10019 If they aren't, make new ones. */
10021 static void
10022 ensure_echo_area_buffers (void)
10024 int i;
10026 for (i = 0; i < 2; ++i)
10027 if (!BUFFERP (echo_buffer[i])
10028 || !BUFFER_LIVE_P (XBUFFER (echo_buffer[i])))
10030 char name[30];
10031 Lisp_Object old_buffer;
10032 int j;
10034 old_buffer = echo_buffer[i];
10035 echo_buffer[i] = Fget_buffer_create
10036 (make_formatted_string (name, " *Echo Area %d*", i));
10037 bset_truncate_lines (XBUFFER (echo_buffer[i]), Qnil);
10038 /* to force word wrap in echo area -
10039 it was decided to postpone this*/
10040 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
10042 for (j = 0; j < 2; ++j)
10043 if (EQ (old_buffer, echo_area_buffer[j]))
10044 echo_area_buffer[j] = echo_buffer[i];
10049 /* Call FN with args A1..A2 with either the current or last displayed
10050 echo_area_buffer as current buffer.
10052 WHICH zero means use the current message buffer
10053 echo_area_buffer[0]. If that is nil, choose a suitable buffer
10054 from echo_buffer[] and clear it.
10056 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
10057 suitable buffer from echo_buffer[] and clear it.
10059 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
10060 that the current message becomes the last displayed one, make
10061 choose a suitable buffer for echo_area_buffer[0], and clear it.
10063 Value is what FN returns. */
10065 static int
10066 with_echo_area_buffer (struct window *w, int which,
10067 int (*fn) (ptrdiff_t, Lisp_Object),
10068 ptrdiff_t a1, Lisp_Object a2)
10070 Lisp_Object buffer;
10071 int this_one, the_other, clear_buffer_p, rc;
10072 ptrdiff_t count = SPECPDL_INDEX ();
10074 /* If buffers aren't live, make new ones. */
10075 ensure_echo_area_buffers ();
10077 clear_buffer_p = 0;
10079 if (which == 0)
10080 this_one = 0, the_other = 1;
10081 else if (which > 0)
10082 this_one = 1, the_other = 0;
10083 else
10085 this_one = 0, the_other = 1;
10086 clear_buffer_p = 1;
10088 /* We need a fresh one in case the current echo buffer equals
10089 the one containing the last displayed echo area message. */
10090 if (!NILP (echo_area_buffer[this_one])
10091 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
10092 echo_area_buffer[this_one] = Qnil;
10095 /* Choose a suitable buffer from echo_buffer[] is we don't
10096 have one. */
10097 if (NILP (echo_area_buffer[this_one]))
10099 echo_area_buffer[this_one]
10100 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
10101 ? echo_buffer[the_other]
10102 : echo_buffer[this_one]);
10103 clear_buffer_p = 1;
10106 buffer = echo_area_buffer[this_one];
10108 /* Don't get confused by reusing the buffer used for echoing
10109 for a different purpose. */
10110 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
10111 cancel_echoing ();
10113 record_unwind_protect (unwind_with_echo_area_buffer,
10114 with_echo_area_buffer_unwind_data (w));
10116 /* Make the echo area buffer current. Note that for display
10117 purposes, it is not necessary that the displayed window's buffer
10118 == current_buffer, except for text property lookup. So, let's
10119 only set that buffer temporarily here without doing a full
10120 Fset_window_buffer. We must also change w->pointm, though,
10121 because otherwise an assertions in unshow_buffer fails, and Emacs
10122 aborts. */
10123 set_buffer_internal_1 (XBUFFER (buffer));
10124 if (w)
10126 wset_buffer (w, buffer);
10127 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
10130 bset_undo_list (current_buffer, Qt);
10131 bset_read_only (current_buffer, Qnil);
10132 specbind (Qinhibit_read_only, Qt);
10133 specbind (Qinhibit_modification_hooks, Qt);
10135 if (clear_buffer_p && Z > BEG)
10136 del_range (BEG, Z);
10138 eassert (BEGV >= BEG);
10139 eassert (ZV <= Z && ZV >= BEGV);
10141 rc = fn (a1, a2);
10143 eassert (BEGV >= BEG);
10144 eassert (ZV <= Z && ZV >= BEGV);
10146 unbind_to (count, Qnil);
10147 return rc;
10151 /* Save state that should be preserved around the call to the function
10152 FN called in with_echo_area_buffer. */
10154 static Lisp_Object
10155 with_echo_area_buffer_unwind_data (struct window *w)
10157 int i = 0;
10158 Lisp_Object vector, tmp;
10160 /* Reduce consing by keeping one vector in
10161 Vwith_echo_area_save_vector. */
10162 vector = Vwith_echo_area_save_vector;
10163 Vwith_echo_area_save_vector = Qnil;
10165 if (NILP (vector))
10166 vector = Fmake_vector (make_number (9), Qnil);
10168 XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
10169 ASET (vector, i, Vdeactivate_mark); ++i;
10170 ASET (vector, i, make_number (windows_or_buffers_changed)); ++i;
10172 if (w)
10174 XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i;
10175 ASET (vector, i, w->contents); ++i;
10176 ASET (vector, i, make_number (marker_position (w->pointm))); ++i;
10177 ASET (vector, i, make_number (marker_byte_position (w->pointm))); ++i;
10178 ASET (vector, i, make_number (marker_position (w->start))); ++i;
10179 ASET (vector, i, make_number (marker_byte_position (w->start))); ++i;
10181 else
10183 int end = i + 6;
10184 for (; i < end; ++i)
10185 ASET (vector, i, Qnil);
10188 eassert (i == ASIZE (vector));
10189 return vector;
10193 /* Restore global state from VECTOR which was created by
10194 with_echo_area_buffer_unwind_data. */
10196 static void
10197 unwind_with_echo_area_buffer (Lisp_Object vector)
10199 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
10200 Vdeactivate_mark = AREF (vector, 1);
10201 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
10203 if (WINDOWP (AREF (vector, 3)))
10205 struct window *w;
10206 Lisp_Object buffer;
10208 w = XWINDOW (AREF (vector, 3));
10209 buffer = AREF (vector, 4);
10211 wset_buffer (w, buffer);
10212 set_marker_both (w->pointm, buffer,
10213 XFASTINT (AREF (vector, 5)),
10214 XFASTINT (AREF (vector, 6)));
10215 set_marker_both (w->start, buffer,
10216 XFASTINT (AREF (vector, 7)),
10217 XFASTINT (AREF (vector, 8)));
10220 Vwith_echo_area_save_vector = vector;
10224 /* Set up the echo area for use by print functions. MULTIBYTE_P
10225 non-zero means we will print multibyte. */
10227 void
10228 setup_echo_area_for_printing (int multibyte_p)
10230 /* If we can't find an echo area any more, exit. */
10231 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
10232 Fkill_emacs (Qnil);
10234 ensure_echo_area_buffers ();
10236 if (!message_buf_print)
10238 /* A message has been output since the last time we printed.
10239 Choose a fresh echo area buffer. */
10240 if (EQ (echo_area_buffer[1], echo_buffer[0]))
10241 echo_area_buffer[0] = echo_buffer[1];
10242 else
10243 echo_area_buffer[0] = echo_buffer[0];
10245 /* Switch to that buffer and clear it. */
10246 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
10247 bset_truncate_lines (current_buffer, Qnil);
10249 if (Z > BEG)
10251 ptrdiff_t count = SPECPDL_INDEX ();
10252 specbind (Qinhibit_read_only, Qt);
10253 /* Note that undo recording is always disabled. */
10254 del_range (BEG, Z);
10255 unbind_to (count, Qnil);
10257 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
10259 /* Set up the buffer for the multibyteness we need. */
10260 if (multibyte_p
10261 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
10262 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
10264 /* Raise the frame containing the echo area. */
10265 if (minibuffer_auto_raise)
10267 struct frame *sf = SELECTED_FRAME ();
10268 Lisp_Object mini_window;
10269 mini_window = FRAME_MINIBUF_WINDOW (sf);
10270 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
10273 message_log_maybe_newline ();
10274 message_buf_print = 1;
10276 else
10278 if (NILP (echo_area_buffer[0]))
10280 if (EQ (echo_area_buffer[1], echo_buffer[0]))
10281 echo_area_buffer[0] = echo_buffer[1];
10282 else
10283 echo_area_buffer[0] = echo_buffer[0];
10286 if (current_buffer != XBUFFER (echo_area_buffer[0]))
10288 /* Someone switched buffers between print requests. */
10289 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
10290 bset_truncate_lines (current_buffer, Qnil);
10296 /* Display an echo area message in window W. Value is non-zero if W's
10297 height is changed. If display_last_displayed_message_p is
10298 non-zero, display the message that was last displayed, otherwise
10299 display the current message. */
10301 static int
10302 display_echo_area (struct window *w)
10304 int i, no_message_p, window_height_changed_p;
10306 /* Temporarily disable garbage collections while displaying the echo
10307 area. This is done because a GC can print a message itself.
10308 That message would modify the echo area buffer's contents while a
10309 redisplay of the buffer is going on, and seriously confuse
10310 redisplay. */
10311 ptrdiff_t count = inhibit_garbage_collection ();
10313 /* If there is no message, we must call display_echo_area_1
10314 nevertheless because it resizes the window. But we will have to
10315 reset the echo_area_buffer in question to nil at the end because
10316 with_echo_area_buffer will sets it to an empty buffer. */
10317 i = display_last_displayed_message_p ? 1 : 0;
10318 no_message_p = NILP (echo_area_buffer[i]);
10320 window_height_changed_p
10321 = with_echo_area_buffer (w, display_last_displayed_message_p,
10322 display_echo_area_1,
10323 (intptr_t) w, Qnil);
10325 if (no_message_p)
10326 echo_area_buffer[i] = Qnil;
10328 unbind_to (count, Qnil);
10329 return window_height_changed_p;
10333 /* Helper for display_echo_area. Display the current buffer which
10334 contains the current echo area message in window W, a mini-window,
10335 a pointer to which is passed in A1. A2..A4 are currently not used.
10336 Change the height of W so that all of the message is displayed.
10337 Value is non-zero if height of W was changed. */
10339 static int
10340 display_echo_area_1 (ptrdiff_t a1, Lisp_Object a2)
10342 intptr_t i1 = a1;
10343 struct window *w = (struct window *) i1;
10344 Lisp_Object window;
10345 struct text_pos start;
10346 int window_height_changed_p = 0;
10348 /* Do this before displaying, so that we have a large enough glyph
10349 matrix for the display. If we can't get enough space for the
10350 whole text, display the last N lines. That works by setting w->start. */
10351 window_height_changed_p = resize_mini_window (w, 0);
10353 /* Use the starting position chosen by resize_mini_window. */
10354 SET_TEXT_POS_FROM_MARKER (start, w->start);
10356 /* Display. */
10357 clear_glyph_matrix (w->desired_matrix);
10358 XSETWINDOW (window, w);
10359 try_window (window, start, 0);
10361 return window_height_changed_p;
10365 /* Resize the echo area window to exactly the size needed for the
10366 currently displayed message, if there is one. If a mini-buffer
10367 is active, don't shrink it. */
10369 void
10370 resize_echo_area_exactly (void)
10372 if (BUFFERP (echo_area_buffer[0])
10373 && WINDOWP (echo_area_window))
10375 struct window *w = XWINDOW (echo_area_window);
10376 int resized_p;
10377 Lisp_Object resize_exactly;
10379 if (minibuf_level == 0)
10380 resize_exactly = Qt;
10381 else
10382 resize_exactly = Qnil;
10384 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
10385 (intptr_t) w, resize_exactly);
10386 if (resized_p)
10388 ++windows_or_buffers_changed;
10389 ++update_mode_lines;
10390 redisplay_internal ();
10396 /* Callback function for with_echo_area_buffer, when used from
10397 resize_echo_area_exactly. A1 contains a pointer to the window to
10398 resize, EXACTLY non-nil means resize the mini-window exactly to the
10399 size of the text displayed. A3 and A4 are not used. Value is what
10400 resize_mini_window returns. */
10402 static int
10403 resize_mini_window_1 (ptrdiff_t a1, Lisp_Object exactly)
10405 intptr_t i1 = a1;
10406 return resize_mini_window ((struct window *) i1, !NILP (exactly));
10410 /* Resize mini-window W to fit the size of its contents. EXACT_P
10411 means size the window exactly to the size needed. Otherwise, it's
10412 only enlarged until W's buffer is empty.
10414 Set W->start to the right place to begin display. If the whole
10415 contents fit, start at the beginning. Otherwise, start so as
10416 to make the end of the contents appear. This is particularly
10417 important for y-or-n-p, but seems desirable generally.
10419 Value is non-zero if the window height has been changed. */
10422 resize_mini_window (struct window *w, int exact_p)
10424 struct frame *f = XFRAME (w->frame);
10425 int window_height_changed_p = 0;
10427 eassert (MINI_WINDOW_P (w));
10429 /* By default, start display at the beginning. */
10430 set_marker_both (w->start, w->contents,
10431 BUF_BEGV (XBUFFER (w->contents)),
10432 BUF_BEGV_BYTE (XBUFFER (w->contents)));
10434 /* Don't resize windows while redisplaying a window; it would
10435 confuse redisplay functions when the size of the window they are
10436 displaying changes from under them. Such a resizing can happen,
10437 for instance, when which-func prints a long message while
10438 we are running fontification-functions. We're running these
10439 functions with safe_call which binds inhibit-redisplay to t. */
10440 if (!NILP (Vinhibit_redisplay))
10441 return 0;
10443 /* Nil means don't try to resize. */
10444 if (NILP (Vresize_mini_windows)
10445 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
10446 return 0;
10448 if (!FRAME_MINIBUF_ONLY_P (f))
10450 struct it it;
10451 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
10452 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
10453 int height;
10454 EMACS_INT max_height;
10455 int unit = FRAME_LINE_HEIGHT (f);
10456 struct text_pos start;
10457 struct buffer *old_current_buffer = NULL;
10459 if (current_buffer != XBUFFER (w->contents))
10461 old_current_buffer = current_buffer;
10462 set_buffer_internal (XBUFFER (w->contents));
10465 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
10467 /* Compute the max. number of lines specified by the user. */
10468 if (FLOATP (Vmax_mini_window_height))
10469 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
10470 else if (INTEGERP (Vmax_mini_window_height))
10471 max_height = XINT (Vmax_mini_window_height);
10472 else
10473 max_height = total_height / 4;
10475 /* Correct that max. height if it's bogus. */
10476 max_height = clip_to_bounds (1, max_height, total_height);
10478 /* Find out the height of the text in the window. */
10479 if (it.line_wrap == TRUNCATE)
10480 height = 1;
10481 else
10483 last_height = 0;
10484 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
10485 if (it.max_ascent == 0 && it.max_descent == 0)
10486 height = it.current_y + last_height;
10487 else
10488 height = it.current_y + it.max_ascent + it.max_descent;
10489 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
10490 height = (height + unit - 1) / unit;
10493 /* Compute a suitable window start. */
10494 if (height > max_height)
10496 height = max_height;
10497 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
10498 move_it_vertically_backward (&it, (height - 1) * unit);
10499 start = it.current.pos;
10501 else
10502 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
10503 SET_MARKER_FROM_TEXT_POS (w->start, start);
10505 if (EQ (Vresize_mini_windows, Qgrow_only))
10507 /* Let it grow only, until we display an empty message, in which
10508 case the window shrinks again. */
10509 if (height > WINDOW_TOTAL_LINES (w))
10511 int old_height = WINDOW_TOTAL_LINES (w);
10513 FRAME_WINDOWS_FROZEN (f) = 1;
10514 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10515 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10517 else if (height < WINDOW_TOTAL_LINES (w)
10518 && (exact_p || BEGV == ZV))
10520 int old_height = WINDOW_TOTAL_LINES (w);
10522 FRAME_WINDOWS_FROZEN (f) = 0;
10523 shrink_mini_window (w);
10524 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10527 else
10529 /* Always resize to exact size needed. */
10530 if (height > WINDOW_TOTAL_LINES (w))
10532 int old_height = WINDOW_TOTAL_LINES (w);
10534 FRAME_WINDOWS_FROZEN (f) = 1;
10535 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10536 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10538 else if (height < WINDOW_TOTAL_LINES (w))
10540 int old_height = WINDOW_TOTAL_LINES (w);
10542 FRAME_WINDOWS_FROZEN (f) = 0;
10543 shrink_mini_window (w);
10545 if (height)
10547 FRAME_WINDOWS_FROZEN (f) = 1;
10548 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10551 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10555 if (old_current_buffer)
10556 set_buffer_internal (old_current_buffer);
10559 return window_height_changed_p;
10563 /* Value is the current message, a string, or nil if there is no
10564 current message. */
10566 Lisp_Object
10567 current_message (void)
10569 Lisp_Object msg;
10571 if (!BUFFERP (echo_area_buffer[0]))
10572 msg = Qnil;
10573 else
10575 with_echo_area_buffer (0, 0, current_message_1,
10576 (intptr_t) &msg, Qnil);
10577 if (NILP (msg))
10578 echo_area_buffer[0] = Qnil;
10581 return msg;
10585 static int
10586 current_message_1 (ptrdiff_t a1, Lisp_Object a2)
10588 intptr_t i1 = a1;
10589 Lisp_Object *msg = (Lisp_Object *) i1;
10591 if (Z > BEG)
10592 *msg = make_buffer_string (BEG, Z, 1);
10593 else
10594 *msg = Qnil;
10595 return 0;
10599 /* Push the current message on Vmessage_stack for later restoration
10600 by restore_message. Value is non-zero if the current message isn't
10601 empty. This is a relatively infrequent operation, so it's not
10602 worth optimizing. */
10604 bool
10605 push_message (void)
10607 Lisp_Object msg = current_message ();
10608 Vmessage_stack = Fcons (msg, Vmessage_stack);
10609 return STRINGP (msg);
10613 /* Restore message display from the top of Vmessage_stack. */
10615 void
10616 restore_message (void)
10618 eassert (CONSP (Vmessage_stack));
10619 message3_nolog (XCAR (Vmessage_stack));
10623 /* Handler for unwind-protect calling pop_message. */
10625 void
10626 pop_message_unwind (void)
10628 /* Pop the top-most entry off Vmessage_stack. */
10629 eassert (CONSP (Vmessage_stack));
10630 Vmessage_stack = XCDR (Vmessage_stack);
10634 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
10635 exits. If the stack is not empty, we have a missing pop_message
10636 somewhere. */
10638 void
10639 check_message_stack (void)
10641 if (!NILP (Vmessage_stack))
10642 emacs_abort ();
10646 /* Truncate to NCHARS what will be displayed in the echo area the next
10647 time we display it---but don't redisplay it now. */
10649 void
10650 truncate_echo_area (ptrdiff_t nchars)
10652 if (nchars == 0)
10653 echo_area_buffer[0] = Qnil;
10654 else if (!noninteractive
10655 && INTERACTIVE
10656 && !NILP (echo_area_buffer[0]))
10658 struct frame *sf = SELECTED_FRAME ();
10659 /* Error messages get reported properly by cmd_error, so this must be
10660 just an informative message; if the frame hasn't really been
10661 initialized yet, just toss it. */
10662 if (sf->glyphs_initialized_p)
10663 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil);
10668 /* Helper function for truncate_echo_area. Truncate the current
10669 message to at most NCHARS characters. */
10671 static int
10672 truncate_message_1 (ptrdiff_t nchars, Lisp_Object a2)
10674 if (BEG + nchars < Z)
10675 del_range (BEG + nchars, Z);
10676 if (Z == BEG)
10677 echo_area_buffer[0] = Qnil;
10678 return 0;
10681 /* Set the current message to STRING. */
10683 static void
10684 set_message (Lisp_Object string)
10686 eassert (STRINGP (string));
10688 message_enable_multibyte = STRING_MULTIBYTE (string);
10690 with_echo_area_buffer (0, -1, set_message_1, 0, string);
10691 message_buf_print = 0;
10692 help_echo_showing_p = 0;
10694 if (STRINGP (Vdebug_on_message)
10695 && STRINGP (string)
10696 && fast_string_match (Vdebug_on_message, string) >= 0)
10697 call_debugger (list2 (Qerror, string));
10701 /* Helper function for set_message. First argument is ignored and second
10702 argument has the same meaning as for set_message.
10703 This function is called with the echo area buffer being current. */
10705 static int
10706 set_message_1 (ptrdiff_t a1, Lisp_Object string)
10708 eassert (STRINGP (string));
10710 /* Change multibyteness of the echo buffer appropriately. */
10711 if (message_enable_multibyte
10712 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
10713 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
10715 bset_truncate_lines (current_buffer, message_truncate_lines ? Qt : Qnil);
10716 if (!NILP (BVAR (current_buffer, bidi_display_reordering)))
10717 bset_bidi_paragraph_direction (current_buffer, Qleft_to_right);
10719 /* Insert new message at BEG. */
10720 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
10722 /* This function takes care of single/multibyte conversion.
10723 We just have to ensure that the echo area buffer has the right
10724 setting of enable_multibyte_characters. */
10725 insert_from_string (string, 0, 0, SCHARS (string), SBYTES (string), 1);
10727 return 0;
10731 /* Clear messages. CURRENT_P non-zero means clear the current
10732 message. LAST_DISPLAYED_P non-zero means clear the message
10733 last displayed. */
10735 void
10736 clear_message (int current_p, int last_displayed_p)
10738 if (current_p)
10740 echo_area_buffer[0] = Qnil;
10741 message_cleared_p = 1;
10744 if (last_displayed_p)
10745 echo_area_buffer[1] = Qnil;
10747 message_buf_print = 0;
10750 /* Clear garbaged frames.
10752 This function is used where the old redisplay called
10753 redraw_garbaged_frames which in turn called redraw_frame which in
10754 turn called clear_frame. The call to clear_frame was a source of
10755 flickering. I believe a clear_frame is not necessary. It should
10756 suffice in the new redisplay to invalidate all current matrices,
10757 and ensure a complete redisplay of all windows. */
10759 static void
10760 clear_garbaged_frames (void)
10762 if (frame_garbaged)
10764 Lisp_Object tail, frame;
10765 int changed_count = 0;
10767 FOR_EACH_FRAME (tail, frame)
10769 struct frame *f = XFRAME (frame);
10771 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
10773 if (f->resized_p)
10775 redraw_frame (f);
10776 f->force_flush_display_p = 1;
10778 clear_current_matrices (f);
10779 changed_count++;
10780 f->garbaged = 0;
10781 f->resized_p = 0;
10785 frame_garbaged = 0;
10786 if (changed_count)
10787 ++windows_or_buffers_changed;
10792 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
10793 is non-zero update selected_frame. Value is non-zero if the
10794 mini-windows height has been changed. */
10796 static int
10797 echo_area_display (int update_frame_p)
10799 Lisp_Object mini_window;
10800 struct window *w;
10801 struct frame *f;
10802 int window_height_changed_p = 0;
10803 struct frame *sf = SELECTED_FRAME ();
10805 mini_window = FRAME_MINIBUF_WINDOW (sf);
10806 w = XWINDOW (mini_window);
10807 f = XFRAME (WINDOW_FRAME (w));
10809 /* Don't display if frame is invisible or not yet initialized. */
10810 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
10811 return 0;
10813 #ifdef HAVE_WINDOW_SYSTEM
10814 /* When Emacs starts, selected_frame may be the initial terminal
10815 frame. If we let this through, a message would be displayed on
10816 the terminal. */
10817 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
10818 return 0;
10819 #endif /* HAVE_WINDOW_SYSTEM */
10821 /* Redraw garbaged frames. */
10822 clear_garbaged_frames ();
10824 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
10826 echo_area_window = mini_window;
10827 window_height_changed_p = display_echo_area (w);
10828 w->must_be_updated_p = 1;
10830 /* Update the display, unless called from redisplay_internal.
10831 Also don't update the screen during redisplay itself. The
10832 update will happen at the end of redisplay, and an update
10833 here could cause confusion. */
10834 if (update_frame_p && !redisplaying_p)
10836 int n = 0;
10838 /* If the display update has been interrupted by pending
10839 input, update mode lines in the frame. Due to the
10840 pending input, it might have been that redisplay hasn't
10841 been called, so that mode lines above the echo area are
10842 garbaged. This looks odd, so we prevent it here. */
10843 if (!display_completed)
10844 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
10846 if (window_height_changed_p
10847 /* Don't do this if Emacs is shutting down. Redisplay
10848 needs to run hooks. */
10849 && !NILP (Vrun_hooks))
10851 /* Must update other windows. Likewise as in other
10852 cases, don't let this update be interrupted by
10853 pending input. */
10854 ptrdiff_t count = SPECPDL_INDEX ();
10855 specbind (Qredisplay_dont_pause, Qt);
10856 windows_or_buffers_changed = 1;
10857 redisplay_internal ();
10858 unbind_to (count, Qnil);
10860 else if (FRAME_WINDOW_P (f) && n == 0)
10862 /* Window configuration is the same as before.
10863 Can do with a display update of the echo area,
10864 unless we displayed some mode lines. */
10865 update_single_window (w, 1);
10866 FRAME_RIF (f)->flush_display (f);
10868 else
10869 update_frame (f, 1, 1);
10871 /* If cursor is in the echo area, make sure that the next
10872 redisplay displays the minibuffer, so that the cursor will
10873 be replaced with what the minibuffer wants. */
10874 if (cursor_in_echo_area)
10875 ++windows_or_buffers_changed;
10878 else if (!EQ (mini_window, selected_window))
10879 windows_or_buffers_changed++;
10881 /* Last displayed message is now the current message. */
10882 echo_area_buffer[1] = echo_area_buffer[0];
10883 /* Inform read_char that we're not echoing. */
10884 echo_message_buffer = Qnil;
10886 /* Prevent redisplay optimization in redisplay_internal by resetting
10887 this_line_start_pos. This is done because the mini-buffer now
10888 displays the message instead of its buffer text. */
10889 if (EQ (mini_window, selected_window))
10890 CHARPOS (this_line_start_pos) = 0;
10892 return window_height_changed_p;
10895 /* Nonzero if the current window's buffer is shown in more than one
10896 window and was modified since last redisplay. */
10898 static int
10899 buffer_shared_and_changed (void)
10901 return (buffer_window_count (current_buffer) > 1
10902 && UNCHANGED_MODIFIED < MODIFF);
10905 /* Nonzero if W's buffer was changed but not saved or Transient Mark mode
10906 is enabled and mark of W's buffer was changed since last W's update. */
10908 static int
10909 window_buffer_changed (struct window *w)
10911 struct buffer *b = XBUFFER (w->contents);
10913 eassert (BUFFER_LIVE_P (b));
10915 return (((BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) != w->last_had_star)
10916 || ((!NILP (Vtransient_mark_mode) && !NILP (BVAR (b, mark_active)))
10917 != (w->region_showing != 0)));
10920 /* Nonzero if W has %c in its mode line and mode line should be updated. */
10922 static int
10923 mode_line_update_needed (struct window *w)
10925 return (w->column_number_displayed != -1
10926 && !(PT == w->last_point && !window_outdated (w))
10927 && (w->column_number_displayed != current_column ()));
10930 /* Nonzero if window start of W is frozen and may not be changed during
10931 redisplay. */
10933 static bool
10934 window_frozen_p (struct window *w)
10936 if (FRAME_WINDOWS_FROZEN (XFRAME (WINDOW_FRAME (w))))
10938 Lisp_Object window;
10940 XSETWINDOW (window, w);
10941 if (MINI_WINDOW_P (w))
10942 return 0;
10943 else if (EQ (window, selected_window))
10944 return 0;
10945 else if (MINI_WINDOW_P (XWINDOW (selected_window))
10946 && EQ (window, Vminibuf_scroll_window))
10947 /* This special window can't be frozen too. */
10948 return 0;
10949 else
10950 return 1;
10952 return 0;
10955 /***********************************************************************
10956 Mode Lines and Frame Titles
10957 ***********************************************************************/
10959 /* A buffer for constructing non-propertized mode-line strings and
10960 frame titles in it; allocated from the heap in init_xdisp and
10961 resized as needed in store_mode_line_noprop_char. */
10963 static char *mode_line_noprop_buf;
10965 /* The buffer's end, and a current output position in it. */
10967 static char *mode_line_noprop_buf_end;
10968 static char *mode_line_noprop_ptr;
10970 #define MODE_LINE_NOPROP_LEN(start) \
10971 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
10973 static enum {
10974 MODE_LINE_DISPLAY = 0,
10975 MODE_LINE_TITLE,
10976 MODE_LINE_NOPROP,
10977 MODE_LINE_STRING
10978 } mode_line_target;
10980 /* Alist that caches the results of :propertize.
10981 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
10982 static Lisp_Object mode_line_proptrans_alist;
10984 /* List of strings making up the mode-line. */
10985 static Lisp_Object mode_line_string_list;
10987 /* Base face property when building propertized mode line string. */
10988 static Lisp_Object mode_line_string_face;
10989 static Lisp_Object mode_line_string_face_prop;
10992 /* Unwind data for mode line strings */
10994 static Lisp_Object Vmode_line_unwind_vector;
10996 static Lisp_Object
10997 format_mode_line_unwind_data (struct frame *target_frame,
10998 struct buffer *obuf,
10999 Lisp_Object owin,
11000 int save_proptrans)
11002 Lisp_Object vector, tmp;
11004 /* Reduce consing by keeping one vector in
11005 Vwith_echo_area_save_vector. */
11006 vector = Vmode_line_unwind_vector;
11007 Vmode_line_unwind_vector = Qnil;
11009 if (NILP (vector))
11010 vector = Fmake_vector (make_number (10), Qnil);
11012 ASET (vector, 0, make_number (mode_line_target));
11013 ASET (vector, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
11014 ASET (vector, 2, mode_line_string_list);
11015 ASET (vector, 3, save_proptrans ? mode_line_proptrans_alist : Qt);
11016 ASET (vector, 4, mode_line_string_face);
11017 ASET (vector, 5, mode_line_string_face_prop);
11019 if (obuf)
11020 XSETBUFFER (tmp, obuf);
11021 else
11022 tmp = Qnil;
11023 ASET (vector, 6, tmp);
11024 ASET (vector, 7, owin);
11025 if (target_frame)
11027 /* Similarly to `with-selected-window', if the operation selects
11028 a window on another frame, we must restore that frame's
11029 selected window, and (for a tty) the top-frame. */
11030 ASET (vector, 8, target_frame->selected_window);
11031 if (FRAME_TERMCAP_P (target_frame))
11032 ASET (vector, 9, FRAME_TTY (target_frame)->top_frame);
11035 return vector;
11038 static void
11039 unwind_format_mode_line (Lisp_Object vector)
11041 Lisp_Object old_window = AREF (vector, 7);
11042 Lisp_Object target_frame_window = AREF (vector, 8);
11043 Lisp_Object old_top_frame = AREF (vector, 9);
11045 mode_line_target = XINT (AREF (vector, 0));
11046 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
11047 mode_line_string_list = AREF (vector, 2);
11048 if (! EQ (AREF (vector, 3), Qt))
11049 mode_line_proptrans_alist = AREF (vector, 3);
11050 mode_line_string_face = AREF (vector, 4);
11051 mode_line_string_face_prop = AREF (vector, 5);
11053 /* Select window before buffer, since it may change the buffer. */
11054 if (!NILP (old_window))
11056 /* If the operation that we are unwinding had selected a window
11057 on a different frame, reset its frame-selected-window. For a
11058 text terminal, reset its top-frame if necessary. */
11059 if (!NILP (target_frame_window))
11061 Lisp_Object frame
11062 = WINDOW_FRAME (XWINDOW (target_frame_window));
11064 if (!EQ (frame, WINDOW_FRAME (XWINDOW (old_window))))
11065 Fselect_window (target_frame_window, Qt);
11067 if (!NILP (old_top_frame) && !EQ (old_top_frame, frame))
11068 Fselect_frame (old_top_frame, Qt);
11071 Fselect_window (old_window, Qt);
11074 if (!NILP (AREF (vector, 6)))
11076 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
11077 ASET (vector, 6, Qnil);
11080 Vmode_line_unwind_vector = vector;
11084 /* Store a single character C for the frame title in mode_line_noprop_buf.
11085 Re-allocate mode_line_noprop_buf if necessary. */
11087 static void
11088 store_mode_line_noprop_char (char c)
11090 /* If output position has reached the end of the allocated buffer,
11091 increase the buffer's size. */
11092 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
11094 ptrdiff_t len = MODE_LINE_NOPROP_LEN (0);
11095 ptrdiff_t size = len;
11096 mode_line_noprop_buf =
11097 xpalloc (mode_line_noprop_buf, &size, 1, STRING_BYTES_BOUND, 1);
11098 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
11099 mode_line_noprop_ptr = mode_line_noprop_buf + len;
11102 *mode_line_noprop_ptr++ = c;
11106 /* Store part of a frame title in mode_line_noprop_buf, beginning at
11107 mode_line_noprop_ptr. STRING is the string to store. Do not copy
11108 characters that yield more columns than PRECISION; PRECISION <= 0
11109 means copy the whole string. Pad with spaces until FIELD_WIDTH
11110 number of characters have been copied; FIELD_WIDTH <= 0 means don't
11111 pad. Called from display_mode_element when it is used to build a
11112 frame title. */
11114 static int
11115 store_mode_line_noprop (const char *string, int field_width, int precision)
11117 const unsigned char *str = (const unsigned char *) string;
11118 int n = 0;
11119 ptrdiff_t dummy, nbytes;
11121 /* Copy at most PRECISION chars from STR. */
11122 nbytes = strlen (string);
11123 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
11124 while (nbytes--)
11125 store_mode_line_noprop_char (*str++);
11127 /* Fill up with spaces until FIELD_WIDTH reached. */
11128 while (field_width > 0
11129 && n < field_width)
11131 store_mode_line_noprop_char (' ');
11132 ++n;
11135 return n;
11138 /***********************************************************************
11139 Frame Titles
11140 ***********************************************************************/
11142 #ifdef HAVE_WINDOW_SYSTEM
11144 /* Set the title of FRAME, if it has changed. The title format is
11145 Vicon_title_format if FRAME is iconified, otherwise it is
11146 frame_title_format. */
11148 static void
11149 x_consider_frame_title (Lisp_Object frame)
11151 struct frame *f = XFRAME (frame);
11153 if (FRAME_WINDOW_P (f)
11154 || FRAME_MINIBUF_ONLY_P (f)
11155 || f->explicit_name)
11157 /* Do we have more than one visible frame on this X display? */
11158 Lisp_Object tail, other_frame, fmt;
11159 ptrdiff_t title_start;
11160 char *title;
11161 ptrdiff_t len;
11162 struct it it;
11163 ptrdiff_t count = SPECPDL_INDEX ();
11165 FOR_EACH_FRAME (tail, other_frame)
11167 struct frame *tf = XFRAME (other_frame);
11169 if (tf != f
11170 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
11171 && !FRAME_MINIBUF_ONLY_P (tf)
11172 && !EQ (other_frame, tip_frame)
11173 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
11174 break;
11177 /* Set global variable indicating that multiple frames exist. */
11178 multiple_frames = CONSP (tail);
11180 /* Switch to the buffer of selected window of the frame. Set up
11181 mode_line_target so that display_mode_element will output into
11182 mode_line_noprop_buf; then display the title. */
11183 record_unwind_protect (unwind_format_mode_line,
11184 format_mode_line_unwind_data
11185 (f, current_buffer, selected_window, 0));
11187 Fselect_window (f->selected_window, Qt);
11188 set_buffer_internal_1
11189 (XBUFFER (XWINDOW (f->selected_window)->contents));
11190 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
11192 mode_line_target = MODE_LINE_TITLE;
11193 title_start = MODE_LINE_NOPROP_LEN (0);
11194 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
11195 NULL, DEFAULT_FACE_ID);
11196 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
11197 len = MODE_LINE_NOPROP_LEN (title_start);
11198 title = mode_line_noprop_buf + title_start;
11199 unbind_to (count, Qnil);
11201 /* Set the title only if it's changed. This avoids consing in
11202 the common case where it hasn't. (If it turns out that we've
11203 already wasted too much time by walking through the list with
11204 display_mode_element, then we might need to optimize at a
11205 higher level than this.) */
11206 if (! STRINGP (f->name)
11207 || SBYTES (f->name) != len
11208 || memcmp (title, SDATA (f->name), len) != 0)
11209 x_implicitly_set_name (f, make_string (title, len), Qnil);
11213 #endif /* not HAVE_WINDOW_SYSTEM */
11216 /***********************************************************************
11217 Menu Bars
11218 ***********************************************************************/
11221 /* Prepare for redisplay by updating menu-bar item lists when
11222 appropriate. This can call eval. */
11224 void
11225 prepare_menu_bars (void)
11227 int all_windows;
11228 struct gcpro gcpro1, gcpro2;
11229 struct frame *f;
11230 Lisp_Object tooltip_frame;
11232 #ifdef HAVE_WINDOW_SYSTEM
11233 tooltip_frame = tip_frame;
11234 #else
11235 tooltip_frame = Qnil;
11236 #endif
11238 /* Update all frame titles based on their buffer names, etc. We do
11239 this before the menu bars so that the buffer-menu will show the
11240 up-to-date frame titles. */
11241 #ifdef HAVE_WINDOW_SYSTEM
11242 if (windows_or_buffers_changed || update_mode_lines)
11244 Lisp_Object tail, frame;
11246 FOR_EACH_FRAME (tail, frame)
11248 f = XFRAME (frame);
11249 if (!EQ (frame, tooltip_frame)
11250 && (FRAME_ICONIFIED_P (f)
11251 || FRAME_VISIBLE_P (f) == 1
11252 /* Exclude TTY frames that are obscured because they
11253 are not the top frame on their console. This is
11254 because x_consider_frame_title actually switches
11255 to the frame, which for TTY frames means it is
11256 marked as garbaged, and will be completely
11257 redrawn on the next redisplay cycle. This causes
11258 TTY frames to be completely redrawn, when there
11259 are more than one of them, even though nothing
11260 should be changed on display. */
11261 || (FRAME_VISIBLE_P (f) == 2 && FRAME_WINDOW_P (f))))
11262 x_consider_frame_title (frame);
11265 #endif /* HAVE_WINDOW_SYSTEM */
11267 /* Update the menu bar item lists, if appropriate. This has to be
11268 done before any actual redisplay or generation of display lines. */
11269 all_windows = (update_mode_lines
11270 || buffer_shared_and_changed ()
11271 || windows_or_buffers_changed);
11272 if (all_windows)
11274 Lisp_Object tail, frame;
11275 ptrdiff_t count = SPECPDL_INDEX ();
11276 /* 1 means that update_menu_bar has run its hooks
11277 so any further calls to update_menu_bar shouldn't do so again. */
11278 int menu_bar_hooks_run = 0;
11280 record_unwind_save_match_data ();
11282 FOR_EACH_FRAME (tail, frame)
11284 f = XFRAME (frame);
11286 /* Ignore tooltip frame. */
11287 if (EQ (frame, tooltip_frame))
11288 continue;
11290 /* If a window on this frame changed size, report that to
11291 the user and clear the size-change flag. */
11292 if (FRAME_WINDOW_SIZES_CHANGED (f))
11294 Lisp_Object functions;
11296 /* Clear flag first in case we get an error below. */
11297 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
11298 functions = Vwindow_size_change_functions;
11299 GCPRO2 (tail, functions);
11301 while (CONSP (functions))
11303 if (!EQ (XCAR (functions), Qt))
11304 call1 (XCAR (functions), frame);
11305 functions = XCDR (functions);
11307 UNGCPRO;
11310 GCPRO1 (tail);
11311 menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
11312 #ifdef HAVE_WINDOW_SYSTEM
11313 update_tool_bar (f, 0);
11314 #endif
11315 #ifdef HAVE_NS
11316 if (windows_or_buffers_changed
11317 && FRAME_NS_P (f))
11318 ns_set_doc_edited
11319 (f, Fbuffer_modified_p (XWINDOW (f->selected_window)->contents));
11320 #endif
11321 UNGCPRO;
11324 unbind_to (count, Qnil);
11326 else
11328 struct frame *sf = SELECTED_FRAME ();
11329 update_menu_bar (sf, 1, 0);
11330 #ifdef HAVE_WINDOW_SYSTEM
11331 update_tool_bar (sf, 1);
11332 #endif
11337 /* Update the menu bar item list for frame F. This has to be done
11338 before we start to fill in any display lines, because it can call
11339 eval.
11341 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
11343 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
11344 already ran the menu bar hooks for this redisplay, so there
11345 is no need to run them again. The return value is the
11346 updated value of this flag, to pass to the next call. */
11348 static int
11349 update_menu_bar (struct frame *f, int save_match_data, int hooks_run)
11351 Lisp_Object window;
11352 register struct window *w;
11354 /* If called recursively during a menu update, do nothing. This can
11355 happen when, for instance, an activate-menubar-hook causes a
11356 redisplay. */
11357 if (inhibit_menubar_update)
11358 return hooks_run;
11360 window = FRAME_SELECTED_WINDOW (f);
11361 w = XWINDOW (window);
11363 if (FRAME_WINDOW_P (f)
11365 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11366 || defined (HAVE_NS) || defined (USE_GTK)
11367 FRAME_EXTERNAL_MENU_BAR (f)
11368 #else
11369 FRAME_MENU_BAR_LINES (f) > 0
11370 #endif
11371 : FRAME_MENU_BAR_LINES (f) > 0)
11373 /* If the user has switched buffers or windows, we need to
11374 recompute to reflect the new bindings. But we'll
11375 recompute when update_mode_lines is set too; that means
11376 that people can use force-mode-line-update to request
11377 that the menu bar be recomputed. The adverse effect on
11378 the rest of the redisplay algorithm is about the same as
11379 windows_or_buffers_changed anyway. */
11380 if (windows_or_buffers_changed
11381 /* This used to test w->update_mode_line, but we believe
11382 there is no need to recompute the menu in that case. */
11383 || update_mode_lines
11384 || window_buffer_changed (w))
11386 struct buffer *prev = current_buffer;
11387 ptrdiff_t count = SPECPDL_INDEX ();
11389 specbind (Qinhibit_menubar_update, Qt);
11391 set_buffer_internal_1 (XBUFFER (w->contents));
11392 if (save_match_data)
11393 record_unwind_save_match_data ();
11394 if (NILP (Voverriding_local_map_menu_flag))
11396 specbind (Qoverriding_terminal_local_map, Qnil);
11397 specbind (Qoverriding_local_map, Qnil);
11400 if (!hooks_run)
11402 /* Run the Lucid hook. */
11403 safe_run_hooks (Qactivate_menubar_hook);
11405 /* If it has changed current-menubar from previous value,
11406 really recompute the menu-bar from the value. */
11407 if (! NILP (Vlucid_menu_bar_dirty_flag))
11408 call0 (Qrecompute_lucid_menubar);
11410 safe_run_hooks (Qmenu_bar_update_hook);
11412 hooks_run = 1;
11415 XSETFRAME (Vmenu_updating_frame, f);
11416 fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f)));
11418 /* Redisplay the menu bar in case we changed it. */
11419 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11420 || defined (HAVE_NS) || defined (USE_GTK)
11421 if (FRAME_WINDOW_P (f))
11423 #if defined (HAVE_NS)
11424 /* All frames on Mac OS share the same menubar. So only
11425 the selected frame should be allowed to set it. */
11426 if (f == SELECTED_FRAME ())
11427 #endif
11428 set_frame_menubar (f, 0, 0);
11430 else
11431 /* On a terminal screen, the menu bar is an ordinary screen
11432 line, and this makes it get updated. */
11433 w->update_mode_line = 1;
11434 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11435 /* In the non-toolkit version, the menu bar is an ordinary screen
11436 line, and this makes it get updated. */
11437 w->update_mode_line = 1;
11438 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11440 unbind_to (count, Qnil);
11441 set_buffer_internal_1 (prev);
11445 return hooks_run;
11450 /***********************************************************************
11451 Output Cursor
11452 ***********************************************************************/
11454 #ifdef HAVE_WINDOW_SYSTEM
11456 /* EXPORT:
11457 Nominal cursor position -- where to draw output.
11458 HPOS and VPOS are window relative glyph matrix coordinates.
11459 X and Y are window relative pixel coordinates. */
11461 struct cursor_pos output_cursor;
11464 /* EXPORT:
11465 Set the global variable output_cursor to CURSOR. All cursor
11466 positions are relative to currently updated window. */
11468 void
11469 set_output_cursor (struct cursor_pos *cursor)
11471 output_cursor.hpos = cursor->hpos;
11472 output_cursor.vpos = cursor->vpos;
11473 output_cursor.x = cursor->x;
11474 output_cursor.y = cursor->y;
11478 /* EXPORT for RIF:
11479 Set a nominal cursor position.
11481 HPOS and VPOS are column/row positions in a window glyph matrix.
11482 X and Y are window text area relative pixel positions.
11484 This is always done during window update, so the position is the
11485 future output cursor position for currently updated window W.
11486 NOTE: W is used only to check whether this function is called
11487 in a consistent manner via the redisplay interface. */
11489 void
11490 x_cursor_to (struct window *w, int vpos, int hpos, int y, int x)
11492 eassert (w);
11494 /* Set the output cursor. */
11495 output_cursor.hpos = hpos;
11496 output_cursor.vpos = vpos;
11497 output_cursor.x = x;
11498 output_cursor.y = y;
11501 #endif /* HAVE_WINDOW_SYSTEM */
11504 /***********************************************************************
11505 Tool-bars
11506 ***********************************************************************/
11508 #ifdef HAVE_WINDOW_SYSTEM
11510 /* Where the mouse was last time we reported a mouse event. */
11512 struct frame *last_mouse_frame;
11514 /* Tool-bar item index of the item on which a mouse button was pressed
11515 or -1. */
11517 int last_tool_bar_item;
11519 /* Select `frame' temporarily without running all the code in
11520 do_switch_frame.
11521 FIXME: Maybe do_switch_frame should be trimmed down similarly
11522 when `norecord' is set. */
11523 static void
11524 fast_set_selected_frame (Lisp_Object frame)
11526 if (!EQ (selected_frame, frame))
11528 selected_frame = frame;
11529 selected_window = XFRAME (frame)->selected_window;
11533 /* Update the tool-bar item list for frame F. This has to be done
11534 before we start to fill in any display lines. Called from
11535 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
11536 and restore it here. */
11538 static void
11539 update_tool_bar (struct frame *f, int save_match_data)
11541 #if defined (USE_GTK) || defined (HAVE_NS)
11542 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
11543 #else
11544 int do_update = WINDOWP (f->tool_bar_window)
11545 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
11546 #endif
11548 if (do_update)
11550 Lisp_Object window;
11551 struct window *w;
11553 window = FRAME_SELECTED_WINDOW (f);
11554 w = XWINDOW (window);
11556 /* If the user has switched buffers or windows, we need to
11557 recompute to reflect the new bindings. But we'll
11558 recompute when update_mode_lines is set too; that means
11559 that people can use force-mode-line-update to request
11560 that the menu bar be recomputed. The adverse effect on
11561 the rest of the redisplay algorithm is about the same as
11562 windows_or_buffers_changed anyway. */
11563 if (windows_or_buffers_changed
11564 || w->update_mode_line
11565 || update_mode_lines
11566 || window_buffer_changed (w))
11568 struct buffer *prev = current_buffer;
11569 ptrdiff_t count = SPECPDL_INDEX ();
11570 Lisp_Object frame, new_tool_bar;
11571 int new_n_tool_bar;
11572 struct gcpro gcpro1;
11574 /* Set current_buffer to the buffer of the selected
11575 window of the frame, so that we get the right local
11576 keymaps. */
11577 set_buffer_internal_1 (XBUFFER (w->contents));
11579 /* Save match data, if we must. */
11580 if (save_match_data)
11581 record_unwind_save_match_data ();
11583 /* Make sure that we don't accidentally use bogus keymaps. */
11584 if (NILP (Voverriding_local_map_menu_flag))
11586 specbind (Qoverriding_terminal_local_map, Qnil);
11587 specbind (Qoverriding_local_map, Qnil);
11590 GCPRO1 (new_tool_bar);
11592 /* We must temporarily set the selected frame to this frame
11593 before calling tool_bar_items, because the calculation of
11594 the tool-bar keymap uses the selected frame (see
11595 `tool-bar-make-keymap' in tool-bar.el). */
11596 eassert (EQ (selected_window,
11597 /* Since we only explicitly preserve selected_frame,
11598 check that selected_window would be redundant. */
11599 XFRAME (selected_frame)->selected_window));
11600 record_unwind_protect (fast_set_selected_frame, selected_frame);
11601 XSETFRAME (frame, f);
11602 fast_set_selected_frame (frame);
11604 /* Build desired tool-bar items from keymaps. */
11605 new_tool_bar
11606 = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
11607 &new_n_tool_bar);
11609 /* Redisplay the tool-bar if we changed it. */
11610 if (new_n_tool_bar != f->n_tool_bar_items
11611 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
11613 /* Redisplay that happens asynchronously due to an expose event
11614 may access f->tool_bar_items. Make sure we update both
11615 variables within BLOCK_INPUT so no such event interrupts. */
11616 block_input ();
11617 fset_tool_bar_items (f, new_tool_bar);
11618 f->n_tool_bar_items = new_n_tool_bar;
11619 w->update_mode_line = 1;
11620 unblock_input ();
11623 UNGCPRO;
11625 unbind_to (count, Qnil);
11626 set_buffer_internal_1 (prev);
11632 /* Set F->desired_tool_bar_string to a Lisp string representing frame
11633 F's desired tool-bar contents. F->tool_bar_items must have
11634 been set up previously by calling prepare_menu_bars. */
11636 static void
11637 build_desired_tool_bar_string (struct frame *f)
11639 int i, size, size_needed;
11640 struct gcpro gcpro1, gcpro2, gcpro3;
11641 Lisp_Object image, plist, props;
11643 image = plist = props = Qnil;
11644 GCPRO3 (image, plist, props);
11646 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
11647 Otherwise, make a new string. */
11649 /* The size of the string we might be able to reuse. */
11650 size = (STRINGP (f->desired_tool_bar_string)
11651 ? SCHARS (f->desired_tool_bar_string)
11652 : 0);
11654 /* We need one space in the string for each image. */
11655 size_needed = f->n_tool_bar_items;
11657 /* Reuse f->desired_tool_bar_string, if possible. */
11658 if (size < size_needed || NILP (f->desired_tool_bar_string))
11659 fset_desired_tool_bar_string
11660 (f, Fmake_string (make_number (size_needed), make_number (' ')));
11661 else
11663 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
11664 Fremove_text_properties (make_number (0), make_number (size),
11665 props, f->desired_tool_bar_string);
11668 /* Put a `display' property on the string for the images to display,
11669 put a `menu_item' property on tool-bar items with a value that
11670 is the index of the item in F's tool-bar item vector. */
11671 for (i = 0; i < f->n_tool_bar_items; ++i)
11673 #define PROP(IDX) \
11674 AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
11676 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
11677 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
11678 int hmargin, vmargin, relief, idx, end;
11680 /* If image is a vector, choose the image according to the
11681 button state. */
11682 image = PROP (TOOL_BAR_ITEM_IMAGES);
11683 if (VECTORP (image))
11685 if (enabled_p)
11686 idx = (selected_p
11687 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
11688 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
11689 else
11690 idx = (selected_p
11691 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
11692 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
11694 eassert (ASIZE (image) >= idx);
11695 image = AREF (image, idx);
11697 else
11698 idx = -1;
11700 /* Ignore invalid image specifications. */
11701 if (!valid_image_p (image))
11702 continue;
11704 /* Display the tool-bar button pressed, or depressed. */
11705 plist = Fcopy_sequence (XCDR (image));
11707 /* Compute margin and relief to draw. */
11708 relief = (tool_bar_button_relief >= 0
11709 ? tool_bar_button_relief
11710 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
11711 hmargin = vmargin = relief;
11713 if (RANGED_INTEGERP (1, Vtool_bar_button_margin,
11714 INT_MAX - max (hmargin, vmargin)))
11716 hmargin += XFASTINT (Vtool_bar_button_margin);
11717 vmargin += XFASTINT (Vtool_bar_button_margin);
11719 else if (CONSP (Vtool_bar_button_margin))
11721 if (RANGED_INTEGERP (1, XCAR (Vtool_bar_button_margin),
11722 INT_MAX - hmargin))
11723 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
11725 if (RANGED_INTEGERP (1, XCDR (Vtool_bar_button_margin),
11726 INT_MAX - vmargin))
11727 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
11730 if (auto_raise_tool_bar_buttons_p)
11732 /* Add a `:relief' property to the image spec if the item is
11733 selected. */
11734 if (selected_p)
11736 plist = Fplist_put (plist, QCrelief, make_number (-relief));
11737 hmargin -= relief;
11738 vmargin -= relief;
11741 else
11743 /* If image is selected, display it pressed, i.e. with a
11744 negative relief. If it's not selected, display it with a
11745 raised relief. */
11746 plist = Fplist_put (plist, QCrelief,
11747 (selected_p
11748 ? make_number (-relief)
11749 : make_number (relief)));
11750 hmargin -= relief;
11751 vmargin -= relief;
11754 /* Put a margin around the image. */
11755 if (hmargin || vmargin)
11757 if (hmargin == vmargin)
11758 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
11759 else
11760 plist = Fplist_put (plist, QCmargin,
11761 Fcons (make_number (hmargin),
11762 make_number (vmargin)));
11765 /* If button is not enabled, and we don't have special images
11766 for the disabled state, make the image appear disabled by
11767 applying an appropriate algorithm to it. */
11768 if (!enabled_p && idx < 0)
11769 plist = Fplist_put (plist, QCconversion, Qdisabled);
11771 /* Put a `display' text property on the string for the image to
11772 display. Put a `menu-item' property on the string that gives
11773 the start of this item's properties in the tool-bar items
11774 vector. */
11775 image = Fcons (Qimage, plist);
11776 props = list4 (Qdisplay, image,
11777 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
11779 /* Let the last image hide all remaining spaces in the tool bar
11780 string. The string can be longer than needed when we reuse a
11781 previous string. */
11782 if (i + 1 == f->n_tool_bar_items)
11783 end = SCHARS (f->desired_tool_bar_string);
11784 else
11785 end = i + 1;
11786 Fadd_text_properties (make_number (i), make_number (end),
11787 props, f->desired_tool_bar_string);
11788 #undef PROP
11791 UNGCPRO;
11795 /* Display one line of the tool-bar of frame IT->f.
11797 HEIGHT specifies the desired height of the tool-bar line.
11798 If the actual height of the glyph row is less than HEIGHT, the
11799 row's height is increased to HEIGHT, and the icons are centered
11800 vertically in the new height.
11802 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
11803 count a final empty row in case the tool-bar width exactly matches
11804 the window width.
11807 static void
11808 display_tool_bar_line (struct it *it, int height)
11810 struct glyph_row *row = it->glyph_row;
11811 int max_x = it->last_visible_x;
11812 struct glyph *last;
11814 prepare_desired_row (row);
11815 row->y = it->current_y;
11817 /* Note that this isn't made use of if the face hasn't a box,
11818 so there's no need to check the face here. */
11819 it->start_of_box_run_p = 1;
11821 while (it->current_x < max_x)
11823 int x, n_glyphs_before, i, nglyphs;
11824 struct it it_before;
11826 /* Get the next display element. */
11827 if (!get_next_display_element (it))
11829 /* Don't count empty row if we are counting needed tool-bar lines. */
11830 if (height < 0 && !it->hpos)
11831 return;
11832 break;
11835 /* Produce glyphs. */
11836 n_glyphs_before = row->used[TEXT_AREA];
11837 it_before = *it;
11839 PRODUCE_GLYPHS (it);
11841 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
11842 i = 0;
11843 x = it_before.current_x;
11844 while (i < nglyphs)
11846 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
11848 if (x + glyph->pixel_width > max_x)
11850 /* Glyph doesn't fit on line. Backtrack. */
11851 row->used[TEXT_AREA] = n_glyphs_before;
11852 *it = it_before;
11853 /* If this is the only glyph on this line, it will never fit on the
11854 tool-bar, so skip it. But ensure there is at least one glyph,
11855 so we don't accidentally disable the tool-bar. */
11856 if (n_glyphs_before == 0
11857 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
11858 break;
11859 goto out;
11862 ++it->hpos;
11863 x += glyph->pixel_width;
11864 ++i;
11867 /* Stop at line end. */
11868 if (ITERATOR_AT_END_OF_LINE_P (it))
11869 break;
11871 set_iterator_to_next (it, 1);
11874 out:;
11876 row->displays_text_p = row->used[TEXT_AREA] != 0;
11878 /* Use default face for the border below the tool bar.
11880 FIXME: When auto-resize-tool-bars is grow-only, there is
11881 no additional border below the possibly empty tool-bar lines.
11882 So to make the extra empty lines look "normal", we have to
11883 use the tool-bar face for the border too. */
11884 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
11885 && !EQ (Vauto_resize_tool_bars, Qgrow_only))
11886 it->face_id = DEFAULT_FACE_ID;
11888 extend_face_to_end_of_line (it);
11889 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
11890 last->right_box_line_p = 1;
11891 if (last == row->glyphs[TEXT_AREA])
11892 last->left_box_line_p = 1;
11894 /* Make line the desired height and center it vertically. */
11895 if ((height -= it->max_ascent + it->max_descent) > 0)
11897 /* Don't add more than one line height. */
11898 height %= FRAME_LINE_HEIGHT (it->f);
11899 it->max_ascent += height / 2;
11900 it->max_descent += (height + 1) / 2;
11903 compute_line_metrics (it);
11905 /* If line is empty, make it occupy the rest of the tool-bar. */
11906 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row))
11908 row->height = row->phys_height = it->last_visible_y - row->y;
11909 row->visible_height = row->height;
11910 row->ascent = row->phys_ascent = 0;
11911 row->extra_line_spacing = 0;
11914 row->full_width_p = 1;
11915 row->continued_p = 0;
11916 row->truncated_on_left_p = 0;
11917 row->truncated_on_right_p = 0;
11919 it->current_x = it->hpos = 0;
11920 it->current_y += row->height;
11921 ++it->vpos;
11922 ++it->glyph_row;
11926 /* Max tool-bar height. */
11928 #define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
11929 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
11931 /* Value is the number of screen lines needed to make all tool-bar
11932 items of frame F visible. The number of actual rows needed is
11933 returned in *N_ROWS if non-NULL. */
11935 static int
11936 tool_bar_lines_needed (struct frame *f, int *n_rows)
11938 struct window *w = XWINDOW (f->tool_bar_window);
11939 struct it it;
11940 /* tool_bar_lines_needed is called from redisplay_tool_bar after building
11941 the desired matrix, so use (unused) mode-line row as temporary row to
11942 avoid destroying the first tool-bar row. */
11943 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
11945 /* Initialize an iterator for iteration over
11946 F->desired_tool_bar_string in the tool-bar window of frame F. */
11947 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
11948 it.first_visible_x = 0;
11949 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
11950 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
11951 it.paragraph_embedding = L2R;
11953 while (!ITERATOR_AT_END_P (&it))
11955 clear_glyph_row (temp_row);
11956 it.glyph_row = temp_row;
11957 display_tool_bar_line (&it, -1);
11959 clear_glyph_row (temp_row);
11961 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
11962 if (n_rows)
11963 *n_rows = it.vpos > 0 ? it.vpos : -1;
11965 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
11969 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
11970 0, 1, 0,
11971 doc: /* Return the number of lines occupied by the tool bar of FRAME.
11972 If FRAME is nil or omitted, use the selected frame. */)
11973 (Lisp_Object frame)
11975 struct frame *f = decode_any_frame (frame);
11976 struct window *w;
11977 int nlines = 0;
11979 if (WINDOWP (f->tool_bar_window)
11980 && (w = XWINDOW (f->tool_bar_window),
11981 WINDOW_TOTAL_LINES (w) > 0))
11983 update_tool_bar (f, 1);
11984 if (f->n_tool_bar_items)
11986 build_desired_tool_bar_string (f);
11987 nlines = tool_bar_lines_needed (f, NULL);
11991 return make_number (nlines);
11995 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
11996 height should be changed. */
11998 static int
11999 redisplay_tool_bar (struct frame *f)
12001 struct window *w;
12002 struct it it;
12003 struct glyph_row *row;
12005 #if defined (USE_GTK) || defined (HAVE_NS)
12006 if (FRAME_EXTERNAL_TOOL_BAR (f))
12007 update_frame_tool_bar (f);
12008 return 0;
12009 #endif
12011 /* If frame hasn't a tool-bar window or if it is zero-height, don't
12012 do anything. This means you must start with tool-bar-lines
12013 non-zero to get the auto-sizing effect. Or in other words, you
12014 can turn off tool-bars by specifying tool-bar-lines zero. */
12015 if (!WINDOWP (f->tool_bar_window)
12016 || (w = XWINDOW (f->tool_bar_window),
12017 WINDOW_TOTAL_LINES (w) == 0))
12018 return 0;
12020 /* Set up an iterator for the tool-bar window. */
12021 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
12022 it.first_visible_x = 0;
12023 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
12024 row = it.glyph_row;
12026 /* Build a string that represents the contents of the tool-bar. */
12027 build_desired_tool_bar_string (f);
12028 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
12029 /* FIXME: This should be controlled by a user option. But it
12030 doesn't make sense to have an R2L tool bar if the menu bar cannot
12031 be drawn also R2L, and making the menu bar R2L is tricky due
12032 toolkit-specific code that implements it. If an R2L tool bar is
12033 ever supported, display_tool_bar_line should also be augmented to
12034 call unproduce_glyphs like display_line and display_string
12035 do. */
12036 it.paragraph_embedding = L2R;
12038 if (f->n_tool_bar_rows == 0)
12040 int nlines;
12042 if ((nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
12043 nlines != WINDOW_TOTAL_LINES (w)))
12045 Lisp_Object frame;
12046 int old_height = WINDOW_TOTAL_LINES (w);
12048 XSETFRAME (frame, f);
12049 Fmodify_frame_parameters (frame,
12050 list1 (Fcons (Qtool_bar_lines,
12051 make_number (nlines))));
12052 if (WINDOW_TOTAL_LINES (w) != old_height)
12054 clear_glyph_matrix (w->desired_matrix);
12055 fonts_changed_p = 1;
12056 return 1;
12061 /* Display as many lines as needed to display all tool-bar items. */
12063 if (f->n_tool_bar_rows > 0)
12065 int border, rows, height, extra;
12067 if (TYPE_RANGED_INTEGERP (int, Vtool_bar_border))
12068 border = XINT (Vtool_bar_border);
12069 else if (EQ (Vtool_bar_border, Qinternal_border_width))
12070 border = FRAME_INTERNAL_BORDER_WIDTH (f);
12071 else if (EQ (Vtool_bar_border, Qborder_width))
12072 border = f->border_width;
12073 else
12074 border = 0;
12075 if (border < 0)
12076 border = 0;
12078 rows = f->n_tool_bar_rows;
12079 height = max (1, (it.last_visible_y - border) / rows);
12080 extra = it.last_visible_y - border - height * rows;
12082 while (it.current_y < it.last_visible_y)
12084 int h = 0;
12085 if (extra > 0 && rows-- > 0)
12087 h = (extra + rows - 1) / rows;
12088 extra -= h;
12090 display_tool_bar_line (&it, height + h);
12093 else
12095 while (it.current_y < it.last_visible_y)
12096 display_tool_bar_line (&it, 0);
12099 /* It doesn't make much sense to try scrolling in the tool-bar
12100 window, so don't do it. */
12101 w->desired_matrix->no_scrolling_p = 1;
12102 w->must_be_updated_p = 1;
12104 if (!NILP (Vauto_resize_tool_bars))
12106 int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
12107 int change_height_p = 0;
12109 /* If we couldn't display everything, change the tool-bar's
12110 height if there is room for more. */
12111 if (IT_STRING_CHARPOS (it) < it.end_charpos
12112 && it.current_y < max_tool_bar_height)
12113 change_height_p = 1;
12115 row = it.glyph_row - 1;
12117 /* If there are blank lines at the end, except for a partially
12118 visible blank line at the end that is smaller than
12119 FRAME_LINE_HEIGHT, change the tool-bar's height. */
12120 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
12121 && row->height >= FRAME_LINE_HEIGHT (f))
12122 change_height_p = 1;
12124 /* If row displays tool-bar items, but is partially visible,
12125 change the tool-bar's height. */
12126 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12127 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y
12128 && MATRIX_ROW_BOTTOM_Y (row) < max_tool_bar_height)
12129 change_height_p = 1;
12131 /* Resize windows as needed by changing the `tool-bar-lines'
12132 frame parameter. */
12133 if (change_height_p)
12135 Lisp_Object frame;
12136 int old_height = WINDOW_TOTAL_LINES (w);
12137 int nrows;
12138 int nlines = tool_bar_lines_needed (f, &nrows);
12140 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
12141 && !f->minimize_tool_bar_window_p)
12142 ? (nlines > old_height)
12143 : (nlines != old_height));
12144 f->minimize_tool_bar_window_p = 0;
12146 if (change_height_p)
12148 XSETFRAME (frame, f);
12149 Fmodify_frame_parameters (frame,
12150 list1 (Fcons (Qtool_bar_lines,
12151 make_number (nlines))));
12152 if (WINDOW_TOTAL_LINES (w) != old_height)
12154 clear_glyph_matrix (w->desired_matrix);
12155 f->n_tool_bar_rows = nrows;
12156 fonts_changed_p = 1;
12157 return 1;
12163 f->minimize_tool_bar_window_p = 0;
12164 return 0;
12168 /* Get information about the tool-bar item which is displayed in GLYPH
12169 on frame F. Return in *PROP_IDX the index where tool-bar item
12170 properties start in F->tool_bar_items. Value is zero if
12171 GLYPH doesn't display a tool-bar item. */
12173 static int
12174 tool_bar_item_info (struct frame *f, struct glyph *glyph, int *prop_idx)
12176 Lisp_Object prop;
12177 int success_p;
12178 int charpos;
12180 /* This function can be called asynchronously, which means we must
12181 exclude any possibility that Fget_text_property signals an
12182 error. */
12183 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
12184 charpos = max (0, charpos);
12186 /* Get the text property `menu-item' at pos. The value of that
12187 property is the start index of this item's properties in
12188 F->tool_bar_items. */
12189 prop = Fget_text_property (make_number (charpos),
12190 Qmenu_item, f->current_tool_bar_string);
12191 if (INTEGERP (prop))
12193 *prop_idx = XINT (prop);
12194 success_p = 1;
12196 else
12197 success_p = 0;
12199 return success_p;
12203 /* Get information about the tool-bar item at position X/Y on frame F.
12204 Return in *GLYPH a pointer to the glyph of the tool-bar item in
12205 the current matrix of the tool-bar window of F, or NULL if not
12206 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
12207 item in F->tool_bar_items. Value is
12209 -1 if X/Y is not on a tool-bar item
12210 0 if X/Y is on the same item that was highlighted before.
12211 1 otherwise. */
12213 static int
12214 get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
12215 int *hpos, int *vpos, int *prop_idx)
12217 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12218 struct window *w = XWINDOW (f->tool_bar_window);
12219 int area;
12221 /* Find the glyph under X/Y. */
12222 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
12223 if (*glyph == NULL)
12224 return -1;
12226 /* Get the start of this tool-bar item's properties in
12227 f->tool_bar_items. */
12228 if (!tool_bar_item_info (f, *glyph, prop_idx))
12229 return -1;
12231 /* Is mouse on the highlighted item? */
12232 if (EQ (f->tool_bar_window, hlinfo->mouse_face_window)
12233 && *vpos >= hlinfo->mouse_face_beg_row
12234 && *vpos <= hlinfo->mouse_face_end_row
12235 && (*vpos > hlinfo->mouse_face_beg_row
12236 || *hpos >= hlinfo->mouse_face_beg_col)
12237 && (*vpos < hlinfo->mouse_face_end_row
12238 || *hpos < hlinfo->mouse_face_end_col
12239 || hlinfo->mouse_face_past_end))
12240 return 0;
12242 return 1;
12246 /* EXPORT:
12247 Handle mouse button event on the tool-bar of frame F, at
12248 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
12249 0 for button release. MODIFIERS is event modifiers for button
12250 release. */
12252 void
12253 handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
12254 int modifiers)
12256 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12257 struct window *w = XWINDOW (f->tool_bar_window);
12258 int hpos, vpos, prop_idx;
12259 struct glyph *glyph;
12260 Lisp_Object enabled_p;
12261 int ts;
12263 /* If not on the highlighted tool-bar item, and mouse-highlight is
12264 non-nil, return. This is so we generate the tool-bar button
12265 click only when the mouse button is released on the same item as
12266 where it was pressed. However, when mouse-highlight is disabled,
12267 generate the click when the button is released regardless of the
12268 highlight, since tool-bar items are not highlighted in that
12269 case. */
12270 frame_to_window_pixel_xy (w, &x, &y);
12271 ts = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
12272 if (ts == -1
12273 || (ts != 0 && !NILP (Vmouse_highlight)))
12274 return;
12276 /* When mouse-highlight is off, generate the click for the item
12277 where the button was pressed, disregarding where it was
12278 released. */
12279 if (NILP (Vmouse_highlight) && !down_p)
12280 prop_idx = last_tool_bar_item;
12282 /* If item is disabled, do nothing. */
12283 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
12284 if (NILP (enabled_p))
12285 return;
12287 if (down_p)
12289 /* Show item in pressed state. */
12290 if (!NILP (Vmouse_highlight))
12291 show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN);
12292 last_tool_bar_item = prop_idx;
12294 else
12296 Lisp_Object key, frame;
12297 struct input_event event;
12298 EVENT_INIT (event);
12300 /* Show item in released state. */
12301 if (!NILP (Vmouse_highlight))
12302 show_mouse_face (hlinfo, DRAW_IMAGE_RAISED);
12304 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
12306 XSETFRAME (frame, f);
12307 event.kind = TOOL_BAR_EVENT;
12308 event.frame_or_window = frame;
12309 event.arg = frame;
12310 kbd_buffer_store_event (&event);
12312 event.kind = TOOL_BAR_EVENT;
12313 event.frame_or_window = frame;
12314 event.arg = key;
12315 event.modifiers = modifiers;
12316 kbd_buffer_store_event (&event);
12317 last_tool_bar_item = -1;
12322 /* Possibly highlight a tool-bar item on frame F when mouse moves to
12323 tool-bar window-relative coordinates X/Y. Called from
12324 note_mouse_highlight. */
12326 static void
12327 note_tool_bar_highlight (struct frame *f, int x, int y)
12329 Lisp_Object window = f->tool_bar_window;
12330 struct window *w = XWINDOW (window);
12331 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
12332 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12333 int hpos, vpos;
12334 struct glyph *glyph;
12335 struct glyph_row *row;
12336 int i;
12337 Lisp_Object enabled_p;
12338 int prop_idx;
12339 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
12340 int mouse_down_p, rc;
12342 /* Function note_mouse_highlight is called with negative X/Y
12343 values when mouse moves outside of the frame. */
12344 if (x <= 0 || y <= 0)
12346 clear_mouse_face (hlinfo);
12347 return;
12350 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
12351 if (rc < 0)
12353 /* Not on tool-bar item. */
12354 clear_mouse_face (hlinfo);
12355 return;
12357 else if (rc == 0)
12358 /* On same tool-bar item as before. */
12359 goto set_help_echo;
12361 clear_mouse_face (hlinfo);
12363 /* Mouse is down, but on different tool-bar item? */
12364 mouse_down_p = (dpyinfo->grabbed
12365 && f == last_mouse_frame
12366 && FRAME_LIVE_P (f));
12367 if (mouse_down_p
12368 && last_tool_bar_item != prop_idx)
12369 return;
12371 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
12373 /* If tool-bar item is not enabled, don't highlight it. */
12374 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
12375 if (!NILP (enabled_p) && !NILP (Vmouse_highlight))
12377 /* Compute the x-position of the glyph. In front and past the
12378 image is a space. We include this in the highlighted area. */
12379 row = MATRIX_ROW (w->current_matrix, vpos);
12380 for (i = x = 0; i < hpos; ++i)
12381 x += row->glyphs[TEXT_AREA][i].pixel_width;
12383 /* Record this as the current active region. */
12384 hlinfo->mouse_face_beg_col = hpos;
12385 hlinfo->mouse_face_beg_row = vpos;
12386 hlinfo->mouse_face_beg_x = x;
12387 hlinfo->mouse_face_beg_y = row->y;
12388 hlinfo->mouse_face_past_end = 0;
12390 hlinfo->mouse_face_end_col = hpos + 1;
12391 hlinfo->mouse_face_end_row = vpos;
12392 hlinfo->mouse_face_end_x = x + glyph->pixel_width;
12393 hlinfo->mouse_face_end_y = row->y;
12394 hlinfo->mouse_face_window = window;
12395 hlinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
12397 /* Display it as active. */
12398 show_mouse_face (hlinfo, draw);
12401 set_help_echo:
12403 /* Set help_echo_string to a help string to display for this tool-bar item.
12404 XTread_socket does the rest. */
12405 help_echo_object = help_echo_window = Qnil;
12406 help_echo_pos = -1;
12407 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
12408 if (NILP (help_echo_string))
12409 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
12412 #endif /* HAVE_WINDOW_SYSTEM */
12416 /************************************************************************
12417 Horizontal scrolling
12418 ************************************************************************/
12420 static int hscroll_window_tree (Lisp_Object);
12421 static int hscroll_windows (Lisp_Object);
12423 /* For all leaf windows in the window tree rooted at WINDOW, set their
12424 hscroll value so that PT is (i) visible in the window, and (ii) so
12425 that it is not within a certain margin at the window's left and
12426 right border. Value is non-zero if any window's hscroll has been
12427 changed. */
12429 static int
12430 hscroll_window_tree (Lisp_Object window)
12432 int hscrolled_p = 0;
12433 int hscroll_relative_p = FLOATP (Vhscroll_step);
12434 int hscroll_step_abs = 0;
12435 double hscroll_step_rel = 0;
12437 if (hscroll_relative_p)
12439 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
12440 if (hscroll_step_rel < 0)
12442 hscroll_relative_p = 0;
12443 hscroll_step_abs = 0;
12446 else if (TYPE_RANGED_INTEGERP (int, Vhscroll_step))
12448 hscroll_step_abs = XINT (Vhscroll_step);
12449 if (hscroll_step_abs < 0)
12450 hscroll_step_abs = 0;
12452 else
12453 hscroll_step_abs = 0;
12455 while (WINDOWP (window))
12457 struct window *w = XWINDOW (window);
12459 if (WINDOWP (w->contents))
12460 hscrolled_p |= hscroll_window_tree (w->contents);
12461 else if (w->cursor.vpos >= 0)
12463 int h_margin;
12464 int text_area_width;
12465 struct glyph_row *current_cursor_row
12466 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
12467 struct glyph_row *desired_cursor_row
12468 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
12469 struct glyph_row *cursor_row
12470 = (desired_cursor_row->enabled_p
12471 ? desired_cursor_row
12472 : current_cursor_row);
12473 int row_r2l_p = cursor_row->reversed_p;
12475 text_area_width = window_box_width (w, TEXT_AREA);
12477 /* Scroll when cursor is inside this scroll margin. */
12478 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
12480 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->contents))
12481 /* For left-to-right rows, hscroll when cursor is either
12482 (i) inside the right hscroll margin, or (ii) if it is
12483 inside the left margin and the window is already
12484 hscrolled. */
12485 && ((!row_r2l_p
12486 && ((w->hscroll
12487 && w->cursor.x <= h_margin)
12488 || (cursor_row->enabled_p
12489 && cursor_row->truncated_on_right_p
12490 && (w->cursor.x >= text_area_width - h_margin))))
12491 /* For right-to-left rows, the logic is similar,
12492 except that rules for scrolling to left and right
12493 are reversed. E.g., if cursor.x <= h_margin, we
12494 need to hscroll "to the right" unconditionally,
12495 and that will scroll the screen to the left so as
12496 to reveal the next portion of the row. */
12497 || (row_r2l_p
12498 && ((cursor_row->enabled_p
12499 /* FIXME: It is confusing to set the
12500 truncated_on_right_p flag when R2L rows
12501 are actually truncated on the left. */
12502 && cursor_row->truncated_on_right_p
12503 && w->cursor.x <= h_margin)
12504 || (w->hscroll
12505 && (w->cursor.x >= text_area_width - h_margin))))))
12507 struct it it;
12508 ptrdiff_t hscroll;
12509 struct buffer *saved_current_buffer;
12510 ptrdiff_t pt;
12511 int wanted_x;
12513 /* Find point in a display of infinite width. */
12514 saved_current_buffer = current_buffer;
12515 current_buffer = XBUFFER (w->contents);
12517 if (w == XWINDOW (selected_window))
12518 pt = PT;
12519 else
12520 pt = clip_to_bounds (BEGV, marker_position (w->pointm), ZV);
12522 /* Move iterator to pt starting at cursor_row->start in
12523 a line with infinite width. */
12524 init_to_row_start (&it, w, cursor_row);
12525 it.last_visible_x = INFINITY;
12526 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
12527 current_buffer = saved_current_buffer;
12529 /* Position cursor in window. */
12530 if (!hscroll_relative_p && hscroll_step_abs == 0)
12531 hscroll = max (0, (it.current_x
12532 - (ITERATOR_AT_END_OF_LINE_P (&it)
12533 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
12534 : (text_area_width / 2))))
12535 / FRAME_COLUMN_WIDTH (it.f);
12536 else if ((!row_r2l_p
12537 && w->cursor.x >= text_area_width - h_margin)
12538 || (row_r2l_p && w->cursor.x <= h_margin))
12540 if (hscroll_relative_p)
12541 wanted_x = text_area_width * (1 - hscroll_step_rel)
12542 - h_margin;
12543 else
12544 wanted_x = text_area_width
12545 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
12546 - h_margin;
12547 hscroll
12548 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
12550 else
12552 if (hscroll_relative_p)
12553 wanted_x = text_area_width * hscroll_step_rel
12554 + h_margin;
12555 else
12556 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
12557 + h_margin;
12558 hscroll
12559 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
12561 hscroll = max (hscroll, w->min_hscroll);
12563 /* Don't prevent redisplay optimizations if hscroll
12564 hasn't changed, as it will unnecessarily slow down
12565 redisplay. */
12566 if (w->hscroll != hscroll)
12568 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
12569 w->hscroll = hscroll;
12570 hscrolled_p = 1;
12575 window = w->next;
12578 /* Value is non-zero if hscroll of any leaf window has been changed. */
12579 return hscrolled_p;
12583 /* Set hscroll so that cursor is visible and not inside horizontal
12584 scroll margins for all windows in the tree rooted at WINDOW. See
12585 also hscroll_window_tree above. Value is non-zero if any window's
12586 hscroll has been changed. If it has, desired matrices on the frame
12587 of WINDOW are cleared. */
12589 static int
12590 hscroll_windows (Lisp_Object window)
12592 int hscrolled_p = hscroll_window_tree (window);
12593 if (hscrolled_p)
12594 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
12595 return hscrolled_p;
12600 /************************************************************************
12601 Redisplay
12602 ************************************************************************/
12604 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
12605 to a non-zero value. This is sometimes handy to have in a debugger
12606 session. */
12608 #ifdef GLYPH_DEBUG
12610 /* First and last unchanged row for try_window_id. */
12612 static int debug_first_unchanged_at_end_vpos;
12613 static int debug_last_unchanged_at_beg_vpos;
12615 /* Delta vpos and y. */
12617 static int debug_dvpos, debug_dy;
12619 /* Delta in characters and bytes for try_window_id. */
12621 static ptrdiff_t debug_delta, debug_delta_bytes;
12623 /* Values of window_end_pos and window_end_vpos at the end of
12624 try_window_id. */
12626 static ptrdiff_t debug_end_vpos;
12628 /* Append a string to W->desired_matrix->method. FMT is a printf
12629 format string. If trace_redisplay_p is non-zero also printf the
12630 resulting string to stderr. */
12632 static void debug_method_add (struct window *, char const *, ...)
12633 ATTRIBUTE_FORMAT_PRINTF (2, 3);
12635 static void
12636 debug_method_add (struct window *w, char const *fmt, ...)
12638 void *ptr = w;
12639 char *method = w->desired_matrix->method;
12640 int len = strlen (method);
12641 int size = sizeof w->desired_matrix->method;
12642 int remaining = size - len - 1;
12643 va_list ap;
12645 if (len && remaining)
12647 method[len] = '|';
12648 --remaining, ++len;
12651 va_start (ap, fmt);
12652 vsnprintf (method + len, remaining + 1, fmt, ap);
12653 va_end (ap);
12655 if (trace_redisplay_p)
12656 fprintf (stderr, "%p (%s): %s\n",
12657 ptr,
12658 ((BUFFERP (w->contents)
12659 && STRINGP (BVAR (XBUFFER (w->contents), name)))
12660 ? SSDATA (BVAR (XBUFFER (w->contents), name))
12661 : "no buffer"),
12662 method + len);
12665 #endif /* GLYPH_DEBUG */
12668 /* Value is non-zero if all changes in window W, which displays
12669 current_buffer, are in the text between START and END. START is a
12670 buffer position, END is given as a distance from Z. Used in
12671 redisplay_internal for display optimization. */
12673 static int
12674 text_outside_line_unchanged_p (struct window *w,
12675 ptrdiff_t start, ptrdiff_t end)
12677 int unchanged_p = 1;
12679 /* If text or overlays have changed, see where. */
12680 if (window_outdated (w))
12682 /* Gap in the line? */
12683 if (GPT < start || Z - GPT < end)
12684 unchanged_p = 0;
12686 /* Changes start in front of the line, or end after it? */
12687 if (unchanged_p
12688 && (BEG_UNCHANGED < start - 1
12689 || END_UNCHANGED < end))
12690 unchanged_p = 0;
12692 /* If selective display, can't optimize if changes start at the
12693 beginning of the line. */
12694 if (unchanged_p
12695 && INTEGERP (BVAR (current_buffer, selective_display))
12696 && XINT (BVAR (current_buffer, selective_display)) > 0
12697 && (BEG_UNCHANGED < start || GPT <= start))
12698 unchanged_p = 0;
12700 /* If there are overlays at the start or end of the line, these
12701 may have overlay strings with newlines in them. A change at
12702 START, for instance, may actually concern the display of such
12703 overlay strings as well, and they are displayed on different
12704 lines. So, quickly rule out this case. (For the future, it
12705 might be desirable to implement something more telling than
12706 just BEG/END_UNCHANGED.) */
12707 if (unchanged_p)
12709 if (BEG + BEG_UNCHANGED == start
12710 && overlay_touches_p (start))
12711 unchanged_p = 0;
12712 if (END_UNCHANGED == end
12713 && overlay_touches_p (Z - end))
12714 unchanged_p = 0;
12717 /* Under bidi reordering, adding or deleting a character in the
12718 beginning of a paragraph, before the first strong directional
12719 character, can change the base direction of the paragraph (unless
12720 the buffer specifies a fixed paragraph direction), which will
12721 require to redisplay the whole paragraph. It might be worthwhile
12722 to find the paragraph limits and widen the range of redisplayed
12723 lines to that, but for now just give up this optimization. */
12724 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
12725 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
12726 unchanged_p = 0;
12729 return unchanged_p;
12733 /* Do a frame update, taking possible shortcuts into account. This is
12734 the main external entry point for redisplay.
12736 If the last redisplay displayed an echo area message and that message
12737 is no longer requested, we clear the echo area or bring back the
12738 mini-buffer if that is in use. */
12740 void
12741 redisplay (void)
12743 redisplay_internal ();
12747 static Lisp_Object
12748 overlay_arrow_string_or_property (Lisp_Object var)
12750 Lisp_Object val;
12752 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
12753 return val;
12755 return Voverlay_arrow_string;
12758 /* Return 1 if there are any overlay-arrows in current_buffer. */
12759 static int
12760 overlay_arrow_in_current_buffer_p (void)
12762 Lisp_Object vlist;
12764 for (vlist = Voverlay_arrow_variable_list;
12765 CONSP (vlist);
12766 vlist = XCDR (vlist))
12768 Lisp_Object var = XCAR (vlist);
12769 Lisp_Object val;
12771 if (!SYMBOLP (var))
12772 continue;
12773 val = find_symbol_value (var);
12774 if (MARKERP (val)
12775 && current_buffer == XMARKER (val)->buffer)
12776 return 1;
12778 return 0;
12782 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
12783 has changed. */
12785 static int
12786 overlay_arrows_changed_p (void)
12788 Lisp_Object vlist;
12790 for (vlist = Voverlay_arrow_variable_list;
12791 CONSP (vlist);
12792 vlist = XCDR (vlist))
12794 Lisp_Object var = XCAR (vlist);
12795 Lisp_Object val, pstr;
12797 if (!SYMBOLP (var))
12798 continue;
12799 val = find_symbol_value (var);
12800 if (!MARKERP (val))
12801 continue;
12802 if (! EQ (COERCE_MARKER (val),
12803 Fget (var, Qlast_arrow_position))
12804 || ! (pstr = overlay_arrow_string_or_property (var),
12805 EQ (pstr, Fget (var, Qlast_arrow_string))))
12806 return 1;
12808 return 0;
12811 /* Mark overlay arrows to be updated on next redisplay. */
12813 static void
12814 update_overlay_arrows (int up_to_date)
12816 Lisp_Object vlist;
12818 for (vlist = Voverlay_arrow_variable_list;
12819 CONSP (vlist);
12820 vlist = XCDR (vlist))
12822 Lisp_Object var = XCAR (vlist);
12824 if (!SYMBOLP (var))
12825 continue;
12827 if (up_to_date > 0)
12829 Lisp_Object val = find_symbol_value (var);
12830 Fput (var, Qlast_arrow_position,
12831 COERCE_MARKER (val));
12832 Fput (var, Qlast_arrow_string,
12833 overlay_arrow_string_or_property (var));
12835 else if (up_to_date < 0
12836 || !NILP (Fget (var, Qlast_arrow_position)))
12838 Fput (var, Qlast_arrow_position, Qt);
12839 Fput (var, Qlast_arrow_string, Qt);
12845 /* Return overlay arrow string to display at row.
12846 Return integer (bitmap number) for arrow bitmap in left fringe.
12847 Return nil if no overlay arrow. */
12849 static Lisp_Object
12850 overlay_arrow_at_row (struct it *it, struct glyph_row *row)
12852 Lisp_Object vlist;
12854 for (vlist = Voverlay_arrow_variable_list;
12855 CONSP (vlist);
12856 vlist = XCDR (vlist))
12858 Lisp_Object var = XCAR (vlist);
12859 Lisp_Object val;
12861 if (!SYMBOLP (var))
12862 continue;
12864 val = find_symbol_value (var);
12866 if (MARKERP (val)
12867 && current_buffer == XMARKER (val)->buffer
12868 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
12870 if (FRAME_WINDOW_P (it->f)
12871 /* FIXME: if ROW->reversed_p is set, this should test
12872 the right fringe, not the left one. */
12873 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
12875 #ifdef HAVE_WINDOW_SYSTEM
12876 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
12878 int fringe_bitmap;
12879 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
12880 return make_number (fringe_bitmap);
12882 #endif
12883 return make_number (-1); /* Use default arrow bitmap. */
12885 return overlay_arrow_string_or_property (var);
12889 return Qnil;
12892 /* Return 1 if point moved out of or into a composition. Otherwise
12893 return 0. PREV_BUF and PREV_PT are the last point buffer and
12894 position. BUF and PT are the current point buffer and position. */
12896 static int
12897 check_point_in_composition (struct buffer *prev_buf, ptrdiff_t prev_pt,
12898 struct buffer *buf, ptrdiff_t pt)
12900 ptrdiff_t start, end;
12901 Lisp_Object prop;
12902 Lisp_Object buffer;
12904 XSETBUFFER (buffer, buf);
12905 /* Check a composition at the last point if point moved within the
12906 same buffer. */
12907 if (prev_buf == buf)
12909 if (prev_pt == pt)
12910 /* Point didn't move. */
12911 return 0;
12913 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
12914 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
12915 && composition_valid_p (start, end, prop)
12916 && start < prev_pt && end > prev_pt)
12917 /* The last point was within the composition. Return 1 iff
12918 point moved out of the composition. */
12919 return (pt <= start || pt >= end);
12922 /* Check a composition at the current point. */
12923 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
12924 && find_composition (pt, -1, &start, &end, &prop, buffer)
12925 && composition_valid_p (start, end, prop)
12926 && start < pt && end > pt);
12929 /* Reconsider the clip changes of buffer which is displayed in W. */
12931 static void
12932 reconsider_clip_changes (struct window *w)
12934 struct buffer *b = XBUFFER (w->contents);
12936 if (b->clip_changed
12937 && w->window_end_valid
12938 && w->current_matrix->buffer == b
12939 && w->current_matrix->zv == BUF_ZV (b)
12940 && w->current_matrix->begv == BUF_BEGV (b))
12941 b->clip_changed = 0;
12943 /* If display wasn't paused, and W is not a tool bar window, see if
12944 point has been moved into or out of a composition. In that case,
12945 we set b->clip_changed to 1 to force updating the screen. If
12946 b->clip_changed has already been set to 1, we can skip this
12947 check. */
12948 if (!b->clip_changed && w->window_end_valid)
12950 ptrdiff_t pt = (w == XWINDOW (selected_window)
12951 ? PT : marker_position (w->pointm));
12953 if ((w->current_matrix->buffer != b || pt != w->last_point)
12954 && check_point_in_composition (w->current_matrix->buffer,
12955 w->last_point, b, pt))
12956 b->clip_changed = 1;
12960 #define STOP_POLLING \
12961 do { if (! polling_stopped_here) stop_polling (); \
12962 polling_stopped_here = 1; } while (0)
12964 #define RESUME_POLLING \
12965 do { if (polling_stopped_here) start_polling (); \
12966 polling_stopped_here = 0; } while (0)
12969 /* Perhaps in the future avoid recentering windows if it
12970 is not necessary; currently that causes some problems. */
12972 static void
12973 redisplay_internal (void)
12975 struct window *w = XWINDOW (selected_window);
12976 struct window *sw;
12977 struct frame *fr;
12978 int pending;
12979 bool must_finish = 0, match_p;
12980 struct text_pos tlbufpos, tlendpos;
12981 int number_of_visible_frames;
12982 ptrdiff_t count;
12983 struct frame *sf;
12984 int polling_stopped_here = 0;
12985 Lisp_Object tail, frame;
12987 /* Non-zero means redisplay has to consider all windows on all
12988 frames. Zero means, only selected_window is considered. */
12989 int consider_all_windows_p;
12991 /* Non-zero means redisplay has to redisplay the miniwindow. */
12992 int update_miniwindow_p = 0;
12994 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
12996 /* No redisplay if running in batch mode or frame is not yet fully
12997 initialized, or redisplay is explicitly turned off by setting
12998 Vinhibit_redisplay. */
12999 if (FRAME_INITIAL_P (SELECTED_FRAME ())
13000 || !NILP (Vinhibit_redisplay))
13001 return;
13003 /* Don't examine these until after testing Vinhibit_redisplay.
13004 When Emacs is shutting down, perhaps because its connection to
13005 X has dropped, we should not look at them at all. */
13006 fr = XFRAME (w->frame);
13007 sf = SELECTED_FRAME ();
13009 if (!fr->glyphs_initialized_p)
13010 return;
13012 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
13013 if (popup_activated ())
13014 return;
13015 #endif
13017 /* I don't think this happens but let's be paranoid. */
13018 if (redisplaying_p)
13019 return;
13021 /* Record a function that clears redisplaying_p
13022 when we leave this function. */
13023 count = SPECPDL_INDEX ();
13024 record_unwind_protect_void (unwind_redisplay);
13025 redisplaying_p = 1;
13026 specbind (Qinhibit_free_realized_faces, Qnil);
13028 /* Record this function, so it appears on the profiler's backtraces. */
13029 record_in_backtrace (Qredisplay_internal, &Qnil, 0);
13031 FOR_EACH_FRAME (tail, frame)
13032 XFRAME (frame)->already_hscrolled_p = 0;
13034 retry:
13035 /* Remember the currently selected window. */
13036 sw = w;
13038 pending = 0;
13039 last_escape_glyph_frame = NULL;
13040 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
13041 last_glyphless_glyph_frame = NULL;
13042 last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
13044 /* If new fonts have been loaded that make a glyph matrix adjustment
13045 necessary, do it. */
13046 if (fonts_changed_p)
13048 adjust_glyphs (NULL);
13049 ++windows_or_buffers_changed;
13050 fonts_changed_p = 0;
13053 /* If face_change_count is non-zero, init_iterator will free all
13054 realized faces, which includes the faces referenced from current
13055 matrices. So, we can't reuse current matrices in this case. */
13056 if (face_change_count)
13057 ++windows_or_buffers_changed;
13059 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
13060 && FRAME_TTY (sf)->previous_frame != sf)
13062 /* Since frames on a single ASCII terminal share the same
13063 display area, displaying a different frame means redisplay
13064 the whole thing. */
13065 windows_or_buffers_changed++;
13066 SET_FRAME_GARBAGED (sf);
13067 #ifndef DOS_NT
13068 set_tty_color_mode (FRAME_TTY (sf), sf);
13069 #endif
13070 FRAME_TTY (sf)->previous_frame = sf;
13073 /* Set the visible flags for all frames. Do this before checking for
13074 resized or garbaged frames; they want to know if their frames are
13075 visible. See the comment in frame.h for FRAME_SAMPLE_VISIBILITY. */
13076 number_of_visible_frames = 0;
13078 FOR_EACH_FRAME (tail, frame)
13080 struct frame *f = XFRAME (frame);
13082 if (FRAME_VISIBLE_P (f))
13083 ++number_of_visible_frames;
13084 clear_desired_matrices (f);
13087 /* Notice any pending interrupt request to change frame size. */
13088 do_pending_window_change (1);
13090 /* do_pending_window_change could change the selected_window due to
13091 frame resizing which makes the selected window too small. */
13092 if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw)
13093 sw = w;
13095 /* Clear frames marked as garbaged. */
13096 clear_garbaged_frames ();
13098 /* Build menubar and tool-bar items. */
13099 if (NILP (Vmemory_full))
13100 prepare_menu_bars ();
13102 if (windows_or_buffers_changed)
13103 update_mode_lines++;
13105 reconsider_clip_changes (w);
13107 /* In most cases selected window displays current buffer. */
13108 match_p = XBUFFER (w->contents) == current_buffer;
13109 if (match_p)
13111 ptrdiff_t count1;
13113 /* Detect case that we need to write or remove a star in the mode line. */
13114 if ((SAVE_MODIFF < MODIFF) != w->last_had_star)
13116 w->update_mode_line = 1;
13117 if (buffer_shared_and_changed ())
13118 update_mode_lines++;
13121 /* Avoid invocation of point motion hooks by `current_column' below. */
13122 count1 = SPECPDL_INDEX ();
13123 specbind (Qinhibit_point_motion_hooks, Qt);
13125 if (mode_line_update_needed (w))
13126 w->update_mode_line = 1;
13128 unbind_to (count1, Qnil);
13131 consider_all_windows_p = (update_mode_lines
13132 || buffer_shared_and_changed ()
13133 || cursor_type_changed);
13135 /* If specs for an arrow have changed, do thorough redisplay
13136 to ensure we remove any arrow that should no longer exist. */
13137 if (overlay_arrows_changed_p ())
13138 consider_all_windows_p = windows_or_buffers_changed = 1;
13140 /* Normally the message* functions will have already displayed and
13141 updated the echo area, but the frame may have been trashed, or
13142 the update may have been preempted, so display the echo area
13143 again here. Checking message_cleared_p captures the case that
13144 the echo area should be cleared. */
13145 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
13146 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
13147 || (message_cleared_p
13148 && minibuf_level == 0
13149 /* If the mini-window is currently selected, this means the
13150 echo-area doesn't show through. */
13151 && !MINI_WINDOW_P (XWINDOW (selected_window))))
13153 int window_height_changed_p = echo_area_display (0);
13155 if (message_cleared_p)
13156 update_miniwindow_p = 1;
13158 must_finish = 1;
13160 /* If we don't display the current message, don't clear the
13161 message_cleared_p flag, because, if we did, we wouldn't clear
13162 the echo area in the next redisplay which doesn't preserve
13163 the echo area. */
13164 if (!display_last_displayed_message_p)
13165 message_cleared_p = 0;
13167 if (fonts_changed_p)
13168 goto retry;
13169 else if (window_height_changed_p)
13171 consider_all_windows_p = 1;
13172 ++update_mode_lines;
13173 ++windows_or_buffers_changed;
13175 /* If window configuration was changed, frames may have been
13176 marked garbaged. Clear them or we will experience
13177 surprises wrt scrolling. */
13178 clear_garbaged_frames ();
13181 else if (EQ (selected_window, minibuf_window)
13182 && (current_buffer->clip_changed || window_outdated (w))
13183 && resize_mini_window (w, 0))
13185 /* Resized active mini-window to fit the size of what it is
13186 showing if its contents might have changed. */
13187 must_finish = 1;
13188 /* FIXME: this causes all frames to be updated, which seems unnecessary
13189 since only the current frame needs to be considered. This function
13190 needs to be rewritten with two variables, consider_all_windows and
13191 consider_all_frames. */
13192 consider_all_windows_p = 1;
13193 ++windows_or_buffers_changed;
13194 ++update_mode_lines;
13196 /* If window configuration was changed, frames may have been
13197 marked garbaged. Clear them or we will experience
13198 surprises wrt scrolling. */
13199 clear_garbaged_frames ();
13202 /* If showing the region, and mark has changed, we must redisplay
13203 the whole window. The assignment to this_line_start_pos prevents
13204 the optimization directly below this if-statement. */
13205 if (((!NILP (Vtransient_mark_mode)
13206 && !NILP (BVAR (XBUFFER (w->contents), mark_active)))
13207 != (w->region_showing > 0))
13208 || (w->region_showing
13209 && w->region_showing
13210 != XINT (Fmarker_position (BVAR (XBUFFER (w->contents), mark)))))
13211 CHARPOS (this_line_start_pos) = 0;
13213 /* Optimize the case that only the line containing the cursor in the
13214 selected window has changed. Variables starting with this_ are
13215 set in display_line and record information about the line
13216 containing the cursor. */
13217 tlbufpos = this_line_start_pos;
13218 tlendpos = this_line_end_pos;
13219 if (!consider_all_windows_p
13220 && CHARPOS (tlbufpos) > 0
13221 && !w->update_mode_line
13222 && !current_buffer->clip_changed
13223 && !current_buffer->prevent_redisplay_optimizations_p
13224 && FRAME_VISIBLE_P (XFRAME (w->frame))
13225 && !FRAME_OBSCURED_P (XFRAME (w->frame))
13226 /* Make sure recorded data applies to current buffer, etc. */
13227 && this_line_buffer == current_buffer
13228 && match_p
13229 && !w->force_start
13230 && !w->optional_new_start
13231 /* Point must be on the line that we have info recorded about. */
13232 && PT >= CHARPOS (tlbufpos)
13233 && PT <= Z - CHARPOS (tlendpos)
13234 /* All text outside that line, including its final newline,
13235 must be unchanged. */
13236 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
13237 CHARPOS (tlendpos)))
13239 if (CHARPOS (tlbufpos) > BEGV
13240 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
13241 && (CHARPOS (tlbufpos) == ZV
13242 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
13243 /* Former continuation line has disappeared by becoming empty. */
13244 goto cancel;
13245 else if (window_outdated (w) || MINI_WINDOW_P (w))
13247 /* We have to handle the case of continuation around a
13248 wide-column character (see the comment in indent.c around
13249 line 1340).
13251 For instance, in the following case:
13253 -------- Insert --------
13254 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
13255 J_I_ ==> J_I_ `^^' are cursors.
13256 ^^ ^^
13257 -------- --------
13259 As we have to redraw the line above, we cannot use this
13260 optimization. */
13262 struct it it;
13263 int line_height_before = this_line_pixel_height;
13265 /* Note that start_display will handle the case that the
13266 line starting at tlbufpos is a continuation line. */
13267 start_display (&it, w, tlbufpos);
13269 /* Implementation note: It this still necessary? */
13270 if (it.current_x != this_line_start_x)
13271 goto cancel;
13273 TRACE ((stderr, "trying display optimization 1\n"));
13274 w->cursor.vpos = -1;
13275 overlay_arrow_seen = 0;
13276 it.vpos = this_line_vpos;
13277 it.current_y = this_line_y;
13278 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
13279 display_line (&it);
13281 /* If line contains point, is not continued,
13282 and ends at same distance from eob as before, we win. */
13283 if (w->cursor.vpos >= 0
13284 /* Line is not continued, otherwise this_line_start_pos
13285 would have been set to 0 in display_line. */
13286 && CHARPOS (this_line_start_pos)
13287 /* Line ends as before. */
13288 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
13289 /* Line has same height as before. Otherwise other lines
13290 would have to be shifted up or down. */
13291 && this_line_pixel_height == line_height_before)
13293 /* If this is not the window's last line, we must adjust
13294 the charstarts of the lines below. */
13295 if (it.current_y < it.last_visible_y)
13297 struct glyph_row *row
13298 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
13299 ptrdiff_t delta, delta_bytes;
13301 /* We used to distinguish between two cases here,
13302 conditioned by Z - CHARPOS (tlendpos) == ZV, for
13303 when the line ends in a newline or the end of the
13304 buffer's accessible portion. But both cases did
13305 the same, so they were collapsed. */
13306 delta = (Z
13307 - CHARPOS (tlendpos)
13308 - MATRIX_ROW_START_CHARPOS (row));
13309 delta_bytes = (Z_BYTE
13310 - BYTEPOS (tlendpos)
13311 - MATRIX_ROW_START_BYTEPOS (row));
13313 increment_matrix_positions (w->current_matrix,
13314 this_line_vpos + 1,
13315 w->current_matrix->nrows,
13316 delta, delta_bytes);
13319 /* If this row displays text now but previously didn't,
13320 or vice versa, w->window_end_vpos may have to be
13321 adjusted. */
13322 if (MATRIX_ROW_DISPLAYS_TEXT_P (it.glyph_row - 1))
13324 if (w->window_end_vpos < this_line_vpos)
13325 w->window_end_vpos = this_line_vpos;
13327 else if (w->window_end_vpos == this_line_vpos
13328 && this_line_vpos > 0)
13329 w->window_end_vpos = this_line_vpos - 1;
13330 w->window_end_valid = 0;
13332 /* Update hint: No need to try to scroll in update_window. */
13333 w->desired_matrix->no_scrolling_p = 1;
13335 #ifdef GLYPH_DEBUG
13336 *w->desired_matrix->method = 0;
13337 debug_method_add (w, "optimization 1");
13338 #endif
13339 #ifdef HAVE_WINDOW_SYSTEM
13340 update_window_fringes (w, 0);
13341 #endif
13342 goto update;
13344 else
13345 goto cancel;
13347 else if (/* Cursor position hasn't changed. */
13348 PT == w->last_point
13349 /* Make sure the cursor was last displayed
13350 in this window. Otherwise we have to reposition it. */
13351 && 0 <= w->cursor.vpos
13352 && w->cursor.vpos < WINDOW_TOTAL_LINES (w))
13354 if (!must_finish)
13356 do_pending_window_change (1);
13357 /* If selected_window changed, redisplay again. */
13358 if (WINDOWP (selected_window)
13359 && (w = XWINDOW (selected_window)) != sw)
13360 goto retry;
13362 /* We used to always goto end_of_redisplay here, but this
13363 isn't enough if we have a blinking cursor. */
13364 if (w->cursor_off_p == w->last_cursor_off_p)
13365 goto end_of_redisplay;
13367 goto update;
13369 /* If highlighting the region, or if the cursor is in the echo area,
13370 then we can't just move the cursor. */
13371 else if (! (!NILP (Vtransient_mark_mode)
13372 && !NILP (BVAR (current_buffer, mark_active)))
13373 && (EQ (selected_window,
13374 BVAR (current_buffer, last_selected_window))
13375 || highlight_nonselected_windows)
13376 && !w->region_showing
13377 && NILP (Vshow_trailing_whitespace)
13378 && !cursor_in_echo_area)
13380 struct it it;
13381 struct glyph_row *row;
13383 /* Skip from tlbufpos to PT and see where it is. Note that
13384 PT may be in invisible text. If so, we will end at the
13385 next visible position. */
13386 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
13387 NULL, DEFAULT_FACE_ID);
13388 it.current_x = this_line_start_x;
13389 it.current_y = this_line_y;
13390 it.vpos = this_line_vpos;
13392 /* The call to move_it_to stops in front of PT, but
13393 moves over before-strings. */
13394 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
13396 if (it.vpos == this_line_vpos
13397 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
13398 row->enabled_p))
13400 eassert (this_line_vpos == it.vpos);
13401 eassert (this_line_y == it.current_y);
13402 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13403 #ifdef GLYPH_DEBUG
13404 *w->desired_matrix->method = 0;
13405 debug_method_add (w, "optimization 3");
13406 #endif
13407 goto update;
13409 else
13410 goto cancel;
13413 cancel:
13414 /* Text changed drastically or point moved off of line. */
13415 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
13418 CHARPOS (this_line_start_pos) = 0;
13419 consider_all_windows_p |= buffer_shared_and_changed ();
13420 ++clear_face_cache_count;
13421 #ifdef HAVE_WINDOW_SYSTEM
13422 ++clear_image_cache_count;
13423 #endif
13425 /* Build desired matrices, and update the display. If
13426 consider_all_windows_p is non-zero, do it for all windows on all
13427 frames. Otherwise do it for selected_window, only. */
13429 if (consider_all_windows_p)
13431 FOR_EACH_FRAME (tail, frame)
13432 XFRAME (frame)->updated_p = 0;
13434 FOR_EACH_FRAME (tail, frame)
13436 struct frame *f = XFRAME (frame);
13438 /* We don't have to do anything for unselected terminal
13439 frames. */
13440 if ((FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
13441 && !EQ (FRAME_TTY (f)->top_frame, frame))
13442 continue;
13444 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
13446 /* Mark all the scroll bars to be removed; we'll redeem
13447 the ones we want when we redisplay their windows. */
13448 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
13449 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
13451 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
13452 redisplay_windows (FRAME_ROOT_WINDOW (f));
13454 /* The X error handler may have deleted that frame. */
13455 if (!FRAME_LIVE_P (f))
13456 continue;
13458 /* Any scroll bars which redisplay_windows should have
13459 nuked should now go away. */
13460 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
13461 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
13463 /* If fonts changed, display again. */
13464 /* ??? rms: I suspect it is a mistake to jump all the way
13465 back to retry here. It should just retry this frame. */
13466 if (fonts_changed_p)
13467 goto retry;
13469 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
13471 /* See if we have to hscroll. */
13472 if (!f->already_hscrolled_p)
13474 f->already_hscrolled_p = 1;
13475 if (hscroll_windows (f->root_window))
13476 goto retry;
13479 /* Prevent various kinds of signals during display
13480 update. stdio is not robust about handling
13481 signals, which can cause an apparent I/O
13482 error. */
13483 if (interrupt_input)
13484 unrequest_sigio ();
13485 STOP_POLLING;
13487 /* Update the display. */
13488 set_window_update_flags (XWINDOW (f->root_window), 1);
13489 pending |= update_frame (f, 0, 0);
13490 f->updated_p = 1;
13495 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
13497 if (!pending)
13499 /* Do the mark_window_display_accurate after all windows have
13500 been redisplayed because this call resets flags in buffers
13501 which are needed for proper redisplay. */
13502 FOR_EACH_FRAME (tail, frame)
13504 struct frame *f = XFRAME (frame);
13505 if (f->updated_p)
13507 mark_window_display_accurate (f->root_window, 1);
13508 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
13509 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
13514 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
13516 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
13517 struct frame *mini_frame;
13519 displayed_buffer = XBUFFER (XWINDOW (selected_window)->contents);
13520 /* Use list_of_error, not Qerror, so that
13521 we catch only errors and don't run the debugger. */
13522 internal_condition_case_1 (redisplay_window_1, selected_window,
13523 list_of_error,
13524 redisplay_window_error);
13525 if (update_miniwindow_p)
13526 internal_condition_case_1 (redisplay_window_1, mini_window,
13527 list_of_error,
13528 redisplay_window_error);
13530 /* Compare desired and current matrices, perform output. */
13532 update:
13533 /* If fonts changed, display again. */
13534 if (fonts_changed_p)
13535 goto retry;
13537 /* Prevent various kinds of signals during display update.
13538 stdio is not robust about handling signals,
13539 which can cause an apparent I/O error. */
13540 if (interrupt_input)
13541 unrequest_sigio ();
13542 STOP_POLLING;
13544 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
13546 if (hscroll_windows (selected_window))
13547 goto retry;
13549 XWINDOW (selected_window)->must_be_updated_p = 1;
13550 pending = update_frame (sf, 0, 0);
13553 /* We may have called echo_area_display at the top of this
13554 function. If the echo area is on another frame, that may
13555 have put text on a frame other than the selected one, so the
13556 above call to update_frame would not have caught it. Catch
13557 it here. */
13558 mini_window = FRAME_MINIBUF_WINDOW (sf);
13559 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
13561 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
13563 XWINDOW (mini_window)->must_be_updated_p = 1;
13564 pending |= update_frame (mini_frame, 0, 0);
13565 if (!pending && hscroll_windows (mini_window))
13566 goto retry;
13570 /* If display was paused because of pending input, make sure we do a
13571 thorough update the next time. */
13572 if (pending)
13574 /* Prevent the optimization at the beginning of
13575 redisplay_internal that tries a single-line update of the
13576 line containing the cursor in the selected window. */
13577 CHARPOS (this_line_start_pos) = 0;
13579 /* Let the overlay arrow be updated the next time. */
13580 update_overlay_arrows (0);
13582 /* If we pause after scrolling, some rows in the current
13583 matrices of some windows are not valid. */
13584 if (!WINDOW_FULL_WIDTH_P (w)
13585 && !FRAME_WINDOW_P (XFRAME (w->frame)))
13586 update_mode_lines = 1;
13588 else
13590 if (!consider_all_windows_p)
13592 /* This has already been done above if
13593 consider_all_windows_p is set. */
13594 mark_window_display_accurate_1 (w, 1);
13596 /* Say overlay arrows are up to date. */
13597 update_overlay_arrows (1);
13599 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
13600 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
13603 update_mode_lines = 0;
13604 windows_or_buffers_changed = 0;
13605 cursor_type_changed = 0;
13608 /* Start SIGIO interrupts coming again. Having them off during the
13609 code above makes it less likely one will discard output, but not
13610 impossible, since there might be stuff in the system buffer here.
13611 But it is much hairier to try to do anything about that. */
13612 if (interrupt_input)
13613 request_sigio ();
13614 RESUME_POLLING;
13616 /* If a frame has become visible which was not before, redisplay
13617 again, so that we display it. Expose events for such a frame
13618 (which it gets when becoming visible) don't call the parts of
13619 redisplay constructing glyphs, so simply exposing a frame won't
13620 display anything in this case. So, we have to display these
13621 frames here explicitly. */
13622 if (!pending)
13624 int new_count = 0;
13626 FOR_EACH_FRAME (tail, frame)
13628 int this_is_visible = 0;
13630 if (XFRAME (frame)->visible)
13631 this_is_visible = 1;
13633 if (this_is_visible)
13634 new_count++;
13637 if (new_count != number_of_visible_frames)
13638 windows_or_buffers_changed++;
13641 /* Change frame size now if a change is pending. */
13642 do_pending_window_change (1);
13644 /* If we just did a pending size change, or have additional
13645 visible frames, or selected_window changed, redisplay again. */
13646 if ((windows_or_buffers_changed && !pending)
13647 || (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw))
13648 goto retry;
13650 /* Clear the face and image caches.
13652 We used to do this only if consider_all_windows_p. But the cache
13653 needs to be cleared if a timer creates images in the current
13654 buffer (e.g. the test case in Bug#6230). */
13656 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
13658 clear_face_cache (0);
13659 clear_face_cache_count = 0;
13662 #ifdef HAVE_WINDOW_SYSTEM
13663 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
13665 clear_image_caches (Qnil);
13666 clear_image_cache_count = 0;
13668 #endif /* HAVE_WINDOW_SYSTEM */
13670 end_of_redisplay:
13671 unbind_to (count, Qnil);
13672 RESUME_POLLING;
13676 /* Redisplay, but leave alone any recent echo area message unless
13677 another message has been requested in its place.
13679 This is useful in situations where you need to redisplay but no
13680 user action has occurred, making it inappropriate for the message
13681 area to be cleared. See tracking_off and
13682 wait_reading_process_output for examples of these situations.
13684 FROM_WHERE is an integer saying from where this function was
13685 called. This is useful for debugging. */
13687 void
13688 redisplay_preserve_echo_area (int from_where)
13690 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
13692 if (!NILP (echo_area_buffer[1]))
13694 /* We have a previously displayed message, but no current
13695 message. Redisplay the previous message. */
13696 display_last_displayed_message_p = 1;
13697 redisplay_internal ();
13698 display_last_displayed_message_p = 0;
13700 else
13701 redisplay_internal ();
13703 if (FRAME_RIF (SELECTED_FRAME ()) != NULL
13704 && FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
13705 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (NULL);
13709 /* Function registered with record_unwind_protect in redisplay_internal. */
13711 static void
13712 unwind_redisplay (void)
13714 redisplaying_p = 0;
13718 /* Mark the display of leaf window W as accurate or inaccurate.
13719 If ACCURATE_P is non-zero mark display of W as accurate. If
13720 ACCURATE_P is zero, arrange for W to be redisplayed the next
13721 time redisplay_internal is called. */
13723 static void
13724 mark_window_display_accurate_1 (struct window *w, int accurate_p)
13726 struct buffer *b = XBUFFER (w->contents);
13728 w->last_modified = accurate_p ? BUF_MODIFF (b) : 0;
13729 w->last_overlay_modified = accurate_p ? BUF_OVERLAY_MODIFF (b) : 0;
13730 w->last_had_star = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b);
13732 if (accurate_p)
13734 b->clip_changed = 0;
13735 b->prevent_redisplay_optimizations_p = 0;
13737 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
13738 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
13739 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
13740 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
13742 w->current_matrix->buffer = b;
13743 w->current_matrix->begv = BUF_BEGV (b);
13744 w->current_matrix->zv = BUF_ZV (b);
13746 w->last_cursor_vpos = w->cursor.vpos;
13747 w->last_cursor_off_p = w->cursor_off_p;
13749 if (w == XWINDOW (selected_window))
13750 w->last_point = BUF_PT (b);
13751 else
13752 w->last_point = marker_position (w->pointm);
13754 w->window_end_valid = 1;
13755 w->update_mode_line = 0;
13760 /* Mark the display of windows in the window tree rooted at WINDOW as
13761 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
13762 windows as accurate. If ACCURATE_P is zero, arrange for windows to
13763 be redisplayed the next time redisplay_internal is called. */
13765 void
13766 mark_window_display_accurate (Lisp_Object window, int accurate_p)
13768 struct window *w;
13770 for (; !NILP (window); window = w->next)
13772 w = XWINDOW (window);
13773 if (WINDOWP (w->contents))
13774 mark_window_display_accurate (w->contents, accurate_p);
13775 else
13776 mark_window_display_accurate_1 (w, accurate_p);
13779 if (accurate_p)
13780 update_overlay_arrows (1);
13781 else
13782 /* Force a thorough redisplay the next time by setting
13783 last_arrow_position and last_arrow_string to t, which is
13784 unequal to any useful value of Voverlay_arrow_... */
13785 update_overlay_arrows (-1);
13789 /* Return value in display table DP (Lisp_Char_Table *) for character
13790 C. Since a display table doesn't have any parent, we don't have to
13791 follow parent. Do not call this function directly but use the
13792 macro DISP_CHAR_VECTOR. */
13794 Lisp_Object
13795 disp_char_vector (struct Lisp_Char_Table *dp, int c)
13797 Lisp_Object val;
13799 if (ASCII_CHAR_P (c))
13801 val = dp->ascii;
13802 if (SUB_CHAR_TABLE_P (val))
13803 val = XSUB_CHAR_TABLE (val)->contents[c];
13805 else
13807 Lisp_Object table;
13809 XSETCHAR_TABLE (table, dp);
13810 val = char_table_ref (table, c);
13812 if (NILP (val))
13813 val = dp->defalt;
13814 return val;
13819 /***********************************************************************
13820 Window Redisplay
13821 ***********************************************************************/
13823 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
13825 static void
13826 redisplay_windows (Lisp_Object window)
13828 while (!NILP (window))
13830 struct window *w = XWINDOW (window);
13832 if (WINDOWP (w->contents))
13833 redisplay_windows (w->contents);
13834 else if (BUFFERP (w->contents))
13836 displayed_buffer = XBUFFER (w->contents);
13837 /* Use list_of_error, not Qerror, so that
13838 we catch only errors and don't run the debugger. */
13839 internal_condition_case_1 (redisplay_window_0, window,
13840 list_of_error,
13841 redisplay_window_error);
13844 window = w->next;
13848 static Lisp_Object
13849 redisplay_window_error (Lisp_Object ignore)
13851 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
13852 return Qnil;
13855 static Lisp_Object
13856 redisplay_window_0 (Lisp_Object window)
13858 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
13859 redisplay_window (window, 0);
13860 return Qnil;
13863 static Lisp_Object
13864 redisplay_window_1 (Lisp_Object window)
13866 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
13867 redisplay_window (window, 1);
13868 return Qnil;
13872 /* Set cursor position of W. PT is assumed to be displayed in ROW.
13873 DELTA and DELTA_BYTES are the numbers of characters and bytes by
13874 which positions recorded in ROW differ from current buffer
13875 positions.
13877 Return 0 if cursor is not on this row, 1 otherwise. */
13879 static int
13880 set_cursor_from_row (struct window *w, struct glyph_row *row,
13881 struct glyph_matrix *matrix,
13882 ptrdiff_t delta, ptrdiff_t delta_bytes,
13883 int dy, int dvpos)
13885 struct glyph *glyph = row->glyphs[TEXT_AREA];
13886 struct glyph *end = glyph + row->used[TEXT_AREA];
13887 struct glyph *cursor = NULL;
13888 /* The last known character position in row. */
13889 ptrdiff_t last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
13890 int x = row->x;
13891 ptrdiff_t pt_old = PT - delta;
13892 ptrdiff_t pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
13893 ptrdiff_t pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
13894 struct glyph *glyph_before = glyph - 1, *glyph_after = end;
13895 /* A glyph beyond the edge of TEXT_AREA which we should never
13896 touch. */
13897 struct glyph *glyphs_end = end;
13898 /* Non-zero means we've found a match for cursor position, but that
13899 glyph has the avoid_cursor_p flag set. */
13900 int match_with_avoid_cursor = 0;
13901 /* Non-zero means we've seen at least one glyph that came from a
13902 display string. */
13903 int string_seen = 0;
13904 /* Largest and smallest buffer positions seen so far during scan of
13905 glyph row. */
13906 ptrdiff_t bpos_max = pos_before;
13907 ptrdiff_t bpos_min = pos_after;
13908 /* Last buffer position covered by an overlay string with an integer
13909 `cursor' property. */
13910 ptrdiff_t bpos_covered = 0;
13911 /* Non-zero means the display string on which to display the cursor
13912 comes from a text property, not from an overlay. */
13913 int string_from_text_prop = 0;
13915 /* Don't even try doing anything if called for a mode-line or
13916 header-line row, since the rest of the code isn't prepared to
13917 deal with such calamities. */
13918 eassert (!row->mode_line_p);
13919 if (row->mode_line_p)
13920 return 0;
13922 /* Skip over glyphs not having an object at the start and the end of
13923 the row. These are special glyphs like truncation marks on
13924 terminal frames. */
13925 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
13927 if (!row->reversed_p)
13929 while (glyph < end
13930 && INTEGERP (glyph->object)
13931 && glyph->charpos < 0)
13933 x += glyph->pixel_width;
13934 ++glyph;
13936 while (end > glyph
13937 && INTEGERP ((end - 1)->object)
13938 /* CHARPOS is zero for blanks and stretch glyphs
13939 inserted by extend_face_to_end_of_line. */
13940 && (end - 1)->charpos <= 0)
13941 --end;
13942 glyph_before = glyph - 1;
13943 glyph_after = end;
13945 else
13947 struct glyph *g;
13949 /* If the glyph row is reversed, we need to process it from back
13950 to front, so swap the edge pointers. */
13951 glyphs_end = end = glyph - 1;
13952 glyph += row->used[TEXT_AREA] - 1;
13954 while (glyph > end + 1
13955 && INTEGERP (glyph->object)
13956 && glyph->charpos < 0)
13958 --glyph;
13959 x -= glyph->pixel_width;
13961 if (INTEGERP (glyph->object) && glyph->charpos < 0)
13962 --glyph;
13963 /* By default, in reversed rows we put the cursor on the
13964 rightmost (first in the reading order) glyph. */
13965 for (g = end + 1; g < glyph; g++)
13966 x += g->pixel_width;
13967 while (end < glyph
13968 && INTEGERP ((end + 1)->object)
13969 && (end + 1)->charpos <= 0)
13970 ++end;
13971 glyph_before = glyph + 1;
13972 glyph_after = end;
13975 else if (row->reversed_p)
13977 /* In R2L rows that don't display text, put the cursor on the
13978 rightmost glyph. Case in point: an empty last line that is
13979 part of an R2L paragraph. */
13980 cursor = end - 1;
13981 /* Avoid placing the cursor on the last glyph of the row, where
13982 on terminal frames we hold the vertical border between
13983 adjacent windows. */
13984 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w))
13985 && !WINDOW_RIGHTMOST_P (w)
13986 && cursor == row->glyphs[LAST_AREA] - 1)
13987 cursor--;
13988 x = -1; /* will be computed below, at label compute_x */
13991 /* Step 1: Try to find the glyph whose character position
13992 corresponds to point. If that's not possible, find 2 glyphs
13993 whose character positions are the closest to point, one before
13994 point, the other after it. */
13995 if (!row->reversed_p)
13996 while (/* not marched to end of glyph row */
13997 glyph < end
13998 /* glyph was not inserted by redisplay for internal purposes */
13999 && !INTEGERP (glyph->object))
14001 if (BUFFERP (glyph->object))
14003 ptrdiff_t dpos = glyph->charpos - pt_old;
14005 if (glyph->charpos > bpos_max)
14006 bpos_max = glyph->charpos;
14007 if (glyph->charpos < bpos_min)
14008 bpos_min = glyph->charpos;
14009 if (!glyph->avoid_cursor_p)
14011 /* If we hit point, we've found the glyph on which to
14012 display the cursor. */
14013 if (dpos == 0)
14015 match_with_avoid_cursor = 0;
14016 break;
14018 /* See if we've found a better approximation to
14019 POS_BEFORE or to POS_AFTER. */
14020 if (0 > dpos && dpos > pos_before - pt_old)
14022 pos_before = glyph->charpos;
14023 glyph_before = glyph;
14025 else if (0 < dpos && dpos < pos_after - pt_old)
14027 pos_after = glyph->charpos;
14028 glyph_after = glyph;
14031 else if (dpos == 0)
14032 match_with_avoid_cursor = 1;
14034 else if (STRINGP (glyph->object))
14036 Lisp_Object chprop;
14037 ptrdiff_t glyph_pos = glyph->charpos;
14039 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
14040 glyph->object);
14041 if (!NILP (chprop))
14043 /* If the string came from a `display' text property,
14044 look up the buffer position of that property and
14045 use that position to update bpos_max, as if we
14046 actually saw such a position in one of the row's
14047 glyphs. This helps with supporting integer values
14048 of `cursor' property on the display string in
14049 situations where most or all of the row's buffer
14050 text is completely covered by display properties,
14051 so that no glyph with valid buffer positions is
14052 ever seen in the row. */
14053 ptrdiff_t prop_pos =
14054 string_buffer_position_lim (glyph->object, pos_before,
14055 pos_after, 0);
14057 if (prop_pos >= pos_before)
14058 bpos_max = prop_pos - 1;
14060 if (INTEGERP (chprop))
14062 bpos_covered = bpos_max + XINT (chprop);
14063 /* If the `cursor' property covers buffer positions up
14064 to and including point, we should display cursor on
14065 this glyph. Note that, if a `cursor' property on one
14066 of the string's characters has an integer value, we
14067 will break out of the loop below _before_ we get to
14068 the position match above. IOW, integer values of
14069 the `cursor' property override the "exact match for
14070 point" strategy of positioning the cursor. */
14071 /* Implementation note: bpos_max == pt_old when, e.g.,
14072 we are in an empty line, where bpos_max is set to
14073 MATRIX_ROW_START_CHARPOS, see above. */
14074 if (bpos_max <= pt_old && bpos_covered >= pt_old)
14076 cursor = glyph;
14077 break;
14081 string_seen = 1;
14083 x += glyph->pixel_width;
14084 ++glyph;
14086 else if (glyph > end) /* row is reversed */
14087 while (!INTEGERP (glyph->object))
14089 if (BUFFERP (glyph->object))
14091 ptrdiff_t dpos = glyph->charpos - pt_old;
14093 if (glyph->charpos > bpos_max)
14094 bpos_max = glyph->charpos;
14095 if (glyph->charpos < bpos_min)
14096 bpos_min = glyph->charpos;
14097 if (!glyph->avoid_cursor_p)
14099 if (dpos == 0)
14101 match_with_avoid_cursor = 0;
14102 break;
14104 if (0 > dpos && dpos > pos_before - pt_old)
14106 pos_before = glyph->charpos;
14107 glyph_before = glyph;
14109 else if (0 < dpos && dpos < pos_after - pt_old)
14111 pos_after = glyph->charpos;
14112 glyph_after = glyph;
14115 else if (dpos == 0)
14116 match_with_avoid_cursor = 1;
14118 else if (STRINGP (glyph->object))
14120 Lisp_Object chprop;
14121 ptrdiff_t glyph_pos = glyph->charpos;
14123 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
14124 glyph->object);
14125 if (!NILP (chprop))
14127 ptrdiff_t prop_pos =
14128 string_buffer_position_lim (glyph->object, pos_before,
14129 pos_after, 0);
14131 if (prop_pos >= pos_before)
14132 bpos_max = prop_pos - 1;
14134 if (INTEGERP (chprop))
14136 bpos_covered = bpos_max + XINT (chprop);
14137 /* If the `cursor' property covers buffer positions up
14138 to and including point, we should display cursor on
14139 this glyph. */
14140 if (bpos_max <= pt_old && bpos_covered >= pt_old)
14142 cursor = glyph;
14143 break;
14146 string_seen = 1;
14148 --glyph;
14149 if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
14151 x--; /* can't use any pixel_width */
14152 break;
14154 x -= glyph->pixel_width;
14157 /* Step 2: If we didn't find an exact match for point, we need to
14158 look for a proper place to put the cursor among glyphs between
14159 GLYPH_BEFORE and GLYPH_AFTER. */
14160 if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
14161 && BUFFERP (glyph->object) && glyph->charpos == pt_old)
14162 && !(bpos_max < pt_old && pt_old <= bpos_covered))
14164 /* An empty line has a single glyph whose OBJECT is zero and
14165 whose CHARPOS is the position of a newline on that line.
14166 Note that on a TTY, there are more glyphs after that, which
14167 were produced by extend_face_to_end_of_line, but their
14168 CHARPOS is zero or negative. */
14169 int empty_line_p =
14170 (row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
14171 && INTEGERP (glyph->object) && glyph->charpos > 0
14172 /* On a TTY, continued and truncated rows also have a glyph at
14173 their end whose OBJECT is zero and whose CHARPOS is
14174 positive (the continuation and truncation glyphs), but such
14175 rows are obviously not "empty". */
14176 && !(row->continued_p || row->truncated_on_right_p);
14178 if (row->ends_in_ellipsis_p && pos_after == last_pos)
14180 ptrdiff_t ellipsis_pos;
14182 /* Scan back over the ellipsis glyphs. */
14183 if (!row->reversed_p)
14185 ellipsis_pos = (glyph - 1)->charpos;
14186 while (glyph > row->glyphs[TEXT_AREA]
14187 && (glyph - 1)->charpos == ellipsis_pos)
14188 glyph--, x -= glyph->pixel_width;
14189 /* That loop always goes one position too far, including
14190 the glyph before the ellipsis. So scan forward over
14191 that one. */
14192 x += glyph->pixel_width;
14193 glyph++;
14195 else /* row is reversed */
14197 ellipsis_pos = (glyph + 1)->charpos;
14198 while (glyph < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14199 && (glyph + 1)->charpos == ellipsis_pos)
14200 glyph++, x += glyph->pixel_width;
14201 x -= glyph->pixel_width;
14202 glyph--;
14205 else if (match_with_avoid_cursor)
14207 cursor = glyph_after;
14208 x = -1;
14210 else if (string_seen)
14212 int incr = row->reversed_p ? -1 : +1;
14214 /* Need to find the glyph that came out of a string which is
14215 present at point. That glyph is somewhere between
14216 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
14217 positioned between POS_BEFORE and POS_AFTER in the
14218 buffer. */
14219 struct glyph *start, *stop;
14220 ptrdiff_t pos = pos_before;
14222 x = -1;
14224 /* If the row ends in a newline from a display string,
14225 reordering could have moved the glyphs belonging to the
14226 string out of the [GLYPH_BEFORE..GLYPH_AFTER] range. So
14227 in this case we extend the search to the last glyph in
14228 the row that was not inserted by redisplay. */
14229 if (row->ends_in_newline_from_string_p)
14231 glyph_after = end;
14232 pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
14235 /* GLYPH_BEFORE and GLYPH_AFTER are the glyphs that
14236 correspond to POS_BEFORE and POS_AFTER, respectively. We
14237 need START and STOP in the order that corresponds to the
14238 row's direction as given by its reversed_p flag. If the
14239 directionality of characters between POS_BEFORE and
14240 POS_AFTER is the opposite of the row's base direction,
14241 these characters will have been reordered for display,
14242 and we need to reverse START and STOP. */
14243 if (!row->reversed_p)
14245 start = min (glyph_before, glyph_after);
14246 stop = max (glyph_before, glyph_after);
14248 else
14250 start = max (glyph_before, glyph_after);
14251 stop = min (glyph_before, glyph_after);
14253 for (glyph = start + incr;
14254 row->reversed_p ? glyph > stop : glyph < stop; )
14257 /* Any glyphs that come from the buffer are here because
14258 of bidi reordering. Skip them, and only pay
14259 attention to glyphs that came from some string. */
14260 if (STRINGP (glyph->object))
14262 Lisp_Object str;
14263 ptrdiff_t tem;
14264 /* If the display property covers the newline, we
14265 need to search for it one position farther. */
14266 ptrdiff_t lim = pos_after
14267 + (pos_after == MATRIX_ROW_END_CHARPOS (row) + delta);
14269 string_from_text_prop = 0;
14270 str = glyph->object;
14271 tem = string_buffer_position_lim (str, pos, lim, 0);
14272 if (tem == 0 /* from overlay */
14273 || pos <= tem)
14275 /* If the string from which this glyph came is
14276 found in the buffer at point, or at position
14277 that is closer to point than pos_after, then
14278 we've found the glyph we've been looking for.
14279 If it comes from an overlay (tem == 0), and
14280 it has the `cursor' property on one of its
14281 glyphs, record that glyph as a candidate for
14282 displaying the cursor. (As in the
14283 unidirectional version, we will display the
14284 cursor on the last candidate we find.) */
14285 if (tem == 0
14286 || tem == pt_old
14287 || (tem - pt_old > 0 && tem < pos_after))
14289 /* The glyphs from this string could have
14290 been reordered. Find the one with the
14291 smallest string position. Or there could
14292 be a character in the string with the
14293 `cursor' property, which means display
14294 cursor on that character's glyph. */
14295 ptrdiff_t strpos = glyph->charpos;
14297 if (tem)
14299 cursor = glyph;
14300 string_from_text_prop = 1;
14302 for ( ;
14303 (row->reversed_p ? glyph > stop : glyph < stop)
14304 && EQ (glyph->object, str);
14305 glyph += incr)
14307 Lisp_Object cprop;
14308 ptrdiff_t gpos = glyph->charpos;
14310 cprop = Fget_char_property (make_number (gpos),
14311 Qcursor,
14312 glyph->object);
14313 if (!NILP (cprop))
14315 cursor = glyph;
14316 break;
14318 if (tem && glyph->charpos < strpos)
14320 strpos = glyph->charpos;
14321 cursor = glyph;
14325 if (tem == pt_old
14326 || (tem - pt_old > 0 && tem < pos_after))
14327 goto compute_x;
14329 if (tem)
14330 pos = tem + 1; /* don't find previous instances */
14332 /* This string is not what we want; skip all of the
14333 glyphs that came from it. */
14334 while ((row->reversed_p ? glyph > stop : glyph < stop)
14335 && EQ (glyph->object, str))
14336 glyph += incr;
14338 else
14339 glyph += incr;
14342 /* If we reached the end of the line, and END was from a string,
14343 the cursor is not on this line. */
14344 if (cursor == NULL
14345 && (row->reversed_p ? glyph <= end : glyph >= end)
14346 && (row->reversed_p ? end > glyphs_end : end < glyphs_end)
14347 && STRINGP (end->object)
14348 && row->continued_p)
14349 return 0;
14351 /* A truncated row may not include PT among its character positions.
14352 Setting the cursor inside the scroll margin will trigger
14353 recalculation of hscroll in hscroll_window_tree. But if a
14354 display string covers point, defer to the string-handling
14355 code below to figure this out. */
14356 else if (row->truncated_on_left_p && pt_old < bpos_min)
14358 cursor = glyph_before;
14359 x = -1;
14361 else if ((row->truncated_on_right_p && pt_old > bpos_max)
14362 /* Zero-width characters produce no glyphs. */
14363 || (!empty_line_p
14364 && (row->reversed_p
14365 ? glyph_after > glyphs_end
14366 : glyph_after < glyphs_end)))
14368 cursor = glyph_after;
14369 x = -1;
14373 compute_x:
14374 if (cursor != NULL)
14375 glyph = cursor;
14376 else if (glyph == glyphs_end
14377 && pos_before == pos_after
14378 && STRINGP ((row->reversed_p
14379 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14380 : row->glyphs[TEXT_AREA])->object))
14382 /* If all the glyphs of this row came from strings, put the
14383 cursor on the first glyph of the row. This avoids having the
14384 cursor outside of the text area in this very rare and hard
14385 use case. */
14386 glyph =
14387 row->reversed_p
14388 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14389 : row->glyphs[TEXT_AREA];
14391 if (x < 0)
14393 struct glyph *g;
14395 /* Need to compute x that corresponds to GLYPH. */
14396 for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++)
14398 if (g >= row->glyphs[TEXT_AREA] + row->used[TEXT_AREA])
14399 emacs_abort ();
14400 x += g->pixel_width;
14404 /* ROW could be part of a continued line, which, under bidi
14405 reordering, might have other rows whose start and end charpos
14406 occlude point. Only set w->cursor if we found a better
14407 approximation to the cursor position than we have from previously
14408 examined candidate rows belonging to the same continued line. */
14409 if (/* we already have a candidate row */
14410 w->cursor.vpos >= 0
14411 /* that candidate is not the row we are processing */
14412 && MATRIX_ROW (matrix, w->cursor.vpos) != row
14413 /* Make sure cursor.vpos specifies a row whose start and end
14414 charpos occlude point, and it is valid candidate for being a
14415 cursor-row. This is because some callers of this function
14416 leave cursor.vpos at the row where the cursor was displayed
14417 during the last redisplay cycle. */
14418 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old
14419 && pt_old <= MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14420 && cursor_row_p (MATRIX_ROW (matrix, w->cursor.vpos)))
14422 struct glyph *g1 =
14423 MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
14425 /* Don't consider glyphs that are outside TEXT_AREA. */
14426 if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
14427 return 0;
14428 /* Keep the candidate whose buffer position is the closest to
14429 point or has the `cursor' property. */
14430 if (/* previous candidate is a glyph in TEXT_AREA of that row */
14431 w->cursor.hpos >= 0
14432 && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
14433 && ((BUFFERP (g1->object)
14434 && (g1->charpos == pt_old /* an exact match always wins */
14435 || (BUFFERP (glyph->object)
14436 && eabs (g1->charpos - pt_old)
14437 < eabs (glyph->charpos - pt_old))))
14438 /* previous candidate is a glyph from a string that has
14439 a non-nil `cursor' property */
14440 || (STRINGP (g1->object)
14441 && (!NILP (Fget_char_property (make_number (g1->charpos),
14442 Qcursor, g1->object))
14443 /* previous candidate is from the same display
14444 string as this one, and the display string
14445 came from a text property */
14446 || (EQ (g1->object, glyph->object)
14447 && string_from_text_prop)
14448 /* this candidate is from newline and its
14449 position is not an exact match */
14450 || (INTEGERP (glyph->object)
14451 && glyph->charpos != pt_old)))))
14452 return 0;
14453 /* If this candidate gives an exact match, use that. */
14454 if (!((BUFFERP (glyph->object) && glyph->charpos == pt_old)
14455 /* If this candidate is a glyph created for the
14456 terminating newline of a line, and point is on that
14457 newline, it wins because it's an exact match. */
14458 || (!row->continued_p
14459 && INTEGERP (glyph->object)
14460 && glyph->charpos == 0
14461 && pt_old == MATRIX_ROW_END_CHARPOS (row) - 1))
14462 /* Otherwise, keep the candidate that comes from a row
14463 spanning less buffer positions. This may win when one or
14464 both candidate positions are on glyphs that came from
14465 display strings, for which we cannot compare buffer
14466 positions. */
14467 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14468 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14469 < MATRIX_ROW_END_CHARPOS (row) - MATRIX_ROW_START_CHARPOS (row))
14470 return 0;
14472 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
14473 w->cursor.x = x;
14474 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
14475 w->cursor.y = row->y + dy;
14477 if (w == XWINDOW (selected_window))
14479 if (!row->continued_p
14480 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
14481 && row->x == 0)
14483 this_line_buffer = XBUFFER (w->contents);
14485 CHARPOS (this_line_start_pos)
14486 = MATRIX_ROW_START_CHARPOS (row) + delta;
14487 BYTEPOS (this_line_start_pos)
14488 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
14490 CHARPOS (this_line_end_pos)
14491 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
14492 BYTEPOS (this_line_end_pos)
14493 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
14495 this_line_y = w->cursor.y;
14496 this_line_pixel_height = row->height;
14497 this_line_vpos = w->cursor.vpos;
14498 this_line_start_x = row->x;
14500 else
14501 CHARPOS (this_line_start_pos) = 0;
14504 return 1;
14508 /* Run window scroll functions, if any, for WINDOW with new window
14509 start STARTP. Sets the window start of WINDOW to that position.
14511 We assume that the window's buffer is really current. */
14513 static struct text_pos
14514 run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
14516 struct window *w = XWINDOW (window);
14517 SET_MARKER_FROM_TEXT_POS (w->start, startp);
14519 eassert (current_buffer == XBUFFER (w->contents));
14521 if (!NILP (Vwindow_scroll_functions))
14523 run_hook_with_args_2 (Qwindow_scroll_functions, window,
14524 make_number (CHARPOS (startp)));
14525 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14526 /* In case the hook functions switch buffers. */
14527 set_buffer_internal (XBUFFER (w->contents));
14530 return startp;
14534 /* Make sure the line containing the cursor is fully visible.
14535 A value of 1 means there is nothing to be done.
14536 (Either the line is fully visible, or it cannot be made so,
14537 or we cannot tell.)
14539 If FORCE_P is non-zero, return 0 even if partial visible cursor row
14540 is higher than window.
14542 A value of 0 means the caller should do scrolling
14543 as if point had gone off the screen. */
14545 static int
14546 cursor_row_fully_visible_p (struct window *w, int force_p, int current_matrix_p)
14548 struct glyph_matrix *matrix;
14549 struct glyph_row *row;
14550 int window_height;
14552 if (!make_cursor_line_fully_visible_p)
14553 return 1;
14555 /* It's not always possible to find the cursor, e.g, when a window
14556 is full of overlay strings. Don't do anything in that case. */
14557 if (w->cursor.vpos < 0)
14558 return 1;
14560 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
14561 row = MATRIX_ROW (matrix, w->cursor.vpos);
14563 /* If the cursor row is not partially visible, there's nothing to do. */
14564 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
14565 return 1;
14567 /* If the row the cursor is in is taller than the window's height,
14568 it's not clear what to do, so do nothing. */
14569 window_height = window_box_height (w);
14570 if (row->height >= window_height)
14572 if (!force_p || MINI_WINDOW_P (w)
14573 || w->vscroll || w->cursor.vpos == 0)
14574 return 1;
14576 return 0;
14580 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
14581 non-zero means only WINDOW is redisplayed in redisplay_internal.
14582 TEMP_SCROLL_STEP has the same meaning as emacs_scroll_step, and is used
14583 in redisplay_window to bring a partially visible line into view in
14584 the case that only the cursor has moved.
14586 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
14587 last screen line's vertical height extends past the end of the screen.
14589 Value is
14591 1 if scrolling succeeded
14593 0 if scrolling didn't find point.
14595 -1 if new fonts have been loaded so that we must interrupt
14596 redisplay, adjust glyph matrices, and try again. */
14598 enum
14600 SCROLLING_SUCCESS,
14601 SCROLLING_FAILED,
14602 SCROLLING_NEED_LARGER_MATRICES
14605 /* If scroll-conservatively is more than this, never recenter.
14607 If you change this, don't forget to update the doc string of
14608 `scroll-conservatively' and the Emacs manual. */
14609 #define SCROLL_LIMIT 100
14611 static int
14612 try_scrolling (Lisp_Object window, int just_this_one_p,
14613 ptrdiff_t arg_scroll_conservatively, ptrdiff_t scroll_step,
14614 int temp_scroll_step, int last_line_misfit)
14616 struct window *w = XWINDOW (window);
14617 struct frame *f = XFRAME (w->frame);
14618 struct text_pos pos, startp;
14619 struct it it;
14620 int this_scroll_margin, scroll_max, rc, height;
14621 int dy = 0, amount_to_scroll = 0, scroll_down_p = 0;
14622 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
14623 Lisp_Object aggressive;
14624 /* We will never try scrolling more than this number of lines. */
14625 int scroll_limit = SCROLL_LIMIT;
14626 int frame_line_height = default_line_pixel_height (w);
14627 int window_total_lines
14628 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
14630 #ifdef GLYPH_DEBUG
14631 debug_method_add (w, "try_scrolling");
14632 #endif
14634 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14636 /* Compute scroll margin height in pixels. We scroll when point is
14637 within this distance from the top or bottom of the window. */
14638 if (scroll_margin > 0)
14639 this_scroll_margin = min (scroll_margin, window_total_lines / 4)
14640 * frame_line_height;
14641 else
14642 this_scroll_margin = 0;
14644 /* Force arg_scroll_conservatively to have a reasonable value, to
14645 avoid scrolling too far away with slow move_it_* functions. Note
14646 that the user can supply scroll-conservatively equal to
14647 `most-positive-fixnum', which can be larger than INT_MAX. */
14648 if (arg_scroll_conservatively > scroll_limit)
14650 arg_scroll_conservatively = scroll_limit + 1;
14651 scroll_max = scroll_limit * frame_line_height;
14653 else if (scroll_step || arg_scroll_conservatively || temp_scroll_step)
14654 /* Compute how much we should try to scroll maximally to bring
14655 point into view. */
14656 scroll_max = (max (scroll_step,
14657 max (arg_scroll_conservatively, temp_scroll_step))
14658 * frame_line_height);
14659 else if (NUMBERP (BVAR (current_buffer, scroll_down_aggressively))
14660 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively)))
14661 /* We're trying to scroll because of aggressive scrolling but no
14662 scroll_step is set. Choose an arbitrary one. */
14663 scroll_max = 10 * frame_line_height;
14664 else
14665 scroll_max = 0;
14667 too_near_end:
14669 /* Decide whether to scroll down. */
14670 if (PT > CHARPOS (startp))
14672 int scroll_margin_y;
14674 /* Compute the pixel ypos of the scroll margin, then move IT to
14675 either that ypos or PT, whichever comes first. */
14676 start_display (&it, w, startp);
14677 scroll_margin_y = it.last_visible_y - this_scroll_margin
14678 - frame_line_height * extra_scroll_margin_lines;
14679 move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
14680 (MOVE_TO_POS | MOVE_TO_Y));
14682 if (PT > CHARPOS (it.current.pos))
14684 int y0 = line_bottom_y (&it);
14685 /* Compute how many pixels below window bottom to stop searching
14686 for PT. This avoids costly search for PT that is far away if
14687 the user limited scrolling by a small number of lines, but
14688 always finds PT if scroll_conservatively is set to a large
14689 number, such as most-positive-fixnum. */
14690 int slack = max (scroll_max, 10 * frame_line_height);
14691 int y_to_move = it.last_visible_y + slack;
14693 /* Compute the distance from the scroll margin to PT or to
14694 the scroll limit, whichever comes first. This should
14695 include the height of the cursor line, to make that line
14696 fully visible. */
14697 move_it_to (&it, PT, -1, y_to_move,
14698 -1, MOVE_TO_POS | MOVE_TO_Y);
14699 dy = line_bottom_y (&it) - y0;
14701 if (dy > scroll_max)
14702 return SCROLLING_FAILED;
14704 if (dy > 0)
14705 scroll_down_p = 1;
14709 if (scroll_down_p)
14711 /* Point is in or below the bottom scroll margin, so move the
14712 window start down. If scrolling conservatively, move it just
14713 enough down to make point visible. If scroll_step is set,
14714 move it down by scroll_step. */
14715 if (arg_scroll_conservatively)
14716 amount_to_scroll
14717 = min (max (dy, frame_line_height),
14718 frame_line_height * arg_scroll_conservatively);
14719 else if (scroll_step || temp_scroll_step)
14720 amount_to_scroll = scroll_max;
14721 else
14723 aggressive = BVAR (current_buffer, scroll_up_aggressively);
14724 height = WINDOW_BOX_TEXT_HEIGHT (w);
14725 if (NUMBERP (aggressive))
14727 double float_amount = XFLOATINT (aggressive) * height;
14728 int aggressive_scroll = float_amount;
14729 if (aggressive_scroll == 0 && float_amount > 0)
14730 aggressive_scroll = 1;
14731 /* Don't let point enter the scroll margin near top of
14732 the window. This could happen if the value of
14733 scroll_up_aggressively is too large and there are
14734 non-zero margins, because scroll_up_aggressively
14735 means put point that fraction of window height
14736 _from_the_bottom_margin_. */
14737 if (aggressive_scroll + 2*this_scroll_margin > height)
14738 aggressive_scroll = height - 2*this_scroll_margin;
14739 amount_to_scroll = dy + aggressive_scroll;
14743 if (amount_to_scroll <= 0)
14744 return SCROLLING_FAILED;
14746 start_display (&it, w, startp);
14747 if (arg_scroll_conservatively <= scroll_limit)
14748 move_it_vertically (&it, amount_to_scroll);
14749 else
14751 /* Extra precision for users who set scroll-conservatively
14752 to a large number: make sure the amount we scroll
14753 the window start is never less than amount_to_scroll,
14754 which was computed as distance from window bottom to
14755 point. This matters when lines at window top and lines
14756 below window bottom have different height. */
14757 struct it it1;
14758 void *it1data = NULL;
14759 /* We use a temporary it1 because line_bottom_y can modify
14760 its argument, if it moves one line down; see there. */
14761 int start_y;
14763 SAVE_IT (it1, it, it1data);
14764 start_y = line_bottom_y (&it1);
14765 do {
14766 RESTORE_IT (&it, &it, it1data);
14767 move_it_by_lines (&it, 1);
14768 SAVE_IT (it1, it, it1data);
14769 } while (line_bottom_y (&it1) - start_y < amount_to_scroll);
14772 /* If STARTP is unchanged, move it down another screen line. */
14773 if (CHARPOS (it.current.pos) == CHARPOS (startp))
14774 move_it_by_lines (&it, 1);
14775 startp = it.current.pos;
14777 else
14779 struct text_pos scroll_margin_pos = startp;
14780 int y_offset = 0;
14782 /* See if point is inside the scroll margin at the top of the
14783 window. */
14784 if (this_scroll_margin)
14786 int y_start;
14788 start_display (&it, w, startp);
14789 y_start = it.current_y;
14790 move_it_vertically (&it, this_scroll_margin);
14791 scroll_margin_pos = it.current.pos;
14792 /* If we didn't move enough before hitting ZV, request
14793 additional amount of scroll, to move point out of the
14794 scroll margin. */
14795 if (IT_CHARPOS (it) == ZV
14796 && it.current_y - y_start < this_scroll_margin)
14797 y_offset = this_scroll_margin - (it.current_y - y_start);
14800 if (PT < CHARPOS (scroll_margin_pos))
14802 /* Point is in the scroll margin at the top of the window or
14803 above what is displayed in the window. */
14804 int y0, y_to_move;
14806 /* Compute the vertical distance from PT to the scroll
14807 margin position. Move as far as scroll_max allows, or
14808 one screenful, or 10 screen lines, whichever is largest.
14809 Give up if distance is greater than scroll_max or if we
14810 didn't reach the scroll margin position. */
14811 SET_TEXT_POS (pos, PT, PT_BYTE);
14812 start_display (&it, w, pos);
14813 y0 = it.current_y;
14814 y_to_move = max (it.last_visible_y,
14815 max (scroll_max, 10 * frame_line_height));
14816 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
14817 y_to_move, -1,
14818 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
14819 dy = it.current_y - y0;
14820 if (dy > scroll_max
14821 || IT_CHARPOS (it) < CHARPOS (scroll_margin_pos))
14822 return SCROLLING_FAILED;
14824 /* Additional scroll for when ZV was too close to point. */
14825 dy += y_offset;
14827 /* Compute new window start. */
14828 start_display (&it, w, startp);
14830 if (arg_scroll_conservatively)
14831 amount_to_scroll = max (dy, frame_line_height *
14832 max (scroll_step, temp_scroll_step));
14833 else if (scroll_step || temp_scroll_step)
14834 amount_to_scroll = scroll_max;
14835 else
14837 aggressive = BVAR (current_buffer, scroll_down_aggressively);
14838 height = WINDOW_BOX_TEXT_HEIGHT (w);
14839 if (NUMBERP (aggressive))
14841 double float_amount = XFLOATINT (aggressive) * height;
14842 int aggressive_scroll = float_amount;
14843 if (aggressive_scroll == 0 && float_amount > 0)
14844 aggressive_scroll = 1;
14845 /* Don't let point enter the scroll margin near
14846 bottom of the window, if the value of
14847 scroll_down_aggressively happens to be too
14848 large. */
14849 if (aggressive_scroll + 2*this_scroll_margin > height)
14850 aggressive_scroll = height - 2*this_scroll_margin;
14851 amount_to_scroll = dy + aggressive_scroll;
14855 if (amount_to_scroll <= 0)
14856 return SCROLLING_FAILED;
14858 move_it_vertically_backward (&it, amount_to_scroll);
14859 startp = it.current.pos;
14863 /* Run window scroll functions. */
14864 startp = run_window_scroll_functions (window, startp);
14866 /* Display the window. Give up if new fonts are loaded, or if point
14867 doesn't appear. */
14868 if (!try_window (window, startp, 0))
14869 rc = SCROLLING_NEED_LARGER_MATRICES;
14870 else if (w->cursor.vpos < 0)
14872 clear_glyph_matrix (w->desired_matrix);
14873 rc = SCROLLING_FAILED;
14875 else
14877 /* Maybe forget recorded base line for line number display. */
14878 if (!just_this_one_p
14879 || current_buffer->clip_changed
14880 || BEG_UNCHANGED < CHARPOS (startp))
14881 w->base_line_number = 0;
14883 /* If cursor ends up on a partially visible line,
14884 treat that as being off the bottom of the screen. */
14885 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0)
14886 /* It's possible that the cursor is on the first line of the
14887 buffer, which is partially obscured due to a vscroll
14888 (Bug#7537). In that case, avoid looping forever . */
14889 && extra_scroll_margin_lines < w->desired_matrix->nrows - 1)
14891 clear_glyph_matrix (w->desired_matrix);
14892 ++extra_scroll_margin_lines;
14893 goto too_near_end;
14895 rc = SCROLLING_SUCCESS;
14898 return rc;
14902 /* Compute a suitable window start for window W if display of W starts
14903 on a continuation line. Value is non-zero if a new window start
14904 was computed.
14906 The new window start will be computed, based on W's width, starting
14907 from the start of the continued line. It is the start of the
14908 screen line with the minimum distance from the old start W->start. */
14910 static int
14911 compute_window_start_on_continuation_line (struct window *w)
14913 struct text_pos pos, start_pos;
14914 int window_start_changed_p = 0;
14916 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
14918 /* If window start is on a continuation line... Window start may be
14919 < BEGV in case there's invisible text at the start of the
14920 buffer (M-x rmail, for example). */
14921 if (CHARPOS (start_pos) > BEGV
14922 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
14924 struct it it;
14925 struct glyph_row *row;
14927 /* Handle the case that the window start is out of range. */
14928 if (CHARPOS (start_pos) < BEGV)
14929 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
14930 else if (CHARPOS (start_pos) > ZV)
14931 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
14933 /* Find the start of the continued line. This should be fast
14934 because find_newline is fast (newline cache). */
14935 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
14936 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
14937 row, DEFAULT_FACE_ID);
14938 reseat_at_previous_visible_line_start (&it);
14940 /* If the line start is "too far" away from the window start,
14941 say it takes too much time to compute a new window start. */
14942 if (CHARPOS (start_pos) - IT_CHARPOS (it)
14943 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
14945 int min_distance, distance;
14947 /* Move forward by display lines to find the new window
14948 start. If window width was enlarged, the new start can
14949 be expected to be > the old start. If window width was
14950 decreased, the new window start will be < the old start.
14951 So, we're looking for the display line start with the
14952 minimum distance from the old window start. */
14953 pos = it.current.pos;
14954 min_distance = INFINITY;
14955 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
14956 distance < min_distance)
14958 min_distance = distance;
14959 pos = it.current.pos;
14960 if (it.line_wrap == WORD_WRAP)
14962 /* Under WORD_WRAP, move_it_by_lines is likely to
14963 overshoot and stop not at the first, but the
14964 second character from the left margin. So in
14965 that case, we need a more tight control on the X
14966 coordinate of the iterator than move_it_by_lines
14967 promises in its contract. The method is to first
14968 go to the last (rightmost) visible character of a
14969 line, then move to the leftmost character on the
14970 next line in a separate call. */
14971 move_it_to (&it, ZV, it.last_visible_x, it.current_y, -1,
14972 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
14973 move_it_to (&it, ZV, 0,
14974 it.current_y + it.max_ascent + it.max_descent, -1,
14975 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
14977 else
14978 move_it_by_lines (&it, 1);
14981 /* Set the window start there. */
14982 SET_MARKER_FROM_TEXT_POS (w->start, pos);
14983 window_start_changed_p = 1;
14987 return window_start_changed_p;
14991 /* Try cursor movement in case text has not changed in window WINDOW,
14992 with window start STARTP. Value is
14994 CURSOR_MOVEMENT_SUCCESS if successful
14996 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
14998 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
14999 display. *SCROLL_STEP is set to 1, under certain circumstances, if
15000 we want to scroll as if scroll-step were set to 1. See the code.
15002 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
15003 which case we have to abort this redisplay, and adjust matrices
15004 first. */
15006 enum
15008 CURSOR_MOVEMENT_SUCCESS,
15009 CURSOR_MOVEMENT_CANNOT_BE_USED,
15010 CURSOR_MOVEMENT_MUST_SCROLL,
15011 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
15014 static int
15015 try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_step)
15017 struct window *w = XWINDOW (window);
15018 struct frame *f = XFRAME (w->frame);
15019 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
15021 #ifdef GLYPH_DEBUG
15022 if (inhibit_try_cursor_movement)
15023 return rc;
15024 #endif
15026 /* Previously, there was a check for Lisp integer in the
15027 if-statement below. Now, this field is converted to
15028 ptrdiff_t, thus zero means invalid position in a buffer. */
15029 eassert (w->last_point > 0);
15030 /* Likewise there was a check whether window_end_vpos is nil or larger
15031 than the window. Now window_end_vpos is int and so never nil, but
15032 let's leave eassert to check whether it fits in the window. */
15033 eassert (w->window_end_vpos < w->current_matrix->nrows);
15035 /* Handle case where text has not changed, only point, and it has
15036 not moved off the frame. */
15037 if (/* Point may be in this window. */
15038 PT >= CHARPOS (startp)
15039 /* Selective display hasn't changed. */
15040 && !current_buffer->clip_changed
15041 /* Function force-mode-line-update is used to force a thorough
15042 redisplay. It sets either windows_or_buffers_changed or
15043 update_mode_lines. So don't take a shortcut here for these
15044 cases. */
15045 && !update_mode_lines
15046 && !windows_or_buffers_changed
15047 && !cursor_type_changed
15048 /* Can't use this case if highlighting a region. When a
15049 region exists, cursor movement has to do more than just
15050 set the cursor. */
15051 && markpos_of_region () < 0
15052 && !w->region_showing
15053 && NILP (Vshow_trailing_whitespace)
15054 /* This code is not used for mini-buffer for the sake of the case
15055 of redisplaying to replace an echo area message; since in
15056 that case the mini-buffer contents per se are usually
15057 unchanged. This code is of no real use in the mini-buffer
15058 since the handling of this_line_start_pos, etc., in redisplay
15059 handles the same cases. */
15060 && !EQ (window, minibuf_window)
15061 && (FRAME_WINDOW_P (f)
15062 || !overlay_arrow_in_current_buffer_p ()))
15064 int this_scroll_margin, top_scroll_margin;
15065 struct glyph_row *row = NULL;
15066 int frame_line_height = default_line_pixel_height (w);
15067 int window_total_lines
15068 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
15070 #ifdef GLYPH_DEBUG
15071 debug_method_add (w, "cursor movement");
15072 #endif
15074 /* Scroll if point within this distance from the top or bottom
15075 of the window. This is a pixel value. */
15076 if (scroll_margin > 0)
15078 this_scroll_margin = min (scroll_margin, window_total_lines / 4);
15079 this_scroll_margin *= frame_line_height;
15081 else
15082 this_scroll_margin = 0;
15084 top_scroll_margin = this_scroll_margin;
15085 if (WINDOW_WANTS_HEADER_LINE_P (w))
15086 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
15088 /* Start with the row the cursor was displayed during the last
15089 not paused redisplay. Give up if that row is not valid. */
15090 if (w->last_cursor_vpos < 0
15091 || w->last_cursor_vpos >= w->current_matrix->nrows)
15092 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15093 else
15095 row = MATRIX_ROW (w->current_matrix, w->last_cursor_vpos);
15096 if (row->mode_line_p)
15097 ++row;
15098 if (!row->enabled_p)
15099 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15102 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
15104 int scroll_p = 0, must_scroll = 0;
15105 int last_y = window_text_bottom_y (w) - this_scroll_margin;
15107 if (PT > w->last_point)
15109 /* Point has moved forward. */
15110 while (MATRIX_ROW_END_CHARPOS (row) < PT
15111 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
15113 eassert (row->enabled_p);
15114 ++row;
15117 /* If the end position of a row equals the start
15118 position of the next row, and PT is at that position,
15119 we would rather display cursor in the next line. */
15120 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15121 && MATRIX_ROW_END_CHARPOS (row) == PT
15122 && row < MATRIX_MODE_LINE_ROW (w->current_matrix)
15123 && MATRIX_ROW_START_CHARPOS (row+1) == PT
15124 && !cursor_row_p (row))
15125 ++row;
15127 /* If within the scroll margin, scroll. Note that
15128 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
15129 the next line would be drawn, and that
15130 this_scroll_margin can be zero. */
15131 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
15132 || PT > MATRIX_ROW_END_CHARPOS (row)
15133 /* Line is completely visible last line in window
15134 and PT is to be set in the next line. */
15135 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
15136 && PT == MATRIX_ROW_END_CHARPOS (row)
15137 && !row->ends_at_zv_p
15138 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
15139 scroll_p = 1;
15141 else if (PT < w->last_point)
15143 /* Cursor has to be moved backward. Note that PT >=
15144 CHARPOS (startp) because of the outer if-statement. */
15145 while (!row->mode_line_p
15146 && (MATRIX_ROW_START_CHARPOS (row) > PT
15147 || (MATRIX_ROW_START_CHARPOS (row) == PT
15148 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
15149 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
15150 row > w->current_matrix->rows
15151 && (row-1)->ends_in_newline_from_string_p))))
15152 && (row->y > top_scroll_margin
15153 || CHARPOS (startp) == BEGV))
15155 eassert (row->enabled_p);
15156 --row;
15159 /* Consider the following case: Window starts at BEGV,
15160 there is invisible, intangible text at BEGV, so that
15161 display starts at some point START > BEGV. It can
15162 happen that we are called with PT somewhere between
15163 BEGV and START. Try to handle that case. */
15164 if (row < w->current_matrix->rows
15165 || row->mode_line_p)
15167 row = w->current_matrix->rows;
15168 if (row->mode_line_p)
15169 ++row;
15172 /* Due to newlines in overlay strings, we may have to
15173 skip forward over overlay strings. */
15174 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15175 && MATRIX_ROW_END_CHARPOS (row) == PT
15176 && !cursor_row_p (row))
15177 ++row;
15179 /* If within the scroll margin, scroll. */
15180 if (row->y < top_scroll_margin
15181 && CHARPOS (startp) != BEGV)
15182 scroll_p = 1;
15184 else
15186 /* Cursor did not move. So don't scroll even if cursor line
15187 is partially visible, as it was so before. */
15188 rc = CURSOR_MOVEMENT_SUCCESS;
15191 if (PT < MATRIX_ROW_START_CHARPOS (row)
15192 || PT > MATRIX_ROW_END_CHARPOS (row))
15194 /* if PT is not in the glyph row, give up. */
15195 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15196 must_scroll = 1;
15198 else if (rc != CURSOR_MOVEMENT_SUCCESS
15199 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
15201 struct glyph_row *row1;
15203 /* If rows are bidi-reordered and point moved, back up
15204 until we find a row that does not belong to a
15205 continuation line. This is because we must consider
15206 all rows of a continued line as candidates for the
15207 new cursor positioning, since row start and end
15208 positions change non-linearly with vertical position
15209 in such rows. */
15210 /* FIXME: Revisit this when glyph ``spilling'' in
15211 continuation lines' rows is implemented for
15212 bidi-reordered rows. */
15213 for (row1 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
15214 MATRIX_ROW_CONTINUATION_LINE_P (row);
15215 --row)
15217 /* If we hit the beginning of the displayed portion
15218 without finding the first row of a continued
15219 line, give up. */
15220 if (row <= row1)
15222 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15223 break;
15225 eassert (row->enabled_p);
15228 if (must_scroll)
15230 else if (rc != CURSOR_MOVEMENT_SUCCESS
15231 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
15232 /* Make sure this isn't a header line by any chance, since
15233 then MATRIX_ROW_PARTIALLY_VISIBLE_P might yield non-zero. */
15234 && !row->mode_line_p
15235 && make_cursor_line_fully_visible_p)
15237 if (PT == MATRIX_ROW_END_CHARPOS (row)
15238 && !row->ends_at_zv_p
15239 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
15240 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15241 else if (row->height > window_box_height (w))
15243 /* If we end up in a partially visible line, let's
15244 make it fully visible, except when it's taller
15245 than the window, in which case we can't do much
15246 about it. */
15247 *scroll_step = 1;
15248 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15250 else
15252 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
15253 if (!cursor_row_fully_visible_p (w, 0, 1))
15254 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15255 else
15256 rc = CURSOR_MOVEMENT_SUCCESS;
15259 else if (scroll_p)
15260 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15261 else if (rc != CURSOR_MOVEMENT_SUCCESS
15262 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
15264 /* With bidi-reordered rows, there could be more than
15265 one candidate row whose start and end positions
15266 occlude point. We need to let set_cursor_from_row
15267 find the best candidate. */
15268 /* FIXME: Revisit this when glyph ``spilling'' in
15269 continuation lines' rows is implemented for
15270 bidi-reordered rows. */
15271 int rv = 0;
15275 int at_zv_p = 0, exact_match_p = 0;
15277 if (MATRIX_ROW_START_CHARPOS (row) <= PT
15278 && PT <= MATRIX_ROW_END_CHARPOS (row)
15279 && cursor_row_p (row))
15280 rv |= set_cursor_from_row (w, row, w->current_matrix,
15281 0, 0, 0, 0);
15282 /* As soon as we've found the exact match for point,
15283 or the first suitable row whose ends_at_zv_p flag
15284 is set, we are done. */
15285 at_zv_p =
15286 MATRIX_ROW (w->current_matrix, w->cursor.vpos)->ends_at_zv_p;
15287 if (rv && !at_zv_p
15288 && w->cursor.hpos >= 0
15289 && w->cursor.hpos < MATRIX_ROW_USED (w->current_matrix,
15290 w->cursor.vpos))
15292 struct glyph_row *candidate =
15293 MATRIX_ROW (w->current_matrix, w->cursor.vpos);
15294 struct glyph *g =
15295 candidate->glyphs[TEXT_AREA] + w->cursor.hpos;
15296 ptrdiff_t endpos = MATRIX_ROW_END_CHARPOS (candidate);
15298 exact_match_p =
15299 (BUFFERP (g->object) && g->charpos == PT)
15300 || (INTEGERP (g->object)
15301 && (g->charpos == PT
15302 || (g->charpos == 0 && endpos - 1 == PT)));
15304 if (rv && (at_zv_p || exact_match_p))
15306 rc = CURSOR_MOVEMENT_SUCCESS;
15307 break;
15309 if (MATRIX_ROW_BOTTOM_Y (row) == last_y)
15310 break;
15311 ++row;
15313 while (((MATRIX_ROW_CONTINUATION_LINE_P (row)
15314 || row->continued_p)
15315 && MATRIX_ROW_BOTTOM_Y (row) <= last_y)
15316 || (MATRIX_ROW_START_CHARPOS (row) == PT
15317 && MATRIX_ROW_BOTTOM_Y (row) < last_y));
15318 /* If we didn't find any candidate rows, or exited the
15319 loop before all the candidates were examined, signal
15320 to the caller that this method failed. */
15321 if (rc != CURSOR_MOVEMENT_SUCCESS
15322 && !(rv
15323 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
15324 && !row->continued_p))
15325 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15326 else if (rv)
15327 rc = CURSOR_MOVEMENT_SUCCESS;
15329 else
15333 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
15335 rc = CURSOR_MOVEMENT_SUCCESS;
15336 break;
15338 ++row;
15340 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15341 && MATRIX_ROW_START_CHARPOS (row) == PT
15342 && cursor_row_p (row));
15347 return rc;
15350 #if !defined USE_TOOLKIT_SCROLL_BARS || defined USE_GTK
15351 static
15352 #endif
15353 void
15354 set_vertical_scroll_bar (struct window *w)
15356 ptrdiff_t start, end, whole;
15358 /* Calculate the start and end positions for the current window.
15359 At some point, it would be nice to choose between scrollbars
15360 which reflect the whole buffer size, with special markers
15361 indicating narrowing, and scrollbars which reflect only the
15362 visible region.
15364 Note that mini-buffers sometimes aren't displaying any text. */
15365 if (!MINI_WINDOW_P (w)
15366 || (w == XWINDOW (minibuf_window)
15367 && NILP (echo_area_buffer[0])))
15369 struct buffer *buf = XBUFFER (w->contents);
15370 whole = BUF_ZV (buf) - BUF_BEGV (buf);
15371 start = marker_position (w->start) - BUF_BEGV (buf);
15372 /* I don't think this is guaranteed to be right. For the
15373 moment, we'll pretend it is. */
15374 end = BUF_Z (buf) - w->window_end_pos - BUF_BEGV (buf);
15376 if (end < start)
15377 end = start;
15378 if (whole < (end - start))
15379 whole = end - start;
15381 else
15382 start = end = whole = 0;
15384 /* Indicate what this scroll bar ought to be displaying now. */
15385 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
15386 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
15387 (w, end - start, whole, start);
15391 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
15392 selected_window is redisplayed.
15394 We can return without actually redisplaying the window if
15395 fonts_changed_p. In that case, redisplay_internal will
15396 retry. */
15398 static void
15399 redisplay_window (Lisp_Object window, int just_this_one_p)
15401 struct window *w = XWINDOW (window);
15402 struct frame *f = XFRAME (w->frame);
15403 struct buffer *buffer = XBUFFER (w->contents);
15404 struct buffer *old = current_buffer;
15405 struct text_pos lpoint, opoint, startp;
15406 int update_mode_line;
15407 int tem;
15408 struct it it;
15409 /* Record it now because it's overwritten. */
15410 int current_matrix_up_to_date_p = 0;
15411 int used_current_matrix_p = 0;
15412 /* This is less strict than current_matrix_up_to_date_p.
15413 It indicates that the buffer contents and narrowing are unchanged. */
15414 int buffer_unchanged_p = 0;
15415 int temp_scroll_step = 0;
15416 ptrdiff_t count = SPECPDL_INDEX ();
15417 int rc;
15418 int centering_position = -1;
15419 int last_line_misfit = 0;
15420 ptrdiff_t beg_unchanged, end_unchanged;
15421 int frame_line_height;
15423 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15424 opoint = lpoint;
15426 #ifdef GLYPH_DEBUG
15427 *w->desired_matrix->method = 0;
15428 #endif
15430 /* Make sure that both W's markers are valid. */
15431 eassert (XMARKER (w->start)->buffer == buffer);
15432 eassert (XMARKER (w->pointm)->buffer == buffer);
15434 restart:
15435 reconsider_clip_changes (w);
15436 frame_line_height = default_line_pixel_height (w);
15438 /* Has the mode line to be updated? */
15439 update_mode_line = (w->update_mode_line
15440 || update_mode_lines
15441 || buffer->clip_changed
15442 || buffer->prevent_redisplay_optimizations_p);
15444 if (MINI_WINDOW_P (w))
15446 if (w == XWINDOW (echo_area_window)
15447 && !NILP (echo_area_buffer[0]))
15449 if (update_mode_line)
15450 /* We may have to update a tty frame's menu bar or a
15451 tool-bar. Example `M-x C-h C-h C-g'. */
15452 goto finish_menu_bars;
15453 else
15454 /* We've already displayed the echo area glyphs in this window. */
15455 goto finish_scroll_bars;
15457 else if ((w != XWINDOW (minibuf_window)
15458 || minibuf_level == 0)
15459 /* When buffer is nonempty, redisplay window normally. */
15460 && BUF_Z (XBUFFER (w->contents)) == BUF_BEG (XBUFFER (w->contents))
15461 /* Quail displays non-mini buffers in minibuffer window.
15462 In that case, redisplay the window normally. */
15463 && !NILP (Fmemq (w->contents, Vminibuffer_list)))
15465 /* W is a mini-buffer window, but it's not active, so clear
15466 it. */
15467 int yb = window_text_bottom_y (w);
15468 struct glyph_row *row;
15469 int y;
15471 for (y = 0, row = w->desired_matrix->rows;
15472 y < yb;
15473 y += row->height, ++row)
15474 blank_row (w, row, y);
15475 goto finish_scroll_bars;
15478 clear_glyph_matrix (w->desired_matrix);
15481 /* Otherwise set up data on this window; select its buffer and point
15482 value. */
15483 /* Really select the buffer, for the sake of buffer-local
15484 variables. */
15485 set_buffer_internal_1 (XBUFFER (w->contents));
15487 current_matrix_up_to_date_p
15488 = (w->window_end_valid
15489 && !current_buffer->clip_changed
15490 && !current_buffer->prevent_redisplay_optimizations_p
15491 && !window_outdated (w));
15493 /* Run the window-bottom-change-functions
15494 if it is possible that the text on the screen has changed
15495 (either due to modification of the text, or any other reason). */
15496 if (!current_matrix_up_to_date_p
15497 && !NILP (Vwindow_text_change_functions))
15499 safe_run_hooks (Qwindow_text_change_functions);
15500 goto restart;
15503 beg_unchanged = BEG_UNCHANGED;
15504 end_unchanged = END_UNCHANGED;
15506 SET_TEXT_POS (opoint, PT, PT_BYTE);
15508 specbind (Qinhibit_point_motion_hooks, Qt);
15510 buffer_unchanged_p
15511 = (w->window_end_valid
15512 && !current_buffer->clip_changed
15513 && !window_outdated (w));
15515 /* When windows_or_buffers_changed is non-zero, we can't rely
15516 on the window end being valid, so set it to zero there. */
15517 if (windows_or_buffers_changed)
15519 /* If window starts on a continuation line, maybe adjust the
15520 window start in case the window's width changed. */
15521 if (XMARKER (w->start)->buffer == current_buffer)
15522 compute_window_start_on_continuation_line (w);
15524 w->window_end_valid = 0;
15525 /* If so, we also can't rely on current matrix
15526 and should not fool try_cursor_movement below. */
15527 current_matrix_up_to_date_p = 0;
15530 /* Some sanity checks. */
15531 CHECK_WINDOW_END (w);
15532 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
15533 emacs_abort ();
15534 if (BYTEPOS (opoint) < CHARPOS (opoint))
15535 emacs_abort ();
15537 if (mode_line_update_needed (w))
15538 update_mode_line = 1;
15540 /* Point refers normally to the selected window. For any other
15541 window, set up appropriate value. */
15542 if (!EQ (window, selected_window))
15544 ptrdiff_t new_pt = marker_position (w->pointm);
15545 ptrdiff_t new_pt_byte = marker_byte_position (w->pointm);
15546 if (new_pt < BEGV)
15548 new_pt = BEGV;
15549 new_pt_byte = BEGV_BYTE;
15550 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
15552 else if (new_pt > (ZV - 1))
15554 new_pt = ZV;
15555 new_pt_byte = ZV_BYTE;
15556 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
15559 /* We don't use SET_PT so that the point-motion hooks don't run. */
15560 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
15563 /* If any of the character widths specified in the display table
15564 have changed, invalidate the width run cache. It's true that
15565 this may be a bit late to catch such changes, but the rest of
15566 redisplay goes (non-fatally) haywire when the display table is
15567 changed, so why should we worry about doing any better? */
15568 if (current_buffer->width_run_cache)
15570 struct Lisp_Char_Table *disptab = buffer_display_table ();
15572 if (! disptab_matches_widthtab
15573 (disptab, XVECTOR (BVAR (current_buffer, width_table))))
15575 invalidate_region_cache (current_buffer,
15576 current_buffer->width_run_cache,
15577 BEG, Z);
15578 recompute_width_table (current_buffer, disptab);
15582 /* If window-start is screwed up, choose a new one. */
15583 if (XMARKER (w->start)->buffer != current_buffer)
15584 goto recenter;
15586 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15588 /* If someone specified a new starting point but did not insist,
15589 check whether it can be used. */
15590 if (w->optional_new_start
15591 && CHARPOS (startp) >= BEGV
15592 && CHARPOS (startp) <= ZV)
15594 w->optional_new_start = 0;
15595 start_display (&it, w, startp);
15596 move_it_to (&it, PT, 0, it.last_visible_y, -1,
15597 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
15598 if (IT_CHARPOS (it) == PT)
15599 w->force_start = 1;
15600 /* IT may overshoot PT if text at PT is invisible. */
15601 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
15602 w->force_start = 1;
15605 force_start:
15607 /* Handle case where place to start displaying has been specified,
15608 unless the specified location is outside the accessible range. */
15609 if (w->force_start || window_frozen_p (w))
15611 /* We set this later on if we have to adjust point. */
15612 int new_vpos = -1;
15614 w->force_start = 0;
15615 w->vscroll = 0;
15616 w->window_end_valid = 0;
15618 /* Forget any recorded base line for line number display. */
15619 if (!buffer_unchanged_p)
15620 w->base_line_number = 0;
15622 /* Redisplay the mode line. Select the buffer properly for that.
15623 Also, run the hook window-scroll-functions
15624 because we have scrolled. */
15625 /* Note, we do this after clearing force_start because
15626 if there's an error, it is better to forget about force_start
15627 than to get into an infinite loop calling the hook functions
15628 and having them get more errors. */
15629 if (!update_mode_line
15630 || ! NILP (Vwindow_scroll_functions))
15632 update_mode_line = 1;
15633 w->update_mode_line = 1;
15634 startp = run_window_scroll_functions (window, startp);
15637 if (CHARPOS (startp) < BEGV)
15638 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
15639 else if (CHARPOS (startp) > ZV)
15640 SET_TEXT_POS (startp, ZV, ZV_BYTE);
15642 /* Redisplay, then check if cursor has been set during the
15643 redisplay. Give up if new fonts were loaded. */
15644 /* We used to issue a CHECK_MARGINS argument to try_window here,
15645 but this causes scrolling to fail when point begins inside
15646 the scroll margin (bug#148) -- cyd */
15647 if (!try_window (window, startp, 0))
15649 w->force_start = 1;
15650 clear_glyph_matrix (w->desired_matrix);
15651 goto need_larger_matrices;
15654 if (w->cursor.vpos < 0 && !window_frozen_p (w))
15656 /* If point does not appear, try to move point so it does
15657 appear. The desired matrix has been built above, so we
15658 can use it here. */
15659 new_vpos = window_box_height (w) / 2;
15662 if (!cursor_row_fully_visible_p (w, 0, 0))
15664 /* Point does appear, but on a line partly visible at end of window.
15665 Move it back to a fully-visible line. */
15666 new_vpos = window_box_height (w);
15668 else if (w->cursor.vpos >=0)
15670 /* Some people insist on not letting point enter the scroll
15671 margin, even though this part handles windows that didn't
15672 scroll at all. */
15673 int window_total_lines
15674 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
15675 int margin = min (scroll_margin, window_total_lines / 4);
15676 int pixel_margin = margin * frame_line_height;
15677 bool header_line = WINDOW_WANTS_HEADER_LINE_P (w);
15679 /* Note: We add an extra FRAME_LINE_HEIGHT, because the loop
15680 below, which finds the row to move point to, advances by
15681 the Y coordinate of the _next_ row, see the definition of
15682 MATRIX_ROW_BOTTOM_Y. */
15683 if (w->cursor.vpos < margin + header_line)
15685 w->cursor.vpos = -1;
15686 clear_glyph_matrix (w->desired_matrix);
15687 goto try_to_scroll;
15689 else
15691 int window_height = window_box_height (w);
15693 if (header_line)
15694 window_height += CURRENT_HEADER_LINE_HEIGHT (w);
15695 if (w->cursor.y >= window_height - pixel_margin)
15697 w->cursor.vpos = -1;
15698 clear_glyph_matrix (w->desired_matrix);
15699 goto try_to_scroll;
15704 /* If we need to move point for either of the above reasons,
15705 now actually do it. */
15706 if (new_vpos >= 0)
15708 struct glyph_row *row;
15710 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
15711 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
15712 ++row;
15714 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
15715 MATRIX_ROW_START_BYTEPOS (row));
15717 if (w != XWINDOW (selected_window))
15718 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
15719 else if (current_buffer == old)
15720 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15722 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
15724 /* If we are highlighting the region, then we just changed
15725 the region, so redisplay to show it. */
15726 if (markpos_of_region () >= 0)
15728 clear_glyph_matrix (w->desired_matrix);
15729 if (!try_window (window, startp, 0))
15730 goto need_larger_matrices;
15734 #ifdef GLYPH_DEBUG
15735 debug_method_add (w, "forced window start");
15736 #endif
15737 goto done;
15740 /* Handle case where text has not changed, only point, and it has
15741 not moved off the frame, and we are not retrying after hscroll.
15742 (current_matrix_up_to_date_p is nonzero when retrying.) */
15743 if (current_matrix_up_to_date_p
15744 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
15745 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
15747 switch (rc)
15749 case CURSOR_MOVEMENT_SUCCESS:
15750 used_current_matrix_p = 1;
15751 goto done;
15753 case CURSOR_MOVEMENT_MUST_SCROLL:
15754 goto try_to_scroll;
15756 default:
15757 emacs_abort ();
15760 /* If current starting point was originally the beginning of a line
15761 but no longer is, find a new starting point. */
15762 else if (w->start_at_line_beg
15763 && !(CHARPOS (startp) <= BEGV
15764 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
15766 #ifdef GLYPH_DEBUG
15767 debug_method_add (w, "recenter 1");
15768 #endif
15769 goto recenter;
15772 /* Try scrolling with try_window_id. Value is > 0 if update has
15773 been done, it is -1 if we know that the same window start will
15774 not work. It is 0 if unsuccessful for some other reason. */
15775 else if ((tem = try_window_id (w)) != 0)
15777 #ifdef GLYPH_DEBUG
15778 debug_method_add (w, "try_window_id %d", tem);
15779 #endif
15781 if (fonts_changed_p)
15782 goto need_larger_matrices;
15783 if (tem > 0)
15784 goto done;
15786 /* Otherwise try_window_id has returned -1 which means that we
15787 don't want the alternative below this comment to execute. */
15789 else if (CHARPOS (startp) >= BEGV
15790 && CHARPOS (startp) <= ZV
15791 && PT >= CHARPOS (startp)
15792 && (CHARPOS (startp) < ZV
15793 /* Avoid starting at end of buffer. */
15794 || CHARPOS (startp) == BEGV
15795 || !window_outdated (w)))
15797 int d1, d2, d3, d4, d5, d6;
15799 /* If first window line is a continuation line, and window start
15800 is inside the modified region, but the first change is before
15801 current window start, we must select a new window start.
15803 However, if this is the result of a down-mouse event (e.g. by
15804 extending the mouse-drag-overlay), we don't want to select a
15805 new window start, since that would change the position under
15806 the mouse, resulting in an unwanted mouse-movement rather
15807 than a simple mouse-click. */
15808 if (!w->start_at_line_beg
15809 && NILP (do_mouse_tracking)
15810 && CHARPOS (startp) > BEGV
15811 && CHARPOS (startp) > BEG + beg_unchanged
15812 && CHARPOS (startp) <= Z - end_unchanged
15813 /* Even if w->start_at_line_beg is nil, a new window may
15814 start at a line_beg, since that's how set_buffer_window
15815 sets it. So, we need to check the return value of
15816 compute_window_start_on_continuation_line. (See also
15817 bug#197). */
15818 && XMARKER (w->start)->buffer == current_buffer
15819 && compute_window_start_on_continuation_line (w)
15820 /* It doesn't make sense to force the window start like we
15821 do at label force_start if it is already known that point
15822 will not be visible in the resulting window, because
15823 doing so will move point from its correct position
15824 instead of scrolling the window to bring point into view.
15825 See bug#9324. */
15826 && pos_visible_p (w, PT, &d1, &d2, &d3, &d4, &d5, &d6))
15828 w->force_start = 1;
15829 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15830 goto force_start;
15833 #ifdef GLYPH_DEBUG
15834 debug_method_add (w, "same window start");
15835 #endif
15837 /* Try to redisplay starting at same place as before.
15838 If point has not moved off frame, accept the results. */
15839 if (!current_matrix_up_to_date_p
15840 /* Don't use try_window_reusing_current_matrix in this case
15841 because a window scroll function can have changed the
15842 buffer. */
15843 || !NILP (Vwindow_scroll_functions)
15844 || MINI_WINDOW_P (w)
15845 || !(used_current_matrix_p
15846 = try_window_reusing_current_matrix (w)))
15848 IF_DEBUG (debug_method_add (w, "1"));
15849 if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
15850 /* -1 means we need to scroll.
15851 0 means we need new matrices, but fonts_changed_p
15852 is set in that case, so we will detect it below. */
15853 goto try_to_scroll;
15856 if (fonts_changed_p)
15857 goto need_larger_matrices;
15859 if (w->cursor.vpos >= 0)
15861 if (!just_this_one_p
15862 || current_buffer->clip_changed
15863 || BEG_UNCHANGED < CHARPOS (startp))
15864 /* Forget any recorded base line for line number display. */
15865 w->base_line_number = 0;
15867 if (!cursor_row_fully_visible_p (w, 1, 0))
15869 clear_glyph_matrix (w->desired_matrix);
15870 last_line_misfit = 1;
15872 /* Drop through and scroll. */
15873 else
15874 goto done;
15876 else
15877 clear_glyph_matrix (w->desired_matrix);
15880 try_to_scroll:
15882 /* Redisplay the mode line. Select the buffer properly for that. */
15883 if (!update_mode_line)
15885 update_mode_line = 1;
15886 w->update_mode_line = 1;
15889 /* Try to scroll by specified few lines. */
15890 if ((scroll_conservatively
15891 || emacs_scroll_step
15892 || temp_scroll_step
15893 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively))
15894 || NUMBERP (BVAR (current_buffer, scroll_down_aggressively)))
15895 && CHARPOS (startp) >= BEGV
15896 && CHARPOS (startp) <= ZV)
15898 /* The function returns -1 if new fonts were loaded, 1 if
15899 successful, 0 if not successful. */
15900 int ss = try_scrolling (window, just_this_one_p,
15901 scroll_conservatively,
15902 emacs_scroll_step,
15903 temp_scroll_step, last_line_misfit);
15904 switch (ss)
15906 case SCROLLING_SUCCESS:
15907 goto done;
15909 case SCROLLING_NEED_LARGER_MATRICES:
15910 goto need_larger_matrices;
15912 case SCROLLING_FAILED:
15913 break;
15915 default:
15916 emacs_abort ();
15920 /* Finally, just choose a place to start which positions point
15921 according to user preferences. */
15923 recenter:
15925 #ifdef GLYPH_DEBUG
15926 debug_method_add (w, "recenter");
15927 #endif
15929 /* Forget any previously recorded base line for line number display. */
15930 if (!buffer_unchanged_p)
15931 w->base_line_number = 0;
15933 /* Determine the window start relative to point. */
15934 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
15935 it.current_y = it.last_visible_y;
15936 if (centering_position < 0)
15938 int window_total_lines
15939 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
15940 int margin =
15941 scroll_margin > 0
15942 ? min (scroll_margin, window_total_lines / 4)
15943 : 0;
15944 ptrdiff_t margin_pos = CHARPOS (startp);
15945 Lisp_Object aggressive;
15946 int scrolling_up;
15948 /* If there is a scroll margin at the top of the window, find
15949 its character position. */
15950 if (margin
15951 /* Cannot call start_display if startp is not in the
15952 accessible region of the buffer. This can happen when we
15953 have just switched to a different buffer and/or changed
15954 its restriction. In that case, startp is initialized to
15955 the character position 1 (BEGV) because we did not yet
15956 have chance to display the buffer even once. */
15957 && BEGV <= CHARPOS (startp) && CHARPOS (startp) <= ZV)
15959 struct it it1;
15960 void *it1data = NULL;
15962 SAVE_IT (it1, it, it1data);
15963 start_display (&it1, w, startp);
15964 move_it_vertically (&it1, margin * frame_line_height);
15965 margin_pos = IT_CHARPOS (it1);
15966 RESTORE_IT (&it, &it, it1data);
15968 scrolling_up = PT > margin_pos;
15969 aggressive =
15970 scrolling_up
15971 ? BVAR (current_buffer, scroll_up_aggressively)
15972 : BVAR (current_buffer, scroll_down_aggressively);
15974 if (!MINI_WINDOW_P (w)
15975 && (scroll_conservatively > SCROLL_LIMIT || NUMBERP (aggressive)))
15977 int pt_offset = 0;
15979 /* Setting scroll-conservatively overrides
15980 scroll-*-aggressively. */
15981 if (!scroll_conservatively && NUMBERP (aggressive))
15983 double float_amount = XFLOATINT (aggressive);
15985 pt_offset = float_amount * WINDOW_BOX_TEXT_HEIGHT (w);
15986 if (pt_offset == 0 && float_amount > 0)
15987 pt_offset = 1;
15988 if (pt_offset && margin > 0)
15989 margin -= 1;
15991 /* Compute how much to move the window start backward from
15992 point so that point will be displayed where the user
15993 wants it. */
15994 if (scrolling_up)
15996 centering_position = it.last_visible_y;
15997 if (pt_offset)
15998 centering_position -= pt_offset;
15999 centering_position -=
16000 frame_line_height * (1 + margin + (last_line_misfit != 0))
16001 + WINDOW_HEADER_LINE_HEIGHT (w);
16002 /* Don't let point enter the scroll margin near top of
16003 the window. */
16004 if (centering_position < margin * frame_line_height)
16005 centering_position = margin * frame_line_height;
16007 else
16008 centering_position = margin * frame_line_height + pt_offset;
16010 else
16011 /* Set the window start half the height of the window backward
16012 from point. */
16013 centering_position = window_box_height (w) / 2;
16015 move_it_vertically_backward (&it, centering_position);
16017 eassert (IT_CHARPOS (it) >= BEGV);
16019 /* The function move_it_vertically_backward may move over more
16020 than the specified y-distance. If it->w is small, e.g. a
16021 mini-buffer window, we may end up in front of the window's
16022 display area. Start displaying at the start of the line
16023 containing PT in this case. */
16024 if (it.current_y <= 0)
16026 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
16027 move_it_vertically_backward (&it, 0);
16028 it.current_y = 0;
16031 it.current_x = it.hpos = 0;
16033 /* Set the window start position here explicitly, to avoid an
16034 infinite loop in case the functions in window-scroll-functions
16035 get errors. */
16036 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
16038 /* Run scroll hooks. */
16039 startp = run_window_scroll_functions (window, it.current.pos);
16041 /* Redisplay the window. */
16042 if (!current_matrix_up_to_date_p
16043 || windows_or_buffers_changed
16044 || cursor_type_changed
16045 /* Don't use try_window_reusing_current_matrix in this case
16046 because it can have changed the buffer. */
16047 || !NILP (Vwindow_scroll_functions)
16048 || !just_this_one_p
16049 || MINI_WINDOW_P (w)
16050 || !(used_current_matrix_p
16051 = try_window_reusing_current_matrix (w)))
16052 try_window (window, startp, 0);
16054 /* If new fonts have been loaded (due to fontsets), give up. We
16055 have to start a new redisplay since we need to re-adjust glyph
16056 matrices. */
16057 if (fonts_changed_p)
16058 goto need_larger_matrices;
16060 /* If cursor did not appear assume that the middle of the window is
16061 in the first line of the window. Do it again with the next line.
16062 (Imagine a window of height 100, displaying two lines of height
16063 60. Moving back 50 from it->last_visible_y will end in the first
16064 line.) */
16065 if (w->cursor.vpos < 0)
16067 if (w->window_end_valid && PT >= Z - w->window_end_pos)
16069 clear_glyph_matrix (w->desired_matrix);
16070 move_it_by_lines (&it, 1);
16071 try_window (window, it.current.pos, 0);
16073 else if (PT < IT_CHARPOS (it))
16075 clear_glyph_matrix (w->desired_matrix);
16076 move_it_by_lines (&it, -1);
16077 try_window (window, it.current.pos, 0);
16079 else
16081 /* Not much we can do about it. */
16085 /* Consider the following case: Window starts at BEGV, there is
16086 invisible, intangible text at BEGV, so that display starts at
16087 some point START > BEGV. It can happen that we are called with
16088 PT somewhere between BEGV and START. Try to handle that case. */
16089 if (w->cursor.vpos < 0)
16091 struct glyph_row *row = w->current_matrix->rows;
16092 if (row->mode_line_p)
16093 ++row;
16094 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
16097 if (!cursor_row_fully_visible_p (w, 0, 0))
16099 /* If vscroll is enabled, disable it and try again. */
16100 if (w->vscroll)
16102 w->vscroll = 0;
16103 clear_glyph_matrix (w->desired_matrix);
16104 goto recenter;
16107 /* Users who set scroll-conservatively to a large number want
16108 point just above/below the scroll margin. If we ended up
16109 with point's row partially visible, move the window start to
16110 make that row fully visible and out of the margin. */
16111 if (scroll_conservatively > SCROLL_LIMIT)
16113 int window_total_lines
16114 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) * frame_line_height;
16115 int margin =
16116 scroll_margin > 0
16117 ? min (scroll_margin, window_total_lines / 4)
16118 : 0;
16119 int move_down = w->cursor.vpos >= window_total_lines / 2;
16121 move_it_by_lines (&it, move_down ? margin + 1 : -(margin + 1));
16122 clear_glyph_matrix (w->desired_matrix);
16123 if (1 == try_window (window, it.current.pos,
16124 TRY_WINDOW_CHECK_MARGINS))
16125 goto done;
16128 /* If centering point failed to make the whole line visible,
16129 put point at the top instead. That has to make the whole line
16130 visible, if it can be done. */
16131 if (centering_position == 0)
16132 goto done;
16134 clear_glyph_matrix (w->desired_matrix);
16135 centering_position = 0;
16136 goto recenter;
16139 done:
16141 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16142 w->start_at_line_beg = (CHARPOS (startp) == BEGV
16143 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n');
16145 /* Display the mode line, if we must. */
16146 if ((update_mode_line
16147 /* If window not full width, must redo its mode line
16148 if (a) the window to its side is being redone and
16149 (b) we do a frame-based redisplay. This is a consequence
16150 of how inverted lines are drawn in frame-based redisplay. */
16151 || (!just_this_one_p
16152 && !FRAME_WINDOW_P (f)
16153 && !WINDOW_FULL_WIDTH_P (w))
16154 /* Line number to display. */
16155 || w->base_line_pos > 0
16156 /* Column number is displayed and different from the one displayed. */
16157 || (w->column_number_displayed != -1
16158 && (w->column_number_displayed != current_column ())))
16159 /* This means that the window has a mode line. */
16160 && (WINDOW_WANTS_MODELINE_P (w)
16161 || WINDOW_WANTS_HEADER_LINE_P (w)))
16163 display_mode_lines (w);
16165 /* If mode line height has changed, arrange for a thorough
16166 immediate redisplay using the correct mode line height. */
16167 if (WINDOW_WANTS_MODELINE_P (w)
16168 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
16170 fonts_changed_p = 1;
16171 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
16172 = DESIRED_MODE_LINE_HEIGHT (w);
16175 /* If header line height has changed, arrange for a thorough
16176 immediate redisplay using the correct header line height. */
16177 if (WINDOW_WANTS_HEADER_LINE_P (w)
16178 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
16180 fonts_changed_p = 1;
16181 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
16182 = DESIRED_HEADER_LINE_HEIGHT (w);
16185 if (fonts_changed_p)
16186 goto need_larger_matrices;
16189 if (!line_number_displayed && w->base_line_pos != -1)
16191 w->base_line_pos = 0;
16192 w->base_line_number = 0;
16195 finish_menu_bars:
16197 /* When we reach a frame's selected window, redo the frame's menu bar. */
16198 if (update_mode_line
16199 && EQ (FRAME_SELECTED_WINDOW (f), window))
16201 int redisplay_menu_p = 0;
16203 if (FRAME_WINDOW_P (f))
16205 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
16206 || defined (HAVE_NS) || defined (USE_GTK)
16207 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
16208 #else
16209 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
16210 #endif
16212 else
16213 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
16215 if (redisplay_menu_p)
16216 display_menu_bar (w);
16218 #ifdef HAVE_WINDOW_SYSTEM
16219 if (FRAME_WINDOW_P (f))
16221 #if defined (USE_GTK) || defined (HAVE_NS)
16222 if (FRAME_EXTERNAL_TOOL_BAR (f))
16223 redisplay_tool_bar (f);
16224 #else
16225 if (WINDOWP (f->tool_bar_window)
16226 && (FRAME_TOOL_BAR_LINES (f) > 0
16227 || !NILP (Vauto_resize_tool_bars))
16228 && redisplay_tool_bar (f))
16229 ignore_mouse_drag_p = 1;
16230 #endif
16232 #endif
16235 #ifdef HAVE_WINDOW_SYSTEM
16236 if (FRAME_WINDOW_P (f)
16237 && update_window_fringes (w, (just_this_one_p
16238 || (!used_current_matrix_p && !overlay_arrow_seen)
16239 || w->pseudo_window_p)))
16241 update_begin (f);
16242 block_input ();
16243 if (draw_window_fringes (w, 1))
16244 x_draw_vertical_border (w);
16245 unblock_input ();
16246 update_end (f);
16248 #endif /* HAVE_WINDOW_SYSTEM */
16250 /* We go to this label, with fonts_changed_p set,
16251 if it is necessary to try again using larger glyph matrices.
16252 We have to redeem the scroll bar even in this case,
16253 because the loop in redisplay_internal expects that. */
16254 need_larger_matrices:
16256 finish_scroll_bars:
16258 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
16260 /* Set the thumb's position and size. */
16261 set_vertical_scroll_bar (w);
16263 /* Note that we actually used the scroll bar attached to this
16264 window, so it shouldn't be deleted at the end of redisplay. */
16265 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
16266 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
16269 /* Restore current_buffer and value of point in it. The window
16270 update may have changed the buffer, so first make sure `opoint'
16271 is still valid (Bug#6177). */
16272 if (CHARPOS (opoint) < BEGV)
16273 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
16274 else if (CHARPOS (opoint) > ZV)
16275 TEMP_SET_PT_BOTH (Z, Z_BYTE);
16276 else
16277 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
16279 set_buffer_internal_1 (old);
16280 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
16281 shorter. This can be caused by log truncation in *Messages*. */
16282 if (CHARPOS (lpoint) <= ZV)
16283 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
16285 unbind_to (count, Qnil);
16289 /* Build the complete desired matrix of WINDOW with a window start
16290 buffer position POS.
16292 Value is 1 if successful. It is zero if fonts were loaded during
16293 redisplay which makes re-adjusting glyph matrices necessary, and -1
16294 if point would appear in the scroll margins.
16295 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
16296 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
16297 set in FLAGS.) */
16300 try_window (Lisp_Object window, struct text_pos pos, int flags)
16302 struct window *w = XWINDOW (window);
16303 struct it it;
16304 struct glyph_row *last_text_row = NULL;
16305 struct frame *f = XFRAME (w->frame);
16306 int frame_line_height = default_line_pixel_height (w);
16308 /* Make POS the new window start. */
16309 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
16311 /* Mark cursor position as unknown. No overlay arrow seen. */
16312 w->cursor.vpos = -1;
16313 overlay_arrow_seen = 0;
16315 /* Initialize iterator and info to start at POS. */
16316 start_display (&it, w, pos);
16318 /* Display all lines of W. */
16319 while (it.current_y < it.last_visible_y)
16321 if (display_line (&it))
16322 last_text_row = it.glyph_row - 1;
16323 if (fonts_changed_p && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
16324 return 0;
16327 /* Don't let the cursor end in the scroll margins. */
16328 if ((flags & TRY_WINDOW_CHECK_MARGINS)
16329 && !MINI_WINDOW_P (w))
16331 int this_scroll_margin;
16332 int window_total_lines
16333 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
16335 if (scroll_margin > 0)
16337 this_scroll_margin = min (scroll_margin, window_total_lines / 4);
16338 this_scroll_margin *= frame_line_height;
16340 else
16341 this_scroll_margin = 0;
16343 if ((w->cursor.y >= 0 /* not vscrolled */
16344 && w->cursor.y < this_scroll_margin
16345 && CHARPOS (pos) > BEGV
16346 && IT_CHARPOS (it) < ZV)
16347 /* rms: considering make_cursor_line_fully_visible_p here
16348 seems to give wrong results. We don't want to recenter
16349 when the last line is partly visible, we want to allow
16350 that case to be handled in the usual way. */
16351 || w->cursor.y > it.last_visible_y - this_scroll_margin - 1)
16353 w->cursor.vpos = -1;
16354 clear_glyph_matrix (w->desired_matrix);
16355 return -1;
16359 /* If bottom moved off end of frame, change mode line percentage. */
16360 if (w->window_end_pos <= 0 && Z != IT_CHARPOS (it))
16361 w->update_mode_line = 1;
16363 /* Set window_end_pos to the offset of the last character displayed
16364 on the window from the end of current_buffer. Set
16365 window_end_vpos to its row number. */
16366 if (last_text_row)
16368 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
16369 adjust_window_ends (w, last_text_row, 0);
16370 eassert
16371 (MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->desired_matrix,
16372 w->window_end_vpos)));
16374 else
16376 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
16377 w->window_end_pos = Z - ZV;
16378 w->window_end_vpos = 0;
16381 /* But that is not valid info until redisplay finishes. */
16382 w->window_end_valid = 0;
16383 return 1;
16388 /************************************************************************
16389 Window redisplay reusing current matrix when buffer has not changed
16390 ************************************************************************/
16392 /* Try redisplay of window W showing an unchanged buffer with a
16393 different window start than the last time it was displayed by
16394 reusing its current matrix. Value is non-zero if successful.
16395 W->start is the new window start. */
16397 static int
16398 try_window_reusing_current_matrix (struct window *w)
16400 struct frame *f = XFRAME (w->frame);
16401 struct glyph_row *bottom_row;
16402 struct it it;
16403 struct run run;
16404 struct text_pos start, new_start;
16405 int nrows_scrolled, i;
16406 struct glyph_row *last_text_row;
16407 struct glyph_row *last_reused_text_row;
16408 struct glyph_row *start_row;
16409 int start_vpos, min_y, max_y;
16411 #ifdef GLYPH_DEBUG
16412 if (inhibit_try_window_reusing)
16413 return 0;
16414 #endif
16416 if (/* This function doesn't handle terminal frames. */
16417 !FRAME_WINDOW_P (f)
16418 /* Don't try to reuse the display if windows have been split
16419 or such. */
16420 || windows_or_buffers_changed
16421 || cursor_type_changed)
16422 return 0;
16424 /* Can't do this if region may have changed. */
16425 if (markpos_of_region () >= 0
16426 || w->region_showing
16427 || !NILP (Vshow_trailing_whitespace))
16428 return 0;
16430 /* If top-line visibility has changed, give up. */
16431 if (WINDOW_WANTS_HEADER_LINE_P (w)
16432 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
16433 return 0;
16435 /* Give up if old or new display is scrolled vertically. We could
16436 make this function handle this, but right now it doesn't. */
16437 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16438 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
16439 return 0;
16441 /* The variable new_start now holds the new window start. The old
16442 start `start' can be determined from the current matrix. */
16443 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
16444 start = start_row->minpos;
16445 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
16447 /* Clear the desired matrix for the display below. */
16448 clear_glyph_matrix (w->desired_matrix);
16450 if (CHARPOS (new_start) <= CHARPOS (start))
16452 /* Don't use this method if the display starts with an ellipsis
16453 displayed for invisible text. It's not easy to handle that case
16454 below, and it's certainly not worth the effort since this is
16455 not a frequent case. */
16456 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
16457 return 0;
16459 IF_DEBUG (debug_method_add (w, "twu1"));
16461 /* Display up to a row that can be reused. The variable
16462 last_text_row is set to the last row displayed that displays
16463 text. Note that it.vpos == 0 if or if not there is a
16464 header-line; it's not the same as the MATRIX_ROW_VPOS! */
16465 start_display (&it, w, new_start);
16466 w->cursor.vpos = -1;
16467 last_text_row = last_reused_text_row = NULL;
16469 while (it.current_y < it.last_visible_y
16470 && !fonts_changed_p)
16472 /* If we have reached into the characters in the START row,
16473 that means the line boundaries have changed. So we
16474 can't start copying with the row START. Maybe it will
16475 work to start copying with the following row. */
16476 while (IT_CHARPOS (it) > CHARPOS (start))
16478 /* Advance to the next row as the "start". */
16479 start_row++;
16480 start = start_row->minpos;
16481 /* If there are no more rows to try, or just one, give up. */
16482 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
16483 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
16484 || CHARPOS (start) == ZV)
16486 clear_glyph_matrix (w->desired_matrix);
16487 return 0;
16490 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
16492 /* If we have reached alignment, we can copy the rest of the
16493 rows. */
16494 if (IT_CHARPOS (it) == CHARPOS (start)
16495 /* Don't accept "alignment" inside a display vector,
16496 since start_row could have started in the middle of
16497 that same display vector (thus their character
16498 positions match), and we have no way of telling if
16499 that is the case. */
16500 && it.current.dpvec_index < 0)
16501 break;
16503 if (display_line (&it))
16504 last_text_row = it.glyph_row - 1;
16508 /* A value of current_y < last_visible_y means that we stopped
16509 at the previous window start, which in turn means that we
16510 have at least one reusable row. */
16511 if (it.current_y < it.last_visible_y)
16513 struct glyph_row *row;
16515 /* IT.vpos always starts from 0; it counts text lines. */
16516 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
16518 /* Find PT if not already found in the lines displayed. */
16519 if (w->cursor.vpos < 0)
16521 int dy = it.current_y - start_row->y;
16523 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16524 row = row_containing_pos (w, PT, row, NULL, dy);
16525 if (row)
16526 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
16527 dy, nrows_scrolled);
16528 else
16530 clear_glyph_matrix (w->desired_matrix);
16531 return 0;
16535 /* Scroll the display. Do it before the current matrix is
16536 changed. The problem here is that update has not yet
16537 run, i.e. part of the current matrix is not up to date.
16538 scroll_run_hook will clear the cursor, and use the
16539 current matrix to get the height of the row the cursor is
16540 in. */
16541 run.current_y = start_row->y;
16542 run.desired_y = it.current_y;
16543 run.height = it.last_visible_y - it.current_y;
16545 if (run.height > 0 && run.current_y != run.desired_y)
16547 update_begin (f);
16548 FRAME_RIF (f)->update_window_begin_hook (w);
16549 FRAME_RIF (f)->clear_window_mouse_face (w);
16550 FRAME_RIF (f)->scroll_run_hook (w, &run);
16551 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
16552 update_end (f);
16555 /* Shift current matrix down by nrows_scrolled lines. */
16556 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
16557 rotate_matrix (w->current_matrix,
16558 start_vpos,
16559 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
16560 nrows_scrolled);
16562 /* Disable lines that must be updated. */
16563 for (i = 0; i < nrows_scrolled; ++i)
16564 (start_row + i)->enabled_p = 0;
16566 /* Re-compute Y positions. */
16567 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
16568 max_y = it.last_visible_y;
16569 for (row = start_row + nrows_scrolled;
16570 row < bottom_row;
16571 ++row)
16573 row->y = it.current_y;
16574 row->visible_height = row->height;
16576 if (row->y < min_y)
16577 row->visible_height -= min_y - row->y;
16578 if (row->y + row->height > max_y)
16579 row->visible_height -= row->y + row->height - max_y;
16580 if (row->fringe_bitmap_periodic_p)
16581 row->redraw_fringe_bitmaps_p = 1;
16583 it.current_y += row->height;
16585 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16586 last_reused_text_row = row;
16587 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
16588 break;
16591 /* Disable lines in the current matrix which are now
16592 below the window. */
16593 for (++row; row < bottom_row; ++row)
16594 row->enabled_p = row->mode_line_p = 0;
16597 /* Update window_end_pos etc.; last_reused_text_row is the last
16598 reused row from the current matrix containing text, if any.
16599 The value of last_text_row is the last displayed line
16600 containing text. */
16601 if (last_reused_text_row)
16602 adjust_window_ends (w, last_reused_text_row, 1);
16603 else if (last_text_row)
16604 adjust_window_ends (w, last_text_row, 0);
16605 else
16607 /* This window must be completely empty. */
16608 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
16609 w->window_end_pos = Z - ZV;
16610 w->window_end_vpos = 0;
16612 w->window_end_valid = 0;
16614 /* Update hint: don't try scrolling again in update_window. */
16615 w->desired_matrix->no_scrolling_p = 1;
16617 #ifdef GLYPH_DEBUG
16618 debug_method_add (w, "try_window_reusing_current_matrix 1");
16619 #endif
16620 return 1;
16622 else if (CHARPOS (new_start) > CHARPOS (start))
16624 struct glyph_row *pt_row, *row;
16625 struct glyph_row *first_reusable_row;
16626 struct glyph_row *first_row_to_display;
16627 int dy;
16628 int yb = window_text_bottom_y (w);
16630 /* Find the row starting at new_start, if there is one. Don't
16631 reuse a partially visible line at the end. */
16632 first_reusable_row = start_row;
16633 while (first_reusable_row->enabled_p
16634 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
16635 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
16636 < CHARPOS (new_start)))
16637 ++first_reusable_row;
16639 /* Give up if there is no row to reuse. */
16640 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
16641 || !first_reusable_row->enabled_p
16642 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
16643 != CHARPOS (new_start)))
16644 return 0;
16646 /* We can reuse fully visible rows beginning with
16647 first_reusable_row to the end of the window. Set
16648 first_row_to_display to the first row that cannot be reused.
16649 Set pt_row to the row containing point, if there is any. */
16650 pt_row = NULL;
16651 for (first_row_to_display = first_reusable_row;
16652 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
16653 ++first_row_to_display)
16655 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
16656 && (PT < MATRIX_ROW_END_CHARPOS (first_row_to_display)
16657 || (PT == MATRIX_ROW_END_CHARPOS (first_row_to_display)
16658 && first_row_to_display->ends_at_zv_p
16659 && pt_row == NULL)))
16660 pt_row = first_row_to_display;
16663 /* Start displaying at the start of first_row_to_display. */
16664 eassert (first_row_to_display->y < yb);
16665 init_to_row_start (&it, w, first_row_to_display);
16667 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
16668 - start_vpos);
16669 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
16670 - nrows_scrolled);
16671 it.current_y = (first_row_to_display->y - first_reusable_row->y
16672 + WINDOW_HEADER_LINE_HEIGHT (w));
16674 /* Display lines beginning with first_row_to_display in the
16675 desired matrix. Set last_text_row to the last row displayed
16676 that displays text. */
16677 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
16678 if (pt_row == NULL)
16679 w->cursor.vpos = -1;
16680 last_text_row = NULL;
16681 while (it.current_y < it.last_visible_y && !fonts_changed_p)
16682 if (display_line (&it))
16683 last_text_row = it.glyph_row - 1;
16685 /* If point is in a reused row, adjust y and vpos of the cursor
16686 position. */
16687 if (pt_row)
16689 w->cursor.vpos -= nrows_scrolled;
16690 w->cursor.y -= first_reusable_row->y - start_row->y;
16693 /* Give up if point isn't in a row displayed or reused. (This
16694 also handles the case where w->cursor.vpos < nrows_scrolled
16695 after the calls to display_line, which can happen with scroll
16696 margins. See bug#1295.) */
16697 if (w->cursor.vpos < 0)
16699 clear_glyph_matrix (w->desired_matrix);
16700 return 0;
16703 /* Scroll the display. */
16704 run.current_y = first_reusable_row->y;
16705 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
16706 run.height = it.last_visible_y - run.current_y;
16707 dy = run.current_y - run.desired_y;
16709 if (run.height)
16711 update_begin (f);
16712 FRAME_RIF (f)->update_window_begin_hook (w);
16713 FRAME_RIF (f)->clear_window_mouse_face (w);
16714 FRAME_RIF (f)->scroll_run_hook (w, &run);
16715 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
16716 update_end (f);
16719 /* Adjust Y positions of reused rows. */
16720 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
16721 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
16722 max_y = it.last_visible_y;
16723 for (row = first_reusable_row; row < first_row_to_display; ++row)
16725 row->y -= dy;
16726 row->visible_height = row->height;
16727 if (row->y < min_y)
16728 row->visible_height -= min_y - row->y;
16729 if (row->y + row->height > max_y)
16730 row->visible_height -= row->y + row->height - max_y;
16731 if (row->fringe_bitmap_periodic_p)
16732 row->redraw_fringe_bitmaps_p = 1;
16735 /* Scroll the current matrix. */
16736 eassert (nrows_scrolled > 0);
16737 rotate_matrix (w->current_matrix,
16738 start_vpos,
16739 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
16740 -nrows_scrolled);
16742 /* Disable rows not reused. */
16743 for (row -= nrows_scrolled; row < bottom_row; ++row)
16744 row->enabled_p = 0;
16746 /* Point may have moved to a different line, so we cannot assume that
16747 the previous cursor position is valid; locate the correct row. */
16748 if (pt_row)
16750 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
16751 row < bottom_row
16752 && PT >= MATRIX_ROW_END_CHARPOS (row)
16753 && !row->ends_at_zv_p;
16754 row++)
16756 w->cursor.vpos++;
16757 w->cursor.y = row->y;
16759 if (row < bottom_row)
16761 /* Can't simply scan the row for point with
16762 bidi-reordered glyph rows. Let set_cursor_from_row
16763 figure out where to put the cursor, and if it fails,
16764 give up. */
16765 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
16767 if (!set_cursor_from_row (w, row, w->current_matrix,
16768 0, 0, 0, 0))
16770 clear_glyph_matrix (w->desired_matrix);
16771 return 0;
16774 else
16776 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
16777 struct glyph *end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
16779 for (; glyph < end
16780 && (!BUFFERP (glyph->object)
16781 || glyph->charpos < PT);
16782 glyph++)
16784 w->cursor.hpos++;
16785 w->cursor.x += glyph->pixel_width;
16791 /* Adjust window end. A null value of last_text_row means that
16792 the window end is in reused rows which in turn means that
16793 only its vpos can have changed. */
16794 if (last_text_row)
16795 adjust_window_ends (w, last_text_row, 0);
16796 else
16797 w->window_end_vpos -= nrows_scrolled;
16799 w->window_end_valid = 0;
16800 w->desired_matrix->no_scrolling_p = 1;
16802 #ifdef GLYPH_DEBUG
16803 debug_method_add (w, "try_window_reusing_current_matrix 2");
16804 #endif
16805 return 1;
16808 return 0;
16813 /************************************************************************
16814 Window redisplay reusing current matrix when buffer has changed
16815 ************************************************************************/
16817 static struct glyph_row *find_last_unchanged_at_beg_row (struct window *);
16818 static struct glyph_row *find_first_unchanged_at_end_row (struct window *,
16819 ptrdiff_t *, ptrdiff_t *);
16820 static struct glyph_row *
16821 find_last_row_displaying_text (struct glyph_matrix *, struct it *,
16822 struct glyph_row *);
16825 /* Return the last row in MATRIX displaying text. If row START is
16826 non-null, start searching with that row. IT gives the dimensions
16827 of the display. Value is null if matrix is empty; otherwise it is
16828 a pointer to the row found. */
16830 static struct glyph_row *
16831 find_last_row_displaying_text (struct glyph_matrix *matrix, struct it *it,
16832 struct glyph_row *start)
16834 struct glyph_row *row, *row_found;
16836 /* Set row_found to the last row in IT->w's current matrix
16837 displaying text. The loop looks funny but think of partially
16838 visible lines. */
16839 row_found = NULL;
16840 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
16841 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16843 eassert (row->enabled_p);
16844 row_found = row;
16845 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
16846 break;
16847 ++row;
16850 return row_found;
16854 /* Return the last row in the current matrix of W that is not affected
16855 by changes at the start of current_buffer that occurred since W's
16856 current matrix was built. Value is null if no such row exists.
16858 BEG_UNCHANGED us the number of characters unchanged at the start of
16859 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
16860 first changed character in current_buffer. Characters at positions <
16861 BEG + BEG_UNCHANGED are at the same buffer positions as they were
16862 when the current matrix was built. */
16864 static struct glyph_row *
16865 find_last_unchanged_at_beg_row (struct window *w)
16867 ptrdiff_t first_changed_pos = BEG + BEG_UNCHANGED;
16868 struct glyph_row *row;
16869 struct glyph_row *row_found = NULL;
16870 int yb = window_text_bottom_y (w);
16872 /* Find the last row displaying unchanged text. */
16873 for (row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16874 MATRIX_ROW_DISPLAYS_TEXT_P (row)
16875 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos;
16876 ++row)
16878 if (/* If row ends before first_changed_pos, it is unchanged,
16879 except in some case. */
16880 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
16881 /* When row ends in ZV and we write at ZV it is not
16882 unchanged. */
16883 && !row->ends_at_zv_p
16884 /* When first_changed_pos is the end of a continued line,
16885 row is not unchanged because it may be no longer
16886 continued. */
16887 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
16888 && (row->continued_p
16889 || row->exact_window_width_line_p))
16890 /* If ROW->end is beyond ZV, then ROW->end is outdated and
16891 needs to be recomputed, so don't consider this row as
16892 unchanged. This happens when the last line was
16893 bidi-reordered and was killed immediately before this
16894 redisplay cycle. In that case, ROW->end stores the
16895 buffer position of the first visual-order character of
16896 the killed text, which is now beyond ZV. */
16897 && CHARPOS (row->end.pos) <= ZV)
16898 row_found = row;
16900 /* Stop if last visible row. */
16901 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
16902 break;
16905 return row_found;
16909 /* Find the first glyph row in the current matrix of W that is not
16910 affected by changes at the end of current_buffer since the
16911 time W's current matrix was built.
16913 Return in *DELTA the number of chars by which buffer positions in
16914 unchanged text at the end of current_buffer must be adjusted.
16916 Return in *DELTA_BYTES the corresponding number of bytes.
16918 Value is null if no such row exists, i.e. all rows are affected by
16919 changes. */
16921 static struct glyph_row *
16922 find_first_unchanged_at_end_row (struct window *w,
16923 ptrdiff_t *delta, ptrdiff_t *delta_bytes)
16925 struct glyph_row *row;
16926 struct glyph_row *row_found = NULL;
16928 *delta = *delta_bytes = 0;
16930 /* Display must not have been paused, otherwise the current matrix
16931 is not up to date. */
16932 eassert (w->window_end_valid);
16934 /* A value of window_end_pos >= END_UNCHANGED means that the window
16935 end is in the range of changed text. If so, there is no
16936 unchanged row at the end of W's current matrix. */
16937 if (w->window_end_pos >= END_UNCHANGED)
16938 return NULL;
16940 /* Set row to the last row in W's current matrix displaying text. */
16941 row = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
16943 /* If matrix is entirely empty, no unchanged row exists. */
16944 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16946 /* The value of row is the last glyph row in the matrix having a
16947 meaningful buffer position in it. The end position of row
16948 corresponds to window_end_pos. This allows us to translate
16949 buffer positions in the current matrix to current buffer
16950 positions for characters not in changed text. */
16951 ptrdiff_t Z_old =
16952 MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos;
16953 ptrdiff_t Z_BYTE_old =
16954 MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
16955 ptrdiff_t last_unchanged_pos, last_unchanged_pos_old;
16956 struct glyph_row *first_text_row
16957 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16959 *delta = Z - Z_old;
16960 *delta_bytes = Z_BYTE - Z_BYTE_old;
16962 /* Set last_unchanged_pos to the buffer position of the last
16963 character in the buffer that has not been changed. Z is the
16964 index + 1 of the last character in current_buffer, i.e. by
16965 subtracting END_UNCHANGED we get the index of the last
16966 unchanged character, and we have to add BEG to get its buffer
16967 position. */
16968 last_unchanged_pos = Z - END_UNCHANGED + BEG;
16969 last_unchanged_pos_old = last_unchanged_pos - *delta;
16971 /* Search backward from ROW for a row displaying a line that
16972 starts at a minimum position >= last_unchanged_pos_old. */
16973 for (; row > first_text_row; --row)
16975 /* This used to abort, but it can happen.
16976 It is ok to just stop the search instead here. KFS. */
16977 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
16978 break;
16980 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
16981 row_found = row;
16985 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
16987 return row_found;
16991 /* Make sure that glyph rows in the current matrix of window W
16992 reference the same glyph memory as corresponding rows in the
16993 frame's frame matrix. This function is called after scrolling W's
16994 current matrix on a terminal frame in try_window_id and
16995 try_window_reusing_current_matrix. */
16997 static void
16998 sync_frame_with_window_matrix_rows (struct window *w)
17000 struct frame *f = XFRAME (w->frame);
17001 struct glyph_row *window_row, *window_row_end, *frame_row;
17003 /* Preconditions: W must be a leaf window and full-width. Its frame
17004 must have a frame matrix. */
17005 eassert (BUFFERP (w->contents));
17006 eassert (WINDOW_FULL_WIDTH_P (w));
17007 eassert (!FRAME_WINDOW_P (f));
17009 /* If W is a full-width window, glyph pointers in W's current matrix
17010 have, by definition, to be the same as glyph pointers in the
17011 corresponding frame matrix. Note that frame matrices have no
17012 marginal areas (see build_frame_matrix). */
17013 window_row = w->current_matrix->rows;
17014 window_row_end = window_row + w->current_matrix->nrows;
17015 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
17016 while (window_row < window_row_end)
17018 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
17019 struct glyph *end = window_row->glyphs[LAST_AREA];
17021 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
17022 frame_row->glyphs[TEXT_AREA] = start;
17023 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
17024 frame_row->glyphs[LAST_AREA] = end;
17026 /* Disable frame rows whose corresponding window rows have
17027 been disabled in try_window_id. */
17028 if (!window_row->enabled_p)
17029 frame_row->enabled_p = 0;
17031 ++window_row, ++frame_row;
17036 /* Find the glyph row in window W containing CHARPOS. Consider all
17037 rows between START and END (not inclusive). END null means search
17038 all rows to the end of the display area of W. Value is the row
17039 containing CHARPOS or null. */
17041 struct glyph_row *
17042 row_containing_pos (struct window *w, ptrdiff_t charpos,
17043 struct glyph_row *start, struct glyph_row *end, int dy)
17045 struct glyph_row *row = start;
17046 struct glyph_row *best_row = NULL;
17047 ptrdiff_t mindif = BUF_ZV (XBUFFER (w->contents)) + 1;
17048 int last_y;
17050 /* If we happen to start on a header-line, skip that. */
17051 if (row->mode_line_p)
17052 ++row;
17054 if ((end && row >= end) || !row->enabled_p)
17055 return NULL;
17057 last_y = window_text_bottom_y (w) - dy;
17059 while (1)
17061 /* Give up if we have gone too far. */
17062 if (end && row >= end)
17063 return NULL;
17064 /* This formerly returned if they were equal.
17065 I think that both quantities are of a "last plus one" type;
17066 if so, when they are equal, the row is within the screen. -- rms. */
17067 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
17068 return NULL;
17070 /* If it is in this row, return this row. */
17071 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
17072 || (MATRIX_ROW_END_CHARPOS (row) == charpos
17073 /* The end position of a row equals the start
17074 position of the next row. If CHARPOS is there, we
17075 would rather consider it displayed in the next
17076 line, except when this line ends in ZV. */
17077 && !row_for_charpos_p (row, charpos)))
17078 && charpos >= MATRIX_ROW_START_CHARPOS (row))
17080 struct glyph *g;
17082 if (NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
17083 || (!best_row && !row->continued_p))
17084 return row;
17085 /* In bidi-reordered rows, there could be several rows whose
17086 edges surround CHARPOS, all of these rows belonging to
17087 the same continued line. We need to find the row which
17088 fits CHARPOS the best. */
17089 for (g = row->glyphs[TEXT_AREA];
17090 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
17091 g++)
17093 if (!STRINGP (g->object))
17095 if (g->charpos > 0 && eabs (g->charpos - charpos) < mindif)
17097 mindif = eabs (g->charpos - charpos);
17098 best_row = row;
17099 /* Exact match always wins. */
17100 if (mindif == 0)
17101 return best_row;
17106 else if (best_row && !row->continued_p)
17107 return best_row;
17108 ++row;
17113 /* Try to redisplay window W by reusing its existing display. W's
17114 current matrix must be up to date when this function is called,
17115 i.e. window_end_valid must be nonzero.
17117 Value is
17119 1 if display has been updated
17120 0 if otherwise unsuccessful
17121 -1 if redisplay with same window start is known not to succeed
17123 The following steps are performed:
17125 1. Find the last row in the current matrix of W that is not
17126 affected by changes at the start of current_buffer. If no such row
17127 is found, give up.
17129 2. Find the first row in W's current matrix that is not affected by
17130 changes at the end of current_buffer. Maybe there is no such row.
17132 3. Display lines beginning with the row + 1 found in step 1 to the
17133 row found in step 2 or, if step 2 didn't find a row, to the end of
17134 the window.
17136 4. If cursor is not known to appear on the window, give up.
17138 5. If display stopped at the row found in step 2, scroll the
17139 display and current matrix as needed.
17141 6. Maybe display some lines at the end of W, if we must. This can
17142 happen under various circumstances, like a partially visible line
17143 becoming fully visible, or because newly displayed lines are displayed
17144 in smaller font sizes.
17146 7. Update W's window end information. */
17148 static int
17149 try_window_id (struct window *w)
17151 struct frame *f = XFRAME (w->frame);
17152 struct glyph_matrix *current_matrix = w->current_matrix;
17153 struct glyph_matrix *desired_matrix = w->desired_matrix;
17154 struct glyph_row *last_unchanged_at_beg_row;
17155 struct glyph_row *first_unchanged_at_end_row;
17156 struct glyph_row *row;
17157 struct glyph_row *bottom_row;
17158 int bottom_vpos;
17159 struct it it;
17160 ptrdiff_t delta = 0, delta_bytes = 0, stop_pos;
17161 int dvpos, dy;
17162 struct text_pos start_pos;
17163 struct run run;
17164 int first_unchanged_at_end_vpos = 0;
17165 struct glyph_row *last_text_row, *last_text_row_at_end;
17166 struct text_pos start;
17167 ptrdiff_t first_changed_charpos, last_changed_charpos;
17169 #ifdef GLYPH_DEBUG
17170 if (inhibit_try_window_id)
17171 return 0;
17172 #endif
17174 /* This is handy for debugging. */
17175 #if 0
17176 #define GIVE_UP(X) \
17177 do { \
17178 fprintf (stderr, "try_window_id give up %d\n", (X)); \
17179 return 0; \
17180 } while (0)
17181 #else
17182 #define GIVE_UP(X) return 0
17183 #endif
17185 SET_TEXT_POS_FROM_MARKER (start, w->start);
17187 /* Don't use this for mini-windows because these can show
17188 messages and mini-buffers, and we don't handle that here. */
17189 if (MINI_WINDOW_P (w))
17190 GIVE_UP (1);
17192 /* This flag is used to prevent redisplay optimizations. */
17193 if (windows_or_buffers_changed || cursor_type_changed)
17194 GIVE_UP (2);
17196 /* Verify that narrowing has not changed.
17197 Also verify that we were not told to prevent redisplay optimizations.
17198 It would be nice to further
17199 reduce the number of cases where this prevents try_window_id. */
17200 if (current_buffer->clip_changed
17201 || current_buffer->prevent_redisplay_optimizations_p)
17202 GIVE_UP (3);
17204 /* Window must either use window-based redisplay or be full width. */
17205 if (!FRAME_WINDOW_P (f)
17206 && (!FRAME_LINE_INS_DEL_OK (f)
17207 || !WINDOW_FULL_WIDTH_P (w)))
17208 GIVE_UP (4);
17210 /* Give up if point is known NOT to appear in W. */
17211 if (PT < CHARPOS (start))
17212 GIVE_UP (5);
17214 /* Another way to prevent redisplay optimizations. */
17215 if (w->last_modified == 0)
17216 GIVE_UP (6);
17218 /* Verify that window is not hscrolled. */
17219 if (w->hscroll != 0)
17220 GIVE_UP (7);
17222 /* Verify that display wasn't paused. */
17223 if (!w->window_end_valid)
17224 GIVE_UP (8);
17226 /* Can't use this if highlighting a region because a cursor movement
17227 will do more than just set the cursor. */
17228 if (markpos_of_region () >= 0)
17229 GIVE_UP (9);
17231 /* Likewise if highlighting trailing whitespace. */
17232 if (!NILP (Vshow_trailing_whitespace))
17233 GIVE_UP (11);
17235 /* Likewise if showing a region. */
17236 if (w->region_showing)
17237 GIVE_UP (10);
17239 /* Can't use this if overlay arrow position and/or string have
17240 changed. */
17241 if (overlay_arrows_changed_p ())
17242 GIVE_UP (12);
17244 /* When word-wrap is on, adding a space to the first word of a
17245 wrapped line can change the wrap position, altering the line
17246 above it. It might be worthwhile to handle this more
17247 intelligently, but for now just redisplay from scratch. */
17248 if (!NILP (BVAR (XBUFFER (w->contents), word_wrap)))
17249 GIVE_UP (21);
17251 /* Under bidi reordering, adding or deleting a character in the
17252 beginning of a paragraph, before the first strong directional
17253 character, can change the base direction of the paragraph (unless
17254 the buffer specifies a fixed paragraph direction), which will
17255 require to redisplay the whole paragraph. It might be worthwhile
17256 to find the paragraph limits and widen the range of redisplayed
17257 lines to that, but for now just give up this optimization and
17258 redisplay from scratch. */
17259 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
17260 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
17261 GIVE_UP (22);
17263 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
17264 only if buffer has really changed. The reason is that the gap is
17265 initially at Z for freshly visited files. The code below would
17266 set end_unchanged to 0 in that case. */
17267 if (MODIFF > SAVE_MODIFF
17268 /* This seems to happen sometimes after saving a buffer. */
17269 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
17271 if (GPT - BEG < BEG_UNCHANGED)
17272 BEG_UNCHANGED = GPT - BEG;
17273 if (Z - GPT < END_UNCHANGED)
17274 END_UNCHANGED = Z - GPT;
17277 /* The position of the first and last character that has been changed. */
17278 first_changed_charpos = BEG + BEG_UNCHANGED;
17279 last_changed_charpos = Z - END_UNCHANGED;
17281 /* If window starts after a line end, and the last change is in
17282 front of that newline, then changes don't affect the display.
17283 This case happens with stealth-fontification. Note that although
17284 the display is unchanged, glyph positions in the matrix have to
17285 be adjusted, of course. */
17286 row = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
17287 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
17288 && ((last_changed_charpos < CHARPOS (start)
17289 && CHARPOS (start) == BEGV)
17290 || (last_changed_charpos < CHARPOS (start) - 1
17291 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
17293 ptrdiff_t Z_old, Z_delta, Z_BYTE_old, Z_delta_bytes;
17294 struct glyph_row *r0;
17296 /* Compute how many chars/bytes have been added to or removed
17297 from the buffer. */
17298 Z_old = MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos;
17299 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
17300 Z_delta = Z - Z_old;
17301 Z_delta_bytes = Z_BYTE - Z_BYTE_old;
17303 /* Give up if PT is not in the window. Note that it already has
17304 been checked at the start of try_window_id that PT is not in
17305 front of the window start. */
17306 if (PT >= MATRIX_ROW_END_CHARPOS (row) + Z_delta)
17307 GIVE_UP (13);
17309 /* If window start is unchanged, we can reuse the whole matrix
17310 as is, after adjusting glyph positions. No need to compute
17311 the window end again, since its offset from Z hasn't changed. */
17312 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
17313 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + Z_delta
17314 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + Z_delta_bytes
17315 /* PT must not be in a partially visible line. */
17316 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + Z_delta
17317 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
17319 /* Adjust positions in the glyph matrix. */
17320 if (Z_delta || Z_delta_bytes)
17322 struct glyph_row *r1
17323 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
17324 increment_matrix_positions (w->current_matrix,
17325 MATRIX_ROW_VPOS (r0, current_matrix),
17326 MATRIX_ROW_VPOS (r1, current_matrix),
17327 Z_delta, Z_delta_bytes);
17330 /* Set the cursor. */
17331 row = row_containing_pos (w, PT, r0, NULL, 0);
17332 if (row)
17333 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
17334 else
17335 emacs_abort ();
17336 return 1;
17340 /* Handle the case that changes are all below what is displayed in
17341 the window, and that PT is in the window. This shortcut cannot
17342 be taken if ZV is visible in the window, and text has been added
17343 there that is visible in the window. */
17344 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
17345 /* ZV is not visible in the window, or there are no
17346 changes at ZV, actually. */
17347 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
17348 || first_changed_charpos == last_changed_charpos))
17350 struct glyph_row *r0;
17352 /* Give up if PT is not in the window. Note that it already has
17353 been checked at the start of try_window_id that PT is not in
17354 front of the window start. */
17355 if (PT >= MATRIX_ROW_END_CHARPOS (row))
17356 GIVE_UP (14);
17358 /* If window start is unchanged, we can reuse the whole matrix
17359 as is, without changing glyph positions since no text has
17360 been added/removed in front of the window end. */
17361 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
17362 if (TEXT_POS_EQUAL_P (start, r0->minpos)
17363 /* PT must not be in a partially visible line. */
17364 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
17365 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
17367 /* We have to compute the window end anew since text
17368 could have been added/removed after it. */
17369 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
17370 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17372 /* Set the cursor. */
17373 row = row_containing_pos (w, PT, r0, NULL, 0);
17374 if (row)
17375 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
17376 else
17377 emacs_abort ();
17378 return 2;
17382 /* Give up if window start is in the changed area.
17384 The condition used to read
17386 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
17388 but why that was tested escapes me at the moment. */
17389 if (CHARPOS (start) >= first_changed_charpos
17390 && CHARPOS (start) <= last_changed_charpos)
17391 GIVE_UP (15);
17393 /* Check that window start agrees with the start of the first glyph
17394 row in its current matrix. Check this after we know the window
17395 start is not in changed text, otherwise positions would not be
17396 comparable. */
17397 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
17398 if (!TEXT_POS_EQUAL_P (start, row->minpos))
17399 GIVE_UP (16);
17401 /* Give up if the window ends in strings. Overlay strings
17402 at the end are difficult to handle, so don't try. */
17403 row = MATRIX_ROW (current_matrix, w->window_end_vpos);
17404 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
17405 GIVE_UP (20);
17407 /* Compute the position at which we have to start displaying new
17408 lines. Some of the lines at the top of the window might be
17409 reusable because they are not displaying changed text. Find the
17410 last row in W's current matrix not affected by changes at the
17411 start of current_buffer. Value is null if changes start in the
17412 first line of window. */
17413 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
17414 if (last_unchanged_at_beg_row)
17416 /* Avoid starting to display in the middle of a character, a TAB
17417 for instance. This is easier than to set up the iterator
17418 exactly, and it's not a frequent case, so the additional
17419 effort wouldn't really pay off. */
17420 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
17421 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
17422 && last_unchanged_at_beg_row > w->current_matrix->rows)
17423 --last_unchanged_at_beg_row;
17425 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
17426 GIVE_UP (17);
17428 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
17429 GIVE_UP (18);
17430 start_pos = it.current.pos;
17432 /* Start displaying new lines in the desired matrix at the same
17433 vpos we would use in the current matrix, i.e. below
17434 last_unchanged_at_beg_row. */
17435 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
17436 current_matrix);
17437 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
17438 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
17440 eassert (it.hpos == 0 && it.current_x == 0);
17442 else
17444 /* There are no reusable lines at the start of the window.
17445 Start displaying in the first text line. */
17446 start_display (&it, w, start);
17447 it.vpos = it.first_vpos;
17448 start_pos = it.current.pos;
17451 /* Find the first row that is not affected by changes at the end of
17452 the buffer. Value will be null if there is no unchanged row, in
17453 which case we must redisplay to the end of the window. delta
17454 will be set to the value by which buffer positions beginning with
17455 first_unchanged_at_end_row have to be adjusted due to text
17456 changes. */
17457 first_unchanged_at_end_row
17458 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
17459 IF_DEBUG (debug_delta = delta);
17460 IF_DEBUG (debug_delta_bytes = delta_bytes);
17462 /* Set stop_pos to the buffer position up to which we will have to
17463 display new lines. If first_unchanged_at_end_row != NULL, this
17464 is the buffer position of the start of the line displayed in that
17465 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
17466 that we don't stop at a buffer position. */
17467 stop_pos = 0;
17468 if (first_unchanged_at_end_row)
17470 eassert (last_unchanged_at_beg_row == NULL
17471 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
17473 /* If this is a continuation line, move forward to the next one
17474 that isn't. Changes in lines above affect this line.
17475 Caution: this may move first_unchanged_at_end_row to a row
17476 not displaying text. */
17477 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
17478 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
17479 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
17480 < it.last_visible_y))
17481 ++first_unchanged_at_end_row;
17483 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
17484 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
17485 >= it.last_visible_y))
17486 first_unchanged_at_end_row = NULL;
17487 else
17489 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
17490 + delta);
17491 first_unchanged_at_end_vpos
17492 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
17493 eassert (stop_pos >= Z - END_UNCHANGED);
17496 else if (last_unchanged_at_beg_row == NULL)
17497 GIVE_UP (19);
17500 #ifdef GLYPH_DEBUG
17502 /* Either there is no unchanged row at the end, or the one we have
17503 now displays text. This is a necessary condition for the window
17504 end pos calculation at the end of this function. */
17505 eassert (first_unchanged_at_end_row == NULL
17506 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
17508 debug_last_unchanged_at_beg_vpos
17509 = (last_unchanged_at_beg_row
17510 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
17511 : -1);
17512 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
17514 #endif /* GLYPH_DEBUG */
17517 /* Display new lines. Set last_text_row to the last new line
17518 displayed which has text on it, i.e. might end up as being the
17519 line where the window_end_vpos is. */
17520 w->cursor.vpos = -1;
17521 last_text_row = NULL;
17522 overlay_arrow_seen = 0;
17523 while (it.current_y < it.last_visible_y
17524 && !fonts_changed_p
17525 && (first_unchanged_at_end_row == NULL
17526 || IT_CHARPOS (it) < stop_pos))
17528 if (display_line (&it))
17529 last_text_row = it.glyph_row - 1;
17532 if (fonts_changed_p)
17533 return -1;
17536 /* Compute differences in buffer positions, y-positions etc. for
17537 lines reused at the bottom of the window. Compute what we can
17538 scroll. */
17539 if (first_unchanged_at_end_row
17540 /* No lines reused because we displayed everything up to the
17541 bottom of the window. */
17542 && it.current_y < it.last_visible_y)
17544 dvpos = (it.vpos
17545 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
17546 current_matrix));
17547 dy = it.current_y - first_unchanged_at_end_row->y;
17548 run.current_y = first_unchanged_at_end_row->y;
17549 run.desired_y = run.current_y + dy;
17550 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
17552 else
17554 delta = delta_bytes = dvpos = dy
17555 = run.current_y = run.desired_y = run.height = 0;
17556 first_unchanged_at_end_row = NULL;
17558 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
17561 /* Find the cursor if not already found. We have to decide whether
17562 PT will appear on this window (it sometimes doesn't, but this is
17563 not a very frequent case.) This decision has to be made before
17564 the current matrix is altered. A value of cursor.vpos < 0 means
17565 that PT is either in one of the lines beginning at
17566 first_unchanged_at_end_row or below the window. Don't care for
17567 lines that might be displayed later at the window end; as
17568 mentioned, this is not a frequent case. */
17569 if (w->cursor.vpos < 0)
17571 /* Cursor in unchanged rows at the top? */
17572 if (PT < CHARPOS (start_pos)
17573 && last_unchanged_at_beg_row)
17575 row = row_containing_pos (w, PT,
17576 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
17577 last_unchanged_at_beg_row + 1, 0);
17578 if (row)
17579 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
17582 /* Start from first_unchanged_at_end_row looking for PT. */
17583 else if (first_unchanged_at_end_row)
17585 row = row_containing_pos (w, PT - delta,
17586 first_unchanged_at_end_row, NULL, 0);
17587 if (row)
17588 set_cursor_from_row (w, row, w->current_matrix, delta,
17589 delta_bytes, dy, dvpos);
17592 /* Give up if cursor was not found. */
17593 if (w->cursor.vpos < 0)
17595 clear_glyph_matrix (w->desired_matrix);
17596 return -1;
17600 /* Don't let the cursor end in the scroll margins. */
17602 int this_scroll_margin, cursor_height;
17603 int frame_line_height = default_line_pixel_height (w);
17604 int window_total_lines
17605 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (it.f) / frame_line_height;
17607 this_scroll_margin =
17608 max (0, min (scroll_margin, window_total_lines / 4));
17609 this_scroll_margin *= frame_line_height;
17610 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
17612 if ((w->cursor.y < this_scroll_margin
17613 && CHARPOS (start) > BEGV)
17614 /* Old redisplay didn't take scroll margin into account at the bottom,
17615 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
17616 || (w->cursor.y + (make_cursor_line_fully_visible_p
17617 ? cursor_height + this_scroll_margin
17618 : 1)) > it.last_visible_y)
17620 w->cursor.vpos = -1;
17621 clear_glyph_matrix (w->desired_matrix);
17622 return -1;
17626 /* Scroll the display. Do it before changing the current matrix so
17627 that xterm.c doesn't get confused about where the cursor glyph is
17628 found. */
17629 if (dy && run.height)
17631 update_begin (f);
17633 if (FRAME_WINDOW_P (f))
17635 FRAME_RIF (f)->update_window_begin_hook (w);
17636 FRAME_RIF (f)->clear_window_mouse_face (w);
17637 FRAME_RIF (f)->scroll_run_hook (w, &run);
17638 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
17640 else
17642 /* Terminal frame. In this case, dvpos gives the number of
17643 lines to scroll by; dvpos < 0 means scroll up. */
17644 int from_vpos
17645 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
17646 int from = WINDOW_TOP_EDGE_LINE (w) + from_vpos;
17647 int end = (WINDOW_TOP_EDGE_LINE (w)
17648 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
17649 + window_internal_height (w));
17651 #if defined (HAVE_GPM) || defined (MSDOS)
17652 x_clear_window_mouse_face (w);
17653 #endif
17654 /* Perform the operation on the screen. */
17655 if (dvpos > 0)
17657 /* Scroll last_unchanged_at_beg_row to the end of the
17658 window down dvpos lines. */
17659 set_terminal_window (f, end);
17661 /* On dumb terminals delete dvpos lines at the end
17662 before inserting dvpos empty lines. */
17663 if (!FRAME_SCROLL_REGION_OK (f))
17664 ins_del_lines (f, end - dvpos, -dvpos);
17666 /* Insert dvpos empty lines in front of
17667 last_unchanged_at_beg_row. */
17668 ins_del_lines (f, from, dvpos);
17670 else if (dvpos < 0)
17672 /* Scroll up last_unchanged_at_beg_vpos to the end of
17673 the window to last_unchanged_at_beg_vpos - |dvpos|. */
17674 set_terminal_window (f, end);
17676 /* Delete dvpos lines in front of
17677 last_unchanged_at_beg_vpos. ins_del_lines will set
17678 the cursor to the given vpos and emit |dvpos| delete
17679 line sequences. */
17680 ins_del_lines (f, from + dvpos, dvpos);
17682 /* On a dumb terminal insert dvpos empty lines at the
17683 end. */
17684 if (!FRAME_SCROLL_REGION_OK (f))
17685 ins_del_lines (f, end + dvpos, -dvpos);
17688 set_terminal_window (f, 0);
17691 update_end (f);
17694 /* Shift reused rows of the current matrix to the right position.
17695 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
17696 text. */
17697 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
17698 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
17699 if (dvpos < 0)
17701 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
17702 bottom_vpos, dvpos);
17703 clear_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
17704 bottom_vpos);
17706 else if (dvpos > 0)
17708 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
17709 bottom_vpos, dvpos);
17710 clear_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
17711 first_unchanged_at_end_vpos + dvpos);
17714 /* For frame-based redisplay, make sure that current frame and window
17715 matrix are in sync with respect to glyph memory. */
17716 if (!FRAME_WINDOW_P (f))
17717 sync_frame_with_window_matrix_rows (w);
17719 /* Adjust buffer positions in reused rows. */
17720 if (delta || delta_bytes)
17721 increment_matrix_positions (current_matrix,
17722 first_unchanged_at_end_vpos + dvpos,
17723 bottom_vpos, delta, delta_bytes);
17725 /* Adjust Y positions. */
17726 if (dy)
17727 shift_glyph_matrix (w, current_matrix,
17728 first_unchanged_at_end_vpos + dvpos,
17729 bottom_vpos, dy);
17731 if (first_unchanged_at_end_row)
17733 first_unchanged_at_end_row += dvpos;
17734 if (first_unchanged_at_end_row->y >= it.last_visible_y
17735 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
17736 first_unchanged_at_end_row = NULL;
17739 /* If scrolling up, there may be some lines to display at the end of
17740 the window. */
17741 last_text_row_at_end = NULL;
17742 if (dy < 0)
17744 /* Scrolling up can leave for example a partially visible line
17745 at the end of the window to be redisplayed. */
17746 /* Set last_row to the glyph row in the current matrix where the
17747 window end line is found. It has been moved up or down in
17748 the matrix by dvpos. */
17749 int last_vpos = w->window_end_vpos + dvpos;
17750 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
17752 /* If last_row is the window end line, it should display text. */
17753 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_row));
17755 /* If window end line was partially visible before, begin
17756 displaying at that line. Otherwise begin displaying with the
17757 line following it. */
17758 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
17760 init_to_row_start (&it, w, last_row);
17761 it.vpos = last_vpos;
17762 it.current_y = last_row->y;
17764 else
17766 init_to_row_end (&it, w, last_row);
17767 it.vpos = 1 + last_vpos;
17768 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
17769 ++last_row;
17772 /* We may start in a continuation line. If so, we have to
17773 get the right continuation_lines_width and current_x. */
17774 it.continuation_lines_width = last_row->continuation_lines_width;
17775 it.hpos = it.current_x = 0;
17777 /* Display the rest of the lines at the window end. */
17778 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
17779 while (it.current_y < it.last_visible_y
17780 && !fonts_changed_p)
17782 /* Is it always sure that the display agrees with lines in
17783 the current matrix? I don't think so, so we mark rows
17784 displayed invalid in the current matrix by setting their
17785 enabled_p flag to zero. */
17786 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
17787 if (display_line (&it))
17788 last_text_row_at_end = it.glyph_row - 1;
17792 /* Update window_end_pos and window_end_vpos. */
17793 if (first_unchanged_at_end_row && !last_text_row_at_end)
17795 /* Window end line if one of the preserved rows from the current
17796 matrix. Set row to the last row displaying text in current
17797 matrix starting at first_unchanged_at_end_row, after
17798 scrolling. */
17799 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
17800 row = find_last_row_displaying_text (w->current_matrix, &it,
17801 first_unchanged_at_end_row);
17802 eassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
17803 adjust_window_ends (w, row, 1);
17804 eassert (w->window_end_bytepos >= 0);
17805 IF_DEBUG (debug_method_add (w, "A"));
17807 else if (last_text_row_at_end)
17809 adjust_window_ends (w, last_text_row_at_end, 0);
17810 eassert (w->window_end_bytepos >= 0);
17811 IF_DEBUG (debug_method_add (w, "B"));
17813 else if (last_text_row)
17815 /* We have displayed either to the end of the window or at the
17816 end of the window, i.e. the last row with text is to be found
17817 in the desired matrix. */
17818 adjust_window_ends (w, last_text_row, 0);
17819 eassert (w->window_end_bytepos >= 0);
17821 else if (first_unchanged_at_end_row == NULL
17822 && last_text_row == NULL
17823 && last_text_row_at_end == NULL)
17825 /* Displayed to end of window, but no line containing text was
17826 displayed. Lines were deleted at the end of the window. */
17827 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
17828 int vpos = w->window_end_vpos;
17829 struct glyph_row *current_row = current_matrix->rows + vpos;
17830 struct glyph_row *desired_row = desired_matrix->rows + vpos;
17832 for (row = NULL;
17833 row == NULL && vpos >= first_vpos;
17834 --vpos, --current_row, --desired_row)
17836 if (desired_row->enabled_p)
17838 if (MATRIX_ROW_DISPLAYS_TEXT_P (desired_row))
17839 row = desired_row;
17841 else if (MATRIX_ROW_DISPLAYS_TEXT_P (current_row))
17842 row = current_row;
17845 eassert (row != NULL);
17846 w->window_end_vpos = vpos + 1;
17847 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
17848 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17849 eassert (w->window_end_bytepos >= 0);
17850 IF_DEBUG (debug_method_add (w, "C"));
17852 else
17853 emacs_abort ();
17855 IF_DEBUG (debug_end_pos = w->window_end_pos;
17856 debug_end_vpos = w->window_end_vpos);
17858 /* Record that display has not been completed. */
17859 w->window_end_valid = 0;
17860 w->desired_matrix->no_scrolling_p = 1;
17861 return 3;
17863 #undef GIVE_UP
17868 /***********************************************************************
17869 More debugging support
17870 ***********************************************************************/
17872 #ifdef GLYPH_DEBUG
17874 void dump_glyph_row (struct glyph_row *, int, int) EXTERNALLY_VISIBLE;
17875 void dump_glyph_matrix (struct glyph_matrix *, int) EXTERNALLY_VISIBLE;
17876 void dump_glyph (struct glyph_row *, struct glyph *, int) EXTERNALLY_VISIBLE;
17879 /* Dump the contents of glyph matrix MATRIX on stderr.
17881 GLYPHS 0 means don't show glyph contents.
17882 GLYPHS 1 means show glyphs in short form
17883 GLYPHS > 1 means show glyphs in long form. */
17885 void
17886 dump_glyph_matrix (struct glyph_matrix *matrix, int glyphs)
17888 int i;
17889 for (i = 0; i < matrix->nrows; ++i)
17890 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
17894 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
17895 the glyph row and area where the glyph comes from. */
17897 void
17898 dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
17900 if (glyph->type == CHAR_GLYPH
17901 || glyph->type == GLYPHLESS_GLYPH)
17903 fprintf (stderr,
17904 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
17905 glyph - row->glyphs[TEXT_AREA],
17906 (glyph->type == CHAR_GLYPH
17907 ? 'C'
17908 : 'G'),
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.ch,
17919 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
17920 ? glyph->u.ch
17921 : '.'),
17922 glyph->face_id,
17923 glyph->left_box_line_p,
17924 glyph->right_box_line_p);
17926 else if (glyph->type == STRETCH_GLYPH)
17928 fprintf (stderr,
17929 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
17930 glyph - row->glyphs[TEXT_AREA],
17931 'S',
17932 glyph->charpos,
17933 (BUFFERP (glyph->object)
17934 ? 'B'
17935 : (STRINGP (glyph->object)
17936 ? 'S'
17937 : (INTEGERP (glyph->object)
17938 ? '0'
17939 : '-'))),
17940 glyph->pixel_width,
17942 ' ',
17943 glyph->face_id,
17944 glyph->left_box_line_p,
17945 glyph->right_box_line_p);
17947 else if (glyph->type == IMAGE_GLYPH)
17949 fprintf (stderr,
17950 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
17951 glyph - row->glyphs[TEXT_AREA],
17952 'I',
17953 glyph->charpos,
17954 (BUFFERP (glyph->object)
17955 ? 'B'
17956 : (STRINGP (glyph->object)
17957 ? 'S'
17958 : (INTEGERP (glyph->object)
17959 ? '0'
17960 : '-'))),
17961 glyph->pixel_width,
17962 glyph->u.img_id,
17963 '.',
17964 glyph->face_id,
17965 glyph->left_box_line_p,
17966 glyph->right_box_line_p);
17968 else if (glyph->type == COMPOSITE_GLYPH)
17970 fprintf (stderr,
17971 " %5"pD"d %c %9"pI"d %c %3d 0x%06x",
17972 glyph - row->glyphs[TEXT_AREA],
17973 '+',
17974 glyph->charpos,
17975 (BUFFERP (glyph->object)
17976 ? 'B'
17977 : (STRINGP (glyph->object)
17978 ? 'S'
17979 : (INTEGERP (glyph->object)
17980 ? '0'
17981 : '-'))),
17982 glyph->pixel_width,
17983 glyph->u.cmp.id);
17984 if (glyph->u.cmp.automatic)
17985 fprintf (stderr,
17986 "[%d-%d]",
17987 glyph->slice.cmp.from, glyph->slice.cmp.to);
17988 fprintf (stderr, " . %4d %1.1d%1.1d\n",
17989 glyph->face_id,
17990 glyph->left_box_line_p,
17991 glyph->right_box_line_p);
17996 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
17997 GLYPHS 0 means don't show glyph contents.
17998 GLYPHS 1 means show glyphs in short form
17999 GLYPHS > 1 means show glyphs in long form. */
18001 void
18002 dump_glyph_row (struct glyph_row *row, int vpos, int glyphs)
18004 if (glyphs != 1)
18006 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
18007 fprintf (stderr, "==============================================================================\n");
18009 fprintf (stderr, "%3d %9"pI"d %9"pI"d %4d %1.1d%1.1d%1.1d%1.1d\
18010 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
18011 vpos,
18012 MATRIX_ROW_START_CHARPOS (row),
18013 MATRIX_ROW_END_CHARPOS (row),
18014 row->used[TEXT_AREA],
18015 row->contains_overlapping_glyphs_p,
18016 row->enabled_p,
18017 row->truncated_on_left_p,
18018 row->truncated_on_right_p,
18019 row->continued_p,
18020 MATRIX_ROW_CONTINUATION_LINE_P (row),
18021 MATRIX_ROW_DISPLAYS_TEXT_P (row),
18022 row->ends_at_zv_p,
18023 row->fill_line_p,
18024 row->ends_in_middle_of_char_p,
18025 row->starts_in_middle_of_char_p,
18026 row->mouse_face_p,
18027 row->x,
18028 row->y,
18029 row->pixel_width,
18030 row->height,
18031 row->visible_height,
18032 row->ascent,
18033 row->phys_ascent);
18034 /* The next 3 lines should align to "Start" in the header. */
18035 fprintf (stderr, " %9"pD"d %9"pD"d\t%5d\n", row->start.overlay_string_index,
18036 row->end.overlay_string_index,
18037 row->continuation_lines_width);
18038 fprintf (stderr, " %9"pI"d %9"pI"d\n",
18039 CHARPOS (row->start.string_pos),
18040 CHARPOS (row->end.string_pos));
18041 fprintf (stderr, " %9d %9d\n", row->start.dpvec_index,
18042 row->end.dpvec_index);
18045 if (glyphs > 1)
18047 int area;
18049 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18051 struct glyph *glyph = row->glyphs[area];
18052 struct glyph *glyph_end = glyph + row->used[area];
18054 /* Glyph for a line end in text. */
18055 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
18056 ++glyph_end;
18058 if (glyph < glyph_end)
18059 fprintf (stderr, " Glyph# Type Pos O W Code C Face LR\n");
18061 for (; glyph < glyph_end; ++glyph)
18062 dump_glyph (row, glyph, area);
18065 else if (glyphs == 1)
18067 int area;
18069 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18071 char *s = alloca (row->used[area] + 4);
18072 int i;
18074 for (i = 0; i < row->used[area]; ++i)
18076 struct glyph *glyph = row->glyphs[area] + i;
18077 if (i == row->used[area] - 1
18078 && area == TEXT_AREA
18079 && INTEGERP (glyph->object)
18080 && glyph->type == CHAR_GLYPH
18081 && glyph->u.ch == ' ')
18083 strcpy (&s[i], "[\\n]");
18084 i += 4;
18086 else if (glyph->type == CHAR_GLYPH
18087 && glyph->u.ch < 0x80
18088 && glyph->u.ch >= ' ')
18089 s[i] = glyph->u.ch;
18090 else
18091 s[i] = '.';
18094 s[i] = '\0';
18095 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
18101 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
18102 Sdump_glyph_matrix, 0, 1, "p",
18103 doc: /* Dump the current matrix of the selected window to stderr.
18104 Shows contents of glyph row structures. With non-nil
18105 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
18106 glyphs in short form, otherwise show glyphs in long form. */)
18107 (Lisp_Object glyphs)
18109 struct window *w = XWINDOW (selected_window);
18110 struct buffer *buffer = XBUFFER (w->contents);
18112 fprintf (stderr, "PT = %"pI"d, BEGV = %"pI"d. ZV = %"pI"d\n",
18113 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
18114 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
18115 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
18116 fprintf (stderr, "=============================================\n");
18117 dump_glyph_matrix (w->current_matrix,
18118 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 0);
18119 return Qnil;
18123 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
18124 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
18125 (void)
18127 struct frame *f = XFRAME (selected_frame);
18128 dump_glyph_matrix (f->current_matrix, 1);
18129 return Qnil;
18133 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
18134 doc: /* Dump glyph row ROW to stderr.
18135 GLYPH 0 means don't dump glyphs.
18136 GLYPH 1 means dump glyphs in short form.
18137 GLYPH > 1 or omitted means dump glyphs in long form. */)
18138 (Lisp_Object row, Lisp_Object glyphs)
18140 struct glyph_matrix *matrix;
18141 EMACS_INT vpos;
18143 CHECK_NUMBER (row);
18144 matrix = XWINDOW (selected_window)->current_matrix;
18145 vpos = XINT (row);
18146 if (vpos >= 0 && vpos < matrix->nrows)
18147 dump_glyph_row (MATRIX_ROW (matrix, vpos),
18148 vpos,
18149 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
18150 return Qnil;
18154 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
18155 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
18156 GLYPH 0 means don't dump glyphs.
18157 GLYPH 1 means dump glyphs in short form.
18158 GLYPH > 1 or omitted means dump glyphs in long form. */)
18159 (Lisp_Object row, Lisp_Object glyphs)
18161 struct frame *sf = SELECTED_FRAME ();
18162 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
18163 EMACS_INT vpos;
18165 CHECK_NUMBER (row);
18166 vpos = XINT (row);
18167 if (vpos >= 0 && vpos < m->nrows)
18168 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
18169 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
18170 return Qnil;
18174 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
18175 doc: /* Toggle tracing of redisplay.
18176 With ARG, turn tracing on if and only if ARG is positive. */)
18177 (Lisp_Object arg)
18179 if (NILP (arg))
18180 trace_redisplay_p = !trace_redisplay_p;
18181 else
18183 arg = Fprefix_numeric_value (arg);
18184 trace_redisplay_p = XINT (arg) > 0;
18187 return Qnil;
18191 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
18192 doc: /* Like `format', but print result to stderr.
18193 usage: (trace-to-stderr STRING &rest OBJECTS) */)
18194 (ptrdiff_t nargs, Lisp_Object *args)
18196 Lisp_Object s = Fformat (nargs, args);
18197 fprintf (stderr, "%s", SDATA (s));
18198 return Qnil;
18201 #endif /* GLYPH_DEBUG */
18205 /***********************************************************************
18206 Building Desired Matrix Rows
18207 ***********************************************************************/
18209 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
18210 Used for non-window-redisplay windows, and for windows w/o left fringe. */
18212 static struct glyph_row *
18213 get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
18215 struct frame *f = XFRAME (WINDOW_FRAME (w));
18216 struct buffer *buffer = XBUFFER (w->contents);
18217 struct buffer *old = current_buffer;
18218 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
18219 int arrow_len = SCHARS (overlay_arrow_string);
18220 const unsigned char *arrow_end = arrow_string + arrow_len;
18221 const unsigned char *p;
18222 struct it it;
18223 bool multibyte_p;
18224 int n_glyphs_before;
18226 set_buffer_temp (buffer);
18227 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
18228 it.glyph_row->used[TEXT_AREA] = 0;
18229 SET_TEXT_POS (it.position, 0, 0);
18231 multibyte_p = !NILP (BVAR (buffer, enable_multibyte_characters));
18232 p = arrow_string;
18233 while (p < arrow_end)
18235 Lisp_Object face, ilisp;
18237 /* Get the next character. */
18238 if (multibyte_p)
18239 it.c = it.char_to_display = string_char_and_length (p, &it.len);
18240 else
18242 it.c = it.char_to_display = *p, it.len = 1;
18243 if (! ASCII_CHAR_P (it.c))
18244 it.char_to_display = BYTE8_TO_CHAR (it.c);
18246 p += it.len;
18248 /* Get its face. */
18249 ilisp = make_number (p - arrow_string);
18250 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
18251 it.face_id = compute_char_face (f, it.char_to_display, face);
18253 /* Compute its width, get its glyphs. */
18254 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
18255 SET_TEXT_POS (it.position, -1, -1);
18256 PRODUCE_GLYPHS (&it);
18258 /* If this character doesn't fit any more in the line, we have
18259 to remove some glyphs. */
18260 if (it.current_x > it.last_visible_x)
18262 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
18263 break;
18267 set_buffer_temp (old);
18268 return it.glyph_row;
18272 /* Insert truncation glyphs at the start of IT->glyph_row. Which
18273 glyphs to insert is determined by produce_special_glyphs. */
18275 static void
18276 insert_left_trunc_glyphs (struct it *it)
18278 struct it truncate_it;
18279 struct glyph *from, *end, *to, *toend;
18281 eassert (!FRAME_WINDOW_P (it->f)
18282 || (!it->glyph_row->reversed_p
18283 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)
18284 || (it->glyph_row->reversed_p
18285 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0));
18287 /* Get the truncation glyphs. */
18288 truncate_it = *it;
18289 truncate_it.current_x = 0;
18290 truncate_it.face_id = DEFAULT_FACE_ID;
18291 truncate_it.glyph_row = &scratch_glyph_row;
18292 truncate_it.glyph_row->used[TEXT_AREA] = 0;
18293 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
18294 truncate_it.object = make_number (0);
18295 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
18297 /* Overwrite glyphs from IT with truncation glyphs. */
18298 if (!it->glyph_row->reversed_p)
18300 short tused = truncate_it.glyph_row->used[TEXT_AREA];
18302 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
18303 end = from + tused;
18304 to = it->glyph_row->glyphs[TEXT_AREA];
18305 toend = to + it->glyph_row->used[TEXT_AREA];
18306 if (FRAME_WINDOW_P (it->f))
18308 /* On GUI frames, when variable-size fonts are displayed,
18309 the truncation glyphs may need more pixels than the row's
18310 glyphs they overwrite. We overwrite more glyphs to free
18311 enough screen real estate, and enlarge the stretch glyph
18312 on the right (see display_line), if there is one, to
18313 preserve the screen position of the truncation glyphs on
18314 the right. */
18315 int w = 0;
18316 struct glyph *g = to;
18317 short used;
18319 /* The first glyph could be partially visible, in which case
18320 it->glyph_row->x will be negative. But we want the left
18321 truncation glyphs to be aligned at the left margin of the
18322 window, so we override the x coordinate at which the row
18323 will begin. */
18324 it->glyph_row->x = 0;
18325 while (g < toend && w < it->truncation_pixel_width)
18327 w += g->pixel_width;
18328 ++g;
18330 if (g - to - tused > 0)
18332 memmove (to + tused, g, (toend - g) * sizeof(*g));
18333 it->glyph_row->used[TEXT_AREA] -= g - to - tused;
18335 used = it->glyph_row->used[TEXT_AREA];
18336 if (it->glyph_row->truncated_on_right_p
18337 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
18338 && it->glyph_row->glyphs[TEXT_AREA][used - 2].type
18339 == STRETCH_GLYPH)
18341 int extra = w - it->truncation_pixel_width;
18343 it->glyph_row->glyphs[TEXT_AREA][used - 2].pixel_width += extra;
18347 while (from < end)
18348 *to++ = *from++;
18350 /* There may be padding glyphs left over. Overwrite them too. */
18351 if (!FRAME_WINDOW_P (it->f))
18353 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
18355 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
18356 while (from < end)
18357 *to++ = *from++;
18361 if (to > toend)
18362 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
18364 else
18366 short tused = truncate_it.glyph_row->used[TEXT_AREA];
18368 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
18369 that back to front. */
18370 end = truncate_it.glyph_row->glyphs[TEXT_AREA];
18371 from = end + truncate_it.glyph_row->used[TEXT_AREA] - 1;
18372 toend = it->glyph_row->glyphs[TEXT_AREA];
18373 to = toend + it->glyph_row->used[TEXT_AREA] - 1;
18374 if (FRAME_WINDOW_P (it->f))
18376 int w = 0;
18377 struct glyph *g = to;
18379 while (g >= toend && w < it->truncation_pixel_width)
18381 w += g->pixel_width;
18382 --g;
18384 if (to - g - tused > 0)
18385 to = g + tused;
18386 if (it->glyph_row->truncated_on_right_p
18387 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0
18388 && it->glyph_row->glyphs[TEXT_AREA][1].type == STRETCH_GLYPH)
18390 int extra = w - it->truncation_pixel_width;
18392 it->glyph_row->glyphs[TEXT_AREA][1].pixel_width += extra;
18396 while (from >= end && to >= toend)
18397 *to-- = *from--;
18398 if (!FRAME_WINDOW_P (it->f))
18400 while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
18402 from =
18403 truncate_it.glyph_row->glyphs[TEXT_AREA]
18404 + truncate_it.glyph_row->used[TEXT_AREA] - 1;
18405 while (from >= end && to >= toend)
18406 *to-- = *from--;
18409 if (from >= end)
18411 /* Need to free some room before prepending additional
18412 glyphs. */
18413 int move_by = from - end + 1;
18414 struct glyph *g0 = it->glyph_row->glyphs[TEXT_AREA];
18415 struct glyph *g = g0 + it->glyph_row->used[TEXT_AREA] - 1;
18417 for ( ; g >= g0; g--)
18418 g[move_by] = *g;
18419 while (from >= end)
18420 *to-- = *from--;
18421 it->glyph_row->used[TEXT_AREA] += move_by;
18426 /* Compute the hash code for ROW. */
18427 unsigned
18428 row_hash (struct glyph_row *row)
18430 int area, k;
18431 unsigned hashval = 0;
18433 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18434 for (k = 0; k < row->used[area]; ++k)
18435 hashval = ((((hashval << 4) + (hashval >> 24)) & 0x0fffffff)
18436 + row->glyphs[area][k].u.val
18437 + row->glyphs[area][k].face_id
18438 + row->glyphs[area][k].padding_p
18439 + (row->glyphs[area][k].type << 2));
18441 return hashval;
18444 /* Compute the pixel height and width of IT->glyph_row.
18446 Most of the time, ascent and height of a display line will be equal
18447 to the max_ascent and max_height values of the display iterator
18448 structure. This is not the case if
18450 1. We hit ZV without displaying anything. In this case, max_ascent
18451 and max_height will be zero.
18453 2. We have some glyphs that don't contribute to the line height.
18454 (The glyph row flag contributes_to_line_height_p is for future
18455 pixmap extensions).
18457 The first case is easily covered by using default values because in
18458 these cases, the line height does not really matter, except that it
18459 must not be zero. */
18461 static void
18462 compute_line_metrics (struct it *it)
18464 struct glyph_row *row = it->glyph_row;
18466 if (FRAME_WINDOW_P (it->f))
18468 int i, min_y, max_y;
18470 /* The line may consist of one space only, that was added to
18471 place the cursor on it. If so, the row's height hasn't been
18472 computed yet. */
18473 if (row->height == 0)
18475 if (it->max_ascent + it->max_descent == 0)
18476 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
18477 row->ascent = it->max_ascent;
18478 row->height = it->max_ascent + it->max_descent;
18479 row->phys_ascent = it->max_phys_ascent;
18480 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
18481 row->extra_line_spacing = it->max_extra_line_spacing;
18484 /* Compute the width of this line. */
18485 row->pixel_width = row->x;
18486 for (i = 0; i < row->used[TEXT_AREA]; ++i)
18487 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
18489 eassert (row->pixel_width >= 0);
18490 eassert (row->ascent >= 0 && row->height > 0);
18492 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
18493 || MATRIX_ROW_OVERLAPS_PRED_P (row));
18495 /* If first line's physical ascent is larger than its logical
18496 ascent, use the physical ascent, and make the row taller.
18497 This makes accented characters fully visible. */
18498 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
18499 && row->phys_ascent > row->ascent)
18501 row->height += row->phys_ascent - row->ascent;
18502 row->ascent = row->phys_ascent;
18505 /* Compute how much of the line is visible. */
18506 row->visible_height = row->height;
18508 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
18509 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
18511 if (row->y < min_y)
18512 row->visible_height -= min_y - row->y;
18513 if (row->y + row->height > max_y)
18514 row->visible_height -= row->y + row->height - max_y;
18516 else
18518 row->pixel_width = row->used[TEXT_AREA];
18519 if (row->continued_p)
18520 row->pixel_width -= it->continuation_pixel_width;
18521 else if (row->truncated_on_right_p)
18522 row->pixel_width -= it->truncation_pixel_width;
18523 row->ascent = row->phys_ascent = 0;
18524 row->height = row->phys_height = row->visible_height = 1;
18525 row->extra_line_spacing = 0;
18528 /* Compute a hash code for this row. */
18529 row->hash = row_hash (row);
18531 it->max_ascent = it->max_descent = 0;
18532 it->max_phys_ascent = it->max_phys_descent = 0;
18536 /* Append one space to the glyph row of iterator IT if doing a
18537 window-based redisplay. The space has the same face as
18538 IT->face_id. Value is non-zero if a space was added.
18540 This function is called to make sure that there is always one glyph
18541 at the end of a glyph row that the cursor can be set on under
18542 window-systems. (If there weren't such a glyph we would not know
18543 how wide and tall a box cursor should be displayed).
18545 At the same time this space let's a nicely handle clearing to the
18546 end of the line if the row ends in italic text. */
18548 static int
18549 append_space_for_newline (struct it *it, int default_face_p)
18551 if (FRAME_WINDOW_P (it->f))
18553 int n = it->glyph_row->used[TEXT_AREA];
18555 if (it->glyph_row->glyphs[TEXT_AREA] + n
18556 < it->glyph_row->glyphs[1 + TEXT_AREA])
18558 /* Save some values that must not be changed.
18559 Must save IT->c and IT->len because otherwise
18560 ITERATOR_AT_END_P wouldn't work anymore after
18561 append_space_for_newline has been called. */
18562 enum display_element_type saved_what = it->what;
18563 int saved_c = it->c, saved_len = it->len;
18564 int saved_char_to_display = it->char_to_display;
18565 int saved_x = it->current_x;
18566 int saved_face_id = it->face_id;
18567 int saved_box_end = it->end_of_box_run_p;
18568 struct text_pos saved_pos;
18569 Lisp_Object saved_object;
18570 struct face *face;
18572 saved_object = it->object;
18573 saved_pos = it->position;
18575 it->what = IT_CHARACTER;
18576 memset (&it->position, 0, sizeof it->position);
18577 it->object = make_number (0);
18578 it->c = it->char_to_display = ' ';
18579 it->len = 1;
18581 /* If the default face was remapped, be sure to use the
18582 remapped face for the appended newline. */
18583 if (default_face_p)
18584 it->face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
18585 else if (it->face_before_selective_p)
18586 it->face_id = it->saved_face_id;
18587 face = FACE_FROM_ID (it->f, it->face_id);
18588 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
18589 /* In R2L rows, we will prepend a stretch glyph that will
18590 have the end_of_box_run_p flag set for it, so there's no
18591 need for the appended newline glyph to have that flag
18592 set. */
18593 if (it->glyph_row->reversed_p
18594 /* But if the appended newline glyph goes all the way to
18595 the end of the row, there will be no stretch glyph,
18596 so leave the box flag set. */
18597 && saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x)
18598 it->end_of_box_run_p = 0;
18600 PRODUCE_GLYPHS (it);
18602 it->override_ascent = -1;
18603 it->constrain_row_ascent_descent_p = 0;
18604 it->current_x = saved_x;
18605 it->object = saved_object;
18606 it->position = saved_pos;
18607 it->what = saved_what;
18608 it->face_id = saved_face_id;
18609 it->len = saved_len;
18610 it->c = saved_c;
18611 it->char_to_display = saved_char_to_display;
18612 it->end_of_box_run_p = saved_box_end;
18613 return 1;
18617 return 0;
18621 /* Extend the face of the last glyph in the text area of IT->glyph_row
18622 to the end of the display line. Called from display_line. If the
18623 glyph row is empty, add a space glyph to it so that we know the
18624 face to draw. Set the glyph row flag fill_line_p. If the glyph
18625 row is R2L, prepend a stretch glyph to cover the empty space to the
18626 left of the leftmost glyph. */
18628 static void
18629 extend_face_to_end_of_line (struct it *it)
18631 struct face *face, *default_face;
18632 struct frame *f = it->f;
18634 /* If line is already filled, do nothing. Non window-system frames
18635 get a grace of one more ``pixel'' because their characters are
18636 1-``pixel'' wide, so they hit the equality too early. This grace
18637 is needed only for R2L rows that are not continued, to produce
18638 one extra blank where we could display the cursor. */
18639 if (it->current_x >= it->last_visible_x
18640 + (!FRAME_WINDOW_P (f)
18641 && it->glyph_row->reversed_p
18642 && !it->glyph_row->continued_p))
18643 return;
18645 /* The default face, possibly remapped. */
18646 default_face = FACE_FROM_ID (f, lookup_basic_face (f, DEFAULT_FACE_ID));
18648 /* Face extension extends the background and box of IT->face_id
18649 to the end of the line. If the background equals the background
18650 of the frame, we don't have to do anything. */
18651 if (it->face_before_selective_p)
18652 face = FACE_FROM_ID (f, it->saved_face_id);
18653 else
18654 face = FACE_FROM_ID (f, it->face_id);
18656 if (FRAME_WINDOW_P (f)
18657 && MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row)
18658 && face->box == FACE_NO_BOX
18659 && face->background == FRAME_BACKGROUND_PIXEL (f)
18660 && !face->stipple
18661 && !it->glyph_row->reversed_p)
18662 return;
18664 /* Set the glyph row flag indicating that the face of the last glyph
18665 in the text area has to be drawn to the end of the text area. */
18666 it->glyph_row->fill_line_p = 1;
18668 /* If current character of IT is not ASCII, make sure we have the
18669 ASCII face. This will be automatically undone the next time
18670 get_next_display_element returns a multibyte character. Note
18671 that the character will always be single byte in unibyte
18672 text. */
18673 if (!ASCII_CHAR_P (it->c))
18675 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
18678 if (FRAME_WINDOW_P (f))
18680 /* If the row is empty, add a space with the current face of IT,
18681 so that we know which face to draw. */
18682 if (it->glyph_row->used[TEXT_AREA] == 0)
18684 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
18685 it->glyph_row->glyphs[TEXT_AREA][0].face_id = face->id;
18686 it->glyph_row->used[TEXT_AREA] = 1;
18688 #ifdef HAVE_WINDOW_SYSTEM
18689 if (it->glyph_row->reversed_p)
18691 /* Prepend a stretch glyph to the row, such that the
18692 rightmost glyph will be drawn flushed all the way to the
18693 right margin of the window. The stretch glyph that will
18694 occupy the empty space, if any, to the left of the
18695 glyphs. */
18696 struct font *font = face->font ? face->font : FRAME_FONT (f);
18697 struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA];
18698 struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA];
18699 struct glyph *g;
18700 int row_width, stretch_ascent, stretch_width;
18701 struct text_pos saved_pos;
18702 int saved_face_id, saved_avoid_cursor, saved_box_start;
18704 for (row_width = 0, g = row_start; g < row_end; g++)
18705 row_width += g->pixel_width;
18706 stretch_width = window_box_width (it->w, TEXT_AREA) - row_width;
18707 if (stretch_width > 0)
18709 stretch_ascent =
18710 (((it->ascent + it->descent)
18711 * FONT_BASE (font)) / FONT_HEIGHT (font));
18712 saved_pos = it->position;
18713 memset (&it->position, 0, sizeof it->position);
18714 saved_avoid_cursor = it->avoid_cursor_p;
18715 it->avoid_cursor_p = 1;
18716 saved_face_id = it->face_id;
18717 saved_box_start = it->start_of_box_run_p;
18718 /* The last row's stretch glyph should get the default
18719 face, to avoid painting the rest of the window with
18720 the region face, if the region ends at ZV. */
18721 if (it->glyph_row->ends_at_zv_p)
18722 it->face_id = default_face->id;
18723 else
18724 it->face_id = face->id;
18725 it->start_of_box_run_p = 0;
18726 append_stretch_glyph (it, make_number (0), stretch_width,
18727 it->ascent + it->descent, stretch_ascent);
18728 it->position = saved_pos;
18729 it->avoid_cursor_p = saved_avoid_cursor;
18730 it->face_id = saved_face_id;
18731 it->start_of_box_run_p = saved_box_start;
18734 #endif /* HAVE_WINDOW_SYSTEM */
18736 else
18738 /* Save some values that must not be changed. */
18739 int saved_x = it->current_x;
18740 struct text_pos saved_pos;
18741 Lisp_Object saved_object;
18742 enum display_element_type saved_what = it->what;
18743 int saved_face_id = it->face_id;
18745 saved_object = it->object;
18746 saved_pos = it->position;
18748 it->what = IT_CHARACTER;
18749 memset (&it->position, 0, sizeof it->position);
18750 it->object = make_number (0);
18751 it->c = it->char_to_display = ' ';
18752 it->len = 1;
18753 /* The last row's blank glyphs should get the default face, to
18754 avoid painting the rest of the window with the region face,
18755 if the region ends at ZV. */
18756 if (it->glyph_row->ends_at_zv_p)
18757 it->face_id = default_face->id;
18758 else
18759 it->face_id = face->id;
18761 PRODUCE_GLYPHS (it);
18763 while (it->current_x <= it->last_visible_x)
18764 PRODUCE_GLYPHS (it);
18766 /* Don't count these blanks really. It would let us insert a left
18767 truncation glyph below and make us set the cursor on them, maybe. */
18768 it->current_x = saved_x;
18769 it->object = saved_object;
18770 it->position = saved_pos;
18771 it->what = saved_what;
18772 it->face_id = saved_face_id;
18777 /* Value is non-zero if text starting at CHARPOS in current_buffer is
18778 trailing whitespace. */
18780 static int
18781 trailing_whitespace_p (ptrdiff_t charpos)
18783 ptrdiff_t bytepos = CHAR_TO_BYTE (charpos);
18784 int c = 0;
18786 while (bytepos < ZV_BYTE
18787 && (c = FETCH_CHAR (bytepos),
18788 c == ' ' || c == '\t'))
18789 ++bytepos;
18791 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
18793 if (bytepos != PT_BYTE)
18794 return 1;
18796 return 0;
18800 /* Highlight trailing whitespace, if any, in ROW. */
18802 static void
18803 highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
18805 int used = row->used[TEXT_AREA];
18807 if (used)
18809 struct glyph *start = row->glyphs[TEXT_AREA];
18810 struct glyph *glyph = start + used - 1;
18812 if (row->reversed_p)
18814 /* Right-to-left rows need to be processed in the opposite
18815 direction, so swap the edge pointers. */
18816 glyph = start;
18817 start = row->glyphs[TEXT_AREA] + used - 1;
18820 /* Skip over glyphs inserted to display the cursor at the
18821 end of a line, for extending the face of the last glyph
18822 to the end of the line on terminals, and for truncation
18823 and continuation glyphs. */
18824 if (!row->reversed_p)
18826 while (glyph >= start
18827 && glyph->type == CHAR_GLYPH
18828 && INTEGERP (glyph->object))
18829 --glyph;
18831 else
18833 while (glyph <= start
18834 && glyph->type == CHAR_GLYPH
18835 && INTEGERP (glyph->object))
18836 ++glyph;
18839 /* If last glyph is a space or stretch, and it's trailing
18840 whitespace, set the face of all trailing whitespace glyphs in
18841 IT->glyph_row to `trailing-whitespace'. */
18842 if ((row->reversed_p ? glyph <= start : glyph >= start)
18843 && BUFFERP (glyph->object)
18844 && (glyph->type == STRETCH_GLYPH
18845 || (glyph->type == CHAR_GLYPH
18846 && glyph->u.ch == ' '))
18847 && trailing_whitespace_p (glyph->charpos))
18849 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
18850 if (face_id < 0)
18851 return;
18853 if (!row->reversed_p)
18855 while (glyph >= start
18856 && BUFFERP (glyph->object)
18857 && (glyph->type == STRETCH_GLYPH
18858 || (glyph->type == CHAR_GLYPH
18859 && glyph->u.ch == ' ')))
18860 (glyph--)->face_id = face_id;
18862 else
18864 while (glyph <= start
18865 && BUFFERP (glyph->object)
18866 && (glyph->type == STRETCH_GLYPH
18867 || (glyph->type == CHAR_GLYPH
18868 && glyph->u.ch == ' ')))
18869 (glyph++)->face_id = face_id;
18876 /* Value is non-zero if glyph row ROW should be
18877 considered to hold the buffer position CHARPOS. */
18879 static int
18880 row_for_charpos_p (struct glyph_row *row, ptrdiff_t charpos)
18882 int result = 1;
18884 if (charpos == CHARPOS (row->end.pos)
18885 || charpos == MATRIX_ROW_END_CHARPOS (row))
18887 /* Suppose the row ends on a string.
18888 Unless the row is continued, that means it ends on a newline
18889 in the string. If it's anything other than a display string
18890 (e.g., a before-string from an overlay), we don't want the
18891 cursor there. (This heuristic seems to give the optimal
18892 behavior for the various types of multi-line strings.)
18893 One exception: if the string has `cursor' property on one of
18894 its characters, we _do_ want the cursor there. */
18895 if (CHARPOS (row->end.string_pos) >= 0)
18897 if (row->continued_p)
18898 result = 1;
18899 else
18901 /* Check for `display' property. */
18902 struct glyph *beg = row->glyphs[TEXT_AREA];
18903 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
18904 struct glyph *glyph;
18906 result = 0;
18907 for (glyph = end; glyph >= beg; --glyph)
18908 if (STRINGP (glyph->object))
18910 Lisp_Object prop
18911 = Fget_char_property (make_number (charpos),
18912 Qdisplay, Qnil);
18913 result =
18914 (!NILP (prop)
18915 && display_prop_string_p (prop, glyph->object));
18916 /* If there's a `cursor' property on one of the
18917 string's characters, this row is a cursor row,
18918 even though this is not a display string. */
18919 if (!result)
18921 Lisp_Object s = glyph->object;
18923 for ( ; glyph >= beg && EQ (glyph->object, s); --glyph)
18925 ptrdiff_t gpos = glyph->charpos;
18927 if (!NILP (Fget_char_property (make_number (gpos),
18928 Qcursor, s)))
18930 result = 1;
18931 break;
18935 break;
18939 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
18941 /* If the row ends in middle of a real character,
18942 and the line is continued, we want the cursor here.
18943 That's because CHARPOS (ROW->end.pos) would equal
18944 PT if PT is before the character. */
18945 if (!row->ends_in_ellipsis_p)
18946 result = row->continued_p;
18947 else
18948 /* If the row ends in an ellipsis, then
18949 CHARPOS (ROW->end.pos) will equal point after the
18950 invisible text. We want that position to be displayed
18951 after the ellipsis. */
18952 result = 0;
18954 /* If the row ends at ZV, display the cursor at the end of that
18955 row instead of at the start of the row below. */
18956 else if (row->ends_at_zv_p)
18957 result = 1;
18958 else
18959 result = 0;
18962 return result;
18965 /* Value is non-zero if glyph row ROW should be
18966 used to hold the cursor. */
18968 static int
18969 cursor_row_p (struct glyph_row *row)
18971 return row_for_charpos_p (row, PT);
18976 /* Push the property PROP so that it will be rendered at the current
18977 position in IT. Return 1 if PROP was successfully pushed, 0
18978 otherwise. Called from handle_line_prefix to handle the
18979 `line-prefix' and `wrap-prefix' properties. */
18981 static int
18982 push_prefix_prop (struct it *it, Lisp_Object prop)
18984 struct text_pos pos =
18985 STRINGP (it->string) ? it->current.string_pos : it->current.pos;
18987 eassert (it->method == GET_FROM_BUFFER
18988 || it->method == GET_FROM_DISPLAY_VECTOR
18989 || it->method == GET_FROM_STRING);
18991 /* We need to save the current buffer/string position, so it will be
18992 restored by pop_it, because iterate_out_of_display_property
18993 depends on that being set correctly, but some situations leave
18994 it->position not yet set when this function is called. */
18995 push_it (it, &pos);
18997 if (STRINGP (prop))
18999 if (SCHARS (prop) == 0)
19001 pop_it (it);
19002 return 0;
19005 it->string = prop;
19006 it->string_from_prefix_prop_p = 1;
19007 it->multibyte_p = STRING_MULTIBYTE (it->string);
19008 it->current.overlay_string_index = -1;
19009 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
19010 it->end_charpos = it->string_nchars = SCHARS (it->string);
19011 it->method = GET_FROM_STRING;
19012 it->stop_charpos = 0;
19013 it->prev_stop = 0;
19014 it->base_level_stop = 0;
19016 /* Force paragraph direction to be that of the parent
19017 buffer/string. */
19018 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
19019 it->paragraph_embedding = it->bidi_it.paragraph_dir;
19020 else
19021 it->paragraph_embedding = L2R;
19023 /* Set up the bidi iterator for this display string. */
19024 if (it->bidi_p)
19026 it->bidi_it.string.lstring = it->string;
19027 it->bidi_it.string.s = NULL;
19028 it->bidi_it.string.schars = it->end_charpos;
19029 it->bidi_it.string.bufpos = IT_CHARPOS (*it);
19030 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
19031 it->bidi_it.string.unibyte = !it->multibyte_p;
19032 it->bidi_it.w = it->w;
19033 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
19036 else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
19038 it->method = GET_FROM_STRETCH;
19039 it->object = prop;
19041 #ifdef HAVE_WINDOW_SYSTEM
19042 else if (IMAGEP (prop))
19044 it->what = IT_IMAGE;
19045 it->image_id = lookup_image (it->f, prop);
19046 it->method = GET_FROM_IMAGE;
19048 #endif /* HAVE_WINDOW_SYSTEM */
19049 else
19051 pop_it (it); /* bogus display property, give up */
19052 return 0;
19055 return 1;
19058 /* Return the character-property PROP at the current position in IT. */
19060 static Lisp_Object
19061 get_it_property (struct it *it, Lisp_Object prop)
19063 Lisp_Object position, object = it->object;
19065 if (STRINGP (object))
19066 position = make_number (IT_STRING_CHARPOS (*it));
19067 else if (BUFFERP (object))
19069 position = make_number (IT_CHARPOS (*it));
19070 object = it->window;
19072 else
19073 return Qnil;
19075 return Fget_char_property (position, prop, object);
19078 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
19080 static void
19081 handle_line_prefix (struct it *it)
19083 Lisp_Object prefix;
19085 if (it->continuation_lines_width > 0)
19087 prefix = get_it_property (it, Qwrap_prefix);
19088 if (NILP (prefix))
19089 prefix = Vwrap_prefix;
19091 else
19093 prefix = get_it_property (it, Qline_prefix);
19094 if (NILP (prefix))
19095 prefix = Vline_prefix;
19097 if (! NILP (prefix) && push_prefix_prop (it, prefix))
19099 /* If the prefix is wider than the window, and we try to wrap
19100 it, it would acquire its own wrap prefix, and so on till the
19101 iterator stack overflows. So, don't wrap the prefix. */
19102 it->line_wrap = TRUNCATE;
19103 it->avoid_cursor_p = 1;
19109 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
19110 only for R2L lines from display_line and display_string, when they
19111 decide that too many glyphs were produced by PRODUCE_GLYPHS, and
19112 the line/string needs to be continued on the next glyph row. */
19113 static void
19114 unproduce_glyphs (struct it *it, int n)
19116 struct glyph *glyph, *end;
19118 eassert (it->glyph_row);
19119 eassert (it->glyph_row->reversed_p);
19120 eassert (it->area == TEXT_AREA);
19121 eassert (n <= it->glyph_row->used[TEXT_AREA]);
19123 if (n > it->glyph_row->used[TEXT_AREA])
19124 n = it->glyph_row->used[TEXT_AREA];
19125 glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
19126 end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
19127 for ( ; glyph < end; glyph++)
19128 glyph[-n] = *glyph;
19131 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
19132 and ROW->maxpos. */
19133 static void
19134 find_row_edges (struct it *it, struct glyph_row *row,
19135 ptrdiff_t min_pos, ptrdiff_t min_bpos,
19136 ptrdiff_t max_pos, ptrdiff_t max_bpos)
19138 /* FIXME: Revisit this when glyph ``spilling'' in continuation
19139 lines' rows is implemented for bidi-reordered rows. */
19141 /* ROW->minpos is the value of min_pos, the minimal buffer position
19142 we have in ROW, or ROW->start.pos if that is smaller. */
19143 if (min_pos <= ZV && min_pos < row->start.pos.charpos)
19144 SET_TEXT_POS (row->minpos, min_pos, min_bpos);
19145 else
19146 /* We didn't find buffer positions smaller than ROW->start, or
19147 didn't find _any_ valid buffer positions in any of the glyphs,
19148 so we must trust the iterator's computed positions. */
19149 row->minpos = row->start.pos;
19150 if (max_pos <= 0)
19152 max_pos = CHARPOS (it->current.pos);
19153 max_bpos = BYTEPOS (it->current.pos);
19156 /* Here are the various use-cases for ending the row, and the
19157 corresponding values for ROW->maxpos:
19159 Line ends in a newline from buffer eol_pos + 1
19160 Line is continued from buffer max_pos + 1
19161 Line is truncated on right it->current.pos
19162 Line ends in a newline from string max_pos + 1(*)
19163 (*) + 1 only when line ends in a forward scan
19164 Line is continued from string max_pos
19165 Line is continued from display vector max_pos
19166 Line is entirely from a string min_pos == max_pos
19167 Line is entirely from a display vector min_pos == max_pos
19168 Line that ends at ZV ZV
19170 If you discover other use-cases, please add them here as
19171 appropriate. */
19172 if (row->ends_at_zv_p)
19173 row->maxpos = it->current.pos;
19174 else if (row->used[TEXT_AREA])
19176 int seen_this_string = 0;
19177 struct glyph_row *r1 = row - 1;
19179 /* Did we see the same display string on the previous row? */
19180 if (STRINGP (it->object)
19181 /* this is not the first row */
19182 && row > it->w->desired_matrix->rows
19183 /* previous row is not the header line */
19184 && !r1->mode_line_p
19185 /* previous row also ends in a newline from a string */
19186 && r1->ends_in_newline_from_string_p)
19188 struct glyph *start, *end;
19190 /* Search for the last glyph of the previous row that came
19191 from buffer or string. Depending on whether the row is
19192 L2R or R2L, we need to process it front to back or the
19193 other way round. */
19194 if (!r1->reversed_p)
19196 start = r1->glyphs[TEXT_AREA];
19197 end = start + r1->used[TEXT_AREA];
19198 /* Glyphs inserted by redisplay have an integer (zero)
19199 as their object. */
19200 while (end > start
19201 && INTEGERP ((end - 1)->object)
19202 && (end - 1)->charpos <= 0)
19203 --end;
19204 if (end > start)
19206 if (EQ ((end - 1)->object, it->object))
19207 seen_this_string = 1;
19209 else
19210 /* If all the glyphs of the previous row were inserted
19211 by redisplay, it means the previous row was
19212 produced from a single newline, which is only
19213 possible if that newline came from the same string
19214 as the one which produced this ROW. */
19215 seen_this_string = 1;
19217 else
19219 end = r1->glyphs[TEXT_AREA] - 1;
19220 start = end + r1->used[TEXT_AREA];
19221 while (end < start
19222 && INTEGERP ((end + 1)->object)
19223 && (end + 1)->charpos <= 0)
19224 ++end;
19225 if (end < start)
19227 if (EQ ((end + 1)->object, it->object))
19228 seen_this_string = 1;
19230 else
19231 seen_this_string = 1;
19234 /* Take note of each display string that covers a newline only
19235 once, the first time we see it. This is for when a display
19236 string includes more than one newline in it. */
19237 if (row->ends_in_newline_from_string_p && !seen_this_string)
19239 /* If we were scanning the buffer forward when we displayed
19240 the string, we want to account for at least one buffer
19241 position that belongs to this row (position covered by
19242 the display string), so that cursor positioning will
19243 consider this row as a candidate when point is at the end
19244 of the visual line represented by this row. This is not
19245 required when scanning back, because max_pos will already
19246 have a much larger value. */
19247 if (CHARPOS (row->end.pos) > max_pos)
19248 INC_BOTH (max_pos, max_bpos);
19249 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19251 else if (CHARPOS (it->eol_pos) > 0)
19252 SET_TEXT_POS (row->maxpos,
19253 CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
19254 else if (row->continued_p)
19256 /* If max_pos is different from IT's current position, it
19257 means IT->method does not belong to the display element
19258 at max_pos. However, it also means that the display
19259 element at max_pos was displayed in its entirety on this
19260 line, which is equivalent to saying that the next line
19261 starts at the next buffer position. */
19262 if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
19263 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19264 else
19266 INC_BOTH (max_pos, max_bpos);
19267 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19270 else if (row->truncated_on_right_p)
19271 /* display_line already called reseat_at_next_visible_line_start,
19272 which puts the iterator at the beginning of the next line, in
19273 the logical order. */
19274 row->maxpos = it->current.pos;
19275 else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
19276 /* A line that is entirely from a string/image/stretch... */
19277 row->maxpos = row->minpos;
19278 else
19279 emacs_abort ();
19281 else
19282 row->maxpos = it->current.pos;
19285 /* Construct the glyph row IT->glyph_row in the desired matrix of
19286 IT->w from text at the current position of IT. See dispextern.h
19287 for an overview of struct it. Value is non-zero if
19288 IT->glyph_row displays text, as opposed to a line displaying ZV
19289 only. */
19291 static int
19292 display_line (struct it *it)
19294 struct glyph_row *row = it->glyph_row;
19295 Lisp_Object overlay_arrow_string;
19296 struct it wrap_it;
19297 void *wrap_data = NULL;
19298 int may_wrap = 0, wrap_x IF_LINT (= 0);
19299 int wrap_row_used = -1;
19300 int wrap_row_ascent IF_LINT (= 0), wrap_row_height IF_LINT (= 0);
19301 int wrap_row_phys_ascent IF_LINT (= 0), wrap_row_phys_height IF_LINT (= 0);
19302 int wrap_row_extra_line_spacing IF_LINT (= 0);
19303 ptrdiff_t wrap_row_min_pos IF_LINT (= 0), wrap_row_min_bpos IF_LINT (= 0);
19304 ptrdiff_t wrap_row_max_pos IF_LINT (= 0), wrap_row_max_bpos IF_LINT (= 0);
19305 int cvpos;
19306 ptrdiff_t min_pos = ZV + 1, max_pos = 0;
19307 ptrdiff_t min_bpos IF_LINT (= 0), max_bpos IF_LINT (= 0);
19309 /* We always start displaying at hpos zero even if hscrolled. */
19310 eassert (it->hpos == 0 && it->current_x == 0);
19312 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
19313 >= it->w->desired_matrix->nrows)
19315 it->w->nrows_scale_factor++;
19316 fonts_changed_p = 1;
19317 return 0;
19320 /* Is IT->w showing the region? */
19321 it->w->region_showing = it->region_beg_charpos > 0 ? it->region_beg_charpos : 0;
19323 /* Clear the result glyph row and enable it. */
19324 prepare_desired_row (row);
19326 row->y = it->current_y;
19327 row->start = it->start;
19328 row->continuation_lines_width = it->continuation_lines_width;
19329 row->displays_text_p = 1;
19330 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
19331 it->starts_in_middle_of_char_p = 0;
19333 /* Arrange the overlays nicely for our purposes. Usually, we call
19334 display_line on only one line at a time, in which case this
19335 can't really hurt too much, or we call it on lines which appear
19336 one after another in the buffer, in which case all calls to
19337 recenter_overlay_lists but the first will be pretty cheap. */
19338 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
19340 /* Move over display elements that are not visible because we are
19341 hscrolled. This may stop at an x-position < IT->first_visible_x
19342 if the first glyph is partially visible or if we hit a line end. */
19343 if (it->current_x < it->first_visible_x)
19345 enum move_it_result move_result;
19347 this_line_min_pos = row->start.pos;
19348 move_result = move_it_in_display_line_to (it, ZV, it->first_visible_x,
19349 MOVE_TO_POS | MOVE_TO_X);
19350 /* If we are under a large hscroll, move_it_in_display_line_to
19351 could hit the end of the line without reaching
19352 it->first_visible_x. Pretend that we did reach it. This is
19353 especially important on a TTY, where we will call
19354 extend_face_to_end_of_line, which needs to know how many
19355 blank glyphs to produce. */
19356 if (it->current_x < it->first_visible_x
19357 && (move_result == MOVE_NEWLINE_OR_CR
19358 || move_result == MOVE_POS_MATCH_OR_ZV))
19359 it->current_x = it->first_visible_x;
19361 /* Record the smallest positions seen while we moved over
19362 display elements that are not visible. This is needed by
19363 redisplay_internal for optimizing the case where the cursor
19364 stays inside the same line. The rest of this function only
19365 considers positions that are actually displayed, so
19366 RECORD_MAX_MIN_POS will not otherwise record positions that
19367 are hscrolled to the left of the left edge of the window. */
19368 min_pos = CHARPOS (this_line_min_pos);
19369 min_bpos = BYTEPOS (this_line_min_pos);
19371 else
19373 /* We only do this when not calling `move_it_in_display_line_to'
19374 above, because move_it_in_display_line_to calls
19375 handle_line_prefix itself. */
19376 handle_line_prefix (it);
19379 /* Get the initial row height. This is either the height of the
19380 text hscrolled, if there is any, or zero. */
19381 row->ascent = it->max_ascent;
19382 row->height = it->max_ascent + it->max_descent;
19383 row->phys_ascent = it->max_phys_ascent;
19384 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
19385 row->extra_line_spacing = it->max_extra_line_spacing;
19387 /* Utility macro to record max and min buffer positions seen until now. */
19388 #define RECORD_MAX_MIN_POS(IT) \
19389 do \
19391 int composition_p = !STRINGP ((IT)->string) \
19392 && ((IT)->what == IT_COMPOSITION); \
19393 ptrdiff_t current_pos = \
19394 composition_p ? (IT)->cmp_it.charpos \
19395 : IT_CHARPOS (*(IT)); \
19396 ptrdiff_t current_bpos = \
19397 composition_p ? CHAR_TO_BYTE (current_pos) \
19398 : IT_BYTEPOS (*(IT)); \
19399 if (current_pos < min_pos) \
19401 min_pos = current_pos; \
19402 min_bpos = current_bpos; \
19404 if (IT_CHARPOS (*it) > max_pos) \
19406 max_pos = IT_CHARPOS (*it); \
19407 max_bpos = IT_BYTEPOS (*it); \
19410 while (0)
19412 /* Loop generating characters. The loop is left with IT on the next
19413 character to display. */
19414 while (1)
19416 int n_glyphs_before, hpos_before, x_before;
19417 int x, nglyphs;
19418 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
19420 /* Retrieve the next thing to display. Value is zero if end of
19421 buffer reached. */
19422 if (!get_next_display_element (it))
19424 /* Maybe add a space at the end of this line that is used to
19425 display the cursor there under X. Set the charpos of the
19426 first glyph of blank lines not corresponding to any text
19427 to -1. */
19428 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19429 row->exact_window_width_line_p = 1;
19430 else if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
19431 || row->used[TEXT_AREA] == 0)
19433 row->glyphs[TEXT_AREA]->charpos = -1;
19434 row->displays_text_p = 0;
19436 if (!NILP (BVAR (XBUFFER (it->w->contents), indicate_empty_lines))
19437 && (!MINI_WINDOW_P (it->w)
19438 || (minibuf_level && EQ (it->window, minibuf_window))))
19439 row->indicate_empty_line_p = 1;
19442 it->continuation_lines_width = 0;
19443 row->ends_at_zv_p = 1;
19444 /* A row that displays right-to-left text must always have
19445 its last face extended all the way to the end of line,
19446 even if this row ends in ZV, because we still write to
19447 the screen left to right. We also need to extend the
19448 last face if the default face is remapped to some
19449 different face, otherwise the functions that clear
19450 portions of the screen will clear with the default face's
19451 background color. */
19452 if (row->reversed_p
19453 || lookup_basic_face (it->f, DEFAULT_FACE_ID) != DEFAULT_FACE_ID)
19454 extend_face_to_end_of_line (it);
19455 break;
19458 /* Now, get the metrics of what we want to display. This also
19459 generates glyphs in `row' (which is IT->glyph_row). */
19460 n_glyphs_before = row->used[TEXT_AREA];
19461 x = it->current_x;
19463 /* Remember the line height so far in case the next element doesn't
19464 fit on the line. */
19465 if (it->line_wrap != TRUNCATE)
19467 ascent = it->max_ascent;
19468 descent = it->max_descent;
19469 phys_ascent = it->max_phys_ascent;
19470 phys_descent = it->max_phys_descent;
19472 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
19474 if (IT_DISPLAYING_WHITESPACE (it))
19475 may_wrap = 1;
19476 else if (may_wrap)
19478 SAVE_IT (wrap_it, *it, wrap_data);
19479 wrap_x = x;
19480 wrap_row_used = row->used[TEXT_AREA];
19481 wrap_row_ascent = row->ascent;
19482 wrap_row_height = row->height;
19483 wrap_row_phys_ascent = row->phys_ascent;
19484 wrap_row_phys_height = row->phys_height;
19485 wrap_row_extra_line_spacing = row->extra_line_spacing;
19486 wrap_row_min_pos = min_pos;
19487 wrap_row_min_bpos = min_bpos;
19488 wrap_row_max_pos = max_pos;
19489 wrap_row_max_bpos = max_bpos;
19490 may_wrap = 0;
19495 PRODUCE_GLYPHS (it);
19497 /* If this display element was in marginal areas, continue with
19498 the next one. */
19499 if (it->area != TEXT_AREA)
19501 row->ascent = max (row->ascent, it->max_ascent);
19502 row->height = max (row->height, it->max_ascent + it->max_descent);
19503 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19504 row->phys_height = max (row->phys_height,
19505 it->max_phys_ascent + it->max_phys_descent);
19506 row->extra_line_spacing = max (row->extra_line_spacing,
19507 it->max_extra_line_spacing);
19508 set_iterator_to_next (it, 1);
19509 continue;
19512 /* Does the display element fit on the line? If we truncate
19513 lines, we should draw past the right edge of the window. If
19514 we don't truncate, we want to stop so that we can display the
19515 continuation glyph before the right margin. If lines are
19516 continued, there are two possible strategies for characters
19517 resulting in more than 1 glyph (e.g. tabs): Display as many
19518 glyphs as possible in this line and leave the rest for the
19519 continuation line, or display the whole element in the next
19520 line. Original redisplay did the former, so we do it also. */
19521 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
19522 hpos_before = it->hpos;
19523 x_before = x;
19525 if (/* Not a newline. */
19526 nglyphs > 0
19527 /* Glyphs produced fit entirely in the line. */
19528 && it->current_x < it->last_visible_x)
19530 it->hpos += nglyphs;
19531 row->ascent = max (row->ascent, it->max_ascent);
19532 row->height = max (row->height, it->max_ascent + it->max_descent);
19533 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19534 row->phys_height = max (row->phys_height,
19535 it->max_phys_ascent + it->max_phys_descent);
19536 row->extra_line_spacing = max (row->extra_line_spacing,
19537 it->max_extra_line_spacing);
19538 if (it->current_x - it->pixel_width < it->first_visible_x)
19539 row->x = x - it->first_visible_x;
19540 /* Record the maximum and minimum buffer positions seen so
19541 far in glyphs that will be displayed by this row. */
19542 if (it->bidi_p)
19543 RECORD_MAX_MIN_POS (it);
19545 else
19547 int i, new_x;
19548 struct glyph *glyph;
19550 for (i = 0; i < nglyphs; ++i, x = new_x)
19552 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
19553 new_x = x + glyph->pixel_width;
19555 if (/* Lines are continued. */
19556 it->line_wrap != TRUNCATE
19557 && (/* Glyph doesn't fit on the line. */
19558 new_x > it->last_visible_x
19559 /* Or it fits exactly on a window system frame. */
19560 || (new_x == it->last_visible_x
19561 && FRAME_WINDOW_P (it->f)
19562 && (row->reversed_p
19563 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19564 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
19566 /* End of a continued line. */
19568 if (it->hpos == 0
19569 || (new_x == it->last_visible_x
19570 && FRAME_WINDOW_P (it->f)
19571 && (row->reversed_p
19572 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19573 : WINDOW_RIGHT_FRINGE_WIDTH (it->w))))
19575 /* Current glyph is the only one on the line or
19576 fits exactly on the line. We must continue
19577 the line because we can't draw the cursor
19578 after the glyph. */
19579 row->continued_p = 1;
19580 it->current_x = new_x;
19581 it->continuation_lines_width += new_x;
19582 ++it->hpos;
19583 if (i == nglyphs - 1)
19585 /* If line-wrap is on, check if a previous
19586 wrap point was found. */
19587 if (wrap_row_used > 0
19588 /* Even if there is a previous wrap
19589 point, continue the line here as
19590 usual, if (i) the previous character
19591 was a space or tab AND (ii) the
19592 current character is not. */
19593 && (!may_wrap
19594 || IT_DISPLAYING_WHITESPACE (it)))
19595 goto back_to_wrap;
19597 /* Record the maximum and minimum buffer
19598 positions seen so far in glyphs that will be
19599 displayed by this row. */
19600 if (it->bidi_p)
19601 RECORD_MAX_MIN_POS (it);
19602 set_iterator_to_next (it, 1);
19603 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19605 if (!get_next_display_element (it))
19607 row->exact_window_width_line_p = 1;
19608 it->continuation_lines_width = 0;
19609 row->continued_p = 0;
19610 row->ends_at_zv_p = 1;
19612 else if (ITERATOR_AT_END_OF_LINE_P (it))
19614 row->continued_p = 0;
19615 row->exact_window_width_line_p = 1;
19619 else if (it->bidi_p)
19620 RECORD_MAX_MIN_POS (it);
19622 else if (CHAR_GLYPH_PADDING_P (*glyph)
19623 && !FRAME_WINDOW_P (it->f))
19625 /* A padding glyph that doesn't fit on this line.
19626 This means the whole character doesn't fit
19627 on the line. */
19628 if (row->reversed_p)
19629 unproduce_glyphs (it, row->used[TEXT_AREA]
19630 - n_glyphs_before);
19631 row->used[TEXT_AREA] = n_glyphs_before;
19633 /* Fill the rest of the row with continuation
19634 glyphs like in 20.x. */
19635 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
19636 < row->glyphs[1 + TEXT_AREA])
19637 produce_special_glyphs (it, IT_CONTINUATION);
19639 row->continued_p = 1;
19640 it->current_x = x_before;
19641 it->continuation_lines_width += x_before;
19643 /* Restore the height to what it was before the
19644 element not fitting on the line. */
19645 it->max_ascent = ascent;
19646 it->max_descent = descent;
19647 it->max_phys_ascent = phys_ascent;
19648 it->max_phys_descent = phys_descent;
19650 else if (wrap_row_used > 0)
19652 back_to_wrap:
19653 if (row->reversed_p)
19654 unproduce_glyphs (it,
19655 row->used[TEXT_AREA] - wrap_row_used);
19656 RESTORE_IT (it, &wrap_it, wrap_data);
19657 it->continuation_lines_width += wrap_x;
19658 row->used[TEXT_AREA] = wrap_row_used;
19659 row->ascent = wrap_row_ascent;
19660 row->height = wrap_row_height;
19661 row->phys_ascent = wrap_row_phys_ascent;
19662 row->phys_height = wrap_row_phys_height;
19663 row->extra_line_spacing = wrap_row_extra_line_spacing;
19664 min_pos = wrap_row_min_pos;
19665 min_bpos = wrap_row_min_bpos;
19666 max_pos = wrap_row_max_pos;
19667 max_bpos = wrap_row_max_bpos;
19668 row->continued_p = 1;
19669 row->ends_at_zv_p = 0;
19670 row->exact_window_width_line_p = 0;
19671 it->continuation_lines_width += x;
19673 /* Make sure that a non-default face is extended
19674 up to the right margin of the window. */
19675 extend_face_to_end_of_line (it);
19677 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
19679 /* A TAB that extends past the right edge of the
19680 window. This produces a single glyph on
19681 window system frames. We leave the glyph in
19682 this row and let it fill the row, but don't
19683 consume the TAB. */
19684 if ((row->reversed_p
19685 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19686 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
19687 produce_special_glyphs (it, IT_CONTINUATION);
19688 it->continuation_lines_width += it->last_visible_x;
19689 row->ends_in_middle_of_char_p = 1;
19690 row->continued_p = 1;
19691 glyph->pixel_width = it->last_visible_x - x;
19692 it->starts_in_middle_of_char_p = 1;
19694 else
19696 /* Something other than a TAB that draws past
19697 the right edge of the window. Restore
19698 positions to values before the element. */
19699 if (row->reversed_p)
19700 unproduce_glyphs (it, row->used[TEXT_AREA]
19701 - (n_glyphs_before + i));
19702 row->used[TEXT_AREA] = n_glyphs_before + i;
19704 /* Display continuation glyphs. */
19705 it->current_x = x_before;
19706 it->continuation_lines_width += x;
19707 if (!FRAME_WINDOW_P (it->f)
19708 || (row->reversed_p
19709 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19710 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
19711 produce_special_glyphs (it, IT_CONTINUATION);
19712 row->continued_p = 1;
19714 extend_face_to_end_of_line (it);
19716 if (nglyphs > 1 && i > 0)
19718 row->ends_in_middle_of_char_p = 1;
19719 it->starts_in_middle_of_char_p = 1;
19722 /* Restore the height to what it was before the
19723 element not fitting on the line. */
19724 it->max_ascent = ascent;
19725 it->max_descent = descent;
19726 it->max_phys_ascent = phys_ascent;
19727 it->max_phys_descent = phys_descent;
19730 break;
19732 else if (new_x > it->first_visible_x)
19734 /* Increment number of glyphs actually displayed. */
19735 ++it->hpos;
19737 /* Record the maximum and minimum buffer positions
19738 seen so far in glyphs that will be displayed by
19739 this row. */
19740 if (it->bidi_p)
19741 RECORD_MAX_MIN_POS (it);
19743 if (x < it->first_visible_x)
19744 /* Glyph is partially visible, i.e. row starts at
19745 negative X position. */
19746 row->x = x - it->first_visible_x;
19748 else
19750 /* Glyph is completely off the left margin of the
19751 window. This should not happen because of the
19752 move_it_in_display_line at the start of this
19753 function, unless the text display area of the
19754 window is empty. */
19755 eassert (it->first_visible_x <= it->last_visible_x);
19758 /* Even if this display element produced no glyphs at all,
19759 we want to record its position. */
19760 if (it->bidi_p && nglyphs == 0)
19761 RECORD_MAX_MIN_POS (it);
19763 row->ascent = max (row->ascent, it->max_ascent);
19764 row->height = max (row->height, it->max_ascent + it->max_descent);
19765 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19766 row->phys_height = max (row->phys_height,
19767 it->max_phys_ascent + it->max_phys_descent);
19768 row->extra_line_spacing = max (row->extra_line_spacing,
19769 it->max_extra_line_spacing);
19771 /* End of this display line if row is continued. */
19772 if (row->continued_p || row->ends_at_zv_p)
19773 break;
19776 at_end_of_line:
19777 /* Is this a line end? If yes, we're also done, after making
19778 sure that a non-default face is extended up to the right
19779 margin of the window. */
19780 if (ITERATOR_AT_END_OF_LINE_P (it))
19782 int used_before = row->used[TEXT_AREA];
19784 row->ends_in_newline_from_string_p = STRINGP (it->object);
19786 /* Add a space at the end of the line that is used to
19787 display the cursor there. */
19788 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19789 append_space_for_newline (it, 0);
19791 /* Extend the face to the end of the line. */
19792 extend_face_to_end_of_line (it);
19794 /* Make sure we have the position. */
19795 if (used_before == 0)
19796 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
19798 /* Record the position of the newline, for use in
19799 find_row_edges. */
19800 it->eol_pos = it->current.pos;
19802 /* Consume the line end. This skips over invisible lines. */
19803 set_iterator_to_next (it, 1);
19804 it->continuation_lines_width = 0;
19805 break;
19808 /* Proceed with next display element. Note that this skips
19809 over lines invisible because of selective display. */
19810 set_iterator_to_next (it, 1);
19812 /* If we truncate lines, we are done when the last displayed
19813 glyphs reach past the right margin of the window. */
19814 if (it->line_wrap == TRUNCATE
19815 && (FRAME_WINDOW_P (it->f) && WINDOW_RIGHT_FRINGE_WIDTH (it->w)
19816 ? (it->current_x >= it->last_visible_x)
19817 : (it->current_x > it->last_visible_x)))
19819 /* Maybe add truncation glyphs. */
19820 if (!FRAME_WINDOW_P (it->f)
19821 || (row->reversed_p
19822 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19823 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
19825 int i, n;
19827 if (!row->reversed_p)
19829 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
19830 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
19831 break;
19833 else
19835 for (i = 0; i < row->used[TEXT_AREA]; i++)
19836 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
19837 break;
19838 /* Remove any padding glyphs at the front of ROW, to
19839 make room for the truncation glyphs we will be
19840 adding below. The loop below always inserts at
19841 least one truncation glyph, so also remove the
19842 last glyph added to ROW. */
19843 unproduce_glyphs (it, i + 1);
19844 /* Adjust i for the loop below. */
19845 i = row->used[TEXT_AREA] - (i + 1);
19848 it->current_x = x_before;
19849 if (!FRAME_WINDOW_P (it->f))
19851 for (n = row->used[TEXT_AREA]; i < n; ++i)
19853 row->used[TEXT_AREA] = i;
19854 produce_special_glyphs (it, IT_TRUNCATION);
19857 else
19859 row->used[TEXT_AREA] = i;
19860 produce_special_glyphs (it, IT_TRUNCATION);
19863 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19865 /* Don't truncate if we can overflow newline into fringe. */
19866 if (!get_next_display_element (it))
19868 it->continuation_lines_width = 0;
19869 row->ends_at_zv_p = 1;
19870 row->exact_window_width_line_p = 1;
19871 break;
19873 if (ITERATOR_AT_END_OF_LINE_P (it))
19875 row->exact_window_width_line_p = 1;
19876 goto at_end_of_line;
19878 it->current_x = x_before;
19881 row->truncated_on_right_p = 1;
19882 it->continuation_lines_width = 0;
19883 reseat_at_next_visible_line_start (it, 0);
19884 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
19885 it->hpos = hpos_before;
19886 break;
19890 if (wrap_data)
19891 bidi_unshelve_cache (wrap_data, 1);
19893 /* If line is not empty and hscrolled, maybe insert truncation glyphs
19894 at the left window margin. */
19895 if (it->first_visible_x
19896 && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
19898 if (!FRAME_WINDOW_P (it->f)
19899 || (row->reversed_p
19900 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
19901 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
19902 insert_left_trunc_glyphs (it);
19903 row->truncated_on_left_p = 1;
19906 /* Remember the position at which this line ends.
19908 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
19909 cannot be before the call to find_row_edges below, since that is
19910 where these positions are determined. */
19911 row->end = it->current;
19912 if (!it->bidi_p)
19914 row->minpos = row->start.pos;
19915 row->maxpos = row->end.pos;
19917 else
19919 /* ROW->minpos and ROW->maxpos must be the smallest and
19920 `1 + the largest' buffer positions in ROW. But if ROW was
19921 bidi-reordered, these two positions can be anywhere in the
19922 row, so we must determine them now. */
19923 find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
19926 /* If the start of this line is the overlay arrow-position, then
19927 mark this glyph row as the one containing the overlay arrow.
19928 This is clearly a mess with variable size fonts. It would be
19929 better to let it be displayed like cursors under X. */
19930 if ((MATRIX_ROW_DISPLAYS_TEXT_P (row) || !overlay_arrow_seen)
19931 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
19932 !NILP (overlay_arrow_string)))
19934 /* Overlay arrow in window redisplay is a fringe bitmap. */
19935 if (STRINGP (overlay_arrow_string))
19937 struct glyph_row *arrow_row
19938 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
19939 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
19940 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
19941 struct glyph *p = row->glyphs[TEXT_AREA];
19942 struct glyph *p2, *end;
19944 /* Copy the arrow glyphs. */
19945 while (glyph < arrow_end)
19946 *p++ = *glyph++;
19948 /* Throw away padding glyphs. */
19949 p2 = p;
19950 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
19951 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
19952 ++p2;
19953 if (p2 > p)
19955 while (p2 < end)
19956 *p++ = *p2++;
19957 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
19960 else
19962 eassert (INTEGERP (overlay_arrow_string));
19963 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
19965 overlay_arrow_seen = 1;
19968 /* Highlight trailing whitespace. */
19969 if (!NILP (Vshow_trailing_whitespace))
19970 highlight_trailing_whitespace (it->f, it->glyph_row);
19972 /* Compute pixel dimensions of this line. */
19973 compute_line_metrics (it);
19975 /* Implementation note: No changes in the glyphs of ROW or in their
19976 faces can be done past this point, because compute_line_metrics
19977 computes ROW's hash value and stores it within the glyph_row
19978 structure. */
19980 /* Record whether this row ends inside an ellipsis. */
19981 row->ends_in_ellipsis_p
19982 = (it->method == GET_FROM_DISPLAY_VECTOR
19983 && it->ellipsis_p);
19985 /* Save fringe bitmaps in this row. */
19986 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
19987 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
19988 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
19989 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
19991 it->left_user_fringe_bitmap = 0;
19992 it->left_user_fringe_face_id = 0;
19993 it->right_user_fringe_bitmap = 0;
19994 it->right_user_fringe_face_id = 0;
19996 /* Maybe set the cursor. */
19997 cvpos = it->w->cursor.vpos;
19998 if ((cvpos < 0
19999 /* In bidi-reordered rows, keep checking for proper cursor
20000 position even if one has been found already, because buffer
20001 positions in such rows change non-linearly with ROW->VPOS,
20002 when a line is continued. One exception: when we are at ZV,
20003 display cursor on the first suitable glyph row, since all
20004 the empty rows after that also have their position set to ZV. */
20005 /* FIXME: Revisit this when glyph ``spilling'' in continuation
20006 lines' rows is implemented for bidi-reordered rows. */
20007 || (it->bidi_p
20008 && !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
20009 && PT >= MATRIX_ROW_START_CHARPOS (row)
20010 && PT <= MATRIX_ROW_END_CHARPOS (row)
20011 && cursor_row_p (row))
20012 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
20014 /* Prepare for the next line. This line starts horizontally at (X
20015 HPOS) = (0 0). Vertical positions are incremented. As a
20016 convenience for the caller, IT->glyph_row is set to the next
20017 row to be used. */
20018 it->current_x = it->hpos = 0;
20019 it->current_y += row->height;
20020 SET_TEXT_POS (it->eol_pos, 0, 0);
20021 ++it->vpos;
20022 ++it->glyph_row;
20023 /* The next row should by default use the same value of the
20024 reversed_p flag as this one. set_iterator_to_next decides when
20025 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
20026 the flag accordingly. */
20027 if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
20028 it->glyph_row->reversed_p = row->reversed_p;
20029 it->start = row->end;
20030 return MATRIX_ROW_DISPLAYS_TEXT_P (row);
20032 #undef RECORD_MAX_MIN_POS
20035 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,
20036 Scurrent_bidi_paragraph_direction, 0, 1, 0,
20037 doc: /* Return paragraph direction at point in BUFFER.
20038 Value is either `left-to-right' or `right-to-left'.
20039 If BUFFER is omitted or nil, it defaults to the current buffer.
20041 Paragraph direction determines how the text in the paragraph is displayed.
20042 In left-to-right paragraphs, text begins at the left margin of the window
20043 and the reading direction is generally left to right. In right-to-left
20044 paragraphs, text begins at the right margin and is read from right to left.
20046 See also `bidi-paragraph-direction'. */)
20047 (Lisp_Object buffer)
20049 struct buffer *buf = current_buffer;
20050 struct buffer *old = buf;
20052 if (! NILP (buffer))
20054 CHECK_BUFFER (buffer);
20055 buf = XBUFFER (buffer);
20058 if (NILP (BVAR (buf, bidi_display_reordering))
20059 || NILP (BVAR (buf, enable_multibyte_characters))
20060 /* When we are loading loadup.el, the character property tables
20061 needed for bidi iteration are not yet available. */
20062 || !NILP (Vpurify_flag))
20063 return Qleft_to_right;
20064 else if (!NILP (BVAR (buf, bidi_paragraph_direction)))
20065 return BVAR (buf, bidi_paragraph_direction);
20066 else
20068 /* Determine the direction from buffer text. We could try to
20069 use current_matrix if it is up to date, but this seems fast
20070 enough as it is. */
20071 struct bidi_it itb;
20072 ptrdiff_t pos = BUF_PT (buf);
20073 ptrdiff_t bytepos = BUF_PT_BYTE (buf);
20074 int c;
20075 void *itb_data = bidi_shelve_cache ();
20077 set_buffer_temp (buf);
20078 /* bidi_paragraph_init finds the base direction of the paragraph
20079 by searching forward from paragraph start. We need the base
20080 direction of the current or _previous_ paragraph, so we need
20081 to make sure we are within that paragraph. To that end, find
20082 the previous non-empty line. */
20083 if (pos >= ZV && pos > BEGV)
20084 DEC_BOTH (pos, bytepos);
20085 if (fast_looking_at (build_string ("[\f\t ]*\n"),
20086 pos, bytepos, ZV, ZV_BYTE, Qnil) > 0)
20088 while ((c = FETCH_BYTE (bytepos)) == '\n'
20089 || c == ' ' || c == '\t' || c == '\f')
20091 if (bytepos <= BEGV_BYTE)
20092 break;
20093 bytepos--;
20094 pos--;
20096 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos)))
20097 bytepos--;
20099 bidi_init_it (pos, bytepos, FRAME_WINDOW_P (SELECTED_FRAME ()), &itb);
20100 itb.paragraph_dir = NEUTRAL_DIR;
20101 itb.string.s = NULL;
20102 itb.string.lstring = Qnil;
20103 itb.string.bufpos = 0;
20104 itb.string.unibyte = 0;
20105 /* We have no window to use here for ignoring window-specific
20106 overlays. Using NULL for window pointer will cause
20107 compute_display_string_pos to use the current buffer. */
20108 itb.w = NULL;
20109 bidi_paragraph_init (NEUTRAL_DIR, &itb, 1);
20110 bidi_unshelve_cache (itb_data, 0);
20111 set_buffer_temp (old);
20112 switch (itb.paragraph_dir)
20114 case L2R:
20115 return Qleft_to_right;
20116 break;
20117 case R2L:
20118 return Qright_to_left;
20119 break;
20120 default:
20121 emacs_abort ();
20126 DEFUN ("move-point-visually", Fmove_point_visually,
20127 Smove_point_visually, 1, 1, 0,
20128 doc: /* Move point in the visual order in the specified DIRECTION.
20129 DIRECTION can be 1, meaning move to the right, or -1, which moves to the
20130 left.
20132 Value is the new character position of point. */)
20133 (Lisp_Object direction)
20135 struct window *w = XWINDOW (selected_window);
20136 struct buffer *b = XBUFFER (w->contents);
20137 struct glyph_row *row;
20138 int dir;
20139 Lisp_Object paragraph_dir;
20141 #define ROW_GLYPH_NEWLINE_P(ROW,GLYPH) \
20142 (!(ROW)->continued_p \
20143 && INTEGERP ((GLYPH)->object) \
20144 && (GLYPH)->type == CHAR_GLYPH \
20145 && (GLYPH)->u.ch == ' ' \
20146 && (GLYPH)->charpos >= 0 \
20147 && !(GLYPH)->avoid_cursor_p)
20149 CHECK_NUMBER (direction);
20150 dir = XINT (direction);
20151 if (dir > 0)
20152 dir = 1;
20153 else
20154 dir = -1;
20156 /* If current matrix is up-to-date, we can use the information
20157 recorded in the glyphs, at least as long as the goal is on the
20158 screen. */
20159 if (w->window_end_valid
20160 && !windows_or_buffers_changed
20161 && b
20162 && !b->clip_changed
20163 && !b->prevent_redisplay_optimizations_p
20164 && !window_outdated (w)
20165 && w->cursor.vpos >= 0
20166 && w->cursor.vpos < w->current_matrix->nrows
20167 && (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos))->enabled_p)
20169 struct glyph *g = row->glyphs[TEXT_AREA];
20170 struct glyph *e = dir > 0 ? g + row->used[TEXT_AREA] : g - 1;
20171 struct glyph *gpt = g + w->cursor.hpos;
20173 for (g = gpt + dir; (dir > 0 ? g < e : g > e); g += dir)
20175 if (BUFFERP (g->object) && g->charpos != PT)
20177 SET_PT (g->charpos);
20178 w->cursor.vpos = -1;
20179 return make_number (PT);
20181 else if (!INTEGERP (g->object) && !EQ (g->object, gpt->object))
20183 ptrdiff_t new_pos;
20185 if (BUFFERP (gpt->object))
20187 new_pos = PT;
20188 if ((gpt->resolved_level - row->reversed_p) % 2 == 0)
20189 new_pos += (row->reversed_p ? -dir : dir);
20190 else
20191 new_pos -= (row->reversed_p ? -dir : dir);;
20193 else if (BUFFERP (g->object))
20194 new_pos = g->charpos;
20195 else
20196 break;
20197 SET_PT (new_pos);
20198 w->cursor.vpos = -1;
20199 return make_number (PT);
20201 else if (ROW_GLYPH_NEWLINE_P (row, g))
20203 /* Glyphs inserted at the end of a non-empty line for
20204 positioning the cursor have zero charpos, so we must
20205 deduce the value of point by other means. */
20206 if (g->charpos > 0)
20207 SET_PT (g->charpos);
20208 else if (row->ends_at_zv_p && PT != ZV)
20209 SET_PT (ZV);
20210 else if (PT != MATRIX_ROW_END_CHARPOS (row) - 1)
20211 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
20212 else
20213 break;
20214 w->cursor.vpos = -1;
20215 return make_number (PT);
20218 if (g == e || INTEGERP (g->object))
20220 if (row->truncated_on_left_p || row->truncated_on_right_p)
20221 goto simulate_display;
20222 if (!row->reversed_p)
20223 row += dir;
20224 else
20225 row -= dir;
20226 if (row < MATRIX_FIRST_TEXT_ROW (w->current_matrix)
20227 || row > MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
20228 goto simulate_display;
20230 if (dir > 0)
20232 if (row->reversed_p && !row->continued_p)
20234 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
20235 w->cursor.vpos = -1;
20236 return make_number (PT);
20238 g = row->glyphs[TEXT_AREA];
20239 e = g + row->used[TEXT_AREA];
20240 for ( ; g < e; g++)
20242 if (BUFFERP (g->object)
20243 /* Empty lines have only one glyph, which stands
20244 for the newline, and whose charpos is the
20245 buffer position of the newline. */
20246 || ROW_GLYPH_NEWLINE_P (row, g)
20247 /* When the buffer ends in a newline, the line at
20248 EOB also has one glyph, but its charpos is -1. */
20249 || (row->ends_at_zv_p
20250 && !row->reversed_p
20251 && INTEGERP (g->object)
20252 && g->type == CHAR_GLYPH
20253 && g->u.ch == ' '))
20255 if (g->charpos > 0)
20256 SET_PT (g->charpos);
20257 else if (!row->reversed_p
20258 && row->ends_at_zv_p
20259 && PT != ZV)
20260 SET_PT (ZV);
20261 else
20262 continue;
20263 w->cursor.vpos = -1;
20264 return make_number (PT);
20268 else
20270 if (!row->reversed_p && !row->continued_p)
20272 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
20273 w->cursor.vpos = -1;
20274 return make_number (PT);
20276 e = row->glyphs[TEXT_AREA];
20277 g = e + row->used[TEXT_AREA] - 1;
20278 for ( ; g >= e; g--)
20280 if (BUFFERP (g->object)
20281 || (ROW_GLYPH_NEWLINE_P (row, g)
20282 && g->charpos > 0)
20283 /* Empty R2L lines on GUI frames have the buffer
20284 position of the newline stored in the stretch
20285 glyph. */
20286 || g->type == STRETCH_GLYPH
20287 || (row->ends_at_zv_p
20288 && row->reversed_p
20289 && INTEGERP (g->object)
20290 && g->type == CHAR_GLYPH
20291 && g->u.ch == ' '))
20293 if (g->charpos > 0)
20294 SET_PT (g->charpos);
20295 else if (row->reversed_p
20296 && row->ends_at_zv_p
20297 && PT != ZV)
20298 SET_PT (ZV);
20299 else
20300 continue;
20301 w->cursor.vpos = -1;
20302 return make_number (PT);
20309 simulate_display:
20311 /* If we wind up here, we failed to move by using the glyphs, so we
20312 need to simulate display instead. */
20314 if (b)
20315 paragraph_dir = Fcurrent_bidi_paragraph_direction (w->contents);
20316 else
20317 paragraph_dir = Qleft_to_right;
20318 if (EQ (paragraph_dir, Qright_to_left))
20319 dir = -dir;
20320 if (PT <= BEGV && dir < 0)
20321 xsignal0 (Qbeginning_of_buffer);
20322 else if (PT >= ZV && dir > 0)
20323 xsignal0 (Qend_of_buffer);
20324 else
20326 struct text_pos pt;
20327 struct it it;
20328 int pt_x, target_x, pixel_width, pt_vpos;
20329 bool at_eol_p;
20330 bool overshoot_expected = false;
20331 bool target_is_eol_p = false;
20333 /* Setup the arena. */
20334 SET_TEXT_POS (pt, PT, PT_BYTE);
20335 start_display (&it, w, pt);
20337 if (it.cmp_it.id < 0
20338 && it.method == GET_FROM_STRING
20339 && it.area == TEXT_AREA
20340 && it.string_from_display_prop_p
20341 && (it.sp > 0 && it.stack[it.sp - 1].method == GET_FROM_BUFFER))
20342 overshoot_expected = true;
20344 /* Find the X coordinate of point. We start from the beginning
20345 of this or previous line to make sure we are before point in
20346 the logical order (since the move_it_* functions can only
20347 move forward). */
20348 reseat_at_previous_visible_line_start (&it);
20349 it.current_x = it.hpos = it.current_y = it.vpos = 0;
20350 if (IT_CHARPOS (it) != PT)
20351 move_it_to (&it, overshoot_expected ? PT - 1 : PT,
20352 -1, -1, -1, MOVE_TO_POS);
20353 pt_x = it.current_x;
20354 pt_vpos = it.vpos;
20355 if (dir > 0 || overshoot_expected)
20357 struct glyph_row *row = it.glyph_row;
20359 /* When point is at beginning of line, we don't have
20360 information about the glyph there loaded into struct
20361 it. Calling get_next_display_element fixes that. */
20362 if (pt_x == 0)
20363 get_next_display_element (&it);
20364 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
20365 it.glyph_row = NULL;
20366 PRODUCE_GLYPHS (&it); /* compute it.pixel_width */
20367 it.glyph_row = row;
20368 /* PRODUCE_GLYPHS advances it.current_x, so we must restore
20369 it, lest it will become out of sync with it's buffer
20370 position. */
20371 it.current_x = pt_x;
20373 else
20374 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
20375 pixel_width = it.pixel_width;
20376 if (overshoot_expected && at_eol_p)
20377 pixel_width = 0;
20378 else if (pixel_width <= 0)
20379 pixel_width = 1;
20381 /* If there's a display string at point, we are actually at the
20382 glyph to the left of point, so we need to correct the X
20383 coordinate. */
20384 if (overshoot_expected)
20385 pt_x += pixel_width;
20387 /* Compute target X coordinate, either to the left or to the
20388 right of point. On TTY frames, all characters have the same
20389 pixel width of 1, so we can use that. On GUI frames we don't
20390 have an easy way of getting at the pixel width of the
20391 character to the left of point, so we use a different method
20392 of getting to that place. */
20393 if (dir > 0)
20394 target_x = pt_x + pixel_width;
20395 else
20396 target_x = pt_x - (!FRAME_WINDOW_P (it.f)) * pixel_width;
20398 /* Target X coordinate could be one line above or below the line
20399 of point, in which case we need to adjust the target X
20400 coordinate. Also, if moving to the left, we need to begin at
20401 the left edge of the point's screen line. */
20402 if (dir < 0)
20404 if (pt_x > 0)
20406 start_display (&it, w, pt);
20407 reseat_at_previous_visible_line_start (&it);
20408 it.current_x = it.current_y = it.hpos = 0;
20409 if (pt_vpos != 0)
20410 move_it_by_lines (&it, pt_vpos);
20412 else
20414 move_it_by_lines (&it, -1);
20415 target_x = it.last_visible_x - !FRAME_WINDOW_P (it.f);
20416 target_is_eol_p = true;
20419 else
20421 if (at_eol_p
20422 || (target_x >= it.last_visible_x
20423 && it.line_wrap != TRUNCATE))
20425 if (pt_x > 0)
20426 move_it_by_lines (&it, 0);
20427 move_it_by_lines (&it, 1);
20428 target_x = 0;
20432 /* Move to the target X coordinate. */
20433 #ifdef HAVE_WINDOW_SYSTEM
20434 /* On GUI frames, as we don't know the X coordinate of the
20435 character to the left of point, moving point to the left
20436 requires walking, one grapheme cluster at a time, until we
20437 find ourself at a place immediately to the left of the
20438 character at point. */
20439 if (FRAME_WINDOW_P (it.f) && dir < 0)
20441 struct text_pos new_pos = it.current.pos;
20442 enum move_it_result rc = MOVE_X_REACHED;
20444 while (it.current_x + it.pixel_width <= target_x
20445 && rc == MOVE_X_REACHED)
20447 int new_x = it.current_x + it.pixel_width;
20449 new_pos = it.current.pos;
20450 if (new_x == it.current_x)
20451 new_x++;
20452 rc = move_it_in_display_line_to (&it, ZV, new_x,
20453 MOVE_TO_POS | MOVE_TO_X);
20454 if (ITERATOR_AT_END_OF_LINE_P (&it) && !target_is_eol_p)
20455 break;
20457 /* If we ended up on a composed character inside
20458 bidi-reordered text (e.g., Hebrew text with diacritics),
20459 the iterator gives us the buffer position of the last (in
20460 logical order) character of the composed grapheme cluster,
20461 which is not what we want. So we cheat: we compute the
20462 character position of the character that follows (in the
20463 logical order) the one where the above loop stopped. That
20464 character will appear on display to the left of point. */
20465 if (it.bidi_p
20466 && it.bidi_it.scan_dir == -1
20467 && new_pos.charpos - IT_CHARPOS (it) > 1)
20469 new_pos.charpos = IT_CHARPOS (it) + 1;
20470 new_pos.bytepos = CHAR_TO_BYTE (new_pos.charpos);
20472 it.current.pos = new_pos;
20474 else
20475 #endif
20476 if (it.current_x != target_x)
20477 move_it_in_display_line_to (&it, ZV, target_x, MOVE_TO_POS | MOVE_TO_X);
20479 /* When lines are truncated, the above loop will stop at the
20480 window edge. But we want to get to the end of line, even if
20481 it is beyond the window edge; automatic hscroll will then
20482 scroll the window to show point as appropriate. */
20483 if (target_is_eol_p && it.line_wrap == TRUNCATE
20484 && get_next_display_element (&it))
20486 struct text_pos new_pos = it.current.pos;
20488 while (!ITERATOR_AT_END_OF_LINE_P (&it))
20490 set_iterator_to_next (&it, 0);
20491 if (it.method == GET_FROM_BUFFER)
20492 new_pos = it.current.pos;
20493 if (!get_next_display_element (&it))
20494 break;
20497 it.current.pos = new_pos;
20500 /* If we ended up in a display string that covers point, move to
20501 buffer position to the right in the visual order. */
20502 if (dir > 0)
20504 while (IT_CHARPOS (it) == PT)
20506 set_iterator_to_next (&it, 0);
20507 if (!get_next_display_element (&it))
20508 break;
20512 /* Move point to that position. */
20513 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
20516 return make_number (PT);
20518 #undef ROW_GLYPH_NEWLINE_P
20522 /***********************************************************************
20523 Menu Bar
20524 ***********************************************************************/
20526 /* Redisplay the menu bar in the frame for window W.
20528 The menu bar of X frames that don't have X toolkit support is
20529 displayed in a special window W->frame->menu_bar_window.
20531 The menu bar of terminal frames is treated specially as far as
20532 glyph matrices are concerned. Menu bar lines are not part of
20533 windows, so the update is done directly on the frame matrix rows
20534 for the menu bar. */
20536 static void
20537 display_menu_bar (struct window *w)
20539 struct frame *f = XFRAME (WINDOW_FRAME (w));
20540 struct it it;
20541 Lisp_Object items;
20542 int i;
20544 /* Don't do all this for graphical frames. */
20545 #ifdef HAVE_NTGUI
20546 if (FRAME_W32_P (f))
20547 return;
20548 #endif
20549 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
20550 if (FRAME_X_P (f))
20551 return;
20552 #endif
20554 #ifdef HAVE_NS
20555 if (FRAME_NS_P (f))
20556 return;
20557 #endif /* HAVE_NS */
20559 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
20560 eassert (!FRAME_WINDOW_P (f));
20561 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
20562 it.first_visible_x = 0;
20563 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
20564 #elif defined (HAVE_X_WINDOWS) /* X without toolkit. */
20565 if (FRAME_WINDOW_P (f))
20567 /* Menu bar lines are displayed in the desired matrix of the
20568 dummy window menu_bar_window. */
20569 struct window *menu_w;
20570 menu_w = XWINDOW (f->menu_bar_window);
20571 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
20572 MENU_FACE_ID);
20573 it.first_visible_x = 0;
20574 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
20576 else
20577 #endif /* not USE_X_TOOLKIT and not USE_GTK */
20579 /* This is a TTY frame, i.e. character hpos/vpos are used as
20580 pixel x/y. */
20581 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
20582 MENU_FACE_ID);
20583 it.first_visible_x = 0;
20584 it.last_visible_x = FRAME_COLS (f);
20587 /* FIXME: This should be controlled by a user option. See the
20588 comments in redisplay_tool_bar and display_mode_line about
20589 this. */
20590 it.paragraph_embedding = L2R;
20592 /* Clear all rows of the menu bar. */
20593 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
20595 struct glyph_row *row = it.glyph_row + i;
20596 clear_glyph_row (row);
20597 row->enabled_p = 1;
20598 row->full_width_p = 1;
20601 /* Display all items of the menu bar. */
20602 items = FRAME_MENU_BAR_ITEMS (it.f);
20603 for (i = 0; i < ASIZE (items); i += 4)
20605 Lisp_Object string;
20607 /* Stop at nil string. */
20608 string = AREF (items, i + 1);
20609 if (NILP (string))
20610 break;
20612 /* Remember where item was displayed. */
20613 ASET (items, i + 3, make_number (it.hpos));
20615 /* Display the item, pad with one space. */
20616 if (it.current_x < it.last_visible_x)
20617 display_string (NULL, string, Qnil, 0, 0, &it,
20618 SCHARS (string) + 1, 0, 0, -1);
20621 /* Fill out the line with spaces. */
20622 if (it.current_x < it.last_visible_x)
20623 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
20625 /* Compute the total height of the lines. */
20626 compute_line_metrics (&it);
20631 /***********************************************************************
20632 Mode Line
20633 ***********************************************************************/
20635 /* Redisplay mode lines in the window tree whose root is WINDOW. If
20636 FORCE is non-zero, redisplay mode lines unconditionally.
20637 Otherwise, redisplay only mode lines that are garbaged. Value is
20638 the number of windows whose mode lines were redisplayed. */
20640 static int
20641 redisplay_mode_lines (Lisp_Object window, int force)
20643 int nwindows = 0;
20645 while (!NILP (window))
20647 struct window *w = XWINDOW (window);
20649 if (WINDOWP (w->contents))
20650 nwindows += redisplay_mode_lines (w->contents, force);
20651 else if (force
20652 || FRAME_GARBAGED_P (XFRAME (w->frame))
20653 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
20655 struct text_pos lpoint;
20656 struct buffer *old = current_buffer;
20658 /* Set the window's buffer for the mode line display. */
20659 SET_TEXT_POS (lpoint, PT, PT_BYTE);
20660 set_buffer_internal_1 (XBUFFER (w->contents));
20662 /* Point refers normally to the selected window. For any
20663 other window, set up appropriate value. */
20664 if (!EQ (window, selected_window))
20666 struct text_pos pt;
20668 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
20669 if (CHARPOS (pt) < BEGV)
20670 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
20671 else if (CHARPOS (pt) > (ZV - 1))
20672 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
20673 else
20674 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
20677 /* Display mode lines. */
20678 clear_glyph_matrix (w->desired_matrix);
20679 if (display_mode_lines (w))
20681 ++nwindows;
20682 w->must_be_updated_p = 1;
20685 /* Restore old settings. */
20686 set_buffer_internal_1 (old);
20687 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
20690 window = w->next;
20693 return nwindows;
20697 /* Display the mode and/or header line of window W. Value is the
20698 sum number of mode lines and header lines displayed. */
20700 static int
20701 display_mode_lines (struct window *w)
20703 Lisp_Object old_selected_window = selected_window;
20704 Lisp_Object old_selected_frame = selected_frame;
20705 Lisp_Object new_frame = w->frame;
20706 Lisp_Object old_frame_selected_window = XFRAME (new_frame)->selected_window;
20707 int n = 0;
20709 selected_frame = new_frame;
20710 /* FIXME: If we were to allow the mode-line's computation changing the buffer
20711 or window's point, then we'd need select_window_1 here as well. */
20712 XSETWINDOW (selected_window, w);
20713 XFRAME (new_frame)->selected_window = selected_window;
20715 /* These will be set while the mode line specs are processed. */
20716 line_number_displayed = 0;
20717 w->column_number_displayed = -1;
20719 if (WINDOW_WANTS_MODELINE_P (w))
20721 struct window *sel_w = XWINDOW (old_selected_window);
20723 /* Select mode line face based on the real selected window. */
20724 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
20725 BVAR (current_buffer, mode_line_format));
20726 ++n;
20729 if (WINDOW_WANTS_HEADER_LINE_P (w))
20731 display_mode_line (w, HEADER_LINE_FACE_ID,
20732 BVAR (current_buffer, header_line_format));
20733 ++n;
20736 XFRAME (new_frame)->selected_window = old_frame_selected_window;
20737 selected_frame = old_selected_frame;
20738 selected_window = old_selected_window;
20739 return n;
20743 /* Display mode or header line of window W. FACE_ID specifies which
20744 line to display; it is either MODE_LINE_FACE_ID or
20745 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
20746 display. Value is the pixel height of the mode/header line
20747 displayed. */
20749 static int
20750 display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
20752 struct it it;
20753 struct face *face;
20754 ptrdiff_t count = SPECPDL_INDEX ();
20756 init_iterator (&it, w, -1, -1, NULL, face_id);
20757 /* Don't extend on a previously drawn mode-line.
20758 This may happen if called from pos_visible_p. */
20759 it.glyph_row->enabled_p = 0;
20760 prepare_desired_row (it.glyph_row);
20762 it.glyph_row->mode_line_p = 1;
20764 /* FIXME: This should be controlled by a user option. But
20765 supporting such an option is not trivial, since the mode line is
20766 made up of many separate strings. */
20767 it.paragraph_embedding = L2R;
20769 record_unwind_protect (unwind_format_mode_line,
20770 format_mode_line_unwind_data (NULL, NULL, Qnil, 0));
20772 mode_line_target = MODE_LINE_DISPLAY;
20774 /* Temporarily make frame's keyboard the current kboard so that
20775 kboard-local variables in the mode_line_format will get the right
20776 values. */
20777 push_kboard (FRAME_KBOARD (it.f));
20778 record_unwind_save_match_data ();
20779 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
20780 pop_kboard ();
20782 unbind_to (count, Qnil);
20784 /* Fill up with spaces. */
20785 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
20787 compute_line_metrics (&it);
20788 it.glyph_row->full_width_p = 1;
20789 it.glyph_row->continued_p = 0;
20790 it.glyph_row->truncated_on_left_p = 0;
20791 it.glyph_row->truncated_on_right_p = 0;
20793 /* Make a 3D mode-line have a shadow at its right end. */
20794 face = FACE_FROM_ID (it.f, face_id);
20795 extend_face_to_end_of_line (&it);
20796 if (face->box != FACE_NO_BOX)
20798 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
20799 + it.glyph_row->used[TEXT_AREA] - 1);
20800 last->right_box_line_p = 1;
20803 return it.glyph_row->height;
20806 /* Move element ELT in LIST to the front of LIST.
20807 Return the updated list. */
20809 static Lisp_Object
20810 move_elt_to_front (Lisp_Object elt, Lisp_Object list)
20812 register Lisp_Object tail, prev;
20813 register Lisp_Object tem;
20815 tail = list;
20816 prev = Qnil;
20817 while (CONSP (tail))
20819 tem = XCAR (tail);
20821 if (EQ (elt, tem))
20823 /* Splice out the link TAIL. */
20824 if (NILP (prev))
20825 list = XCDR (tail);
20826 else
20827 Fsetcdr (prev, XCDR (tail));
20829 /* Now make it the first. */
20830 Fsetcdr (tail, list);
20831 return tail;
20833 else
20834 prev = tail;
20835 tail = XCDR (tail);
20836 QUIT;
20839 /* Not found--return unchanged LIST. */
20840 return list;
20843 /* Contribute ELT to the mode line for window IT->w. How it
20844 translates into text depends on its data type.
20846 IT describes the display environment in which we display, as usual.
20848 DEPTH is the depth in recursion. It is used to prevent
20849 infinite recursion here.
20851 FIELD_WIDTH is the number of characters the display of ELT should
20852 occupy in the mode line, and PRECISION is the maximum number of
20853 characters to display from ELT's representation. See
20854 display_string for details.
20856 Returns the hpos of the end of the text generated by ELT.
20858 PROPS is a property list to add to any string we encounter.
20860 If RISKY is nonzero, remove (disregard) any properties in any string
20861 we encounter, and ignore :eval and :propertize.
20863 The global variable `mode_line_target' determines whether the
20864 output is passed to `store_mode_line_noprop',
20865 `store_mode_line_string', or `display_string'. */
20867 static int
20868 display_mode_element (struct it *it, int depth, int field_width, int precision,
20869 Lisp_Object elt, Lisp_Object props, int risky)
20871 int n = 0, field, prec;
20872 int literal = 0;
20874 tail_recurse:
20875 if (depth > 100)
20876 elt = build_string ("*too-deep*");
20878 depth++;
20880 switch (XTYPE (elt))
20882 case Lisp_String:
20884 /* A string: output it and check for %-constructs within it. */
20885 unsigned char c;
20886 ptrdiff_t offset = 0;
20888 if (SCHARS (elt) > 0
20889 && (!NILP (props) || risky))
20891 Lisp_Object oprops, aelt;
20892 oprops = Ftext_properties_at (make_number (0), elt);
20894 /* If the starting string's properties are not what
20895 we want, translate the string. Also, if the string
20896 is risky, do that anyway. */
20898 if (NILP (Fequal (props, oprops)) || risky)
20900 /* If the starting string has properties,
20901 merge the specified ones onto the existing ones. */
20902 if (! NILP (oprops) && !risky)
20904 Lisp_Object tem;
20906 oprops = Fcopy_sequence (oprops);
20907 tem = props;
20908 while (CONSP (tem))
20910 oprops = Fplist_put (oprops, XCAR (tem),
20911 XCAR (XCDR (tem)));
20912 tem = XCDR (XCDR (tem));
20914 props = oprops;
20917 aelt = Fassoc (elt, mode_line_proptrans_alist);
20918 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
20920 /* AELT is what we want. Move it to the front
20921 without consing. */
20922 elt = XCAR (aelt);
20923 mode_line_proptrans_alist
20924 = move_elt_to_front (aelt, mode_line_proptrans_alist);
20926 else
20928 Lisp_Object tem;
20930 /* If AELT has the wrong props, it is useless.
20931 so get rid of it. */
20932 if (! NILP (aelt))
20933 mode_line_proptrans_alist
20934 = Fdelq (aelt, mode_line_proptrans_alist);
20936 elt = Fcopy_sequence (elt);
20937 Fset_text_properties (make_number (0), Flength (elt),
20938 props, elt);
20939 /* Add this item to mode_line_proptrans_alist. */
20940 mode_line_proptrans_alist
20941 = Fcons (Fcons (elt, props),
20942 mode_line_proptrans_alist);
20943 /* Truncate mode_line_proptrans_alist
20944 to at most 50 elements. */
20945 tem = Fnthcdr (make_number (50),
20946 mode_line_proptrans_alist);
20947 if (! NILP (tem))
20948 XSETCDR (tem, Qnil);
20953 offset = 0;
20955 if (literal)
20957 prec = precision - n;
20958 switch (mode_line_target)
20960 case MODE_LINE_NOPROP:
20961 case MODE_LINE_TITLE:
20962 n += store_mode_line_noprop (SSDATA (elt), -1, prec);
20963 break;
20964 case MODE_LINE_STRING:
20965 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
20966 break;
20967 case MODE_LINE_DISPLAY:
20968 n += display_string (NULL, elt, Qnil, 0, 0, it,
20969 0, prec, 0, STRING_MULTIBYTE (elt));
20970 break;
20973 break;
20976 /* Handle the non-literal case. */
20978 while ((precision <= 0 || n < precision)
20979 && SREF (elt, offset) != 0
20980 && (mode_line_target != MODE_LINE_DISPLAY
20981 || it->current_x < it->last_visible_x))
20983 ptrdiff_t last_offset = offset;
20985 /* Advance to end of string or next format specifier. */
20986 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
20989 if (offset - 1 != last_offset)
20991 ptrdiff_t nchars, nbytes;
20993 /* Output to end of string or up to '%'. Field width
20994 is length of string. Don't output more than
20995 PRECISION allows us. */
20996 offset--;
20998 prec = c_string_width (SDATA (elt) + last_offset,
20999 offset - last_offset, precision - n,
21000 &nchars, &nbytes);
21002 switch (mode_line_target)
21004 case MODE_LINE_NOPROP:
21005 case MODE_LINE_TITLE:
21006 n += store_mode_line_noprop (SSDATA (elt) + last_offset, 0, prec);
21007 break;
21008 case MODE_LINE_STRING:
21010 ptrdiff_t bytepos = last_offset;
21011 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
21012 ptrdiff_t endpos = (precision <= 0
21013 ? string_byte_to_char (elt, offset)
21014 : charpos + nchars);
21016 n += store_mode_line_string (NULL,
21017 Fsubstring (elt, make_number (charpos),
21018 make_number (endpos)),
21019 0, 0, 0, Qnil);
21021 break;
21022 case MODE_LINE_DISPLAY:
21024 ptrdiff_t bytepos = last_offset;
21025 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
21027 if (precision <= 0)
21028 nchars = string_byte_to_char (elt, offset) - charpos;
21029 n += display_string (NULL, elt, Qnil, 0, charpos,
21030 it, 0, nchars, 0,
21031 STRING_MULTIBYTE (elt));
21033 break;
21036 else /* c == '%' */
21038 ptrdiff_t percent_position = offset;
21040 /* Get the specified minimum width. Zero means
21041 don't pad. */
21042 field = 0;
21043 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
21044 field = field * 10 + c - '0';
21046 /* Don't pad beyond the total padding allowed. */
21047 if (field_width - n > 0 && field > field_width - n)
21048 field = field_width - n;
21050 /* Note that either PRECISION <= 0 or N < PRECISION. */
21051 prec = precision - n;
21053 if (c == 'M')
21054 n += display_mode_element (it, depth, field, prec,
21055 Vglobal_mode_string, props,
21056 risky);
21057 else if (c != 0)
21059 bool multibyte;
21060 ptrdiff_t bytepos, charpos;
21061 const char *spec;
21062 Lisp_Object string;
21064 bytepos = percent_position;
21065 charpos = (STRING_MULTIBYTE (elt)
21066 ? string_byte_to_char (elt, bytepos)
21067 : bytepos);
21068 spec = decode_mode_spec (it->w, c, field, &string);
21069 multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
21071 switch (mode_line_target)
21073 case MODE_LINE_NOPROP:
21074 case MODE_LINE_TITLE:
21075 n += store_mode_line_noprop (spec, field, prec);
21076 break;
21077 case MODE_LINE_STRING:
21079 Lisp_Object tem = build_string (spec);
21080 props = Ftext_properties_at (make_number (charpos), elt);
21081 /* Should only keep face property in props */
21082 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
21084 break;
21085 case MODE_LINE_DISPLAY:
21087 int nglyphs_before, nwritten;
21089 nglyphs_before = it->glyph_row->used[TEXT_AREA];
21090 nwritten = display_string (spec, string, elt,
21091 charpos, 0, it,
21092 field, prec, 0,
21093 multibyte);
21095 /* Assign to the glyphs written above the
21096 string where the `%x' came from, position
21097 of the `%'. */
21098 if (nwritten > 0)
21100 struct glyph *glyph
21101 = (it->glyph_row->glyphs[TEXT_AREA]
21102 + nglyphs_before);
21103 int i;
21105 for (i = 0; i < nwritten; ++i)
21107 glyph[i].object = elt;
21108 glyph[i].charpos = charpos;
21111 n += nwritten;
21114 break;
21117 else /* c == 0 */
21118 break;
21122 break;
21124 case Lisp_Symbol:
21125 /* A symbol: process the value of the symbol recursively
21126 as if it appeared here directly. Avoid error if symbol void.
21127 Special case: if value of symbol is a string, output the string
21128 literally. */
21130 register Lisp_Object tem;
21132 /* If the variable is not marked as risky to set
21133 then its contents are risky to use. */
21134 if (NILP (Fget (elt, Qrisky_local_variable)))
21135 risky = 1;
21137 tem = Fboundp (elt);
21138 if (!NILP (tem))
21140 tem = Fsymbol_value (elt);
21141 /* If value is a string, output that string literally:
21142 don't check for % within it. */
21143 if (STRINGP (tem))
21144 literal = 1;
21146 if (!EQ (tem, elt))
21148 /* Give up right away for nil or t. */
21149 elt = tem;
21150 goto tail_recurse;
21154 break;
21156 case Lisp_Cons:
21158 register Lisp_Object car, tem;
21160 /* A cons cell: five distinct cases.
21161 If first element is :eval or :propertize, do something special.
21162 If first element is a string or a cons, process all the elements
21163 and effectively concatenate them.
21164 If first element is a negative number, truncate displaying cdr to
21165 at most that many characters. If positive, pad (with spaces)
21166 to at least that many characters.
21167 If first element is a symbol, process the cadr or caddr recursively
21168 according to whether the symbol's value is non-nil or nil. */
21169 car = XCAR (elt);
21170 if (EQ (car, QCeval))
21172 /* An element of the form (:eval FORM) means evaluate FORM
21173 and use the result as mode line elements. */
21175 if (risky)
21176 break;
21178 if (CONSP (XCDR (elt)))
21180 Lisp_Object spec;
21181 spec = safe_eval (XCAR (XCDR (elt)));
21182 n += display_mode_element (it, depth, field_width - n,
21183 precision - n, spec, props,
21184 risky);
21187 else if (EQ (car, QCpropertize))
21189 /* An element of the form (:propertize ELT PROPS...)
21190 means display ELT but applying properties PROPS. */
21192 if (risky)
21193 break;
21195 if (CONSP (XCDR (elt)))
21196 n += display_mode_element (it, depth, field_width - n,
21197 precision - n, XCAR (XCDR (elt)),
21198 XCDR (XCDR (elt)), risky);
21200 else if (SYMBOLP (car))
21202 tem = Fboundp (car);
21203 elt = XCDR (elt);
21204 if (!CONSP (elt))
21205 goto invalid;
21206 /* elt is now the cdr, and we know it is a cons cell.
21207 Use its car if CAR has a non-nil value. */
21208 if (!NILP (tem))
21210 tem = Fsymbol_value (car);
21211 if (!NILP (tem))
21213 elt = XCAR (elt);
21214 goto tail_recurse;
21217 /* Symbol's value is nil (or symbol is unbound)
21218 Get the cddr of the original list
21219 and if possible find the caddr and use that. */
21220 elt = XCDR (elt);
21221 if (NILP (elt))
21222 break;
21223 else if (!CONSP (elt))
21224 goto invalid;
21225 elt = XCAR (elt);
21226 goto tail_recurse;
21228 else if (INTEGERP (car))
21230 register int lim = XINT (car);
21231 elt = XCDR (elt);
21232 if (lim < 0)
21234 /* Negative int means reduce maximum width. */
21235 if (precision <= 0)
21236 precision = -lim;
21237 else
21238 precision = min (precision, -lim);
21240 else if (lim > 0)
21242 /* Padding specified. Don't let it be more than
21243 current maximum. */
21244 if (precision > 0)
21245 lim = min (precision, lim);
21247 /* If that's more padding than already wanted, queue it.
21248 But don't reduce padding already specified even if
21249 that is beyond the current truncation point. */
21250 field_width = max (lim, field_width);
21252 goto tail_recurse;
21254 else if (STRINGP (car) || CONSP (car))
21256 Lisp_Object halftail = elt;
21257 int len = 0;
21259 while (CONSP (elt)
21260 && (precision <= 0 || n < precision))
21262 n += display_mode_element (it, depth,
21263 /* Do padding only after the last
21264 element in the list. */
21265 (! CONSP (XCDR (elt))
21266 ? field_width - n
21267 : 0),
21268 precision - n, XCAR (elt),
21269 props, risky);
21270 elt = XCDR (elt);
21271 len++;
21272 if ((len & 1) == 0)
21273 halftail = XCDR (halftail);
21274 /* Check for cycle. */
21275 if (EQ (halftail, elt))
21276 break;
21280 break;
21282 default:
21283 invalid:
21284 elt = build_string ("*invalid*");
21285 goto tail_recurse;
21288 /* Pad to FIELD_WIDTH. */
21289 if (field_width > 0 && n < field_width)
21291 switch (mode_line_target)
21293 case MODE_LINE_NOPROP:
21294 case MODE_LINE_TITLE:
21295 n += store_mode_line_noprop ("", field_width - n, 0);
21296 break;
21297 case MODE_LINE_STRING:
21298 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
21299 break;
21300 case MODE_LINE_DISPLAY:
21301 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
21302 0, 0, 0);
21303 break;
21307 return n;
21310 /* Store a mode-line string element in mode_line_string_list.
21312 If STRING is non-null, display that C string. Otherwise, the Lisp
21313 string LISP_STRING is displayed.
21315 FIELD_WIDTH is the minimum number of output glyphs to produce.
21316 If STRING has fewer characters than FIELD_WIDTH, pad to the right
21317 with spaces. FIELD_WIDTH <= 0 means don't pad.
21319 PRECISION is the maximum number of characters to output from
21320 STRING. PRECISION <= 0 means don't truncate the string.
21322 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
21323 properties to the string.
21325 PROPS are the properties to add to the string.
21326 The mode_line_string_face face property is always added to the string.
21329 static int
21330 store_mode_line_string (const char *string, Lisp_Object lisp_string, int copy_string,
21331 int field_width, int precision, Lisp_Object props)
21333 ptrdiff_t len;
21334 int n = 0;
21336 if (string != NULL)
21338 len = strlen (string);
21339 if (precision > 0 && len > precision)
21340 len = precision;
21341 lisp_string = make_string (string, len);
21342 if (NILP (props))
21343 props = mode_line_string_face_prop;
21344 else if (!NILP (mode_line_string_face))
21346 Lisp_Object face = Fplist_get (props, Qface);
21347 props = Fcopy_sequence (props);
21348 if (NILP (face))
21349 face = mode_line_string_face;
21350 else
21351 face = list2 (face, mode_line_string_face);
21352 props = Fplist_put (props, Qface, face);
21354 Fadd_text_properties (make_number (0), make_number (len),
21355 props, lisp_string);
21357 else
21359 len = XFASTINT (Flength (lisp_string));
21360 if (precision > 0 && len > precision)
21362 len = precision;
21363 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
21364 precision = -1;
21366 if (!NILP (mode_line_string_face))
21368 Lisp_Object face;
21369 if (NILP (props))
21370 props = Ftext_properties_at (make_number (0), lisp_string);
21371 face = Fplist_get (props, Qface);
21372 if (NILP (face))
21373 face = mode_line_string_face;
21374 else
21375 face = list2 (face, mode_line_string_face);
21376 props = list2 (Qface, face);
21377 if (copy_string)
21378 lisp_string = Fcopy_sequence (lisp_string);
21380 if (!NILP (props))
21381 Fadd_text_properties (make_number (0), make_number (len),
21382 props, lisp_string);
21385 if (len > 0)
21387 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
21388 n += len;
21391 if (field_width > len)
21393 field_width -= len;
21394 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
21395 if (!NILP (props))
21396 Fadd_text_properties (make_number (0), make_number (field_width),
21397 props, lisp_string);
21398 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
21399 n += field_width;
21402 return n;
21406 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
21407 1, 4, 0,
21408 doc: /* Format a string out of a mode line format specification.
21409 First arg FORMAT specifies the mode line format (see `mode-line-format'
21410 for details) to use.
21412 By default, the format is evaluated for the currently selected window.
21414 Optional second arg FACE specifies the face property to put on all
21415 characters for which no face is specified. The value nil means the
21416 default face. The value t means whatever face the window's mode line
21417 currently uses (either `mode-line' or `mode-line-inactive',
21418 depending on whether the window is the selected window or not).
21419 An integer value means the value string has no text
21420 properties.
21422 Optional third and fourth args WINDOW and BUFFER specify the window
21423 and buffer to use as the context for the formatting (defaults
21424 are the selected window and the WINDOW's buffer). */)
21425 (Lisp_Object format, Lisp_Object face,
21426 Lisp_Object window, Lisp_Object buffer)
21428 struct it it;
21429 int len;
21430 struct window *w;
21431 struct buffer *old_buffer = NULL;
21432 int face_id;
21433 int no_props = INTEGERP (face);
21434 ptrdiff_t count = SPECPDL_INDEX ();
21435 Lisp_Object str;
21436 int string_start = 0;
21438 w = decode_any_window (window);
21439 XSETWINDOW (window, w);
21441 if (NILP (buffer))
21442 buffer = w->contents;
21443 CHECK_BUFFER (buffer);
21445 /* Make formatting the modeline a non-op when noninteractive, otherwise
21446 there will be problems later caused by a partially initialized frame. */
21447 if (NILP (format) || noninteractive)
21448 return empty_unibyte_string;
21450 if (no_props)
21451 face = Qnil;
21453 face_id = (NILP (face) || EQ (face, Qdefault)) ? DEFAULT_FACE_ID
21454 : EQ (face, Qt) ? (EQ (window, selected_window)
21455 ? MODE_LINE_FACE_ID : MODE_LINE_INACTIVE_FACE_ID)
21456 : EQ (face, Qmode_line) ? MODE_LINE_FACE_ID
21457 : EQ (face, Qmode_line_inactive) ? MODE_LINE_INACTIVE_FACE_ID
21458 : EQ (face, Qheader_line) ? HEADER_LINE_FACE_ID
21459 : EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID
21460 : DEFAULT_FACE_ID;
21462 old_buffer = current_buffer;
21464 /* Save things including mode_line_proptrans_alist,
21465 and set that to nil so that we don't alter the outer value. */
21466 record_unwind_protect (unwind_format_mode_line,
21467 format_mode_line_unwind_data
21468 (XFRAME (WINDOW_FRAME (w)),
21469 old_buffer, selected_window, 1));
21470 mode_line_proptrans_alist = Qnil;
21472 Fselect_window (window, Qt);
21473 set_buffer_internal_1 (XBUFFER (buffer));
21475 init_iterator (&it, w, -1, -1, NULL, face_id);
21477 if (no_props)
21479 mode_line_target = MODE_LINE_NOPROP;
21480 mode_line_string_face_prop = Qnil;
21481 mode_line_string_list = Qnil;
21482 string_start = MODE_LINE_NOPROP_LEN (0);
21484 else
21486 mode_line_target = MODE_LINE_STRING;
21487 mode_line_string_list = Qnil;
21488 mode_line_string_face = face;
21489 mode_line_string_face_prop
21490 = NILP (face) ? Qnil : list2 (Qface, face);
21493 push_kboard (FRAME_KBOARD (it.f));
21494 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
21495 pop_kboard ();
21497 if (no_props)
21499 len = MODE_LINE_NOPROP_LEN (string_start);
21500 str = make_string (mode_line_noprop_buf + string_start, len);
21502 else
21504 mode_line_string_list = Fnreverse (mode_line_string_list);
21505 str = Fmapconcat (intern ("identity"), mode_line_string_list,
21506 empty_unibyte_string);
21509 unbind_to (count, Qnil);
21510 return str;
21513 /* Write a null-terminated, right justified decimal representation of
21514 the positive integer D to BUF using a minimal field width WIDTH. */
21516 static void
21517 pint2str (register char *buf, register int width, register ptrdiff_t d)
21519 register char *p = buf;
21521 if (d <= 0)
21522 *p++ = '0';
21523 else
21525 while (d > 0)
21527 *p++ = d % 10 + '0';
21528 d /= 10;
21532 for (width -= (int) (p - buf); width > 0; --width)
21533 *p++ = ' ';
21534 *p-- = '\0';
21535 while (p > buf)
21537 d = *buf;
21538 *buf++ = *p;
21539 *p-- = d;
21543 /* Write a null-terminated, right justified decimal and "human
21544 readable" representation of the nonnegative integer D to BUF using
21545 a minimal field width WIDTH. D should be smaller than 999.5e24. */
21547 static const char power_letter[] =
21549 0, /* no letter */
21550 'k', /* kilo */
21551 'M', /* mega */
21552 'G', /* giga */
21553 'T', /* tera */
21554 'P', /* peta */
21555 'E', /* exa */
21556 'Z', /* zetta */
21557 'Y' /* yotta */
21560 static void
21561 pint2hrstr (char *buf, int width, ptrdiff_t d)
21563 /* We aim to represent the nonnegative integer D as
21564 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
21565 ptrdiff_t quotient = d;
21566 int remainder = 0;
21567 /* -1 means: do not use TENTHS. */
21568 int tenths = -1;
21569 int exponent = 0;
21571 /* Length of QUOTIENT.TENTHS as a string. */
21572 int length;
21574 char * psuffix;
21575 char * p;
21577 if (quotient >= 1000)
21579 /* Scale to the appropriate EXPONENT. */
21582 remainder = quotient % 1000;
21583 quotient /= 1000;
21584 exponent++;
21586 while (quotient >= 1000);
21588 /* Round to nearest and decide whether to use TENTHS or not. */
21589 if (quotient <= 9)
21591 tenths = remainder / 100;
21592 if (remainder % 100 >= 50)
21594 if (tenths < 9)
21595 tenths++;
21596 else
21598 quotient++;
21599 if (quotient == 10)
21600 tenths = -1;
21601 else
21602 tenths = 0;
21606 else
21607 if (remainder >= 500)
21609 if (quotient < 999)
21610 quotient++;
21611 else
21613 quotient = 1;
21614 exponent++;
21615 tenths = 0;
21620 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
21621 if (tenths == -1 && quotient <= 99)
21622 if (quotient <= 9)
21623 length = 1;
21624 else
21625 length = 2;
21626 else
21627 length = 3;
21628 p = psuffix = buf + max (width, length);
21630 /* Print EXPONENT. */
21631 *psuffix++ = power_letter[exponent];
21632 *psuffix = '\0';
21634 /* Print TENTHS. */
21635 if (tenths >= 0)
21637 *--p = '0' + tenths;
21638 *--p = '.';
21641 /* Print QUOTIENT. */
21644 int digit = quotient % 10;
21645 *--p = '0' + digit;
21647 while ((quotient /= 10) != 0);
21649 /* Print leading spaces. */
21650 while (buf < p)
21651 *--p = ' ';
21654 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
21655 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
21656 type of CODING_SYSTEM. Return updated pointer into BUF. */
21658 static unsigned char invalid_eol_type[] = "(*invalid*)";
21660 static char *
21661 decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_flag)
21663 Lisp_Object val;
21664 bool multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
21665 const unsigned char *eol_str;
21666 int eol_str_len;
21667 /* The EOL conversion we are using. */
21668 Lisp_Object eoltype;
21670 val = CODING_SYSTEM_SPEC (coding_system);
21671 eoltype = Qnil;
21673 if (!VECTORP (val)) /* Not yet decided. */
21675 *buf++ = multibyte ? '-' : ' ';
21676 if (eol_flag)
21677 eoltype = eol_mnemonic_undecided;
21678 /* Don't mention EOL conversion if it isn't decided. */
21680 else
21682 Lisp_Object attrs;
21683 Lisp_Object eolvalue;
21685 attrs = AREF (val, 0);
21686 eolvalue = AREF (val, 2);
21688 *buf++ = multibyte
21689 ? XFASTINT (CODING_ATTR_MNEMONIC (attrs))
21690 : ' ';
21692 if (eol_flag)
21694 /* The EOL conversion that is normal on this system. */
21696 if (NILP (eolvalue)) /* Not yet decided. */
21697 eoltype = eol_mnemonic_undecided;
21698 else if (VECTORP (eolvalue)) /* Not yet decided. */
21699 eoltype = eol_mnemonic_undecided;
21700 else /* eolvalue is Qunix, Qdos, or Qmac. */
21701 eoltype = (EQ (eolvalue, Qunix)
21702 ? eol_mnemonic_unix
21703 : (EQ (eolvalue, Qdos) == 1
21704 ? eol_mnemonic_dos : eol_mnemonic_mac));
21708 if (eol_flag)
21710 /* Mention the EOL conversion if it is not the usual one. */
21711 if (STRINGP (eoltype))
21713 eol_str = SDATA (eoltype);
21714 eol_str_len = SBYTES (eoltype);
21716 else if (CHARACTERP (eoltype))
21718 unsigned char *tmp = alloca (MAX_MULTIBYTE_LENGTH);
21719 int c = XFASTINT (eoltype);
21720 eol_str_len = CHAR_STRING (c, tmp);
21721 eol_str = tmp;
21723 else
21725 eol_str = invalid_eol_type;
21726 eol_str_len = sizeof (invalid_eol_type) - 1;
21728 memcpy (buf, eol_str, eol_str_len);
21729 buf += eol_str_len;
21732 return buf;
21735 /* Return a string for the output of a mode line %-spec for window W,
21736 generated by character C. FIELD_WIDTH > 0 means pad the string
21737 returned with spaces to that value. Return a Lisp string in
21738 *STRING if the resulting string is taken from that Lisp string.
21740 Note we operate on the current buffer for most purposes. */
21742 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
21744 static const char *
21745 decode_mode_spec (struct window *w, register int c, int field_width,
21746 Lisp_Object *string)
21748 Lisp_Object obj;
21749 struct frame *f = XFRAME (WINDOW_FRAME (w));
21750 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
21751 /* We are going to use f->decode_mode_spec_buffer as the buffer to
21752 produce strings from numerical values, so limit preposterously
21753 large values of FIELD_WIDTH to avoid overrunning the buffer's
21754 end. The size of the buffer is enough for FRAME_MESSAGE_BUF_SIZE
21755 bytes plus the terminating null. */
21756 int width = min (field_width, FRAME_MESSAGE_BUF_SIZE (f));
21757 struct buffer *b = current_buffer;
21759 obj = Qnil;
21760 *string = Qnil;
21762 switch (c)
21764 case '*':
21765 if (!NILP (BVAR (b, read_only)))
21766 return "%";
21767 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21768 return "*";
21769 return "-";
21771 case '+':
21772 /* This differs from %* only for a modified read-only buffer. */
21773 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21774 return "*";
21775 if (!NILP (BVAR (b, read_only)))
21776 return "%";
21777 return "-";
21779 case '&':
21780 /* This differs from %* in ignoring read-only-ness. */
21781 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21782 return "*";
21783 return "-";
21785 case '%':
21786 return "%";
21788 case '[':
21790 int i;
21791 char *p;
21793 if (command_loop_level > 5)
21794 return "[[[... ";
21795 p = decode_mode_spec_buf;
21796 for (i = 0; i < command_loop_level; i++)
21797 *p++ = '[';
21798 *p = 0;
21799 return decode_mode_spec_buf;
21802 case ']':
21804 int i;
21805 char *p;
21807 if (command_loop_level > 5)
21808 return " ...]]]";
21809 p = decode_mode_spec_buf;
21810 for (i = 0; i < command_loop_level; i++)
21811 *p++ = ']';
21812 *p = 0;
21813 return decode_mode_spec_buf;
21816 case '-':
21818 register int i;
21820 /* Let lots_of_dashes be a string of infinite length. */
21821 if (mode_line_target == MODE_LINE_NOPROP
21822 || mode_line_target == MODE_LINE_STRING)
21823 return "--";
21824 if (field_width <= 0
21825 || field_width > sizeof (lots_of_dashes))
21827 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
21828 decode_mode_spec_buf[i] = '-';
21829 decode_mode_spec_buf[i] = '\0';
21830 return decode_mode_spec_buf;
21832 else
21833 return lots_of_dashes;
21836 case 'b':
21837 obj = BVAR (b, name);
21838 break;
21840 case 'c':
21841 /* %c and %l are ignored in `frame-title-format'.
21842 (In redisplay_internal, the frame title is drawn _before_ the
21843 windows are updated, so the stuff which depends on actual
21844 window contents (such as %l) may fail to render properly, or
21845 even crash emacs.) */
21846 if (mode_line_target == MODE_LINE_TITLE)
21847 return "";
21848 else
21850 ptrdiff_t col = current_column ();
21851 w->column_number_displayed = col;
21852 pint2str (decode_mode_spec_buf, width, col);
21853 return decode_mode_spec_buf;
21856 case 'e':
21857 #ifndef SYSTEM_MALLOC
21859 if (NILP (Vmemory_full))
21860 return "";
21861 else
21862 return "!MEM FULL! ";
21864 #else
21865 return "";
21866 #endif
21868 case 'F':
21869 /* %F displays the frame name. */
21870 if (!NILP (f->title))
21871 return SSDATA (f->title);
21872 if (f->explicit_name || ! FRAME_WINDOW_P (f))
21873 return SSDATA (f->name);
21874 return "Emacs";
21876 case 'f':
21877 obj = BVAR (b, filename);
21878 break;
21880 case 'i':
21882 ptrdiff_t size = ZV - BEGV;
21883 pint2str (decode_mode_spec_buf, width, size);
21884 return decode_mode_spec_buf;
21887 case 'I':
21889 ptrdiff_t size = ZV - BEGV;
21890 pint2hrstr (decode_mode_spec_buf, width, size);
21891 return decode_mode_spec_buf;
21894 case 'l':
21896 ptrdiff_t startpos, startpos_byte, line, linepos, linepos_byte;
21897 ptrdiff_t topline, nlines, height;
21898 ptrdiff_t junk;
21900 /* %c and %l are ignored in `frame-title-format'. */
21901 if (mode_line_target == MODE_LINE_TITLE)
21902 return "";
21904 startpos = marker_position (w->start);
21905 startpos_byte = marker_byte_position (w->start);
21906 height = WINDOW_TOTAL_LINES (w);
21908 /* If we decided that this buffer isn't suitable for line numbers,
21909 don't forget that too fast. */
21910 if (w->base_line_pos == -1)
21911 goto no_value;
21913 /* If the buffer is very big, don't waste time. */
21914 if (INTEGERP (Vline_number_display_limit)
21915 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
21917 w->base_line_pos = 0;
21918 w->base_line_number = 0;
21919 goto no_value;
21922 if (w->base_line_number > 0
21923 && w->base_line_pos > 0
21924 && w->base_line_pos <= startpos)
21926 line = w->base_line_number;
21927 linepos = w->base_line_pos;
21928 linepos_byte = buf_charpos_to_bytepos (b, linepos);
21930 else
21932 line = 1;
21933 linepos = BUF_BEGV (b);
21934 linepos_byte = BUF_BEGV_BYTE (b);
21937 /* Count lines from base line to window start position. */
21938 nlines = display_count_lines (linepos_byte,
21939 startpos_byte,
21940 startpos, &junk);
21942 topline = nlines + line;
21944 /* Determine a new base line, if the old one is too close
21945 or too far away, or if we did not have one.
21946 "Too close" means it's plausible a scroll-down would
21947 go back past it. */
21948 if (startpos == BUF_BEGV (b))
21950 w->base_line_number = topline;
21951 w->base_line_pos = BUF_BEGV (b);
21953 else if (nlines < height + 25 || nlines > height * 3 + 50
21954 || linepos == BUF_BEGV (b))
21956 ptrdiff_t limit = BUF_BEGV (b);
21957 ptrdiff_t limit_byte = BUF_BEGV_BYTE (b);
21958 ptrdiff_t position;
21959 ptrdiff_t distance =
21960 (height * 2 + 30) * line_number_display_limit_width;
21962 if (startpos - distance > limit)
21964 limit = startpos - distance;
21965 limit_byte = CHAR_TO_BYTE (limit);
21968 nlines = display_count_lines (startpos_byte,
21969 limit_byte,
21970 - (height * 2 + 30),
21971 &position);
21972 /* If we couldn't find the lines we wanted within
21973 line_number_display_limit_width chars per line,
21974 give up on line numbers for this window. */
21975 if (position == limit_byte && limit == startpos - distance)
21977 w->base_line_pos = -1;
21978 w->base_line_number = 0;
21979 goto no_value;
21982 w->base_line_number = topline - nlines;
21983 w->base_line_pos = BYTE_TO_CHAR (position);
21986 /* Now count lines from the start pos to point. */
21987 nlines = display_count_lines (startpos_byte,
21988 PT_BYTE, PT, &junk);
21990 /* Record that we did display the line number. */
21991 line_number_displayed = 1;
21993 /* Make the string to show. */
21994 pint2str (decode_mode_spec_buf, width, topline + nlines);
21995 return decode_mode_spec_buf;
21996 no_value:
21998 char* p = decode_mode_spec_buf;
21999 int pad = width - 2;
22000 while (pad-- > 0)
22001 *p++ = ' ';
22002 *p++ = '?';
22003 *p++ = '?';
22004 *p = '\0';
22005 return decode_mode_spec_buf;
22008 break;
22010 case 'm':
22011 obj = BVAR (b, mode_name);
22012 break;
22014 case 'n':
22015 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
22016 return " Narrow";
22017 break;
22019 case 'p':
22021 ptrdiff_t pos = marker_position (w->start);
22022 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
22024 if (w->window_end_pos <= BUF_Z (b) - BUF_ZV (b))
22026 if (pos <= BUF_BEGV (b))
22027 return "All";
22028 else
22029 return "Bottom";
22031 else if (pos <= BUF_BEGV (b))
22032 return "Top";
22033 else
22035 if (total > 1000000)
22036 /* Do it differently for a large value, to avoid overflow. */
22037 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
22038 else
22039 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
22040 /* We can't normally display a 3-digit number,
22041 so get us a 2-digit number that is close. */
22042 if (total == 100)
22043 total = 99;
22044 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
22045 return decode_mode_spec_buf;
22049 /* Display percentage of size above the bottom of the screen. */
22050 case 'P':
22052 ptrdiff_t toppos = marker_position (w->start);
22053 ptrdiff_t botpos = BUF_Z (b) - w->window_end_pos;
22054 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
22056 if (botpos >= BUF_ZV (b))
22058 if (toppos <= BUF_BEGV (b))
22059 return "All";
22060 else
22061 return "Bottom";
22063 else
22065 if (total > 1000000)
22066 /* Do it differently for a large value, to avoid overflow. */
22067 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
22068 else
22069 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
22070 /* We can't normally display a 3-digit number,
22071 so get us a 2-digit number that is close. */
22072 if (total == 100)
22073 total = 99;
22074 if (toppos <= BUF_BEGV (b))
22075 sprintf (decode_mode_spec_buf, "Top%2"pD"d%%", total);
22076 else
22077 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
22078 return decode_mode_spec_buf;
22082 case 's':
22083 /* status of process */
22084 obj = Fget_buffer_process (Fcurrent_buffer ());
22085 if (NILP (obj))
22086 return "no process";
22087 #ifndef MSDOS
22088 obj = Fsymbol_name (Fprocess_status (obj));
22089 #endif
22090 break;
22092 case '@':
22094 ptrdiff_t count = inhibit_garbage_collection ();
22095 Lisp_Object val = call1 (intern ("file-remote-p"),
22096 BVAR (current_buffer, directory));
22097 unbind_to (count, Qnil);
22099 if (NILP (val))
22100 return "-";
22101 else
22102 return "@";
22105 case 'z':
22106 /* coding-system (not including end-of-line format) */
22107 case 'Z':
22108 /* coding-system (including end-of-line type) */
22110 int eol_flag = (c == 'Z');
22111 char *p = decode_mode_spec_buf;
22113 if (! FRAME_WINDOW_P (f))
22115 /* No need to mention EOL here--the terminal never needs
22116 to do EOL conversion. */
22117 p = decode_mode_spec_coding (CODING_ID_NAME
22118 (FRAME_KEYBOARD_CODING (f)->id),
22119 p, 0);
22120 p = decode_mode_spec_coding (CODING_ID_NAME
22121 (FRAME_TERMINAL_CODING (f)->id),
22122 p, 0);
22124 p = decode_mode_spec_coding (BVAR (b, buffer_file_coding_system),
22125 p, eol_flag);
22127 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
22128 #ifdef subprocesses
22129 obj = Fget_buffer_process (Fcurrent_buffer ());
22130 if (PROCESSP (obj))
22132 p = decode_mode_spec_coding
22133 (XPROCESS (obj)->decode_coding_system, p, eol_flag);
22134 p = decode_mode_spec_coding
22135 (XPROCESS (obj)->encode_coding_system, p, eol_flag);
22137 #endif /* subprocesses */
22138 #endif /* 0 */
22139 *p = 0;
22140 return decode_mode_spec_buf;
22144 if (STRINGP (obj))
22146 *string = obj;
22147 return SSDATA (obj);
22149 else
22150 return "";
22154 /* Count up to COUNT lines starting from START_BYTE. COUNT negative
22155 means count lines back from START_BYTE. But don't go beyond
22156 LIMIT_BYTE. Return the number of lines thus found (always
22157 nonnegative).
22159 Set *BYTE_POS_PTR to the byte position where we stopped. This is
22160 either the position COUNT lines after/before START_BYTE, if we
22161 found COUNT lines, or LIMIT_BYTE if we hit the limit before finding
22162 COUNT lines. */
22164 static ptrdiff_t
22165 display_count_lines (ptrdiff_t start_byte,
22166 ptrdiff_t limit_byte, ptrdiff_t count,
22167 ptrdiff_t *byte_pos_ptr)
22169 register unsigned char *cursor;
22170 unsigned char *base;
22172 register ptrdiff_t ceiling;
22173 register unsigned char *ceiling_addr;
22174 ptrdiff_t orig_count = count;
22176 /* If we are not in selective display mode,
22177 check only for newlines. */
22178 int selective_display = (!NILP (BVAR (current_buffer, selective_display))
22179 && !INTEGERP (BVAR (current_buffer, selective_display)));
22181 if (count > 0)
22183 while (start_byte < limit_byte)
22185 ceiling = BUFFER_CEILING_OF (start_byte);
22186 ceiling = min (limit_byte - 1, ceiling);
22187 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
22188 base = (cursor = BYTE_POS_ADDR (start_byte));
22192 if (selective_display)
22194 while (*cursor != '\n' && *cursor != 015
22195 && ++cursor != ceiling_addr)
22196 continue;
22197 if (cursor == ceiling_addr)
22198 break;
22200 else
22202 cursor = memchr (cursor, '\n', ceiling_addr - cursor);
22203 if (! cursor)
22204 break;
22207 cursor++;
22209 if (--count == 0)
22211 start_byte += cursor - base;
22212 *byte_pos_ptr = start_byte;
22213 return orig_count;
22216 while (cursor < ceiling_addr);
22218 start_byte += ceiling_addr - base;
22221 else
22223 while (start_byte > limit_byte)
22225 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
22226 ceiling = max (limit_byte, ceiling);
22227 ceiling_addr = BYTE_POS_ADDR (ceiling);
22228 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
22229 while (1)
22231 if (selective_display)
22233 while (--cursor >= ceiling_addr
22234 && *cursor != '\n' && *cursor != 015)
22235 continue;
22236 if (cursor < ceiling_addr)
22237 break;
22239 else
22241 cursor = memrchr (ceiling_addr, '\n', cursor - ceiling_addr);
22242 if (! cursor)
22243 break;
22246 if (++count == 0)
22248 start_byte += cursor - base + 1;
22249 *byte_pos_ptr = start_byte;
22250 /* When scanning backwards, we should
22251 not count the newline posterior to which we stop. */
22252 return - orig_count - 1;
22255 start_byte += ceiling_addr - base;
22259 *byte_pos_ptr = limit_byte;
22261 if (count < 0)
22262 return - orig_count + count;
22263 return orig_count - count;
22269 /***********************************************************************
22270 Displaying strings
22271 ***********************************************************************/
22273 /* Display a NUL-terminated string, starting with index START.
22275 If STRING is non-null, display that C string. Otherwise, the Lisp
22276 string LISP_STRING is displayed. There's a case that STRING is
22277 non-null and LISP_STRING is not nil. It means STRING is a string
22278 data of LISP_STRING. In that case, we display LISP_STRING while
22279 ignoring its text properties.
22281 If FACE_STRING is not nil, FACE_STRING_POS is a position in
22282 FACE_STRING. Display STRING or LISP_STRING with the face at
22283 FACE_STRING_POS in FACE_STRING:
22285 Display the string in the environment given by IT, but use the
22286 standard display table, temporarily.
22288 FIELD_WIDTH is the minimum number of output glyphs to produce.
22289 If STRING has fewer characters than FIELD_WIDTH, pad to the right
22290 with spaces. If STRING has more characters, more than FIELD_WIDTH
22291 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
22293 PRECISION is the maximum number of characters to output from
22294 STRING. PRECISION < 0 means don't truncate the string.
22296 This is roughly equivalent to printf format specifiers:
22298 FIELD_WIDTH PRECISION PRINTF
22299 ----------------------------------------
22300 -1 -1 %s
22301 -1 10 %.10s
22302 10 -1 %10s
22303 20 10 %20.10s
22305 MULTIBYTE zero means do not display multibyte chars, > 0 means do
22306 display them, and < 0 means obey the current buffer's value of
22307 enable_multibyte_characters.
22309 Value is the number of columns displayed. */
22311 static int
22312 display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_string,
22313 ptrdiff_t face_string_pos, ptrdiff_t start, struct it *it,
22314 int field_width, int precision, int max_x, int multibyte)
22316 int hpos_at_start = it->hpos;
22317 int saved_face_id = it->face_id;
22318 struct glyph_row *row = it->glyph_row;
22319 ptrdiff_t it_charpos;
22321 /* Initialize the iterator IT for iteration over STRING beginning
22322 with index START. */
22323 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
22324 precision, field_width, multibyte);
22325 if (string && STRINGP (lisp_string))
22326 /* LISP_STRING is the one returned by decode_mode_spec. We should
22327 ignore its text properties. */
22328 it->stop_charpos = it->end_charpos;
22330 /* If displaying STRING, set up the face of the iterator from
22331 FACE_STRING, if that's given. */
22332 if (STRINGP (face_string))
22334 ptrdiff_t endptr;
22335 struct face *face;
22337 it->face_id
22338 = face_at_string_position (it->w, face_string, face_string_pos,
22339 0, it->region_beg_charpos,
22340 it->region_end_charpos,
22341 &endptr, it->base_face_id, 0);
22342 face = FACE_FROM_ID (it->f, it->face_id);
22343 it->face_box_p = face->box != FACE_NO_BOX;
22346 /* Set max_x to the maximum allowed X position. Don't let it go
22347 beyond the right edge of the window. */
22348 if (max_x <= 0)
22349 max_x = it->last_visible_x;
22350 else
22351 max_x = min (max_x, it->last_visible_x);
22353 /* Skip over display elements that are not visible. because IT->w is
22354 hscrolled. */
22355 if (it->current_x < it->first_visible_x)
22356 move_it_in_display_line_to (it, 100000, it->first_visible_x,
22357 MOVE_TO_POS | MOVE_TO_X);
22359 row->ascent = it->max_ascent;
22360 row->height = it->max_ascent + it->max_descent;
22361 row->phys_ascent = it->max_phys_ascent;
22362 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
22363 row->extra_line_spacing = it->max_extra_line_spacing;
22365 if (STRINGP (it->string))
22366 it_charpos = IT_STRING_CHARPOS (*it);
22367 else
22368 it_charpos = IT_CHARPOS (*it);
22370 /* This condition is for the case that we are called with current_x
22371 past last_visible_x. */
22372 while (it->current_x < max_x)
22374 int x_before, x, n_glyphs_before, i, nglyphs;
22376 /* Get the next display element. */
22377 if (!get_next_display_element (it))
22378 break;
22380 /* Produce glyphs. */
22381 x_before = it->current_x;
22382 n_glyphs_before = row->used[TEXT_AREA];
22383 PRODUCE_GLYPHS (it);
22385 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
22386 i = 0;
22387 x = x_before;
22388 while (i < nglyphs)
22390 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
22392 if (it->line_wrap != TRUNCATE
22393 && x + glyph->pixel_width > max_x)
22395 /* End of continued line or max_x reached. */
22396 if (CHAR_GLYPH_PADDING_P (*glyph))
22398 /* A wide character is unbreakable. */
22399 if (row->reversed_p)
22400 unproduce_glyphs (it, row->used[TEXT_AREA]
22401 - n_glyphs_before);
22402 row->used[TEXT_AREA] = n_glyphs_before;
22403 it->current_x = x_before;
22405 else
22407 if (row->reversed_p)
22408 unproduce_glyphs (it, row->used[TEXT_AREA]
22409 - (n_glyphs_before + i));
22410 row->used[TEXT_AREA] = n_glyphs_before + i;
22411 it->current_x = x;
22413 break;
22415 else if (x + glyph->pixel_width >= it->first_visible_x)
22417 /* Glyph is at least partially visible. */
22418 ++it->hpos;
22419 if (x < it->first_visible_x)
22420 row->x = x - it->first_visible_x;
22422 else
22424 /* Glyph is off the left margin of the display area.
22425 Should not happen. */
22426 emacs_abort ();
22429 row->ascent = max (row->ascent, it->max_ascent);
22430 row->height = max (row->height, it->max_ascent + it->max_descent);
22431 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
22432 row->phys_height = max (row->phys_height,
22433 it->max_phys_ascent + it->max_phys_descent);
22434 row->extra_line_spacing = max (row->extra_line_spacing,
22435 it->max_extra_line_spacing);
22436 x += glyph->pixel_width;
22437 ++i;
22440 /* Stop if max_x reached. */
22441 if (i < nglyphs)
22442 break;
22444 /* Stop at line ends. */
22445 if (ITERATOR_AT_END_OF_LINE_P (it))
22447 it->continuation_lines_width = 0;
22448 break;
22451 set_iterator_to_next (it, 1);
22452 if (STRINGP (it->string))
22453 it_charpos = IT_STRING_CHARPOS (*it);
22454 else
22455 it_charpos = IT_CHARPOS (*it);
22457 /* Stop if truncating at the right edge. */
22458 if (it->line_wrap == TRUNCATE
22459 && it->current_x >= it->last_visible_x)
22461 /* Add truncation mark, but don't do it if the line is
22462 truncated at a padding space. */
22463 if (it_charpos < it->string_nchars)
22465 if (!FRAME_WINDOW_P (it->f))
22467 int ii, n;
22469 if (it->current_x > it->last_visible_x)
22471 if (!row->reversed_p)
22473 for (ii = row->used[TEXT_AREA] - 1; ii > 0; --ii)
22474 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
22475 break;
22477 else
22479 for (ii = 0; ii < row->used[TEXT_AREA]; ii++)
22480 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
22481 break;
22482 unproduce_glyphs (it, ii + 1);
22483 ii = row->used[TEXT_AREA] - (ii + 1);
22485 for (n = row->used[TEXT_AREA]; ii < n; ++ii)
22487 row->used[TEXT_AREA] = ii;
22488 produce_special_glyphs (it, IT_TRUNCATION);
22491 produce_special_glyphs (it, IT_TRUNCATION);
22493 row->truncated_on_right_p = 1;
22495 break;
22499 /* Maybe insert a truncation at the left. */
22500 if (it->first_visible_x
22501 && it_charpos > 0)
22503 if (!FRAME_WINDOW_P (it->f)
22504 || (row->reversed_p
22505 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
22506 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
22507 insert_left_trunc_glyphs (it);
22508 row->truncated_on_left_p = 1;
22511 it->face_id = saved_face_id;
22513 /* Value is number of columns displayed. */
22514 return it->hpos - hpos_at_start;
22519 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
22520 appears as an element of LIST or as the car of an element of LIST.
22521 If PROPVAL is a list, compare each element against LIST in that
22522 way, and return 1/2 if any element of PROPVAL is found in LIST.
22523 Otherwise return 0. This function cannot quit.
22524 The return value is 2 if the text is invisible but with an ellipsis
22525 and 1 if it's invisible and without an ellipsis. */
22528 invisible_p (register Lisp_Object propval, Lisp_Object list)
22530 register Lisp_Object tail, proptail;
22532 for (tail = list; CONSP (tail); tail = XCDR (tail))
22534 register Lisp_Object tem;
22535 tem = XCAR (tail);
22536 if (EQ (propval, tem))
22537 return 1;
22538 if (CONSP (tem) && EQ (propval, XCAR (tem)))
22539 return NILP (XCDR (tem)) ? 1 : 2;
22542 if (CONSP (propval))
22544 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
22546 Lisp_Object propelt;
22547 propelt = XCAR (proptail);
22548 for (tail = list; CONSP (tail); tail = XCDR (tail))
22550 register Lisp_Object tem;
22551 tem = XCAR (tail);
22552 if (EQ (propelt, tem))
22553 return 1;
22554 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
22555 return NILP (XCDR (tem)) ? 1 : 2;
22560 return 0;
22563 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
22564 doc: /* Non-nil if the property makes the text invisible.
22565 POS-OR-PROP can be a marker or number, in which case it is taken to be
22566 a position in the current buffer and the value of the `invisible' property
22567 is checked; or it can be some other value, which is then presumed to be the
22568 value of the `invisible' property of the text of interest.
22569 The non-nil value returned can be t for truly invisible text or something
22570 else if the text is replaced by an ellipsis. */)
22571 (Lisp_Object pos_or_prop)
22573 Lisp_Object prop
22574 = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
22575 ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
22576 : pos_or_prop);
22577 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
22578 return (invis == 0 ? Qnil
22579 : invis == 1 ? Qt
22580 : make_number (invis));
22583 /* Calculate a width or height in pixels from a specification using
22584 the following elements:
22586 SPEC ::=
22587 NUM - a (fractional) multiple of the default font width/height
22588 (NUM) - specifies exactly NUM pixels
22589 UNIT - a fixed number of pixels, see below.
22590 ELEMENT - size of a display element in pixels, see below.
22591 (NUM . SPEC) - equals NUM * SPEC
22592 (+ SPEC SPEC ...) - add pixel values
22593 (- SPEC SPEC ...) - subtract pixel values
22594 (- SPEC) - negate pixel value
22596 NUM ::=
22597 INT or FLOAT - a number constant
22598 SYMBOL - use symbol's (buffer local) variable binding.
22600 UNIT ::=
22601 in - pixels per inch *)
22602 mm - pixels per 1/1000 meter *)
22603 cm - pixels per 1/100 meter *)
22604 width - width of current font in pixels.
22605 height - height of current font in pixels.
22607 *) using the ratio(s) defined in display-pixels-per-inch.
22609 ELEMENT ::=
22611 left-fringe - left fringe width in pixels
22612 right-fringe - right fringe width in pixels
22614 left-margin - left margin width in pixels
22615 right-margin - right margin width in pixels
22617 scroll-bar - scroll-bar area width in pixels
22619 Examples:
22621 Pixels corresponding to 5 inches:
22622 (5 . in)
22624 Total width of non-text areas on left side of window (if scroll-bar is on left):
22625 '(space :width (+ left-fringe left-margin scroll-bar))
22627 Align to first text column (in header line):
22628 '(space :align-to 0)
22630 Align to middle of text area minus half the width of variable `my-image'
22631 containing a loaded image:
22632 '(space :align-to (0.5 . (- text my-image)))
22634 Width of left margin minus width of 1 character in the default font:
22635 '(space :width (- left-margin 1))
22637 Width of left margin minus width of 2 characters in the current font:
22638 '(space :width (- left-margin (2 . width)))
22640 Center 1 character over left-margin (in header line):
22641 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
22643 Different ways to express width of left fringe plus left margin minus one pixel:
22644 '(space :width (- (+ left-fringe left-margin) (1)))
22645 '(space :width (+ left-fringe left-margin (- (1))))
22646 '(space :width (+ left-fringe left-margin (-1)))
22650 static int
22651 calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
22652 struct font *font, int width_p, int *align_to)
22654 double pixels;
22656 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
22657 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
22659 if (NILP (prop))
22660 return OK_PIXELS (0);
22662 eassert (FRAME_LIVE_P (it->f));
22664 if (SYMBOLP (prop))
22666 if (SCHARS (SYMBOL_NAME (prop)) == 2)
22668 char *unit = SSDATA (SYMBOL_NAME (prop));
22670 if (unit[0] == 'i' && unit[1] == 'n')
22671 pixels = 1.0;
22672 else if (unit[0] == 'm' && unit[1] == 'm')
22673 pixels = 25.4;
22674 else if (unit[0] == 'c' && unit[1] == 'm')
22675 pixels = 2.54;
22676 else
22677 pixels = 0;
22678 if (pixels > 0)
22680 double ppi = (width_p ? FRAME_RES_X (it->f)
22681 : FRAME_RES_Y (it->f));
22683 if (ppi > 0)
22684 return OK_PIXELS (ppi / pixels);
22685 return 0;
22689 #ifdef HAVE_WINDOW_SYSTEM
22690 if (EQ (prop, Qheight))
22691 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
22692 if (EQ (prop, Qwidth))
22693 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
22694 #else
22695 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
22696 return OK_PIXELS (1);
22697 #endif
22699 if (EQ (prop, Qtext))
22700 return OK_PIXELS (width_p
22701 ? window_box_width (it->w, TEXT_AREA)
22702 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
22704 if (align_to && *align_to < 0)
22706 *res = 0;
22707 if (EQ (prop, Qleft))
22708 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
22709 if (EQ (prop, Qright))
22710 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
22711 if (EQ (prop, Qcenter))
22712 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
22713 + window_box_width (it->w, TEXT_AREA) / 2);
22714 if (EQ (prop, Qleft_fringe))
22715 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22716 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
22717 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
22718 if (EQ (prop, Qright_fringe))
22719 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22720 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
22721 : window_box_right_offset (it->w, TEXT_AREA));
22722 if (EQ (prop, Qleft_margin))
22723 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
22724 if (EQ (prop, Qright_margin))
22725 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
22726 if (EQ (prop, Qscroll_bar))
22727 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
22729 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
22730 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22731 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
22732 : 0)));
22734 else
22736 if (EQ (prop, Qleft_fringe))
22737 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
22738 if (EQ (prop, Qright_fringe))
22739 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
22740 if (EQ (prop, Qleft_margin))
22741 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
22742 if (EQ (prop, Qright_margin))
22743 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
22744 if (EQ (prop, Qscroll_bar))
22745 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
22748 prop = buffer_local_value_1 (prop, it->w->contents);
22749 if (EQ (prop, Qunbound))
22750 prop = Qnil;
22753 if (INTEGERP (prop) || FLOATP (prop))
22755 int base_unit = (width_p
22756 ? FRAME_COLUMN_WIDTH (it->f)
22757 : FRAME_LINE_HEIGHT (it->f));
22758 return OK_PIXELS (XFLOATINT (prop) * base_unit);
22761 if (CONSP (prop))
22763 Lisp_Object car = XCAR (prop);
22764 Lisp_Object cdr = XCDR (prop);
22766 if (SYMBOLP (car))
22768 #ifdef HAVE_WINDOW_SYSTEM
22769 if (FRAME_WINDOW_P (it->f)
22770 && valid_image_p (prop))
22772 ptrdiff_t id = lookup_image (it->f, prop);
22773 struct image *img = IMAGE_FROM_ID (it->f, id);
22775 return OK_PIXELS (width_p ? img->width : img->height);
22777 #endif
22778 if (EQ (car, Qplus) || EQ (car, Qminus))
22780 int first = 1;
22781 double px;
22783 pixels = 0;
22784 while (CONSP (cdr))
22786 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
22787 font, width_p, align_to))
22788 return 0;
22789 if (first)
22790 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
22791 else
22792 pixels += px;
22793 cdr = XCDR (cdr);
22795 if (EQ (car, Qminus))
22796 pixels = -pixels;
22797 return OK_PIXELS (pixels);
22800 car = buffer_local_value_1 (car, it->w->contents);
22801 if (EQ (car, Qunbound))
22802 car = Qnil;
22805 if (INTEGERP (car) || FLOATP (car))
22807 double fact;
22808 pixels = XFLOATINT (car);
22809 if (NILP (cdr))
22810 return OK_PIXELS (pixels);
22811 if (calc_pixel_width_or_height (&fact, it, cdr,
22812 font, width_p, align_to))
22813 return OK_PIXELS (pixels * fact);
22814 return 0;
22817 return 0;
22820 return 0;
22824 /***********************************************************************
22825 Glyph Display
22826 ***********************************************************************/
22828 #ifdef HAVE_WINDOW_SYSTEM
22830 #ifdef GLYPH_DEBUG
22832 void
22833 dump_glyph_string (struct glyph_string *s)
22835 fprintf (stderr, "glyph string\n");
22836 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
22837 s->x, s->y, s->width, s->height);
22838 fprintf (stderr, " ybase = %d\n", s->ybase);
22839 fprintf (stderr, " hl = %d\n", s->hl);
22840 fprintf (stderr, " left overhang = %d, right = %d\n",
22841 s->left_overhang, s->right_overhang);
22842 fprintf (stderr, " nchars = %d\n", s->nchars);
22843 fprintf (stderr, " extends to end of line = %d\n",
22844 s->extends_to_end_of_line_p);
22845 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
22846 fprintf (stderr, " bg width = %d\n", s->background_width);
22849 #endif /* GLYPH_DEBUG */
22851 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
22852 of XChar2b structures for S; it can't be allocated in
22853 init_glyph_string because it must be allocated via `alloca'. W
22854 is the window on which S is drawn. ROW and AREA are the glyph row
22855 and area within the row from which S is constructed. START is the
22856 index of the first glyph structure covered by S. HL is a
22857 face-override for drawing S. */
22859 #ifdef HAVE_NTGUI
22860 #define OPTIONAL_HDC(hdc) HDC hdc,
22861 #define DECLARE_HDC(hdc) HDC hdc;
22862 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
22863 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
22864 #endif
22866 #ifndef OPTIONAL_HDC
22867 #define OPTIONAL_HDC(hdc)
22868 #define DECLARE_HDC(hdc)
22869 #define ALLOCATE_HDC(hdc, f)
22870 #define RELEASE_HDC(hdc, f)
22871 #endif
22873 static void
22874 init_glyph_string (struct glyph_string *s,
22875 OPTIONAL_HDC (hdc)
22876 XChar2b *char2b, struct window *w, struct glyph_row *row,
22877 enum glyph_row_area area, int start, enum draw_glyphs_face hl)
22879 memset (s, 0, sizeof *s);
22880 s->w = w;
22881 s->f = XFRAME (w->frame);
22882 #ifdef HAVE_NTGUI
22883 s->hdc = hdc;
22884 #endif
22885 s->display = FRAME_X_DISPLAY (s->f);
22886 s->window = FRAME_X_WINDOW (s->f);
22887 s->char2b = char2b;
22888 s->hl = hl;
22889 s->row = row;
22890 s->area = area;
22891 s->first_glyph = row->glyphs[area] + start;
22892 s->height = row->height;
22893 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
22894 s->ybase = s->y + row->ascent;
22898 /* Append the list of glyph strings with head H and tail T to the list
22899 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
22901 static void
22902 append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
22903 struct glyph_string *h, struct glyph_string *t)
22905 if (h)
22907 if (*head)
22908 (*tail)->next = h;
22909 else
22910 *head = h;
22911 h->prev = *tail;
22912 *tail = t;
22917 /* Prepend the list of glyph strings with head H and tail T to the
22918 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
22919 result. */
22921 static void
22922 prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
22923 struct glyph_string *h, struct glyph_string *t)
22925 if (h)
22927 if (*head)
22928 (*head)->prev = t;
22929 else
22930 *tail = t;
22931 t->next = *head;
22932 *head = h;
22937 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
22938 Set *HEAD and *TAIL to the resulting list. */
22940 static void
22941 append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
22942 struct glyph_string *s)
22944 s->next = s->prev = NULL;
22945 append_glyph_string_lists (head, tail, s, s);
22949 /* Get face and two-byte form of character C in face FACE_ID on frame F.
22950 The encoding of C is returned in *CHAR2B. DISPLAY_P non-zero means
22951 make sure that X resources for the face returned are allocated.
22952 Value is a pointer to a realized face that is ready for display if
22953 DISPLAY_P is non-zero. */
22955 static struct face *
22956 get_char_face_and_encoding (struct frame *f, int c, int face_id,
22957 XChar2b *char2b, int display_p)
22959 struct face *face = FACE_FROM_ID (f, face_id);
22960 unsigned code = 0;
22962 if (face->font)
22964 code = face->font->driver->encode_char (face->font, c);
22966 if (code == FONT_INVALID_CODE)
22967 code = 0;
22969 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
22971 /* Make sure X resources of the face are allocated. */
22972 #ifdef HAVE_X_WINDOWS
22973 if (display_p)
22974 #endif
22976 eassert (face != NULL);
22977 PREPARE_FACE_FOR_DISPLAY (f, face);
22980 return face;
22984 /* Get face and two-byte form of character glyph GLYPH on frame F.
22985 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
22986 a pointer to a realized face that is ready for display. */
22988 static struct face *
22989 get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
22990 XChar2b *char2b, int *two_byte_p)
22992 struct face *face;
22993 unsigned code = 0;
22995 eassert (glyph->type == CHAR_GLYPH);
22996 face = FACE_FROM_ID (f, glyph->face_id);
22998 /* Make sure X resources of the face are allocated. */
22999 eassert (face != NULL);
23000 PREPARE_FACE_FOR_DISPLAY (f, face);
23002 if (two_byte_p)
23003 *two_byte_p = 0;
23005 if (face->font)
23007 if (CHAR_BYTE8_P (glyph->u.ch))
23008 code = CHAR_TO_BYTE8 (glyph->u.ch);
23009 else
23010 code = face->font->driver->encode_char (face->font, glyph->u.ch);
23012 if (code == FONT_INVALID_CODE)
23013 code = 0;
23016 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
23017 return face;
23021 /* Get glyph code of character C in FONT in the two-byte form CHAR2B.
23022 Return 1 if FONT has a glyph for C, otherwise return 0. */
23024 static int
23025 get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
23027 unsigned code;
23029 if (CHAR_BYTE8_P (c))
23030 code = CHAR_TO_BYTE8 (c);
23031 else
23032 code = font->driver->encode_char (font, c);
23034 if (code == FONT_INVALID_CODE)
23035 return 0;
23036 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
23037 return 1;
23041 /* Fill glyph string S with composition components specified by S->cmp.
23043 BASE_FACE is the base face of the composition.
23044 S->cmp_from is the index of the first component for S.
23046 OVERLAPS non-zero means S should draw the foreground only, and use
23047 its physical height for clipping. See also draw_glyphs.
23049 Value is the index of a component not in S. */
23051 static int
23052 fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
23053 int overlaps)
23055 int i;
23056 /* For all glyphs of this composition, starting at the offset
23057 S->cmp_from, until we reach the end of the definition or encounter a
23058 glyph that requires the different face, add it to S. */
23059 struct face *face;
23061 eassert (s);
23063 s->for_overlaps = overlaps;
23064 s->face = NULL;
23065 s->font = NULL;
23066 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
23068 int c = COMPOSITION_GLYPH (s->cmp, i);
23070 /* TAB in a composition means display glyphs with padding space
23071 on the left or right. */
23072 if (c != '\t')
23074 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
23075 -1, Qnil);
23077 face = get_char_face_and_encoding (s->f, c, face_id,
23078 s->char2b + i, 1);
23079 if (face)
23081 if (! s->face)
23083 s->face = face;
23084 s->font = s->face->font;
23086 else if (s->face != face)
23087 break;
23090 ++s->nchars;
23092 s->cmp_to = i;
23094 if (s->face == NULL)
23096 s->face = base_face->ascii_face;
23097 s->font = s->face->font;
23100 /* All glyph strings for the same composition has the same width,
23101 i.e. the width set for the first component of the composition. */
23102 s->width = s->first_glyph->pixel_width;
23104 /* If the specified font could not be loaded, use the frame's
23105 default font, but record the fact that we couldn't load it in
23106 the glyph string so that we can draw rectangles for the
23107 characters of the glyph string. */
23108 if (s->font == NULL)
23110 s->font_not_found_p = 1;
23111 s->font = FRAME_FONT (s->f);
23114 /* Adjust base line for subscript/superscript text. */
23115 s->ybase += s->first_glyph->voffset;
23117 /* This glyph string must always be drawn with 16-bit functions. */
23118 s->two_byte_p = 1;
23120 return s->cmp_to;
23123 static int
23124 fill_gstring_glyph_string (struct glyph_string *s, int face_id,
23125 int start, int end, int overlaps)
23127 struct glyph *glyph, *last;
23128 Lisp_Object lgstring;
23129 int i;
23131 s->for_overlaps = overlaps;
23132 glyph = s->row->glyphs[s->area] + start;
23133 last = s->row->glyphs[s->area] + end;
23134 s->cmp_id = glyph->u.cmp.id;
23135 s->cmp_from = glyph->slice.cmp.from;
23136 s->cmp_to = glyph->slice.cmp.to + 1;
23137 s->face = FACE_FROM_ID (s->f, face_id);
23138 lgstring = composition_gstring_from_id (s->cmp_id);
23139 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
23140 glyph++;
23141 while (glyph < last
23142 && glyph->u.cmp.automatic
23143 && glyph->u.cmp.id == s->cmp_id
23144 && s->cmp_to == glyph->slice.cmp.from)
23145 s->cmp_to = (glyph++)->slice.cmp.to + 1;
23147 for (i = s->cmp_from; i < s->cmp_to; i++)
23149 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
23150 unsigned code = LGLYPH_CODE (lglyph);
23152 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
23154 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
23155 return glyph - s->row->glyphs[s->area];
23159 /* Fill glyph string S from a sequence glyphs for glyphless characters.
23160 See the comment of fill_glyph_string for arguments.
23161 Value is the index of the first glyph not in S. */
23164 static int
23165 fill_glyphless_glyph_string (struct glyph_string *s, int face_id,
23166 int start, int end, int overlaps)
23168 struct glyph *glyph, *last;
23169 int voffset;
23171 eassert (s->first_glyph->type == GLYPHLESS_GLYPH);
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->face = FACE_FROM_ID (s->f, face_id);
23177 s->font = s->face->font ? s->face->font : FRAME_FONT (s->f);
23178 s->nchars = 1;
23179 s->width = glyph->pixel_width;
23180 glyph++;
23181 while (glyph < last
23182 && glyph->type == GLYPHLESS_GLYPH
23183 && glyph->voffset == voffset
23184 && glyph->face_id == face_id)
23186 s->nchars++;
23187 s->width += glyph->pixel_width;
23188 glyph++;
23190 s->ybase += voffset;
23191 return glyph - s->row->glyphs[s->area];
23195 /* Fill glyph string S from a sequence of character glyphs.
23197 FACE_ID is the face id of the string. START is the index of the
23198 first glyph to consider, END is the index of the last + 1.
23199 OVERLAPS non-zero means S should draw the foreground only, and use
23200 its physical height for clipping. See also draw_glyphs.
23202 Value is the index of the first glyph not in S. */
23204 static int
23205 fill_glyph_string (struct glyph_string *s, int face_id,
23206 int start, int end, int overlaps)
23208 struct glyph *glyph, *last;
23209 int voffset;
23210 int glyph_not_available_p;
23212 eassert (s->f == XFRAME (s->w->frame));
23213 eassert (s->nchars == 0);
23214 eassert (start >= 0 && end > start);
23216 s->for_overlaps = overlaps;
23217 glyph = s->row->glyphs[s->area] + start;
23218 last = s->row->glyphs[s->area] + end;
23219 voffset = glyph->voffset;
23220 s->padding_p = glyph->padding_p;
23221 glyph_not_available_p = glyph->glyph_not_available_p;
23223 while (glyph < last
23224 && glyph->type == CHAR_GLYPH
23225 && glyph->voffset == voffset
23226 /* Same face id implies same font, nowadays. */
23227 && glyph->face_id == face_id
23228 && glyph->glyph_not_available_p == glyph_not_available_p)
23230 int two_byte_p;
23232 s->face = get_glyph_face_and_encoding (s->f, glyph,
23233 s->char2b + s->nchars,
23234 &two_byte_p);
23235 s->two_byte_p = two_byte_p;
23236 ++s->nchars;
23237 eassert (s->nchars <= end - start);
23238 s->width += glyph->pixel_width;
23239 if (glyph++->padding_p != s->padding_p)
23240 break;
23243 s->font = s->face->font;
23245 /* If the specified font could not be loaded, use the frame's font,
23246 but record the fact that we couldn't load it in
23247 S->font_not_found_p so that we can draw rectangles for the
23248 characters of the glyph string. */
23249 if (s->font == NULL || glyph_not_available_p)
23251 s->font_not_found_p = 1;
23252 s->font = FRAME_FONT (s->f);
23255 /* Adjust base line for subscript/superscript text. */
23256 s->ybase += voffset;
23258 eassert (s->face && s->face->gc);
23259 return glyph - s->row->glyphs[s->area];
23263 /* Fill glyph string S from image glyph S->first_glyph. */
23265 static void
23266 fill_image_glyph_string (struct glyph_string *s)
23268 eassert (s->first_glyph->type == IMAGE_GLYPH);
23269 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
23270 eassert (s->img);
23271 s->slice = s->first_glyph->slice.img;
23272 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
23273 s->font = s->face->font;
23274 s->width = s->first_glyph->pixel_width;
23276 /* Adjust base line for subscript/superscript text. */
23277 s->ybase += s->first_glyph->voffset;
23281 /* Fill glyph string S from a sequence of stretch glyphs.
23283 START is the index of the first glyph to consider,
23284 END is the index of the last + 1.
23286 Value is the index of the first glyph not in S. */
23288 static int
23289 fill_stretch_glyph_string (struct glyph_string *s, int start, int end)
23291 struct glyph *glyph, *last;
23292 int voffset, face_id;
23294 eassert (s->first_glyph->type == STRETCH_GLYPH);
23296 glyph = s->row->glyphs[s->area] + start;
23297 last = s->row->glyphs[s->area] + end;
23298 face_id = glyph->face_id;
23299 s->face = FACE_FROM_ID (s->f, face_id);
23300 s->font = s->face->font;
23301 s->width = glyph->pixel_width;
23302 s->nchars = 1;
23303 voffset = glyph->voffset;
23305 for (++glyph;
23306 (glyph < last
23307 && glyph->type == STRETCH_GLYPH
23308 && glyph->voffset == voffset
23309 && glyph->face_id == face_id);
23310 ++glyph)
23311 s->width += glyph->pixel_width;
23313 /* Adjust base line for subscript/superscript text. */
23314 s->ybase += voffset;
23316 /* The case that face->gc == 0 is handled when drawing the glyph
23317 string by calling PREPARE_FACE_FOR_DISPLAY. */
23318 eassert (s->face);
23319 return glyph - s->row->glyphs[s->area];
23322 static struct font_metrics *
23323 get_per_char_metric (struct font *font, XChar2b *char2b)
23325 static struct font_metrics metrics;
23326 unsigned code;
23328 if (! font)
23329 return NULL;
23330 code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
23331 if (code == FONT_INVALID_CODE)
23332 return NULL;
23333 font->driver->text_extents (font, &code, 1, &metrics);
23334 return &metrics;
23337 /* EXPORT for RIF:
23338 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
23339 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
23340 assumed to be zero. */
23342 void
23343 x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *right)
23345 *left = *right = 0;
23347 if (glyph->type == CHAR_GLYPH)
23349 struct face *face;
23350 XChar2b char2b;
23351 struct font_metrics *pcm;
23353 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
23354 if (face->font && (pcm = get_per_char_metric (face->font, &char2b)))
23356 if (pcm->rbearing > pcm->width)
23357 *right = pcm->rbearing - pcm->width;
23358 if (pcm->lbearing < 0)
23359 *left = -pcm->lbearing;
23362 else if (glyph->type == COMPOSITE_GLYPH)
23364 if (! glyph->u.cmp.automatic)
23366 struct composition *cmp = composition_table[glyph->u.cmp.id];
23368 if (cmp->rbearing > cmp->pixel_width)
23369 *right = cmp->rbearing - cmp->pixel_width;
23370 if (cmp->lbearing < 0)
23371 *left = - cmp->lbearing;
23373 else
23375 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
23376 struct font_metrics metrics;
23378 composition_gstring_width (gstring, glyph->slice.cmp.from,
23379 glyph->slice.cmp.to + 1, &metrics);
23380 if (metrics.rbearing > metrics.width)
23381 *right = metrics.rbearing - metrics.width;
23382 if (metrics.lbearing < 0)
23383 *left = - metrics.lbearing;
23389 /* Return the index of the first glyph preceding glyph string S that
23390 is overwritten by S because of S's left overhang. Value is -1
23391 if no glyphs are overwritten. */
23393 static int
23394 left_overwritten (struct glyph_string *s)
23396 int k;
23398 if (s->left_overhang)
23400 int x = 0, i;
23401 struct glyph *glyphs = s->row->glyphs[s->area];
23402 int first = s->first_glyph - glyphs;
23404 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
23405 x -= glyphs[i].pixel_width;
23407 k = i + 1;
23409 else
23410 k = -1;
23412 return k;
23416 /* Return the index of the first glyph preceding glyph string S that
23417 is overwriting S because of its right overhang. Value is -1 if no
23418 glyph in front of S overwrites S. */
23420 static int
23421 left_overwriting (struct glyph_string *s)
23423 int i, k, x;
23424 struct glyph *glyphs = s->row->glyphs[s->area];
23425 int first = s->first_glyph - glyphs;
23427 k = -1;
23428 x = 0;
23429 for (i = first - 1; i >= 0; --i)
23431 int left, right;
23432 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
23433 if (x + right > 0)
23434 k = i;
23435 x -= glyphs[i].pixel_width;
23438 return k;
23442 /* Return the index of the last glyph following glyph string S that is
23443 overwritten by S because of S's right overhang. Value is -1 if
23444 no such glyph is found. */
23446 static int
23447 right_overwritten (struct glyph_string *s)
23449 int k = -1;
23451 if (s->right_overhang)
23453 int x = 0, i;
23454 struct glyph *glyphs = s->row->glyphs[s->area];
23455 int first = (s->first_glyph - glyphs
23456 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
23457 int end = s->row->used[s->area];
23459 for (i = first; i < end && s->right_overhang > x; ++i)
23460 x += glyphs[i].pixel_width;
23462 k = i;
23465 return k;
23469 /* Return the index of the last glyph following glyph string S that
23470 overwrites S because of its left overhang. Value is negative
23471 if no such glyph is found. */
23473 static int
23474 right_overwriting (struct glyph_string *s)
23476 int i, k, x;
23477 int end = s->row->used[s->area];
23478 struct glyph *glyphs = s->row->glyphs[s->area];
23479 int first = (s->first_glyph - glyphs
23480 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
23482 k = -1;
23483 x = 0;
23484 for (i = first; i < end; ++i)
23486 int left, right;
23487 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
23488 if (x - left < 0)
23489 k = i;
23490 x += glyphs[i].pixel_width;
23493 return k;
23497 /* Set background width of glyph string S. START is the index of the
23498 first glyph following S. LAST_X is the right-most x-position + 1
23499 in the drawing area. */
23501 static void
23502 set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
23504 /* If the face of this glyph string has to be drawn to the end of
23505 the drawing area, set S->extends_to_end_of_line_p. */
23507 if (start == s->row->used[s->area]
23508 && s->area == TEXT_AREA
23509 && ((s->row->fill_line_p
23510 && (s->hl == DRAW_NORMAL_TEXT
23511 || s->hl == DRAW_IMAGE_RAISED
23512 || s->hl == DRAW_IMAGE_SUNKEN))
23513 || s->hl == DRAW_MOUSE_FACE))
23514 s->extends_to_end_of_line_p = 1;
23516 /* If S extends its face to the end of the line, set its
23517 background_width to the distance to the right edge of the drawing
23518 area. */
23519 if (s->extends_to_end_of_line_p)
23520 s->background_width = last_x - s->x + 1;
23521 else
23522 s->background_width = s->width;
23526 /* Compute overhangs and x-positions for glyph string S and its
23527 predecessors, or successors. X is the starting x-position for S.
23528 BACKWARD_P non-zero means process predecessors. */
23530 static void
23531 compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
23533 if (backward_p)
23535 while (s)
23537 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
23538 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
23539 x -= s->width;
23540 s->x = x;
23541 s = s->prev;
23544 else
23546 while (s)
23548 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
23549 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
23550 s->x = x;
23551 x += s->width;
23552 s = s->next;
23559 /* The following macros are only called from draw_glyphs below.
23560 They reference the following parameters of that function directly:
23561 `w', `row', `area', and `overlap_p'
23562 as well as the following local variables:
23563 `s', `f', and `hdc' (in W32) */
23565 #ifdef HAVE_NTGUI
23566 /* On W32, silently add local `hdc' variable to argument list of
23567 init_glyph_string. */
23568 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
23569 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
23570 #else
23571 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
23572 init_glyph_string (s, char2b, w, row, area, start, hl)
23573 #endif
23575 /* Add a glyph string for a stretch glyph to the list of strings
23576 between HEAD and TAIL. START is the index of the stretch glyph in
23577 row area AREA of glyph row ROW. END is the index of the last glyph
23578 in that glyph row area. X is the current output position assigned
23579 to the new glyph string constructed. HL overrides that face of the
23580 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
23581 is the right-most x-position of the drawing area. */
23583 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
23584 and below -- keep them on one line. */
23585 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23586 do \
23588 s = alloca (sizeof *s); \
23589 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23590 START = fill_stretch_glyph_string (s, START, END); \
23591 append_glyph_string (&HEAD, &TAIL, s); \
23592 s->x = (X); \
23594 while (0)
23597 /* Add a glyph string for an image glyph to the list of strings
23598 between HEAD and TAIL. START is the index of the image glyph in
23599 row area AREA of glyph row ROW. END is the index of the last glyph
23600 in that glyph row area. X is the current output position assigned
23601 to the new glyph string constructed. HL overrides that face of the
23602 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
23603 is the right-most x-position of the drawing area. */
23605 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23606 do \
23608 s = alloca (sizeof *s); \
23609 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23610 fill_image_glyph_string (s); \
23611 append_glyph_string (&HEAD, &TAIL, s); \
23612 ++START; \
23613 s->x = (X); \
23615 while (0)
23618 /* Add a glyph string for a sequence of character glyphs to the list
23619 of strings between HEAD and TAIL. START is the index of the first
23620 glyph in row area AREA of glyph row ROW that is part of the new
23621 glyph string. END is the index of the last glyph in that glyph row
23622 area. X is the current output position assigned to the new glyph
23623 string constructed. HL overrides that face of the glyph; e.g. it
23624 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
23625 right-most x-position of the drawing area. */
23627 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
23628 do \
23630 int face_id; \
23631 XChar2b *char2b; \
23633 face_id = (row)->glyphs[area][START].face_id; \
23635 s = alloca (sizeof *s); \
23636 char2b = alloca ((END - START) * sizeof *char2b); \
23637 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23638 append_glyph_string (&HEAD, &TAIL, s); \
23639 s->x = (X); \
23640 START = fill_glyph_string (s, face_id, START, END, overlaps); \
23642 while (0)
23645 /* Add a glyph string for a composite sequence to the list of strings
23646 between HEAD and TAIL. START is the index of the first glyph in
23647 row area AREA of glyph row ROW that is part of the new glyph
23648 string. END is the index of the last glyph in that glyph row area.
23649 X is the current output position assigned to the new glyph string
23650 constructed. HL overrides that face of the glyph; e.g. it is
23651 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
23652 x-position of the drawing area. */
23654 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23655 do { \
23656 int face_id = (row)->glyphs[area][START].face_id; \
23657 struct face *base_face = FACE_FROM_ID (f, face_id); \
23658 ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \
23659 struct composition *cmp = composition_table[cmp_id]; \
23660 XChar2b *char2b; \
23661 struct glyph_string *first_s = NULL; \
23662 int n; \
23664 char2b = alloca (cmp->glyph_len * sizeof *char2b); \
23666 /* Make glyph_strings for each glyph sequence that is drawable by \
23667 the same face, and append them to HEAD/TAIL. */ \
23668 for (n = 0; n < cmp->glyph_len;) \
23670 s = alloca (sizeof *s); \
23671 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23672 append_glyph_string (&(HEAD), &(TAIL), s); \
23673 s->cmp = cmp; \
23674 s->cmp_from = n; \
23675 s->x = (X); \
23676 if (n == 0) \
23677 first_s = s; \
23678 n = fill_composite_glyph_string (s, base_face, overlaps); \
23681 ++START; \
23682 s = first_s; \
23683 } while (0)
23686 /* Add a glyph string for a glyph-string sequence to the list of strings
23687 between HEAD and TAIL. */
23689 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23690 do { \
23691 int face_id; \
23692 XChar2b *char2b; \
23693 Lisp_Object gstring; \
23695 face_id = (row)->glyphs[area][START].face_id; \
23696 gstring = (composition_gstring_from_id \
23697 ((row)->glyphs[area][START].u.cmp.id)); \
23698 s = alloca (sizeof *s); \
23699 char2b = alloca (LGSTRING_GLYPH_LEN (gstring) * sizeof *char2b); \
23700 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23701 append_glyph_string (&(HEAD), &(TAIL), s); \
23702 s->x = (X); \
23703 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
23704 } while (0)
23707 /* Add a glyph string for a sequence of glyphless character's glyphs
23708 to the list of strings between HEAD and TAIL. The meanings of
23709 arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */
23711 #define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23712 do \
23714 int face_id; \
23716 face_id = (row)->glyphs[area][START].face_id; \
23718 s = alloca (sizeof *s); \
23719 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23720 append_glyph_string (&HEAD, &TAIL, s); \
23721 s->x = (X); \
23722 START = fill_glyphless_glyph_string (s, face_id, START, END, \
23723 overlaps); \
23725 while (0)
23728 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
23729 of AREA of glyph row ROW on window W between indices START and END.
23730 HL overrides the face for drawing glyph strings, e.g. it is
23731 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
23732 x-positions of the drawing area.
23734 This is an ugly monster macro construct because we must use alloca
23735 to allocate glyph strings (because draw_glyphs can be called
23736 asynchronously). */
23738 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
23739 do \
23741 HEAD = TAIL = NULL; \
23742 while (START < END) \
23744 struct glyph *first_glyph = (row)->glyphs[area] + START; \
23745 switch (first_glyph->type) \
23747 case CHAR_GLYPH: \
23748 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
23749 HL, X, LAST_X); \
23750 break; \
23752 case COMPOSITE_GLYPH: \
23753 if (first_glyph->u.cmp.automatic) \
23754 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
23755 HL, X, LAST_X); \
23756 else \
23757 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
23758 HL, X, LAST_X); \
23759 break; \
23761 case STRETCH_GLYPH: \
23762 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
23763 HL, X, LAST_X); \
23764 break; \
23766 case IMAGE_GLYPH: \
23767 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
23768 HL, X, LAST_X); \
23769 break; \
23771 case GLYPHLESS_GLYPH: \
23772 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
23773 HL, X, LAST_X); \
23774 break; \
23776 default: \
23777 emacs_abort (); \
23780 if (s) \
23782 set_glyph_string_background_width (s, START, LAST_X); \
23783 (X) += s->width; \
23786 } while (0)
23789 /* Draw glyphs between START and END in AREA of ROW on window W,
23790 starting at x-position X. X is relative to AREA in W. HL is a
23791 face-override with the following meaning:
23793 DRAW_NORMAL_TEXT draw normally
23794 DRAW_CURSOR draw in cursor face
23795 DRAW_MOUSE_FACE draw in mouse face.
23796 DRAW_INVERSE_VIDEO draw in mode line face
23797 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
23798 DRAW_IMAGE_RAISED draw an image with a raised relief around it
23800 If OVERLAPS is non-zero, draw only the foreground of characters and
23801 clip to the physical height of ROW. Non-zero value also defines
23802 the overlapping part to be drawn:
23804 OVERLAPS_PRED overlap with preceding rows
23805 OVERLAPS_SUCC overlap with succeeding rows
23806 OVERLAPS_BOTH overlap with both preceding/succeeding rows
23807 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
23809 Value is the x-position reached, relative to AREA of W. */
23811 static int
23812 draw_glyphs (struct window *w, int x, struct glyph_row *row,
23813 enum glyph_row_area area, ptrdiff_t start, ptrdiff_t end,
23814 enum draw_glyphs_face hl, int overlaps)
23816 struct glyph_string *head, *tail;
23817 struct glyph_string *s;
23818 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
23819 int i, j, x_reached, last_x, area_left = 0;
23820 struct frame *f = XFRAME (WINDOW_FRAME (w));
23821 DECLARE_HDC (hdc);
23823 ALLOCATE_HDC (hdc, f);
23825 /* Let's rather be paranoid than getting a SEGV. */
23826 end = min (end, row->used[area]);
23827 start = clip_to_bounds (0, start, end);
23829 /* Translate X to frame coordinates. Set last_x to the right
23830 end of the drawing area. */
23831 if (row->full_width_p)
23833 /* X is relative to the left edge of W, without scroll bars
23834 or fringes. */
23835 area_left = WINDOW_LEFT_EDGE_X (w);
23836 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
23838 else
23840 area_left = window_box_left (w, area);
23841 last_x = area_left + window_box_width (w, area);
23843 x += area_left;
23845 /* Build a doubly-linked list of glyph_string structures between
23846 head and tail from what we have to draw. Note that the macro
23847 BUILD_GLYPH_STRINGS will modify its start parameter. That's
23848 the reason we use a separate variable `i'. */
23849 i = start;
23850 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
23851 if (tail)
23852 x_reached = tail->x + tail->background_width;
23853 else
23854 x_reached = x;
23856 /* If there are any glyphs with lbearing < 0 or rbearing > width in
23857 the row, redraw some glyphs in front or following the glyph
23858 strings built above. */
23859 if (head && !overlaps && row->contains_overlapping_glyphs_p)
23861 struct glyph_string *h, *t;
23862 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
23863 int mouse_beg_col IF_LINT (= 0), mouse_end_col IF_LINT (= 0);
23864 int check_mouse_face = 0;
23865 int dummy_x = 0;
23867 /* If mouse highlighting is on, we may need to draw adjacent
23868 glyphs using mouse-face highlighting. */
23869 if (area == TEXT_AREA && row->mouse_face_p
23870 && hlinfo->mouse_face_beg_row >= 0
23871 && hlinfo->mouse_face_end_row >= 0)
23873 ptrdiff_t row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
23875 if (row_vpos >= hlinfo->mouse_face_beg_row
23876 && row_vpos <= hlinfo->mouse_face_end_row)
23878 check_mouse_face = 1;
23879 mouse_beg_col = (row_vpos == hlinfo->mouse_face_beg_row)
23880 ? hlinfo->mouse_face_beg_col : 0;
23881 mouse_end_col = (row_vpos == hlinfo->mouse_face_end_row)
23882 ? hlinfo->mouse_face_end_col
23883 : row->used[TEXT_AREA];
23887 /* Compute overhangs for all glyph strings. */
23888 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
23889 for (s = head; s; s = s->next)
23890 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
23892 /* Prepend glyph strings for glyphs in front of the first glyph
23893 string that are overwritten because of the first glyph
23894 string's left overhang. The background of all strings
23895 prepended must be drawn because the first glyph string
23896 draws over it. */
23897 i = left_overwritten (head);
23898 if (i >= 0)
23900 enum draw_glyphs_face overlap_hl;
23902 /* If this row contains mouse highlighting, attempt to draw
23903 the overlapped glyphs with the correct highlight. This
23904 code fails if the overlap encompasses more than one glyph
23905 and mouse-highlight spans only some of these glyphs.
23906 However, making it work perfectly involves a lot more
23907 code, and I don't know if the pathological case occurs in
23908 practice, so we'll stick to this for now. --- cyd */
23909 if (check_mouse_face
23910 && mouse_beg_col < start && mouse_end_col > i)
23911 overlap_hl = DRAW_MOUSE_FACE;
23912 else
23913 overlap_hl = DRAW_NORMAL_TEXT;
23915 j = i;
23916 BUILD_GLYPH_STRINGS (j, start, h, t,
23917 overlap_hl, dummy_x, last_x);
23918 start = i;
23919 compute_overhangs_and_x (t, head->x, 1);
23920 prepend_glyph_string_lists (&head, &tail, h, t);
23921 clip_head = head;
23924 /* Prepend glyph strings for glyphs in front of the first glyph
23925 string that overwrite that glyph string because of their
23926 right overhang. For these strings, only the foreground must
23927 be drawn, because it draws over the glyph string at `head'.
23928 The background must not be drawn because this would overwrite
23929 right overhangs of preceding glyphs for which no glyph
23930 strings exist. */
23931 i = left_overwriting (head);
23932 if (i >= 0)
23934 enum draw_glyphs_face overlap_hl;
23936 if (check_mouse_face
23937 && mouse_beg_col < start && mouse_end_col > i)
23938 overlap_hl = DRAW_MOUSE_FACE;
23939 else
23940 overlap_hl = DRAW_NORMAL_TEXT;
23942 clip_head = head;
23943 BUILD_GLYPH_STRINGS (i, start, h, t,
23944 overlap_hl, dummy_x, last_x);
23945 for (s = h; s; s = s->next)
23946 s->background_filled_p = 1;
23947 compute_overhangs_and_x (t, head->x, 1);
23948 prepend_glyph_string_lists (&head, &tail, h, t);
23951 /* Append glyphs strings for glyphs following the last glyph
23952 string tail that are overwritten by tail. The background of
23953 these strings has to be drawn because tail's foreground draws
23954 over it. */
23955 i = right_overwritten (tail);
23956 if (i >= 0)
23958 enum draw_glyphs_face overlap_hl;
23960 if (check_mouse_face
23961 && mouse_beg_col < i && mouse_end_col > end)
23962 overlap_hl = DRAW_MOUSE_FACE;
23963 else
23964 overlap_hl = DRAW_NORMAL_TEXT;
23966 BUILD_GLYPH_STRINGS (end, i, h, t,
23967 overlap_hl, x, last_x);
23968 /* Because BUILD_GLYPH_STRINGS updates the first argument,
23969 we don't have `end = i;' here. */
23970 compute_overhangs_and_x (h, tail->x + tail->width, 0);
23971 append_glyph_string_lists (&head, &tail, h, t);
23972 clip_tail = tail;
23975 /* Append glyph strings for glyphs following the last glyph
23976 string tail that overwrite tail. The foreground of such
23977 glyphs has to be drawn because it writes into the background
23978 of tail. The background must not be drawn because it could
23979 paint over the foreground of following glyphs. */
23980 i = right_overwriting (tail);
23981 if (i >= 0)
23983 enum draw_glyphs_face overlap_hl;
23984 if (check_mouse_face
23985 && mouse_beg_col < i && mouse_end_col > end)
23986 overlap_hl = DRAW_MOUSE_FACE;
23987 else
23988 overlap_hl = DRAW_NORMAL_TEXT;
23990 clip_tail = tail;
23991 i++; /* We must include the Ith glyph. */
23992 BUILD_GLYPH_STRINGS (end, i, h, t,
23993 overlap_hl, x, last_x);
23994 for (s = h; s; s = s->next)
23995 s->background_filled_p = 1;
23996 compute_overhangs_and_x (h, tail->x + tail->width, 0);
23997 append_glyph_string_lists (&head, &tail, h, t);
23999 if (clip_head || clip_tail)
24000 for (s = head; s; s = s->next)
24002 s->clip_head = clip_head;
24003 s->clip_tail = clip_tail;
24007 /* Draw all strings. */
24008 for (s = head; s; s = s->next)
24009 FRAME_RIF (f)->draw_glyph_string (s);
24011 #ifndef HAVE_NS
24012 /* When focus a sole frame and move horizontally, this sets on_p to 0
24013 causing a failure to erase prev cursor position. */
24014 if (area == TEXT_AREA
24015 && !row->full_width_p
24016 /* When drawing overlapping rows, only the glyph strings'
24017 foreground is drawn, which doesn't erase a cursor
24018 completely. */
24019 && !overlaps)
24021 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
24022 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
24023 : (tail ? tail->x + tail->background_width : x));
24024 x0 -= area_left;
24025 x1 -= area_left;
24027 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
24028 row->y, MATRIX_ROW_BOTTOM_Y (row));
24030 #endif
24032 /* Value is the x-position up to which drawn, relative to AREA of W.
24033 This doesn't include parts drawn because of overhangs. */
24034 if (row->full_width_p)
24035 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
24036 else
24037 x_reached -= area_left;
24039 RELEASE_HDC (hdc, f);
24041 return x_reached;
24044 /* Expand row matrix if too narrow. Don't expand if area
24045 is not present. */
24047 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
24049 if (!fonts_changed_p \
24050 && (it->glyph_row->glyphs[area] \
24051 < it->glyph_row->glyphs[area + 1])) \
24053 it->w->ncols_scale_factor++; \
24054 fonts_changed_p = 1; \
24058 /* Store one glyph for IT->char_to_display in IT->glyph_row.
24059 Called from x_produce_glyphs when IT->glyph_row is non-null. */
24061 static void
24062 append_glyph (struct it *it)
24064 struct glyph *glyph;
24065 enum glyph_row_area area = it->area;
24067 eassert (it->glyph_row);
24068 eassert (it->char_to_display != '\n' && it->char_to_display != '\t');
24070 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24071 if (glyph < it->glyph_row->glyphs[area + 1])
24073 /* If the glyph row is reversed, we need to prepend the glyph
24074 rather than append it. */
24075 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24077 struct glyph *g;
24079 /* Make room for the additional glyph. */
24080 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
24081 g[1] = *g;
24082 glyph = it->glyph_row->glyphs[area];
24084 glyph->charpos = CHARPOS (it->position);
24085 glyph->object = it->object;
24086 if (it->pixel_width > 0)
24088 glyph->pixel_width = it->pixel_width;
24089 glyph->padding_p = 0;
24091 else
24093 /* Assure at least 1-pixel width. Otherwise, cursor can't
24094 be displayed correctly. */
24095 glyph->pixel_width = 1;
24096 glyph->padding_p = 1;
24098 glyph->ascent = it->ascent;
24099 glyph->descent = it->descent;
24100 glyph->voffset = it->voffset;
24101 glyph->type = CHAR_GLYPH;
24102 glyph->avoid_cursor_p = it->avoid_cursor_p;
24103 glyph->multibyte_p = it->multibyte_p;
24104 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24106 /* In R2L rows, the left and the right box edges need to be
24107 drawn in reverse direction. */
24108 glyph->right_box_line_p = it->start_of_box_run_p;
24109 glyph->left_box_line_p = it->end_of_box_run_p;
24111 else
24113 glyph->left_box_line_p = it->start_of_box_run_p;
24114 glyph->right_box_line_p = it->end_of_box_run_p;
24116 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
24117 || it->phys_descent > it->descent);
24118 glyph->glyph_not_available_p = it->glyph_not_available_p;
24119 glyph->face_id = it->face_id;
24120 glyph->u.ch = it->char_to_display;
24121 glyph->slice.img = null_glyph_slice;
24122 glyph->font_type = FONT_TYPE_UNKNOWN;
24123 if (it->bidi_p)
24125 glyph->resolved_level = it->bidi_it.resolved_level;
24126 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24127 emacs_abort ();
24128 glyph->bidi_type = it->bidi_it.type;
24130 else
24132 glyph->resolved_level = 0;
24133 glyph->bidi_type = UNKNOWN_BT;
24135 ++it->glyph_row->used[area];
24137 else
24138 IT_EXPAND_MATRIX_WIDTH (it, area);
24141 /* Store one glyph for the composition IT->cmp_it.id in
24142 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
24143 non-null. */
24145 static void
24146 append_composite_glyph (struct it *it)
24148 struct glyph *glyph;
24149 enum glyph_row_area area = it->area;
24151 eassert (it->glyph_row);
24153 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24154 if (glyph < it->glyph_row->glyphs[area + 1])
24156 /* If the glyph row is reversed, we need to prepend the glyph
24157 rather than append it. */
24158 if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
24160 struct glyph *g;
24162 /* Make room for the new glyph. */
24163 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
24164 g[1] = *g;
24165 glyph = it->glyph_row->glyphs[it->area];
24167 glyph->charpos = it->cmp_it.charpos;
24168 glyph->object = it->object;
24169 glyph->pixel_width = it->pixel_width;
24170 glyph->ascent = it->ascent;
24171 glyph->descent = it->descent;
24172 glyph->voffset = it->voffset;
24173 glyph->type = COMPOSITE_GLYPH;
24174 if (it->cmp_it.ch < 0)
24176 glyph->u.cmp.automatic = 0;
24177 glyph->u.cmp.id = it->cmp_it.id;
24178 glyph->slice.cmp.from = glyph->slice.cmp.to = 0;
24180 else
24182 glyph->u.cmp.automatic = 1;
24183 glyph->u.cmp.id = it->cmp_it.id;
24184 glyph->slice.cmp.from = it->cmp_it.from;
24185 glyph->slice.cmp.to = it->cmp_it.to - 1;
24187 glyph->avoid_cursor_p = it->avoid_cursor_p;
24188 glyph->multibyte_p = it->multibyte_p;
24189 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24191 /* In R2L rows, the left and the right box edges need to be
24192 drawn in reverse direction. */
24193 glyph->right_box_line_p = it->start_of_box_run_p;
24194 glyph->left_box_line_p = it->end_of_box_run_p;
24196 else
24198 glyph->left_box_line_p = it->start_of_box_run_p;
24199 glyph->right_box_line_p = it->end_of_box_run_p;
24201 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
24202 || it->phys_descent > it->descent);
24203 glyph->padding_p = 0;
24204 glyph->glyph_not_available_p = 0;
24205 glyph->face_id = it->face_id;
24206 glyph->font_type = FONT_TYPE_UNKNOWN;
24207 if (it->bidi_p)
24209 glyph->resolved_level = it->bidi_it.resolved_level;
24210 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24211 emacs_abort ();
24212 glyph->bidi_type = it->bidi_it.type;
24214 ++it->glyph_row->used[area];
24216 else
24217 IT_EXPAND_MATRIX_WIDTH (it, area);
24221 /* Change IT->ascent and IT->height according to the setting of
24222 IT->voffset. */
24224 static void
24225 take_vertical_position_into_account (struct it *it)
24227 if (it->voffset)
24229 if (it->voffset < 0)
24230 /* Increase the ascent so that we can display the text higher
24231 in the line. */
24232 it->ascent -= it->voffset;
24233 else
24234 /* Increase the descent so that we can display the text lower
24235 in the line. */
24236 it->descent += it->voffset;
24241 /* Produce glyphs/get display metrics for the image IT is loaded with.
24242 See the description of struct display_iterator in dispextern.h for
24243 an overview of struct display_iterator. */
24245 static void
24246 produce_image_glyph (struct it *it)
24248 struct image *img;
24249 struct face *face;
24250 int glyph_ascent, crop;
24251 struct glyph_slice slice;
24253 eassert (it->what == IT_IMAGE);
24255 face = FACE_FROM_ID (it->f, it->face_id);
24256 eassert (face);
24257 /* Make sure X resources of the face is loaded. */
24258 PREPARE_FACE_FOR_DISPLAY (it->f, face);
24260 if (it->image_id < 0)
24262 /* Fringe bitmap. */
24263 it->ascent = it->phys_ascent = 0;
24264 it->descent = it->phys_descent = 0;
24265 it->pixel_width = 0;
24266 it->nglyphs = 0;
24267 return;
24270 img = IMAGE_FROM_ID (it->f, it->image_id);
24271 eassert (img);
24272 /* Make sure X resources of the image is loaded. */
24273 prepare_image_for_display (it->f, img);
24275 slice.x = slice.y = 0;
24276 slice.width = img->width;
24277 slice.height = img->height;
24279 if (INTEGERP (it->slice.x))
24280 slice.x = XINT (it->slice.x);
24281 else if (FLOATP (it->slice.x))
24282 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
24284 if (INTEGERP (it->slice.y))
24285 slice.y = XINT (it->slice.y);
24286 else if (FLOATP (it->slice.y))
24287 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
24289 if (INTEGERP (it->slice.width))
24290 slice.width = XINT (it->slice.width);
24291 else if (FLOATP (it->slice.width))
24292 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
24294 if (INTEGERP (it->slice.height))
24295 slice.height = XINT (it->slice.height);
24296 else if (FLOATP (it->slice.height))
24297 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
24299 if (slice.x >= img->width)
24300 slice.x = img->width;
24301 if (slice.y >= img->height)
24302 slice.y = img->height;
24303 if (slice.x + slice.width >= img->width)
24304 slice.width = img->width - slice.x;
24305 if (slice.y + slice.height > img->height)
24306 slice.height = img->height - slice.y;
24308 if (slice.width == 0 || slice.height == 0)
24309 return;
24311 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
24313 it->descent = slice.height - glyph_ascent;
24314 if (slice.y == 0)
24315 it->descent += img->vmargin;
24316 if (slice.y + slice.height == img->height)
24317 it->descent += img->vmargin;
24318 it->phys_descent = it->descent;
24320 it->pixel_width = slice.width;
24321 if (slice.x == 0)
24322 it->pixel_width += img->hmargin;
24323 if (slice.x + slice.width == img->width)
24324 it->pixel_width += img->hmargin;
24326 /* It's quite possible for images to have an ascent greater than
24327 their height, so don't get confused in that case. */
24328 if (it->descent < 0)
24329 it->descent = 0;
24331 it->nglyphs = 1;
24333 if (face->box != FACE_NO_BOX)
24335 if (face->box_line_width > 0)
24337 if (slice.y == 0)
24338 it->ascent += face->box_line_width;
24339 if (slice.y + slice.height == img->height)
24340 it->descent += face->box_line_width;
24343 if (it->start_of_box_run_p && slice.x == 0)
24344 it->pixel_width += eabs (face->box_line_width);
24345 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
24346 it->pixel_width += eabs (face->box_line_width);
24349 take_vertical_position_into_account (it);
24351 /* Automatically crop wide image glyphs at right edge so we can
24352 draw the cursor on same display row. */
24353 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
24354 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
24356 it->pixel_width -= crop;
24357 slice.width -= crop;
24360 if (it->glyph_row)
24362 struct glyph *glyph;
24363 enum glyph_row_area area = it->area;
24365 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24366 if (glyph < it->glyph_row->glyphs[area + 1])
24368 glyph->charpos = CHARPOS (it->position);
24369 glyph->object = it->object;
24370 glyph->pixel_width = it->pixel_width;
24371 glyph->ascent = glyph_ascent;
24372 glyph->descent = it->descent;
24373 glyph->voffset = it->voffset;
24374 glyph->type = IMAGE_GLYPH;
24375 glyph->avoid_cursor_p = it->avoid_cursor_p;
24376 glyph->multibyte_p = it->multibyte_p;
24377 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24379 /* In R2L rows, the left and the right box edges need to be
24380 drawn in reverse direction. */
24381 glyph->right_box_line_p = it->start_of_box_run_p;
24382 glyph->left_box_line_p = it->end_of_box_run_p;
24384 else
24386 glyph->left_box_line_p = it->start_of_box_run_p;
24387 glyph->right_box_line_p = it->end_of_box_run_p;
24389 glyph->overlaps_vertically_p = 0;
24390 glyph->padding_p = 0;
24391 glyph->glyph_not_available_p = 0;
24392 glyph->face_id = it->face_id;
24393 glyph->u.img_id = img->id;
24394 glyph->slice.img = slice;
24395 glyph->font_type = FONT_TYPE_UNKNOWN;
24396 if (it->bidi_p)
24398 glyph->resolved_level = it->bidi_it.resolved_level;
24399 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24400 emacs_abort ();
24401 glyph->bidi_type = it->bidi_it.type;
24403 ++it->glyph_row->used[area];
24405 else
24406 IT_EXPAND_MATRIX_WIDTH (it, area);
24411 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
24412 of the glyph, WIDTH and HEIGHT are the width and height of the
24413 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
24415 static void
24416 append_stretch_glyph (struct it *it, Lisp_Object object,
24417 int width, int height, int ascent)
24419 struct glyph *glyph;
24420 enum glyph_row_area area = it->area;
24422 eassert (ascent >= 0 && ascent <= height);
24424 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24425 if (glyph < it->glyph_row->glyphs[area + 1])
24427 /* If the glyph row is reversed, we need to prepend the glyph
24428 rather than append it. */
24429 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24431 struct glyph *g;
24433 /* Make room for the additional glyph. */
24434 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
24435 g[1] = *g;
24436 glyph = it->glyph_row->glyphs[area];
24438 glyph->charpos = CHARPOS (it->position);
24439 glyph->object = object;
24440 glyph->pixel_width = width;
24441 glyph->ascent = ascent;
24442 glyph->descent = height - ascent;
24443 glyph->voffset = it->voffset;
24444 glyph->type = STRETCH_GLYPH;
24445 glyph->avoid_cursor_p = it->avoid_cursor_p;
24446 glyph->multibyte_p = it->multibyte_p;
24447 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24449 /* In R2L rows, the left and the right box edges need to be
24450 drawn in reverse direction. */
24451 glyph->right_box_line_p = it->start_of_box_run_p;
24452 glyph->left_box_line_p = it->end_of_box_run_p;
24454 else
24456 glyph->left_box_line_p = it->start_of_box_run_p;
24457 glyph->right_box_line_p = it->end_of_box_run_p;
24459 glyph->overlaps_vertically_p = 0;
24460 glyph->padding_p = 0;
24461 glyph->glyph_not_available_p = 0;
24462 glyph->face_id = it->face_id;
24463 glyph->u.stretch.ascent = ascent;
24464 glyph->u.stretch.height = height;
24465 glyph->slice.img = null_glyph_slice;
24466 glyph->font_type = FONT_TYPE_UNKNOWN;
24467 if (it->bidi_p)
24469 glyph->resolved_level = it->bidi_it.resolved_level;
24470 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24471 emacs_abort ();
24472 glyph->bidi_type = it->bidi_it.type;
24474 else
24476 glyph->resolved_level = 0;
24477 glyph->bidi_type = UNKNOWN_BT;
24479 ++it->glyph_row->used[area];
24481 else
24482 IT_EXPAND_MATRIX_WIDTH (it, area);
24485 #endif /* HAVE_WINDOW_SYSTEM */
24487 /* Produce a stretch glyph for iterator IT. IT->object is the value
24488 of the glyph property displayed. The value must be a list
24489 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
24490 being recognized:
24492 1. `:width WIDTH' specifies that the space should be WIDTH *
24493 canonical char width wide. WIDTH may be an integer or floating
24494 point number.
24496 2. `:relative-width FACTOR' specifies that the width of the stretch
24497 should be computed from the width of the first character having the
24498 `glyph' property, and should be FACTOR times that width.
24500 3. `:align-to HPOS' specifies that the space should be wide enough
24501 to reach HPOS, a value in canonical character units.
24503 Exactly one of the above pairs must be present.
24505 4. `:height HEIGHT' specifies that the height of the stretch produced
24506 should be HEIGHT, measured in canonical character units.
24508 5. `:relative-height FACTOR' specifies that the height of the
24509 stretch should be FACTOR times the height of the characters having
24510 the glyph property.
24512 Either none or exactly one of 4 or 5 must be present.
24514 6. `:ascent ASCENT' specifies that ASCENT percent of the height
24515 of the stretch should be used for the ascent of the stretch.
24516 ASCENT must be in the range 0 <= ASCENT <= 100. */
24518 void
24519 produce_stretch_glyph (struct it *it)
24521 /* (space :width WIDTH :height HEIGHT ...) */
24522 Lisp_Object prop, plist;
24523 int width = 0, height = 0, align_to = -1;
24524 int zero_width_ok_p = 0;
24525 double tem;
24526 struct font *font = NULL;
24528 #ifdef HAVE_WINDOW_SYSTEM
24529 int ascent = 0;
24530 int zero_height_ok_p = 0;
24532 if (FRAME_WINDOW_P (it->f))
24534 struct face *face = FACE_FROM_ID (it->f, it->face_id);
24535 font = face->font ? face->font : FRAME_FONT (it->f);
24536 PREPARE_FACE_FOR_DISPLAY (it->f, face);
24538 #endif
24540 /* List should start with `space'. */
24541 eassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
24542 plist = XCDR (it->object);
24544 /* Compute the width of the stretch. */
24545 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
24546 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
24548 /* Absolute width `:width WIDTH' specified and valid. */
24549 zero_width_ok_p = 1;
24550 width = (int)tem;
24552 #ifdef HAVE_WINDOW_SYSTEM
24553 else if (FRAME_WINDOW_P (it->f)
24554 && (prop = Fplist_get (plist, QCrelative_width), NUMVAL (prop) > 0))
24556 /* Relative width `:relative-width FACTOR' specified and valid.
24557 Compute the width of the characters having the `glyph'
24558 property. */
24559 struct it it2;
24560 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
24562 it2 = *it;
24563 if (it->multibyte_p)
24564 it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
24565 else
24567 it2.c = it2.char_to_display = *p, it2.len = 1;
24568 if (! ASCII_CHAR_P (it2.c))
24569 it2.char_to_display = BYTE8_TO_CHAR (it2.c);
24572 it2.glyph_row = NULL;
24573 it2.what = IT_CHARACTER;
24574 x_produce_glyphs (&it2);
24575 width = NUMVAL (prop) * it2.pixel_width;
24577 #endif /* HAVE_WINDOW_SYSTEM */
24578 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
24579 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
24581 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
24582 align_to = (align_to < 0
24584 : align_to - window_box_left_offset (it->w, TEXT_AREA));
24585 else if (align_to < 0)
24586 align_to = window_box_left_offset (it->w, TEXT_AREA);
24587 width = max (0, (int)tem + align_to - it->current_x);
24588 zero_width_ok_p = 1;
24590 else
24591 /* Nothing specified -> width defaults to canonical char width. */
24592 width = FRAME_COLUMN_WIDTH (it->f);
24594 if (width <= 0 && (width < 0 || !zero_width_ok_p))
24595 width = 1;
24597 #ifdef HAVE_WINDOW_SYSTEM
24598 /* Compute height. */
24599 if (FRAME_WINDOW_P (it->f))
24601 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
24602 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
24604 height = (int)tem;
24605 zero_height_ok_p = 1;
24607 else if (prop = Fplist_get (plist, QCrelative_height),
24608 NUMVAL (prop) > 0)
24609 height = FONT_HEIGHT (font) * NUMVAL (prop);
24610 else
24611 height = FONT_HEIGHT (font);
24613 if (height <= 0 && (height < 0 || !zero_height_ok_p))
24614 height = 1;
24616 /* Compute percentage of height used for ascent. If
24617 `:ascent ASCENT' is present and valid, use that. Otherwise,
24618 derive the ascent from the font in use. */
24619 if (prop = Fplist_get (plist, QCascent),
24620 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
24621 ascent = height * NUMVAL (prop) / 100.0;
24622 else if (!NILP (prop)
24623 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
24624 ascent = min (max (0, (int)tem), height);
24625 else
24626 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
24628 else
24629 #endif /* HAVE_WINDOW_SYSTEM */
24630 height = 1;
24632 if (width > 0 && it->line_wrap != TRUNCATE
24633 && it->current_x + width > it->last_visible_x)
24635 width = it->last_visible_x - it->current_x;
24636 #ifdef HAVE_WINDOW_SYSTEM
24637 /* Subtract one more pixel from the stretch width, but only on
24638 GUI frames, since on a TTY each glyph is one "pixel" wide. */
24639 width -= FRAME_WINDOW_P (it->f);
24640 #endif
24643 if (width > 0 && height > 0 && it->glyph_row)
24645 Lisp_Object o_object = it->object;
24646 Lisp_Object object = it->stack[it->sp - 1].string;
24647 int n = width;
24649 if (!STRINGP (object))
24650 object = it->w->contents;
24651 #ifdef HAVE_WINDOW_SYSTEM
24652 if (FRAME_WINDOW_P (it->f))
24653 append_stretch_glyph (it, object, width, height, ascent);
24654 else
24655 #endif
24657 it->object = object;
24658 it->char_to_display = ' ';
24659 it->pixel_width = it->len = 1;
24660 while (n--)
24661 tty_append_glyph (it);
24662 it->object = o_object;
24666 it->pixel_width = width;
24667 #ifdef HAVE_WINDOW_SYSTEM
24668 if (FRAME_WINDOW_P (it->f))
24670 it->ascent = it->phys_ascent = ascent;
24671 it->descent = it->phys_descent = height - it->ascent;
24672 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
24673 take_vertical_position_into_account (it);
24675 else
24676 #endif
24677 it->nglyphs = width;
24680 /* Get information about special display element WHAT in an
24681 environment described by IT. WHAT is one of IT_TRUNCATION or
24682 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
24683 non-null glyph_row member. This function ensures that fields like
24684 face_id, c, len of IT are left untouched. */
24686 static void
24687 produce_special_glyphs (struct it *it, enum display_element_type what)
24689 struct it temp_it;
24690 Lisp_Object gc;
24691 GLYPH glyph;
24693 temp_it = *it;
24694 temp_it.object = make_number (0);
24695 memset (&temp_it.current, 0, sizeof temp_it.current);
24697 if (what == IT_CONTINUATION)
24699 /* Continuation glyph. For R2L lines, we mirror it by hand. */
24700 if (it->bidi_it.paragraph_dir == R2L)
24701 SET_GLYPH_FROM_CHAR (glyph, '/');
24702 else
24703 SET_GLYPH_FROM_CHAR (glyph, '\\');
24704 if (it->dp
24705 && (gc = DISP_CONTINUE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
24707 /* FIXME: Should we mirror GC for R2L lines? */
24708 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
24709 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
24712 else if (what == IT_TRUNCATION)
24714 /* Truncation glyph. */
24715 SET_GLYPH_FROM_CHAR (glyph, '$');
24716 if (it->dp
24717 && (gc = DISP_TRUNC_GLYPH (it->dp), GLYPH_CODE_P (gc)))
24719 /* FIXME: Should we mirror GC for R2L lines? */
24720 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
24721 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
24724 else
24725 emacs_abort ();
24727 #ifdef HAVE_WINDOW_SYSTEM
24728 /* On a GUI frame, when the right fringe (left fringe for R2L rows)
24729 is turned off, we precede the truncation/continuation glyphs by a
24730 stretch glyph whose width is computed such that these special
24731 glyphs are aligned at the window margin, even when very different
24732 fonts are used in different glyph rows. */
24733 if (FRAME_WINDOW_P (temp_it.f)
24734 /* init_iterator calls this with it->glyph_row == NULL, and it
24735 wants only the pixel width of the truncation/continuation
24736 glyphs. */
24737 && temp_it.glyph_row
24738 /* insert_left_trunc_glyphs calls us at the beginning of the
24739 row, and it has its own calculation of the stretch glyph
24740 width. */
24741 && temp_it.glyph_row->used[TEXT_AREA] > 0
24742 && (temp_it.glyph_row->reversed_p
24743 ? WINDOW_LEFT_FRINGE_WIDTH (temp_it.w)
24744 : WINDOW_RIGHT_FRINGE_WIDTH (temp_it.w)) == 0)
24746 int stretch_width = temp_it.last_visible_x - temp_it.current_x;
24748 if (stretch_width > 0)
24750 struct face *face = FACE_FROM_ID (temp_it.f, temp_it.face_id);
24751 struct font *font =
24752 face->font ? face->font : FRAME_FONT (temp_it.f);
24753 int stretch_ascent =
24754 (((temp_it.ascent + temp_it.descent)
24755 * FONT_BASE (font)) / FONT_HEIGHT (font));
24757 append_stretch_glyph (&temp_it, make_number (0), stretch_width,
24758 temp_it.ascent + temp_it.descent,
24759 stretch_ascent);
24762 #endif
24764 temp_it.dp = NULL;
24765 temp_it.what = IT_CHARACTER;
24766 temp_it.len = 1;
24767 temp_it.c = temp_it.char_to_display = GLYPH_CHAR (glyph);
24768 temp_it.face_id = GLYPH_FACE (glyph);
24769 temp_it.len = CHAR_BYTES (temp_it.c);
24771 PRODUCE_GLYPHS (&temp_it);
24772 it->pixel_width = temp_it.pixel_width;
24773 it->nglyphs = temp_it.pixel_width;
24776 #ifdef HAVE_WINDOW_SYSTEM
24778 /* Calculate line-height and line-spacing properties.
24779 An integer value specifies explicit pixel value.
24780 A float value specifies relative value to current face height.
24781 A cons (float . face-name) specifies relative value to
24782 height of specified face font.
24784 Returns height in pixels, or nil. */
24787 static Lisp_Object
24788 calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
24789 int boff, int override)
24791 Lisp_Object face_name = Qnil;
24792 int ascent, descent, height;
24794 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
24795 return val;
24797 if (CONSP (val))
24799 face_name = XCAR (val);
24800 val = XCDR (val);
24801 if (!NUMBERP (val))
24802 val = make_number (1);
24803 if (NILP (face_name))
24805 height = it->ascent + it->descent;
24806 goto scale;
24810 if (NILP (face_name))
24812 font = FRAME_FONT (it->f);
24813 boff = FRAME_BASELINE_OFFSET (it->f);
24815 else if (EQ (face_name, Qt))
24817 override = 0;
24819 else
24821 int face_id;
24822 struct face *face;
24824 face_id = lookup_named_face (it->f, face_name, 0);
24825 if (face_id < 0)
24826 return make_number (-1);
24828 face = FACE_FROM_ID (it->f, face_id);
24829 font = face->font;
24830 if (font == NULL)
24831 return make_number (-1);
24832 boff = font->baseline_offset;
24833 if (font->vertical_centering)
24834 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
24837 ascent = FONT_BASE (font) + boff;
24838 descent = FONT_DESCENT (font) - boff;
24840 if (override)
24842 it->override_ascent = ascent;
24843 it->override_descent = descent;
24844 it->override_boff = boff;
24847 height = ascent + descent;
24849 scale:
24850 if (FLOATP (val))
24851 height = (int)(XFLOAT_DATA (val) * height);
24852 else if (INTEGERP (val))
24853 height *= XINT (val);
24855 return make_number (height);
24859 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
24860 is a face ID to be used for the glyph. FOR_NO_FONT is nonzero if
24861 and only if this is for a character for which no font was found.
24863 If the display method (it->glyphless_method) is
24864 GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
24865 length of the acronym or the hexadecimal string, UPPER_XOFF and
24866 UPPER_YOFF are pixel offsets for the upper part of the string,
24867 LOWER_XOFF and LOWER_YOFF are for the lower part.
24869 For the other display methods, LEN through LOWER_YOFF are zero. */
24871 static void
24872 append_glyphless_glyph (struct it *it, int face_id, int for_no_font, int len,
24873 short upper_xoff, short upper_yoff,
24874 short lower_xoff, short lower_yoff)
24876 struct glyph *glyph;
24877 enum glyph_row_area area = it->area;
24879 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24880 if (glyph < it->glyph_row->glyphs[area + 1])
24882 /* If the glyph row is reversed, we need to prepend the glyph
24883 rather than append it. */
24884 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24886 struct glyph *g;
24888 /* Make room for the additional glyph. */
24889 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
24890 g[1] = *g;
24891 glyph = it->glyph_row->glyphs[area];
24893 glyph->charpos = CHARPOS (it->position);
24894 glyph->object = it->object;
24895 glyph->pixel_width = it->pixel_width;
24896 glyph->ascent = it->ascent;
24897 glyph->descent = it->descent;
24898 glyph->voffset = it->voffset;
24899 glyph->type = GLYPHLESS_GLYPH;
24900 glyph->u.glyphless.method = it->glyphless_method;
24901 glyph->u.glyphless.for_no_font = for_no_font;
24902 glyph->u.glyphless.len = len;
24903 glyph->u.glyphless.ch = it->c;
24904 glyph->slice.glyphless.upper_xoff = upper_xoff;
24905 glyph->slice.glyphless.upper_yoff = upper_yoff;
24906 glyph->slice.glyphless.lower_xoff = lower_xoff;
24907 glyph->slice.glyphless.lower_yoff = lower_yoff;
24908 glyph->avoid_cursor_p = it->avoid_cursor_p;
24909 glyph->multibyte_p = it->multibyte_p;
24910 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24912 /* In R2L rows, the left and the right box edges need to be
24913 drawn in reverse direction. */
24914 glyph->right_box_line_p = it->start_of_box_run_p;
24915 glyph->left_box_line_p = it->end_of_box_run_p;
24917 else
24919 glyph->left_box_line_p = it->start_of_box_run_p;
24920 glyph->right_box_line_p = it->end_of_box_run_p;
24922 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
24923 || it->phys_descent > it->descent);
24924 glyph->padding_p = 0;
24925 glyph->glyph_not_available_p = 0;
24926 glyph->face_id = face_id;
24927 glyph->font_type = FONT_TYPE_UNKNOWN;
24928 if (it->bidi_p)
24930 glyph->resolved_level = it->bidi_it.resolved_level;
24931 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24932 emacs_abort ();
24933 glyph->bidi_type = it->bidi_it.type;
24935 ++it->glyph_row->used[area];
24937 else
24938 IT_EXPAND_MATRIX_WIDTH (it, area);
24942 /* Produce a glyph for a glyphless character for iterator IT.
24943 IT->glyphless_method specifies which method to use for displaying
24944 the character. See the description of enum
24945 glyphless_display_method in dispextern.h for the detail.
24947 FOR_NO_FONT is nonzero if and only if this is for a character for
24948 which no font was found. ACRONYM, if non-nil, is an acronym string
24949 for the character. */
24951 static void
24952 produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
24954 int face_id;
24955 struct face *face;
24956 struct font *font;
24957 int base_width, base_height, width, height;
24958 short upper_xoff, upper_yoff, lower_xoff, lower_yoff;
24959 int len;
24961 /* Get the metrics of the base font. We always refer to the current
24962 ASCII face. */
24963 face = FACE_FROM_ID (it->f, it->face_id)->ascii_face;
24964 font = face->font ? face->font : FRAME_FONT (it->f);
24965 it->ascent = FONT_BASE (font) + font->baseline_offset;
24966 it->descent = FONT_DESCENT (font) - font->baseline_offset;
24967 base_height = it->ascent + it->descent;
24968 base_width = font->average_width;
24970 /* Get a face ID for the glyph by utilizing a cache (the same way as
24971 done for `escape-glyph' in get_next_display_element). */
24972 if (it->f == last_glyphless_glyph_frame
24973 && it->face_id == last_glyphless_glyph_face_id)
24975 face_id = last_glyphless_glyph_merged_face_id;
24977 else
24979 /* Merge the `glyphless-char' face into the current face. */
24980 face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
24981 last_glyphless_glyph_frame = it->f;
24982 last_glyphless_glyph_face_id = it->face_id;
24983 last_glyphless_glyph_merged_face_id = face_id;
24986 if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
24988 it->pixel_width = THIN_SPACE_WIDTH;
24989 len = 0;
24990 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
24992 else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX)
24994 width = CHAR_WIDTH (it->c);
24995 if (width == 0)
24996 width = 1;
24997 else if (width > 4)
24998 width = 4;
24999 it->pixel_width = base_width * width;
25000 len = 0;
25001 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
25003 else
25005 char buf[7];
25006 const char *str;
25007 unsigned int code[6];
25008 int upper_len;
25009 int ascent, descent;
25010 struct font_metrics metrics_upper, metrics_lower;
25012 face = FACE_FROM_ID (it->f, face_id);
25013 font = face->font ? face->font : FRAME_FONT (it->f);
25014 PREPARE_FACE_FOR_DISPLAY (it->f, face);
25016 if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM)
25018 if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
25019 acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
25020 if (CONSP (acronym))
25021 acronym = XCAR (acronym);
25022 str = STRINGP (acronym) ? SSDATA (acronym) : "";
25024 else
25026 eassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
25027 sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c);
25028 str = buf;
25030 for (len = 0; str[len] && ASCII_BYTE_P (str[len]) && len < 6; len++)
25031 code[len] = font->driver->encode_char (font, str[len]);
25032 upper_len = (len + 1) / 2;
25033 font->driver->text_extents (font, code, upper_len,
25034 &metrics_upper);
25035 font->driver->text_extents (font, code + upper_len, len - upper_len,
25036 &metrics_lower);
25040 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
25041 width = max (metrics_upper.width, metrics_lower.width) + 4;
25042 upper_xoff = upper_yoff = 2; /* the typical case */
25043 if (base_width >= width)
25045 /* Align the upper to the left, the lower to the right. */
25046 it->pixel_width = base_width;
25047 lower_xoff = base_width - 2 - metrics_lower.width;
25049 else
25051 /* Center the shorter one. */
25052 it->pixel_width = width;
25053 if (metrics_upper.width >= metrics_lower.width)
25054 lower_xoff = (width - metrics_lower.width) / 2;
25055 else
25057 /* FIXME: This code doesn't look right. It formerly was
25058 missing the "lower_xoff = 0;", which couldn't have
25059 been right since it left lower_xoff uninitialized. */
25060 lower_xoff = 0;
25061 upper_xoff = (width - metrics_upper.width) / 2;
25065 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
25066 top, bottom, and between upper and lower strings. */
25067 height = (metrics_upper.ascent + metrics_upper.descent
25068 + metrics_lower.ascent + metrics_lower.descent) + 5;
25069 /* Center vertically.
25070 H:base_height, D:base_descent
25071 h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent
25073 ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up
25074 descent = D - H/2 + h/2;
25075 lower_yoff = descent - 2 - ld;
25076 upper_yoff = lower_yoff - la - 1 - ud; */
25077 ascent = - (it->descent - (base_height + height + 1) / 2);
25078 descent = it->descent - (base_height - height) / 2;
25079 lower_yoff = descent - 2 - metrics_lower.descent;
25080 upper_yoff = (lower_yoff - metrics_lower.ascent - 1
25081 - metrics_upper.descent);
25082 /* Don't make the height shorter than the base height. */
25083 if (height > base_height)
25085 it->ascent = ascent;
25086 it->descent = descent;
25090 it->phys_ascent = it->ascent;
25091 it->phys_descent = it->descent;
25092 if (it->glyph_row)
25093 append_glyphless_glyph (it, face_id, for_no_font, len,
25094 upper_xoff, upper_yoff,
25095 lower_xoff, lower_yoff);
25096 it->nglyphs = 1;
25097 take_vertical_position_into_account (it);
25101 /* RIF:
25102 Produce glyphs/get display metrics for the display element IT is
25103 loaded with. See the description of struct it in dispextern.h
25104 for an overview of struct it. */
25106 void
25107 x_produce_glyphs (struct it *it)
25109 int extra_line_spacing = it->extra_line_spacing;
25111 it->glyph_not_available_p = 0;
25113 if (it->what == IT_CHARACTER)
25115 XChar2b char2b;
25116 struct face *face = FACE_FROM_ID (it->f, it->face_id);
25117 struct font *font = face->font;
25118 struct font_metrics *pcm = NULL;
25119 int boff; /* baseline offset */
25121 if (font == NULL)
25123 /* When no suitable font is found, display this character by
25124 the method specified in the first extra slot of
25125 Vglyphless_char_display. */
25126 Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
25128 eassert (it->what == IT_GLYPHLESS);
25129 produce_glyphless_glyph (it, 1, STRINGP (acronym) ? acronym : Qnil);
25130 goto done;
25133 boff = font->baseline_offset;
25134 if (font->vertical_centering)
25135 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
25137 if (it->char_to_display != '\n' && it->char_to_display != '\t')
25139 int stretched_p;
25141 it->nglyphs = 1;
25143 if (it->override_ascent >= 0)
25145 it->ascent = it->override_ascent;
25146 it->descent = it->override_descent;
25147 boff = it->override_boff;
25149 else
25151 it->ascent = FONT_BASE (font) + boff;
25152 it->descent = FONT_DESCENT (font) - boff;
25155 if (get_char_glyph_code (it->char_to_display, font, &char2b))
25157 pcm = get_per_char_metric (font, &char2b);
25158 if (pcm->width == 0
25159 && pcm->rbearing == 0 && pcm->lbearing == 0)
25160 pcm = NULL;
25163 if (pcm)
25165 it->phys_ascent = pcm->ascent + boff;
25166 it->phys_descent = pcm->descent - boff;
25167 it->pixel_width = pcm->width;
25169 else
25171 it->glyph_not_available_p = 1;
25172 it->phys_ascent = it->ascent;
25173 it->phys_descent = it->descent;
25174 it->pixel_width = font->space_width;
25177 if (it->constrain_row_ascent_descent_p)
25179 if (it->descent > it->max_descent)
25181 it->ascent += it->descent - it->max_descent;
25182 it->descent = it->max_descent;
25184 if (it->ascent > it->max_ascent)
25186 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
25187 it->ascent = it->max_ascent;
25189 it->phys_ascent = min (it->phys_ascent, it->ascent);
25190 it->phys_descent = min (it->phys_descent, it->descent);
25191 extra_line_spacing = 0;
25194 /* If this is a space inside a region of text with
25195 `space-width' property, change its width. */
25196 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
25197 if (stretched_p)
25198 it->pixel_width *= XFLOATINT (it->space_width);
25200 /* If face has a box, add the box thickness to the character
25201 height. If character has a box line to the left and/or
25202 right, add the box line width to the character's width. */
25203 if (face->box != FACE_NO_BOX)
25205 int thick = face->box_line_width;
25207 if (thick > 0)
25209 it->ascent += thick;
25210 it->descent += thick;
25212 else
25213 thick = -thick;
25215 if (it->start_of_box_run_p)
25216 it->pixel_width += thick;
25217 if (it->end_of_box_run_p)
25218 it->pixel_width += thick;
25221 /* If face has an overline, add the height of the overline
25222 (1 pixel) and a 1 pixel margin to the character height. */
25223 if (face->overline_p)
25224 it->ascent += overline_margin;
25226 if (it->constrain_row_ascent_descent_p)
25228 if (it->ascent > it->max_ascent)
25229 it->ascent = it->max_ascent;
25230 if (it->descent > it->max_descent)
25231 it->descent = it->max_descent;
25234 take_vertical_position_into_account (it);
25236 /* If we have to actually produce glyphs, do it. */
25237 if (it->glyph_row)
25239 if (stretched_p)
25241 /* Translate a space with a `space-width' property
25242 into a stretch glyph. */
25243 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
25244 / FONT_HEIGHT (font));
25245 append_stretch_glyph (it, it->object, it->pixel_width,
25246 it->ascent + it->descent, ascent);
25248 else
25249 append_glyph (it);
25251 /* If characters with lbearing or rbearing are displayed
25252 in this line, record that fact in a flag of the
25253 glyph row. This is used to optimize X output code. */
25254 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
25255 it->glyph_row->contains_overlapping_glyphs_p = 1;
25257 if (! stretched_p && it->pixel_width == 0)
25258 /* We assure that all visible glyphs have at least 1-pixel
25259 width. */
25260 it->pixel_width = 1;
25262 else if (it->char_to_display == '\n')
25264 /* A newline has no width, but we need the height of the
25265 line. But if previous part of the line sets a height,
25266 don't increase that height */
25268 Lisp_Object height;
25269 Lisp_Object total_height = Qnil;
25271 it->override_ascent = -1;
25272 it->pixel_width = 0;
25273 it->nglyphs = 0;
25275 height = get_it_property (it, Qline_height);
25276 /* Split (line-height total-height) list */
25277 if (CONSP (height)
25278 && CONSP (XCDR (height))
25279 && NILP (XCDR (XCDR (height))))
25281 total_height = XCAR (XCDR (height));
25282 height = XCAR (height);
25284 height = calc_line_height_property (it, height, font, boff, 1);
25286 if (it->override_ascent >= 0)
25288 it->ascent = it->override_ascent;
25289 it->descent = it->override_descent;
25290 boff = it->override_boff;
25292 else
25294 it->ascent = FONT_BASE (font) + boff;
25295 it->descent = FONT_DESCENT (font) - boff;
25298 if (EQ (height, Qt))
25300 if (it->descent > it->max_descent)
25302 it->ascent += it->descent - it->max_descent;
25303 it->descent = it->max_descent;
25305 if (it->ascent > it->max_ascent)
25307 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
25308 it->ascent = it->max_ascent;
25310 it->phys_ascent = min (it->phys_ascent, it->ascent);
25311 it->phys_descent = min (it->phys_descent, it->descent);
25312 it->constrain_row_ascent_descent_p = 1;
25313 extra_line_spacing = 0;
25315 else
25317 Lisp_Object spacing;
25319 it->phys_ascent = it->ascent;
25320 it->phys_descent = it->descent;
25322 if ((it->max_ascent > 0 || it->max_descent > 0)
25323 && face->box != FACE_NO_BOX
25324 && face->box_line_width > 0)
25326 it->ascent += face->box_line_width;
25327 it->descent += face->box_line_width;
25329 if (!NILP (height)
25330 && XINT (height) > it->ascent + it->descent)
25331 it->ascent = XINT (height) - it->descent;
25333 if (!NILP (total_height))
25334 spacing = calc_line_height_property (it, total_height, font, boff, 0);
25335 else
25337 spacing = get_it_property (it, Qline_spacing);
25338 spacing = calc_line_height_property (it, spacing, font, boff, 0);
25340 if (INTEGERP (spacing))
25342 extra_line_spacing = XINT (spacing);
25343 if (!NILP (total_height))
25344 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
25348 else /* i.e. (it->char_to_display == '\t') */
25350 if (font->space_width > 0)
25352 int tab_width = it->tab_width * font->space_width;
25353 int x = it->current_x + it->continuation_lines_width;
25354 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
25356 /* If the distance from the current position to the next tab
25357 stop is less than a space character width, use the
25358 tab stop after that. */
25359 if (next_tab_x - x < font->space_width)
25360 next_tab_x += tab_width;
25362 it->pixel_width = next_tab_x - x;
25363 it->nglyphs = 1;
25364 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
25365 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
25367 if (it->glyph_row)
25369 append_stretch_glyph (it, it->object, it->pixel_width,
25370 it->ascent + it->descent, it->ascent);
25373 else
25375 it->pixel_width = 0;
25376 it->nglyphs = 1;
25380 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
25382 /* A static composition.
25384 Note: A composition is represented as one glyph in the
25385 glyph matrix. There are no padding glyphs.
25387 Important note: pixel_width, ascent, and descent are the
25388 values of what is drawn by draw_glyphs (i.e. the values of
25389 the overall glyphs composed). */
25390 struct face *face = FACE_FROM_ID (it->f, it->face_id);
25391 int boff; /* baseline offset */
25392 struct composition *cmp = composition_table[it->cmp_it.id];
25393 int glyph_len = cmp->glyph_len;
25394 struct font *font = face->font;
25396 it->nglyphs = 1;
25398 /* If we have not yet calculated pixel size data of glyphs of
25399 the composition for the current face font, calculate them
25400 now. Theoretically, we have to check all fonts for the
25401 glyphs, but that requires much time and memory space. So,
25402 here we check only the font of the first glyph. This may
25403 lead to incorrect display, but it's very rare, and C-l
25404 (recenter-top-bottom) can correct the display anyway. */
25405 if (! cmp->font || cmp->font != font)
25407 /* Ascent and descent of the font of the first character
25408 of this composition (adjusted by baseline offset).
25409 Ascent and descent of overall glyphs should not be less
25410 than these, respectively. */
25411 int font_ascent, font_descent, font_height;
25412 /* Bounding box of the overall glyphs. */
25413 int leftmost, rightmost, lowest, highest;
25414 int lbearing, rbearing;
25415 int i, width, ascent, descent;
25416 int left_padded = 0, right_padded = 0;
25417 int c IF_LINT (= 0); /* cmp->glyph_len can't be zero; see Bug#8512 */
25418 XChar2b char2b;
25419 struct font_metrics *pcm;
25420 int font_not_found_p;
25421 ptrdiff_t pos;
25423 for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
25424 if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
25425 break;
25426 if (glyph_len < cmp->glyph_len)
25427 right_padded = 1;
25428 for (i = 0; i < glyph_len; i++)
25430 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
25431 break;
25432 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
25434 if (i > 0)
25435 left_padded = 1;
25437 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
25438 : IT_CHARPOS (*it));
25439 /* If no suitable font is found, use the default font. */
25440 font_not_found_p = font == NULL;
25441 if (font_not_found_p)
25443 face = face->ascii_face;
25444 font = face->font;
25446 boff = font->baseline_offset;
25447 if (font->vertical_centering)
25448 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
25449 font_ascent = FONT_BASE (font) + boff;
25450 font_descent = FONT_DESCENT (font) - boff;
25451 font_height = FONT_HEIGHT (font);
25453 cmp->font = font;
25455 pcm = NULL;
25456 if (! font_not_found_p)
25458 get_char_face_and_encoding (it->f, c, it->face_id,
25459 &char2b, 0);
25460 pcm = get_per_char_metric (font, &char2b);
25463 /* Initialize the bounding box. */
25464 if (pcm)
25466 width = cmp->glyph_len > 0 ? pcm->width : 0;
25467 ascent = pcm->ascent;
25468 descent = pcm->descent;
25469 lbearing = pcm->lbearing;
25470 rbearing = pcm->rbearing;
25472 else
25474 width = cmp->glyph_len > 0 ? font->space_width : 0;
25475 ascent = FONT_BASE (font);
25476 descent = FONT_DESCENT (font);
25477 lbearing = 0;
25478 rbearing = width;
25481 rightmost = width;
25482 leftmost = 0;
25483 lowest = - descent + boff;
25484 highest = ascent + boff;
25486 if (! font_not_found_p
25487 && font->default_ascent
25488 && CHAR_TABLE_P (Vuse_default_ascent)
25489 && !NILP (Faref (Vuse_default_ascent,
25490 make_number (it->char_to_display))))
25491 highest = font->default_ascent + boff;
25493 /* Draw the first glyph at the normal position. It may be
25494 shifted to right later if some other glyphs are drawn
25495 at the left. */
25496 cmp->offsets[i * 2] = 0;
25497 cmp->offsets[i * 2 + 1] = boff;
25498 cmp->lbearing = lbearing;
25499 cmp->rbearing = rbearing;
25501 /* Set cmp->offsets for the remaining glyphs. */
25502 for (i++; i < glyph_len; i++)
25504 int left, right, btm, top;
25505 int ch = COMPOSITION_GLYPH (cmp, i);
25506 int face_id;
25507 struct face *this_face;
25509 if (ch == '\t')
25510 ch = ' ';
25511 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
25512 this_face = FACE_FROM_ID (it->f, face_id);
25513 font = this_face->font;
25515 if (font == NULL)
25516 pcm = NULL;
25517 else
25519 get_char_face_and_encoding (it->f, ch, face_id,
25520 &char2b, 0);
25521 pcm = get_per_char_metric (font, &char2b);
25523 if (! pcm)
25524 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
25525 else
25527 width = pcm->width;
25528 ascent = pcm->ascent;
25529 descent = pcm->descent;
25530 lbearing = pcm->lbearing;
25531 rbearing = pcm->rbearing;
25532 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
25534 /* Relative composition with or without
25535 alternate chars. */
25536 left = (leftmost + rightmost - width) / 2;
25537 btm = - descent + boff;
25538 if (font->relative_compose
25539 && (! CHAR_TABLE_P (Vignore_relative_composition)
25540 || NILP (Faref (Vignore_relative_composition,
25541 make_number (ch)))))
25544 if (- descent >= font->relative_compose)
25545 /* One extra pixel between two glyphs. */
25546 btm = highest + 1;
25547 else if (ascent <= 0)
25548 /* One extra pixel between two glyphs. */
25549 btm = lowest - 1 - ascent - descent;
25552 else
25554 /* A composition rule is specified by an integer
25555 value that encodes global and new reference
25556 points (GREF and NREF). GREF and NREF are
25557 specified by numbers as below:
25559 0---1---2 -- ascent
25563 9--10--11 -- center
25565 ---3---4---5--- baseline
25567 6---7---8 -- descent
25569 int rule = COMPOSITION_RULE (cmp, i);
25570 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
25572 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
25573 grefx = gref % 3, nrefx = nref % 3;
25574 grefy = gref / 3, nrefy = nref / 3;
25575 if (xoff)
25576 xoff = font_height * (xoff - 128) / 256;
25577 if (yoff)
25578 yoff = font_height * (yoff - 128) / 256;
25580 left = (leftmost
25581 + grefx * (rightmost - leftmost) / 2
25582 - nrefx * width / 2
25583 + xoff);
25585 btm = ((grefy == 0 ? highest
25586 : grefy == 1 ? 0
25587 : grefy == 2 ? lowest
25588 : (highest + lowest) / 2)
25589 - (nrefy == 0 ? ascent + descent
25590 : nrefy == 1 ? descent - boff
25591 : nrefy == 2 ? 0
25592 : (ascent + descent) / 2)
25593 + yoff);
25596 cmp->offsets[i * 2] = left;
25597 cmp->offsets[i * 2 + 1] = btm + descent;
25599 /* Update the bounding box of the overall glyphs. */
25600 if (width > 0)
25602 right = left + width;
25603 if (left < leftmost)
25604 leftmost = left;
25605 if (right > rightmost)
25606 rightmost = right;
25608 top = btm + descent + ascent;
25609 if (top > highest)
25610 highest = top;
25611 if (btm < lowest)
25612 lowest = btm;
25614 if (cmp->lbearing > left + lbearing)
25615 cmp->lbearing = left + lbearing;
25616 if (cmp->rbearing < left + rbearing)
25617 cmp->rbearing = left + rbearing;
25621 /* If there are glyphs whose x-offsets are negative,
25622 shift all glyphs to the right and make all x-offsets
25623 non-negative. */
25624 if (leftmost < 0)
25626 for (i = 0; i < cmp->glyph_len; i++)
25627 cmp->offsets[i * 2] -= leftmost;
25628 rightmost -= leftmost;
25629 cmp->lbearing -= leftmost;
25630 cmp->rbearing -= leftmost;
25633 if (left_padded && cmp->lbearing < 0)
25635 for (i = 0; i < cmp->glyph_len; i++)
25636 cmp->offsets[i * 2] -= cmp->lbearing;
25637 rightmost -= cmp->lbearing;
25638 cmp->rbearing -= cmp->lbearing;
25639 cmp->lbearing = 0;
25641 if (right_padded && rightmost < cmp->rbearing)
25643 rightmost = cmp->rbearing;
25646 cmp->pixel_width = rightmost;
25647 cmp->ascent = highest;
25648 cmp->descent = - lowest;
25649 if (cmp->ascent < font_ascent)
25650 cmp->ascent = font_ascent;
25651 if (cmp->descent < font_descent)
25652 cmp->descent = font_descent;
25655 if (it->glyph_row
25656 && (cmp->lbearing < 0
25657 || cmp->rbearing > cmp->pixel_width))
25658 it->glyph_row->contains_overlapping_glyphs_p = 1;
25660 it->pixel_width = cmp->pixel_width;
25661 it->ascent = it->phys_ascent = cmp->ascent;
25662 it->descent = it->phys_descent = cmp->descent;
25663 if (face->box != FACE_NO_BOX)
25665 int thick = face->box_line_width;
25667 if (thick > 0)
25669 it->ascent += thick;
25670 it->descent += thick;
25672 else
25673 thick = - thick;
25675 if (it->start_of_box_run_p)
25676 it->pixel_width += thick;
25677 if (it->end_of_box_run_p)
25678 it->pixel_width += thick;
25681 /* If face has an overline, add the height of the overline
25682 (1 pixel) and a 1 pixel margin to the character height. */
25683 if (face->overline_p)
25684 it->ascent += overline_margin;
25686 take_vertical_position_into_account (it);
25687 if (it->ascent < 0)
25688 it->ascent = 0;
25689 if (it->descent < 0)
25690 it->descent = 0;
25692 if (it->glyph_row && cmp->glyph_len > 0)
25693 append_composite_glyph (it);
25695 else if (it->what == IT_COMPOSITION)
25697 /* A dynamic (automatic) composition. */
25698 struct face *face = FACE_FROM_ID (it->f, it->face_id);
25699 Lisp_Object gstring;
25700 struct font_metrics metrics;
25702 it->nglyphs = 1;
25704 gstring = composition_gstring_from_id (it->cmp_it.id);
25705 it->pixel_width
25706 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
25707 &metrics);
25708 if (it->glyph_row
25709 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
25710 it->glyph_row->contains_overlapping_glyphs_p = 1;
25711 it->ascent = it->phys_ascent = metrics.ascent;
25712 it->descent = it->phys_descent = metrics.descent;
25713 if (face->box != FACE_NO_BOX)
25715 int thick = face->box_line_width;
25717 if (thick > 0)
25719 it->ascent += thick;
25720 it->descent += thick;
25722 else
25723 thick = - thick;
25725 if (it->start_of_box_run_p)
25726 it->pixel_width += thick;
25727 if (it->end_of_box_run_p)
25728 it->pixel_width += thick;
25730 /* If face has an overline, add the height of the overline
25731 (1 pixel) and a 1 pixel margin to the character height. */
25732 if (face->overline_p)
25733 it->ascent += overline_margin;
25734 take_vertical_position_into_account (it);
25735 if (it->ascent < 0)
25736 it->ascent = 0;
25737 if (it->descent < 0)
25738 it->descent = 0;
25740 if (it->glyph_row)
25741 append_composite_glyph (it);
25743 else if (it->what == IT_GLYPHLESS)
25744 produce_glyphless_glyph (it, 0, Qnil);
25745 else if (it->what == IT_IMAGE)
25746 produce_image_glyph (it);
25747 else if (it->what == IT_STRETCH)
25748 produce_stretch_glyph (it);
25750 done:
25751 /* Accumulate dimensions. Note: can't assume that it->descent > 0
25752 because this isn't true for images with `:ascent 100'. */
25753 eassert (it->ascent >= 0 && it->descent >= 0);
25754 if (it->area == TEXT_AREA)
25755 it->current_x += it->pixel_width;
25757 if (extra_line_spacing > 0)
25759 it->descent += extra_line_spacing;
25760 if (extra_line_spacing > it->max_extra_line_spacing)
25761 it->max_extra_line_spacing = extra_line_spacing;
25764 it->max_ascent = max (it->max_ascent, it->ascent);
25765 it->max_descent = max (it->max_descent, it->descent);
25766 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
25767 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
25770 /* EXPORT for RIF:
25771 Output LEN glyphs starting at START at the nominal cursor position.
25772 Advance the nominal cursor over the text. UPDATED_ROW is the glyph row
25773 being updated, and UPDATED_AREA is the area of that row being updated. */
25775 void
25776 x_write_glyphs (struct window *w, struct glyph_row *updated_row,
25777 struct glyph *start, enum glyph_row_area updated_area, int len)
25779 int x, hpos, chpos = w->phys_cursor.hpos;
25781 eassert (updated_row);
25782 /* When the window is hscrolled, cursor hpos can legitimately be out
25783 of bounds, but we draw the cursor at the corresponding window
25784 margin in that case. */
25785 if (!updated_row->reversed_p && chpos < 0)
25786 chpos = 0;
25787 if (updated_row->reversed_p && chpos >= updated_row->used[TEXT_AREA])
25788 chpos = updated_row->used[TEXT_AREA] - 1;
25790 block_input ();
25792 /* Write glyphs. */
25794 hpos = start - updated_row->glyphs[updated_area];
25795 x = draw_glyphs (w, output_cursor.x,
25796 updated_row, updated_area,
25797 hpos, hpos + len,
25798 DRAW_NORMAL_TEXT, 0);
25800 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
25801 if (updated_area == TEXT_AREA
25802 && w->phys_cursor_on_p
25803 && w->phys_cursor.vpos == output_cursor.vpos
25804 && chpos >= hpos
25805 && chpos < hpos + len)
25806 w->phys_cursor_on_p = 0;
25808 unblock_input ();
25810 /* Advance the output cursor. */
25811 output_cursor.hpos += len;
25812 output_cursor.x = x;
25816 /* EXPORT for RIF:
25817 Insert LEN glyphs from START at the nominal cursor position. */
25819 void
25820 x_insert_glyphs (struct window *w, struct glyph_row *updated_row,
25821 struct glyph *start, enum glyph_row_area updated_area, int len)
25823 struct frame *f;
25824 int line_height, shift_by_width, shifted_region_width;
25825 struct glyph_row *row;
25826 struct glyph *glyph;
25827 int frame_x, frame_y;
25828 ptrdiff_t hpos;
25830 eassert (updated_row);
25831 block_input ();
25832 f = XFRAME (WINDOW_FRAME (w));
25834 /* Get the height of the line we are in. */
25835 row = updated_row;
25836 line_height = row->height;
25838 /* Get the width of the glyphs to insert. */
25839 shift_by_width = 0;
25840 for (glyph = start; glyph < start + len; ++glyph)
25841 shift_by_width += glyph->pixel_width;
25843 /* Get the width of the region to shift right. */
25844 shifted_region_width = (window_box_width (w, updated_area)
25845 - output_cursor.x
25846 - shift_by_width);
25848 /* Shift right. */
25849 frame_x = window_box_left (w, updated_area) + output_cursor.x;
25850 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
25852 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
25853 line_height, shift_by_width);
25855 /* Write the glyphs. */
25856 hpos = start - row->glyphs[updated_area];
25857 draw_glyphs (w, output_cursor.x, row, updated_area,
25858 hpos, hpos + len,
25859 DRAW_NORMAL_TEXT, 0);
25861 /* Advance the output cursor. */
25862 output_cursor.hpos += len;
25863 output_cursor.x += shift_by_width;
25864 unblock_input ();
25868 /* EXPORT for RIF:
25869 Erase the current text line from the nominal cursor position
25870 (inclusive) to pixel column TO_X (exclusive). The idea is that
25871 everything from TO_X onward is already erased.
25873 TO_X is a pixel position relative to UPDATED_AREA of currently
25874 updated window W. TO_X == -1 means clear to the end of this area. */
25876 void
25877 x_clear_end_of_line (struct window *w, struct glyph_row *updated_row,
25878 enum glyph_row_area updated_area, int to_x)
25880 struct frame *f;
25881 int max_x, min_y, max_y;
25882 int from_x, from_y, to_y;
25884 eassert (updated_row);
25885 f = XFRAME (w->frame);
25887 if (updated_row->full_width_p)
25888 max_x = WINDOW_TOTAL_WIDTH (w);
25889 else
25890 max_x = window_box_width (w, updated_area);
25891 max_y = window_text_bottom_y (w);
25893 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
25894 of window. For TO_X > 0, truncate to end of drawing area. */
25895 if (to_x == 0)
25896 return;
25897 else if (to_x < 0)
25898 to_x = max_x;
25899 else
25900 to_x = min (to_x, max_x);
25902 to_y = min (max_y, output_cursor.y + updated_row->height);
25904 /* Notice if the cursor will be cleared by this operation. */
25905 if (!updated_row->full_width_p)
25906 notice_overwritten_cursor (w, updated_area,
25907 output_cursor.x, -1,
25908 updated_row->y,
25909 MATRIX_ROW_BOTTOM_Y (updated_row));
25911 from_x = output_cursor.x;
25913 /* Translate to frame coordinates. */
25914 if (updated_row->full_width_p)
25916 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
25917 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
25919 else
25921 int area_left = window_box_left (w, updated_area);
25922 from_x += area_left;
25923 to_x += area_left;
25926 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
25927 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
25928 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
25930 /* Prevent inadvertently clearing to end of the X window. */
25931 if (to_x > from_x && to_y > from_y)
25933 block_input ();
25934 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
25935 to_x - from_x, to_y - from_y);
25936 unblock_input ();
25940 #endif /* HAVE_WINDOW_SYSTEM */
25944 /***********************************************************************
25945 Cursor types
25946 ***********************************************************************/
25948 /* Value is the internal representation of the specified cursor type
25949 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
25950 of the bar cursor. */
25952 static enum text_cursor_kinds
25953 get_specified_cursor_type (Lisp_Object arg, int *width)
25955 enum text_cursor_kinds type;
25957 if (NILP (arg))
25958 return NO_CURSOR;
25960 if (EQ (arg, Qbox))
25961 return FILLED_BOX_CURSOR;
25963 if (EQ (arg, Qhollow))
25964 return HOLLOW_BOX_CURSOR;
25966 if (EQ (arg, Qbar))
25968 *width = 2;
25969 return BAR_CURSOR;
25972 if (CONSP (arg)
25973 && EQ (XCAR (arg), Qbar)
25974 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
25976 *width = XINT (XCDR (arg));
25977 return BAR_CURSOR;
25980 if (EQ (arg, Qhbar))
25982 *width = 2;
25983 return HBAR_CURSOR;
25986 if (CONSP (arg)
25987 && EQ (XCAR (arg), Qhbar)
25988 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
25990 *width = XINT (XCDR (arg));
25991 return HBAR_CURSOR;
25994 /* Treat anything unknown as "hollow box cursor".
25995 It was bad to signal an error; people have trouble fixing
25996 .Xdefaults with Emacs, when it has something bad in it. */
25997 type = HOLLOW_BOX_CURSOR;
25999 return type;
26002 /* Set the default cursor types for specified frame. */
26003 void
26004 set_frame_cursor_types (struct frame *f, Lisp_Object arg)
26006 int width = 1;
26007 Lisp_Object tem;
26009 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
26010 FRAME_CURSOR_WIDTH (f) = width;
26012 /* By default, set up the blink-off state depending on the on-state. */
26014 tem = Fassoc (arg, Vblink_cursor_alist);
26015 if (!NILP (tem))
26017 FRAME_BLINK_OFF_CURSOR (f)
26018 = get_specified_cursor_type (XCDR (tem), &width);
26019 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
26021 else
26022 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
26024 /* Make sure the cursor gets redrawn. */
26025 cursor_type_changed = 1;
26029 #ifdef HAVE_WINDOW_SYSTEM
26031 /* Return the cursor we want to be displayed in window W. Return
26032 width of bar/hbar cursor through WIDTH arg. Return with
26033 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
26034 (i.e. if the `system caret' should track this cursor).
26036 In a mini-buffer window, we want the cursor only to appear if we
26037 are reading input from this window. For the selected window, we
26038 want the cursor type given by the frame parameter or buffer local
26039 setting of cursor-type. If explicitly marked off, draw no cursor.
26040 In all other cases, we want a hollow box cursor. */
26042 static enum text_cursor_kinds
26043 get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
26044 int *active_cursor)
26046 struct frame *f = XFRAME (w->frame);
26047 struct buffer *b = XBUFFER (w->contents);
26048 int cursor_type = DEFAULT_CURSOR;
26049 Lisp_Object alt_cursor;
26050 int non_selected = 0;
26052 *active_cursor = 1;
26054 /* Echo area */
26055 if (cursor_in_echo_area
26056 && FRAME_HAS_MINIBUF_P (f)
26057 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
26059 if (w == XWINDOW (echo_area_window))
26061 if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
26063 *width = FRAME_CURSOR_WIDTH (f);
26064 return FRAME_DESIRED_CURSOR (f);
26066 else
26067 return get_specified_cursor_type (BVAR (b, cursor_type), width);
26070 *active_cursor = 0;
26071 non_selected = 1;
26074 /* Detect a nonselected window or nonselected frame. */
26075 else if (w != XWINDOW (f->selected_window)
26076 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame)
26078 *active_cursor = 0;
26080 if (MINI_WINDOW_P (w) && minibuf_level == 0)
26081 return NO_CURSOR;
26083 non_selected = 1;
26086 /* Never display a cursor in a window in which cursor-type is nil. */
26087 if (NILP (BVAR (b, cursor_type)))
26088 return NO_CURSOR;
26090 /* Get the normal cursor type for this window. */
26091 if (EQ (BVAR (b, cursor_type), Qt))
26093 cursor_type = FRAME_DESIRED_CURSOR (f);
26094 *width = FRAME_CURSOR_WIDTH (f);
26096 else
26097 cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
26099 /* Use cursor-in-non-selected-windows instead
26100 for non-selected window or frame. */
26101 if (non_selected)
26103 alt_cursor = BVAR (b, cursor_in_non_selected_windows);
26104 if (!EQ (Qt, alt_cursor))
26105 return get_specified_cursor_type (alt_cursor, width);
26106 /* t means modify the normal cursor type. */
26107 if (cursor_type == FILLED_BOX_CURSOR)
26108 cursor_type = HOLLOW_BOX_CURSOR;
26109 else if (cursor_type == BAR_CURSOR && *width > 1)
26110 --*width;
26111 return cursor_type;
26114 /* Use normal cursor if not blinked off. */
26115 if (!w->cursor_off_p)
26117 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
26119 if (cursor_type == FILLED_BOX_CURSOR)
26121 /* Using a block cursor on large images can be very annoying.
26122 So use a hollow cursor for "large" images.
26123 If image is not transparent (no mask), also use hollow cursor. */
26124 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
26125 if (img != NULL && IMAGEP (img->spec))
26127 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
26128 where N = size of default frame font size.
26129 This should cover most of the "tiny" icons people may use. */
26130 if (!img->mask
26131 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
26132 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
26133 cursor_type = HOLLOW_BOX_CURSOR;
26136 else if (cursor_type != NO_CURSOR)
26138 /* Display current only supports BOX and HOLLOW cursors for images.
26139 So for now, unconditionally use a HOLLOW cursor when cursor is
26140 not a solid box cursor. */
26141 cursor_type = HOLLOW_BOX_CURSOR;
26144 return cursor_type;
26147 /* Cursor is blinked off, so determine how to "toggle" it. */
26149 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
26150 if ((alt_cursor = Fassoc (BVAR (b, cursor_type), Vblink_cursor_alist), !NILP (alt_cursor)))
26151 return get_specified_cursor_type (XCDR (alt_cursor), width);
26153 /* Then see if frame has specified a specific blink off cursor type. */
26154 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
26156 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
26157 return FRAME_BLINK_OFF_CURSOR (f);
26160 #if 0
26161 /* Some people liked having a permanently visible blinking cursor,
26162 while others had very strong opinions against it. So it was
26163 decided to remove it. KFS 2003-09-03 */
26165 /* Finally perform built-in cursor blinking:
26166 filled box <-> hollow box
26167 wide [h]bar <-> narrow [h]bar
26168 narrow [h]bar <-> no cursor
26169 other type <-> no cursor */
26171 if (cursor_type == FILLED_BOX_CURSOR)
26172 return HOLLOW_BOX_CURSOR;
26174 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
26176 *width = 1;
26177 return cursor_type;
26179 #endif
26181 return NO_CURSOR;
26185 /* Notice when the text cursor of window W has been completely
26186 overwritten by a drawing operation that outputs glyphs in AREA
26187 starting at X0 and ending at X1 in the line starting at Y0 and
26188 ending at Y1. X coordinates are area-relative. X1 < 0 means all
26189 the rest of the line after X0 has been written. Y coordinates
26190 are window-relative. */
26192 static void
26193 notice_overwritten_cursor (struct window *w, enum glyph_row_area area,
26194 int x0, int x1, int y0, int y1)
26196 int cx0, cx1, cy0, cy1;
26197 struct glyph_row *row;
26199 if (!w->phys_cursor_on_p)
26200 return;
26201 if (area != TEXT_AREA)
26202 return;
26204 if (w->phys_cursor.vpos < 0
26205 || w->phys_cursor.vpos >= w->current_matrix->nrows
26206 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
26207 !(row->enabled_p && MATRIX_ROW_DISPLAYS_TEXT_P (row))))
26208 return;
26210 if (row->cursor_in_fringe_p)
26212 row->cursor_in_fringe_p = 0;
26213 draw_fringe_bitmap (w, row, row->reversed_p);
26214 w->phys_cursor_on_p = 0;
26215 return;
26218 cx0 = w->phys_cursor.x;
26219 cx1 = cx0 + w->phys_cursor_width;
26220 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
26221 return;
26223 /* The cursor image will be completely removed from the
26224 screen if the output area intersects the cursor area in
26225 y-direction. When we draw in [y0 y1[, and some part of
26226 the cursor is at y < y0, that part must have been drawn
26227 before. When scrolling, the cursor is erased before
26228 actually scrolling, so we don't come here. When not
26229 scrolling, the rows above the old cursor row must have
26230 changed, and in this case these rows must have written
26231 over the cursor image.
26233 Likewise if part of the cursor is below y1, with the
26234 exception of the cursor being in the first blank row at
26235 the buffer and window end because update_text_area
26236 doesn't draw that row. (Except when it does, but
26237 that's handled in update_text_area.) */
26239 cy0 = w->phys_cursor.y;
26240 cy1 = cy0 + w->phys_cursor_height;
26241 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
26242 return;
26244 w->phys_cursor_on_p = 0;
26247 #endif /* HAVE_WINDOW_SYSTEM */
26250 /************************************************************************
26251 Mouse Face
26252 ************************************************************************/
26254 #ifdef HAVE_WINDOW_SYSTEM
26256 /* EXPORT for RIF:
26257 Fix the display of area AREA of overlapping row ROW in window W
26258 with respect to the overlapping part OVERLAPS. */
26260 void
26261 x_fix_overlapping_area (struct window *w, struct glyph_row *row,
26262 enum glyph_row_area area, int overlaps)
26264 int i, x;
26266 block_input ();
26268 x = 0;
26269 for (i = 0; i < row->used[area];)
26271 if (row->glyphs[area][i].overlaps_vertically_p)
26273 int start = i, start_x = x;
26277 x += row->glyphs[area][i].pixel_width;
26278 ++i;
26280 while (i < row->used[area]
26281 && row->glyphs[area][i].overlaps_vertically_p);
26283 draw_glyphs (w, start_x, row, area,
26284 start, i,
26285 DRAW_NORMAL_TEXT, overlaps);
26287 else
26289 x += row->glyphs[area][i].pixel_width;
26290 ++i;
26294 unblock_input ();
26298 /* EXPORT:
26299 Draw the cursor glyph of window W in glyph row ROW. See the
26300 comment of draw_glyphs for the meaning of HL. */
26302 void
26303 draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
26304 enum draw_glyphs_face hl)
26306 /* If cursor hpos is out of bounds, don't draw garbage. This can
26307 happen in mini-buffer windows when switching between echo area
26308 glyphs and mini-buffer. */
26309 if ((row->reversed_p
26310 ? (w->phys_cursor.hpos >= 0)
26311 : (w->phys_cursor.hpos < row->used[TEXT_AREA])))
26313 int on_p = w->phys_cursor_on_p;
26314 int x1;
26315 int hpos = w->phys_cursor.hpos;
26317 /* When the window is hscrolled, cursor hpos can legitimately be
26318 out of bounds, but we draw the cursor at the corresponding
26319 window margin in that case. */
26320 if (!row->reversed_p && hpos < 0)
26321 hpos = 0;
26322 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26323 hpos = row->used[TEXT_AREA] - 1;
26325 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA, hpos, hpos + 1,
26326 hl, 0);
26327 w->phys_cursor_on_p = on_p;
26329 if (hl == DRAW_CURSOR)
26330 w->phys_cursor_width = x1 - w->phys_cursor.x;
26331 /* When we erase the cursor, and ROW is overlapped by other
26332 rows, make sure that these overlapping parts of other rows
26333 are redrawn. */
26334 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
26336 w->phys_cursor_width = x1 - w->phys_cursor.x;
26338 if (row > w->current_matrix->rows
26339 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
26340 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
26341 OVERLAPS_ERASED_CURSOR);
26343 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
26344 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
26345 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
26346 OVERLAPS_ERASED_CURSOR);
26352 /* EXPORT:
26353 Erase the image of a cursor of window W from the screen. */
26355 void
26356 erase_phys_cursor (struct window *w)
26358 struct frame *f = XFRAME (w->frame);
26359 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
26360 int hpos = w->phys_cursor.hpos;
26361 int vpos = w->phys_cursor.vpos;
26362 int mouse_face_here_p = 0;
26363 struct glyph_matrix *active_glyphs = w->current_matrix;
26364 struct glyph_row *cursor_row;
26365 struct glyph *cursor_glyph;
26366 enum draw_glyphs_face hl;
26368 /* No cursor displayed or row invalidated => nothing to do on the
26369 screen. */
26370 if (w->phys_cursor_type == NO_CURSOR)
26371 goto mark_cursor_off;
26373 /* VPOS >= active_glyphs->nrows means that window has been resized.
26374 Don't bother to erase the cursor. */
26375 if (vpos >= active_glyphs->nrows)
26376 goto mark_cursor_off;
26378 /* If row containing cursor is marked invalid, there is nothing we
26379 can do. */
26380 cursor_row = MATRIX_ROW (active_glyphs, vpos);
26381 if (!cursor_row->enabled_p)
26382 goto mark_cursor_off;
26384 /* If line spacing is > 0, old cursor may only be partially visible in
26385 window after split-window. So adjust visible height. */
26386 cursor_row->visible_height = min (cursor_row->visible_height,
26387 window_text_bottom_y (w) - cursor_row->y);
26389 /* If row is completely invisible, don't attempt to delete a cursor which
26390 isn't there. This can happen if cursor is at top of a window, and
26391 we switch to a buffer with a header line in that window. */
26392 if (cursor_row->visible_height <= 0)
26393 goto mark_cursor_off;
26395 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
26396 if (cursor_row->cursor_in_fringe_p)
26398 cursor_row->cursor_in_fringe_p = 0;
26399 draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
26400 goto mark_cursor_off;
26403 /* This can happen when the new row is shorter than the old one.
26404 In this case, either draw_glyphs or clear_end_of_line
26405 should have cleared the cursor. Note that we wouldn't be
26406 able to erase the cursor in this case because we don't have a
26407 cursor glyph at hand. */
26408 if ((cursor_row->reversed_p
26409 ? (w->phys_cursor.hpos < 0)
26410 : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
26411 goto mark_cursor_off;
26413 /* When the window is hscrolled, cursor hpos can legitimately be out
26414 of bounds, but we draw the cursor at the corresponding window
26415 margin in that case. */
26416 if (!cursor_row->reversed_p && hpos < 0)
26417 hpos = 0;
26418 if (cursor_row->reversed_p && hpos >= cursor_row->used[TEXT_AREA])
26419 hpos = cursor_row->used[TEXT_AREA] - 1;
26421 /* If the cursor is in the mouse face area, redisplay that when
26422 we clear the cursor. */
26423 if (! NILP (hlinfo->mouse_face_window)
26424 && coords_in_mouse_face_p (w, hpos, vpos)
26425 /* Don't redraw the cursor's spot in mouse face if it is at the
26426 end of a line (on a newline). The cursor appears there, but
26427 mouse highlighting does not. */
26428 && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
26429 mouse_face_here_p = 1;
26431 /* Maybe clear the display under the cursor. */
26432 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
26434 int x, y, left_x;
26435 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
26436 int width;
26438 cursor_glyph = get_phys_cursor_glyph (w);
26439 if (cursor_glyph == NULL)
26440 goto mark_cursor_off;
26442 width = cursor_glyph->pixel_width;
26443 left_x = window_box_left_offset (w, TEXT_AREA);
26444 x = w->phys_cursor.x;
26445 if (x < left_x)
26446 width -= left_x - x;
26447 width = min (width, window_box_width (w, TEXT_AREA) - x);
26448 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
26449 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
26451 if (width > 0)
26452 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
26455 /* Erase the cursor by redrawing the character underneath it. */
26456 if (mouse_face_here_p)
26457 hl = DRAW_MOUSE_FACE;
26458 else
26459 hl = DRAW_NORMAL_TEXT;
26460 draw_phys_cursor_glyph (w, cursor_row, hl);
26462 mark_cursor_off:
26463 w->phys_cursor_on_p = 0;
26464 w->phys_cursor_type = NO_CURSOR;
26468 /* EXPORT:
26469 Display or clear cursor of window W. If ON is zero, clear the
26470 cursor. If it is non-zero, display the cursor. If ON is nonzero,
26471 where to put the cursor is specified by HPOS, VPOS, X and Y. */
26473 void
26474 display_and_set_cursor (struct window *w, bool on,
26475 int hpos, int vpos, int x, int y)
26477 struct frame *f = XFRAME (w->frame);
26478 int new_cursor_type;
26479 int new_cursor_width;
26480 int active_cursor;
26481 struct glyph_row *glyph_row;
26482 struct glyph *glyph;
26484 /* This is pointless on invisible frames, and dangerous on garbaged
26485 windows and frames; in the latter case, the frame or window may
26486 be in the midst of changing its size, and x and y may be off the
26487 window. */
26488 if (! FRAME_VISIBLE_P (f)
26489 || FRAME_GARBAGED_P (f)
26490 || vpos >= w->current_matrix->nrows
26491 || hpos >= w->current_matrix->matrix_w)
26492 return;
26494 /* If cursor is off and we want it off, return quickly. */
26495 if (!on && !w->phys_cursor_on_p)
26496 return;
26498 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
26499 /* If cursor row is not enabled, we don't really know where to
26500 display the cursor. */
26501 if (!glyph_row->enabled_p)
26503 w->phys_cursor_on_p = 0;
26504 return;
26507 glyph = NULL;
26508 if (!glyph_row->exact_window_width_line_p
26509 || (0 <= hpos && hpos < glyph_row->used[TEXT_AREA]))
26510 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
26512 eassert (input_blocked_p ());
26514 /* Set new_cursor_type to the cursor we want to be displayed. */
26515 new_cursor_type = get_window_cursor_type (w, glyph,
26516 &new_cursor_width, &active_cursor);
26518 /* If cursor is currently being shown and we don't want it to be or
26519 it is in the wrong place, or the cursor type is not what we want,
26520 erase it. */
26521 if (w->phys_cursor_on_p
26522 && (!on
26523 || w->phys_cursor.x != x
26524 || w->phys_cursor.y != y
26525 || new_cursor_type != w->phys_cursor_type
26526 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
26527 && new_cursor_width != w->phys_cursor_width)))
26528 erase_phys_cursor (w);
26530 /* Don't check phys_cursor_on_p here because that flag is only set
26531 to zero in some cases where we know that the cursor has been
26532 completely erased, to avoid the extra work of erasing the cursor
26533 twice. In other words, phys_cursor_on_p can be 1 and the cursor
26534 still not be visible, or it has only been partly erased. */
26535 if (on)
26537 w->phys_cursor_ascent = glyph_row->ascent;
26538 w->phys_cursor_height = glyph_row->height;
26540 /* Set phys_cursor_.* before x_draw_.* is called because some
26541 of them may need the information. */
26542 w->phys_cursor.x = x;
26543 w->phys_cursor.y = glyph_row->y;
26544 w->phys_cursor.hpos = hpos;
26545 w->phys_cursor.vpos = vpos;
26548 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
26549 new_cursor_type, new_cursor_width,
26550 on, active_cursor);
26554 /* Switch the display of W's cursor on or off, according to the value
26555 of ON. */
26557 static void
26558 update_window_cursor (struct window *w, bool on)
26560 /* Don't update cursor in windows whose frame is in the process
26561 of being deleted. */
26562 if (w->current_matrix)
26564 int hpos = w->phys_cursor.hpos;
26565 int vpos = w->phys_cursor.vpos;
26566 struct glyph_row *row;
26568 if (vpos >= w->current_matrix->nrows
26569 || hpos >= w->current_matrix->matrix_w)
26570 return;
26572 row = MATRIX_ROW (w->current_matrix, vpos);
26574 /* When the window is hscrolled, cursor hpos can legitimately be
26575 out of bounds, but we draw the cursor at the corresponding
26576 window margin in that case. */
26577 if (!row->reversed_p && hpos < 0)
26578 hpos = 0;
26579 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26580 hpos = row->used[TEXT_AREA] - 1;
26582 block_input ();
26583 display_and_set_cursor (w, on, hpos, vpos,
26584 w->phys_cursor.x, w->phys_cursor.y);
26585 unblock_input ();
26590 /* Call update_window_cursor with parameter ON_P on all leaf windows
26591 in the window tree rooted at W. */
26593 static void
26594 update_cursor_in_window_tree (struct window *w, bool on_p)
26596 while (w)
26598 if (WINDOWP (w->contents))
26599 update_cursor_in_window_tree (XWINDOW (w->contents), on_p);
26600 else
26601 update_window_cursor (w, on_p);
26603 w = NILP (w->next) ? 0 : XWINDOW (w->next);
26608 /* EXPORT:
26609 Display the cursor on window W, or clear it, according to ON_P.
26610 Don't change the cursor's position. */
26612 void
26613 x_update_cursor (struct frame *f, bool on_p)
26615 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
26619 /* EXPORT:
26620 Clear the cursor of window W to background color, and mark the
26621 cursor as not shown. This is used when the text where the cursor
26622 is about to be rewritten. */
26624 void
26625 x_clear_cursor (struct window *w)
26627 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
26628 update_window_cursor (w, 0);
26631 #endif /* HAVE_WINDOW_SYSTEM */
26633 /* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
26634 and MSDOS. */
26635 static void
26636 draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
26637 int start_hpos, int end_hpos,
26638 enum draw_glyphs_face draw)
26640 #ifdef HAVE_WINDOW_SYSTEM
26641 if (FRAME_WINDOW_P (XFRAME (w->frame)))
26643 draw_glyphs (w, start_x, row, TEXT_AREA, start_hpos, end_hpos, draw, 0);
26644 return;
26646 #endif
26647 #if defined (HAVE_GPM) || defined (MSDOS) || defined (WINDOWSNT)
26648 tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
26649 #endif
26652 /* Display the active region described by mouse_face_* according to DRAW. */
26654 static void
26655 show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
26657 struct window *w = XWINDOW (hlinfo->mouse_face_window);
26658 struct frame *f = XFRAME (WINDOW_FRAME (w));
26660 if (/* If window is in the process of being destroyed, don't bother
26661 to do anything. */
26662 w->current_matrix != NULL
26663 /* Don't update mouse highlight if hidden */
26664 && (draw != DRAW_MOUSE_FACE || !hlinfo->mouse_face_hidden)
26665 /* Recognize when we are called to operate on rows that don't exist
26666 anymore. This can happen when a window is split. */
26667 && hlinfo->mouse_face_end_row < w->current_matrix->nrows)
26669 int phys_cursor_on_p = w->phys_cursor_on_p;
26670 struct glyph_row *row, *first, *last;
26672 first = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
26673 last = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
26675 for (row = first; row <= last && row->enabled_p; ++row)
26677 int start_hpos, end_hpos, start_x;
26679 /* For all but the first row, the highlight starts at column 0. */
26680 if (row == first)
26682 /* R2L rows have BEG and END in reversed order, but the
26683 screen drawing geometry is always left to right. So
26684 we need to mirror the beginning and end of the
26685 highlighted area in R2L rows. */
26686 if (!row->reversed_p)
26688 start_hpos = hlinfo->mouse_face_beg_col;
26689 start_x = hlinfo->mouse_face_beg_x;
26691 else if (row == last)
26693 start_hpos = hlinfo->mouse_face_end_col;
26694 start_x = hlinfo->mouse_face_end_x;
26696 else
26698 start_hpos = 0;
26699 start_x = 0;
26702 else if (row->reversed_p && row == last)
26704 start_hpos = hlinfo->mouse_face_end_col;
26705 start_x = hlinfo->mouse_face_end_x;
26707 else
26709 start_hpos = 0;
26710 start_x = 0;
26713 if (row == last)
26715 if (!row->reversed_p)
26716 end_hpos = hlinfo->mouse_face_end_col;
26717 else if (row == first)
26718 end_hpos = hlinfo->mouse_face_beg_col;
26719 else
26721 end_hpos = row->used[TEXT_AREA];
26722 if (draw == DRAW_NORMAL_TEXT)
26723 row->fill_line_p = 1; /* Clear to end of line */
26726 else if (row->reversed_p && row == first)
26727 end_hpos = hlinfo->mouse_face_beg_col;
26728 else
26730 end_hpos = row->used[TEXT_AREA];
26731 if (draw == DRAW_NORMAL_TEXT)
26732 row->fill_line_p = 1; /* Clear to end of line */
26735 if (end_hpos > start_hpos)
26737 draw_row_with_mouse_face (w, start_x, row,
26738 start_hpos, end_hpos, draw);
26740 row->mouse_face_p
26741 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
26745 #ifdef HAVE_WINDOW_SYSTEM
26746 /* When we've written over the cursor, arrange for it to
26747 be displayed again. */
26748 if (FRAME_WINDOW_P (f)
26749 && phys_cursor_on_p && !w->phys_cursor_on_p)
26751 int hpos = w->phys_cursor.hpos;
26753 /* When the window is hscrolled, cursor hpos can legitimately be
26754 out of bounds, but we draw the cursor at the corresponding
26755 window margin in that case. */
26756 if (!row->reversed_p && hpos < 0)
26757 hpos = 0;
26758 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26759 hpos = row->used[TEXT_AREA] - 1;
26761 block_input ();
26762 display_and_set_cursor (w, 1, hpos, w->phys_cursor.vpos,
26763 w->phys_cursor.x, w->phys_cursor.y);
26764 unblock_input ();
26766 #endif /* HAVE_WINDOW_SYSTEM */
26769 #ifdef HAVE_WINDOW_SYSTEM
26770 /* Change the mouse cursor. */
26771 if (FRAME_WINDOW_P (f))
26773 if (draw == DRAW_NORMAL_TEXT
26774 && !EQ (hlinfo->mouse_face_window, f->tool_bar_window))
26775 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
26776 else if (draw == DRAW_MOUSE_FACE)
26777 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
26778 else
26779 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
26781 #endif /* HAVE_WINDOW_SYSTEM */
26784 /* EXPORT:
26785 Clear out the mouse-highlighted active region.
26786 Redraw it un-highlighted first. Value is non-zero if mouse
26787 face was actually drawn unhighlighted. */
26790 clear_mouse_face (Mouse_HLInfo *hlinfo)
26792 int cleared = 0;
26794 if (!hlinfo->mouse_face_hidden && !NILP (hlinfo->mouse_face_window))
26796 show_mouse_face (hlinfo, DRAW_NORMAL_TEXT);
26797 cleared = 1;
26800 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
26801 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
26802 hlinfo->mouse_face_window = Qnil;
26803 hlinfo->mouse_face_overlay = Qnil;
26804 return cleared;
26807 /* Return non-zero if the coordinates HPOS and VPOS on windows W are
26808 within the mouse face on that window. */
26809 static int
26810 coords_in_mouse_face_p (struct window *w, int hpos, int vpos)
26812 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
26814 /* Quickly resolve the easy cases. */
26815 if (!(WINDOWP (hlinfo->mouse_face_window)
26816 && XWINDOW (hlinfo->mouse_face_window) == w))
26817 return 0;
26818 if (vpos < hlinfo->mouse_face_beg_row
26819 || vpos > hlinfo->mouse_face_end_row)
26820 return 0;
26821 if (vpos > hlinfo->mouse_face_beg_row
26822 && vpos < hlinfo->mouse_face_end_row)
26823 return 1;
26825 if (!MATRIX_ROW (w->current_matrix, vpos)->reversed_p)
26827 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
26829 if (hlinfo->mouse_face_beg_col <= hpos && hpos < hlinfo->mouse_face_end_col)
26830 return 1;
26832 else if ((vpos == hlinfo->mouse_face_beg_row
26833 && hpos >= hlinfo->mouse_face_beg_col)
26834 || (vpos == hlinfo->mouse_face_end_row
26835 && hpos < hlinfo->mouse_face_end_col))
26836 return 1;
26838 else
26840 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
26842 if (hlinfo->mouse_face_end_col < hpos && hpos <= hlinfo->mouse_face_beg_col)
26843 return 1;
26845 else if ((vpos == hlinfo->mouse_face_beg_row
26846 && hpos <= hlinfo->mouse_face_beg_col)
26847 || (vpos == hlinfo->mouse_face_end_row
26848 && hpos > hlinfo->mouse_face_end_col))
26849 return 1;
26851 return 0;
26855 /* EXPORT:
26856 Non-zero if physical cursor of window W is within mouse face. */
26859 cursor_in_mouse_face_p (struct window *w)
26861 int hpos = w->phys_cursor.hpos;
26862 int vpos = w->phys_cursor.vpos;
26863 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
26865 /* When the window is hscrolled, cursor hpos can legitimately be out
26866 of bounds, but we draw the cursor at the corresponding window
26867 margin in that case. */
26868 if (!row->reversed_p && hpos < 0)
26869 hpos = 0;
26870 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26871 hpos = row->used[TEXT_AREA] - 1;
26873 return coords_in_mouse_face_p (w, hpos, vpos);
26878 /* Find the glyph rows START_ROW and END_ROW of window W that display
26879 characters between buffer positions START_CHARPOS and END_CHARPOS
26880 (excluding END_CHARPOS). DISP_STRING is a display string that
26881 covers these buffer positions. This is similar to
26882 row_containing_pos, but is more accurate when bidi reordering makes
26883 buffer positions change non-linearly with glyph rows. */
26884 static void
26885 rows_from_pos_range (struct window *w,
26886 ptrdiff_t start_charpos, ptrdiff_t end_charpos,
26887 Lisp_Object disp_string,
26888 struct glyph_row **start, struct glyph_row **end)
26890 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
26891 int last_y = window_text_bottom_y (w);
26892 struct glyph_row *row;
26894 *start = NULL;
26895 *end = NULL;
26897 while (!first->enabled_p
26898 && first < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
26899 first++;
26901 /* Find the START row. */
26902 for (row = first;
26903 row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y;
26904 row++)
26906 /* A row can potentially be the START row if the range of the
26907 characters it displays intersects the range
26908 [START_CHARPOS..END_CHARPOS). */
26909 if (! ((start_charpos < MATRIX_ROW_START_CHARPOS (row)
26910 && end_charpos < MATRIX_ROW_START_CHARPOS (row))
26911 /* See the commentary in row_containing_pos, for the
26912 explanation of the complicated way to check whether
26913 some position is beyond the end of the characters
26914 displayed by a row. */
26915 || ((start_charpos > MATRIX_ROW_END_CHARPOS (row)
26916 || (start_charpos == MATRIX_ROW_END_CHARPOS (row)
26917 && !row->ends_at_zv_p
26918 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
26919 && (end_charpos > MATRIX_ROW_END_CHARPOS (row)
26920 || (end_charpos == MATRIX_ROW_END_CHARPOS (row)
26921 && !row->ends_at_zv_p
26922 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))))))
26924 /* Found a candidate row. Now make sure at least one of the
26925 glyphs it displays has a charpos from the range
26926 [START_CHARPOS..END_CHARPOS).
26928 This is not obvious because bidi reordering could make
26929 buffer positions of a row be 1,2,3,102,101,100, and if we
26930 want to highlight characters in [50..60), we don't want
26931 this row, even though [50..60) does intersect [1..103),
26932 the range of character positions given by the row's start
26933 and end positions. */
26934 struct glyph *g = row->glyphs[TEXT_AREA];
26935 struct glyph *e = g + row->used[TEXT_AREA];
26937 while (g < e)
26939 if (((BUFFERP (g->object) || INTEGERP (g->object))
26940 && start_charpos <= g->charpos && g->charpos < end_charpos)
26941 /* A glyph that comes from DISP_STRING is by
26942 definition to be highlighted. */
26943 || EQ (g->object, disp_string))
26944 *start = row;
26945 g++;
26947 if (*start)
26948 break;
26952 /* Find the END row. */
26953 if (!*start
26954 /* If the last row is partially visible, start looking for END
26955 from that row, instead of starting from FIRST. */
26956 && !(row->enabled_p
26957 && row->y < last_y && MATRIX_ROW_BOTTOM_Y (row) > last_y))
26958 row = first;
26959 for ( ; row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y; row++)
26961 struct glyph_row *next = row + 1;
26962 ptrdiff_t next_start = MATRIX_ROW_START_CHARPOS (next);
26964 if (!next->enabled_p
26965 || next >= MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)
26966 /* The first row >= START whose range of displayed characters
26967 does NOT intersect the range [START_CHARPOS..END_CHARPOS]
26968 is the row END + 1. */
26969 || (start_charpos < next_start
26970 && end_charpos < next_start)
26971 || ((start_charpos > MATRIX_ROW_END_CHARPOS (next)
26972 || (start_charpos == MATRIX_ROW_END_CHARPOS (next)
26973 && !next->ends_at_zv_p
26974 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))
26975 && (end_charpos > MATRIX_ROW_END_CHARPOS (next)
26976 || (end_charpos == MATRIX_ROW_END_CHARPOS (next)
26977 && !next->ends_at_zv_p
26978 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))))
26980 *end = row;
26981 break;
26983 else
26985 /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
26986 but none of the characters it displays are in the range, it is
26987 also END + 1. */
26988 struct glyph *g = next->glyphs[TEXT_AREA];
26989 struct glyph *s = g;
26990 struct glyph *e = g + next->used[TEXT_AREA];
26992 while (g < e)
26994 if (((BUFFERP (g->object) || INTEGERP (g->object))
26995 && ((start_charpos <= g->charpos && g->charpos < end_charpos)
26996 /* If the buffer position of the first glyph in
26997 the row is equal to END_CHARPOS, it means
26998 the last character to be highlighted is the
26999 newline of ROW, and we must consider NEXT as
27000 END, not END+1. */
27001 || (((!next->reversed_p && g == s)
27002 || (next->reversed_p && g == e - 1))
27003 && (g->charpos == end_charpos
27004 /* Special case for when NEXT is an
27005 empty line at ZV. */
27006 || (g->charpos == -1
27007 && !row->ends_at_zv_p
27008 && next_start == end_charpos)))))
27009 /* A glyph that comes from DISP_STRING is by
27010 definition to be highlighted. */
27011 || EQ (g->object, disp_string))
27012 break;
27013 g++;
27015 if (g == e)
27017 *end = row;
27018 break;
27020 /* The first row that ends at ZV must be the last to be
27021 highlighted. */
27022 else if (next->ends_at_zv_p)
27024 *end = next;
27025 break;
27031 /* This function sets the mouse_face_* elements of HLINFO, assuming
27032 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
27033 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
27034 for the overlay or run of text properties specifying the mouse
27035 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
27036 before-string and after-string that must also be highlighted.
27037 DISP_STRING, if non-nil, is a display string that may cover some
27038 or all of the highlighted text. */
27040 static void
27041 mouse_face_from_buffer_pos (Lisp_Object window,
27042 Mouse_HLInfo *hlinfo,
27043 ptrdiff_t mouse_charpos,
27044 ptrdiff_t start_charpos,
27045 ptrdiff_t end_charpos,
27046 Lisp_Object before_string,
27047 Lisp_Object after_string,
27048 Lisp_Object disp_string)
27050 struct window *w = XWINDOW (window);
27051 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
27052 struct glyph_row *r1, *r2;
27053 struct glyph *glyph, *end;
27054 ptrdiff_t ignore, pos;
27055 int x;
27057 eassert (NILP (disp_string) || STRINGP (disp_string));
27058 eassert (NILP (before_string) || STRINGP (before_string));
27059 eassert (NILP (after_string) || STRINGP (after_string));
27061 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
27062 rows_from_pos_range (w, start_charpos, end_charpos, disp_string, &r1, &r2);
27063 if (r1 == NULL)
27064 r1 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
27065 /* If the before-string or display-string contains newlines,
27066 rows_from_pos_range skips to its last row. Move back. */
27067 if (!NILP (before_string) || !NILP (disp_string))
27069 struct glyph_row *prev;
27070 while ((prev = r1 - 1, prev >= first)
27071 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
27072 && prev->used[TEXT_AREA] > 0)
27074 struct glyph *beg = prev->glyphs[TEXT_AREA];
27075 glyph = beg + prev->used[TEXT_AREA];
27076 while (--glyph >= beg && INTEGERP (glyph->object));
27077 if (glyph < beg
27078 || !(EQ (glyph->object, before_string)
27079 || EQ (glyph->object, disp_string)))
27080 break;
27081 r1 = prev;
27084 if (r2 == NULL)
27086 r2 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
27087 hlinfo->mouse_face_past_end = 1;
27089 else if (!NILP (after_string))
27091 /* If the after-string has newlines, advance to its last row. */
27092 struct glyph_row *next;
27093 struct glyph_row *last
27094 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
27096 for (next = r2 + 1;
27097 next <= last
27098 && next->used[TEXT_AREA] > 0
27099 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
27100 ++next)
27101 r2 = next;
27103 /* The rest of the display engine assumes that mouse_face_beg_row is
27104 either above mouse_face_end_row or identical to it. But with
27105 bidi-reordered continued lines, the row for START_CHARPOS could
27106 be below the row for END_CHARPOS. If so, swap the rows and store
27107 them in correct order. */
27108 if (r1->y > r2->y)
27110 struct glyph_row *tem = r2;
27112 r2 = r1;
27113 r1 = tem;
27116 hlinfo->mouse_face_beg_y = r1->y;
27117 hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
27118 hlinfo->mouse_face_end_y = r2->y;
27119 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
27121 /* For a bidi-reordered row, the positions of BEFORE_STRING,
27122 AFTER_STRING, DISP_STRING, START_CHARPOS, and END_CHARPOS
27123 could be anywhere in the row and in any order. The strategy
27124 below is to find the leftmost and the rightmost glyph that
27125 belongs to either of these 3 strings, or whose position is
27126 between START_CHARPOS and END_CHARPOS, and highlight all the
27127 glyphs between those two. This may cover more than just the text
27128 between START_CHARPOS and END_CHARPOS if the range of characters
27129 strides the bidi level boundary, e.g. if the beginning is in R2L
27130 text while the end is in L2R text or vice versa. */
27131 if (!r1->reversed_p)
27133 /* This row is in a left to right paragraph. Scan it left to
27134 right. */
27135 glyph = r1->glyphs[TEXT_AREA];
27136 end = glyph + r1->used[TEXT_AREA];
27137 x = r1->x;
27139 /* Skip truncation glyphs at the start of the glyph row. */
27140 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
27141 for (; glyph < end
27142 && INTEGERP (glyph->object)
27143 && glyph->charpos < 0;
27144 ++glyph)
27145 x += glyph->pixel_width;
27147 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
27148 or DISP_STRING, and the first glyph from buffer whose
27149 position is between START_CHARPOS and END_CHARPOS. */
27150 for (; glyph < end
27151 && !INTEGERP (glyph->object)
27152 && !EQ (glyph->object, disp_string)
27153 && !(BUFFERP (glyph->object)
27154 && (glyph->charpos >= start_charpos
27155 && glyph->charpos < end_charpos));
27156 ++glyph)
27158 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27159 are present at buffer positions between START_CHARPOS and
27160 END_CHARPOS, or if they come from an overlay. */
27161 if (EQ (glyph->object, before_string))
27163 pos = string_buffer_position (before_string,
27164 start_charpos);
27165 /* If pos == 0, it means before_string came from an
27166 overlay, not from a buffer position. */
27167 if (!pos || (pos >= start_charpos && pos < end_charpos))
27168 break;
27170 else if (EQ (glyph->object, after_string))
27172 pos = string_buffer_position (after_string, end_charpos);
27173 if (!pos || (pos >= start_charpos && pos < end_charpos))
27174 break;
27176 x += glyph->pixel_width;
27178 hlinfo->mouse_face_beg_x = x;
27179 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
27181 else
27183 /* This row is in a right to left paragraph. Scan it right to
27184 left. */
27185 struct glyph *g;
27187 end = r1->glyphs[TEXT_AREA] - 1;
27188 glyph = end + r1->used[TEXT_AREA];
27190 /* Skip truncation glyphs at the start of the glyph row. */
27191 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
27192 for (; glyph > end
27193 && INTEGERP (glyph->object)
27194 && glyph->charpos < 0;
27195 --glyph)
27198 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
27199 or DISP_STRING, and the first glyph from buffer whose
27200 position is between START_CHARPOS and END_CHARPOS. */
27201 for (; glyph > end
27202 && !INTEGERP (glyph->object)
27203 && !EQ (glyph->object, disp_string)
27204 && !(BUFFERP (glyph->object)
27205 && (glyph->charpos >= start_charpos
27206 && glyph->charpos < end_charpos));
27207 --glyph)
27209 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27210 are present at buffer positions between START_CHARPOS and
27211 END_CHARPOS, or if they come from an overlay. */
27212 if (EQ (glyph->object, before_string))
27214 pos = string_buffer_position (before_string, start_charpos);
27215 /* If pos == 0, it means before_string came from an
27216 overlay, not from a buffer position. */
27217 if (!pos || (pos >= start_charpos && pos < end_charpos))
27218 break;
27220 else if (EQ (glyph->object, after_string))
27222 pos = string_buffer_position (after_string, end_charpos);
27223 if (!pos || (pos >= start_charpos && pos < end_charpos))
27224 break;
27228 glyph++; /* first glyph to the right of the highlighted area */
27229 for (g = r1->glyphs[TEXT_AREA], x = r1->x; g < glyph; g++)
27230 x += g->pixel_width;
27231 hlinfo->mouse_face_beg_x = x;
27232 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
27235 /* If the highlight ends in a different row, compute GLYPH and END
27236 for the end row. Otherwise, reuse the values computed above for
27237 the row where the highlight begins. */
27238 if (r2 != r1)
27240 if (!r2->reversed_p)
27242 glyph = r2->glyphs[TEXT_AREA];
27243 end = glyph + r2->used[TEXT_AREA];
27244 x = r2->x;
27246 else
27248 end = r2->glyphs[TEXT_AREA] - 1;
27249 glyph = end + r2->used[TEXT_AREA];
27253 if (!r2->reversed_p)
27255 /* Skip truncation and continuation glyphs near the end of the
27256 row, and also blanks and stretch glyphs inserted by
27257 extend_face_to_end_of_line. */
27258 while (end > glyph
27259 && INTEGERP ((end - 1)->object))
27260 --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 (--end;
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;
27290 /* Find the X coordinate of the last glyph to be highlighted. */
27291 for (; glyph <= end; ++glyph)
27292 x += glyph->pixel_width;
27294 hlinfo->mouse_face_end_x = x;
27295 hlinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
27297 else
27299 /* Skip truncation and continuation glyphs near the end of the
27300 row, and also blanks and stretch glyphs inserted by
27301 extend_face_to_end_of_line. */
27302 x = r2->x;
27303 end++;
27304 while (end < glyph
27305 && INTEGERP (end->object))
27307 x += end->pixel_width;
27308 ++end;
27310 /* Scan the rest of the glyph row from the end, looking for the
27311 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
27312 DISP_STRING, or whose position is between START_CHARPOS
27313 and END_CHARPOS */
27314 for ( ;
27315 end < glyph
27316 && !INTEGERP (end->object)
27317 && !EQ (end->object, disp_string)
27318 && !(BUFFERP (end->object)
27319 && (end->charpos >= start_charpos
27320 && end->charpos < end_charpos));
27321 ++end)
27323 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27324 are present at buffer positions between START_CHARPOS and
27325 END_CHARPOS, or if they come from an overlay. */
27326 if (EQ (end->object, before_string))
27328 pos = string_buffer_position (before_string, start_charpos);
27329 if (!pos || (pos >= start_charpos && pos < end_charpos))
27330 break;
27332 else if (EQ (end->object, after_string))
27334 pos = string_buffer_position (after_string, end_charpos);
27335 if (!pos || (pos >= start_charpos && pos < end_charpos))
27336 break;
27338 x += end->pixel_width;
27340 /* If we exited the above loop because we arrived at the last
27341 glyph of the row, and its buffer position is still not in
27342 range, it means the last character in range is the preceding
27343 newline. Bump the end column and x values to get past the
27344 last glyph. */
27345 if (end == glyph
27346 && BUFFERP (end->object)
27347 && (end->charpos < start_charpos
27348 || end->charpos >= end_charpos))
27350 x += end->pixel_width;
27351 ++end;
27353 hlinfo->mouse_face_end_x = x;
27354 hlinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
27357 hlinfo->mouse_face_window = window;
27358 hlinfo->mouse_face_face_id
27359 = face_at_buffer_position (w, mouse_charpos, 0, 0, &ignore,
27360 mouse_charpos + 1,
27361 !hlinfo->mouse_face_hidden, -1);
27362 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
27365 /* The following function is not used anymore (replaced with
27366 mouse_face_from_string_pos), but I leave it here for the time
27367 being, in case someone would. */
27369 #if 0 /* not used */
27371 /* Find the position of the glyph for position POS in OBJECT in
27372 window W's current matrix, and return in *X, *Y the pixel
27373 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
27375 RIGHT_P non-zero means return the position of the right edge of the
27376 glyph, RIGHT_P zero means return the left edge position.
27378 If no glyph for POS exists in the matrix, return the position of
27379 the glyph with the next smaller position that is in the matrix, if
27380 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
27381 exists in the matrix, return the position of the glyph with the
27382 next larger position in OBJECT.
27384 Value is non-zero if a glyph was found. */
27386 static int
27387 fast_find_string_pos (struct window *w, ptrdiff_t pos, Lisp_Object object,
27388 int *hpos, int *vpos, int *x, int *y, int right_p)
27390 int yb = window_text_bottom_y (w);
27391 struct glyph_row *r;
27392 struct glyph *best_glyph = NULL;
27393 struct glyph_row *best_row = NULL;
27394 int best_x = 0;
27396 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
27397 r->enabled_p && r->y < yb;
27398 ++r)
27400 struct glyph *g = r->glyphs[TEXT_AREA];
27401 struct glyph *e = g + r->used[TEXT_AREA];
27402 int gx;
27404 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
27405 if (EQ (g->object, object))
27407 if (g->charpos == pos)
27409 best_glyph = g;
27410 best_x = gx;
27411 best_row = r;
27412 goto found;
27414 else if (best_glyph == NULL
27415 || ((eabs (g->charpos - pos)
27416 < eabs (best_glyph->charpos - pos))
27417 && (right_p
27418 ? g->charpos < pos
27419 : g->charpos > pos)))
27421 best_glyph = g;
27422 best_x = gx;
27423 best_row = r;
27428 found:
27430 if (best_glyph)
27432 *x = best_x;
27433 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
27435 if (right_p)
27437 *x += best_glyph->pixel_width;
27438 ++*hpos;
27441 *y = best_row->y;
27442 *vpos = MATRIX_ROW_VPOS (best_row, w->current_matrix);
27445 return best_glyph != NULL;
27447 #endif /* not used */
27449 /* Find the positions of the first and the last glyphs in window W's
27450 current matrix that occlude positions [STARTPOS..ENDPOS] in OBJECT
27451 (assumed to be a string), and return in HLINFO's mouse_face_*
27452 members the pixel and column/row coordinates of those glyphs. */
27454 static void
27455 mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
27456 Lisp_Object object,
27457 ptrdiff_t startpos, ptrdiff_t endpos)
27459 int yb = window_text_bottom_y (w);
27460 struct glyph_row *r;
27461 struct glyph *g, *e;
27462 int gx;
27463 int found = 0;
27465 /* Find the glyph row with at least one position in the range
27466 [STARTPOS..ENDPOS], and the first glyph in that row whose
27467 position belongs to that range. */
27468 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
27469 r->enabled_p && r->y < yb;
27470 ++r)
27472 if (!r->reversed_p)
27474 g = r->glyphs[TEXT_AREA];
27475 e = g + r->used[TEXT_AREA];
27476 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
27477 if (EQ (g->object, object)
27478 && startpos <= g->charpos && g->charpos <= endpos)
27480 hlinfo->mouse_face_beg_row
27481 = MATRIX_ROW_VPOS (r, w->current_matrix);
27482 hlinfo->mouse_face_beg_y = r->y;
27483 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
27484 hlinfo->mouse_face_beg_x = gx;
27485 found = 1;
27486 break;
27489 else
27491 struct glyph *g1;
27493 e = r->glyphs[TEXT_AREA];
27494 g = e + r->used[TEXT_AREA];
27495 for ( ; g > e; --g)
27496 if (EQ ((g-1)->object, object)
27497 && startpos <= (g-1)->charpos && (g-1)->charpos <= endpos)
27499 hlinfo->mouse_face_beg_row
27500 = MATRIX_ROW_VPOS (r, w->current_matrix);
27501 hlinfo->mouse_face_beg_y = r->y;
27502 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
27503 for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
27504 gx += g1->pixel_width;
27505 hlinfo->mouse_face_beg_x = gx;
27506 found = 1;
27507 break;
27510 if (found)
27511 break;
27514 if (!found)
27515 return;
27517 /* Starting with the next row, look for the first row which does NOT
27518 include any glyphs whose positions are in the range. */
27519 for (++r; r->enabled_p && r->y < yb; ++r)
27521 g = r->glyphs[TEXT_AREA];
27522 e = g + r->used[TEXT_AREA];
27523 found = 0;
27524 for ( ; g < e; ++g)
27525 if (EQ (g->object, object)
27526 && startpos <= g->charpos && g->charpos <= endpos)
27528 found = 1;
27529 break;
27531 if (!found)
27532 break;
27535 /* The highlighted region ends on the previous row. */
27536 r--;
27538 /* Set the end row and its vertical pixel coordinate. */
27539 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r, w->current_matrix);
27540 hlinfo->mouse_face_end_y = r->y;
27542 /* Compute and set the end column and the end column's horizontal
27543 pixel coordinate. */
27544 if (!r->reversed_p)
27546 g = r->glyphs[TEXT_AREA];
27547 e = g + r->used[TEXT_AREA];
27548 for ( ; e > g; --e)
27549 if (EQ ((e-1)->object, object)
27550 && startpos <= (e-1)->charpos && (e-1)->charpos <= endpos)
27551 break;
27552 hlinfo->mouse_face_end_col = e - g;
27554 for (gx = r->x; g < e; ++g)
27555 gx += g->pixel_width;
27556 hlinfo->mouse_face_end_x = gx;
27558 else
27560 e = r->glyphs[TEXT_AREA];
27561 g = e + r->used[TEXT_AREA];
27562 for (gx = r->x ; e < g; ++e)
27564 if (EQ (e->object, object)
27565 && startpos <= e->charpos && e->charpos <= endpos)
27566 break;
27567 gx += e->pixel_width;
27569 hlinfo->mouse_face_end_col = e - r->glyphs[TEXT_AREA];
27570 hlinfo->mouse_face_end_x = gx;
27574 #ifdef HAVE_WINDOW_SYSTEM
27576 /* See if position X, Y is within a hot-spot of an image. */
27578 static int
27579 on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
27581 if (!CONSP (hot_spot))
27582 return 0;
27584 if (EQ (XCAR (hot_spot), Qrect))
27586 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
27587 Lisp_Object rect = XCDR (hot_spot);
27588 Lisp_Object tem;
27589 if (!CONSP (rect))
27590 return 0;
27591 if (!CONSP (XCAR (rect)))
27592 return 0;
27593 if (!CONSP (XCDR (rect)))
27594 return 0;
27595 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
27596 return 0;
27597 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
27598 return 0;
27599 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
27600 return 0;
27601 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
27602 return 0;
27603 return 1;
27605 else if (EQ (XCAR (hot_spot), Qcircle))
27607 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
27608 Lisp_Object circ = XCDR (hot_spot);
27609 Lisp_Object lr, lx0, ly0;
27610 if (CONSP (circ)
27611 && CONSP (XCAR (circ))
27612 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
27613 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
27614 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
27616 double r = XFLOATINT (lr);
27617 double dx = XINT (lx0) - x;
27618 double dy = XINT (ly0) - y;
27619 return (dx * dx + dy * dy <= r * r);
27622 else if (EQ (XCAR (hot_spot), Qpoly))
27624 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
27625 if (VECTORP (XCDR (hot_spot)))
27627 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
27628 Lisp_Object *poly = v->contents;
27629 ptrdiff_t n = v->header.size;
27630 ptrdiff_t i;
27631 int inside = 0;
27632 Lisp_Object lx, ly;
27633 int x0, y0;
27635 /* Need an even number of coordinates, and at least 3 edges. */
27636 if (n < 6 || n & 1)
27637 return 0;
27639 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
27640 If count is odd, we are inside polygon. Pixels on edges
27641 may or may not be included depending on actual geometry of the
27642 polygon. */
27643 if ((lx = poly[n-2], !INTEGERP (lx))
27644 || (ly = poly[n-1], !INTEGERP (lx)))
27645 return 0;
27646 x0 = XINT (lx), y0 = XINT (ly);
27647 for (i = 0; i < n; i += 2)
27649 int x1 = x0, y1 = y0;
27650 if ((lx = poly[i], !INTEGERP (lx))
27651 || (ly = poly[i+1], !INTEGERP (ly)))
27652 return 0;
27653 x0 = XINT (lx), y0 = XINT (ly);
27655 /* Does this segment cross the X line? */
27656 if (x0 >= x)
27658 if (x1 >= x)
27659 continue;
27661 else if (x1 < x)
27662 continue;
27663 if (y > y0 && y > y1)
27664 continue;
27665 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
27666 inside = !inside;
27668 return inside;
27671 return 0;
27674 Lisp_Object
27675 find_hot_spot (Lisp_Object map, int x, int y)
27677 while (CONSP (map))
27679 if (CONSP (XCAR (map))
27680 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
27681 return XCAR (map);
27682 map = XCDR (map);
27685 return Qnil;
27688 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
27689 3, 3, 0,
27690 doc: /* Lookup in image map MAP coordinates X and Y.
27691 An image map is an alist where each element has the format (AREA ID PLIST).
27692 An AREA is specified as either a rectangle, a circle, or a polygon:
27693 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
27694 pixel coordinates of the upper left and bottom right corners.
27695 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
27696 and the radius of the circle; r may be a float or integer.
27697 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
27698 vector describes one corner in the polygon.
27699 Returns the alist element for the first matching AREA in MAP. */)
27700 (Lisp_Object map, Lisp_Object x, Lisp_Object y)
27702 if (NILP (map))
27703 return Qnil;
27705 CHECK_NUMBER (x);
27706 CHECK_NUMBER (y);
27708 return find_hot_spot (map,
27709 clip_to_bounds (INT_MIN, XINT (x), INT_MAX),
27710 clip_to_bounds (INT_MIN, XINT (y), INT_MAX));
27714 /* Display frame CURSOR, optionally using shape defined by POINTER. */
27715 static void
27716 define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
27718 /* Do not change cursor shape while dragging mouse. */
27719 if (!NILP (do_mouse_tracking))
27720 return;
27722 if (!NILP (pointer))
27724 if (EQ (pointer, Qarrow))
27725 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27726 else if (EQ (pointer, Qhand))
27727 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
27728 else if (EQ (pointer, Qtext))
27729 cursor = FRAME_X_OUTPUT (f)->text_cursor;
27730 else if (EQ (pointer, intern ("hdrag")))
27731 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
27732 #ifdef HAVE_X_WINDOWS
27733 else if (EQ (pointer, intern ("vdrag")))
27734 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
27735 #endif
27736 else if (EQ (pointer, intern ("hourglass")))
27737 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
27738 else if (EQ (pointer, Qmodeline))
27739 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
27740 else
27741 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27744 if (cursor != No_Cursor)
27745 FRAME_RIF (f)->define_frame_cursor (f, cursor);
27748 #endif /* HAVE_WINDOW_SYSTEM */
27750 /* Take proper action when mouse has moved to the mode or header line
27751 or marginal area AREA of window W, x-position X and y-position Y.
27752 X is relative to the start of the text display area of W, so the
27753 width of bitmap areas and scroll bars must be subtracted to get a
27754 position relative to the start of the mode line. */
27756 static void
27757 note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
27758 enum window_part area)
27760 struct window *w = XWINDOW (window);
27761 struct frame *f = XFRAME (w->frame);
27762 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
27763 #ifdef HAVE_WINDOW_SYSTEM
27764 Display_Info *dpyinfo;
27765 #endif
27766 Cursor cursor = No_Cursor;
27767 Lisp_Object pointer = Qnil;
27768 int dx, dy, width, height;
27769 ptrdiff_t charpos;
27770 Lisp_Object string, object = Qnil;
27771 Lisp_Object pos IF_LINT (= Qnil), help;
27773 Lisp_Object mouse_face;
27774 int original_x_pixel = x;
27775 struct glyph * glyph = NULL, * row_start_glyph = NULL;
27776 struct glyph_row *row IF_LINT (= 0);
27778 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
27780 int x0;
27781 struct glyph *end;
27783 /* Kludge alert: mode_line_string takes X/Y in pixels, but
27784 returns them in row/column units! */
27785 string = mode_line_string (w, area, &x, &y, &charpos,
27786 &object, &dx, &dy, &width, &height);
27788 row = (area == ON_MODE_LINE
27789 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
27790 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
27792 /* Find the glyph under the mouse pointer. */
27793 if (row->mode_line_p && row->enabled_p)
27795 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
27796 end = glyph + row->used[TEXT_AREA];
27798 for (x0 = original_x_pixel;
27799 glyph < end && x0 >= glyph->pixel_width;
27800 ++glyph)
27801 x0 -= glyph->pixel_width;
27803 if (glyph >= end)
27804 glyph = NULL;
27807 else
27809 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
27810 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
27811 returns them in row/column units! */
27812 string = marginal_area_string (w, area, &x, &y, &charpos,
27813 &object, &dx, &dy, &width, &height);
27816 help = Qnil;
27818 #ifdef HAVE_WINDOW_SYSTEM
27819 if (IMAGEP (object))
27821 Lisp_Object image_map, hotspot;
27822 if ((image_map = Fplist_get (XCDR (object), QCmap),
27823 !NILP (image_map))
27824 && (hotspot = find_hot_spot (image_map, dx, dy),
27825 CONSP (hotspot))
27826 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
27828 Lisp_Object plist;
27830 /* Could check XCAR (hotspot) to see if we enter/leave this hot-spot.
27831 If so, we could look for mouse-enter, mouse-leave
27832 properties in PLIST (and do something...). */
27833 hotspot = XCDR (hotspot);
27834 if (CONSP (hotspot)
27835 && (plist = XCAR (hotspot), CONSP (plist)))
27837 pointer = Fplist_get (plist, Qpointer);
27838 if (NILP (pointer))
27839 pointer = Qhand;
27840 help = Fplist_get (plist, Qhelp_echo);
27841 if (!NILP (help))
27843 help_echo_string = help;
27844 XSETWINDOW (help_echo_window, w);
27845 help_echo_object = w->contents;
27846 help_echo_pos = charpos;
27850 if (NILP (pointer))
27851 pointer = Fplist_get (XCDR (object), QCpointer);
27853 #endif /* HAVE_WINDOW_SYSTEM */
27855 if (STRINGP (string))
27856 pos = make_number (charpos);
27858 /* Set the help text and mouse pointer. If the mouse is on a part
27859 of the mode line without any text (e.g. past the right edge of
27860 the mode line text), use the default help text and pointer. */
27861 if (STRINGP (string) || area == ON_MODE_LINE)
27863 /* Arrange to display the help by setting the global variables
27864 help_echo_string, help_echo_object, and help_echo_pos. */
27865 if (NILP (help))
27867 if (STRINGP (string))
27868 help = Fget_text_property (pos, Qhelp_echo, string);
27870 if (!NILP (help))
27872 help_echo_string = help;
27873 XSETWINDOW (help_echo_window, w);
27874 help_echo_object = string;
27875 help_echo_pos = charpos;
27877 else if (area == ON_MODE_LINE)
27879 Lisp_Object default_help
27880 = buffer_local_value_1 (Qmode_line_default_help_echo,
27881 w->contents);
27883 if (STRINGP (default_help))
27885 help_echo_string = default_help;
27886 XSETWINDOW (help_echo_window, w);
27887 help_echo_object = Qnil;
27888 help_echo_pos = -1;
27893 #ifdef HAVE_WINDOW_SYSTEM
27894 /* Change the mouse pointer according to what is under it. */
27895 if (FRAME_WINDOW_P (f))
27897 dpyinfo = FRAME_X_DISPLAY_INFO (f);
27898 if (STRINGP (string))
27900 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27902 if (NILP (pointer))
27903 pointer = Fget_text_property (pos, Qpointer, string);
27905 /* Change the mouse pointer according to what is under X/Y. */
27906 if (NILP (pointer)
27907 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
27909 Lisp_Object map;
27910 map = Fget_text_property (pos, Qlocal_map, string);
27911 if (!KEYMAPP (map))
27912 map = Fget_text_property (pos, Qkeymap, string);
27913 if (!KEYMAPP (map))
27914 cursor = dpyinfo->vertical_scroll_bar_cursor;
27917 else
27918 /* Default mode-line pointer. */
27919 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
27921 #endif
27924 /* Change the mouse face according to what is under X/Y. */
27925 if (STRINGP (string))
27927 mouse_face = Fget_text_property (pos, Qmouse_face, string);
27928 if (!NILP (Vmouse_highlight) && !NILP (mouse_face)
27929 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
27930 && glyph)
27932 Lisp_Object b, e;
27934 struct glyph * tmp_glyph;
27936 int gpos;
27937 int gseq_length;
27938 int total_pixel_width;
27939 ptrdiff_t begpos, endpos, ignore;
27941 int vpos, hpos;
27943 b = Fprevious_single_property_change (make_number (charpos + 1),
27944 Qmouse_face, string, Qnil);
27945 if (NILP (b))
27946 begpos = 0;
27947 else
27948 begpos = XINT (b);
27950 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
27951 if (NILP (e))
27952 endpos = SCHARS (string);
27953 else
27954 endpos = XINT (e);
27956 /* Calculate the glyph position GPOS of GLYPH in the
27957 displayed string, relative to the beginning of the
27958 highlighted part of the string.
27960 Note: GPOS is different from CHARPOS. CHARPOS is the
27961 position of GLYPH in the internal string object. A mode
27962 line string format has structures which are converted to
27963 a flattened string by the Emacs Lisp interpreter. The
27964 internal string is an element of those structures. The
27965 displayed string is the flattened string. */
27966 tmp_glyph = row_start_glyph;
27967 while (tmp_glyph < glyph
27968 && (!(EQ (tmp_glyph->object, glyph->object)
27969 && begpos <= tmp_glyph->charpos
27970 && tmp_glyph->charpos < endpos)))
27971 tmp_glyph++;
27972 gpos = glyph - tmp_glyph;
27974 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
27975 the highlighted part of the displayed string to which
27976 GLYPH belongs. Note: GSEQ_LENGTH is different from
27977 SCHARS (STRING), because the latter returns the length of
27978 the internal string. */
27979 for (tmp_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
27980 tmp_glyph > glyph
27981 && (!(EQ (tmp_glyph->object, glyph->object)
27982 && begpos <= tmp_glyph->charpos
27983 && tmp_glyph->charpos < endpos));
27984 tmp_glyph--)
27986 gseq_length = gpos + (tmp_glyph - glyph) + 1;
27988 /* Calculate the total pixel width of all the glyphs between
27989 the beginning of the highlighted area and GLYPH. */
27990 total_pixel_width = 0;
27991 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
27992 total_pixel_width += tmp_glyph->pixel_width;
27994 /* Pre calculation of re-rendering position. Note: X is in
27995 column units here, after the call to mode_line_string or
27996 marginal_area_string. */
27997 hpos = x - gpos;
27998 vpos = (area == ON_MODE_LINE
27999 ? (w->current_matrix)->nrows - 1
28000 : 0);
28002 /* If GLYPH's position is included in the region that is
28003 already drawn in mouse face, we have nothing to do. */
28004 if ( EQ (window, hlinfo->mouse_face_window)
28005 && (!row->reversed_p
28006 ? (hlinfo->mouse_face_beg_col <= hpos
28007 && hpos < hlinfo->mouse_face_end_col)
28008 /* In R2L rows we swap BEG and END, see below. */
28009 : (hlinfo->mouse_face_end_col <= hpos
28010 && hpos < hlinfo->mouse_face_beg_col))
28011 && hlinfo->mouse_face_beg_row == vpos )
28012 return;
28014 if (clear_mouse_face (hlinfo))
28015 cursor = No_Cursor;
28017 if (!row->reversed_p)
28019 hlinfo->mouse_face_beg_col = hpos;
28020 hlinfo->mouse_face_beg_x = original_x_pixel
28021 - (total_pixel_width + dx);
28022 hlinfo->mouse_face_end_col = hpos + gseq_length;
28023 hlinfo->mouse_face_end_x = 0;
28025 else
28027 /* In R2L rows, show_mouse_face expects BEG and END
28028 coordinates to be swapped. */
28029 hlinfo->mouse_face_end_col = hpos;
28030 hlinfo->mouse_face_end_x = original_x_pixel
28031 - (total_pixel_width + dx);
28032 hlinfo->mouse_face_beg_col = hpos + gseq_length;
28033 hlinfo->mouse_face_beg_x = 0;
28036 hlinfo->mouse_face_beg_row = vpos;
28037 hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row;
28038 hlinfo->mouse_face_beg_y = 0;
28039 hlinfo->mouse_face_end_y = 0;
28040 hlinfo->mouse_face_past_end = 0;
28041 hlinfo->mouse_face_window = window;
28043 hlinfo->mouse_face_face_id = face_at_string_position (w, string,
28044 charpos,
28045 0, 0, 0,
28046 &ignore,
28047 glyph->face_id,
28049 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
28051 if (NILP (pointer))
28052 pointer = Qhand;
28054 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
28055 clear_mouse_face (hlinfo);
28057 #ifdef HAVE_WINDOW_SYSTEM
28058 if (FRAME_WINDOW_P (f))
28059 define_frame_cursor1 (f, cursor, pointer);
28060 #endif
28064 /* EXPORT:
28065 Take proper action when the mouse has moved to position X, Y on
28066 frame F with regards to highlighting portions of display that have
28067 mouse-face properties. Also de-highlight portions of display where
28068 the mouse was before, set the mouse pointer shape as appropriate
28069 for the mouse coordinates, and activate help echo (tooltips).
28070 X and Y can be negative or out of range. */
28072 void
28073 note_mouse_highlight (struct frame *f, int x, int y)
28075 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
28076 enum window_part part = ON_NOTHING;
28077 Lisp_Object window;
28078 struct window *w;
28079 Cursor cursor = No_Cursor;
28080 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
28081 struct buffer *b;
28083 /* When a menu is active, don't highlight because this looks odd. */
28084 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
28085 if (popup_activated ())
28086 return;
28087 #endif
28089 if (!f->glyphs_initialized_p
28090 || f->pointer_invisible)
28091 return;
28093 hlinfo->mouse_face_mouse_x = x;
28094 hlinfo->mouse_face_mouse_y = y;
28095 hlinfo->mouse_face_mouse_frame = f;
28097 if (hlinfo->mouse_face_defer)
28098 return;
28100 /* Which window is that in? */
28101 window = window_from_coordinates (f, x, y, &part, 1);
28103 /* If displaying active text in another window, clear that. */
28104 if (! EQ (window, hlinfo->mouse_face_window)
28105 /* Also clear if we move out of text area in same window. */
28106 || (!NILP (hlinfo->mouse_face_window)
28107 && !NILP (window)
28108 && part != ON_TEXT
28109 && part != ON_MODE_LINE
28110 && part != ON_HEADER_LINE))
28111 clear_mouse_face (hlinfo);
28113 /* Not on a window -> return. */
28114 if (!WINDOWP (window))
28115 return;
28117 /* Reset help_echo_string. It will get recomputed below. */
28118 help_echo_string = Qnil;
28120 /* Convert to window-relative pixel coordinates. */
28121 w = XWINDOW (window);
28122 frame_to_window_pixel_xy (w, &x, &y);
28124 #ifdef HAVE_WINDOW_SYSTEM
28125 /* Handle tool-bar window differently since it doesn't display a
28126 buffer. */
28127 if (EQ (window, f->tool_bar_window))
28129 note_tool_bar_highlight (f, x, y);
28130 return;
28132 #endif
28134 /* Mouse is on the mode, header line or margin? */
28135 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
28136 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
28138 note_mode_line_or_margin_highlight (window, x, y, part);
28139 return;
28142 #ifdef HAVE_WINDOW_SYSTEM
28143 if (part == ON_VERTICAL_BORDER)
28145 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
28146 help_echo_string = build_string ("drag-mouse-1: resize");
28148 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
28149 || part == ON_SCROLL_BAR)
28150 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
28151 else
28152 cursor = FRAME_X_OUTPUT (f)->text_cursor;
28153 #endif
28155 /* Are we in a window whose display is up to date?
28156 And verify the buffer's text has not changed. */
28157 b = XBUFFER (w->contents);
28158 if (part == ON_TEXT && w->window_end_valid && !window_outdated (w))
28160 int hpos, vpos, dx, dy, area = LAST_AREA;
28161 ptrdiff_t pos;
28162 struct glyph *glyph;
28163 Lisp_Object object;
28164 Lisp_Object mouse_face = Qnil, position;
28165 Lisp_Object *overlay_vec = NULL;
28166 ptrdiff_t i, noverlays;
28167 struct buffer *obuf;
28168 ptrdiff_t obegv, ozv;
28169 int same_region;
28171 /* Find the glyph under X/Y. */
28172 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
28174 #ifdef HAVE_WINDOW_SYSTEM
28175 /* Look for :pointer property on image. */
28176 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
28178 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
28179 if (img != NULL && IMAGEP (img->spec))
28181 Lisp_Object image_map, hotspot;
28182 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
28183 !NILP (image_map))
28184 && (hotspot = find_hot_spot (image_map,
28185 glyph->slice.img.x + dx,
28186 glyph->slice.img.y + dy),
28187 CONSP (hotspot))
28188 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
28190 Lisp_Object plist;
28192 /* Could check XCAR (hotspot) to see if we enter/leave
28193 this hot-spot.
28194 If so, we could look for mouse-enter, mouse-leave
28195 properties in PLIST (and do something...). */
28196 hotspot = XCDR (hotspot);
28197 if (CONSP (hotspot)
28198 && (plist = XCAR (hotspot), CONSP (plist)))
28200 pointer = Fplist_get (plist, Qpointer);
28201 if (NILP (pointer))
28202 pointer = Qhand;
28203 help_echo_string = Fplist_get (plist, Qhelp_echo);
28204 if (!NILP (help_echo_string))
28206 help_echo_window = window;
28207 help_echo_object = glyph->object;
28208 help_echo_pos = glyph->charpos;
28212 if (NILP (pointer))
28213 pointer = Fplist_get (XCDR (img->spec), QCpointer);
28216 #endif /* HAVE_WINDOW_SYSTEM */
28218 /* Clear mouse face if X/Y not over text. */
28219 if (glyph == NULL
28220 || area != TEXT_AREA
28221 || !MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->current_matrix, vpos))
28222 /* Glyph's OBJECT is an integer for glyphs inserted by the
28223 display engine for its internal purposes, like truncation
28224 and continuation glyphs and blanks beyond the end of
28225 line's text on text terminals. If we are over such a
28226 glyph, we are not over any text. */
28227 || INTEGERP (glyph->object)
28228 /* R2L rows have a stretch glyph at their front, which
28229 stands for no text, whereas L2R rows have no glyphs at
28230 all beyond the end of text. Treat such stretch glyphs
28231 like we do with NULL glyphs in L2R rows. */
28232 || (MATRIX_ROW (w->current_matrix, vpos)->reversed_p
28233 && glyph == MATRIX_ROW_GLYPH_START (w->current_matrix, vpos)
28234 && glyph->type == STRETCH_GLYPH
28235 && glyph->avoid_cursor_p))
28237 if (clear_mouse_face (hlinfo))
28238 cursor = No_Cursor;
28239 #ifdef HAVE_WINDOW_SYSTEM
28240 if (FRAME_WINDOW_P (f) && NILP (pointer))
28242 if (area != TEXT_AREA)
28243 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
28244 else
28245 pointer = Vvoid_text_area_pointer;
28247 #endif
28248 goto set_cursor;
28251 pos = glyph->charpos;
28252 object = glyph->object;
28253 if (!STRINGP (object) && !BUFFERP (object))
28254 goto set_cursor;
28256 /* If we get an out-of-range value, return now; avoid an error. */
28257 if (BUFFERP (object) && pos > BUF_Z (b))
28258 goto set_cursor;
28260 /* Make the window's buffer temporarily current for
28261 overlays_at and compute_char_face. */
28262 obuf = current_buffer;
28263 current_buffer = b;
28264 obegv = BEGV;
28265 ozv = ZV;
28266 BEGV = BEG;
28267 ZV = Z;
28269 /* Is this char mouse-active or does it have help-echo? */
28270 position = make_number (pos);
28272 if (BUFFERP (object))
28274 /* Put all the overlays we want in a vector in overlay_vec. */
28275 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
28276 /* Sort overlays into increasing priority order. */
28277 noverlays = sort_overlays (overlay_vec, noverlays, w);
28279 else
28280 noverlays = 0;
28282 if (NILP (Vmouse_highlight))
28284 clear_mouse_face (hlinfo);
28285 goto check_help_echo;
28288 same_region = coords_in_mouse_face_p (w, hpos, vpos);
28290 if (same_region)
28291 cursor = No_Cursor;
28293 /* Check mouse-face highlighting. */
28294 if (! same_region
28295 /* If there exists an overlay with mouse-face overlapping
28296 the one we are currently highlighting, we have to
28297 check if we enter the overlapping overlay, and then
28298 highlight only that. */
28299 || (OVERLAYP (hlinfo->mouse_face_overlay)
28300 && mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
28302 /* Find the highest priority overlay with a mouse-face. */
28303 Lisp_Object overlay = Qnil;
28304 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
28306 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
28307 if (!NILP (mouse_face))
28308 overlay = overlay_vec[i];
28311 /* If we're highlighting the same overlay as before, there's
28312 no need to do that again. */
28313 if (!NILP (overlay) && EQ (overlay, hlinfo->mouse_face_overlay))
28314 goto check_help_echo;
28315 hlinfo->mouse_face_overlay = overlay;
28317 /* Clear the display of the old active region, if any. */
28318 if (clear_mouse_face (hlinfo))
28319 cursor = No_Cursor;
28321 /* If no overlay applies, get a text property. */
28322 if (NILP (overlay))
28323 mouse_face = Fget_text_property (position, Qmouse_face, object);
28325 /* Next, compute the bounds of the mouse highlighting and
28326 display it. */
28327 if (!NILP (mouse_face) && STRINGP (object))
28329 /* The mouse-highlighting comes from a display string
28330 with a mouse-face. */
28331 Lisp_Object s, e;
28332 ptrdiff_t ignore;
28334 s = Fprevious_single_property_change
28335 (make_number (pos + 1), Qmouse_face, object, Qnil);
28336 e = Fnext_single_property_change
28337 (position, Qmouse_face, object, Qnil);
28338 if (NILP (s))
28339 s = make_number (0);
28340 if (NILP (e))
28341 e = make_number (SCHARS (object) - 1);
28342 mouse_face_from_string_pos (w, hlinfo, object,
28343 XINT (s), XINT (e));
28344 hlinfo->mouse_face_past_end = 0;
28345 hlinfo->mouse_face_window = window;
28346 hlinfo->mouse_face_face_id
28347 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
28348 glyph->face_id, 1);
28349 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
28350 cursor = No_Cursor;
28352 else
28354 /* The mouse-highlighting, if any, comes from an overlay
28355 or text property in the buffer. */
28356 Lisp_Object buffer IF_LINT (= Qnil);
28357 Lisp_Object disp_string IF_LINT (= Qnil);
28359 if (STRINGP (object))
28361 /* If we are on a display string with no mouse-face,
28362 check if the text under it has one. */
28363 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
28364 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
28365 pos = string_buffer_position (object, start);
28366 if (pos > 0)
28368 mouse_face = get_char_property_and_overlay
28369 (make_number (pos), Qmouse_face, w->contents, &overlay);
28370 buffer = w->contents;
28371 disp_string = object;
28374 else
28376 buffer = object;
28377 disp_string = Qnil;
28380 if (!NILP (mouse_face))
28382 Lisp_Object before, after;
28383 Lisp_Object before_string, after_string;
28384 /* To correctly find the limits of mouse highlight
28385 in a bidi-reordered buffer, we must not use the
28386 optimization of limiting the search in
28387 previous-single-property-change and
28388 next-single-property-change, because
28389 rows_from_pos_range needs the real start and end
28390 positions to DTRT in this case. That's because
28391 the first row visible in a window does not
28392 necessarily display the character whose position
28393 is the smallest. */
28394 Lisp_Object lim1 =
28395 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
28396 ? Fmarker_position (w->start)
28397 : Qnil;
28398 Lisp_Object lim2 =
28399 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
28400 ? make_number (BUF_Z (XBUFFER (buffer)) - w->window_end_pos)
28401 : Qnil;
28403 if (NILP (overlay))
28405 /* Handle the text property case. */
28406 before = Fprevious_single_property_change
28407 (make_number (pos + 1), Qmouse_face, buffer, lim1);
28408 after = Fnext_single_property_change
28409 (make_number (pos), Qmouse_face, buffer, lim2);
28410 before_string = after_string = Qnil;
28412 else
28414 /* Handle the overlay case. */
28415 before = Foverlay_start (overlay);
28416 after = Foverlay_end (overlay);
28417 before_string = Foverlay_get (overlay, Qbefore_string);
28418 after_string = Foverlay_get (overlay, Qafter_string);
28420 if (!STRINGP (before_string)) before_string = Qnil;
28421 if (!STRINGP (after_string)) after_string = Qnil;
28424 mouse_face_from_buffer_pos (window, hlinfo, pos,
28425 NILP (before)
28427 : XFASTINT (before),
28428 NILP (after)
28429 ? BUF_Z (XBUFFER (buffer))
28430 : XFASTINT (after),
28431 before_string, after_string,
28432 disp_string);
28433 cursor = No_Cursor;
28438 check_help_echo:
28440 /* Look for a `help-echo' property. */
28441 if (NILP (help_echo_string)) {
28442 Lisp_Object help, overlay;
28444 /* Check overlays first. */
28445 help = overlay = Qnil;
28446 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
28448 overlay = overlay_vec[i];
28449 help = Foverlay_get (overlay, Qhelp_echo);
28452 if (!NILP (help))
28454 help_echo_string = help;
28455 help_echo_window = window;
28456 help_echo_object = overlay;
28457 help_echo_pos = pos;
28459 else
28461 Lisp_Object obj = glyph->object;
28462 ptrdiff_t charpos = glyph->charpos;
28464 /* Try text properties. */
28465 if (STRINGP (obj)
28466 && charpos >= 0
28467 && charpos < SCHARS (obj))
28469 help = Fget_text_property (make_number (charpos),
28470 Qhelp_echo, obj);
28471 if (NILP (help))
28473 /* If the string itself doesn't specify a help-echo,
28474 see if the buffer text ``under'' it does. */
28475 struct glyph_row *r
28476 = MATRIX_ROW (w->current_matrix, vpos);
28477 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
28478 ptrdiff_t p = string_buffer_position (obj, start);
28479 if (p > 0)
28481 help = Fget_char_property (make_number (p),
28482 Qhelp_echo, w->contents);
28483 if (!NILP (help))
28485 charpos = p;
28486 obj = w->contents;
28491 else if (BUFFERP (obj)
28492 && charpos >= BEGV
28493 && charpos < ZV)
28494 help = Fget_text_property (make_number (charpos), Qhelp_echo,
28495 obj);
28497 if (!NILP (help))
28499 help_echo_string = help;
28500 help_echo_window = window;
28501 help_echo_object = obj;
28502 help_echo_pos = charpos;
28507 #ifdef HAVE_WINDOW_SYSTEM
28508 /* Look for a `pointer' property. */
28509 if (FRAME_WINDOW_P (f) && NILP (pointer))
28511 /* Check overlays first. */
28512 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
28513 pointer = Foverlay_get (overlay_vec[i], Qpointer);
28515 if (NILP (pointer))
28517 Lisp_Object obj = glyph->object;
28518 ptrdiff_t charpos = glyph->charpos;
28520 /* Try text properties. */
28521 if (STRINGP (obj)
28522 && charpos >= 0
28523 && charpos < SCHARS (obj))
28525 pointer = Fget_text_property (make_number (charpos),
28526 Qpointer, obj);
28527 if (NILP (pointer))
28529 /* If the string itself doesn't specify a pointer,
28530 see if the buffer text ``under'' it does. */
28531 struct glyph_row *r
28532 = MATRIX_ROW (w->current_matrix, vpos);
28533 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
28534 ptrdiff_t p = string_buffer_position (obj, start);
28535 if (p > 0)
28536 pointer = Fget_char_property (make_number (p),
28537 Qpointer, w->contents);
28540 else if (BUFFERP (obj)
28541 && charpos >= BEGV
28542 && charpos < ZV)
28543 pointer = Fget_text_property (make_number (charpos),
28544 Qpointer, obj);
28547 #endif /* HAVE_WINDOW_SYSTEM */
28549 BEGV = obegv;
28550 ZV = ozv;
28551 current_buffer = obuf;
28554 set_cursor:
28556 #ifdef HAVE_WINDOW_SYSTEM
28557 if (FRAME_WINDOW_P (f))
28558 define_frame_cursor1 (f, cursor, pointer);
28559 #else
28560 /* This is here to prevent a compiler error, about "label at end of
28561 compound statement". */
28562 return;
28563 #endif
28567 /* EXPORT for RIF:
28568 Clear any mouse-face on window W. This function is part of the
28569 redisplay interface, and is called from try_window_id and similar
28570 functions to ensure the mouse-highlight is off. */
28572 void
28573 x_clear_window_mouse_face (struct window *w)
28575 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
28576 Lisp_Object window;
28578 block_input ();
28579 XSETWINDOW (window, w);
28580 if (EQ (window, hlinfo->mouse_face_window))
28581 clear_mouse_face (hlinfo);
28582 unblock_input ();
28586 /* EXPORT:
28587 Just discard the mouse face information for frame F, if any.
28588 This is used when the size of F is changed. */
28590 void
28591 cancel_mouse_face (struct frame *f)
28593 Lisp_Object window;
28594 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
28596 window = hlinfo->mouse_face_window;
28597 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
28599 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
28600 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
28601 hlinfo->mouse_face_window = Qnil;
28607 /***********************************************************************
28608 Exposure Events
28609 ***********************************************************************/
28611 #ifdef HAVE_WINDOW_SYSTEM
28613 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
28614 which intersects rectangle R. R is in window-relative coordinates. */
28616 static void
28617 expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
28618 enum glyph_row_area area)
28620 struct glyph *first = row->glyphs[area];
28621 struct glyph *end = row->glyphs[area] + row->used[area];
28622 struct glyph *last;
28623 int first_x, start_x, x;
28625 if (area == TEXT_AREA && row->fill_line_p)
28626 /* If row extends face to end of line write the whole line. */
28627 draw_glyphs (w, 0, row, area,
28628 0, row->used[area],
28629 DRAW_NORMAL_TEXT, 0);
28630 else
28632 /* Set START_X to the window-relative start position for drawing glyphs of
28633 AREA. The first glyph of the text area can be partially visible.
28634 The first glyphs of other areas cannot. */
28635 start_x = window_box_left_offset (w, area);
28636 x = start_x;
28637 if (area == TEXT_AREA)
28638 x += row->x;
28640 /* Find the first glyph that must be redrawn. */
28641 while (first < end
28642 && x + first->pixel_width < r->x)
28644 x += first->pixel_width;
28645 ++first;
28648 /* Find the last one. */
28649 last = first;
28650 first_x = x;
28651 while (last < end
28652 && x < r->x + r->width)
28654 x += last->pixel_width;
28655 ++last;
28658 /* Repaint. */
28659 if (last > first)
28660 draw_glyphs (w, first_x - start_x, row, area,
28661 first - row->glyphs[area], last - row->glyphs[area],
28662 DRAW_NORMAL_TEXT, 0);
28667 /* Redraw the parts of the glyph row ROW on window W intersecting
28668 rectangle R. R is in window-relative coordinates. Value is
28669 non-zero if mouse-face was overwritten. */
28671 static int
28672 expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
28674 eassert (row->enabled_p);
28676 if (row->mode_line_p || w->pseudo_window_p)
28677 draw_glyphs (w, 0, row, TEXT_AREA,
28678 0, row->used[TEXT_AREA],
28679 DRAW_NORMAL_TEXT, 0);
28680 else
28682 if (row->used[LEFT_MARGIN_AREA])
28683 expose_area (w, row, r, LEFT_MARGIN_AREA);
28684 if (row->used[TEXT_AREA])
28685 expose_area (w, row, r, TEXT_AREA);
28686 if (row->used[RIGHT_MARGIN_AREA])
28687 expose_area (w, row, r, RIGHT_MARGIN_AREA);
28688 draw_row_fringe_bitmaps (w, row);
28691 return row->mouse_face_p;
28695 /* Redraw those parts of glyphs rows during expose event handling that
28696 overlap other rows. Redrawing of an exposed line writes over parts
28697 of lines overlapping that exposed line; this function fixes that.
28699 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
28700 row in W's current matrix that is exposed and overlaps other rows.
28701 LAST_OVERLAPPING_ROW is the last such row. */
28703 static void
28704 expose_overlaps (struct window *w,
28705 struct glyph_row *first_overlapping_row,
28706 struct glyph_row *last_overlapping_row,
28707 XRectangle *r)
28709 struct glyph_row *row;
28711 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
28712 if (row->overlapping_p)
28714 eassert (row->enabled_p && !row->mode_line_p);
28716 row->clip = r;
28717 if (row->used[LEFT_MARGIN_AREA])
28718 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
28720 if (row->used[TEXT_AREA])
28721 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
28723 if (row->used[RIGHT_MARGIN_AREA])
28724 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
28725 row->clip = NULL;
28730 /* Return non-zero if W's cursor intersects rectangle R. */
28732 static int
28733 phys_cursor_in_rect_p (struct window *w, XRectangle *r)
28735 XRectangle cr, result;
28736 struct glyph *cursor_glyph;
28737 struct glyph_row *row;
28739 if (w->phys_cursor.vpos >= 0
28740 && w->phys_cursor.vpos < w->current_matrix->nrows
28741 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
28742 row->enabled_p)
28743 && row->cursor_in_fringe_p)
28745 /* Cursor is in the fringe. */
28746 cr.x = window_box_right_offset (w,
28747 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
28748 ? RIGHT_MARGIN_AREA
28749 : TEXT_AREA));
28750 cr.y = row->y;
28751 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
28752 cr.height = row->height;
28753 return x_intersect_rectangles (&cr, r, &result);
28756 cursor_glyph = get_phys_cursor_glyph (w);
28757 if (cursor_glyph)
28759 /* r is relative to W's box, but w->phys_cursor.x is relative
28760 to left edge of W's TEXT area. Adjust it. */
28761 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
28762 cr.y = w->phys_cursor.y;
28763 cr.width = cursor_glyph->pixel_width;
28764 cr.height = w->phys_cursor_height;
28765 /* ++KFS: W32 version used W32-specific IntersectRect here, but
28766 I assume the effect is the same -- and this is portable. */
28767 return x_intersect_rectangles (&cr, r, &result);
28769 /* If we don't understand the format, pretend we're not in the hot-spot. */
28770 return 0;
28774 /* EXPORT:
28775 Draw a vertical window border to the right of window W if W doesn't
28776 have vertical scroll bars. */
28778 void
28779 x_draw_vertical_border (struct window *w)
28781 struct frame *f = XFRAME (WINDOW_FRAME (w));
28783 /* We could do better, if we knew what type of scroll-bar the adjacent
28784 windows (on either side) have... But we don't :-(
28785 However, I think this works ok. ++KFS 2003-04-25 */
28787 /* Redraw borders between horizontally adjacent windows. Don't
28788 do it for frames with vertical scroll bars because either the
28789 right scroll bar of a window, or the left scroll bar of its
28790 neighbor will suffice as a border. */
28791 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
28792 return;
28794 /* Note: It is necessary to redraw both the left and the right
28795 borders, for when only this single window W is being
28796 redisplayed. */
28797 if (!WINDOW_RIGHTMOST_P (w)
28798 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
28800 int x0, x1, y0, y1;
28802 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
28803 y1 -= 1;
28805 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
28806 x1 -= 1;
28808 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
28810 if (!WINDOW_LEFTMOST_P (w)
28811 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
28813 int x0, x1, y0, y1;
28815 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
28816 y1 -= 1;
28818 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
28819 x0 -= 1;
28821 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
28826 /* Redraw the part of window W intersection rectangle FR. Pixel
28827 coordinates in FR are frame-relative. Call this function with
28828 input blocked. Value is non-zero if the exposure overwrites
28829 mouse-face. */
28831 static int
28832 expose_window (struct window *w, XRectangle *fr)
28834 struct frame *f = XFRAME (w->frame);
28835 XRectangle wr, r;
28836 int mouse_face_overwritten_p = 0;
28838 /* If window is not yet fully initialized, do nothing. This can
28839 happen when toolkit scroll bars are used and a window is split.
28840 Reconfiguring the scroll bar will generate an expose for a newly
28841 created window. */
28842 if (w->current_matrix == NULL)
28843 return 0;
28845 /* When we're currently updating the window, display and current
28846 matrix usually don't agree. Arrange for a thorough display
28847 later. */
28848 if (w->must_be_updated_p)
28850 SET_FRAME_GARBAGED (f);
28851 return 0;
28854 /* Frame-relative pixel rectangle of W. */
28855 wr.x = WINDOW_LEFT_EDGE_X (w);
28856 wr.y = WINDOW_TOP_EDGE_Y (w);
28857 wr.width = WINDOW_TOTAL_WIDTH (w);
28858 wr.height = WINDOW_TOTAL_HEIGHT (w);
28860 if (x_intersect_rectangles (fr, &wr, &r))
28862 int yb = window_text_bottom_y (w);
28863 struct glyph_row *row;
28864 int cursor_cleared_p, phys_cursor_on_p;
28865 struct glyph_row *first_overlapping_row, *last_overlapping_row;
28867 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
28868 r.x, r.y, r.width, r.height));
28870 /* Convert to window coordinates. */
28871 r.x -= WINDOW_LEFT_EDGE_X (w);
28872 r.y -= WINDOW_TOP_EDGE_Y (w);
28874 /* Turn off the cursor. */
28875 if (!w->pseudo_window_p
28876 && phys_cursor_in_rect_p (w, &r))
28878 x_clear_cursor (w);
28879 cursor_cleared_p = 1;
28881 else
28882 cursor_cleared_p = 0;
28884 /* If the row containing the cursor extends face to end of line,
28885 then expose_area might overwrite the cursor outside the
28886 rectangle and thus notice_overwritten_cursor might clear
28887 w->phys_cursor_on_p. We remember the original value and
28888 check later if it is changed. */
28889 phys_cursor_on_p = w->phys_cursor_on_p;
28891 /* Update lines intersecting rectangle R. */
28892 first_overlapping_row = last_overlapping_row = NULL;
28893 for (row = w->current_matrix->rows;
28894 row->enabled_p;
28895 ++row)
28897 int y0 = row->y;
28898 int y1 = MATRIX_ROW_BOTTOM_Y (row);
28900 if ((y0 >= r.y && y0 < r.y + r.height)
28901 || (y1 > r.y && y1 < r.y + r.height)
28902 || (r.y >= y0 && r.y < y1)
28903 || (r.y + r.height > y0 && r.y + r.height < y1))
28905 /* A header line may be overlapping, but there is no need
28906 to fix overlapping areas for them. KFS 2005-02-12 */
28907 if (row->overlapping_p && !row->mode_line_p)
28909 if (first_overlapping_row == NULL)
28910 first_overlapping_row = row;
28911 last_overlapping_row = row;
28914 row->clip = fr;
28915 if (expose_line (w, row, &r))
28916 mouse_face_overwritten_p = 1;
28917 row->clip = NULL;
28919 else if (row->overlapping_p)
28921 /* We must redraw a row overlapping the exposed area. */
28922 if (y0 < r.y
28923 ? y0 + row->phys_height > r.y
28924 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
28926 if (first_overlapping_row == NULL)
28927 first_overlapping_row = row;
28928 last_overlapping_row = row;
28932 if (y1 >= yb)
28933 break;
28936 /* Display the mode line if there is one. */
28937 if (WINDOW_WANTS_MODELINE_P (w)
28938 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
28939 row->enabled_p)
28940 && row->y < r.y + r.height)
28942 if (expose_line (w, row, &r))
28943 mouse_face_overwritten_p = 1;
28946 if (!w->pseudo_window_p)
28948 /* Fix the display of overlapping rows. */
28949 if (first_overlapping_row)
28950 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
28951 fr);
28953 /* Draw border between windows. */
28954 x_draw_vertical_border (w);
28956 /* Turn the cursor on again. */
28957 if (cursor_cleared_p
28958 || (phys_cursor_on_p && !w->phys_cursor_on_p))
28959 update_window_cursor (w, 1);
28963 return mouse_face_overwritten_p;
28968 /* Redraw (parts) of all windows in the window tree rooted at W that
28969 intersect R. R contains frame pixel coordinates. Value is
28970 non-zero if the exposure overwrites mouse-face. */
28972 static int
28973 expose_window_tree (struct window *w, XRectangle *r)
28975 struct frame *f = XFRAME (w->frame);
28976 int mouse_face_overwritten_p = 0;
28978 while (w && !FRAME_GARBAGED_P (f))
28980 if (WINDOWP (w->contents))
28981 mouse_face_overwritten_p
28982 |= expose_window_tree (XWINDOW (w->contents), r);
28983 else
28984 mouse_face_overwritten_p |= expose_window (w, r);
28986 w = NILP (w->next) ? NULL : XWINDOW (w->next);
28989 return mouse_face_overwritten_p;
28993 /* EXPORT:
28994 Redisplay an exposed area of frame F. X and Y are the upper-left
28995 corner of the exposed rectangle. W and H are width and height of
28996 the exposed area. All are pixel values. W or H zero means redraw
28997 the entire frame. */
28999 void
29000 expose_frame (struct frame *f, int x, int y, int w, int h)
29002 XRectangle r;
29003 int mouse_face_overwritten_p = 0;
29005 TRACE ((stderr, "expose_frame "));
29007 /* No need to redraw if frame will be redrawn soon. */
29008 if (FRAME_GARBAGED_P (f))
29010 TRACE ((stderr, " garbaged\n"));
29011 return;
29014 /* If basic faces haven't been realized yet, there is no point in
29015 trying to redraw anything. This can happen when we get an expose
29016 event while Emacs is starting, e.g. by moving another window. */
29017 if (FRAME_FACE_CACHE (f) == NULL
29018 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
29020 TRACE ((stderr, " no faces\n"));
29021 return;
29024 if (w == 0 || h == 0)
29026 r.x = r.y = 0;
29027 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
29028 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
29030 else
29032 r.x = x;
29033 r.y = y;
29034 r.width = w;
29035 r.height = h;
29038 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
29039 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
29041 if (WINDOWP (f->tool_bar_window))
29042 mouse_face_overwritten_p
29043 |= expose_window (XWINDOW (f->tool_bar_window), &r);
29045 #ifdef HAVE_X_WINDOWS
29046 #ifndef MSDOS
29047 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
29048 if (WINDOWP (f->menu_bar_window))
29049 mouse_face_overwritten_p
29050 |= expose_window (XWINDOW (f->menu_bar_window), &r);
29051 #endif /* not USE_X_TOOLKIT and not USE_GTK */
29052 #endif
29053 #endif
29055 /* Some window managers support a focus-follows-mouse style with
29056 delayed raising of frames. Imagine a partially obscured frame,
29057 and moving the mouse into partially obscured mouse-face on that
29058 frame. The visible part of the mouse-face will be highlighted,
29059 then the WM raises the obscured frame. With at least one WM, KDE
29060 2.1, Emacs is not getting any event for the raising of the frame
29061 (even tried with SubstructureRedirectMask), only Expose events.
29062 These expose events will draw text normally, i.e. not
29063 highlighted. Which means we must redo the highlight here.
29064 Subsume it under ``we love X''. --gerd 2001-08-15 */
29065 /* Included in Windows version because Windows most likely does not
29066 do the right thing if any third party tool offers
29067 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
29068 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
29070 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
29071 if (f == hlinfo->mouse_face_mouse_frame)
29073 int mouse_x = hlinfo->mouse_face_mouse_x;
29074 int mouse_y = hlinfo->mouse_face_mouse_y;
29075 clear_mouse_face (hlinfo);
29076 note_mouse_highlight (f, mouse_x, mouse_y);
29082 /* EXPORT:
29083 Determine the intersection of two rectangles R1 and R2. Return
29084 the intersection in *RESULT. Value is non-zero if RESULT is not
29085 empty. */
29088 x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
29090 XRectangle *left, *right;
29091 XRectangle *upper, *lower;
29092 int intersection_p = 0;
29094 /* Rearrange so that R1 is the left-most rectangle. */
29095 if (r1->x < r2->x)
29096 left = r1, right = r2;
29097 else
29098 left = r2, right = r1;
29100 /* X0 of the intersection is right.x0, if this is inside R1,
29101 otherwise there is no intersection. */
29102 if (right->x <= left->x + left->width)
29104 result->x = right->x;
29106 /* The right end of the intersection is the minimum of
29107 the right ends of left and right. */
29108 result->width = (min (left->x + left->width, right->x + right->width)
29109 - result->x);
29111 /* Same game for Y. */
29112 if (r1->y < r2->y)
29113 upper = r1, lower = r2;
29114 else
29115 upper = r2, lower = r1;
29117 /* The upper end of the intersection is lower.y0, if this is inside
29118 of upper. Otherwise, there is no intersection. */
29119 if (lower->y <= upper->y + upper->height)
29121 result->y = lower->y;
29123 /* The lower end of the intersection is the minimum of the lower
29124 ends of upper and lower. */
29125 result->height = (min (lower->y + lower->height,
29126 upper->y + upper->height)
29127 - result->y);
29128 intersection_p = 1;
29132 return intersection_p;
29135 #endif /* HAVE_WINDOW_SYSTEM */
29138 /***********************************************************************
29139 Initialization
29140 ***********************************************************************/
29142 void
29143 syms_of_xdisp (void)
29145 Vwith_echo_area_save_vector = Qnil;
29146 staticpro (&Vwith_echo_area_save_vector);
29148 Vmessage_stack = Qnil;
29149 staticpro (&Vmessage_stack);
29151 DEFSYM (Qinhibit_redisplay, "inhibit-redisplay");
29152 DEFSYM (Qredisplay_internal, "redisplay_internal (C function)");
29154 message_dolog_marker1 = Fmake_marker ();
29155 staticpro (&message_dolog_marker1);
29156 message_dolog_marker2 = Fmake_marker ();
29157 staticpro (&message_dolog_marker2);
29158 message_dolog_marker3 = Fmake_marker ();
29159 staticpro (&message_dolog_marker3);
29161 #ifdef GLYPH_DEBUG
29162 defsubr (&Sdump_frame_glyph_matrix);
29163 defsubr (&Sdump_glyph_matrix);
29164 defsubr (&Sdump_glyph_row);
29165 defsubr (&Sdump_tool_bar_row);
29166 defsubr (&Strace_redisplay);
29167 defsubr (&Strace_to_stderr);
29168 #endif
29169 #ifdef HAVE_WINDOW_SYSTEM
29170 defsubr (&Stool_bar_lines_needed);
29171 defsubr (&Slookup_image_map);
29172 #endif
29173 defsubr (&Sline_pixel_height);
29174 defsubr (&Sformat_mode_line);
29175 defsubr (&Sinvisible_p);
29176 defsubr (&Scurrent_bidi_paragraph_direction);
29177 defsubr (&Smove_point_visually);
29179 DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook");
29180 DEFSYM (Qoverriding_terminal_local_map, "overriding-terminal-local-map");
29181 DEFSYM (Qoverriding_local_map, "overriding-local-map");
29182 DEFSYM (Qwindow_scroll_functions, "window-scroll-functions");
29183 DEFSYM (Qwindow_text_change_functions, "window-text-change-functions");
29184 DEFSYM (Qredisplay_end_trigger_functions, "redisplay-end-trigger-functions");
29185 DEFSYM (Qinhibit_point_motion_hooks, "inhibit-point-motion-hooks");
29186 DEFSYM (Qeval, "eval");
29187 DEFSYM (QCdata, ":data");
29188 DEFSYM (Qdisplay, "display");
29189 DEFSYM (Qspace_width, "space-width");
29190 DEFSYM (Qraise, "raise");
29191 DEFSYM (Qslice, "slice");
29192 DEFSYM (Qspace, "space");
29193 DEFSYM (Qmargin, "margin");
29194 DEFSYM (Qpointer, "pointer");
29195 DEFSYM (Qleft_margin, "left-margin");
29196 DEFSYM (Qright_margin, "right-margin");
29197 DEFSYM (Qcenter, "center");
29198 DEFSYM (Qline_height, "line-height");
29199 DEFSYM (QCalign_to, ":align-to");
29200 DEFSYM (QCrelative_width, ":relative-width");
29201 DEFSYM (QCrelative_height, ":relative-height");
29202 DEFSYM (QCeval, ":eval");
29203 DEFSYM (QCpropertize, ":propertize");
29204 DEFSYM (QCfile, ":file");
29205 DEFSYM (Qfontified, "fontified");
29206 DEFSYM (Qfontification_functions, "fontification-functions");
29207 DEFSYM (Qtrailing_whitespace, "trailing-whitespace");
29208 DEFSYM (Qescape_glyph, "escape-glyph");
29209 DEFSYM (Qnobreak_space, "nobreak-space");
29210 DEFSYM (Qimage, "image");
29211 DEFSYM (Qtext, "text");
29212 DEFSYM (Qboth, "both");
29213 DEFSYM (Qboth_horiz, "both-horiz");
29214 DEFSYM (Qtext_image_horiz, "text-image-horiz");
29215 DEFSYM (QCmap, ":map");
29216 DEFSYM (QCpointer, ":pointer");
29217 DEFSYM (Qrect, "rect");
29218 DEFSYM (Qcircle, "circle");
29219 DEFSYM (Qpoly, "poly");
29220 DEFSYM (Qmessage_truncate_lines, "message-truncate-lines");
29221 DEFSYM (Qgrow_only, "grow-only");
29222 DEFSYM (Qinhibit_menubar_update, "inhibit-menubar-update");
29223 DEFSYM (Qinhibit_eval_during_redisplay, "inhibit-eval-during-redisplay");
29224 DEFSYM (Qposition, "position");
29225 DEFSYM (Qbuffer_position, "buffer-position");
29226 DEFSYM (Qobject, "object");
29227 DEFSYM (Qbar, "bar");
29228 DEFSYM (Qhbar, "hbar");
29229 DEFSYM (Qbox, "box");
29230 DEFSYM (Qhollow, "hollow");
29231 DEFSYM (Qhand, "hand");
29232 DEFSYM (Qarrow, "arrow");
29233 DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces");
29235 list_of_error = list1 (list2 (intern_c_string ("error"),
29236 intern_c_string ("void-variable")));
29237 staticpro (&list_of_error);
29239 DEFSYM (Qlast_arrow_position, "last-arrow-position");
29240 DEFSYM (Qlast_arrow_string, "last-arrow-string");
29241 DEFSYM (Qoverlay_arrow_string, "overlay-arrow-string");
29242 DEFSYM (Qoverlay_arrow_bitmap, "overlay-arrow-bitmap");
29244 echo_buffer[0] = echo_buffer[1] = Qnil;
29245 staticpro (&echo_buffer[0]);
29246 staticpro (&echo_buffer[1]);
29248 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
29249 staticpro (&echo_area_buffer[0]);
29250 staticpro (&echo_area_buffer[1]);
29252 Vmessages_buffer_name = build_pure_c_string ("*Messages*");
29253 staticpro (&Vmessages_buffer_name);
29255 mode_line_proptrans_alist = Qnil;
29256 staticpro (&mode_line_proptrans_alist);
29257 mode_line_string_list = Qnil;
29258 staticpro (&mode_line_string_list);
29259 mode_line_string_face = Qnil;
29260 staticpro (&mode_line_string_face);
29261 mode_line_string_face_prop = Qnil;
29262 staticpro (&mode_line_string_face_prop);
29263 Vmode_line_unwind_vector = Qnil;
29264 staticpro (&Vmode_line_unwind_vector);
29266 DEFSYM (Qmode_line_default_help_echo, "mode-line-default-help-echo");
29268 help_echo_string = Qnil;
29269 staticpro (&help_echo_string);
29270 help_echo_object = Qnil;
29271 staticpro (&help_echo_object);
29272 help_echo_window = Qnil;
29273 staticpro (&help_echo_window);
29274 previous_help_echo_string = Qnil;
29275 staticpro (&previous_help_echo_string);
29276 help_echo_pos = -1;
29278 DEFSYM (Qright_to_left, "right-to-left");
29279 DEFSYM (Qleft_to_right, "left-to-right");
29281 #ifdef HAVE_WINDOW_SYSTEM
29282 DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p,
29283 doc: /* Non-nil means draw block cursor as wide as the glyph under it.
29284 For example, if a block cursor is over a tab, it will be drawn as
29285 wide as that tab on the display. */);
29286 x_stretch_cursor_p = 0;
29287 #endif
29289 DEFVAR_LISP ("show-trailing-whitespace", Vshow_trailing_whitespace,
29290 doc: /* Non-nil means highlight trailing whitespace.
29291 The face used for trailing whitespace is `trailing-whitespace'. */);
29292 Vshow_trailing_whitespace = Qnil;
29294 DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display,
29295 doc: /* Control highlighting of non-ASCII space and hyphen chars.
29296 If the value is t, Emacs highlights non-ASCII chars which have the
29297 same appearance as an ASCII space or hyphen, using the `nobreak-space'
29298 or `escape-glyph' face respectively.
29300 U+00A0 (no-break space), U+00AD (soft hyphen), U+2010 (hyphen), and
29301 U+2011 (non-breaking hyphen) are affected.
29303 Any other non-nil value means to display these characters as a escape
29304 glyph followed by an ordinary space or hyphen.
29306 A value of nil means no special handling of these characters. */);
29307 Vnobreak_char_display = Qt;
29309 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer,
29310 doc: /* The pointer shape to show in void text areas.
29311 A value of nil means to show the text pointer. Other options are `arrow',
29312 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
29313 Vvoid_text_area_pointer = Qarrow;
29315 DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay,
29316 doc: /* Non-nil means don't actually do any redisplay.
29317 This is used for internal purposes. */);
29318 Vinhibit_redisplay = Qnil;
29320 DEFVAR_LISP ("global-mode-string", Vglobal_mode_string,
29321 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
29322 Vglobal_mode_string = Qnil;
29324 DEFVAR_LISP ("overlay-arrow-position", Voverlay_arrow_position,
29325 doc: /* Marker for where to display an arrow on top of the buffer text.
29326 This must be the beginning of a line in order to work.
29327 See also `overlay-arrow-string'. */);
29328 Voverlay_arrow_position = Qnil;
29330 DEFVAR_LISP ("overlay-arrow-string", Voverlay_arrow_string,
29331 doc: /* String to display as an arrow in non-window frames.
29332 See also `overlay-arrow-position'. */);
29333 Voverlay_arrow_string = build_pure_c_string ("=>");
29335 DEFVAR_LISP ("overlay-arrow-variable-list", Voverlay_arrow_variable_list,
29336 doc: /* List of variables (symbols) which hold markers for overlay arrows.
29337 The symbols on this list are examined during redisplay to determine
29338 where to display overlay arrows. */);
29339 Voverlay_arrow_variable_list
29340 = list1 (intern_c_string ("overlay-arrow-position"));
29342 DEFVAR_INT ("scroll-step", emacs_scroll_step,
29343 doc: /* The number of lines to try scrolling a window by when point moves out.
29344 If that fails to bring point back on frame, point is centered instead.
29345 If this is zero, point is always centered after it moves off frame.
29346 If you want scrolling to always be a line at a time, you should set
29347 `scroll-conservatively' to a large value rather than set this to 1. */);
29349 DEFVAR_INT ("scroll-conservatively", scroll_conservatively,
29350 doc: /* Scroll up to this many lines, to bring point back on screen.
29351 If point moves off-screen, redisplay will scroll by up to
29352 `scroll-conservatively' lines in order to bring point just barely
29353 onto the screen again. If that cannot be done, then redisplay
29354 recenters point as usual.
29356 If the value is greater than 100, redisplay will never recenter point,
29357 but will always scroll just enough text to bring point into view, even
29358 if you move far away.
29360 A value of zero means always recenter point if it moves off screen. */);
29361 scroll_conservatively = 0;
29363 DEFVAR_INT ("scroll-margin", scroll_margin,
29364 doc: /* Number of lines of margin at the top and bottom of a window.
29365 Recenter the window whenever point gets within this many lines
29366 of the top or bottom of the window. */);
29367 scroll_margin = 0;
29369 DEFVAR_LISP ("display-pixels-per-inch", Vdisplay_pixels_per_inch,
29370 doc: /* Pixels per inch value for non-window system displays.
29371 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
29372 Vdisplay_pixels_per_inch = make_float (72.0);
29374 #ifdef GLYPH_DEBUG
29375 DEFVAR_INT ("debug-end-pos", debug_end_pos, doc: /* Don't ask. */);
29376 #endif
29378 DEFVAR_LISP ("truncate-partial-width-windows",
29379 Vtruncate_partial_width_windows,
29380 doc: /* Non-nil means truncate lines in windows narrower than the frame.
29381 For an integer value, truncate lines in each window narrower than the
29382 full frame width, provided the window width is less than that integer;
29383 otherwise, respect the value of `truncate-lines'.
29385 For any other non-nil value, truncate lines in all windows that do
29386 not span the full frame width.
29388 A value of nil means to respect the value of `truncate-lines'.
29390 If `word-wrap' is enabled, you might want to reduce this. */);
29391 Vtruncate_partial_width_windows = make_number (50);
29393 DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit,
29394 doc: /* Maximum buffer size for which line number should be displayed.
29395 If the buffer is bigger than this, the line number does not appear
29396 in the mode line. A value of nil means no limit. */);
29397 Vline_number_display_limit = Qnil;
29399 DEFVAR_INT ("line-number-display-limit-width",
29400 line_number_display_limit_width,
29401 doc: /* Maximum line width (in characters) for line number display.
29402 If the average length of the lines near point is bigger than this, then the
29403 line number may be omitted from the mode line. */);
29404 line_number_display_limit_width = 200;
29406 DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows,
29407 doc: /* Non-nil means highlight region even in nonselected windows. */);
29408 highlight_nonselected_windows = 0;
29410 DEFVAR_BOOL ("multiple-frames", multiple_frames,
29411 doc: /* Non-nil if more than one frame is visible on this display.
29412 Minibuffer-only frames don't count, but iconified frames do.
29413 This variable is not guaranteed to be accurate except while processing
29414 `frame-title-format' and `icon-title-format'. */);
29416 DEFVAR_LISP ("frame-title-format", Vframe_title_format,
29417 doc: /* Template for displaying the title bar of visible frames.
29418 \(Assuming the window manager supports this feature.)
29420 This variable has the same structure as `mode-line-format', except that
29421 the %c and %l constructs are ignored. It is used only on frames for
29422 which no explicit name has been set \(see `modify-frame-parameters'). */);
29424 DEFVAR_LISP ("icon-title-format", Vicon_title_format,
29425 doc: /* Template for displaying the title bar of an iconified frame.
29426 \(Assuming the window manager supports this feature.)
29427 This variable has the same structure as `mode-line-format' (which see),
29428 and is used only on frames for which no explicit name has been set
29429 \(see `modify-frame-parameters'). */);
29430 Vicon_title_format
29431 = Vframe_title_format
29432 = listn (CONSTYPE_PURE, 3,
29433 intern_c_string ("multiple-frames"),
29434 build_pure_c_string ("%b"),
29435 listn (CONSTYPE_PURE, 4,
29436 empty_unibyte_string,
29437 intern_c_string ("invocation-name"),
29438 build_pure_c_string ("@"),
29439 intern_c_string ("system-name")));
29441 DEFVAR_LISP ("message-log-max", Vmessage_log_max,
29442 doc: /* Maximum number of lines to keep in the message log buffer.
29443 If nil, disable message logging. If t, log messages but don't truncate
29444 the buffer when it becomes large. */);
29445 Vmessage_log_max = make_number (1000);
29447 DEFVAR_LISP ("window-size-change-functions", Vwindow_size_change_functions,
29448 doc: /* Functions called before redisplay, if window sizes have changed.
29449 The value should be a list of functions that take one argument.
29450 Just before redisplay, for each frame, if any of its windows have changed
29451 size since the last redisplay, or have been split or deleted,
29452 all the functions in the list are called, with the frame as argument. */);
29453 Vwindow_size_change_functions = Qnil;
29455 DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions,
29456 doc: /* List of functions to call before redisplaying a window with scrolling.
29457 Each function is called with two arguments, the window and its new
29458 display-start position. Note that these functions are also called by
29459 `set-window-buffer'. Also note that the value of `window-end' is not
29460 valid when these functions are called.
29462 Warning: Do not use this feature to alter the way the window
29463 is scrolled. It is not designed for that, and such use probably won't
29464 work. */);
29465 Vwindow_scroll_functions = Qnil;
29467 DEFVAR_LISP ("window-text-change-functions",
29468 Vwindow_text_change_functions,
29469 doc: /* Functions to call in redisplay when text in the window might change. */);
29470 Vwindow_text_change_functions = Qnil;
29472 DEFVAR_LISP ("redisplay-end-trigger-functions", Vredisplay_end_trigger_functions,
29473 doc: /* Functions called when redisplay of a window reaches the end trigger.
29474 Each function is called with two arguments, the window and the end trigger value.
29475 See `set-window-redisplay-end-trigger'. */);
29476 Vredisplay_end_trigger_functions = Qnil;
29478 DEFVAR_LISP ("mouse-autoselect-window", Vmouse_autoselect_window,
29479 doc: /* Non-nil means autoselect window with mouse pointer.
29480 If nil, do not autoselect windows.
29481 A positive number means delay autoselection by that many seconds: a
29482 window is autoselected only after the mouse has remained in that
29483 window for the duration of the delay.
29484 A negative number has a similar effect, but causes windows to be
29485 autoselected only after the mouse has stopped moving. \(Because of
29486 the way Emacs compares mouse events, you will occasionally wait twice
29487 that time before the window gets selected.\)
29488 Any other value means to autoselect window instantaneously when the
29489 mouse pointer enters it.
29491 Autoselection selects the minibuffer only if it is active, and never
29492 unselects the minibuffer if it is active.
29494 When customizing this variable make sure that the actual value of
29495 `focus-follows-mouse' matches the behavior of your window manager. */);
29496 Vmouse_autoselect_window = Qnil;
29498 DEFVAR_LISP ("auto-resize-tool-bars", Vauto_resize_tool_bars,
29499 doc: /* Non-nil means automatically resize tool-bars.
29500 This dynamically changes the tool-bar's height to the minimum height
29501 that is needed to make all tool-bar items visible.
29502 If value is `grow-only', the tool-bar's height is only increased
29503 automatically; to decrease the tool-bar height, use \\[recenter]. */);
29504 Vauto_resize_tool_bars = Qt;
29506 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p,
29507 doc: /* Non-nil means raise tool-bar buttons when the mouse moves over them. */);
29508 auto_raise_tool_bar_buttons_p = 1;
29510 DEFVAR_BOOL ("make-cursor-line-fully-visible", make_cursor_line_fully_visible_p,
29511 doc: /* Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
29512 make_cursor_line_fully_visible_p = 1;
29514 DEFVAR_LISP ("tool-bar-border", Vtool_bar_border,
29515 doc: /* Border below tool-bar in pixels.
29516 If an integer, use it as the height of the border.
29517 If it is one of `internal-border-width' or `border-width', use the
29518 value of the corresponding frame parameter.
29519 Otherwise, no border is added below the tool-bar. */);
29520 Vtool_bar_border = Qinternal_border_width;
29522 DEFVAR_LISP ("tool-bar-button-margin", Vtool_bar_button_margin,
29523 doc: /* Margin around tool-bar buttons in pixels.
29524 If an integer, use that for both horizontal and vertical margins.
29525 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
29526 HORZ specifying the horizontal margin, and VERT specifying the
29527 vertical margin. */);
29528 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
29530 DEFVAR_INT ("tool-bar-button-relief", tool_bar_button_relief,
29531 doc: /* Relief thickness of tool-bar buttons. */);
29532 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
29534 DEFVAR_LISP ("tool-bar-style", Vtool_bar_style,
29535 doc: /* Tool bar style to use.
29536 It can be one of
29537 image - show images only
29538 text - show text only
29539 both - show both, text below image
29540 both-horiz - show text to the right of the image
29541 text-image-horiz - show text to the left of the image
29542 any other - use system default or image if no system default.
29544 This variable only affects the GTK+ toolkit version of Emacs. */);
29545 Vtool_bar_style = Qnil;
29547 DEFVAR_INT ("tool-bar-max-label-size", tool_bar_max_label_size,
29548 doc: /* Maximum number of characters a label can have to be shown.
29549 The tool bar style must also show labels for this to have any effect, see
29550 `tool-bar-style'. */);
29551 tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
29553 DEFVAR_LISP ("fontification-functions", Vfontification_functions,
29554 doc: /* List of functions to call to fontify regions of text.
29555 Each function is called with one argument POS. Functions must
29556 fontify a region starting at POS in the current buffer, and give
29557 fontified regions the property `fontified'. */);
29558 Vfontification_functions = Qnil;
29559 Fmake_variable_buffer_local (Qfontification_functions);
29561 DEFVAR_BOOL ("unibyte-display-via-language-environment",
29562 unibyte_display_via_language_environment,
29563 doc: /* Non-nil means display unibyte text according to language environment.
29564 Specifically, this means that raw bytes in the range 160-255 decimal
29565 are displayed by converting them to the equivalent multibyte characters
29566 according to the current language environment. As a result, they are
29567 displayed according to the current fontset.
29569 Note that this variable affects only how these bytes are displayed,
29570 but does not change the fact they are interpreted as raw bytes. */);
29571 unibyte_display_via_language_environment = 0;
29573 DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height,
29574 doc: /* Maximum height for resizing mini-windows (the minibuffer and the echo area).
29575 If a float, it specifies a fraction of the mini-window frame's height.
29576 If an integer, it specifies a number of lines. */);
29577 Vmax_mini_window_height = make_float (0.25);
29579 DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows,
29580 doc: /* How to resize mini-windows (the minibuffer and the echo area).
29581 A value of nil means don't automatically resize mini-windows.
29582 A value of t means resize them to fit the text displayed in them.
29583 A value of `grow-only', the default, means let mini-windows grow only;
29584 they return to their normal size when the minibuffer is closed, or the
29585 echo area becomes empty. */);
29586 Vresize_mini_windows = Qgrow_only;
29588 DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist,
29589 doc: /* Alist specifying how to blink the cursor off.
29590 Each element has the form (ON-STATE . OFF-STATE). Whenever the
29591 `cursor-type' frame-parameter or variable equals ON-STATE,
29592 comparing using `equal', Emacs uses OFF-STATE to specify
29593 how to blink it off. ON-STATE and OFF-STATE are values for
29594 the `cursor-type' frame parameter.
29596 If a frame's ON-STATE has no entry in this list,
29597 the frame's other specifications determine how to blink the cursor off. */);
29598 Vblink_cursor_alist = Qnil;
29600 DEFVAR_BOOL ("auto-hscroll-mode", automatic_hscrolling_p,
29601 doc: /* Allow or disallow automatic horizontal scrolling of windows.
29602 If non-nil, windows are automatically scrolled horizontally to make
29603 point visible. */);
29604 automatic_hscrolling_p = 1;
29605 DEFSYM (Qauto_hscroll_mode, "auto-hscroll-mode");
29607 DEFVAR_INT ("hscroll-margin", hscroll_margin,
29608 doc: /* How many columns away from the window edge point is allowed to get
29609 before automatic hscrolling will horizontally scroll the window. */);
29610 hscroll_margin = 5;
29612 DEFVAR_LISP ("hscroll-step", Vhscroll_step,
29613 doc: /* How many columns to scroll the window when point gets too close to the edge.
29614 When point is less than `hscroll-margin' columns from the window
29615 edge, automatic hscrolling will scroll the window by the amount of columns
29616 determined by this variable. If its value is a positive integer, scroll that
29617 many columns. If it's a positive floating-point number, it specifies the
29618 fraction of the window's width to scroll. If it's nil or zero, point will be
29619 centered horizontally after the scroll. Any other value, including negative
29620 numbers, are treated as if the value were zero.
29622 Automatic hscrolling always moves point outside the scroll margin, so if
29623 point was more than scroll step columns inside the margin, the window will
29624 scroll more than the value given by the scroll step.
29626 Note that the lower bound for automatic hscrolling specified by `scroll-left'
29627 and `scroll-right' overrides this variable's effect. */);
29628 Vhscroll_step = make_number (0);
29630 DEFVAR_BOOL ("message-truncate-lines", message_truncate_lines,
29631 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
29632 Bind this around calls to `message' to let it take effect. */);
29633 message_truncate_lines = 0;
29635 DEFVAR_LISP ("menu-bar-update-hook", Vmenu_bar_update_hook,
29636 doc: /* Normal hook run to update the menu bar definitions.
29637 Redisplay runs this hook before it redisplays the menu bar.
29638 This is used to update submenus such as Buffers,
29639 whose contents depend on various data. */);
29640 Vmenu_bar_update_hook = Qnil;
29642 DEFVAR_LISP ("menu-updating-frame", Vmenu_updating_frame,
29643 doc: /* Frame for which we are updating a menu.
29644 The enable predicate for a menu binding should check this variable. */);
29645 Vmenu_updating_frame = Qnil;
29647 DEFVAR_BOOL ("inhibit-menubar-update", inhibit_menubar_update,
29648 doc: /* Non-nil means don't update menu bars. Internal use only. */);
29649 inhibit_menubar_update = 0;
29651 DEFVAR_LISP ("wrap-prefix", Vwrap_prefix,
29652 doc: /* Prefix prepended to all continuation lines at display time.
29653 The value may be a string, an image, or a stretch-glyph; it is
29654 interpreted in the same way as the value of a `display' text property.
29656 This variable is overridden by any `wrap-prefix' text or overlay
29657 property.
29659 To add a prefix to non-continuation lines, use `line-prefix'. */);
29660 Vwrap_prefix = Qnil;
29661 DEFSYM (Qwrap_prefix, "wrap-prefix");
29662 Fmake_variable_buffer_local (Qwrap_prefix);
29664 DEFVAR_LISP ("line-prefix", Vline_prefix,
29665 doc: /* Prefix prepended to all non-continuation lines at display time.
29666 The value may be a string, an image, or a stretch-glyph; it is
29667 interpreted in the same way as the value of a `display' text property.
29669 This variable is overridden by any `line-prefix' text or overlay
29670 property.
29672 To add a prefix to continuation lines, use `wrap-prefix'. */);
29673 Vline_prefix = Qnil;
29674 DEFSYM (Qline_prefix, "line-prefix");
29675 Fmake_variable_buffer_local (Qline_prefix);
29677 DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay,
29678 doc: /* Non-nil means don't eval Lisp during redisplay. */);
29679 inhibit_eval_during_redisplay = 0;
29681 DEFVAR_BOOL ("inhibit-free-realized-faces", inhibit_free_realized_faces,
29682 doc: /* Non-nil means don't free realized faces. Internal use only. */);
29683 inhibit_free_realized_faces = 0;
29685 #ifdef GLYPH_DEBUG
29686 DEFVAR_BOOL ("inhibit-try-window-id", inhibit_try_window_id,
29687 doc: /* Inhibit try_window_id display optimization. */);
29688 inhibit_try_window_id = 0;
29690 DEFVAR_BOOL ("inhibit-try-window-reusing", inhibit_try_window_reusing,
29691 doc: /* Inhibit try_window_reusing display optimization. */);
29692 inhibit_try_window_reusing = 0;
29694 DEFVAR_BOOL ("inhibit-try-cursor-movement", inhibit_try_cursor_movement,
29695 doc: /* Inhibit try_cursor_movement display optimization. */);
29696 inhibit_try_cursor_movement = 0;
29697 #endif /* GLYPH_DEBUG */
29699 DEFVAR_INT ("overline-margin", overline_margin,
29700 doc: /* Space between overline and text, in pixels.
29701 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
29702 margin to the character height. */);
29703 overline_margin = 2;
29705 DEFVAR_INT ("underline-minimum-offset",
29706 underline_minimum_offset,
29707 doc: /* Minimum distance between baseline and underline.
29708 This can improve legibility of underlined text at small font sizes,
29709 particularly when using variable `x-use-underline-position-properties'
29710 with fonts that specify an UNDERLINE_POSITION relatively close to the
29711 baseline. The default value is 1. */);
29712 underline_minimum_offset = 1;
29714 DEFVAR_BOOL ("display-hourglass", display_hourglass_p,
29715 doc: /* Non-nil means show an hourglass pointer, when Emacs is busy.
29716 This feature only works when on a window system that can change
29717 cursor shapes. */);
29718 display_hourglass_p = 1;
29720 DEFVAR_LISP ("hourglass-delay", Vhourglass_delay,
29721 doc: /* Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
29722 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
29724 hourglass_atimer = NULL;
29725 hourglass_shown_p = 0;
29727 DEFSYM (Qglyphless_char, "glyphless-char");
29728 DEFSYM (Qhex_code, "hex-code");
29729 DEFSYM (Qempty_box, "empty-box");
29730 DEFSYM (Qthin_space, "thin-space");
29731 DEFSYM (Qzero_width, "zero-width");
29733 DEFSYM (Qglyphless_char_display, "glyphless-char-display");
29734 Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
29736 DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display,
29737 doc: /* Char-table defining glyphless characters.
29738 Each element, if non-nil, should be one of the following:
29739 an ASCII acronym string: display this string in a box
29740 `hex-code': display the hexadecimal code of a character in a box
29741 `empty-box': display as an empty box
29742 `thin-space': display as 1-pixel width space
29743 `zero-width': don't display
29744 An element may also be a cons cell (GRAPHICAL . TEXT), which specifies the
29745 display method for graphical terminals and text terminals respectively.
29746 GRAPHICAL and TEXT should each have one of the values listed above.
29748 The char-table has one extra slot to control the display of a character for
29749 which no font is found. This slot only takes effect on graphical terminals.
29750 Its value should be an ASCII acronym string, `hex-code', `empty-box', or
29751 `thin-space'. The default is `empty-box'. */);
29752 Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
29753 Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
29754 Qempty_box);
29756 DEFVAR_LISP ("debug-on-message", Vdebug_on_message,
29757 doc: /* If non-nil, debug if a message matching this regexp is displayed. */);
29758 Vdebug_on_message = Qnil;
29762 /* Initialize this module when Emacs starts. */
29764 void
29765 init_xdisp (void)
29767 current_header_line_height = current_mode_line_height = -1;
29769 CHARPOS (this_line_start_pos) = 0;
29771 if (!noninteractive)
29773 struct window *m = XWINDOW (minibuf_window);
29774 Lisp_Object frame = m->frame;
29775 struct frame *f = XFRAME (frame);
29776 Lisp_Object root = FRAME_ROOT_WINDOW (f);
29777 struct window *r = XWINDOW (root);
29778 int i;
29780 echo_area_window = minibuf_window;
29782 r->top_line = FRAME_TOP_MARGIN (f);
29783 r->total_lines = FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f);
29784 r->total_cols = FRAME_COLS (f);
29786 m->top_line = FRAME_LINES (f) - 1;
29787 m->total_lines = 1;
29788 m->total_cols = FRAME_COLS (f);
29790 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
29791 scratch_glyph_row.glyphs[TEXT_AREA + 1]
29792 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
29794 /* The default ellipsis glyphs `...'. */
29795 for (i = 0; i < 3; ++i)
29796 default_invis_vector[i] = make_number ('.');
29800 /* Allocate the buffer for frame titles.
29801 Also used for `format-mode-line'. */
29802 int size = 100;
29803 mode_line_noprop_buf = xmalloc (size);
29804 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
29805 mode_line_noprop_ptr = mode_line_noprop_buf;
29806 mode_line_target = MODE_LINE_DISPLAY;
29809 help_echo_showing_p = 0;
29812 /* Platform-independent portion of hourglass implementation. */
29814 /* Cancel a currently active hourglass timer, and start a new one. */
29815 void
29816 start_hourglass (void)
29818 #if defined (HAVE_WINDOW_SYSTEM)
29819 EMACS_TIME delay;
29821 cancel_hourglass ();
29823 if (INTEGERP (Vhourglass_delay)
29824 && XINT (Vhourglass_delay) > 0)
29825 delay = make_emacs_time (min (XINT (Vhourglass_delay),
29826 TYPE_MAXIMUM (time_t)),
29828 else if (FLOATP (Vhourglass_delay)
29829 && XFLOAT_DATA (Vhourglass_delay) > 0)
29830 delay = EMACS_TIME_FROM_DOUBLE (XFLOAT_DATA (Vhourglass_delay));
29831 else
29832 delay = make_emacs_time (DEFAULT_HOURGLASS_DELAY, 0);
29834 #ifdef HAVE_NTGUI
29836 extern void w32_note_current_window (void);
29837 w32_note_current_window ();
29839 #endif /* HAVE_NTGUI */
29841 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
29842 show_hourglass, NULL);
29843 #endif
29847 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
29848 shown. */
29849 void
29850 cancel_hourglass (void)
29852 #if defined (HAVE_WINDOW_SYSTEM)
29853 if (hourglass_atimer)
29855 cancel_atimer (hourglass_atimer);
29856 hourglass_atimer = NULL;
29859 if (hourglass_shown_p)
29860 hide_hourglass ();
29861 #endif