Don't call sit-for in right-char and left-char for visual cursor motion.
[emacs.git] / src / xdisp.c
blob660c6b9130f92d2127252f24c7a5ae5615708ab4
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 #include "font.h"
318 #ifndef FRAME_X_OUTPUT
319 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
320 #endif
322 #define INFINITY 10000000
324 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
325 Lisp_Object Qwindow_scroll_functions;
326 static Lisp_Object Qwindow_text_change_functions;
327 static Lisp_Object Qredisplay_end_trigger_functions;
328 Lisp_Object Qinhibit_point_motion_hooks;
329 static Lisp_Object QCeval, QCpropertize;
330 Lisp_Object QCfile, QCdata;
331 static Lisp_Object Qfontified;
332 static Lisp_Object Qgrow_only;
333 static Lisp_Object Qinhibit_eval_during_redisplay;
334 static Lisp_Object Qbuffer_position, Qposition, Qobject;
335 static Lisp_Object Qright_to_left, Qleft_to_right;
337 /* Cursor shapes. */
338 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
340 /* Pointer shapes. */
341 static Lisp_Object Qarrow, Qhand;
342 Lisp_Object Qtext;
344 /* Holds the list (error). */
345 static Lisp_Object list_of_error;
347 static Lisp_Object Qfontification_functions;
349 static Lisp_Object Qwrap_prefix;
350 static Lisp_Object Qline_prefix;
351 static Lisp_Object Qredisplay_internal;
353 /* Non-nil means don't actually do any redisplay. */
355 Lisp_Object Qinhibit_redisplay;
357 /* Names of text properties relevant for redisplay. */
359 Lisp_Object Qdisplay;
361 Lisp_Object Qspace, QCalign_to;
362 static Lisp_Object QCrelative_width, QCrelative_height;
363 Lisp_Object Qleft_margin, Qright_margin;
364 static Lisp_Object Qspace_width, Qraise;
365 static Lisp_Object Qslice;
366 Lisp_Object Qcenter;
367 static Lisp_Object Qmargin, Qpointer;
368 static Lisp_Object Qline_height;
370 #ifdef HAVE_WINDOW_SYSTEM
372 /* Test if overflow newline into fringe. Called with iterator IT
373 at or past right window margin, and with IT->current_x set. */
375 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(IT) \
376 (!NILP (Voverflow_newline_into_fringe) \
377 && FRAME_WINDOW_P ((IT)->f) \
378 && ((IT)->bidi_it.paragraph_dir == R2L \
379 ? (WINDOW_LEFT_FRINGE_WIDTH ((IT)->w) > 0) \
380 : (WINDOW_RIGHT_FRINGE_WIDTH ((IT)->w) > 0)) \
381 && (IT)->current_x == (IT)->last_visible_x \
382 && (IT)->line_wrap != WORD_WRAP)
384 #else /* !HAVE_WINDOW_SYSTEM */
385 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) 0
386 #endif /* HAVE_WINDOW_SYSTEM */
388 /* Test if the display element loaded in IT, or the underlying buffer
389 or string character, is a space or a TAB character. This is used
390 to determine where word wrapping can occur. */
392 #define IT_DISPLAYING_WHITESPACE(it) \
393 ((it->what == IT_CHARACTER && (it->c == ' ' || it->c == '\t')) \
394 || ((STRINGP (it->string) \
395 && (SREF (it->string, IT_STRING_BYTEPOS (*it)) == ' ' \
396 || SREF (it->string, IT_STRING_BYTEPOS (*it)) == '\t')) \
397 || (it->s \
398 && (it->s[IT_BYTEPOS (*it)] == ' ' \
399 || it->s[IT_BYTEPOS (*it)] == '\t')) \
400 || (IT_BYTEPOS (*it) < ZV_BYTE \
401 && (*BYTE_POS_ADDR (IT_BYTEPOS (*it)) == ' ' \
402 || *BYTE_POS_ADDR (IT_BYTEPOS (*it)) == '\t')))) \
404 /* Name of the face used to highlight trailing whitespace. */
406 static Lisp_Object Qtrailing_whitespace;
408 /* Name and number of the face used to highlight escape glyphs. */
410 static Lisp_Object Qescape_glyph;
412 /* Name and number of the face used to highlight non-breaking spaces. */
414 static Lisp_Object Qnobreak_space;
416 /* The symbol `image' which is the car of the lists used to represent
417 images in Lisp. Also a tool bar style. */
419 Lisp_Object Qimage;
421 /* The image map types. */
422 Lisp_Object QCmap;
423 static Lisp_Object QCpointer;
424 static Lisp_Object Qrect, Qcircle, Qpoly;
426 /* Tool bar styles */
427 Lisp_Object Qboth, Qboth_horiz, Qtext_image_horiz;
429 /* Non-zero means print newline to stdout before next mini-buffer
430 message. */
432 int noninteractive_need_newline;
434 /* Non-zero means print newline to message log before next message. */
436 static int message_log_need_newline;
438 /* Three markers that message_dolog uses.
439 It could allocate them itself, but that causes trouble
440 in handling memory-full errors. */
441 static Lisp_Object message_dolog_marker1;
442 static Lisp_Object message_dolog_marker2;
443 static Lisp_Object message_dolog_marker3;
445 /* The buffer position of the first character appearing entirely or
446 partially on the line of the selected window which contains the
447 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
448 redisplay optimization in redisplay_internal. */
450 static struct text_pos this_line_start_pos;
452 /* Number of characters past the end of the line above, including the
453 terminating newline. */
455 static struct text_pos this_line_end_pos;
457 /* The vertical positions and the height of this line. */
459 static int this_line_vpos;
460 static int this_line_y;
461 static int this_line_pixel_height;
463 /* X position at which this display line starts. Usually zero;
464 negative if first character is partially visible. */
466 static int this_line_start_x;
468 /* The smallest character position seen by move_it_* functions as they
469 move across display lines. Used to set MATRIX_ROW_START_CHARPOS of
470 hscrolled lines, see display_line. */
472 static struct text_pos this_line_min_pos;
474 /* Buffer that this_line_.* variables are referring to. */
476 static struct buffer *this_line_buffer;
479 /* Values of those variables at last redisplay are stored as
480 properties on `overlay-arrow-position' symbol. However, if
481 Voverlay_arrow_position is a marker, last-arrow-position is its
482 numerical position. */
484 static Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
486 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
487 properties on a symbol in overlay-arrow-variable-list. */
489 static Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
491 Lisp_Object Qmenu_bar_update_hook;
493 /* Nonzero if an overlay arrow has been displayed in this window. */
495 static int overlay_arrow_seen;
497 /* Vector containing glyphs for an ellipsis `...'. */
499 static Lisp_Object default_invis_vector[3];
501 /* This is the window where the echo area message was displayed. It
502 is always a mini-buffer window, but it may not be the same window
503 currently active as a mini-buffer. */
505 Lisp_Object echo_area_window;
507 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
508 pushes the current message and the value of
509 message_enable_multibyte on the stack, the function restore_message
510 pops the stack and displays MESSAGE again. */
512 static Lisp_Object Vmessage_stack;
514 /* Nonzero means multibyte characters were enabled when the echo area
515 message was specified. */
517 static int message_enable_multibyte;
519 /* Nonzero if we should redraw the mode lines on the next redisplay. */
521 int update_mode_lines;
523 /* Nonzero if window sizes or contents have changed since last
524 redisplay that finished. */
526 int windows_or_buffers_changed;
528 /* Nonzero means a frame's cursor type has been changed. */
530 int cursor_type_changed;
532 /* Nonzero after display_mode_line if %l was used and it displayed a
533 line number. */
535 static int line_number_displayed;
537 /* The name of the *Messages* buffer, a string. */
539 static Lisp_Object Vmessages_buffer_name;
541 /* Current, index 0, and last displayed echo area message. Either
542 buffers from echo_buffers, or nil to indicate no message. */
544 Lisp_Object echo_area_buffer[2];
546 /* The buffers referenced from echo_area_buffer. */
548 static Lisp_Object echo_buffer[2];
550 /* A vector saved used in with_area_buffer to reduce consing. */
552 static Lisp_Object Vwith_echo_area_save_vector;
554 /* Non-zero means display_echo_area should display the last echo area
555 message again. Set by redisplay_preserve_echo_area. */
557 static int display_last_displayed_message_p;
559 /* Nonzero if echo area is being used by print; zero if being used by
560 message. */
562 static int message_buf_print;
564 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
566 static Lisp_Object Qinhibit_menubar_update;
567 static Lisp_Object Qmessage_truncate_lines;
569 /* Set to 1 in clear_message to make redisplay_internal aware
570 of an emptied echo area. */
572 static int message_cleared_p;
574 /* A scratch glyph row with contents used for generating truncation
575 glyphs. Also used in direct_output_for_insert. */
577 #define MAX_SCRATCH_GLYPHS 100
578 static struct glyph_row scratch_glyph_row;
579 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
581 /* Ascent and height of the last line processed by move_it_to. */
583 static int last_height;
585 /* Non-zero if there's a help-echo in the echo area. */
587 int help_echo_showing_p;
589 /* If >= 0, computed, exact values of mode-line and header-line height
590 to use in the macros CURRENT_MODE_LINE_HEIGHT and
591 CURRENT_HEADER_LINE_HEIGHT. */
593 int current_mode_line_height, current_header_line_height;
595 /* The maximum distance to look ahead for text properties. Values
596 that are too small let us call compute_char_face and similar
597 functions too often which is expensive. Values that are too large
598 let us call compute_char_face and alike too often because we
599 might not be interested in text properties that far away. */
601 #define TEXT_PROP_DISTANCE_LIMIT 100
603 /* SAVE_IT and RESTORE_IT are called when we save a snapshot of the
604 iterator state and later restore it. This is needed because the
605 bidi iterator on bidi.c keeps a stacked cache of its states, which
606 is really a singleton. When we use scratch iterator objects to
607 move around the buffer, we can cause the bidi cache to be pushed or
608 popped, and therefore we need to restore the cache state when we
609 return to the original iterator. */
610 #define SAVE_IT(ITCOPY,ITORIG,CACHE) \
611 do { \
612 if (CACHE) \
613 bidi_unshelve_cache (CACHE, 1); \
614 ITCOPY = ITORIG; \
615 CACHE = bidi_shelve_cache (); \
616 } while (0)
618 #define RESTORE_IT(pITORIG,pITCOPY,CACHE) \
619 do { \
620 if (pITORIG != pITCOPY) \
621 *(pITORIG) = *(pITCOPY); \
622 bidi_unshelve_cache (CACHE, 0); \
623 CACHE = NULL; \
624 } while (0)
626 #ifdef GLYPH_DEBUG
628 /* Non-zero means print traces of redisplay if compiled with
629 GLYPH_DEBUG defined. */
631 int trace_redisplay_p;
633 #endif /* GLYPH_DEBUG */
635 #ifdef DEBUG_TRACE_MOVE
636 /* Non-zero means trace with TRACE_MOVE to stderr. */
637 int trace_move;
639 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
640 #else
641 #define TRACE_MOVE(x) (void) 0
642 #endif
644 static Lisp_Object Qauto_hscroll_mode;
646 /* Buffer being redisplayed -- for redisplay_window_error. */
648 static struct buffer *displayed_buffer;
650 /* Value returned from text property handlers (see below). */
652 enum prop_handled
654 HANDLED_NORMALLY,
655 HANDLED_RECOMPUTE_PROPS,
656 HANDLED_OVERLAY_STRING_CONSUMED,
657 HANDLED_RETURN
660 /* A description of text properties that redisplay is interested
661 in. */
663 struct props
665 /* The name of the property. */
666 Lisp_Object *name;
668 /* A unique index for the property. */
669 enum prop_idx idx;
671 /* A handler function called to set up iterator IT from the property
672 at IT's current position. Value is used to steer handle_stop. */
673 enum prop_handled (*handler) (struct it *it);
676 static enum prop_handled handle_face_prop (struct it *);
677 static enum prop_handled handle_invisible_prop (struct it *);
678 static enum prop_handled handle_display_prop (struct it *);
679 static enum prop_handled handle_composition_prop (struct it *);
680 static enum prop_handled handle_overlay_change (struct it *);
681 static enum prop_handled handle_fontified_prop (struct it *);
683 /* Properties handled by iterators. */
685 static struct props it_props[] =
687 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
688 /* Handle `face' before `display' because some sub-properties of
689 `display' need to know the face. */
690 {&Qface, FACE_PROP_IDX, handle_face_prop},
691 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
692 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
693 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
694 {NULL, 0, NULL}
697 /* Value is the position described by X. If X is a marker, value is
698 the marker_position of X. Otherwise, value is X. */
700 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
702 /* Enumeration returned by some move_it_.* functions internally. */
704 enum move_it_result
706 /* Not used. Undefined value. */
707 MOVE_UNDEFINED,
709 /* Move ended at the requested buffer position or ZV. */
710 MOVE_POS_MATCH_OR_ZV,
712 /* Move ended at the requested X pixel position. */
713 MOVE_X_REACHED,
715 /* Move within a line ended at the end of a line that must be
716 continued. */
717 MOVE_LINE_CONTINUED,
719 /* Move within a line ended at the end of a line that would
720 be displayed truncated. */
721 MOVE_LINE_TRUNCATED,
723 /* Move within a line ended at a line end. */
724 MOVE_NEWLINE_OR_CR
727 /* This counter is used to clear the face cache every once in a while
728 in redisplay_internal. It is incremented for each redisplay.
729 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
730 cleared. */
732 #define CLEAR_FACE_CACHE_COUNT 500
733 static int clear_face_cache_count;
735 /* Similarly for the image cache. */
737 #ifdef HAVE_WINDOW_SYSTEM
738 #define CLEAR_IMAGE_CACHE_COUNT 101
739 static int clear_image_cache_count;
741 /* Null glyph slice */
742 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
743 #endif
745 /* True while redisplay_internal is in progress. */
747 bool redisplaying_p;
749 static Lisp_Object Qinhibit_free_realized_faces;
750 static Lisp_Object Qmode_line_default_help_echo;
752 /* If a string, XTread_socket generates an event to display that string.
753 (The display is done in read_char.) */
755 Lisp_Object help_echo_string;
756 Lisp_Object help_echo_window;
757 Lisp_Object help_echo_object;
758 ptrdiff_t help_echo_pos;
760 /* Temporary variable for XTread_socket. */
762 Lisp_Object previous_help_echo_string;
764 /* Platform-independent portion of hourglass implementation. */
766 /* Non-zero means an hourglass cursor is currently shown. */
767 int hourglass_shown_p;
769 /* If non-null, an asynchronous timer that, when it expires, displays
770 an hourglass cursor on all frames. */
771 struct atimer *hourglass_atimer;
773 /* Name of the face used to display glyphless characters. */
774 Lisp_Object Qglyphless_char;
776 /* Symbol for the purpose of Vglyphless_char_display. */
777 static Lisp_Object Qglyphless_char_display;
779 /* Method symbols for Vglyphless_char_display. */
780 static Lisp_Object Qhex_code, Qempty_box, Qthin_space, Qzero_width;
782 /* Default pixel width of `thin-space' display method. */
783 #define THIN_SPACE_WIDTH 1
785 /* Default number of seconds to wait before displaying an hourglass
786 cursor. */
787 #define DEFAULT_HOURGLASS_DELAY 1
790 /* Function prototypes. */
792 static void setup_for_ellipsis (struct it *, int);
793 static void set_iterator_to_next (struct it *, int);
794 static void mark_window_display_accurate_1 (struct window *, int);
795 static int single_display_spec_string_p (Lisp_Object, Lisp_Object);
796 static int display_prop_string_p (Lisp_Object, Lisp_Object);
797 static int row_for_charpos_p (struct glyph_row *, ptrdiff_t);
798 static int cursor_row_p (struct glyph_row *);
799 static int redisplay_mode_lines (Lisp_Object, int);
800 static char *decode_mode_spec_coding (Lisp_Object, char *, int);
802 static Lisp_Object get_it_property (struct it *it, Lisp_Object prop);
804 static void handle_line_prefix (struct it *);
806 static void pint2str (char *, int, ptrdiff_t);
807 static void pint2hrstr (char *, int, ptrdiff_t);
808 static struct text_pos run_window_scroll_functions (Lisp_Object,
809 struct text_pos);
810 static void reconsider_clip_changes (struct window *, struct buffer *);
811 static int text_outside_line_unchanged_p (struct window *,
812 ptrdiff_t, ptrdiff_t);
813 static void store_mode_line_noprop_char (char);
814 static int store_mode_line_noprop (const char *, int, int);
815 static void handle_stop (struct it *);
816 static void handle_stop_backwards (struct it *, ptrdiff_t);
817 static void vmessage (const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (1, 0);
818 static void ensure_echo_area_buffers (void);
819 static Lisp_Object unwind_with_echo_area_buffer (Lisp_Object);
820 static Lisp_Object with_echo_area_buffer_unwind_data (struct window *);
821 static int with_echo_area_buffer (struct window *, int,
822 int (*) (ptrdiff_t, Lisp_Object),
823 ptrdiff_t, Lisp_Object);
824 static void clear_garbaged_frames (void);
825 static int current_message_1 (ptrdiff_t, Lisp_Object);
826 static void pop_message (void);
827 static int truncate_message_1 (ptrdiff_t, Lisp_Object);
828 static void set_message (Lisp_Object);
829 static int set_message_1 (ptrdiff_t, Lisp_Object);
830 static int display_echo_area (struct window *);
831 static int display_echo_area_1 (ptrdiff_t, Lisp_Object);
832 static int resize_mini_window_1 (ptrdiff_t, Lisp_Object);
833 static Lisp_Object unwind_redisplay (Lisp_Object);
834 static int string_char_and_length (const unsigned char *, int *);
835 static struct text_pos display_prop_end (struct it *, Lisp_Object,
836 struct text_pos);
837 static int compute_window_start_on_continuation_line (struct window *);
838 static void insert_left_trunc_glyphs (struct it *);
839 static struct glyph_row *get_overlay_arrow_glyph_row (struct window *,
840 Lisp_Object);
841 static void extend_face_to_end_of_line (struct it *);
842 static int append_space_for_newline (struct it *, int);
843 static int cursor_row_fully_visible_p (struct window *, int, int);
844 static int try_scrolling (Lisp_Object, int, ptrdiff_t, ptrdiff_t, int, int);
845 static int try_cursor_movement (Lisp_Object, struct text_pos, int *);
846 static int trailing_whitespace_p (ptrdiff_t);
847 static intmax_t message_log_check_duplicate (ptrdiff_t, ptrdiff_t);
848 static void push_it (struct it *, struct text_pos *);
849 static void iterate_out_of_display_property (struct it *);
850 static void pop_it (struct it *);
851 static void sync_frame_with_window_matrix_rows (struct window *);
852 static void redisplay_internal (void);
853 static int echo_area_display (int);
854 static void redisplay_windows (Lisp_Object);
855 static void redisplay_window (Lisp_Object, int);
856 static Lisp_Object redisplay_window_error (Lisp_Object);
857 static Lisp_Object redisplay_window_0 (Lisp_Object);
858 static Lisp_Object redisplay_window_1 (Lisp_Object);
859 static int set_cursor_from_row (struct window *, struct glyph_row *,
860 struct glyph_matrix *, ptrdiff_t, ptrdiff_t,
861 int, int);
862 static int update_menu_bar (struct frame *, int, int);
863 static int try_window_reusing_current_matrix (struct window *);
864 static int try_window_id (struct window *);
865 static int display_line (struct it *);
866 static int display_mode_lines (struct window *);
867 static int display_mode_line (struct window *, enum face_id, Lisp_Object);
868 static int display_mode_element (struct it *, int, int, int, Lisp_Object, Lisp_Object, int);
869 static int store_mode_line_string (const char *, Lisp_Object, int, int, int, Lisp_Object);
870 static const char *decode_mode_spec (struct window *, int, int, Lisp_Object *);
871 static void display_menu_bar (struct window *);
872 static ptrdiff_t display_count_lines (ptrdiff_t, ptrdiff_t, ptrdiff_t,
873 ptrdiff_t *);
874 static int display_string (const char *, Lisp_Object, Lisp_Object,
875 ptrdiff_t, ptrdiff_t, struct it *, int, int, int, int);
876 static void compute_line_metrics (struct it *);
877 static void run_redisplay_end_trigger_hook (struct it *);
878 static int get_overlay_strings (struct it *, ptrdiff_t);
879 static int get_overlay_strings_1 (struct it *, ptrdiff_t, int);
880 static void next_overlay_string (struct it *);
881 static void reseat (struct it *, struct text_pos, int);
882 static void reseat_1 (struct it *, struct text_pos, int);
883 static void back_to_previous_visible_line_start (struct it *);
884 static void reseat_at_next_visible_line_start (struct it *, int);
885 static int next_element_from_ellipsis (struct it *);
886 static int next_element_from_display_vector (struct it *);
887 static int next_element_from_string (struct it *);
888 static int next_element_from_c_string (struct it *);
889 static int next_element_from_buffer (struct it *);
890 static int next_element_from_composition (struct it *);
891 static int next_element_from_image (struct it *);
892 static int next_element_from_stretch (struct it *);
893 static void load_overlay_strings (struct it *, ptrdiff_t);
894 static int init_from_display_pos (struct it *, struct window *,
895 struct display_pos *);
896 static void reseat_to_string (struct it *, const char *,
897 Lisp_Object, ptrdiff_t, ptrdiff_t, int, int);
898 static int get_next_display_element (struct it *);
899 static enum move_it_result
900 move_it_in_display_line_to (struct it *, ptrdiff_t, int,
901 enum move_operation_enum);
902 static void get_visually_first_element (struct it *);
903 static void init_to_row_start (struct it *, struct window *,
904 struct glyph_row *);
905 static int init_to_row_end (struct it *, struct window *,
906 struct glyph_row *);
907 static void back_to_previous_line_start (struct it *);
908 static int forward_to_next_line_start (struct it *, int *, struct bidi_it *);
909 static struct text_pos string_pos_nchars_ahead (struct text_pos,
910 Lisp_Object, ptrdiff_t);
911 static struct text_pos string_pos (ptrdiff_t, Lisp_Object);
912 static struct text_pos c_string_pos (ptrdiff_t, const char *, bool);
913 static ptrdiff_t number_of_chars (const char *, bool);
914 static void compute_stop_pos (struct it *);
915 static void compute_string_pos (struct text_pos *, struct text_pos,
916 Lisp_Object);
917 static int face_before_or_after_it_pos (struct it *, int);
918 static ptrdiff_t next_overlay_change (ptrdiff_t);
919 static int handle_display_spec (struct it *, Lisp_Object, Lisp_Object,
920 Lisp_Object, struct text_pos *, ptrdiff_t, int);
921 static int handle_single_display_spec (struct it *, Lisp_Object,
922 Lisp_Object, Lisp_Object,
923 struct text_pos *, ptrdiff_t, int, int);
924 static int underlying_face_id (struct it *);
925 static int in_ellipses_for_invisible_text_p (struct display_pos *,
926 struct window *);
928 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
929 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
931 #ifdef HAVE_WINDOW_SYSTEM
933 static void x_consider_frame_title (Lisp_Object);
934 static int tool_bar_lines_needed (struct frame *, int *);
935 static void update_tool_bar (struct frame *, int);
936 static void build_desired_tool_bar_string (struct frame *f);
937 static int redisplay_tool_bar (struct frame *);
938 static void display_tool_bar_line (struct it *, int);
939 static void notice_overwritten_cursor (struct window *,
940 enum glyph_row_area,
941 int, int, int, int);
942 static void append_stretch_glyph (struct it *, Lisp_Object,
943 int, int, int);
946 #endif /* HAVE_WINDOW_SYSTEM */
948 static void produce_special_glyphs (struct it *, enum display_element_type);
949 static void show_mouse_face (Mouse_HLInfo *, enum draw_glyphs_face);
950 static int coords_in_mouse_face_p (struct window *, int, int);
954 /***********************************************************************
955 Window display dimensions
956 ***********************************************************************/
958 /* Return the bottom boundary y-position for text lines in window W.
959 This is the first y position at which a line cannot start.
960 It is relative to the top of the window.
962 This is the height of W minus the height of a mode line, if any. */
965 window_text_bottom_y (struct window *w)
967 int height = WINDOW_TOTAL_HEIGHT (w);
969 if (WINDOW_WANTS_MODELINE_P (w))
970 height -= CURRENT_MODE_LINE_HEIGHT (w);
971 return height;
974 /* Return the pixel width of display area AREA of window W. AREA < 0
975 means return the total width of W, not including fringes to
976 the left and right of the window. */
979 window_box_width (struct window *w, int area)
981 int cols = w->total_cols;
982 int pixels = 0;
984 if (!w->pseudo_window_p)
986 cols -= WINDOW_SCROLL_BAR_COLS (w);
988 if (area == TEXT_AREA)
990 if (INTEGERP (w->left_margin_cols))
991 cols -= XFASTINT (w->left_margin_cols);
992 if (INTEGERP (w->right_margin_cols))
993 cols -= XFASTINT (w->right_margin_cols);
994 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
996 else if (area == LEFT_MARGIN_AREA)
998 cols = (INTEGERP (w->left_margin_cols)
999 ? XFASTINT (w->left_margin_cols) : 0);
1000 pixels = 0;
1002 else if (area == RIGHT_MARGIN_AREA)
1004 cols = (INTEGERP (w->right_margin_cols)
1005 ? XFASTINT (w->right_margin_cols) : 0);
1006 pixels = 0;
1010 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1014 /* Return the pixel height of the display area of window W, not
1015 including mode lines of W, if any. */
1018 window_box_height (struct window *w)
1020 struct frame *f = XFRAME (w->frame);
1021 int height = WINDOW_TOTAL_HEIGHT (w);
1023 eassert (height >= 0);
1025 /* Note: the code below that determines the mode-line/header-line
1026 height is essentially the same as that contained in the macro
1027 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1028 the appropriate glyph row has its `mode_line_p' flag set,
1029 and if it doesn't, uses estimate_mode_line_height instead. */
1031 if (WINDOW_WANTS_MODELINE_P (w))
1033 struct glyph_row *ml_row
1034 = (w->current_matrix && w->current_matrix->rows
1035 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1036 : 0);
1037 if (ml_row && ml_row->mode_line_p)
1038 height -= ml_row->height;
1039 else
1040 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1043 if (WINDOW_WANTS_HEADER_LINE_P (w))
1045 struct glyph_row *hl_row
1046 = (w->current_matrix && w->current_matrix->rows
1047 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1048 : 0);
1049 if (hl_row && hl_row->mode_line_p)
1050 height -= hl_row->height;
1051 else
1052 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1055 /* With a very small font and a mode-line that's taller than
1056 default, we might end up with a negative height. */
1057 return max (0, height);
1060 /* Return the window-relative coordinate of the left edge of display
1061 area AREA of window W. AREA < 0 means return the left edge of the
1062 whole window, to the right of the left fringe of W. */
1065 window_box_left_offset (struct window *w, int area)
1067 int x;
1069 if (w->pseudo_window_p)
1070 return 0;
1072 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1074 if (area == TEXT_AREA)
1075 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1076 + window_box_width (w, LEFT_MARGIN_AREA));
1077 else if (area == RIGHT_MARGIN_AREA)
1078 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1079 + window_box_width (w, LEFT_MARGIN_AREA)
1080 + window_box_width (w, TEXT_AREA)
1081 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1083 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1084 else if (area == LEFT_MARGIN_AREA
1085 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1086 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1088 return x;
1092 /* Return the window-relative coordinate of the right edge of display
1093 area AREA of window W. AREA < 0 means return the right edge of the
1094 whole window, to the left of the right fringe of W. */
1097 window_box_right_offset (struct window *w, int area)
1099 return window_box_left_offset (w, area) + window_box_width (w, area);
1102 /* Return the frame-relative coordinate of the left edge of display
1103 area AREA of window W. AREA < 0 means return the left edge of the
1104 whole window, to the right of the left fringe of W. */
1107 window_box_left (struct window *w, int area)
1109 struct frame *f = XFRAME (w->frame);
1110 int x;
1112 if (w->pseudo_window_p)
1113 return FRAME_INTERNAL_BORDER_WIDTH (f);
1115 x = (WINDOW_LEFT_EDGE_X (w)
1116 + window_box_left_offset (w, area));
1118 return x;
1122 /* Return the frame-relative coordinate of the right edge of display
1123 area AREA of window W. AREA < 0 means return the right edge of the
1124 whole window, to the left of the right fringe of W. */
1127 window_box_right (struct window *w, int area)
1129 return window_box_left (w, area) + window_box_width (w, area);
1132 /* Get the bounding box of the display area AREA of window W, without
1133 mode lines, in frame-relative coordinates. AREA < 0 means the
1134 whole window, not including the left and right fringes of
1135 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1136 coordinates of the upper-left corner of the box. Return in
1137 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1139 void
1140 window_box (struct window *w, int area, int *box_x, int *box_y,
1141 int *box_width, int *box_height)
1143 if (box_width)
1144 *box_width = window_box_width (w, area);
1145 if (box_height)
1146 *box_height = window_box_height (w);
1147 if (box_x)
1148 *box_x = window_box_left (w, area);
1149 if (box_y)
1151 *box_y = WINDOW_TOP_EDGE_Y (w);
1152 if (WINDOW_WANTS_HEADER_LINE_P (w))
1153 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1158 /* Get the bounding box of the display area AREA of window W, without
1159 mode lines. AREA < 0 means the whole window, not including the
1160 left and right fringe of the window. Return in *TOP_LEFT_X
1161 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1162 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1163 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1164 box. */
1166 static void
1167 window_box_edges (struct window *w, int area, int *top_left_x, int *top_left_y,
1168 int *bottom_right_x, int *bottom_right_y)
1170 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1171 bottom_right_y);
1172 *bottom_right_x += *top_left_x;
1173 *bottom_right_y += *top_left_y;
1178 /***********************************************************************
1179 Utilities
1180 ***********************************************************************/
1182 /* Return the bottom y-position of the line the iterator IT is in.
1183 This can modify IT's settings. */
1186 line_bottom_y (struct it *it)
1188 int line_height = it->max_ascent + it->max_descent;
1189 int line_top_y = it->current_y;
1191 if (line_height == 0)
1193 if (last_height)
1194 line_height = last_height;
1195 else if (IT_CHARPOS (*it) < ZV)
1197 move_it_by_lines (it, 1);
1198 line_height = (it->max_ascent || it->max_descent
1199 ? it->max_ascent + it->max_descent
1200 : last_height);
1202 else
1204 struct glyph_row *row = it->glyph_row;
1206 /* Use the default character height. */
1207 it->glyph_row = NULL;
1208 it->what = IT_CHARACTER;
1209 it->c = ' ';
1210 it->len = 1;
1211 PRODUCE_GLYPHS (it);
1212 line_height = it->ascent + it->descent;
1213 it->glyph_row = row;
1217 return line_top_y + line_height;
1220 DEFUN ("line-pixel-height", Fline_pixel_height,
1221 Sline_pixel_height, 0, 0, 0,
1222 doc: /* Return height in pixels of text line in the selected window.
1224 Value is the height in pixels of the line at point. */)
1225 (void)
1227 struct it it;
1228 struct text_pos pt;
1229 struct window *w = XWINDOW (selected_window);
1231 SET_TEXT_POS (pt, PT, PT_BYTE);
1232 start_display (&it, w, pt);
1233 it.vpos = it.current_y = 0;
1234 last_height = 0;
1235 return make_number (line_bottom_y (&it));
1238 /* Subroutine of pos_visible_p below. Extracts a display string, if
1239 any, from the display spec given as its argument. */
1240 static Lisp_Object
1241 string_from_display_spec (Lisp_Object spec)
1243 if (CONSP (spec))
1245 while (CONSP (spec))
1247 if (STRINGP (XCAR (spec)))
1248 return XCAR (spec);
1249 spec = XCDR (spec);
1252 else if (VECTORP (spec))
1254 ptrdiff_t i;
1256 for (i = 0; i < ASIZE (spec); i++)
1258 if (STRINGP (AREF (spec, i)))
1259 return AREF (spec, i);
1261 return Qnil;
1264 return spec;
1268 /* Limit insanely large values of W->hscroll on frame F to the largest
1269 value that will still prevent first_visible_x and last_visible_x of
1270 'struct it' from overflowing an int. */
1271 static int
1272 window_hscroll_limited (struct window *w, struct frame *f)
1274 ptrdiff_t window_hscroll = w->hscroll;
1275 int window_text_width = window_box_width (w, TEXT_AREA);
1276 int colwidth = FRAME_COLUMN_WIDTH (f);
1278 if (window_hscroll > (INT_MAX - window_text_width) / colwidth - 1)
1279 window_hscroll = (INT_MAX - window_text_width) / colwidth - 1;
1281 return window_hscroll;
1284 /* Return 1 if position CHARPOS is visible in window W.
1285 CHARPOS < 0 means return info about WINDOW_END position.
1286 If visible, set *X and *Y to pixel coordinates of top left corner.
1287 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1288 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1291 pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
1292 int *rtop, int *rbot, int *rowh, int *vpos)
1294 struct it it;
1295 void *itdata = bidi_shelve_cache ();
1296 struct text_pos top;
1297 int visible_p = 0;
1298 struct buffer *old_buffer = NULL;
1300 if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w))))
1301 return visible_p;
1303 if (XBUFFER (w->contents) != current_buffer)
1305 old_buffer = current_buffer;
1306 set_buffer_internal_1 (XBUFFER (w->contents));
1309 SET_TEXT_POS_FROM_MARKER (top, w->start);
1310 /* Scrolling a minibuffer window via scroll bar when the echo area
1311 shows long text sometimes resets the minibuffer contents behind
1312 our backs. */
1313 if (CHARPOS (top) > ZV)
1314 SET_TEXT_POS (top, BEGV, BEGV_BYTE);
1316 /* Compute exact mode line heights. */
1317 if (WINDOW_WANTS_MODELINE_P (w))
1318 current_mode_line_height
1319 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1320 BVAR (current_buffer, mode_line_format));
1322 if (WINDOW_WANTS_HEADER_LINE_P (w))
1323 current_header_line_height
1324 = display_mode_line (w, HEADER_LINE_FACE_ID,
1325 BVAR (current_buffer, header_line_format));
1327 start_display (&it, w, top);
1328 move_it_to (&it, charpos, -1, it.last_visible_y - 1, -1,
1329 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
1331 if (charpos >= 0
1332 && (((!it.bidi_p || it.bidi_it.scan_dir == 1)
1333 && IT_CHARPOS (it) >= charpos)
1334 /* When scanning backwards under bidi iteration, move_it_to
1335 stops at or _before_ CHARPOS, because it stops at or to
1336 the _right_ of the character at CHARPOS. */
1337 || (it.bidi_p && it.bidi_it.scan_dir == -1
1338 && IT_CHARPOS (it) <= charpos)))
1340 /* We have reached CHARPOS, or passed it. How the call to
1341 move_it_to can overshoot: (i) If CHARPOS is on invisible text
1342 or covered by a display property, move_it_to stops at the end
1343 of the invisible text, to the right of CHARPOS. (ii) If
1344 CHARPOS is in a display vector, move_it_to stops on its last
1345 glyph. */
1346 int top_x = it.current_x;
1347 int top_y = it.current_y;
1348 /* Calling line_bottom_y may change it.method, it.position, etc. */
1349 enum it_method it_method = it.method;
1350 int bottom_y = (last_height = 0, line_bottom_y (&it));
1351 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1353 if (top_y < window_top_y)
1354 visible_p = bottom_y > window_top_y;
1355 else if (top_y < it.last_visible_y)
1356 visible_p = 1;
1357 if (bottom_y >= it.last_visible_y
1358 && it.bidi_p && it.bidi_it.scan_dir == -1
1359 && IT_CHARPOS (it) < charpos)
1361 /* When the last line of the window is scanned backwards
1362 under bidi iteration, we could be duped into thinking
1363 that we have passed CHARPOS, when in fact move_it_to
1364 simply stopped short of CHARPOS because it reached
1365 last_visible_y. To see if that's what happened, we call
1366 move_it_to again with a slightly larger vertical limit,
1367 and see if it actually moved vertically; if it did, we
1368 didn't really reach CHARPOS, which is beyond window end. */
1369 struct it save_it = it;
1370 /* Why 10? because we don't know how many canonical lines
1371 will the height of the next line(s) be. So we guess. */
1372 int ten_more_lines =
1373 10 * FRAME_LINE_HEIGHT (XFRAME (WINDOW_FRAME (w)));
1375 move_it_to (&it, charpos, -1, bottom_y + ten_more_lines, -1,
1376 MOVE_TO_POS | MOVE_TO_Y);
1377 if (it.current_y > top_y)
1378 visible_p = 0;
1380 it = save_it;
1382 if (visible_p)
1384 if (it_method == GET_FROM_DISPLAY_VECTOR)
1386 /* We stopped on the last glyph of a display vector.
1387 Try and recompute. Hack alert! */
1388 if (charpos < 2 || top.charpos >= charpos)
1389 top_x = it.glyph_row->x;
1390 else
1392 struct it it2, it2_prev;
1393 /* The idea is to get to the previous buffer
1394 position, consume the character there, and use
1395 the pixel coordinates we get after that. But if
1396 the previous buffer position is also displayed
1397 from a display vector, we need to consume all of
1398 the glyphs from that display vector. */
1399 start_display (&it2, w, top);
1400 move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS);
1401 /* If we didn't get to CHARPOS - 1, there's some
1402 replacing display property at that position, and
1403 we stopped after it. That is exactly the place
1404 whose coordinates we want. */
1405 if (IT_CHARPOS (it2) != charpos - 1)
1406 it2_prev = it2;
1407 else
1409 /* Iterate until we get out of the display
1410 vector that displays the character at
1411 CHARPOS - 1. */
1412 do {
1413 get_next_display_element (&it2);
1414 PRODUCE_GLYPHS (&it2);
1415 it2_prev = it2;
1416 set_iterator_to_next (&it2, 1);
1417 } while (it2.method == GET_FROM_DISPLAY_VECTOR
1418 && IT_CHARPOS (it2) < charpos);
1420 if (ITERATOR_AT_END_OF_LINE_P (&it2_prev)
1421 || it2_prev.current_x > it2_prev.last_visible_x)
1422 top_x = it.glyph_row->x;
1423 else
1425 top_x = it2_prev.current_x;
1426 top_y = it2_prev.current_y;
1430 else if (IT_CHARPOS (it) != charpos)
1432 Lisp_Object cpos = make_number (charpos);
1433 Lisp_Object spec = Fget_char_property (cpos, Qdisplay, Qnil);
1434 Lisp_Object string = string_from_display_spec (spec);
1435 struct text_pos tpos;
1436 int replacing_spec_p;
1437 bool newline_in_string
1438 = (STRINGP (string)
1439 && memchr (SDATA (string), '\n', SBYTES (string)));
1441 SET_TEXT_POS (tpos, charpos, CHAR_TO_BYTE (charpos));
1442 replacing_spec_p
1443 = (!NILP (spec)
1444 && handle_display_spec (NULL, spec, Qnil, Qnil, &tpos,
1445 charpos, FRAME_WINDOW_P (it.f)));
1446 /* The tricky code below is needed because there's a
1447 discrepancy between move_it_to and how we set cursor
1448 when PT is at the beginning of a portion of text
1449 covered by a display property or an overlay with a
1450 display property, or the display line ends in a
1451 newline from a display string. move_it_to will stop
1452 _after_ such display strings, whereas
1453 set_cursor_from_row conspires with cursor_row_p to
1454 place the cursor on the first glyph produced from the
1455 display string. */
1457 /* We have overshoot PT because it is covered by a
1458 display property that replaces the text it covers.
1459 If the string includes embedded newlines, we are also
1460 in the wrong display line. Backtrack to the correct
1461 line, where the display property begins. */
1462 if (replacing_spec_p)
1464 Lisp_Object startpos, endpos;
1465 EMACS_INT start, end;
1466 struct it it3;
1467 int it3_moved;
1469 /* Find the first and the last buffer positions
1470 covered by the display string. */
1471 endpos =
1472 Fnext_single_char_property_change (cpos, Qdisplay,
1473 Qnil, Qnil);
1474 startpos =
1475 Fprevious_single_char_property_change (endpos, Qdisplay,
1476 Qnil, Qnil);
1477 start = XFASTINT (startpos);
1478 end = XFASTINT (endpos);
1479 /* Move to the last buffer position before the
1480 display property. */
1481 start_display (&it3, w, top);
1482 move_it_to (&it3, start - 1, -1, -1, -1, MOVE_TO_POS);
1483 /* Move forward one more line if the position before
1484 the display string is a newline or if it is the
1485 rightmost character on a line that is
1486 continued or word-wrapped. */
1487 if (it3.method == GET_FROM_BUFFER
1488 && (it3.c == '\n'
1489 || FETCH_BYTE (IT_BYTEPOS (it3)) == '\n'))
1490 move_it_by_lines (&it3, 1);
1491 else if (move_it_in_display_line_to (&it3, -1,
1492 it3.current_x
1493 + it3.pixel_width,
1494 MOVE_TO_X)
1495 == MOVE_LINE_CONTINUED)
1497 move_it_by_lines (&it3, 1);
1498 /* When we are under word-wrap, the #$@%!
1499 move_it_by_lines moves 2 lines, so we need to
1500 fix that up. */
1501 if (it3.line_wrap == WORD_WRAP)
1502 move_it_by_lines (&it3, -1);
1505 /* Record the vertical coordinate of the display
1506 line where we wound up. */
1507 top_y = it3.current_y;
1508 if (it3.bidi_p)
1510 /* When characters are reordered for display,
1511 the character displayed to the left of the
1512 display string could be _after_ the display
1513 property in the logical order. Use the
1514 smallest vertical position of these two. */
1515 start_display (&it3, w, top);
1516 move_it_to (&it3, end + 1, -1, -1, -1, MOVE_TO_POS);
1517 if (it3.current_y < top_y)
1518 top_y = it3.current_y;
1520 /* Move from the top of the window to the beginning
1521 of the display line where the display string
1522 begins. */
1523 start_display (&it3, w, top);
1524 move_it_to (&it3, -1, 0, top_y, -1, MOVE_TO_X | MOVE_TO_Y);
1525 /* If it3_moved stays zero after the 'while' loop
1526 below, that means we already were at a newline
1527 before the loop (e.g., the display string begins
1528 with a newline), so we don't need to (and cannot)
1529 inspect the glyphs of it3.glyph_row, because
1530 PRODUCE_GLYPHS will not produce anything for a
1531 newline, and thus it3.glyph_row stays at its
1532 stale content it got at top of the window. */
1533 it3_moved = 0;
1534 /* Finally, advance the iterator until we hit the
1535 first display element whose character position is
1536 CHARPOS, or until the first newline from the
1537 display string, which signals the end of the
1538 display line. */
1539 while (get_next_display_element (&it3))
1541 PRODUCE_GLYPHS (&it3);
1542 if (IT_CHARPOS (it3) == charpos
1543 || ITERATOR_AT_END_OF_LINE_P (&it3))
1544 break;
1545 it3_moved = 1;
1546 set_iterator_to_next (&it3, 0);
1548 top_x = it3.current_x - it3.pixel_width;
1549 /* Normally, we would exit the above loop because we
1550 found the display element whose character
1551 position is CHARPOS. For the contingency that we
1552 didn't, and stopped at the first newline from the
1553 display string, move back over the glyphs
1554 produced from the string, until we find the
1555 rightmost glyph not from the string. */
1556 if (it3_moved
1557 && newline_in_string
1558 && IT_CHARPOS (it3) != charpos && EQ (it3.object, string))
1560 struct glyph *g = it3.glyph_row->glyphs[TEXT_AREA]
1561 + it3.glyph_row->used[TEXT_AREA];
1563 while (EQ ((g - 1)->object, string))
1565 --g;
1566 top_x -= g->pixel_width;
1568 eassert (g < it3.glyph_row->glyphs[TEXT_AREA]
1569 + it3.glyph_row->used[TEXT_AREA]);
1574 *x = top_x;
1575 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1576 *rtop = max (0, window_top_y - top_y);
1577 *rbot = max (0, bottom_y - it.last_visible_y);
1578 *rowh = max (0, (min (bottom_y, it.last_visible_y)
1579 - max (top_y, window_top_y)));
1580 *vpos = it.vpos;
1583 else
1585 /* We were asked to provide info about WINDOW_END. */
1586 struct it it2;
1587 void *it2data = NULL;
1589 SAVE_IT (it2, it, it2data);
1590 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1591 move_it_by_lines (&it, 1);
1592 if (charpos < IT_CHARPOS (it)
1593 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1595 visible_p = 1;
1596 RESTORE_IT (&it2, &it2, it2data);
1597 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1598 *x = it2.current_x;
1599 *y = it2.current_y + it2.max_ascent - it2.ascent;
1600 *rtop = max (0, -it2.current_y);
1601 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1602 - it.last_visible_y));
1603 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
1604 it.last_visible_y)
1605 - max (it2.current_y,
1606 WINDOW_HEADER_LINE_HEIGHT (w))));
1607 *vpos = it2.vpos;
1609 else
1610 bidi_unshelve_cache (it2data, 1);
1612 bidi_unshelve_cache (itdata, 0);
1614 if (old_buffer)
1615 set_buffer_internal_1 (old_buffer);
1617 current_header_line_height = current_mode_line_height = -1;
1619 if (visible_p && w->hscroll > 0)
1620 *x -=
1621 window_hscroll_limited (w, WINDOW_XFRAME (w))
1622 * WINDOW_FRAME_COLUMN_WIDTH (w);
1624 #if 0
1625 /* Debugging code. */
1626 if (visible_p)
1627 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1628 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
1629 else
1630 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
1631 #endif
1633 return visible_p;
1637 /* Return the next character from STR. Return in *LEN the length of
1638 the character. This is like STRING_CHAR_AND_LENGTH but never
1639 returns an invalid character. If we find one, we return a `?', but
1640 with the length of the invalid character. */
1642 static int
1643 string_char_and_length (const unsigned char *str, int *len)
1645 int c;
1647 c = STRING_CHAR_AND_LENGTH (str, *len);
1648 if (!CHAR_VALID_P (c))
1649 /* We may not change the length here because other places in Emacs
1650 don't use this function, i.e. they silently accept invalid
1651 characters. */
1652 c = '?';
1654 return c;
1659 /* Given a position POS containing a valid character and byte position
1660 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1662 static struct text_pos
1663 string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, ptrdiff_t nchars)
1665 eassert (STRINGP (string) && nchars >= 0);
1667 if (STRING_MULTIBYTE (string))
1669 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1670 int len;
1672 while (nchars--)
1674 string_char_and_length (p, &len);
1675 p += len;
1676 CHARPOS (pos) += 1;
1677 BYTEPOS (pos) += len;
1680 else
1681 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1683 return pos;
1687 /* Value is the text position, i.e. character and byte position,
1688 for character position CHARPOS in STRING. */
1690 static struct text_pos
1691 string_pos (ptrdiff_t charpos, Lisp_Object string)
1693 struct text_pos pos;
1694 eassert (STRINGP (string));
1695 eassert (charpos >= 0);
1696 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1697 return pos;
1701 /* Value is a text position, i.e. character and byte position, for
1702 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1703 means recognize multibyte characters. */
1705 static struct text_pos
1706 c_string_pos (ptrdiff_t charpos, const char *s, bool multibyte_p)
1708 struct text_pos pos;
1710 eassert (s != NULL);
1711 eassert (charpos >= 0);
1713 if (multibyte_p)
1715 int len;
1717 SET_TEXT_POS (pos, 0, 0);
1718 while (charpos--)
1720 string_char_and_length ((const unsigned char *) s, &len);
1721 s += len;
1722 CHARPOS (pos) += 1;
1723 BYTEPOS (pos) += len;
1726 else
1727 SET_TEXT_POS (pos, charpos, charpos);
1729 return pos;
1733 /* Value is the number of characters in C string S. MULTIBYTE_P
1734 non-zero means recognize multibyte characters. */
1736 static ptrdiff_t
1737 number_of_chars (const char *s, bool multibyte_p)
1739 ptrdiff_t nchars;
1741 if (multibyte_p)
1743 ptrdiff_t rest = strlen (s);
1744 int len;
1745 const unsigned char *p = (const unsigned char *) s;
1747 for (nchars = 0; rest > 0; ++nchars)
1749 string_char_and_length (p, &len);
1750 rest -= len, p += len;
1753 else
1754 nchars = strlen (s);
1756 return nchars;
1760 /* Compute byte position NEWPOS->bytepos corresponding to
1761 NEWPOS->charpos. POS is a known position in string STRING.
1762 NEWPOS->charpos must be >= POS.charpos. */
1764 static void
1765 compute_string_pos (struct text_pos *newpos, struct text_pos pos, Lisp_Object string)
1767 eassert (STRINGP (string));
1768 eassert (CHARPOS (*newpos) >= CHARPOS (pos));
1770 if (STRING_MULTIBYTE (string))
1771 *newpos = string_pos_nchars_ahead (pos, string,
1772 CHARPOS (*newpos) - CHARPOS (pos));
1773 else
1774 BYTEPOS (*newpos) = CHARPOS (*newpos);
1777 /* EXPORT:
1778 Return an estimation of the pixel height of mode or header lines on
1779 frame F. FACE_ID specifies what line's height to estimate. */
1782 estimate_mode_line_height (struct frame *f, enum face_id face_id)
1784 #ifdef HAVE_WINDOW_SYSTEM
1785 if (FRAME_WINDOW_P (f))
1787 int height = FONT_HEIGHT (FRAME_FONT (f));
1789 /* This function is called so early when Emacs starts that the face
1790 cache and mode line face are not yet initialized. */
1791 if (FRAME_FACE_CACHE (f))
1793 struct face *face = FACE_FROM_ID (f, face_id);
1794 if (face)
1796 if (face->font)
1797 height = FONT_HEIGHT (face->font);
1798 if (face->box_line_width > 0)
1799 height += 2 * face->box_line_width;
1803 return height;
1805 #endif
1807 return 1;
1810 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1811 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1812 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1813 not force the value into range. */
1815 void
1816 pixel_to_glyph_coords (FRAME_PTR f, register int pix_x, register int pix_y,
1817 int *x, int *y, NativeRectangle *bounds, int noclip)
1820 #ifdef HAVE_WINDOW_SYSTEM
1821 if (FRAME_WINDOW_P (f))
1823 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1824 even for negative values. */
1825 if (pix_x < 0)
1826 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1827 if (pix_y < 0)
1828 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1830 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1831 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1833 if (bounds)
1834 STORE_NATIVE_RECT (*bounds,
1835 FRAME_COL_TO_PIXEL_X (f, pix_x),
1836 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1837 FRAME_COLUMN_WIDTH (f) - 1,
1838 FRAME_LINE_HEIGHT (f) - 1);
1840 if (!noclip)
1842 if (pix_x < 0)
1843 pix_x = 0;
1844 else if (pix_x > FRAME_TOTAL_COLS (f))
1845 pix_x = FRAME_TOTAL_COLS (f);
1847 if (pix_y < 0)
1848 pix_y = 0;
1849 else if (pix_y > FRAME_LINES (f))
1850 pix_y = FRAME_LINES (f);
1853 #endif
1855 *x = pix_x;
1856 *y = pix_y;
1860 /* Find the glyph under window-relative coordinates X/Y in window W.
1861 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1862 strings. Return in *HPOS and *VPOS the row and column number of
1863 the glyph found. Return in *AREA the glyph area containing X.
1864 Value is a pointer to the glyph found or null if X/Y is not on
1865 text, or we can't tell because W's current matrix is not up to
1866 date. */
1868 static
1869 struct glyph *
1870 x_y_to_hpos_vpos (struct window *w, int x, int y, int *hpos, int *vpos,
1871 int *dx, int *dy, int *area)
1873 struct glyph *glyph, *end;
1874 struct glyph_row *row = NULL;
1875 int x0, i;
1877 /* Find row containing Y. Give up if some row is not enabled. */
1878 for (i = 0; i < w->current_matrix->nrows; ++i)
1880 row = MATRIX_ROW (w->current_matrix, i);
1881 if (!row->enabled_p)
1882 return NULL;
1883 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1884 break;
1887 *vpos = i;
1888 *hpos = 0;
1890 /* Give up if Y is not in the window. */
1891 if (i == w->current_matrix->nrows)
1892 return NULL;
1894 /* Get the glyph area containing X. */
1895 if (w->pseudo_window_p)
1897 *area = TEXT_AREA;
1898 x0 = 0;
1900 else
1902 if (x < window_box_left_offset (w, TEXT_AREA))
1904 *area = LEFT_MARGIN_AREA;
1905 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1907 else if (x < window_box_right_offset (w, TEXT_AREA))
1909 *area = TEXT_AREA;
1910 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1912 else
1914 *area = RIGHT_MARGIN_AREA;
1915 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1919 /* Find glyph containing X. */
1920 glyph = row->glyphs[*area];
1921 end = glyph + row->used[*area];
1922 x -= x0;
1923 while (glyph < end && x >= glyph->pixel_width)
1925 x -= glyph->pixel_width;
1926 ++glyph;
1929 if (glyph == end)
1930 return NULL;
1932 if (dx)
1934 *dx = x;
1935 *dy = y - (row->y + row->ascent - glyph->ascent);
1938 *hpos = glyph - row->glyphs[*area];
1939 return glyph;
1942 /* Convert frame-relative x/y to coordinates relative to window W.
1943 Takes pseudo-windows into account. */
1945 static void
1946 frame_to_window_pixel_xy (struct window *w, int *x, int *y)
1948 if (w->pseudo_window_p)
1950 /* A pseudo-window is always full-width, and starts at the
1951 left edge of the frame, plus a frame border. */
1952 struct frame *f = XFRAME (w->frame);
1953 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1954 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1956 else
1958 *x -= WINDOW_LEFT_EDGE_X (w);
1959 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1963 #ifdef HAVE_WINDOW_SYSTEM
1965 /* EXPORT:
1966 Return in RECTS[] at most N clipping rectangles for glyph string S.
1967 Return the number of stored rectangles. */
1970 get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int n)
1972 XRectangle r;
1974 if (n <= 0)
1975 return 0;
1977 if (s->row->full_width_p)
1979 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1980 r.x = WINDOW_LEFT_EDGE_X (s->w);
1981 r.width = WINDOW_TOTAL_WIDTH (s->w);
1983 /* Unless displaying a mode or menu bar line, which are always
1984 fully visible, clip to the visible part of the row. */
1985 if (s->w->pseudo_window_p)
1986 r.height = s->row->visible_height;
1987 else
1988 r.height = s->height;
1990 else
1992 /* This is a text line that may be partially visible. */
1993 r.x = window_box_left (s->w, s->area);
1994 r.width = window_box_width (s->w, s->area);
1995 r.height = s->row->visible_height;
1998 if (s->clip_head)
1999 if (r.x < s->clip_head->x)
2001 if (r.width >= s->clip_head->x - r.x)
2002 r.width -= s->clip_head->x - r.x;
2003 else
2004 r.width = 0;
2005 r.x = s->clip_head->x;
2007 if (s->clip_tail)
2008 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
2010 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
2011 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
2012 else
2013 r.width = 0;
2016 /* If S draws overlapping rows, it's sufficient to use the top and
2017 bottom of the window for clipping because this glyph string
2018 intentionally draws over other lines. */
2019 if (s->for_overlaps)
2021 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2022 r.height = window_text_bottom_y (s->w) - r.y;
2024 /* Alas, the above simple strategy does not work for the
2025 environments with anti-aliased text: if the same text is
2026 drawn onto the same place multiple times, it gets thicker.
2027 If the overlap we are processing is for the erased cursor, we
2028 take the intersection with the rectangle of the cursor. */
2029 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
2031 XRectangle rc, r_save = r;
2033 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
2034 rc.y = s->w->phys_cursor.y;
2035 rc.width = s->w->phys_cursor_width;
2036 rc.height = s->w->phys_cursor_height;
2038 x_intersect_rectangles (&r_save, &rc, &r);
2041 else
2043 /* Don't use S->y for clipping because it doesn't take partially
2044 visible lines into account. For example, it can be negative for
2045 partially visible lines at the top of a window. */
2046 if (!s->row->full_width_p
2047 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
2048 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2049 else
2050 r.y = max (0, s->row->y);
2053 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
2055 /* If drawing the cursor, don't let glyph draw outside its
2056 advertised boundaries. Cleartype does this under some circumstances. */
2057 if (s->hl == DRAW_CURSOR)
2059 struct glyph *glyph = s->first_glyph;
2060 int height, max_y;
2062 if (s->x > r.x)
2064 r.width -= s->x - r.x;
2065 r.x = s->x;
2067 r.width = min (r.width, glyph->pixel_width);
2069 /* If r.y is below window bottom, ensure that we still see a cursor. */
2070 height = min (glyph->ascent + glyph->descent,
2071 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
2072 max_y = window_text_bottom_y (s->w) - height;
2073 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
2074 if (s->ybase - glyph->ascent > max_y)
2076 r.y = max_y;
2077 r.height = height;
2079 else
2081 /* Don't draw cursor glyph taller than our actual glyph. */
2082 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
2083 if (height < r.height)
2085 max_y = r.y + r.height;
2086 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
2087 r.height = min (max_y - r.y, height);
2092 if (s->row->clip)
2094 XRectangle r_save = r;
2096 if (! x_intersect_rectangles (&r_save, s->row->clip, &r))
2097 r.width = 0;
2100 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
2101 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
2103 #ifdef CONVERT_FROM_XRECT
2104 CONVERT_FROM_XRECT (r, *rects);
2105 #else
2106 *rects = r;
2107 #endif
2108 return 1;
2110 else
2112 /* If we are processing overlapping and allowed to return
2113 multiple clipping rectangles, we exclude the row of the glyph
2114 string from the clipping rectangle. This is to avoid drawing
2115 the same text on the environment with anti-aliasing. */
2116 #ifdef CONVERT_FROM_XRECT
2117 XRectangle rs[2];
2118 #else
2119 XRectangle *rs = rects;
2120 #endif
2121 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
2123 if (s->for_overlaps & OVERLAPS_PRED)
2125 rs[i] = r;
2126 if (r.y + r.height > row_y)
2128 if (r.y < row_y)
2129 rs[i].height = row_y - r.y;
2130 else
2131 rs[i].height = 0;
2133 i++;
2135 if (s->for_overlaps & OVERLAPS_SUCC)
2137 rs[i] = r;
2138 if (r.y < row_y + s->row->visible_height)
2140 if (r.y + r.height > row_y + s->row->visible_height)
2142 rs[i].y = row_y + s->row->visible_height;
2143 rs[i].height = r.y + r.height - rs[i].y;
2145 else
2146 rs[i].height = 0;
2148 i++;
2151 n = i;
2152 #ifdef CONVERT_FROM_XRECT
2153 for (i = 0; i < n; i++)
2154 CONVERT_FROM_XRECT (rs[i], rects[i]);
2155 #endif
2156 return n;
2160 /* EXPORT:
2161 Return in *NR the clipping rectangle for glyph string S. */
2163 void
2164 get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr)
2166 get_glyph_string_clip_rects (s, nr, 1);
2170 /* EXPORT:
2171 Return the position and height of the phys cursor in window W.
2172 Set w->phys_cursor_width to width of phys cursor.
2175 void
2176 get_phys_cursor_geometry (struct window *w, struct glyph_row *row,
2177 struct glyph *glyph, int *xp, int *yp, int *heightp)
2179 struct frame *f = XFRAME (WINDOW_FRAME (w));
2180 int x, y, wd, h, h0, y0;
2182 /* Compute the width of the rectangle to draw. If on a stretch
2183 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2184 rectangle as wide as the glyph, but use a canonical character
2185 width instead. */
2186 wd = glyph->pixel_width - 1;
2187 #if defined (HAVE_NTGUI) || defined (HAVE_NS)
2188 wd++; /* Why? */
2189 #endif
2191 x = w->phys_cursor.x;
2192 if (x < 0)
2194 wd += x;
2195 x = 0;
2198 if (glyph->type == STRETCH_GLYPH
2199 && !x_stretch_cursor_p)
2200 wd = min (FRAME_COLUMN_WIDTH (f), wd);
2201 w->phys_cursor_width = wd;
2203 y = w->phys_cursor.y + row->ascent - glyph->ascent;
2205 /* If y is below window bottom, ensure that we still see a cursor. */
2206 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
2208 h = max (h0, glyph->ascent + glyph->descent);
2209 h0 = min (h0, glyph->ascent + glyph->descent);
2211 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
2212 if (y < y0)
2214 h = max (h - (y0 - y) + 1, h0);
2215 y = y0 - 1;
2217 else
2219 y0 = window_text_bottom_y (w) - h0;
2220 if (y > y0)
2222 h += y - y0;
2223 y = y0;
2227 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
2228 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
2229 *heightp = h;
2233 * Remember which glyph the mouse is over.
2236 void
2237 remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
2239 Lisp_Object window;
2240 struct window *w;
2241 struct glyph_row *r, *gr, *end_row;
2242 enum window_part part;
2243 enum glyph_row_area area;
2244 int x, y, width, height;
2246 /* Try to determine frame pixel position and size of the glyph under
2247 frame pixel coordinates X/Y on frame F. */
2249 if (!f->glyphs_initialized_p
2250 || (window = window_from_coordinates (f, gx, gy, &part, 0),
2251 NILP (window)))
2253 width = FRAME_SMALLEST_CHAR_WIDTH (f);
2254 height = FRAME_SMALLEST_FONT_HEIGHT (f);
2255 goto virtual_glyph;
2258 w = XWINDOW (window);
2259 width = WINDOW_FRAME_COLUMN_WIDTH (w);
2260 height = WINDOW_FRAME_LINE_HEIGHT (w);
2262 x = window_relative_x_coord (w, part, gx);
2263 y = gy - WINDOW_TOP_EDGE_Y (w);
2265 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
2266 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
2268 if (w->pseudo_window_p)
2270 area = TEXT_AREA;
2271 part = ON_MODE_LINE; /* Don't adjust margin. */
2272 goto text_glyph;
2275 switch (part)
2277 case ON_LEFT_MARGIN:
2278 area = LEFT_MARGIN_AREA;
2279 goto text_glyph;
2281 case ON_RIGHT_MARGIN:
2282 area = RIGHT_MARGIN_AREA;
2283 goto text_glyph;
2285 case ON_HEADER_LINE:
2286 case ON_MODE_LINE:
2287 gr = (part == ON_HEADER_LINE
2288 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
2289 : MATRIX_MODE_LINE_ROW (w->current_matrix));
2290 gy = gr->y;
2291 area = TEXT_AREA;
2292 goto text_glyph_row_found;
2294 case ON_TEXT:
2295 area = TEXT_AREA;
2297 text_glyph:
2298 gr = 0; gy = 0;
2299 for (; r <= end_row && r->enabled_p; ++r)
2300 if (r->y + r->height > y)
2302 gr = r; gy = r->y;
2303 break;
2306 text_glyph_row_found:
2307 if (gr && gy <= y)
2309 struct glyph *g = gr->glyphs[area];
2310 struct glyph *end = g + gr->used[area];
2312 height = gr->height;
2313 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2314 if (gx + g->pixel_width > x)
2315 break;
2317 if (g < end)
2319 if (g->type == IMAGE_GLYPH)
2321 /* Don't remember when mouse is over image, as
2322 image may have hot-spots. */
2323 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2324 return;
2326 width = g->pixel_width;
2328 else
2330 /* Use nominal char spacing at end of line. */
2331 x -= gx;
2332 gx += (x / width) * width;
2335 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2336 gx += window_box_left_offset (w, area);
2338 else
2340 /* Use nominal line height at end of window. */
2341 gx = (x / width) * width;
2342 y -= gy;
2343 gy += (y / height) * height;
2345 break;
2347 case ON_LEFT_FRINGE:
2348 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2349 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2350 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2351 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2352 goto row_glyph;
2354 case ON_RIGHT_FRINGE:
2355 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2356 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2357 : window_box_right_offset (w, TEXT_AREA));
2358 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2359 goto row_glyph;
2361 case ON_SCROLL_BAR:
2362 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2364 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2365 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2366 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2367 : 0)));
2368 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2370 row_glyph:
2371 gr = 0, gy = 0;
2372 for (; r <= end_row && r->enabled_p; ++r)
2373 if (r->y + r->height > y)
2375 gr = r; gy = r->y;
2376 break;
2379 if (gr && gy <= y)
2380 height = gr->height;
2381 else
2383 /* Use nominal line height at end of window. */
2384 y -= gy;
2385 gy += (y / height) * height;
2387 break;
2389 default:
2391 virtual_glyph:
2392 /* If there is no glyph under the mouse, then we divide the screen
2393 into a grid of the smallest glyph in the frame, and use that
2394 as our "glyph". */
2396 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2397 round down even for negative values. */
2398 if (gx < 0)
2399 gx -= width - 1;
2400 if (gy < 0)
2401 gy -= height - 1;
2403 gx = (gx / width) * width;
2404 gy = (gy / height) * height;
2406 goto store_rect;
2409 gx += WINDOW_LEFT_EDGE_X (w);
2410 gy += WINDOW_TOP_EDGE_Y (w);
2412 store_rect:
2413 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2415 /* Visible feedback for debugging. */
2416 #if 0
2417 #if HAVE_X_WINDOWS
2418 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2419 f->output_data.x->normal_gc,
2420 gx, gy, width, height);
2421 #endif
2422 #endif
2426 #endif /* HAVE_WINDOW_SYSTEM */
2429 /***********************************************************************
2430 Lisp form evaluation
2431 ***********************************************************************/
2433 /* Error handler for safe_eval and safe_call. */
2435 static Lisp_Object
2436 safe_eval_handler (Lisp_Object arg, ptrdiff_t nargs, Lisp_Object *args)
2438 add_to_log ("Error during redisplay: %S signaled %S",
2439 Flist (nargs, args), arg);
2440 return Qnil;
2443 /* Call function FUNC with the rest of NARGS - 1 arguments
2444 following. Return the result, or nil if something went
2445 wrong. Prevent redisplay during the evaluation. */
2447 Lisp_Object
2448 safe_call (ptrdiff_t nargs, Lisp_Object func, ...)
2450 Lisp_Object val;
2452 if (inhibit_eval_during_redisplay)
2453 val = Qnil;
2454 else
2456 va_list ap;
2457 ptrdiff_t i;
2458 ptrdiff_t count = SPECPDL_INDEX ();
2459 struct gcpro gcpro1;
2460 Lisp_Object *args = alloca (nargs * word_size);
2462 args[0] = func;
2463 va_start (ap, func);
2464 for (i = 1; i < nargs; i++)
2465 args[i] = va_arg (ap, Lisp_Object);
2466 va_end (ap);
2468 GCPRO1 (args[0]);
2469 gcpro1.nvars = nargs;
2470 specbind (Qinhibit_redisplay, Qt);
2471 /* Use Qt to ensure debugger does not run,
2472 so there is no possibility of wanting to redisplay. */
2473 val = internal_condition_case_n (Ffuncall, nargs, args, Qt,
2474 safe_eval_handler);
2475 UNGCPRO;
2476 val = unbind_to (count, val);
2479 return val;
2483 /* Call function FN with one argument ARG.
2484 Return the result, or nil if something went wrong. */
2486 Lisp_Object
2487 safe_call1 (Lisp_Object fn, Lisp_Object arg)
2489 return safe_call (2, fn, arg);
2492 static Lisp_Object Qeval;
2494 Lisp_Object
2495 safe_eval (Lisp_Object sexpr)
2497 return safe_call1 (Qeval, sexpr);
2500 /* Call function FN with two arguments ARG1 and ARG2.
2501 Return the result, or nil if something went wrong. */
2503 Lisp_Object
2504 safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
2506 return safe_call (3, fn, arg1, arg2);
2511 /***********************************************************************
2512 Debugging
2513 ***********************************************************************/
2515 #if 0
2517 /* Define CHECK_IT to perform sanity checks on iterators.
2518 This is for debugging. It is too slow to do unconditionally. */
2520 static void
2521 check_it (struct it *it)
2523 if (it->method == GET_FROM_STRING)
2525 eassert (STRINGP (it->string));
2526 eassert (IT_STRING_CHARPOS (*it) >= 0);
2528 else
2530 eassert (IT_STRING_CHARPOS (*it) < 0);
2531 if (it->method == GET_FROM_BUFFER)
2533 /* Check that character and byte positions agree. */
2534 eassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2538 if (it->dpvec)
2539 eassert (it->current.dpvec_index >= 0);
2540 else
2541 eassert (it->current.dpvec_index < 0);
2544 #define CHECK_IT(IT) check_it ((IT))
2546 #else /* not 0 */
2548 #define CHECK_IT(IT) (void) 0
2550 #endif /* not 0 */
2553 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2555 /* Check that the window end of window W is what we expect it
2556 to be---the last row in the current matrix displaying text. */
2558 static void
2559 check_window_end (struct window *w)
2561 if (!MINI_WINDOW_P (w) && w->window_end_valid)
2563 struct glyph_row *row;
2564 eassert ((row = MATRIX_ROW (w->current_matrix,
2565 XFASTINT (w->window_end_vpos)),
2566 !row->enabled_p
2567 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2568 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2572 #define CHECK_WINDOW_END(W) check_window_end ((W))
2574 #else
2576 #define CHECK_WINDOW_END(W) (void) 0
2578 #endif /* GLYPH_DEBUG and ENABLE_CHECKING */
2580 /* Return mark position if current buffer has the region of non-zero length,
2581 or -1 otherwise. */
2583 static ptrdiff_t
2584 markpos_of_region (void)
2586 if (!NILP (Vtransient_mark_mode)
2587 && !NILP (BVAR (current_buffer, mark_active))
2588 && XMARKER (BVAR (current_buffer, mark))->buffer != NULL)
2590 ptrdiff_t markpos = XMARKER (BVAR (current_buffer, mark))->charpos;
2592 if (markpos != PT)
2593 return markpos;
2595 return -1;
2598 /***********************************************************************
2599 Iterator initialization
2600 ***********************************************************************/
2602 /* Initialize IT for displaying current_buffer in window W, starting
2603 at character position CHARPOS. CHARPOS < 0 means that no buffer
2604 position is specified which is useful when the iterator is assigned
2605 a position later. BYTEPOS is the byte position corresponding to
2606 CHARPOS.
2608 If ROW is not null, calls to produce_glyphs with IT as parameter
2609 will produce glyphs in that row.
2611 BASE_FACE_ID is the id of a base face to use. It must be one of
2612 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2613 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2614 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2616 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2617 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2618 will be initialized to use the corresponding mode line glyph row of
2619 the desired matrix of W. */
2621 void
2622 init_iterator (struct it *it, struct window *w,
2623 ptrdiff_t charpos, ptrdiff_t bytepos,
2624 struct glyph_row *row, enum face_id base_face_id)
2626 ptrdiff_t markpos;
2627 enum face_id remapped_base_face_id = base_face_id;
2629 /* Some precondition checks. */
2630 eassert (w != NULL && it != NULL);
2631 eassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2632 && charpos <= ZV));
2634 /* If face attributes have been changed since the last redisplay,
2635 free realized faces now because they depend on face definitions
2636 that might have changed. Don't free faces while there might be
2637 desired matrices pending which reference these faces. */
2638 if (face_change_count && !inhibit_free_realized_faces)
2640 face_change_count = 0;
2641 free_all_realized_faces (Qnil);
2644 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
2645 if (! NILP (Vface_remapping_alist))
2646 remapped_base_face_id
2647 = lookup_basic_face (XFRAME (w->frame), base_face_id);
2649 /* Use one of the mode line rows of W's desired matrix if
2650 appropriate. */
2651 if (row == NULL)
2653 if (base_face_id == MODE_LINE_FACE_ID
2654 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2655 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2656 else if (base_face_id == HEADER_LINE_FACE_ID)
2657 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2660 /* Clear IT. */
2661 memset (it, 0, sizeof *it);
2662 it->current.overlay_string_index = -1;
2663 it->current.dpvec_index = -1;
2664 it->base_face_id = remapped_base_face_id;
2665 it->string = Qnil;
2666 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2667 it->paragraph_embedding = L2R;
2668 it->bidi_it.string.lstring = Qnil;
2669 it->bidi_it.string.s = NULL;
2670 it->bidi_it.string.bufpos = 0;
2671 it->bidi_it.w = w;
2673 /* The window in which we iterate over current_buffer: */
2674 XSETWINDOW (it->window, w);
2675 it->w = w;
2676 it->f = XFRAME (w->frame);
2678 it->cmp_it.id = -1;
2680 /* Extra space between lines (on window systems only). */
2681 if (base_face_id == DEFAULT_FACE_ID
2682 && FRAME_WINDOW_P (it->f))
2684 if (NATNUMP (BVAR (current_buffer, extra_line_spacing)))
2685 it->extra_line_spacing = XFASTINT (BVAR (current_buffer, extra_line_spacing));
2686 else if (FLOATP (BVAR (current_buffer, extra_line_spacing)))
2687 it->extra_line_spacing = (XFLOAT_DATA (BVAR (current_buffer, extra_line_spacing))
2688 * FRAME_LINE_HEIGHT (it->f));
2689 else if (it->f->extra_line_spacing > 0)
2690 it->extra_line_spacing = it->f->extra_line_spacing;
2691 it->max_extra_line_spacing = 0;
2694 /* If realized faces have been removed, e.g. because of face
2695 attribute changes of named faces, recompute them. When running
2696 in batch mode, the face cache of the initial frame is null. If
2697 we happen to get called, make a dummy face cache. */
2698 if (FRAME_FACE_CACHE (it->f) == NULL)
2699 init_frame_faces (it->f);
2700 if (FRAME_FACE_CACHE (it->f)->used == 0)
2701 recompute_basic_faces (it->f);
2703 /* Current value of the `slice', `space-width', and 'height' properties. */
2704 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2705 it->space_width = Qnil;
2706 it->font_height = Qnil;
2707 it->override_ascent = -1;
2709 /* Are control characters displayed as `^C'? */
2710 it->ctl_arrow_p = !NILP (BVAR (current_buffer, ctl_arrow));
2712 /* -1 means everything between a CR and the following line end
2713 is invisible. >0 means lines indented more than this value are
2714 invisible. */
2715 it->selective = (INTEGERP (BVAR (current_buffer, selective_display))
2716 ? (clip_to_bounds
2717 (-1, XINT (BVAR (current_buffer, selective_display)),
2718 PTRDIFF_MAX))
2719 : (!NILP (BVAR (current_buffer, selective_display))
2720 ? -1 : 0));
2721 it->selective_display_ellipsis_p
2722 = !NILP (BVAR (current_buffer, selective_display_ellipses));
2724 /* Display table to use. */
2725 it->dp = window_display_table (w);
2727 /* Are multibyte characters enabled in current_buffer? */
2728 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
2730 /* If visible region is of non-zero length, set IT->region_beg_charpos
2731 and IT->region_end_charpos to the start and end of a visible region
2732 in window IT->w. Set both to -1 to indicate no region. */
2733 markpos = markpos_of_region ();
2734 if (markpos >= 0
2735 /* Maybe highlight only in selected window. */
2736 && (/* Either show region everywhere. */
2737 highlight_nonselected_windows
2738 /* Or show region in the selected window. */
2739 || w == XWINDOW (selected_window)
2740 /* Or show the region if we are in the mini-buffer and W is
2741 the window the mini-buffer refers to. */
2742 || (MINI_WINDOW_P (XWINDOW (selected_window))
2743 && WINDOWP (minibuf_selected_window)
2744 && w == XWINDOW (minibuf_selected_window))))
2746 it->region_beg_charpos = min (PT, markpos);
2747 it->region_end_charpos = max (PT, markpos);
2749 else
2750 it->region_beg_charpos = it->region_end_charpos = -1;
2752 /* Get the position at which the redisplay_end_trigger hook should
2753 be run, if it is to be run at all. */
2754 if (MARKERP (w->redisplay_end_trigger)
2755 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2756 it->redisplay_end_trigger_charpos
2757 = marker_position (w->redisplay_end_trigger);
2758 else if (INTEGERP (w->redisplay_end_trigger))
2759 it->redisplay_end_trigger_charpos =
2760 clip_to_bounds (PTRDIFF_MIN, XINT (w->redisplay_end_trigger), PTRDIFF_MAX);
2762 it->tab_width = SANE_TAB_WIDTH (current_buffer);
2764 /* Are lines in the display truncated? */
2765 if (base_face_id != DEFAULT_FACE_ID
2766 || it->w->hscroll
2767 || (! WINDOW_FULL_WIDTH_P (it->w)
2768 && ((!NILP (Vtruncate_partial_width_windows)
2769 && !INTEGERP (Vtruncate_partial_width_windows))
2770 || (INTEGERP (Vtruncate_partial_width_windows)
2771 && (WINDOW_TOTAL_COLS (it->w)
2772 < XINT (Vtruncate_partial_width_windows))))))
2773 it->line_wrap = TRUNCATE;
2774 else if (NILP (BVAR (current_buffer, truncate_lines)))
2775 it->line_wrap = NILP (BVAR (current_buffer, word_wrap))
2776 ? WINDOW_WRAP : WORD_WRAP;
2777 else
2778 it->line_wrap = TRUNCATE;
2780 /* Get dimensions of truncation and continuation glyphs. These are
2781 displayed as fringe bitmaps under X, but we need them for such
2782 frames when the fringes are turned off. But leave the dimensions
2783 zero for tooltip frames, as these glyphs look ugly there and also
2784 sabotage calculations of tooltip dimensions in x-show-tip. */
2785 #ifdef HAVE_WINDOW_SYSTEM
2786 if (!(FRAME_WINDOW_P (it->f)
2787 && FRAMEP (tip_frame)
2788 && it->f == XFRAME (tip_frame)))
2789 #endif
2791 if (it->line_wrap == TRUNCATE)
2793 /* We will need the truncation glyph. */
2794 eassert (it->glyph_row == NULL);
2795 produce_special_glyphs (it, IT_TRUNCATION);
2796 it->truncation_pixel_width = it->pixel_width;
2798 else
2800 /* We will need the continuation glyph. */
2801 eassert (it->glyph_row == NULL);
2802 produce_special_glyphs (it, IT_CONTINUATION);
2803 it->continuation_pixel_width = it->pixel_width;
2807 /* Reset these values to zero because the produce_special_glyphs
2808 above has changed them. */
2809 it->pixel_width = it->ascent = it->descent = 0;
2810 it->phys_ascent = it->phys_descent = 0;
2812 /* Set this after getting the dimensions of truncation and
2813 continuation glyphs, so that we don't produce glyphs when calling
2814 produce_special_glyphs, above. */
2815 it->glyph_row = row;
2816 it->area = TEXT_AREA;
2818 /* Forget any previous info about this row being reversed. */
2819 if (it->glyph_row)
2820 it->glyph_row->reversed_p = 0;
2822 /* Get the dimensions of the display area. The display area
2823 consists of the visible window area plus a horizontally scrolled
2824 part to the left of the window. All x-values are relative to the
2825 start of this total display area. */
2826 if (base_face_id != DEFAULT_FACE_ID)
2828 /* Mode lines, menu bar in terminal frames. */
2829 it->first_visible_x = 0;
2830 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2832 else
2834 it->first_visible_x =
2835 window_hscroll_limited (it->w, it->f) * FRAME_COLUMN_WIDTH (it->f);
2836 it->last_visible_x = (it->first_visible_x
2837 + window_box_width (w, TEXT_AREA));
2839 /* If we truncate lines, leave room for the truncation glyph(s) at
2840 the right margin. Otherwise, leave room for the continuation
2841 glyph(s). Done only if the window has no fringes. Since we
2842 don't know at this point whether there will be any R2L lines in
2843 the window, we reserve space for truncation/continuation glyphs
2844 even if only one of the fringes is absent. */
2845 if (WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
2846 || (it->bidi_p && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0))
2848 if (it->line_wrap == TRUNCATE)
2849 it->last_visible_x -= it->truncation_pixel_width;
2850 else
2851 it->last_visible_x -= it->continuation_pixel_width;
2854 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2855 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2858 /* Leave room for a border glyph. */
2859 if (!FRAME_WINDOW_P (it->f)
2860 && !WINDOW_RIGHTMOST_P (it->w))
2861 it->last_visible_x -= 1;
2863 it->last_visible_y = window_text_bottom_y (w);
2865 /* For mode lines and alike, arrange for the first glyph having a
2866 left box line if the face specifies a box. */
2867 if (base_face_id != DEFAULT_FACE_ID)
2869 struct face *face;
2871 it->face_id = remapped_base_face_id;
2873 /* If we have a boxed mode line, make the first character appear
2874 with a left box line. */
2875 face = FACE_FROM_ID (it->f, remapped_base_face_id);
2876 if (face->box != FACE_NO_BOX)
2877 it->start_of_box_run_p = 1;
2880 /* If a buffer position was specified, set the iterator there,
2881 getting overlays and face properties from that position. */
2882 if (charpos >= BUF_BEG (current_buffer))
2884 it->end_charpos = ZV;
2885 eassert (charpos == BYTE_TO_CHAR (bytepos));
2886 IT_CHARPOS (*it) = charpos;
2887 IT_BYTEPOS (*it) = bytepos;
2889 /* We will rely on `reseat' to set this up properly, via
2890 handle_face_prop. */
2891 it->face_id = it->base_face_id;
2893 it->start = it->current;
2894 /* Do we need to reorder bidirectional text? Not if this is a
2895 unibyte buffer: by definition, none of the single-byte
2896 characters are strong R2L, so no reordering is needed. And
2897 bidi.c doesn't support unibyte buffers anyway. Also, don't
2898 reorder while we are loading loadup.el, since the tables of
2899 character properties needed for reordering are not yet
2900 available. */
2901 it->bidi_p =
2902 NILP (Vpurify_flag)
2903 && !NILP (BVAR (current_buffer, bidi_display_reordering))
2904 && it->multibyte_p;
2906 /* If we are to reorder bidirectional text, init the bidi
2907 iterator. */
2908 if (it->bidi_p)
2910 /* Note the paragraph direction that this buffer wants to
2911 use. */
2912 if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
2913 Qleft_to_right))
2914 it->paragraph_embedding = L2R;
2915 else if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
2916 Qright_to_left))
2917 it->paragraph_embedding = R2L;
2918 else
2919 it->paragraph_embedding = NEUTRAL_DIR;
2920 bidi_unshelve_cache (NULL, 0);
2921 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
2922 &it->bidi_it);
2925 /* Compute faces etc. */
2926 reseat (it, it->current.pos, 1);
2929 CHECK_IT (it);
2933 /* Initialize IT for the display of window W with window start POS. */
2935 void
2936 start_display (struct it *it, struct window *w, struct text_pos pos)
2938 struct glyph_row *row;
2939 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2941 row = w->desired_matrix->rows + first_vpos;
2942 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2943 it->first_vpos = first_vpos;
2945 /* Don't reseat to previous visible line start if current start
2946 position is in a string or image. */
2947 if (it->method == GET_FROM_BUFFER && it->line_wrap != TRUNCATE)
2949 int start_at_line_beg_p;
2950 int first_y = it->current_y;
2952 /* If window start is not at a line start, skip forward to POS to
2953 get the correct continuation lines width. */
2954 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2955 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2956 if (!start_at_line_beg_p)
2958 int new_x;
2960 reseat_at_previous_visible_line_start (it);
2961 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2963 new_x = it->current_x + it->pixel_width;
2965 /* If lines are continued, this line may end in the middle
2966 of a multi-glyph character (e.g. a control character
2967 displayed as \003, or in the middle of an overlay
2968 string). In this case move_it_to above will not have
2969 taken us to the start of the continuation line but to the
2970 end of the continued line. */
2971 if (it->current_x > 0
2972 && it->line_wrap != TRUNCATE /* Lines are continued. */
2973 && (/* And glyph doesn't fit on the line. */
2974 new_x > it->last_visible_x
2975 /* Or it fits exactly and we're on a window
2976 system frame. */
2977 || (new_x == it->last_visible_x
2978 && FRAME_WINDOW_P (it->f)
2979 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
2980 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
2981 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
2983 if ((it->current.dpvec_index >= 0
2984 || it->current.overlay_string_index >= 0)
2985 /* If we are on a newline from a display vector or
2986 overlay string, then we are already at the end of
2987 a screen line; no need to go to the next line in
2988 that case, as this line is not really continued.
2989 (If we do go to the next line, C-e will not DTRT.) */
2990 && it->c != '\n')
2992 set_iterator_to_next (it, 1);
2993 move_it_in_display_line_to (it, -1, -1, 0);
2996 it->continuation_lines_width += it->current_x;
2998 /* If the character at POS is displayed via a display
2999 vector, move_it_to above stops at the final glyph of
3000 IT->dpvec. To make the caller redisplay that character
3001 again (a.k.a. start at POS), we need to reset the
3002 dpvec_index to the beginning of IT->dpvec. */
3003 else if (it->current.dpvec_index >= 0)
3004 it->current.dpvec_index = 0;
3006 /* We're starting a new display line, not affected by the
3007 height of the continued line, so clear the appropriate
3008 fields in the iterator structure. */
3009 it->max_ascent = it->max_descent = 0;
3010 it->max_phys_ascent = it->max_phys_descent = 0;
3012 it->current_y = first_y;
3013 it->vpos = 0;
3014 it->current_x = it->hpos = 0;
3020 /* Return 1 if POS is a position in ellipses displayed for invisible
3021 text. W is the window we display, for text property lookup. */
3023 static int
3024 in_ellipses_for_invisible_text_p (struct display_pos *pos, struct window *w)
3026 Lisp_Object prop, window;
3027 int ellipses_p = 0;
3028 ptrdiff_t charpos = CHARPOS (pos->pos);
3030 /* If POS specifies a position in a display vector, this might
3031 be for an ellipsis displayed for invisible text. We won't
3032 get the iterator set up for delivering that ellipsis unless
3033 we make sure that it gets aware of the invisible text. */
3034 if (pos->dpvec_index >= 0
3035 && pos->overlay_string_index < 0
3036 && CHARPOS (pos->string_pos) < 0
3037 && charpos > BEGV
3038 && (XSETWINDOW (window, w),
3039 prop = Fget_char_property (make_number (charpos),
3040 Qinvisible, window),
3041 !TEXT_PROP_MEANS_INVISIBLE (prop)))
3043 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
3044 window);
3045 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
3048 return ellipses_p;
3052 /* Initialize IT for stepping through current_buffer in window W,
3053 starting at position POS that includes overlay string and display
3054 vector/ control character translation position information. Value
3055 is zero if there are overlay strings with newlines at POS. */
3057 static int
3058 init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos)
3060 ptrdiff_t charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
3061 int i, overlay_strings_with_newlines = 0;
3063 /* If POS specifies a position in a display vector, this might
3064 be for an ellipsis displayed for invisible text. We won't
3065 get the iterator set up for delivering that ellipsis unless
3066 we make sure that it gets aware of the invisible text. */
3067 if (in_ellipses_for_invisible_text_p (pos, w))
3069 --charpos;
3070 bytepos = 0;
3073 /* Keep in mind: the call to reseat in init_iterator skips invisible
3074 text, so we might end up at a position different from POS. This
3075 is only a problem when POS is a row start after a newline and an
3076 overlay starts there with an after-string, and the overlay has an
3077 invisible property. Since we don't skip invisible text in
3078 display_line and elsewhere immediately after consuming the
3079 newline before the row start, such a POS will not be in a string,
3080 but the call to init_iterator below will move us to the
3081 after-string. */
3082 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
3084 /* This only scans the current chunk -- it should scan all chunks.
3085 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
3086 to 16 in 22.1 to make this a lesser problem. */
3087 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
3089 const char *s = SSDATA (it->overlay_strings[i]);
3090 const char *e = s + SBYTES (it->overlay_strings[i]);
3092 while (s < e && *s != '\n')
3093 ++s;
3095 if (s < e)
3097 overlay_strings_with_newlines = 1;
3098 break;
3102 /* If position is within an overlay string, set up IT to the right
3103 overlay string. */
3104 if (pos->overlay_string_index >= 0)
3106 int relative_index;
3108 /* If the first overlay string happens to have a `display'
3109 property for an image, the iterator will be set up for that
3110 image, and we have to undo that setup first before we can
3111 correct the overlay string index. */
3112 if (it->method == GET_FROM_IMAGE)
3113 pop_it (it);
3115 /* We already have the first chunk of overlay strings in
3116 IT->overlay_strings. Load more until the one for
3117 pos->overlay_string_index is in IT->overlay_strings. */
3118 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
3120 ptrdiff_t n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
3121 it->current.overlay_string_index = 0;
3122 while (n--)
3124 load_overlay_strings (it, 0);
3125 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
3129 it->current.overlay_string_index = pos->overlay_string_index;
3130 relative_index = (it->current.overlay_string_index
3131 % OVERLAY_STRING_CHUNK_SIZE);
3132 it->string = it->overlay_strings[relative_index];
3133 eassert (STRINGP (it->string));
3134 it->current.string_pos = pos->string_pos;
3135 it->method = GET_FROM_STRING;
3136 it->end_charpos = SCHARS (it->string);
3137 /* Set up the bidi iterator for this overlay string. */
3138 if (it->bidi_p)
3140 it->bidi_it.string.lstring = it->string;
3141 it->bidi_it.string.s = NULL;
3142 it->bidi_it.string.schars = SCHARS (it->string);
3143 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
3144 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
3145 it->bidi_it.string.unibyte = !it->multibyte_p;
3146 it->bidi_it.w = it->w;
3147 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3148 FRAME_WINDOW_P (it->f), &it->bidi_it);
3150 /* Synchronize the state of the bidi iterator with
3151 pos->string_pos. For any string position other than
3152 zero, this will be done automagically when we resume
3153 iteration over the string and get_visually_first_element
3154 is called. But if string_pos is zero, and the string is
3155 to be reordered for display, we need to resync manually,
3156 since it could be that the iteration state recorded in
3157 pos ended at string_pos of 0 moving backwards in string. */
3158 if (CHARPOS (pos->string_pos) == 0)
3160 get_visually_first_element (it);
3161 if (IT_STRING_CHARPOS (*it) != 0)
3162 do {
3163 /* Paranoia. */
3164 eassert (it->bidi_it.charpos < it->bidi_it.string.schars);
3165 bidi_move_to_visually_next (&it->bidi_it);
3166 } while (it->bidi_it.charpos != 0);
3168 eassert (IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
3169 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos);
3173 if (CHARPOS (pos->string_pos) >= 0)
3175 /* Recorded position is not in an overlay string, but in another
3176 string. This can only be a string from a `display' property.
3177 IT should already be filled with that string. */
3178 it->current.string_pos = pos->string_pos;
3179 eassert (STRINGP (it->string));
3180 if (it->bidi_p)
3181 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3182 FRAME_WINDOW_P (it->f), &it->bidi_it);
3185 /* Restore position in display vector translations, control
3186 character translations or ellipses. */
3187 if (pos->dpvec_index >= 0)
3189 if (it->dpvec == NULL)
3190 get_next_display_element (it);
3191 eassert (it->dpvec && it->current.dpvec_index == 0);
3192 it->current.dpvec_index = pos->dpvec_index;
3195 CHECK_IT (it);
3196 return !overlay_strings_with_newlines;
3200 /* Initialize IT for stepping through current_buffer in window W
3201 starting at ROW->start. */
3203 static void
3204 init_to_row_start (struct it *it, struct window *w, struct glyph_row *row)
3206 init_from_display_pos (it, w, &row->start);
3207 it->start = row->start;
3208 it->continuation_lines_width = row->continuation_lines_width;
3209 CHECK_IT (it);
3213 /* Initialize IT for stepping through current_buffer in window W
3214 starting in the line following ROW, i.e. starting at ROW->end.
3215 Value is zero if there are overlay strings with newlines at ROW's
3216 end position. */
3218 static int
3219 init_to_row_end (struct it *it, struct window *w, struct glyph_row *row)
3221 int success = 0;
3223 if (init_from_display_pos (it, w, &row->end))
3225 if (row->continued_p)
3226 it->continuation_lines_width
3227 = row->continuation_lines_width + row->pixel_width;
3228 CHECK_IT (it);
3229 success = 1;
3232 return success;
3238 /***********************************************************************
3239 Text properties
3240 ***********************************************************************/
3242 /* Called when IT reaches IT->stop_charpos. Handle text property and
3243 overlay changes. Set IT->stop_charpos to the next position where
3244 to stop. */
3246 static void
3247 handle_stop (struct it *it)
3249 enum prop_handled handled;
3250 int handle_overlay_change_p;
3251 struct props *p;
3253 it->dpvec = NULL;
3254 it->current.dpvec_index = -1;
3255 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
3256 it->ignore_overlay_strings_at_pos_p = 0;
3257 it->ellipsis_p = 0;
3259 /* Use face of preceding text for ellipsis (if invisible) */
3260 if (it->selective_display_ellipsis_p)
3261 it->saved_face_id = it->face_id;
3265 handled = HANDLED_NORMALLY;
3267 /* Call text property handlers. */
3268 for (p = it_props; p->handler; ++p)
3270 handled = p->handler (it);
3272 if (handled == HANDLED_RECOMPUTE_PROPS)
3273 break;
3274 else if (handled == HANDLED_RETURN)
3276 /* We still want to show before and after strings from
3277 overlays even if the actual buffer text is replaced. */
3278 if (!handle_overlay_change_p
3279 || it->sp > 1
3280 /* Don't call get_overlay_strings_1 if we already
3281 have overlay strings loaded, because doing so
3282 will load them again and push the iterator state
3283 onto the stack one more time, which is not
3284 expected by the rest of the code that processes
3285 overlay strings. */
3286 || (it->current.overlay_string_index < 0
3287 ? !get_overlay_strings_1 (it, 0, 0)
3288 : 0))
3290 if (it->ellipsis_p)
3291 setup_for_ellipsis (it, 0);
3292 /* When handling a display spec, we might load an
3293 empty string. In that case, discard it here. We
3294 used to discard it in handle_single_display_spec,
3295 but that causes get_overlay_strings_1, above, to
3296 ignore overlay strings that we must check. */
3297 if (STRINGP (it->string) && !SCHARS (it->string))
3298 pop_it (it);
3299 return;
3301 else if (STRINGP (it->string) && !SCHARS (it->string))
3302 pop_it (it);
3303 else
3305 it->ignore_overlay_strings_at_pos_p = 1;
3306 it->string_from_display_prop_p = 0;
3307 it->from_disp_prop_p = 0;
3308 handle_overlay_change_p = 0;
3310 handled = HANDLED_RECOMPUTE_PROPS;
3311 break;
3313 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
3314 handle_overlay_change_p = 0;
3317 if (handled != HANDLED_RECOMPUTE_PROPS)
3319 /* Don't check for overlay strings below when set to deliver
3320 characters from a display vector. */
3321 if (it->method == GET_FROM_DISPLAY_VECTOR)
3322 handle_overlay_change_p = 0;
3324 /* Handle overlay changes.
3325 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
3326 if it finds overlays. */
3327 if (handle_overlay_change_p)
3328 handled = handle_overlay_change (it);
3331 if (it->ellipsis_p)
3333 setup_for_ellipsis (it, 0);
3334 break;
3337 while (handled == HANDLED_RECOMPUTE_PROPS);
3339 /* Determine where to stop next. */
3340 if (handled == HANDLED_NORMALLY)
3341 compute_stop_pos (it);
3345 /* Compute IT->stop_charpos from text property and overlay change
3346 information for IT's current position. */
3348 static void
3349 compute_stop_pos (struct it *it)
3351 register INTERVAL iv, next_iv;
3352 Lisp_Object object, limit, position;
3353 ptrdiff_t charpos, bytepos;
3355 if (STRINGP (it->string))
3357 /* Strings are usually short, so don't limit the search for
3358 properties. */
3359 it->stop_charpos = it->end_charpos;
3360 object = it->string;
3361 limit = Qnil;
3362 charpos = IT_STRING_CHARPOS (*it);
3363 bytepos = IT_STRING_BYTEPOS (*it);
3365 else
3367 ptrdiff_t pos;
3369 /* If end_charpos is out of range for some reason, such as a
3370 misbehaving display function, rationalize it (Bug#5984). */
3371 if (it->end_charpos > ZV)
3372 it->end_charpos = ZV;
3373 it->stop_charpos = it->end_charpos;
3375 /* If next overlay change is in front of the current stop pos
3376 (which is IT->end_charpos), stop there. Note: value of
3377 next_overlay_change is point-max if no overlay change
3378 follows. */
3379 charpos = IT_CHARPOS (*it);
3380 bytepos = IT_BYTEPOS (*it);
3381 pos = next_overlay_change (charpos);
3382 if (pos < it->stop_charpos)
3383 it->stop_charpos = pos;
3385 /* If showing the region, we have to stop at the region
3386 start or end because the face might change there. */
3387 if (it->region_beg_charpos > 0)
3389 if (IT_CHARPOS (*it) < it->region_beg_charpos)
3390 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
3391 else if (IT_CHARPOS (*it) < it->region_end_charpos)
3392 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
3395 /* Set up variables for computing the stop position from text
3396 property changes. */
3397 XSETBUFFER (object, current_buffer);
3398 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3401 /* Get the interval containing IT's position. Value is a null
3402 interval if there isn't such an interval. */
3403 position = make_number (charpos);
3404 iv = validate_interval_range (object, &position, &position, 0);
3405 if (iv)
3407 Lisp_Object values_here[LAST_PROP_IDX];
3408 struct props *p;
3410 /* Get properties here. */
3411 for (p = it_props; p->handler; ++p)
3412 values_here[p->idx] = textget (iv->plist, *p->name);
3414 /* Look for an interval following iv that has different
3415 properties. */
3416 for (next_iv = next_interval (iv);
3417 (next_iv
3418 && (NILP (limit)
3419 || XFASTINT (limit) > next_iv->position));
3420 next_iv = next_interval (next_iv))
3422 for (p = it_props; p->handler; ++p)
3424 Lisp_Object new_value;
3426 new_value = textget (next_iv->plist, *p->name);
3427 if (!EQ (values_here[p->idx], new_value))
3428 break;
3431 if (p->handler)
3432 break;
3435 if (next_iv)
3437 if (INTEGERP (limit)
3438 && next_iv->position >= XFASTINT (limit))
3439 /* No text property change up to limit. */
3440 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3441 else
3442 /* Text properties change in next_iv. */
3443 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3447 if (it->cmp_it.id < 0)
3449 ptrdiff_t stoppos = it->end_charpos;
3451 if (it->bidi_p && it->bidi_it.scan_dir < 0)
3452 stoppos = -1;
3453 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
3454 stoppos, it->string);
3457 eassert (STRINGP (it->string)
3458 || (it->stop_charpos >= BEGV
3459 && it->stop_charpos >= IT_CHARPOS (*it)));
3463 /* Return the position of the next overlay change after POS in
3464 current_buffer. Value is point-max if no overlay change
3465 follows. This is like `next-overlay-change' but doesn't use
3466 xmalloc. */
3468 static ptrdiff_t
3469 next_overlay_change (ptrdiff_t pos)
3471 ptrdiff_t i, noverlays;
3472 ptrdiff_t endpos;
3473 Lisp_Object *overlays;
3475 /* Get all overlays at the given position. */
3476 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
3478 /* If any of these overlays ends before endpos,
3479 use its ending point instead. */
3480 for (i = 0; i < noverlays; ++i)
3482 Lisp_Object oend;
3483 ptrdiff_t oendpos;
3485 oend = OVERLAY_END (overlays[i]);
3486 oendpos = OVERLAY_POSITION (oend);
3487 endpos = min (endpos, oendpos);
3490 return endpos;
3493 /* How many characters forward to search for a display property or
3494 display string. Searching too far forward makes the bidi display
3495 sluggish, especially in small windows. */
3496 #define MAX_DISP_SCAN 250
3498 /* Return the character position of a display string at or after
3499 position specified by POSITION. If no display string exists at or
3500 after POSITION, return ZV. A display string is either an overlay
3501 with `display' property whose value is a string, or a `display'
3502 text property whose value is a string. STRING is data about the
3503 string to iterate; if STRING->lstring is nil, we are iterating a
3504 buffer. FRAME_WINDOW_P is non-zero when we are displaying a window
3505 on a GUI frame. DISP_PROP is set to zero if we searched
3506 MAX_DISP_SCAN characters forward without finding any display
3507 strings, non-zero otherwise. It is set to 2 if the display string
3508 uses any kind of `(space ...)' spec that will produce a stretch of
3509 white space in the text area. */
3510 ptrdiff_t
3511 compute_display_string_pos (struct text_pos *position,
3512 struct bidi_string_data *string,
3513 struct window *w,
3514 int frame_window_p, int *disp_prop)
3516 /* OBJECT = nil means current buffer. */
3517 Lisp_Object object, object1;
3518 Lisp_Object pos, spec, limpos;
3519 int string_p = (string && (STRINGP (string->lstring) || string->s));
3520 ptrdiff_t eob = string_p ? string->schars : ZV;
3521 ptrdiff_t begb = string_p ? 0 : BEGV;
3522 ptrdiff_t bufpos, charpos = CHARPOS (*position);
3523 ptrdiff_t lim =
3524 (charpos < eob - MAX_DISP_SCAN) ? charpos + MAX_DISP_SCAN : eob;
3525 struct text_pos tpos;
3526 int rv = 0;
3528 if (string && STRINGP (string->lstring))
3529 object1 = object = string->lstring;
3530 else if (w && !string_p)
3532 XSETWINDOW (object, w);
3533 object1 = Qnil;
3535 else
3536 object1 = object = Qnil;
3538 *disp_prop = 1;
3540 if (charpos >= eob
3541 /* We don't support display properties whose values are strings
3542 that have display string properties. */
3543 || string->from_disp_str
3544 /* C strings cannot have display properties. */
3545 || (string->s && !STRINGP (object)))
3547 *disp_prop = 0;
3548 return eob;
3551 /* If the character at CHARPOS is where the display string begins,
3552 return CHARPOS. */
3553 pos = make_number (charpos);
3554 if (STRINGP (object))
3555 bufpos = string->bufpos;
3556 else
3557 bufpos = charpos;
3558 tpos = *position;
3559 if (!NILP (spec = Fget_char_property (pos, Qdisplay, object))
3560 && (charpos <= begb
3561 || !EQ (Fget_char_property (make_number (charpos - 1), Qdisplay,
3562 object),
3563 spec))
3564 && (rv = handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
3565 frame_window_p)))
3567 if (rv == 2)
3568 *disp_prop = 2;
3569 return charpos;
3572 /* Look forward for the first character with a `display' property
3573 that will replace the underlying text when displayed. */
3574 limpos = make_number (lim);
3575 do {
3576 pos = Fnext_single_char_property_change (pos, Qdisplay, object1, limpos);
3577 CHARPOS (tpos) = XFASTINT (pos);
3578 if (CHARPOS (tpos) >= lim)
3580 *disp_prop = 0;
3581 break;
3583 if (STRINGP (object))
3584 BYTEPOS (tpos) = string_char_to_byte (object, CHARPOS (tpos));
3585 else
3586 BYTEPOS (tpos) = CHAR_TO_BYTE (CHARPOS (tpos));
3587 spec = Fget_char_property (pos, Qdisplay, object);
3588 if (!STRINGP (object))
3589 bufpos = CHARPOS (tpos);
3590 } while (NILP (spec)
3591 || !(rv = handle_display_spec (NULL, spec, object, Qnil, &tpos,
3592 bufpos, frame_window_p)));
3593 if (rv == 2)
3594 *disp_prop = 2;
3596 return CHARPOS (tpos);
3599 /* Return the character position of the end of the display string that
3600 started at CHARPOS. If there's no display string at CHARPOS,
3601 return -1. A display string is either an overlay with `display'
3602 property whose value is a string or a `display' text property whose
3603 value is a string. */
3604 ptrdiff_t
3605 compute_display_string_end (ptrdiff_t charpos, struct bidi_string_data *string)
3607 /* OBJECT = nil means current buffer. */
3608 Lisp_Object object =
3609 (string && STRINGP (string->lstring)) ? string->lstring : Qnil;
3610 Lisp_Object pos = make_number (charpos);
3611 ptrdiff_t eob =
3612 (STRINGP (object) || (string && string->s)) ? string->schars : ZV;
3614 if (charpos >= eob || (string->s && !STRINGP (object)))
3615 return eob;
3617 /* It could happen that the display property or overlay was removed
3618 since we found it in compute_display_string_pos above. One way
3619 this can happen is if JIT font-lock was called (through
3620 handle_fontified_prop), and jit-lock-functions remove text
3621 properties or overlays from the portion of buffer that includes
3622 CHARPOS. Muse mode is known to do that, for example. In this
3623 case, we return -1 to the caller, to signal that no display
3624 string is actually present at CHARPOS. See bidi_fetch_char for
3625 how this is handled.
3627 An alternative would be to never look for display properties past
3628 it->stop_charpos. But neither compute_display_string_pos nor
3629 bidi_fetch_char that calls it know or care where the next
3630 stop_charpos is. */
3631 if (NILP (Fget_char_property (pos, Qdisplay, object)))
3632 return -1;
3634 /* Look forward for the first character where the `display' property
3635 changes. */
3636 pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil);
3638 return XFASTINT (pos);
3643 /***********************************************************************
3644 Fontification
3645 ***********************************************************************/
3647 /* Handle changes in the `fontified' property of the current buffer by
3648 calling hook functions from Qfontification_functions to fontify
3649 regions of text. */
3651 static enum prop_handled
3652 handle_fontified_prop (struct it *it)
3654 Lisp_Object prop, pos;
3655 enum prop_handled handled = HANDLED_NORMALLY;
3657 if (!NILP (Vmemory_full))
3658 return handled;
3660 /* Get the value of the `fontified' property at IT's current buffer
3661 position. (The `fontified' property doesn't have a special
3662 meaning in strings.) If the value is nil, call functions from
3663 Qfontification_functions. */
3664 if (!STRINGP (it->string)
3665 && it->s == NULL
3666 && !NILP (Vfontification_functions)
3667 && !NILP (Vrun_hooks)
3668 && (pos = make_number (IT_CHARPOS (*it)),
3669 prop = Fget_char_property (pos, Qfontified, Qnil),
3670 /* Ignore the special cased nil value always present at EOB since
3671 no amount of fontifying will be able to change it. */
3672 NILP (prop) && IT_CHARPOS (*it) < Z))
3674 ptrdiff_t count = SPECPDL_INDEX ();
3675 Lisp_Object val;
3676 struct buffer *obuf = current_buffer;
3677 int begv = BEGV, zv = ZV;
3678 int old_clip_changed = current_buffer->clip_changed;
3680 val = Vfontification_functions;
3681 specbind (Qfontification_functions, Qnil);
3683 eassert (it->end_charpos == ZV);
3685 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3686 safe_call1 (val, pos);
3687 else
3689 Lisp_Object fns, fn;
3690 struct gcpro gcpro1, gcpro2;
3692 fns = Qnil;
3693 GCPRO2 (val, fns);
3695 for (; CONSP (val); val = XCDR (val))
3697 fn = XCAR (val);
3699 if (EQ (fn, Qt))
3701 /* A value of t indicates this hook has a local
3702 binding; it means to run the global binding too.
3703 In a global value, t should not occur. If it
3704 does, we must ignore it to avoid an endless
3705 loop. */
3706 for (fns = Fdefault_value (Qfontification_functions);
3707 CONSP (fns);
3708 fns = XCDR (fns))
3710 fn = XCAR (fns);
3711 if (!EQ (fn, Qt))
3712 safe_call1 (fn, pos);
3715 else
3716 safe_call1 (fn, pos);
3719 UNGCPRO;
3722 unbind_to (count, Qnil);
3724 /* Fontification functions routinely call `save-restriction'.
3725 Normally, this tags clip_changed, which can confuse redisplay
3726 (see discussion in Bug#6671). Since we don't perform any
3727 special handling of fontification changes in the case where
3728 `save-restriction' isn't called, there's no point doing so in
3729 this case either. So, if the buffer's restrictions are
3730 actually left unchanged, reset clip_changed. */
3731 if (obuf == current_buffer)
3733 if (begv == BEGV && zv == ZV)
3734 current_buffer->clip_changed = old_clip_changed;
3736 /* There isn't much we can reasonably do to protect against
3737 misbehaving fontification, but here's a fig leaf. */
3738 else if (BUFFER_LIVE_P (obuf))
3739 set_buffer_internal_1 (obuf);
3741 /* The fontification code may have added/removed text.
3742 It could do even a lot worse, but let's at least protect against
3743 the most obvious case where only the text past `pos' gets changed',
3744 as is/was done in grep.el where some escapes sequences are turned
3745 into face properties (bug#7876). */
3746 it->end_charpos = ZV;
3748 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3749 something. This avoids an endless loop if they failed to
3750 fontify the text for which reason ever. */
3751 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3752 handled = HANDLED_RECOMPUTE_PROPS;
3755 return handled;
3760 /***********************************************************************
3761 Faces
3762 ***********************************************************************/
3764 /* Set up iterator IT from face properties at its current position.
3765 Called from handle_stop. */
3767 static enum prop_handled
3768 handle_face_prop (struct it *it)
3770 int new_face_id;
3771 ptrdiff_t next_stop;
3773 if (!STRINGP (it->string))
3775 new_face_id
3776 = face_at_buffer_position (it->w,
3777 IT_CHARPOS (*it),
3778 it->region_beg_charpos,
3779 it->region_end_charpos,
3780 &next_stop,
3781 (IT_CHARPOS (*it)
3782 + TEXT_PROP_DISTANCE_LIMIT),
3783 0, it->base_face_id);
3785 /* Is this a start of a run of characters with box face?
3786 Caveat: this can be called for a freshly initialized
3787 iterator; face_id is -1 in this case. We know that the new
3788 face will not change until limit, i.e. if the new face has a
3789 box, all characters up to limit will have one. But, as
3790 usual, we don't know whether limit is really the end. */
3791 if (new_face_id != it->face_id)
3793 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3794 /* If it->face_id is -1, old_face below will be NULL, see
3795 the definition of FACE_FROM_ID. This will happen if this
3796 is the initial call that gets the face. */
3797 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3799 /* If the value of face_id of the iterator is -1, we have to
3800 look in front of IT's position and see whether there is a
3801 face there that's different from new_face_id. */
3802 if (!old_face && IT_CHARPOS (*it) > BEG)
3804 int prev_face_id = face_before_it_pos (it);
3806 old_face = FACE_FROM_ID (it->f, prev_face_id);
3809 /* If the new face has a box, but the old face does not,
3810 this is the start of a run of characters with box face,
3811 i.e. this character has a shadow on the left side. */
3812 it->start_of_box_run_p = (new_face->box != FACE_NO_BOX
3813 && (old_face == NULL || !old_face->box));
3814 it->face_box_p = new_face->box != FACE_NO_BOX;
3817 else
3819 int base_face_id;
3820 ptrdiff_t bufpos;
3821 int i;
3822 Lisp_Object from_overlay
3823 = (it->current.overlay_string_index >= 0
3824 ? it->string_overlays[it->current.overlay_string_index
3825 % OVERLAY_STRING_CHUNK_SIZE]
3826 : Qnil);
3828 /* See if we got to this string directly or indirectly from
3829 an overlay property. That includes the before-string or
3830 after-string of an overlay, strings in display properties
3831 provided by an overlay, their text properties, etc.
3833 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
3834 if (! NILP (from_overlay))
3835 for (i = it->sp - 1; i >= 0; i--)
3837 if (it->stack[i].current.overlay_string_index >= 0)
3838 from_overlay
3839 = it->string_overlays[it->stack[i].current.overlay_string_index
3840 % OVERLAY_STRING_CHUNK_SIZE];
3841 else if (! NILP (it->stack[i].from_overlay))
3842 from_overlay = it->stack[i].from_overlay;
3844 if (!NILP (from_overlay))
3845 break;
3848 if (! NILP (from_overlay))
3850 bufpos = IT_CHARPOS (*it);
3851 /* For a string from an overlay, the base face depends
3852 only on text properties and ignores overlays. */
3853 base_face_id
3854 = face_for_overlay_string (it->w,
3855 IT_CHARPOS (*it),
3856 it->region_beg_charpos,
3857 it->region_end_charpos,
3858 &next_stop,
3859 (IT_CHARPOS (*it)
3860 + TEXT_PROP_DISTANCE_LIMIT),
3862 from_overlay);
3864 else
3866 bufpos = 0;
3868 /* For strings from a `display' property, use the face at
3869 IT's current buffer position as the base face to merge
3870 with, so that overlay strings appear in the same face as
3871 surrounding text, unless they specify their own
3872 faces. */
3873 base_face_id = it->string_from_prefix_prop_p
3874 ? DEFAULT_FACE_ID
3875 : underlying_face_id (it);
3878 new_face_id = face_at_string_position (it->w,
3879 it->string,
3880 IT_STRING_CHARPOS (*it),
3881 bufpos,
3882 it->region_beg_charpos,
3883 it->region_end_charpos,
3884 &next_stop,
3885 base_face_id, 0);
3887 /* Is this a start of a run of characters with box? Caveat:
3888 this can be called for a freshly allocated iterator; face_id
3889 is -1 is this case. We know that the new face will not
3890 change until the next check pos, i.e. if the new face has a
3891 box, all characters up to that position will have a
3892 box. But, as usual, we don't know whether that position
3893 is really the end. */
3894 if (new_face_id != it->face_id)
3896 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3897 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3899 /* If new face has a box but old face hasn't, this is the
3900 start of a run of characters with box, i.e. it has a
3901 shadow on the left side. */
3902 it->start_of_box_run_p
3903 = new_face->box && (old_face == NULL || !old_face->box);
3904 it->face_box_p = new_face->box != FACE_NO_BOX;
3908 it->face_id = new_face_id;
3909 return HANDLED_NORMALLY;
3913 /* Return the ID of the face ``underlying'' IT's current position,
3914 which is in a string. If the iterator is associated with a
3915 buffer, return the face at IT's current buffer position.
3916 Otherwise, use the iterator's base_face_id. */
3918 static int
3919 underlying_face_id (struct it *it)
3921 int face_id = it->base_face_id, i;
3923 eassert (STRINGP (it->string));
3925 for (i = it->sp - 1; i >= 0; --i)
3926 if (NILP (it->stack[i].string))
3927 face_id = it->stack[i].face_id;
3929 return face_id;
3933 /* Compute the face one character before or after the current position
3934 of IT, in the visual order. BEFORE_P non-zero means get the face
3935 in front (to the left in L2R paragraphs, to the right in R2L
3936 paragraphs) of IT's screen position. Value is the ID of the face. */
3938 static int
3939 face_before_or_after_it_pos (struct it *it, int before_p)
3941 int face_id, limit;
3942 ptrdiff_t next_check_charpos;
3943 struct it it_copy;
3944 void *it_copy_data = NULL;
3946 eassert (it->s == NULL);
3948 if (STRINGP (it->string))
3950 ptrdiff_t bufpos, charpos;
3951 int base_face_id;
3953 /* No face change past the end of the string (for the case
3954 we are padding with spaces). No face change before the
3955 string start. */
3956 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
3957 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
3958 return it->face_id;
3960 if (!it->bidi_p)
3962 /* Set charpos to the position before or after IT's current
3963 position, in the logical order, which in the non-bidi
3964 case is the same as the visual order. */
3965 if (before_p)
3966 charpos = IT_STRING_CHARPOS (*it) - 1;
3967 else if (it->what == IT_COMPOSITION)
3968 /* For composition, we must check the character after the
3969 composition. */
3970 charpos = IT_STRING_CHARPOS (*it) + it->cmp_it.nchars;
3971 else
3972 charpos = IT_STRING_CHARPOS (*it) + 1;
3974 else
3976 if (before_p)
3978 /* With bidi iteration, the character before the current
3979 in the visual order cannot be found by simple
3980 iteration, because "reverse" reordering is not
3981 supported. Instead, we need to use the move_it_*
3982 family of functions. */
3983 /* Ignore face changes before the first visible
3984 character on this display line. */
3985 if (it->current_x <= it->first_visible_x)
3986 return it->face_id;
3987 SAVE_IT (it_copy, *it, it_copy_data);
3988 /* Implementation note: Since move_it_in_display_line
3989 works in the iterator geometry, and thinks the first
3990 character is always the leftmost, even in R2L lines,
3991 we don't need to distinguish between the R2L and L2R
3992 cases here. */
3993 move_it_in_display_line (&it_copy, SCHARS (it_copy.string),
3994 it_copy.current_x - 1, MOVE_TO_X);
3995 charpos = IT_STRING_CHARPOS (it_copy);
3996 RESTORE_IT (it, it, it_copy_data);
3998 else
4000 /* Set charpos to the string position of the character
4001 that comes after IT's current position in the visual
4002 order. */
4003 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
4005 it_copy = *it;
4006 while (n--)
4007 bidi_move_to_visually_next (&it_copy.bidi_it);
4009 charpos = it_copy.bidi_it.charpos;
4012 eassert (0 <= charpos && charpos <= SCHARS (it->string));
4014 if (it->current.overlay_string_index >= 0)
4015 bufpos = IT_CHARPOS (*it);
4016 else
4017 bufpos = 0;
4019 base_face_id = underlying_face_id (it);
4021 /* Get the face for ASCII, or unibyte. */
4022 face_id = face_at_string_position (it->w,
4023 it->string,
4024 charpos,
4025 bufpos,
4026 it->region_beg_charpos,
4027 it->region_end_charpos,
4028 &next_check_charpos,
4029 base_face_id, 0);
4031 /* Correct the face for charsets different from ASCII. Do it
4032 for the multibyte case only. The face returned above is
4033 suitable for unibyte text if IT->string is unibyte. */
4034 if (STRING_MULTIBYTE (it->string))
4036 struct text_pos pos1 = string_pos (charpos, it->string);
4037 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos1);
4038 int c, len;
4039 struct face *face = FACE_FROM_ID (it->f, face_id);
4041 c = string_char_and_length (p, &len);
4042 face_id = FACE_FOR_CHAR (it->f, face, c, charpos, it->string);
4045 else
4047 struct text_pos pos;
4049 if ((IT_CHARPOS (*it) >= ZV && !before_p)
4050 || (IT_CHARPOS (*it) <= BEGV && before_p))
4051 return it->face_id;
4053 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
4054 pos = it->current.pos;
4056 if (!it->bidi_p)
4058 if (before_p)
4059 DEC_TEXT_POS (pos, it->multibyte_p);
4060 else
4062 if (it->what == IT_COMPOSITION)
4064 /* For composition, we must check the position after
4065 the composition. */
4066 pos.charpos += it->cmp_it.nchars;
4067 pos.bytepos += it->len;
4069 else
4070 INC_TEXT_POS (pos, it->multibyte_p);
4073 else
4075 if (before_p)
4077 /* With bidi iteration, the character before the current
4078 in the visual order cannot be found by simple
4079 iteration, because "reverse" reordering is not
4080 supported. Instead, we need to use the move_it_*
4081 family of functions. */
4082 /* Ignore face changes before the first visible
4083 character on this display line. */
4084 if (it->current_x <= it->first_visible_x)
4085 return it->face_id;
4086 SAVE_IT (it_copy, *it, it_copy_data);
4087 /* Implementation note: Since move_it_in_display_line
4088 works in the iterator geometry, and thinks the first
4089 character is always the leftmost, even in R2L lines,
4090 we don't need to distinguish between the R2L and L2R
4091 cases here. */
4092 move_it_in_display_line (&it_copy, ZV,
4093 it_copy.current_x - 1, MOVE_TO_X);
4094 pos = it_copy.current.pos;
4095 RESTORE_IT (it, it, it_copy_data);
4097 else
4099 /* Set charpos to the buffer position of the character
4100 that comes after IT's current position in the visual
4101 order. */
4102 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
4104 it_copy = *it;
4105 while (n--)
4106 bidi_move_to_visually_next (&it_copy.bidi_it);
4108 SET_TEXT_POS (pos,
4109 it_copy.bidi_it.charpos, it_copy.bidi_it.bytepos);
4112 eassert (BEGV <= CHARPOS (pos) && CHARPOS (pos) <= ZV);
4114 /* Determine face for CHARSET_ASCII, or unibyte. */
4115 face_id = face_at_buffer_position (it->w,
4116 CHARPOS (pos),
4117 it->region_beg_charpos,
4118 it->region_end_charpos,
4119 &next_check_charpos,
4120 limit, 0, -1);
4122 /* Correct the face for charsets different from ASCII. Do it
4123 for the multibyte case only. The face returned above is
4124 suitable for unibyte text if current_buffer is unibyte. */
4125 if (it->multibyte_p)
4127 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
4128 struct face *face = FACE_FROM_ID (it->f, face_id);
4129 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
4133 return face_id;
4138 /***********************************************************************
4139 Invisible text
4140 ***********************************************************************/
4142 /* Set up iterator IT from invisible properties at its current
4143 position. Called from handle_stop. */
4145 static enum prop_handled
4146 handle_invisible_prop (struct it *it)
4148 enum prop_handled handled = HANDLED_NORMALLY;
4149 int invis_p;
4150 Lisp_Object prop;
4152 if (STRINGP (it->string))
4154 Lisp_Object end_charpos, limit, charpos;
4156 /* Get the value of the invisible text property at the
4157 current position. Value will be nil if there is no such
4158 property. */
4159 charpos = make_number (IT_STRING_CHARPOS (*it));
4160 prop = Fget_text_property (charpos, Qinvisible, it->string);
4161 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4163 if (invis_p && IT_STRING_CHARPOS (*it) < it->end_charpos)
4165 /* Record whether we have to display an ellipsis for the
4166 invisible text. */
4167 int display_ellipsis_p = (invis_p == 2);
4168 ptrdiff_t len, endpos;
4170 handled = HANDLED_RECOMPUTE_PROPS;
4172 /* Get the position at which the next visible text can be
4173 found in IT->string, if any. */
4174 endpos = len = SCHARS (it->string);
4175 XSETINT (limit, len);
4178 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
4179 it->string, limit);
4180 if (INTEGERP (end_charpos))
4182 endpos = XFASTINT (end_charpos);
4183 prop = Fget_text_property (end_charpos, Qinvisible, it->string);
4184 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4185 if (invis_p == 2)
4186 display_ellipsis_p = 1;
4189 while (invis_p && endpos < len);
4191 if (display_ellipsis_p)
4192 it->ellipsis_p = 1;
4194 if (endpos < len)
4196 /* Text at END_CHARPOS is visible. Move IT there. */
4197 struct text_pos old;
4198 ptrdiff_t oldpos;
4200 old = it->current.string_pos;
4201 oldpos = CHARPOS (old);
4202 if (it->bidi_p)
4204 if (it->bidi_it.first_elt
4205 && it->bidi_it.charpos < SCHARS (it->string))
4206 bidi_paragraph_init (it->paragraph_embedding,
4207 &it->bidi_it, 1);
4208 /* Bidi-iterate out of the invisible text. */
4211 bidi_move_to_visually_next (&it->bidi_it);
4213 while (oldpos <= it->bidi_it.charpos
4214 && it->bidi_it.charpos < endpos);
4216 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
4217 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
4218 if (IT_CHARPOS (*it) >= endpos)
4219 it->prev_stop = endpos;
4221 else
4223 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
4224 compute_string_pos (&it->current.string_pos, old, it->string);
4227 else
4229 /* The rest of the string is invisible. If this is an
4230 overlay string, proceed with the next overlay string
4231 or whatever comes and return a character from there. */
4232 if (it->current.overlay_string_index >= 0
4233 && !display_ellipsis_p)
4235 next_overlay_string (it);
4236 /* Don't check for overlay strings when we just
4237 finished processing them. */
4238 handled = HANDLED_OVERLAY_STRING_CONSUMED;
4240 else
4242 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
4243 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
4248 else
4250 ptrdiff_t newpos, next_stop, start_charpos, tem;
4251 Lisp_Object pos, overlay;
4253 /* First of all, is there invisible text at this position? */
4254 tem = start_charpos = IT_CHARPOS (*it);
4255 pos = make_number (tem);
4256 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
4257 &overlay);
4258 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4260 /* If we are on invisible text, skip over it. */
4261 if (invis_p && start_charpos < it->end_charpos)
4263 /* Record whether we have to display an ellipsis for the
4264 invisible text. */
4265 int display_ellipsis_p = invis_p == 2;
4267 handled = HANDLED_RECOMPUTE_PROPS;
4269 /* Loop skipping over invisible text. The loop is left at
4270 ZV or with IT on the first char being visible again. */
4273 /* Try to skip some invisible text. Return value is the
4274 position reached which can be equal to where we start
4275 if there is nothing invisible there. This skips both
4276 over invisible text properties and overlays with
4277 invisible property. */
4278 newpos = skip_invisible (tem, &next_stop, ZV, it->window);
4280 /* If we skipped nothing at all we weren't at invisible
4281 text in the first place. If everything to the end of
4282 the buffer was skipped, end the loop. */
4283 if (newpos == tem || newpos >= ZV)
4284 invis_p = 0;
4285 else
4287 /* We skipped some characters but not necessarily
4288 all there are. Check if we ended up on visible
4289 text. Fget_char_property returns the property of
4290 the char before the given position, i.e. if we
4291 get invis_p = 0, this means that the char at
4292 newpos is visible. */
4293 pos = make_number (newpos);
4294 prop = Fget_char_property (pos, Qinvisible, it->window);
4295 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4298 /* If we ended up on invisible text, proceed to
4299 skip starting with next_stop. */
4300 if (invis_p)
4301 tem = next_stop;
4303 /* If there are adjacent invisible texts, don't lose the
4304 second one's ellipsis. */
4305 if (invis_p == 2)
4306 display_ellipsis_p = 1;
4308 while (invis_p);
4310 /* The position newpos is now either ZV or on visible text. */
4311 if (it->bidi_p)
4313 ptrdiff_t bpos = CHAR_TO_BYTE (newpos);
4314 int on_newline =
4315 bpos == ZV_BYTE || FETCH_BYTE (bpos) == '\n';
4316 int after_newline =
4317 newpos <= BEGV || FETCH_BYTE (bpos - 1) == '\n';
4319 /* If the invisible text ends on a newline or on a
4320 character after a newline, we can avoid the costly,
4321 character by character, bidi iteration to NEWPOS, and
4322 instead simply reseat the iterator there. That's
4323 because all bidi reordering information is tossed at
4324 the newline. This is a big win for modes that hide
4325 complete lines, like Outline, Org, etc. */
4326 if (on_newline || after_newline)
4328 struct text_pos tpos;
4329 bidi_dir_t pdir = it->bidi_it.paragraph_dir;
4331 SET_TEXT_POS (tpos, newpos, bpos);
4332 reseat_1 (it, tpos, 0);
4333 /* If we reseat on a newline/ZV, we need to prep the
4334 bidi iterator for advancing to the next character
4335 after the newline/EOB, keeping the current paragraph
4336 direction (so that PRODUCE_GLYPHS does TRT wrt
4337 prepending/appending glyphs to a glyph row). */
4338 if (on_newline)
4340 it->bidi_it.first_elt = 0;
4341 it->bidi_it.paragraph_dir = pdir;
4342 it->bidi_it.ch = (bpos == ZV_BYTE) ? -1 : '\n';
4343 it->bidi_it.nchars = 1;
4344 it->bidi_it.ch_len = 1;
4347 else /* Must use the slow method. */
4349 /* With bidi iteration, the region of invisible text
4350 could start and/or end in the middle of a
4351 non-base embedding level. Therefore, we need to
4352 skip invisible text using the bidi iterator,
4353 starting at IT's current position, until we find
4354 ourselves outside of the invisible text.
4355 Skipping invisible text _after_ bidi iteration
4356 avoids affecting the visual order of the
4357 displayed text when invisible properties are
4358 added or removed. */
4359 if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV)
4361 /* If we were `reseat'ed to a new paragraph,
4362 determine the paragraph base direction. We
4363 need to do it now because
4364 next_element_from_buffer may not have a
4365 chance to do it, if we are going to skip any
4366 text at the beginning, which resets the
4367 FIRST_ELT flag. */
4368 bidi_paragraph_init (it->paragraph_embedding,
4369 &it->bidi_it, 1);
4373 bidi_move_to_visually_next (&it->bidi_it);
4375 while (it->stop_charpos <= it->bidi_it.charpos
4376 && it->bidi_it.charpos < newpos);
4377 IT_CHARPOS (*it) = it->bidi_it.charpos;
4378 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
4379 /* If we overstepped NEWPOS, record its position in
4380 the iterator, so that we skip invisible text if
4381 later the bidi iteration lands us in the
4382 invisible region again. */
4383 if (IT_CHARPOS (*it) >= newpos)
4384 it->prev_stop = newpos;
4387 else
4389 IT_CHARPOS (*it) = newpos;
4390 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
4393 /* If there are before-strings at the start of invisible
4394 text, and the text is invisible because of a text
4395 property, arrange to show before-strings because 20.x did
4396 it that way. (If the text is invisible because of an
4397 overlay property instead of a text property, this is
4398 already handled in the overlay code.) */
4399 if (NILP (overlay)
4400 && get_overlay_strings (it, it->stop_charpos))
4402 handled = HANDLED_RECOMPUTE_PROPS;
4403 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
4405 else if (display_ellipsis_p)
4407 /* Make sure that the glyphs of the ellipsis will get
4408 correct `charpos' values. If we would not update
4409 it->position here, the glyphs would belong to the
4410 last visible character _before_ the invisible
4411 text, which confuses `set_cursor_from_row'.
4413 We use the last invisible position instead of the
4414 first because this way the cursor is always drawn on
4415 the first "." of the ellipsis, whenever PT is inside
4416 the invisible text. Otherwise the cursor would be
4417 placed _after_ the ellipsis when the point is after the
4418 first invisible character. */
4419 if (!STRINGP (it->object))
4421 it->position.charpos = newpos - 1;
4422 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
4424 it->ellipsis_p = 1;
4425 /* Let the ellipsis display before
4426 considering any properties of the following char.
4427 Fixes jasonr@gnu.org 01 Oct 07 bug. */
4428 handled = HANDLED_RETURN;
4433 return handled;
4437 /* Make iterator IT return `...' next.
4438 Replaces LEN characters from buffer. */
4440 static void
4441 setup_for_ellipsis (struct it *it, int len)
4443 /* Use the display table definition for `...'. Invalid glyphs
4444 will be handled by the method returning elements from dpvec. */
4445 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
4447 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
4448 it->dpvec = v->contents;
4449 it->dpend = v->contents + v->header.size;
4451 else
4453 /* Default `...'. */
4454 it->dpvec = default_invis_vector;
4455 it->dpend = default_invis_vector + 3;
4458 it->dpvec_char_len = len;
4459 it->current.dpvec_index = 0;
4460 it->dpvec_face_id = -1;
4462 /* Remember the current face id in case glyphs specify faces.
4463 IT's face is restored in set_iterator_to_next.
4464 saved_face_id was set to preceding char's face in handle_stop. */
4465 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
4466 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
4468 it->method = GET_FROM_DISPLAY_VECTOR;
4469 it->ellipsis_p = 1;
4474 /***********************************************************************
4475 'display' property
4476 ***********************************************************************/
4478 /* Set up iterator IT from `display' property at its current position.
4479 Called from handle_stop.
4480 We return HANDLED_RETURN if some part of the display property
4481 overrides the display of the buffer text itself.
4482 Otherwise we return HANDLED_NORMALLY. */
4484 static enum prop_handled
4485 handle_display_prop (struct it *it)
4487 Lisp_Object propval, object, overlay;
4488 struct text_pos *position;
4489 ptrdiff_t bufpos;
4490 /* Nonzero if some property replaces the display of the text itself. */
4491 int display_replaced_p = 0;
4493 if (STRINGP (it->string))
4495 object = it->string;
4496 position = &it->current.string_pos;
4497 bufpos = CHARPOS (it->current.pos);
4499 else
4501 XSETWINDOW (object, it->w);
4502 position = &it->current.pos;
4503 bufpos = CHARPOS (*position);
4506 /* Reset those iterator values set from display property values. */
4507 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
4508 it->space_width = Qnil;
4509 it->font_height = Qnil;
4510 it->voffset = 0;
4512 /* We don't support recursive `display' properties, i.e. string
4513 values that have a string `display' property, that have a string
4514 `display' property etc. */
4515 if (!it->string_from_display_prop_p)
4516 it->area = TEXT_AREA;
4518 propval = get_char_property_and_overlay (make_number (position->charpos),
4519 Qdisplay, object, &overlay);
4520 if (NILP (propval))
4521 return HANDLED_NORMALLY;
4522 /* Now OVERLAY is the overlay that gave us this property, or nil
4523 if it was a text property. */
4525 if (!STRINGP (it->string))
4526 object = it->w->contents;
4528 display_replaced_p = handle_display_spec (it, propval, object, overlay,
4529 position, bufpos,
4530 FRAME_WINDOW_P (it->f));
4532 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
4535 /* Subroutine of handle_display_prop. Returns non-zero if the display
4536 specification in SPEC is a replacing specification, i.e. it would
4537 replace the text covered by `display' property with something else,
4538 such as an image or a display string. If SPEC includes any kind or
4539 `(space ...) specification, the value is 2; this is used by
4540 compute_display_string_pos, which see.
4542 See handle_single_display_spec for documentation of arguments.
4543 frame_window_p is non-zero if the window being redisplayed is on a
4544 GUI frame; this argument is used only if IT is NULL, see below.
4546 IT can be NULL, if this is called by the bidi reordering code
4547 through compute_display_string_pos, which see. In that case, this
4548 function only examines SPEC, but does not otherwise "handle" it, in
4549 the sense that it doesn't set up members of IT from the display
4550 spec. */
4551 static int
4552 handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4553 Lisp_Object overlay, struct text_pos *position,
4554 ptrdiff_t bufpos, int frame_window_p)
4556 int replacing_p = 0;
4557 int rv;
4559 if (CONSP (spec)
4560 /* Simple specifications. */
4561 && !EQ (XCAR (spec), Qimage)
4562 && !EQ (XCAR (spec), Qspace)
4563 && !EQ (XCAR (spec), Qwhen)
4564 && !EQ (XCAR (spec), Qslice)
4565 && !EQ (XCAR (spec), Qspace_width)
4566 && !EQ (XCAR (spec), Qheight)
4567 && !EQ (XCAR (spec), Qraise)
4568 /* Marginal area specifications. */
4569 && !(CONSP (XCAR (spec)) && EQ (XCAR (XCAR (spec)), Qmargin))
4570 && !EQ (XCAR (spec), Qleft_fringe)
4571 && !EQ (XCAR (spec), Qright_fringe)
4572 && !NILP (XCAR (spec)))
4574 for (; CONSP (spec); spec = XCDR (spec))
4576 if ((rv = handle_single_display_spec (it, XCAR (spec), object,
4577 overlay, position, bufpos,
4578 replacing_p, frame_window_p)))
4580 replacing_p = rv;
4581 /* If some text in a string is replaced, `position' no
4582 longer points to the position of `object'. */
4583 if (!it || STRINGP (object))
4584 break;
4588 else if (VECTORP (spec))
4590 ptrdiff_t i;
4591 for (i = 0; i < ASIZE (spec); ++i)
4592 if ((rv = handle_single_display_spec (it, AREF (spec, i), object,
4593 overlay, position, bufpos,
4594 replacing_p, frame_window_p)))
4596 replacing_p = rv;
4597 /* If some text in a string is replaced, `position' no
4598 longer points to the position of `object'. */
4599 if (!it || STRINGP (object))
4600 break;
4603 else
4605 if ((rv = handle_single_display_spec (it, spec, object, overlay,
4606 position, bufpos, 0,
4607 frame_window_p)))
4608 replacing_p = rv;
4611 return replacing_p;
4614 /* Value is the position of the end of the `display' property starting
4615 at START_POS in OBJECT. */
4617 static struct text_pos
4618 display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
4620 Lisp_Object end;
4621 struct text_pos end_pos;
4623 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
4624 Qdisplay, object, Qnil);
4625 CHARPOS (end_pos) = XFASTINT (end);
4626 if (STRINGP (object))
4627 compute_string_pos (&end_pos, start_pos, it->string);
4628 else
4629 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
4631 return end_pos;
4635 /* Set up IT from a single `display' property specification SPEC. OBJECT
4636 is the object in which the `display' property was found. *POSITION
4637 is the position in OBJECT at which the `display' property was found.
4638 BUFPOS is the buffer position of OBJECT (different from POSITION if
4639 OBJECT is not a buffer). DISPLAY_REPLACED_P non-zero means that we
4640 previously saw a display specification which already replaced text
4641 display with something else, for example an image; we ignore such
4642 properties after the first one has been processed.
4644 OVERLAY is the overlay this `display' property came from,
4645 or nil if it was a text property.
4647 If SPEC is a `space' or `image' specification, and in some other
4648 cases too, set *POSITION to the position where the `display'
4649 property ends.
4651 If IT is NULL, only examine the property specification in SPEC, but
4652 don't set up IT. In that case, FRAME_WINDOW_P non-zero means SPEC
4653 is intended to be displayed in a window on a GUI frame.
4655 Value is non-zero if something was found which replaces the display
4656 of buffer or string text. */
4658 static int
4659 handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4660 Lisp_Object overlay, struct text_pos *position,
4661 ptrdiff_t bufpos, int display_replaced_p,
4662 int frame_window_p)
4664 Lisp_Object form;
4665 Lisp_Object location, value;
4666 struct text_pos start_pos = *position;
4667 int valid_p;
4669 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4670 If the result is non-nil, use VALUE instead of SPEC. */
4671 form = Qt;
4672 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
4674 spec = XCDR (spec);
4675 if (!CONSP (spec))
4676 return 0;
4677 form = XCAR (spec);
4678 spec = XCDR (spec);
4681 if (!NILP (form) && !EQ (form, Qt))
4683 ptrdiff_t count = SPECPDL_INDEX ();
4684 struct gcpro gcpro1;
4686 /* Bind `object' to the object having the `display' property, a
4687 buffer or string. Bind `position' to the position in the
4688 object where the property was found, and `buffer-position'
4689 to the current position in the buffer. */
4691 if (NILP (object))
4692 XSETBUFFER (object, current_buffer);
4693 specbind (Qobject, object);
4694 specbind (Qposition, make_number (CHARPOS (*position)));
4695 specbind (Qbuffer_position, make_number (bufpos));
4696 GCPRO1 (form);
4697 form = safe_eval (form);
4698 UNGCPRO;
4699 unbind_to (count, Qnil);
4702 if (NILP (form))
4703 return 0;
4705 /* Handle `(height HEIGHT)' specifications. */
4706 if (CONSP (spec)
4707 && EQ (XCAR (spec), Qheight)
4708 && CONSP (XCDR (spec)))
4710 if (it)
4712 if (!FRAME_WINDOW_P (it->f))
4713 return 0;
4715 it->font_height = XCAR (XCDR (spec));
4716 if (!NILP (it->font_height))
4718 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4719 int new_height = -1;
4721 if (CONSP (it->font_height)
4722 && (EQ (XCAR (it->font_height), Qplus)
4723 || EQ (XCAR (it->font_height), Qminus))
4724 && CONSP (XCDR (it->font_height))
4725 && RANGED_INTEGERP (0, XCAR (XCDR (it->font_height)), INT_MAX))
4727 /* `(+ N)' or `(- N)' where N is an integer. */
4728 int steps = XINT (XCAR (XCDR (it->font_height)));
4729 if (EQ (XCAR (it->font_height), Qplus))
4730 steps = - steps;
4731 it->face_id = smaller_face (it->f, it->face_id, steps);
4733 else if (FUNCTIONP (it->font_height))
4735 /* Call function with current height as argument.
4736 Value is the new height. */
4737 Lisp_Object height;
4738 height = safe_call1 (it->font_height,
4739 face->lface[LFACE_HEIGHT_INDEX]);
4740 if (NUMBERP (height))
4741 new_height = XFLOATINT (height);
4743 else if (NUMBERP (it->font_height))
4745 /* Value is a multiple of the canonical char height. */
4746 struct face *f;
4748 f = FACE_FROM_ID (it->f,
4749 lookup_basic_face (it->f, DEFAULT_FACE_ID));
4750 new_height = (XFLOATINT (it->font_height)
4751 * XINT (f->lface[LFACE_HEIGHT_INDEX]));
4753 else
4755 /* Evaluate IT->font_height with `height' bound to the
4756 current specified height to get the new height. */
4757 ptrdiff_t count = SPECPDL_INDEX ();
4759 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
4760 value = safe_eval (it->font_height);
4761 unbind_to (count, Qnil);
4763 if (NUMBERP (value))
4764 new_height = XFLOATINT (value);
4767 if (new_height > 0)
4768 it->face_id = face_with_height (it->f, it->face_id, new_height);
4772 return 0;
4775 /* Handle `(space-width WIDTH)'. */
4776 if (CONSP (spec)
4777 && EQ (XCAR (spec), Qspace_width)
4778 && CONSP (XCDR (spec)))
4780 if (it)
4782 if (!FRAME_WINDOW_P (it->f))
4783 return 0;
4785 value = XCAR (XCDR (spec));
4786 if (NUMBERP (value) && XFLOATINT (value) > 0)
4787 it->space_width = value;
4790 return 0;
4793 /* Handle `(slice X Y WIDTH HEIGHT)'. */
4794 if (CONSP (spec)
4795 && EQ (XCAR (spec), Qslice))
4797 Lisp_Object tem;
4799 if (it)
4801 if (!FRAME_WINDOW_P (it->f))
4802 return 0;
4804 if (tem = XCDR (spec), CONSP (tem))
4806 it->slice.x = XCAR (tem);
4807 if (tem = XCDR (tem), CONSP (tem))
4809 it->slice.y = XCAR (tem);
4810 if (tem = XCDR (tem), CONSP (tem))
4812 it->slice.width = XCAR (tem);
4813 if (tem = XCDR (tem), CONSP (tem))
4814 it->slice.height = XCAR (tem);
4820 return 0;
4823 /* Handle `(raise FACTOR)'. */
4824 if (CONSP (spec)
4825 && EQ (XCAR (spec), Qraise)
4826 && CONSP (XCDR (spec)))
4828 if (it)
4830 if (!FRAME_WINDOW_P (it->f))
4831 return 0;
4833 #ifdef HAVE_WINDOW_SYSTEM
4834 value = XCAR (XCDR (spec));
4835 if (NUMBERP (value))
4837 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4838 it->voffset = - (XFLOATINT (value)
4839 * (FONT_HEIGHT (face->font)));
4841 #endif /* HAVE_WINDOW_SYSTEM */
4844 return 0;
4847 /* Don't handle the other kinds of display specifications
4848 inside a string that we got from a `display' property. */
4849 if (it && it->string_from_display_prop_p)
4850 return 0;
4852 /* Characters having this form of property are not displayed, so
4853 we have to find the end of the property. */
4854 if (it)
4856 start_pos = *position;
4857 *position = display_prop_end (it, object, start_pos);
4859 value = Qnil;
4861 /* Stop the scan at that end position--we assume that all
4862 text properties change there. */
4863 if (it)
4864 it->stop_charpos = position->charpos;
4866 /* Handle `(left-fringe BITMAP [FACE])'
4867 and `(right-fringe BITMAP [FACE])'. */
4868 if (CONSP (spec)
4869 && (EQ (XCAR (spec), Qleft_fringe)
4870 || EQ (XCAR (spec), Qright_fringe))
4871 && CONSP (XCDR (spec)))
4873 int fringe_bitmap;
4875 if (it)
4877 if (!FRAME_WINDOW_P (it->f))
4878 /* If we return here, POSITION has been advanced
4879 across the text with this property. */
4881 /* Synchronize the bidi iterator with POSITION. This is
4882 needed because we are not going to push the iterator
4883 on behalf of this display property, so there will be
4884 no pop_it call to do this synchronization for us. */
4885 if (it->bidi_p)
4887 it->position = *position;
4888 iterate_out_of_display_property (it);
4889 *position = it->position;
4891 return 1;
4894 else if (!frame_window_p)
4895 return 1;
4897 #ifdef HAVE_WINDOW_SYSTEM
4898 value = XCAR (XCDR (spec));
4899 if (!SYMBOLP (value)
4900 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
4901 /* If we return here, POSITION has been advanced
4902 across the text with this property. */
4904 if (it && it->bidi_p)
4906 it->position = *position;
4907 iterate_out_of_display_property (it);
4908 *position = it->position;
4910 return 1;
4913 if (it)
4915 int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);;
4917 if (CONSP (XCDR (XCDR (spec))))
4919 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
4920 int face_id2 = lookup_derived_face (it->f, face_name,
4921 FRINGE_FACE_ID, 0);
4922 if (face_id2 >= 0)
4923 face_id = face_id2;
4926 /* Save current settings of IT so that we can restore them
4927 when we are finished with the glyph property value. */
4928 push_it (it, position);
4930 it->area = TEXT_AREA;
4931 it->what = IT_IMAGE;
4932 it->image_id = -1; /* no image */
4933 it->position = start_pos;
4934 it->object = NILP (object) ? it->w->contents : object;
4935 it->method = GET_FROM_IMAGE;
4936 it->from_overlay = Qnil;
4937 it->face_id = face_id;
4938 it->from_disp_prop_p = 1;
4940 /* Say that we haven't consumed the characters with
4941 `display' property yet. The call to pop_it in
4942 set_iterator_to_next will clean this up. */
4943 *position = start_pos;
4945 if (EQ (XCAR (spec), Qleft_fringe))
4947 it->left_user_fringe_bitmap = fringe_bitmap;
4948 it->left_user_fringe_face_id = face_id;
4950 else
4952 it->right_user_fringe_bitmap = fringe_bitmap;
4953 it->right_user_fringe_face_id = face_id;
4956 #endif /* HAVE_WINDOW_SYSTEM */
4957 return 1;
4960 /* Prepare to handle `((margin left-margin) ...)',
4961 `((margin right-margin) ...)' and `((margin nil) ...)'
4962 prefixes for display specifications. */
4963 location = Qunbound;
4964 if (CONSP (spec) && CONSP (XCAR (spec)))
4966 Lisp_Object tem;
4968 value = XCDR (spec);
4969 if (CONSP (value))
4970 value = XCAR (value);
4972 tem = XCAR (spec);
4973 if (EQ (XCAR (tem), Qmargin)
4974 && (tem = XCDR (tem),
4975 tem = CONSP (tem) ? XCAR (tem) : Qnil,
4976 (NILP (tem)
4977 || EQ (tem, Qleft_margin)
4978 || EQ (tem, Qright_margin))))
4979 location = tem;
4982 if (EQ (location, Qunbound))
4984 location = Qnil;
4985 value = spec;
4988 /* After this point, VALUE is the property after any
4989 margin prefix has been stripped. It must be a string,
4990 an image specification, or `(space ...)'.
4992 LOCATION specifies where to display: `left-margin',
4993 `right-margin' or nil. */
4995 valid_p = (STRINGP (value)
4996 #ifdef HAVE_WINDOW_SYSTEM
4997 || ((it ? FRAME_WINDOW_P (it->f) : frame_window_p)
4998 && valid_image_p (value))
4999 #endif /* not HAVE_WINDOW_SYSTEM */
5000 || (CONSP (value) && EQ (XCAR (value), Qspace)));
5002 if (valid_p && !display_replaced_p)
5004 int retval = 1;
5006 if (!it)
5008 /* Callers need to know whether the display spec is any kind
5009 of `(space ...)' spec that is about to affect text-area
5010 display. */
5011 if (CONSP (value) && EQ (XCAR (value), Qspace) && NILP (location))
5012 retval = 2;
5013 return retval;
5016 /* Save current settings of IT so that we can restore them
5017 when we are finished with the glyph property value. */
5018 push_it (it, position);
5019 it->from_overlay = overlay;
5020 it->from_disp_prop_p = 1;
5022 if (NILP (location))
5023 it->area = TEXT_AREA;
5024 else if (EQ (location, Qleft_margin))
5025 it->area = LEFT_MARGIN_AREA;
5026 else
5027 it->area = RIGHT_MARGIN_AREA;
5029 if (STRINGP (value))
5031 it->string = value;
5032 it->multibyte_p = STRING_MULTIBYTE (it->string);
5033 it->current.overlay_string_index = -1;
5034 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5035 it->end_charpos = it->string_nchars = SCHARS (it->string);
5036 it->method = GET_FROM_STRING;
5037 it->stop_charpos = 0;
5038 it->prev_stop = 0;
5039 it->base_level_stop = 0;
5040 it->string_from_display_prop_p = 1;
5041 /* Say that we haven't consumed the characters with
5042 `display' property yet. The call to pop_it in
5043 set_iterator_to_next will clean this up. */
5044 if (BUFFERP (object))
5045 *position = start_pos;
5047 /* Force paragraph direction to be that of the parent
5048 object. If the parent object's paragraph direction is
5049 not yet determined, default to L2R. */
5050 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
5051 it->paragraph_embedding = it->bidi_it.paragraph_dir;
5052 else
5053 it->paragraph_embedding = L2R;
5055 /* Set up the bidi iterator for this display string. */
5056 if (it->bidi_p)
5058 it->bidi_it.string.lstring = it->string;
5059 it->bidi_it.string.s = NULL;
5060 it->bidi_it.string.schars = it->end_charpos;
5061 it->bidi_it.string.bufpos = bufpos;
5062 it->bidi_it.string.from_disp_str = 1;
5063 it->bidi_it.string.unibyte = !it->multibyte_p;
5064 it->bidi_it.w = it->w;
5065 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5068 else if (CONSP (value) && EQ (XCAR (value), Qspace))
5070 it->method = GET_FROM_STRETCH;
5071 it->object = value;
5072 *position = it->position = start_pos;
5073 retval = 1 + (it->area == TEXT_AREA);
5075 #ifdef HAVE_WINDOW_SYSTEM
5076 else
5078 it->what = IT_IMAGE;
5079 it->image_id = lookup_image (it->f, value);
5080 it->position = start_pos;
5081 it->object = NILP (object) ? it->w->contents : object;
5082 it->method = GET_FROM_IMAGE;
5084 /* Say that we haven't consumed the characters with
5085 `display' property yet. The call to pop_it in
5086 set_iterator_to_next will clean this up. */
5087 *position = start_pos;
5089 #endif /* HAVE_WINDOW_SYSTEM */
5091 return retval;
5094 /* Invalid property or property not supported. Restore
5095 POSITION to what it was before. */
5096 *position = start_pos;
5097 return 0;
5100 /* Check if PROP is a display property value whose text should be
5101 treated as intangible. OVERLAY is the overlay from which PROP
5102 came, or nil if it came from a text property. CHARPOS and BYTEPOS
5103 specify the buffer position covered by PROP. */
5106 display_prop_intangible_p (Lisp_Object prop, Lisp_Object overlay,
5107 ptrdiff_t charpos, ptrdiff_t bytepos)
5109 int frame_window_p = FRAME_WINDOW_P (XFRAME (selected_frame));
5110 struct text_pos position;
5112 SET_TEXT_POS (position, charpos, bytepos);
5113 return handle_display_spec (NULL, prop, Qnil, overlay,
5114 &position, charpos, frame_window_p);
5118 /* Return 1 if PROP is a display sub-property value containing STRING.
5120 Implementation note: this and the following function are really
5121 special cases of handle_display_spec and
5122 handle_single_display_spec, and should ideally use the same code.
5123 Until they do, these two pairs must be consistent and must be
5124 modified in sync. */
5126 static int
5127 single_display_spec_string_p (Lisp_Object prop, Lisp_Object string)
5129 if (EQ (string, prop))
5130 return 1;
5132 /* Skip over `when FORM'. */
5133 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
5135 prop = XCDR (prop);
5136 if (!CONSP (prop))
5137 return 0;
5138 /* Actually, the condition following `when' should be eval'ed,
5139 like handle_single_display_spec does, and we should return
5140 zero if it evaluates to nil. However, this function is
5141 called only when the buffer was already displayed and some
5142 glyph in the glyph matrix was found to come from a display
5143 string. Therefore, the condition was already evaluated, and
5144 the result was non-nil, otherwise the display string wouldn't
5145 have been displayed and we would have never been called for
5146 this property. Thus, we can skip the evaluation and assume
5147 its result is non-nil. */
5148 prop = XCDR (prop);
5151 if (CONSP (prop))
5152 /* Skip over `margin LOCATION'. */
5153 if (EQ (XCAR (prop), Qmargin))
5155 prop = XCDR (prop);
5156 if (!CONSP (prop))
5157 return 0;
5159 prop = XCDR (prop);
5160 if (!CONSP (prop))
5161 return 0;
5164 return EQ (prop, string) || (CONSP (prop) && EQ (XCAR (prop), string));
5168 /* Return 1 if STRING appears in the `display' property PROP. */
5170 static int
5171 display_prop_string_p (Lisp_Object prop, Lisp_Object string)
5173 if (CONSP (prop)
5174 && !EQ (XCAR (prop), Qwhen)
5175 && !(CONSP (XCAR (prop)) && EQ (Qmargin, XCAR (XCAR (prop)))))
5177 /* A list of sub-properties. */
5178 while (CONSP (prop))
5180 if (single_display_spec_string_p (XCAR (prop), string))
5181 return 1;
5182 prop = XCDR (prop);
5185 else if (VECTORP (prop))
5187 /* A vector of sub-properties. */
5188 ptrdiff_t i;
5189 for (i = 0; i < ASIZE (prop); ++i)
5190 if (single_display_spec_string_p (AREF (prop, i), string))
5191 return 1;
5193 else
5194 return single_display_spec_string_p (prop, string);
5196 return 0;
5199 /* Look for STRING in overlays and text properties in the current
5200 buffer, between character positions FROM and TO (excluding TO).
5201 BACK_P non-zero means look back (in this case, TO is supposed to be
5202 less than FROM).
5203 Value is the first character position where STRING was found, or
5204 zero if it wasn't found before hitting TO.
5206 This function may only use code that doesn't eval because it is
5207 called asynchronously from note_mouse_highlight. */
5209 static ptrdiff_t
5210 string_buffer_position_lim (Lisp_Object string,
5211 ptrdiff_t from, ptrdiff_t to, int back_p)
5213 Lisp_Object limit, prop, pos;
5214 int found = 0;
5216 pos = make_number (max (from, BEGV));
5218 if (!back_p) /* looking forward */
5220 limit = make_number (min (to, ZV));
5221 while (!found && !EQ (pos, limit))
5223 prop = Fget_char_property (pos, Qdisplay, Qnil);
5224 if (!NILP (prop) && display_prop_string_p (prop, string))
5225 found = 1;
5226 else
5227 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil,
5228 limit);
5231 else /* looking back */
5233 limit = make_number (max (to, BEGV));
5234 while (!found && !EQ (pos, limit))
5236 prop = Fget_char_property (pos, Qdisplay, Qnil);
5237 if (!NILP (prop) && display_prop_string_p (prop, string))
5238 found = 1;
5239 else
5240 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
5241 limit);
5245 return found ? XINT (pos) : 0;
5248 /* Determine which buffer position in current buffer STRING comes from.
5249 AROUND_CHARPOS is an approximate position where it could come from.
5250 Value is the buffer position or 0 if it couldn't be determined.
5252 This function is necessary because we don't record buffer positions
5253 in glyphs generated from strings (to keep struct glyph small).
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 (Lisp_Object string, ptrdiff_t around_charpos)
5260 const int MAX_DISTANCE = 1000;
5261 ptrdiff_t found = string_buffer_position_lim (string, around_charpos,
5262 around_charpos + MAX_DISTANCE,
5265 if (!found)
5266 found = string_buffer_position_lim (string, around_charpos,
5267 around_charpos - MAX_DISTANCE, 1);
5268 return found;
5273 /***********************************************************************
5274 `composition' property
5275 ***********************************************************************/
5277 /* Set up iterator IT from `composition' property at its current
5278 position. Called from handle_stop. */
5280 static enum prop_handled
5281 handle_composition_prop (struct it *it)
5283 Lisp_Object prop, string;
5284 ptrdiff_t pos, pos_byte, start, end;
5286 if (STRINGP (it->string))
5288 unsigned char *s;
5290 pos = IT_STRING_CHARPOS (*it);
5291 pos_byte = IT_STRING_BYTEPOS (*it);
5292 string = it->string;
5293 s = SDATA (string) + pos_byte;
5294 it->c = STRING_CHAR (s);
5296 else
5298 pos = IT_CHARPOS (*it);
5299 pos_byte = IT_BYTEPOS (*it);
5300 string = Qnil;
5301 it->c = FETCH_CHAR (pos_byte);
5304 /* If there's a valid composition and point is not inside of the
5305 composition (in the case that the composition is from the current
5306 buffer), draw a glyph composed from the composition components. */
5307 if (find_composition (pos, -1, &start, &end, &prop, string)
5308 && COMPOSITION_VALID_P (start, end, prop)
5309 && (STRINGP (it->string) || (PT <= start || PT >= end)))
5311 if (start < pos)
5312 /* As we can't handle this situation (perhaps font-lock added
5313 a new composition), we just return here hoping that next
5314 redisplay will detect this composition much earlier. */
5315 return HANDLED_NORMALLY;
5316 if (start != pos)
5318 if (STRINGP (it->string))
5319 pos_byte = string_char_to_byte (it->string, start);
5320 else
5321 pos_byte = CHAR_TO_BYTE (start);
5323 it->cmp_it.id = get_composition_id (start, pos_byte, end - start,
5324 prop, string);
5326 if (it->cmp_it.id >= 0)
5328 it->cmp_it.ch = -1;
5329 it->cmp_it.nchars = COMPOSITION_LENGTH (prop);
5330 it->cmp_it.nglyphs = -1;
5334 return HANDLED_NORMALLY;
5339 /***********************************************************************
5340 Overlay strings
5341 ***********************************************************************/
5343 /* The following structure is used to record overlay strings for
5344 later sorting in load_overlay_strings. */
5346 struct overlay_entry
5348 Lisp_Object overlay;
5349 Lisp_Object string;
5350 EMACS_INT priority;
5351 int after_string_p;
5355 /* Set up iterator IT from overlay strings at its current position.
5356 Called from handle_stop. */
5358 static enum prop_handled
5359 handle_overlay_change (struct it *it)
5361 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
5362 return HANDLED_RECOMPUTE_PROPS;
5363 else
5364 return HANDLED_NORMALLY;
5368 /* Set up the next overlay string for delivery by IT, if there is an
5369 overlay string to deliver. Called by set_iterator_to_next when the
5370 end of the current overlay string is reached. If there are more
5371 overlay strings to display, IT->string and
5372 IT->current.overlay_string_index are set appropriately here.
5373 Otherwise IT->string is set to nil. */
5375 static void
5376 next_overlay_string (struct it *it)
5378 ++it->current.overlay_string_index;
5379 if (it->current.overlay_string_index == it->n_overlay_strings)
5381 /* No more overlay strings. Restore IT's settings to what
5382 they were before overlay strings were processed, and
5383 continue to deliver from current_buffer. */
5385 it->ellipsis_p = (it->stack[it->sp - 1].display_ellipsis_p != 0);
5386 pop_it (it);
5387 eassert (it->sp > 0
5388 || (NILP (it->string)
5389 && it->method == GET_FROM_BUFFER
5390 && it->stop_charpos >= BEGV
5391 && it->stop_charpos <= it->end_charpos));
5392 it->current.overlay_string_index = -1;
5393 it->n_overlay_strings = 0;
5394 it->overlay_strings_charpos = -1;
5395 /* If there's an empty display string on the stack, pop the
5396 stack, to resync the bidi iterator with IT's position. Such
5397 empty strings are pushed onto the stack in
5398 get_overlay_strings_1. */
5399 if (it->sp > 0 && STRINGP (it->string) && !SCHARS (it->string))
5400 pop_it (it);
5402 /* If we're at the end of the buffer, record that we have
5403 processed the overlay strings there already, so that
5404 next_element_from_buffer doesn't try it again. */
5405 if (NILP (it->string) && IT_CHARPOS (*it) >= it->end_charpos)
5406 it->overlay_strings_at_end_processed_p = 1;
5408 else
5410 /* There are more overlay strings to process. If
5411 IT->current.overlay_string_index has advanced to a position
5412 where we must load IT->overlay_strings with more strings, do
5413 it. We must load at the IT->overlay_strings_charpos where
5414 IT->n_overlay_strings was originally computed; when invisible
5415 text is present, this might not be IT_CHARPOS (Bug#7016). */
5416 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
5418 if (it->current.overlay_string_index && i == 0)
5419 load_overlay_strings (it, it->overlay_strings_charpos);
5421 /* Initialize IT to deliver display elements from the overlay
5422 string. */
5423 it->string = it->overlay_strings[i];
5424 it->multibyte_p = STRING_MULTIBYTE (it->string);
5425 SET_TEXT_POS (it->current.string_pos, 0, 0);
5426 it->method = GET_FROM_STRING;
5427 it->stop_charpos = 0;
5428 it->end_charpos = SCHARS (it->string);
5429 if (it->cmp_it.stop_pos >= 0)
5430 it->cmp_it.stop_pos = 0;
5431 it->prev_stop = 0;
5432 it->base_level_stop = 0;
5434 /* Set up the bidi iterator for this overlay string. */
5435 if (it->bidi_p)
5437 it->bidi_it.string.lstring = it->string;
5438 it->bidi_it.string.s = NULL;
5439 it->bidi_it.string.schars = SCHARS (it->string);
5440 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
5441 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5442 it->bidi_it.string.unibyte = !it->multibyte_p;
5443 it->bidi_it.w = it->w;
5444 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5448 CHECK_IT (it);
5452 /* Compare two overlay_entry structures E1 and E2. Used as a
5453 comparison function for qsort in load_overlay_strings. Overlay
5454 strings for the same position are sorted so that
5456 1. All after-strings come in front of before-strings, except
5457 when they come from the same overlay.
5459 2. Within after-strings, strings are sorted so that overlay strings
5460 from overlays with higher priorities come first.
5462 2. Within before-strings, strings are sorted so that overlay
5463 strings from overlays with higher priorities come last.
5465 Value is analogous to strcmp. */
5468 static int
5469 compare_overlay_entries (const void *e1, const void *e2)
5471 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
5472 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
5473 int result;
5475 if (entry1->after_string_p != entry2->after_string_p)
5477 /* Let after-strings appear in front of before-strings if
5478 they come from different overlays. */
5479 if (EQ (entry1->overlay, entry2->overlay))
5480 result = entry1->after_string_p ? 1 : -1;
5481 else
5482 result = entry1->after_string_p ? -1 : 1;
5484 else if (entry1->priority != entry2->priority)
5486 if (entry1->after_string_p)
5487 /* After-strings sorted in order of decreasing priority. */
5488 result = entry2->priority < entry1->priority ? -1 : 1;
5489 else
5490 /* Before-strings sorted in order of increasing priority. */
5491 result = entry1->priority < entry2->priority ? -1 : 1;
5493 else
5494 result = 0;
5496 return result;
5500 /* Load the vector IT->overlay_strings with overlay strings from IT's
5501 current buffer position, or from CHARPOS if that is > 0. Set
5502 IT->n_overlays to the total number of overlay strings found.
5504 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
5505 a time. On entry into load_overlay_strings,
5506 IT->current.overlay_string_index gives the number of overlay
5507 strings that have already been loaded by previous calls to this
5508 function.
5510 IT->add_overlay_start contains an additional overlay start
5511 position to consider for taking overlay strings from, if non-zero.
5512 This position comes into play when the overlay has an `invisible'
5513 property, and both before and after-strings. When we've skipped to
5514 the end of the overlay, because of its `invisible' property, we
5515 nevertheless want its before-string to appear.
5516 IT->add_overlay_start will contain the overlay start position
5517 in this case.
5519 Overlay strings are sorted so that after-string strings come in
5520 front of before-string strings. Within before and after-strings,
5521 strings are sorted by overlay priority. See also function
5522 compare_overlay_entries. */
5524 static void
5525 load_overlay_strings (struct it *it, ptrdiff_t charpos)
5527 Lisp_Object overlay, window, str, invisible;
5528 struct Lisp_Overlay *ov;
5529 ptrdiff_t start, end;
5530 ptrdiff_t size = 20;
5531 ptrdiff_t n = 0, i, j;
5532 int invis_p;
5533 struct overlay_entry *entries = alloca (size * sizeof *entries);
5534 USE_SAFE_ALLOCA;
5536 if (charpos <= 0)
5537 charpos = IT_CHARPOS (*it);
5539 /* Append the overlay string STRING of overlay OVERLAY to vector
5540 `entries' which has size `size' and currently contains `n'
5541 elements. AFTER_P non-zero means STRING is an after-string of
5542 OVERLAY. */
5543 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
5544 do \
5546 Lisp_Object priority; \
5548 if (n == size) \
5550 struct overlay_entry *old = entries; \
5551 SAFE_NALLOCA (entries, 2, size); \
5552 memcpy (entries, old, size * sizeof *entries); \
5553 size *= 2; \
5556 entries[n].string = (STRING); \
5557 entries[n].overlay = (OVERLAY); \
5558 priority = Foverlay_get ((OVERLAY), Qpriority); \
5559 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
5560 entries[n].after_string_p = (AFTER_P); \
5561 ++n; \
5563 while (0)
5565 /* Process overlay before the overlay center. */
5566 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
5568 XSETMISC (overlay, ov);
5569 eassert (OVERLAYP (overlay));
5570 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5571 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5573 if (end < charpos)
5574 break;
5576 /* Skip this overlay if it doesn't start or end at IT's current
5577 position. */
5578 if (end != charpos && start != charpos)
5579 continue;
5581 /* Skip this overlay if it doesn't apply to IT->w. */
5582 window = Foverlay_get (overlay, Qwindow);
5583 if (WINDOWP (window) && XWINDOW (window) != it->w)
5584 continue;
5586 /* If the text ``under'' the overlay is invisible, both before-
5587 and after-strings from this overlay are visible; start and
5588 end position are indistinguishable. */
5589 invisible = Foverlay_get (overlay, Qinvisible);
5590 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5592 /* If overlay has a non-empty before-string, record it. */
5593 if ((start == charpos || (end == charpos && invis_p))
5594 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5595 && SCHARS (str))
5596 RECORD_OVERLAY_STRING (overlay, str, 0);
5598 /* If overlay has a non-empty after-string, record it. */
5599 if ((end == charpos || (start == charpos && invis_p))
5600 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5601 && SCHARS (str))
5602 RECORD_OVERLAY_STRING (overlay, str, 1);
5605 /* Process overlays after the overlay center. */
5606 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
5608 XSETMISC (overlay, ov);
5609 eassert (OVERLAYP (overlay));
5610 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5611 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5613 if (start > charpos)
5614 break;
5616 /* Skip this overlay if it doesn't start or end at IT's current
5617 position. */
5618 if (end != charpos && start != charpos)
5619 continue;
5621 /* Skip this overlay if it doesn't apply to IT->w. */
5622 window = Foverlay_get (overlay, Qwindow);
5623 if (WINDOWP (window) && XWINDOW (window) != it->w)
5624 continue;
5626 /* If the text ``under'' the overlay is invisible, it has a zero
5627 dimension, and both before- and after-strings apply. */
5628 invisible = Foverlay_get (overlay, Qinvisible);
5629 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5631 /* If overlay has a non-empty before-string, record it. */
5632 if ((start == charpos || (end == charpos && invis_p))
5633 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5634 && SCHARS (str))
5635 RECORD_OVERLAY_STRING (overlay, str, 0);
5637 /* If overlay has a non-empty after-string, record it. */
5638 if ((end == charpos || (start == charpos && invis_p))
5639 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5640 && SCHARS (str))
5641 RECORD_OVERLAY_STRING (overlay, str, 1);
5644 #undef RECORD_OVERLAY_STRING
5646 /* Sort entries. */
5647 if (n > 1)
5648 qsort (entries, n, sizeof *entries, compare_overlay_entries);
5650 /* Record number of overlay strings, and where we computed it. */
5651 it->n_overlay_strings = n;
5652 it->overlay_strings_charpos = charpos;
5654 /* IT->current.overlay_string_index is the number of overlay strings
5655 that have already been consumed by IT. Copy some of the
5656 remaining overlay strings to IT->overlay_strings. */
5657 i = 0;
5658 j = it->current.overlay_string_index;
5659 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
5661 it->overlay_strings[i] = entries[j].string;
5662 it->string_overlays[i++] = entries[j++].overlay;
5665 CHECK_IT (it);
5666 SAFE_FREE ();
5670 /* Get the first chunk of overlay strings at IT's current buffer
5671 position, or at CHARPOS if that is > 0. Value is non-zero if at
5672 least one overlay string was found. */
5674 static int
5675 get_overlay_strings_1 (struct it *it, ptrdiff_t charpos, int compute_stop_p)
5677 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
5678 process. This fills IT->overlay_strings with strings, and sets
5679 IT->n_overlay_strings to the total number of strings to process.
5680 IT->pos.overlay_string_index has to be set temporarily to zero
5681 because load_overlay_strings needs this; it must be set to -1
5682 when no overlay strings are found because a zero value would
5683 indicate a position in the first overlay string. */
5684 it->current.overlay_string_index = 0;
5685 load_overlay_strings (it, charpos);
5687 /* If we found overlay strings, set up IT to deliver display
5688 elements from the first one. Otherwise set up IT to deliver
5689 from current_buffer. */
5690 if (it->n_overlay_strings)
5692 /* Make sure we know settings in current_buffer, so that we can
5693 restore meaningful values when we're done with the overlay
5694 strings. */
5695 if (compute_stop_p)
5696 compute_stop_pos (it);
5697 eassert (it->face_id >= 0);
5699 /* Save IT's settings. They are restored after all overlay
5700 strings have been processed. */
5701 eassert (!compute_stop_p || it->sp == 0);
5703 /* When called from handle_stop, there might be an empty display
5704 string loaded. In that case, don't bother saving it. But
5705 don't use this optimization with the bidi iterator, since we
5706 need the corresponding pop_it call to resync the bidi
5707 iterator's position with IT's position, after we are done
5708 with the overlay strings. (The corresponding call to pop_it
5709 in case of an empty display string is in
5710 next_overlay_string.) */
5711 if (!(!it->bidi_p
5712 && STRINGP (it->string) && !SCHARS (it->string)))
5713 push_it (it, NULL);
5715 /* Set up IT to deliver display elements from the first overlay
5716 string. */
5717 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5718 it->string = it->overlay_strings[0];
5719 it->from_overlay = Qnil;
5720 it->stop_charpos = 0;
5721 eassert (STRINGP (it->string));
5722 it->end_charpos = SCHARS (it->string);
5723 it->prev_stop = 0;
5724 it->base_level_stop = 0;
5725 it->multibyte_p = STRING_MULTIBYTE (it->string);
5726 it->method = GET_FROM_STRING;
5727 it->from_disp_prop_p = 0;
5729 /* Force paragraph direction to be that of the parent
5730 buffer. */
5731 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
5732 it->paragraph_embedding = it->bidi_it.paragraph_dir;
5733 else
5734 it->paragraph_embedding = L2R;
5736 /* Set up the bidi iterator for this overlay string. */
5737 if (it->bidi_p)
5739 ptrdiff_t pos = (charpos > 0 ? charpos : IT_CHARPOS (*it));
5741 it->bidi_it.string.lstring = it->string;
5742 it->bidi_it.string.s = NULL;
5743 it->bidi_it.string.schars = SCHARS (it->string);
5744 it->bidi_it.string.bufpos = pos;
5745 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5746 it->bidi_it.string.unibyte = !it->multibyte_p;
5747 it->bidi_it.w = it->w;
5748 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5750 return 1;
5753 it->current.overlay_string_index = -1;
5754 return 0;
5757 static int
5758 get_overlay_strings (struct it *it, ptrdiff_t charpos)
5760 it->string = Qnil;
5761 it->method = GET_FROM_BUFFER;
5763 (void) get_overlay_strings_1 (it, charpos, 1);
5765 CHECK_IT (it);
5767 /* Value is non-zero if we found at least one overlay string. */
5768 return STRINGP (it->string);
5773 /***********************************************************************
5774 Saving and restoring state
5775 ***********************************************************************/
5777 /* Save current settings of IT on IT->stack. Called, for example,
5778 before setting up IT for an overlay string, to be able to restore
5779 IT's settings to what they were after the overlay string has been
5780 processed. If POSITION is non-NULL, it is the position to save on
5781 the stack instead of IT->position. */
5783 static void
5784 push_it (struct it *it, struct text_pos *position)
5786 struct iterator_stack_entry *p;
5788 eassert (it->sp < IT_STACK_SIZE);
5789 p = it->stack + it->sp;
5791 p->stop_charpos = it->stop_charpos;
5792 p->prev_stop = it->prev_stop;
5793 p->base_level_stop = it->base_level_stop;
5794 p->cmp_it = it->cmp_it;
5795 eassert (it->face_id >= 0);
5796 p->face_id = it->face_id;
5797 p->string = it->string;
5798 p->method = it->method;
5799 p->from_overlay = it->from_overlay;
5800 switch (p->method)
5802 case GET_FROM_IMAGE:
5803 p->u.image.object = it->object;
5804 p->u.image.image_id = it->image_id;
5805 p->u.image.slice = it->slice;
5806 break;
5807 case GET_FROM_STRETCH:
5808 p->u.stretch.object = it->object;
5809 break;
5811 p->position = position ? *position : it->position;
5812 p->current = it->current;
5813 p->end_charpos = it->end_charpos;
5814 p->string_nchars = it->string_nchars;
5815 p->area = it->area;
5816 p->multibyte_p = it->multibyte_p;
5817 p->avoid_cursor_p = it->avoid_cursor_p;
5818 p->space_width = it->space_width;
5819 p->font_height = it->font_height;
5820 p->voffset = it->voffset;
5821 p->string_from_display_prop_p = it->string_from_display_prop_p;
5822 p->string_from_prefix_prop_p = it->string_from_prefix_prop_p;
5823 p->display_ellipsis_p = 0;
5824 p->line_wrap = it->line_wrap;
5825 p->bidi_p = it->bidi_p;
5826 p->paragraph_embedding = it->paragraph_embedding;
5827 p->from_disp_prop_p = it->from_disp_prop_p;
5828 ++it->sp;
5830 /* Save the state of the bidi iterator as well. */
5831 if (it->bidi_p)
5832 bidi_push_it (&it->bidi_it);
5835 static void
5836 iterate_out_of_display_property (struct it *it)
5838 int buffer_p = !STRINGP (it->string);
5839 ptrdiff_t eob = (buffer_p ? ZV : it->end_charpos);
5840 ptrdiff_t bob = (buffer_p ? BEGV : 0);
5842 eassert (eob >= CHARPOS (it->position) && CHARPOS (it->position) >= bob);
5844 /* Maybe initialize paragraph direction. If we are at the beginning
5845 of a new paragraph, next_element_from_buffer may not have a
5846 chance to do that. */
5847 if (it->bidi_it.first_elt && it->bidi_it.charpos < eob)
5848 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
5849 /* prev_stop can be zero, so check against BEGV as well. */
5850 while (it->bidi_it.charpos >= bob
5851 && it->prev_stop <= it->bidi_it.charpos
5852 && it->bidi_it.charpos < CHARPOS (it->position)
5853 && it->bidi_it.charpos < eob)
5854 bidi_move_to_visually_next (&it->bidi_it);
5855 /* Record the stop_pos we just crossed, for when we cross it
5856 back, maybe. */
5857 if (it->bidi_it.charpos > CHARPOS (it->position))
5858 it->prev_stop = CHARPOS (it->position);
5859 /* If we ended up not where pop_it put us, resync IT's
5860 positional members with the bidi iterator. */
5861 if (it->bidi_it.charpos != CHARPOS (it->position))
5862 SET_TEXT_POS (it->position, it->bidi_it.charpos, it->bidi_it.bytepos);
5863 if (buffer_p)
5864 it->current.pos = it->position;
5865 else
5866 it->current.string_pos = it->position;
5869 /* Restore IT's settings from IT->stack. Called, for example, when no
5870 more overlay strings must be processed, and we return to delivering
5871 display elements from a buffer, or when the end of a string from a
5872 `display' property is reached and we return to delivering display
5873 elements from an overlay string, or from a buffer. */
5875 static void
5876 pop_it (struct it *it)
5878 struct iterator_stack_entry *p;
5879 int from_display_prop = it->from_disp_prop_p;
5881 eassert (it->sp > 0);
5882 --it->sp;
5883 p = it->stack + it->sp;
5884 it->stop_charpos = p->stop_charpos;
5885 it->prev_stop = p->prev_stop;
5886 it->base_level_stop = p->base_level_stop;
5887 it->cmp_it = p->cmp_it;
5888 it->face_id = p->face_id;
5889 it->current = p->current;
5890 it->position = p->position;
5891 it->string = p->string;
5892 it->from_overlay = p->from_overlay;
5893 if (NILP (it->string))
5894 SET_TEXT_POS (it->current.string_pos, -1, -1);
5895 it->method = p->method;
5896 switch (it->method)
5898 case GET_FROM_IMAGE:
5899 it->image_id = p->u.image.image_id;
5900 it->object = p->u.image.object;
5901 it->slice = p->u.image.slice;
5902 break;
5903 case GET_FROM_STRETCH:
5904 it->object = p->u.stretch.object;
5905 break;
5906 case GET_FROM_BUFFER:
5907 it->object = it->w->contents;
5908 break;
5909 case GET_FROM_STRING:
5910 it->object = it->string;
5911 break;
5912 case GET_FROM_DISPLAY_VECTOR:
5913 if (it->s)
5914 it->method = GET_FROM_C_STRING;
5915 else if (STRINGP (it->string))
5916 it->method = GET_FROM_STRING;
5917 else
5919 it->method = GET_FROM_BUFFER;
5920 it->object = it->w->contents;
5923 it->end_charpos = p->end_charpos;
5924 it->string_nchars = p->string_nchars;
5925 it->area = p->area;
5926 it->multibyte_p = p->multibyte_p;
5927 it->avoid_cursor_p = p->avoid_cursor_p;
5928 it->space_width = p->space_width;
5929 it->font_height = p->font_height;
5930 it->voffset = p->voffset;
5931 it->string_from_display_prop_p = p->string_from_display_prop_p;
5932 it->string_from_prefix_prop_p = p->string_from_prefix_prop_p;
5933 it->line_wrap = p->line_wrap;
5934 it->bidi_p = p->bidi_p;
5935 it->paragraph_embedding = p->paragraph_embedding;
5936 it->from_disp_prop_p = p->from_disp_prop_p;
5937 if (it->bidi_p)
5939 bidi_pop_it (&it->bidi_it);
5940 /* Bidi-iterate until we get out of the portion of text, if any,
5941 covered by a `display' text property or by an overlay with
5942 `display' property. (We cannot just jump there, because the
5943 internal coherency of the bidi iterator state can not be
5944 preserved across such jumps.) We also must determine the
5945 paragraph base direction if the overlay we just processed is
5946 at the beginning of a new paragraph. */
5947 if (from_display_prop
5948 && (it->method == GET_FROM_BUFFER || it->method == GET_FROM_STRING))
5949 iterate_out_of_display_property (it);
5951 eassert ((BUFFERP (it->object)
5952 && IT_CHARPOS (*it) == it->bidi_it.charpos
5953 && IT_BYTEPOS (*it) == it->bidi_it.bytepos)
5954 || (STRINGP (it->object)
5955 && IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
5956 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos)
5957 || (CONSP (it->object) && it->method == GET_FROM_STRETCH));
5963 /***********************************************************************
5964 Moving over lines
5965 ***********************************************************************/
5967 /* Set IT's current position to the previous line start. */
5969 static void
5970 back_to_previous_line_start (struct it *it)
5972 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
5974 DEC_BOTH (cp, bp);
5975 IT_CHARPOS (*it) = find_newline_no_quit (cp, bp, -1, &IT_BYTEPOS (*it));
5979 /* Move IT to the next line start.
5981 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
5982 we skipped over part of the text (as opposed to moving the iterator
5983 continuously over the text). Otherwise, don't change the value
5984 of *SKIPPED_P.
5986 If BIDI_IT_PREV is non-NULL, store into it the state of the bidi
5987 iterator on the newline, if it was found.
5989 Newlines may come from buffer text, overlay strings, or strings
5990 displayed via the `display' property. That's the reason we can't
5991 simply use find_newline_no_quit.
5993 Note that this function may not skip over invisible text that is so
5994 because of text properties and immediately follows a newline. If
5995 it would, function reseat_at_next_visible_line_start, when called
5996 from set_iterator_to_next, would effectively make invisible
5997 characters following a newline part of the wrong glyph row, which
5998 leads to wrong cursor motion. */
6000 static int
6001 forward_to_next_line_start (struct it *it, int *skipped_p,
6002 struct bidi_it *bidi_it_prev)
6004 ptrdiff_t old_selective;
6005 int newline_found_p, n;
6006 const int MAX_NEWLINE_DISTANCE = 500;
6008 /* If already on a newline, just consume it to avoid unintended
6009 skipping over invisible text below. */
6010 if (it->what == IT_CHARACTER
6011 && it->c == '\n'
6012 && CHARPOS (it->position) == IT_CHARPOS (*it))
6014 if (it->bidi_p && bidi_it_prev)
6015 *bidi_it_prev = it->bidi_it;
6016 set_iterator_to_next (it, 0);
6017 it->c = 0;
6018 return 1;
6021 /* Don't handle selective display in the following. It's (a)
6022 unnecessary because it's done by the caller, and (b) leads to an
6023 infinite recursion because next_element_from_ellipsis indirectly
6024 calls this function. */
6025 old_selective = it->selective;
6026 it->selective = 0;
6028 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
6029 from buffer text. */
6030 for (n = newline_found_p = 0;
6031 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
6032 n += STRINGP (it->string) ? 0 : 1)
6034 if (!get_next_display_element (it))
6035 return 0;
6036 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
6037 if (newline_found_p && it->bidi_p && bidi_it_prev)
6038 *bidi_it_prev = it->bidi_it;
6039 set_iterator_to_next (it, 0);
6042 /* If we didn't find a newline near enough, see if we can use a
6043 short-cut. */
6044 if (!newline_found_p)
6046 ptrdiff_t bytepos, start = IT_CHARPOS (*it);
6047 ptrdiff_t limit = find_newline_no_quit (start, IT_BYTEPOS (*it),
6048 1, &bytepos);
6049 Lisp_Object pos;
6051 eassert (!STRINGP (it->string));
6053 /* If there isn't any `display' property in sight, and no
6054 overlays, we can just use the position of the newline in
6055 buffer text. */
6056 if (it->stop_charpos >= limit
6057 || ((pos = Fnext_single_property_change (make_number (start),
6058 Qdisplay, Qnil,
6059 make_number (limit)),
6060 NILP (pos))
6061 && next_overlay_change (start) == ZV))
6063 if (!it->bidi_p)
6065 IT_CHARPOS (*it) = limit;
6066 IT_BYTEPOS (*it) = bytepos;
6068 else
6070 struct bidi_it bprev;
6072 /* Help bidi.c avoid expensive searches for display
6073 properties and overlays, by telling it that there are
6074 none up to `limit'. */
6075 if (it->bidi_it.disp_pos < limit)
6077 it->bidi_it.disp_pos = limit;
6078 it->bidi_it.disp_prop = 0;
6080 do {
6081 bprev = it->bidi_it;
6082 bidi_move_to_visually_next (&it->bidi_it);
6083 } while (it->bidi_it.charpos != limit);
6084 IT_CHARPOS (*it) = limit;
6085 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6086 if (bidi_it_prev)
6087 *bidi_it_prev = bprev;
6089 *skipped_p = newline_found_p = 1;
6091 else
6093 while (get_next_display_element (it)
6094 && !newline_found_p)
6096 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
6097 if (newline_found_p && it->bidi_p && bidi_it_prev)
6098 *bidi_it_prev = it->bidi_it;
6099 set_iterator_to_next (it, 0);
6104 it->selective = old_selective;
6105 return newline_found_p;
6109 /* Set IT's current position to the previous visible line start. Skip
6110 invisible text that is so either due to text properties or due to
6111 selective display. Caution: this does not change IT->current_x and
6112 IT->hpos. */
6114 static void
6115 back_to_previous_visible_line_start (struct it *it)
6117 while (IT_CHARPOS (*it) > BEGV)
6119 back_to_previous_line_start (it);
6121 if (IT_CHARPOS (*it) <= BEGV)
6122 break;
6124 /* If selective > 0, then lines indented more than its value are
6125 invisible. */
6126 if (it->selective > 0
6127 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6128 it->selective))
6129 continue;
6131 /* Check the newline before point for invisibility. */
6133 Lisp_Object prop;
6134 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
6135 Qinvisible, it->window);
6136 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6137 continue;
6140 if (IT_CHARPOS (*it) <= BEGV)
6141 break;
6144 struct it it2;
6145 void *it2data = NULL;
6146 ptrdiff_t pos;
6147 ptrdiff_t beg, end;
6148 Lisp_Object val, overlay;
6150 SAVE_IT (it2, *it, it2data);
6152 /* If newline is part of a composition, continue from start of composition */
6153 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
6154 && beg < IT_CHARPOS (*it))
6155 goto replaced;
6157 /* If newline is replaced by a display property, find start of overlay
6158 or interval and continue search from that point. */
6159 pos = --IT_CHARPOS (it2);
6160 --IT_BYTEPOS (it2);
6161 it2.sp = 0;
6162 bidi_unshelve_cache (NULL, 0);
6163 it2.string_from_display_prop_p = 0;
6164 it2.from_disp_prop_p = 0;
6165 if (handle_display_prop (&it2) == HANDLED_RETURN
6166 && !NILP (val = get_char_property_and_overlay
6167 (make_number (pos), Qdisplay, Qnil, &overlay))
6168 && (OVERLAYP (overlay)
6169 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
6170 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
6172 RESTORE_IT (it, it, it2data);
6173 goto replaced;
6176 /* Newline is not replaced by anything -- so we are done. */
6177 RESTORE_IT (it, it, it2data);
6178 break;
6180 replaced:
6181 if (beg < BEGV)
6182 beg = BEGV;
6183 IT_CHARPOS (*it) = beg;
6184 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
6188 it->continuation_lines_width = 0;
6190 eassert (IT_CHARPOS (*it) >= BEGV);
6191 eassert (IT_CHARPOS (*it) == BEGV
6192 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6193 CHECK_IT (it);
6197 /* Reseat iterator IT at the previous visible line start. Skip
6198 invisible text that is so either due to text properties or due to
6199 selective display. At the end, update IT's overlay information,
6200 face information etc. */
6202 void
6203 reseat_at_previous_visible_line_start (struct it *it)
6205 back_to_previous_visible_line_start (it);
6206 reseat (it, it->current.pos, 1);
6207 CHECK_IT (it);
6211 /* Reseat iterator IT on the next visible line start in the current
6212 buffer. ON_NEWLINE_P non-zero means position IT on the newline
6213 preceding the line start. Skip over invisible text that is so
6214 because of selective display. Compute faces, overlays etc at the
6215 new position. Note that this function does not skip over text that
6216 is invisible because of text properties. */
6218 static void
6219 reseat_at_next_visible_line_start (struct it *it, int on_newline_p)
6221 int newline_found_p, skipped_p = 0;
6222 struct bidi_it bidi_it_prev;
6224 newline_found_p = forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6226 /* Skip over lines that are invisible because they are indented
6227 more than the value of IT->selective. */
6228 if (it->selective > 0)
6229 while (IT_CHARPOS (*it) < ZV
6230 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6231 it->selective))
6233 eassert (IT_BYTEPOS (*it) == BEGV
6234 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6235 newline_found_p =
6236 forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6239 /* Position on the newline if that's what's requested. */
6240 if (on_newline_p && newline_found_p)
6242 if (STRINGP (it->string))
6244 if (IT_STRING_CHARPOS (*it) > 0)
6246 if (!it->bidi_p)
6248 --IT_STRING_CHARPOS (*it);
6249 --IT_STRING_BYTEPOS (*it);
6251 else
6253 /* We need to restore the bidi iterator to the state
6254 it had on the newline, and resync the IT's
6255 position with that. */
6256 it->bidi_it = bidi_it_prev;
6257 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
6258 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
6262 else if (IT_CHARPOS (*it) > BEGV)
6264 if (!it->bidi_p)
6266 --IT_CHARPOS (*it);
6267 --IT_BYTEPOS (*it);
6269 else
6271 /* We need to restore the bidi iterator to the state it
6272 had on the newline and resync IT with that. */
6273 it->bidi_it = bidi_it_prev;
6274 IT_CHARPOS (*it) = it->bidi_it.charpos;
6275 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6277 reseat (it, it->current.pos, 0);
6280 else if (skipped_p)
6281 reseat (it, it->current.pos, 0);
6283 CHECK_IT (it);
6288 /***********************************************************************
6289 Changing an iterator's position
6290 ***********************************************************************/
6292 /* Change IT's current position to POS in current_buffer. If FORCE_P
6293 is non-zero, always check for text properties at the new position.
6294 Otherwise, text properties are only looked up if POS >=
6295 IT->check_charpos of a property. */
6297 static void
6298 reseat (struct it *it, struct text_pos pos, int force_p)
6300 ptrdiff_t original_pos = IT_CHARPOS (*it);
6302 reseat_1 (it, pos, 0);
6304 /* Determine where to check text properties. Avoid doing it
6305 where possible because text property lookup is very expensive. */
6306 if (force_p
6307 || CHARPOS (pos) > it->stop_charpos
6308 || CHARPOS (pos) < original_pos)
6310 if (it->bidi_p)
6312 /* For bidi iteration, we need to prime prev_stop and
6313 base_level_stop with our best estimations. */
6314 /* Implementation note: Of course, POS is not necessarily a
6315 stop position, so assigning prev_pos to it is a lie; we
6316 should have called compute_stop_backwards. However, if
6317 the current buffer does not include any R2L characters,
6318 that call would be a waste of cycles, because the
6319 iterator will never move back, and thus never cross this
6320 "fake" stop position. So we delay that backward search
6321 until the time we really need it, in next_element_from_buffer. */
6322 if (CHARPOS (pos) != it->prev_stop)
6323 it->prev_stop = CHARPOS (pos);
6324 if (CHARPOS (pos) < it->base_level_stop)
6325 it->base_level_stop = 0; /* meaning it's unknown */
6326 handle_stop (it);
6328 else
6330 handle_stop (it);
6331 it->prev_stop = it->base_level_stop = 0;
6336 CHECK_IT (it);
6340 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
6341 IT->stop_pos to POS, also. */
6343 static void
6344 reseat_1 (struct it *it, struct text_pos pos, int set_stop_p)
6346 /* Don't call this function when scanning a C string. */
6347 eassert (it->s == NULL);
6349 /* POS must be a reasonable value. */
6350 eassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
6352 it->current.pos = it->position = pos;
6353 it->end_charpos = ZV;
6354 it->dpvec = NULL;
6355 it->current.dpvec_index = -1;
6356 it->current.overlay_string_index = -1;
6357 IT_STRING_CHARPOS (*it) = -1;
6358 IT_STRING_BYTEPOS (*it) = -1;
6359 it->string = Qnil;
6360 it->method = GET_FROM_BUFFER;
6361 it->object = it->w->contents;
6362 it->area = TEXT_AREA;
6363 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
6364 it->sp = 0;
6365 it->string_from_display_prop_p = 0;
6366 it->string_from_prefix_prop_p = 0;
6368 it->from_disp_prop_p = 0;
6369 it->face_before_selective_p = 0;
6370 if (it->bidi_p)
6372 bidi_init_it (IT_CHARPOS (*it), IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6373 &it->bidi_it);
6374 bidi_unshelve_cache (NULL, 0);
6375 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6376 it->bidi_it.string.s = NULL;
6377 it->bidi_it.string.lstring = Qnil;
6378 it->bidi_it.string.bufpos = 0;
6379 it->bidi_it.string.unibyte = 0;
6380 it->bidi_it.w = it->w;
6383 if (set_stop_p)
6385 it->stop_charpos = CHARPOS (pos);
6386 it->base_level_stop = CHARPOS (pos);
6388 /* This make the information stored in it->cmp_it invalidate. */
6389 it->cmp_it.id = -1;
6393 /* Set up IT for displaying a string, starting at CHARPOS in window W.
6394 If S is non-null, it is a C string to iterate over. Otherwise,
6395 STRING gives a Lisp string to iterate over.
6397 If PRECISION > 0, don't return more then PRECISION number of
6398 characters from the string.
6400 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
6401 characters have been returned. FIELD_WIDTH < 0 means an infinite
6402 field width.
6404 MULTIBYTE = 0 means disable processing of multibyte characters,
6405 MULTIBYTE > 0 means enable it,
6406 MULTIBYTE < 0 means use IT->multibyte_p.
6408 IT must be initialized via a prior call to init_iterator before
6409 calling this function. */
6411 static void
6412 reseat_to_string (struct it *it, const char *s, Lisp_Object string,
6413 ptrdiff_t charpos, ptrdiff_t precision, int field_width,
6414 int multibyte)
6416 /* No region in strings. */
6417 it->region_beg_charpos = it->region_end_charpos = -1;
6419 /* No text property checks performed by default, but see below. */
6420 it->stop_charpos = -1;
6422 /* Set iterator position and end position. */
6423 memset (&it->current, 0, sizeof it->current);
6424 it->current.overlay_string_index = -1;
6425 it->current.dpvec_index = -1;
6426 eassert (charpos >= 0);
6428 /* If STRING is specified, use its multibyteness, otherwise use the
6429 setting of MULTIBYTE, if specified. */
6430 if (multibyte >= 0)
6431 it->multibyte_p = multibyte > 0;
6433 /* Bidirectional reordering of strings is controlled by the default
6434 value of bidi-display-reordering. Don't try to reorder while
6435 loading loadup.el, as the necessary character property tables are
6436 not yet available. */
6437 it->bidi_p =
6438 NILP (Vpurify_flag)
6439 && !NILP (BVAR (&buffer_defaults, bidi_display_reordering));
6441 if (s == NULL)
6443 eassert (STRINGP (string));
6444 it->string = string;
6445 it->s = NULL;
6446 it->end_charpos = it->string_nchars = SCHARS (string);
6447 it->method = GET_FROM_STRING;
6448 it->current.string_pos = string_pos (charpos, string);
6450 if (it->bidi_p)
6452 it->bidi_it.string.lstring = string;
6453 it->bidi_it.string.s = NULL;
6454 it->bidi_it.string.schars = it->end_charpos;
6455 it->bidi_it.string.bufpos = 0;
6456 it->bidi_it.string.from_disp_str = 0;
6457 it->bidi_it.string.unibyte = !it->multibyte_p;
6458 it->bidi_it.w = it->w;
6459 bidi_init_it (charpos, IT_STRING_BYTEPOS (*it),
6460 FRAME_WINDOW_P (it->f), &it->bidi_it);
6463 else
6465 it->s = (const unsigned char *) s;
6466 it->string = Qnil;
6468 /* Note that we use IT->current.pos, not it->current.string_pos,
6469 for displaying C strings. */
6470 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
6471 if (it->multibyte_p)
6473 it->current.pos = c_string_pos (charpos, s, 1);
6474 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
6476 else
6478 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
6479 it->end_charpos = it->string_nchars = strlen (s);
6482 if (it->bidi_p)
6484 it->bidi_it.string.lstring = Qnil;
6485 it->bidi_it.string.s = (const unsigned char *) s;
6486 it->bidi_it.string.schars = it->end_charpos;
6487 it->bidi_it.string.bufpos = 0;
6488 it->bidi_it.string.from_disp_str = 0;
6489 it->bidi_it.string.unibyte = !it->multibyte_p;
6490 it->bidi_it.w = it->w;
6491 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6492 &it->bidi_it);
6494 it->method = GET_FROM_C_STRING;
6497 /* PRECISION > 0 means don't return more than PRECISION characters
6498 from the string. */
6499 if (precision > 0 && it->end_charpos - charpos > precision)
6501 it->end_charpos = it->string_nchars = charpos + precision;
6502 if (it->bidi_p)
6503 it->bidi_it.string.schars = it->end_charpos;
6506 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
6507 characters have been returned. FIELD_WIDTH == 0 means don't pad,
6508 FIELD_WIDTH < 0 means infinite field width. This is useful for
6509 padding with `-' at the end of a mode line. */
6510 if (field_width < 0)
6511 field_width = INFINITY;
6512 /* Implementation note: We deliberately don't enlarge
6513 it->bidi_it.string.schars here to fit it->end_charpos, because
6514 the bidi iterator cannot produce characters out of thin air. */
6515 if (field_width > it->end_charpos - charpos)
6516 it->end_charpos = charpos + field_width;
6518 /* Use the standard display table for displaying strings. */
6519 if (DISP_TABLE_P (Vstandard_display_table))
6520 it->dp = XCHAR_TABLE (Vstandard_display_table);
6522 it->stop_charpos = charpos;
6523 it->prev_stop = charpos;
6524 it->base_level_stop = 0;
6525 if (it->bidi_p)
6527 it->bidi_it.first_elt = 1;
6528 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6529 it->bidi_it.disp_pos = -1;
6531 if (s == NULL && it->multibyte_p)
6533 ptrdiff_t endpos = SCHARS (it->string);
6534 if (endpos > it->end_charpos)
6535 endpos = it->end_charpos;
6536 composition_compute_stop_pos (&it->cmp_it, charpos, -1, endpos,
6537 it->string);
6539 CHECK_IT (it);
6544 /***********************************************************************
6545 Iteration
6546 ***********************************************************************/
6548 /* Map enum it_method value to corresponding next_element_from_* function. */
6550 static int (* get_next_element[NUM_IT_METHODS]) (struct it *it) =
6552 next_element_from_buffer,
6553 next_element_from_display_vector,
6554 next_element_from_string,
6555 next_element_from_c_string,
6556 next_element_from_image,
6557 next_element_from_stretch
6560 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
6563 /* Return 1 iff a character at CHARPOS (and BYTEPOS) is composed
6564 (possibly with the following characters). */
6566 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS) \
6567 ((IT)->cmp_it.id >= 0 \
6568 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
6569 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
6570 END_CHARPOS, (IT)->w, \
6571 FACE_FROM_ID ((IT)->f, (IT)->face_id), \
6572 (IT)->string)))
6575 /* Lookup the char-table Vglyphless_char_display for character C (-1
6576 if we want information for no-font case), and return the display
6577 method symbol. By side-effect, update it->what and
6578 it->glyphless_method. This function is called from
6579 get_next_display_element for each character element, and from
6580 x_produce_glyphs when no suitable font was found. */
6582 Lisp_Object
6583 lookup_glyphless_char_display (int c, struct it *it)
6585 Lisp_Object glyphless_method = Qnil;
6587 if (CHAR_TABLE_P (Vglyphless_char_display)
6588 && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display)) >= 1)
6590 if (c >= 0)
6592 glyphless_method = CHAR_TABLE_REF (Vglyphless_char_display, c);
6593 if (CONSP (glyphless_method))
6594 glyphless_method = FRAME_WINDOW_P (it->f)
6595 ? XCAR (glyphless_method)
6596 : XCDR (glyphless_method);
6598 else
6599 glyphless_method = XCHAR_TABLE (Vglyphless_char_display)->extras[0];
6602 retry:
6603 if (NILP (glyphless_method))
6605 if (c >= 0)
6606 /* The default is to display the character by a proper font. */
6607 return Qnil;
6608 /* The default for the no-font case is to display an empty box. */
6609 glyphless_method = Qempty_box;
6611 if (EQ (glyphless_method, Qzero_width))
6613 if (c >= 0)
6614 return glyphless_method;
6615 /* This method can't be used for the no-font case. */
6616 glyphless_method = Qempty_box;
6618 if (EQ (glyphless_method, Qthin_space))
6619 it->glyphless_method = GLYPHLESS_DISPLAY_THIN_SPACE;
6620 else if (EQ (glyphless_method, Qempty_box))
6621 it->glyphless_method = GLYPHLESS_DISPLAY_EMPTY_BOX;
6622 else if (EQ (glyphless_method, Qhex_code))
6623 it->glyphless_method = GLYPHLESS_DISPLAY_HEX_CODE;
6624 else if (STRINGP (glyphless_method))
6625 it->glyphless_method = GLYPHLESS_DISPLAY_ACRONYM;
6626 else
6628 /* Invalid value. We use the default method. */
6629 glyphless_method = Qnil;
6630 goto retry;
6632 it->what = IT_GLYPHLESS;
6633 return glyphless_method;
6636 /* Load IT's display element fields with information about the next
6637 display element from the current position of IT. Value is zero if
6638 end of buffer (or C string) is reached. */
6640 static struct frame *last_escape_glyph_frame = NULL;
6641 static int last_escape_glyph_face_id = (1 << FACE_ID_BITS);
6642 static int last_escape_glyph_merged_face_id = 0;
6644 struct frame *last_glyphless_glyph_frame = NULL;
6645 int last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
6646 int last_glyphless_glyph_merged_face_id = 0;
6648 static int
6649 get_next_display_element (struct it *it)
6651 /* Non-zero means that we found a display element. Zero means that
6652 we hit the end of what we iterate over. Performance note: the
6653 function pointer `method' used here turns out to be faster than
6654 using a sequence of if-statements. */
6655 int success_p;
6657 get_next:
6658 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
6660 if (it->what == IT_CHARACTER)
6662 /* UAX#9, L4: "A character is depicted by a mirrored glyph if
6663 and only if (a) the resolved directionality of that character
6664 is R..." */
6665 /* FIXME: Do we need an exception for characters from display
6666 tables? */
6667 if (it->bidi_p && it->bidi_it.type == STRONG_R)
6668 it->c = bidi_mirror_char (it->c);
6669 /* Map via display table or translate control characters.
6670 IT->c, IT->len etc. have been set to the next character by
6671 the function call above. If we have a display table, and it
6672 contains an entry for IT->c, translate it. Don't do this if
6673 IT->c itself comes from a display table, otherwise we could
6674 end up in an infinite recursion. (An alternative could be to
6675 count the recursion depth of this function and signal an
6676 error when a certain maximum depth is reached.) Is it worth
6677 it? */
6678 if (success_p && it->dpvec == NULL)
6680 Lisp_Object dv;
6681 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
6682 int nonascii_space_p = 0;
6683 int nonascii_hyphen_p = 0;
6684 int c = it->c; /* This is the character to display. */
6686 if (! it->multibyte_p && ! ASCII_CHAR_P (c))
6688 eassert (SINGLE_BYTE_CHAR_P (c));
6689 if (unibyte_display_via_language_environment)
6691 c = DECODE_CHAR (unibyte, c);
6692 if (c < 0)
6693 c = BYTE8_TO_CHAR (it->c);
6695 else
6696 c = BYTE8_TO_CHAR (it->c);
6699 if (it->dp
6700 && (dv = DISP_CHAR_VECTOR (it->dp, c),
6701 VECTORP (dv)))
6703 struct Lisp_Vector *v = XVECTOR (dv);
6705 /* Return the first character from the display table
6706 entry, if not empty. If empty, don't display the
6707 current character. */
6708 if (v->header.size)
6710 it->dpvec_char_len = it->len;
6711 it->dpvec = v->contents;
6712 it->dpend = v->contents + v->header.size;
6713 it->current.dpvec_index = 0;
6714 it->dpvec_face_id = -1;
6715 it->saved_face_id = it->face_id;
6716 it->method = GET_FROM_DISPLAY_VECTOR;
6717 it->ellipsis_p = 0;
6719 else
6721 set_iterator_to_next (it, 0);
6723 goto get_next;
6726 if (! NILP (lookup_glyphless_char_display (c, it)))
6728 if (it->what == IT_GLYPHLESS)
6729 goto done;
6730 /* Don't display this character. */
6731 set_iterator_to_next (it, 0);
6732 goto get_next;
6735 /* If `nobreak-char-display' is non-nil, we display
6736 non-ASCII spaces and hyphens specially. */
6737 if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
6739 if (c == 0xA0)
6740 nonascii_space_p = 1;
6741 else if (c == 0xAD || c == 0x2010 || c == 0x2011)
6742 nonascii_hyphen_p = 1;
6745 /* Translate control characters into `\003' or `^C' form.
6746 Control characters coming from a display table entry are
6747 currently not translated because we use IT->dpvec to hold
6748 the translation. This could easily be changed but I
6749 don't believe that it is worth doing.
6751 The characters handled by `nobreak-char-display' must be
6752 translated too.
6754 Non-printable characters and raw-byte characters are also
6755 translated to octal form. */
6756 if (((c < ' ' || c == 127) /* ASCII control chars */
6757 ? (it->area != TEXT_AREA
6758 /* In mode line, treat \n, \t like other crl chars. */
6759 || (c != '\t'
6760 && it->glyph_row
6761 && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
6762 || (c != '\n' && c != '\t'))
6763 : (nonascii_space_p
6764 || nonascii_hyphen_p
6765 || CHAR_BYTE8_P (c)
6766 || ! CHAR_PRINTABLE_P (c))))
6768 /* C is a control character, non-ASCII space/hyphen,
6769 raw-byte, or a non-printable character which must be
6770 displayed either as '\003' or as `^C' where the '\\'
6771 and '^' can be defined in the display table. Fill
6772 IT->ctl_chars with glyphs for what we have to
6773 display. Then, set IT->dpvec to these glyphs. */
6774 Lisp_Object gc;
6775 int ctl_len;
6776 int face_id;
6777 int lface_id = 0;
6778 int escape_glyph;
6780 /* Handle control characters with ^. */
6782 if (ASCII_CHAR_P (c) && it->ctl_arrow_p)
6784 int g;
6786 g = '^'; /* default glyph for Control */
6787 /* Set IT->ctl_chars[0] to the glyph for `^'. */
6788 if (it->dp
6789 && (gc = DISP_CTRL_GLYPH (it->dp), GLYPH_CODE_P (gc)))
6791 g = GLYPH_CODE_CHAR (gc);
6792 lface_id = GLYPH_CODE_FACE (gc);
6794 if (lface_id)
6796 face_id = merge_faces (it->f, Qt, lface_id, it->face_id);
6798 else if (it->f == last_escape_glyph_frame
6799 && it->face_id == last_escape_glyph_face_id)
6801 face_id = last_escape_glyph_merged_face_id;
6803 else
6805 /* Merge the escape-glyph face into the current face. */
6806 face_id = merge_faces (it->f, Qescape_glyph, 0,
6807 it->face_id);
6808 last_escape_glyph_frame = it->f;
6809 last_escape_glyph_face_id = it->face_id;
6810 last_escape_glyph_merged_face_id = face_id;
6813 XSETINT (it->ctl_chars[0], g);
6814 XSETINT (it->ctl_chars[1], c ^ 0100);
6815 ctl_len = 2;
6816 goto display_control;
6819 /* Handle non-ascii space in the mode where it only gets
6820 highlighting. */
6822 if (nonascii_space_p && EQ (Vnobreak_char_display, Qt))
6824 /* Merge `nobreak-space' into the current face. */
6825 face_id = merge_faces (it->f, Qnobreak_space, 0,
6826 it->face_id);
6827 XSETINT (it->ctl_chars[0], ' ');
6828 ctl_len = 1;
6829 goto display_control;
6832 /* Handle sequences that start with the "escape glyph". */
6834 /* the default escape glyph is \. */
6835 escape_glyph = '\\';
6837 if (it->dp
6838 && (gc = DISP_ESCAPE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
6840 escape_glyph = GLYPH_CODE_CHAR (gc);
6841 lface_id = GLYPH_CODE_FACE (gc);
6843 if (lface_id)
6845 /* The display table specified a face.
6846 Merge it into face_id and also into escape_glyph. */
6847 face_id = merge_faces (it->f, Qt, lface_id,
6848 it->face_id);
6850 else if (it->f == last_escape_glyph_frame
6851 && it->face_id == last_escape_glyph_face_id)
6853 face_id = last_escape_glyph_merged_face_id;
6855 else
6857 /* Merge the escape-glyph face into the current face. */
6858 face_id = merge_faces (it->f, Qescape_glyph, 0,
6859 it->face_id);
6860 last_escape_glyph_frame = it->f;
6861 last_escape_glyph_face_id = it->face_id;
6862 last_escape_glyph_merged_face_id = face_id;
6865 /* Draw non-ASCII hyphen with just highlighting: */
6867 if (nonascii_hyphen_p && EQ (Vnobreak_char_display, Qt))
6869 XSETINT (it->ctl_chars[0], '-');
6870 ctl_len = 1;
6871 goto display_control;
6874 /* Draw non-ASCII space/hyphen with escape glyph: */
6876 if (nonascii_space_p || nonascii_hyphen_p)
6878 XSETINT (it->ctl_chars[0], escape_glyph);
6879 XSETINT (it->ctl_chars[1], nonascii_space_p ? ' ' : '-');
6880 ctl_len = 2;
6881 goto display_control;
6885 char str[10];
6886 int len, i;
6888 if (CHAR_BYTE8_P (c))
6889 /* Display \200 instead of \17777600. */
6890 c = CHAR_TO_BYTE8 (c);
6891 len = sprintf (str, "%03o", c);
6893 XSETINT (it->ctl_chars[0], escape_glyph);
6894 for (i = 0; i < len; i++)
6895 XSETINT (it->ctl_chars[i + 1], str[i]);
6896 ctl_len = len + 1;
6899 display_control:
6900 /* Set up IT->dpvec and return first character from it. */
6901 it->dpvec_char_len = it->len;
6902 it->dpvec = it->ctl_chars;
6903 it->dpend = it->dpvec + ctl_len;
6904 it->current.dpvec_index = 0;
6905 it->dpvec_face_id = face_id;
6906 it->saved_face_id = it->face_id;
6907 it->method = GET_FROM_DISPLAY_VECTOR;
6908 it->ellipsis_p = 0;
6909 goto get_next;
6911 it->char_to_display = c;
6913 else if (success_p)
6915 it->char_to_display = it->c;
6919 /* Adjust face id for a multibyte character. There are no multibyte
6920 character in unibyte text. */
6921 if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
6922 && it->multibyte_p
6923 && success_p
6924 && FRAME_WINDOW_P (it->f))
6926 struct face *face = FACE_FROM_ID (it->f, it->face_id);
6928 if (it->what == IT_COMPOSITION && it->cmp_it.ch >= 0)
6930 /* Automatic composition with glyph-string. */
6931 Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id);
6933 it->face_id = face_for_font (it->f, LGSTRING_FONT (gstring), face);
6935 else
6937 ptrdiff_t pos = (it->s ? -1
6938 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
6939 : IT_CHARPOS (*it));
6940 int c;
6942 if (it->what == IT_CHARACTER)
6943 c = it->char_to_display;
6944 else
6946 struct composition *cmp = composition_table[it->cmp_it.id];
6947 int i;
6949 c = ' ';
6950 for (i = 0; i < cmp->glyph_len; i++)
6951 /* TAB in a composition means display glyphs with
6952 padding space on the left or right. */
6953 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
6954 break;
6956 it->face_id = FACE_FOR_CHAR (it->f, face, c, pos, it->string);
6960 done:
6961 /* Is this character the last one of a run of characters with
6962 box? If yes, set IT->end_of_box_run_p to 1. */
6963 if (it->face_box_p
6964 && it->s == NULL)
6966 if (it->method == GET_FROM_STRING && it->sp)
6968 int face_id = underlying_face_id (it);
6969 struct face *face = FACE_FROM_ID (it->f, face_id);
6971 if (face)
6973 if (face->box == FACE_NO_BOX)
6975 /* If the box comes from face properties in a
6976 display string, check faces in that string. */
6977 int string_face_id = face_after_it_pos (it);
6978 it->end_of_box_run_p
6979 = (FACE_FROM_ID (it->f, string_face_id)->box
6980 == FACE_NO_BOX);
6982 /* Otherwise, the box comes from the underlying face.
6983 If this is the last string character displayed, check
6984 the next buffer location. */
6985 else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1)
6986 && (it->current.overlay_string_index
6987 == it->n_overlay_strings - 1))
6989 ptrdiff_t ignore;
6990 int next_face_id;
6991 struct text_pos pos = it->current.pos;
6992 INC_TEXT_POS (pos, it->multibyte_p);
6994 next_face_id = face_at_buffer_position
6995 (it->w, CHARPOS (pos), it->region_beg_charpos,
6996 it->region_end_charpos, &ignore,
6997 (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT), 0,
6998 -1);
6999 it->end_of_box_run_p
7000 = (FACE_FROM_ID (it->f, next_face_id)->box
7001 == FACE_NO_BOX);
7005 else
7007 int face_id = face_after_it_pos (it);
7008 it->end_of_box_run_p
7009 = (face_id != it->face_id
7010 && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX);
7013 /* If we reached the end of the object we've been iterating (e.g., a
7014 display string or an overlay string), and there's something on
7015 IT->stack, proceed with what's on the stack. It doesn't make
7016 sense to return zero if there's unprocessed stuff on the stack,
7017 because otherwise that stuff will never be displayed. */
7018 if (!success_p && it->sp > 0)
7020 set_iterator_to_next (it, 0);
7021 success_p = get_next_display_element (it);
7024 /* Value is 0 if end of buffer or string reached. */
7025 return success_p;
7029 /* Move IT to the next display element.
7031 RESEAT_P non-zero means if called on a newline in buffer text,
7032 skip to the next visible line start.
7034 Functions get_next_display_element and set_iterator_to_next are
7035 separate because I find this arrangement easier to handle than a
7036 get_next_display_element function that also increments IT's
7037 position. The way it is we can first look at an iterator's current
7038 display element, decide whether it fits on a line, and if it does,
7039 increment the iterator position. The other way around we probably
7040 would either need a flag indicating whether the iterator has to be
7041 incremented the next time, or we would have to implement a
7042 decrement position function which would not be easy to write. */
7044 void
7045 set_iterator_to_next (struct it *it, int reseat_p)
7047 /* Reset flags indicating start and end of a sequence of characters
7048 with box. Reset them at the start of this function because
7049 moving the iterator to a new position might set them. */
7050 it->start_of_box_run_p = it->end_of_box_run_p = 0;
7052 switch (it->method)
7054 case GET_FROM_BUFFER:
7055 /* The current display element of IT is a character from
7056 current_buffer. Advance in the buffer, and maybe skip over
7057 invisible lines that are so because of selective display. */
7058 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
7059 reseat_at_next_visible_line_start (it, 0);
7060 else if (it->cmp_it.id >= 0)
7062 /* We are currently getting glyphs from a composition. */
7063 int i;
7065 if (! it->bidi_p)
7067 IT_CHARPOS (*it) += it->cmp_it.nchars;
7068 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
7069 if (it->cmp_it.to < it->cmp_it.nglyphs)
7071 it->cmp_it.from = it->cmp_it.to;
7073 else
7075 it->cmp_it.id = -1;
7076 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7077 IT_BYTEPOS (*it),
7078 it->end_charpos, Qnil);
7081 else if (! it->cmp_it.reversed_p)
7083 /* Composition created while scanning forward. */
7084 /* Update IT's char/byte positions to point to the first
7085 character of the next grapheme cluster, or to the
7086 character visually after the current composition. */
7087 for (i = 0; i < it->cmp_it.nchars; i++)
7088 bidi_move_to_visually_next (&it->bidi_it);
7089 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7090 IT_CHARPOS (*it) = it->bidi_it.charpos;
7092 if (it->cmp_it.to < it->cmp_it.nglyphs)
7094 /* Proceed to the next grapheme cluster. */
7095 it->cmp_it.from = it->cmp_it.to;
7097 else
7099 /* No more grapheme clusters in this composition.
7100 Find the next stop position. */
7101 ptrdiff_t stop = it->end_charpos;
7102 if (it->bidi_it.scan_dir < 0)
7103 /* Now we are scanning backward and don't know
7104 where to stop. */
7105 stop = -1;
7106 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7107 IT_BYTEPOS (*it), stop, Qnil);
7110 else
7112 /* Composition created while scanning backward. */
7113 /* Update IT's char/byte positions to point to the last
7114 character of the previous grapheme cluster, or the
7115 character visually after the current composition. */
7116 for (i = 0; i < it->cmp_it.nchars; i++)
7117 bidi_move_to_visually_next (&it->bidi_it);
7118 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7119 IT_CHARPOS (*it) = it->bidi_it.charpos;
7120 if (it->cmp_it.from > 0)
7122 /* Proceed to the previous grapheme cluster. */
7123 it->cmp_it.to = it->cmp_it.from;
7125 else
7127 /* No more grapheme clusters in this composition.
7128 Find the next stop position. */
7129 ptrdiff_t stop = it->end_charpos;
7130 if (it->bidi_it.scan_dir < 0)
7131 /* Now we are scanning backward and don't know
7132 where to stop. */
7133 stop = -1;
7134 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7135 IT_BYTEPOS (*it), stop, Qnil);
7139 else
7141 eassert (it->len != 0);
7143 if (!it->bidi_p)
7145 IT_BYTEPOS (*it) += it->len;
7146 IT_CHARPOS (*it) += 1;
7148 else
7150 int prev_scan_dir = it->bidi_it.scan_dir;
7151 /* If this is a new paragraph, determine its base
7152 direction (a.k.a. its base embedding level). */
7153 if (it->bidi_it.new_paragraph)
7154 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
7155 bidi_move_to_visually_next (&it->bidi_it);
7156 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7157 IT_CHARPOS (*it) = it->bidi_it.charpos;
7158 if (prev_scan_dir != it->bidi_it.scan_dir)
7160 /* As the scan direction was changed, we must
7161 re-compute the stop position for composition. */
7162 ptrdiff_t stop = it->end_charpos;
7163 if (it->bidi_it.scan_dir < 0)
7164 stop = -1;
7165 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7166 IT_BYTEPOS (*it), stop, Qnil);
7169 eassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
7171 break;
7173 case GET_FROM_C_STRING:
7174 /* Current display element of IT is from a C string. */
7175 if (!it->bidi_p
7176 /* If the string position is beyond string's end, it means
7177 next_element_from_c_string is padding the string with
7178 blanks, in which case we bypass the bidi iterator,
7179 because it cannot deal with such virtual characters. */
7180 || IT_CHARPOS (*it) >= it->bidi_it.string.schars)
7182 IT_BYTEPOS (*it) += it->len;
7183 IT_CHARPOS (*it) += 1;
7185 else
7187 bidi_move_to_visually_next (&it->bidi_it);
7188 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7189 IT_CHARPOS (*it) = it->bidi_it.charpos;
7191 break;
7193 case GET_FROM_DISPLAY_VECTOR:
7194 /* Current display element of IT is from a display table entry.
7195 Advance in the display table definition. Reset it to null if
7196 end reached, and continue with characters from buffers/
7197 strings. */
7198 ++it->current.dpvec_index;
7200 /* Restore face of the iterator to what they were before the
7201 display vector entry (these entries may contain faces). */
7202 it->face_id = it->saved_face_id;
7204 if (it->dpvec + it->current.dpvec_index >= it->dpend)
7206 int recheck_faces = it->ellipsis_p;
7208 if (it->s)
7209 it->method = GET_FROM_C_STRING;
7210 else if (STRINGP (it->string))
7211 it->method = GET_FROM_STRING;
7212 else
7214 it->method = GET_FROM_BUFFER;
7215 it->object = it->w->contents;
7218 it->dpvec = NULL;
7219 it->current.dpvec_index = -1;
7221 /* Skip over characters which were displayed via IT->dpvec. */
7222 if (it->dpvec_char_len < 0)
7223 reseat_at_next_visible_line_start (it, 1);
7224 else if (it->dpvec_char_len > 0)
7226 if (it->method == GET_FROM_STRING
7227 && it->current.overlay_string_index >= 0
7228 && it->n_overlay_strings > 0)
7229 it->ignore_overlay_strings_at_pos_p = 1;
7230 it->len = it->dpvec_char_len;
7231 set_iterator_to_next (it, reseat_p);
7234 /* Maybe recheck faces after display vector */
7235 if (recheck_faces)
7236 it->stop_charpos = IT_CHARPOS (*it);
7238 break;
7240 case GET_FROM_STRING:
7241 /* Current display element is a character from a Lisp string. */
7242 eassert (it->s == NULL && STRINGP (it->string));
7243 /* Don't advance past string end. These conditions are true
7244 when set_iterator_to_next is called at the end of
7245 get_next_display_element, in which case the Lisp string is
7246 already exhausted, and all we want is pop the iterator
7247 stack. */
7248 if (it->current.overlay_string_index >= 0)
7250 /* This is an overlay string, so there's no padding with
7251 spaces, and the number of characters in the string is
7252 where the string ends. */
7253 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7254 goto consider_string_end;
7256 else
7258 /* Not an overlay string. There could be padding, so test
7259 against it->end_charpos . */
7260 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7261 goto consider_string_end;
7263 if (it->cmp_it.id >= 0)
7265 int i;
7267 if (! it->bidi_p)
7269 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
7270 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
7271 if (it->cmp_it.to < it->cmp_it.nglyphs)
7272 it->cmp_it.from = it->cmp_it.to;
7273 else
7275 it->cmp_it.id = -1;
7276 composition_compute_stop_pos (&it->cmp_it,
7277 IT_STRING_CHARPOS (*it),
7278 IT_STRING_BYTEPOS (*it),
7279 it->end_charpos, it->string);
7282 else if (! it->cmp_it.reversed_p)
7284 for (i = 0; i < it->cmp_it.nchars; i++)
7285 bidi_move_to_visually_next (&it->bidi_it);
7286 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7287 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7289 if (it->cmp_it.to < it->cmp_it.nglyphs)
7290 it->cmp_it.from = it->cmp_it.to;
7291 else
7293 ptrdiff_t stop = it->end_charpos;
7294 if (it->bidi_it.scan_dir < 0)
7295 stop = -1;
7296 composition_compute_stop_pos (&it->cmp_it,
7297 IT_STRING_CHARPOS (*it),
7298 IT_STRING_BYTEPOS (*it), stop,
7299 it->string);
7302 else
7304 for (i = 0; i < it->cmp_it.nchars; i++)
7305 bidi_move_to_visually_next (&it->bidi_it);
7306 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7307 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7308 if (it->cmp_it.from > 0)
7309 it->cmp_it.to = it->cmp_it.from;
7310 else
7312 ptrdiff_t stop = it->end_charpos;
7313 if (it->bidi_it.scan_dir < 0)
7314 stop = -1;
7315 composition_compute_stop_pos (&it->cmp_it,
7316 IT_STRING_CHARPOS (*it),
7317 IT_STRING_BYTEPOS (*it), stop,
7318 it->string);
7322 else
7324 if (!it->bidi_p
7325 /* If the string position is beyond string's end, it
7326 means next_element_from_string is padding the string
7327 with blanks, in which case we bypass the bidi
7328 iterator, because it cannot deal with such virtual
7329 characters. */
7330 || IT_STRING_CHARPOS (*it) >= it->bidi_it.string.schars)
7332 IT_STRING_BYTEPOS (*it) += it->len;
7333 IT_STRING_CHARPOS (*it) += 1;
7335 else
7337 int prev_scan_dir = it->bidi_it.scan_dir;
7339 bidi_move_to_visually_next (&it->bidi_it);
7340 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7341 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7342 if (prev_scan_dir != it->bidi_it.scan_dir)
7344 ptrdiff_t stop = it->end_charpos;
7346 if (it->bidi_it.scan_dir < 0)
7347 stop = -1;
7348 composition_compute_stop_pos (&it->cmp_it,
7349 IT_STRING_CHARPOS (*it),
7350 IT_STRING_BYTEPOS (*it), stop,
7351 it->string);
7356 consider_string_end:
7358 if (it->current.overlay_string_index >= 0)
7360 /* IT->string is an overlay string. Advance to the
7361 next, if there is one. */
7362 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7364 it->ellipsis_p = 0;
7365 next_overlay_string (it);
7366 if (it->ellipsis_p)
7367 setup_for_ellipsis (it, 0);
7370 else
7372 /* IT->string is not an overlay string. If we reached
7373 its end, and there is something on IT->stack, proceed
7374 with what is on the stack. This can be either another
7375 string, this time an overlay string, or a buffer. */
7376 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
7377 && it->sp > 0)
7379 pop_it (it);
7380 if (it->method == GET_FROM_STRING)
7381 goto consider_string_end;
7384 break;
7386 case GET_FROM_IMAGE:
7387 case GET_FROM_STRETCH:
7388 /* The position etc with which we have to proceed are on
7389 the stack. The position may be at the end of a string,
7390 if the `display' property takes up the whole string. */
7391 eassert (it->sp > 0);
7392 pop_it (it);
7393 if (it->method == GET_FROM_STRING)
7394 goto consider_string_end;
7395 break;
7397 default:
7398 /* There are no other methods defined, so this should be a bug. */
7399 emacs_abort ();
7402 eassert (it->method != GET_FROM_STRING
7403 || (STRINGP (it->string)
7404 && IT_STRING_CHARPOS (*it) >= 0));
7407 /* Load IT's display element fields with information about the next
7408 display element which comes from a display table entry or from the
7409 result of translating a control character to one of the forms `^C'
7410 or `\003'.
7412 IT->dpvec holds the glyphs to return as characters.
7413 IT->saved_face_id holds the face id before the display vector--it
7414 is restored into IT->face_id in set_iterator_to_next. */
7416 static int
7417 next_element_from_display_vector (struct it *it)
7419 Lisp_Object gc;
7421 /* Precondition. */
7422 eassert (it->dpvec && it->current.dpvec_index >= 0);
7424 it->face_id = it->saved_face_id;
7426 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
7427 That seemed totally bogus - so I changed it... */
7428 gc = it->dpvec[it->current.dpvec_index];
7430 if (GLYPH_CODE_P (gc))
7432 it->c = GLYPH_CODE_CHAR (gc);
7433 it->len = CHAR_BYTES (it->c);
7435 /* The entry may contain a face id to use. Such a face id is
7436 the id of a Lisp face, not a realized face. A face id of
7437 zero means no face is specified. */
7438 if (it->dpvec_face_id >= 0)
7439 it->face_id = it->dpvec_face_id;
7440 else
7442 int lface_id = GLYPH_CODE_FACE (gc);
7443 if (lface_id > 0)
7444 it->face_id = merge_faces (it->f, Qt, lface_id,
7445 it->saved_face_id);
7448 else
7449 /* Display table entry is invalid. Return a space. */
7450 it->c = ' ', it->len = 1;
7452 /* Don't change position and object of the iterator here. They are
7453 still the values of the character that had this display table
7454 entry or was translated, and that's what we want. */
7455 it->what = IT_CHARACTER;
7456 return 1;
7459 /* Get the first element of string/buffer in the visual order, after
7460 being reseated to a new position in a string or a buffer. */
7461 static void
7462 get_visually_first_element (struct it *it)
7464 int string_p = STRINGP (it->string) || it->s;
7465 ptrdiff_t eob = (string_p ? it->bidi_it.string.schars : ZV);
7466 ptrdiff_t bob = (string_p ? 0 : BEGV);
7468 if (STRINGP (it->string))
7470 it->bidi_it.charpos = IT_STRING_CHARPOS (*it);
7471 it->bidi_it.bytepos = IT_STRING_BYTEPOS (*it);
7473 else
7475 it->bidi_it.charpos = IT_CHARPOS (*it);
7476 it->bidi_it.bytepos = IT_BYTEPOS (*it);
7479 if (it->bidi_it.charpos == eob)
7481 /* Nothing to do, but reset the FIRST_ELT flag, like
7482 bidi_paragraph_init does, because we are not going to
7483 call it. */
7484 it->bidi_it.first_elt = 0;
7486 else if (it->bidi_it.charpos == bob
7487 || (!string_p
7488 && (FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n'
7489 || FETCH_CHAR (it->bidi_it.bytepos) == '\n')))
7491 /* If we are at the beginning of a line/string, we can produce
7492 the next element right away. */
7493 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
7494 bidi_move_to_visually_next (&it->bidi_it);
7496 else
7498 ptrdiff_t orig_bytepos = it->bidi_it.bytepos;
7500 /* We need to prime the bidi iterator starting at the line's or
7501 string's beginning, before we will be able to produce the
7502 next element. */
7503 if (string_p)
7504 it->bidi_it.charpos = it->bidi_it.bytepos = 0;
7505 else
7506 it->bidi_it.charpos = find_newline_no_quit (IT_CHARPOS (*it),
7507 IT_BYTEPOS (*it), -1,
7508 &it->bidi_it.bytepos);
7509 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
7512 /* Now return to buffer/string position where we were asked
7513 to get the next display element, and produce that. */
7514 bidi_move_to_visually_next (&it->bidi_it);
7516 while (it->bidi_it.bytepos != orig_bytepos
7517 && it->bidi_it.charpos < eob);
7520 /* Adjust IT's position information to where we ended up. */
7521 if (STRINGP (it->string))
7523 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7524 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7526 else
7528 IT_CHARPOS (*it) = it->bidi_it.charpos;
7529 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7532 if (STRINGP (it->string) || !it->s)
7534 ptrdiff_t stop, charpos, bytepos;
7536 if (STRINGP (it->string))
7538 eassert (!it->s);
7539 stop = SCHARS (it->string);
7540 if (stop > it->end_charpos)
7541 stop = it->end_charpos;
7542 charpos = IT_STRING_CHARPOS (*it);
7543 bytepos = IT_STRING_BYTEPOS (*it);
7545 else
7547 stop = it->end_charpos;
7548 charpos = IT_CHARPOS (*it);
7549 bytepos = IT_BYTEPOS (*it);
7551 if (it->bidi_it.scan_dir < 0)
7552 stop = -1;
7553 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos, stop,
7554 it->string);
7558 /* Load IT with the next display element from Lisp string IT->string.
7559 IT->current.string_pos is the current position within the string.
7560 If IT->current.overlay_string_index >= 0, the Lisp string is an
7561 overlay string. */
7563 static int
7564 next_element_from_string (struct it *it)
7566 struct text_pos position;
7568 eassert (STRINGP (it->string));
7569 eassert (!it->bidi_p || EQ (it->string, it->bidi_it.string.lstring));
7570 eassert (IT_STRING_CHARPOS (*it) >= 0);
7571 position = it->current.string_pos;
7573 /* With bidi reordering, the character to display might not be the
7574 character at IT_STRING_CHARPOS. BIDI_IT.FIRST_ELT non-zero means
7575 that we were reseat()ed to a new string, whose paragraph
7576 direction is not known. */
7577 if (it->bidi_p && it->bidi_it.first_elt)
7579 get_visually_first_element (it);
7580 SET_TEXT_POS (position, IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it));
7583 /* Time to check for invisible text? */
7584 if (IT_STRING_CHARPOS (*it) < it->end_charpos)
7586 if (IT_STRING_CHARPOS (*it) >= it->stop_charpos)
7588 if (!(!it->bidi_p
7589 || BIDI_AT_BASE_LEVEL (it->bidi_it)
7590 || IT_STRING_CHARPOS (*it) == it->stop_charpos))
7592 /* With bidi non-linear iteration, we could find
7593 ourselves far beyond the last computed stop_charpos,
7594 with several other stop positions in between that we
7595 missed. Scan them all now, in buffer's logical
7596 order, until we find and handle the last stop_charpos
7597 that precedes our current position. */
7598 handle_stop_backwards (it, it->stop_charpos);
7599 return GET_NEXT_DISPLAY_ELEMENT (it);
7601 else
7603 if (it->bidi_p)
7605 /* Take note of the stop position we just moved
7606 across, for when we will move back across it. */
7607 it->prev_stop = it->stop_charpos;
7608 /* If we are at base paragraph embedding level, take
7609 note of the last stop position seen at this
7610 level. */
7611 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
7612 it->base_level_stop = it->stop_charpos;
7614 handle_stop (it);
7616 /* Since a handler may have changed IT->method, we must
7617 recurse here. */
7618 return GET_NEXT_DISPLAY_ELEMENT (it);
7621 else if (it->bidi_p
7622 /* If we are before prev_stop, we may have overstepped
7623 on our way backwards a stop_pos, and if so, we need
7624 to handle that stop_pos. */
7625 && IT_STRING_CHARPOS (*it) < it->prev_stop
7626 /* We can sometimes back up for reasons that have nothing
7627 to do with bidi reordering. E.g., compositions. The
7628 code below is only needed when we are above the base
7629 embedding level, so test for that explicitly. */
7630 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
7632 /* If we lost track of base_level_stop, we have no better
7633 place for handle_stop_backwards to start from than string
7634 beginning. This happens, e.g., when we were reseated to
7635 the previous screenful of text by vertical-motion. */
7636 if (it->base_level_stop <= 0
7637 || IT_STRING_CHARPOS (*it) < it->base_level_stop)
7638 it->base_level_stop = 0;
7639 handle_stop_backwards (it, it->base_level_stop);
7640 return GET_NEXT_DISPLAY_ELEMENT (it);
7644 if (it->current.overlay_string_index >= 0)
7646 /* Get the next character from an overlay string. In overlay
7647 strings, there is no field width or padding with spaces to
7648 do. */
7649 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7651 it->what = IT_EOB;
7652 return 0;
7654 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
7655 IT_STRING_BYTEPOS (*it),
7656 it->bidi_it.scan_dir < 0
7657 ? -1
7658 : SCHARS (it->string))
7659 && next_element_from_composition (it))
7661 return 1;
7663 else if (STRING_MULTIBYTE (it->string))
7665 const unsigned char *s = (SDATA (it->string)
7666 + IT_STRING_BYTEPOS (*it));
7667 it->c = string_char_and_length (s, &it->len);
7669 else
7671 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
7672 it->len = 1;
7675 else
7677 /* Get the next character from a Lisp string that is not an
7678 overlay string. Such strings come from the mode line, for
7679 example. We may have to pad with spaces, or truncate the
7680 string. See also next_element_from_c_string. */
7681 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7683 it->what = IT_EOB;
7684 return 0;
7686 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
7688 /* Pad with spaces. */
7689 it->c = ' ', it->len = 1;
7690 CHARPOS (position) = BYTEPOS (position) = -1;
7692 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
7693 IT_STRING_BYTEPOS (*it),
7694 it->bidi_it.scan_dir < 0
7695 ? -1
7696 : it->string_nchars)
7697 && next_element_from_composition (it))
7699 return 1;
7701 else if (STRING_MULTIBYTE (it->string))
7703 const unsigned char *s = (SDATA (it->string)
7704 + IT_STRING_BYTEPOS (*it));
7705 it->c = string_char_and_length (s, &it->len);
7707 else
7709 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
7710 it->len = 1;
7714 /* Record what we have and where it came from. */
7715 it->what = IT_CHARACTER;
7716 it->object = it->string;
7717 it->position = position;
7718 return 1;
7722 /* Load IT with next display element from C string IT->s.
7723 IT->string_nchars is the maximum number of characters to return
7724 from the string. IT->end_charpos may be greater than
7725 IT->string_nchars when this function is called, in which case we
7726 may have to return padding spaces. Value is zero if end of string
7727 reached, including padding spaces. */
7729 static int
7730 next_element_from_c_string (struct it *it)
7732 int success_p = 1;
7734 eassert (it->s);
7735 eassert (!it->bidi_p || it->s == it->bidi_it.string.s);
7736 it->what = IT_CHARACTER;
7737 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
7738 it->object = Qnil;
7740 /* With bidi reordering, the character to display might not be the
7741 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
7742 we were reseated to a new string, whose paragraph direction is
7743 not known. */
7744 if (it->bidi_p && it->bidi_it.first_elt)
7745 get_visually_first_element (it);
7747 /* IT's position can be greater than IT->string_nchars in case a
7748 field width or precision has been specified when the iterator was
7749 initialized. */
7750 if (IT_CHARPOS (*it) >= it->end_charpos)
7752 /* End of the game. */
7753 it->what = IT_EOB;
7754 success_p = 0;
7756 else if (IT_CHARPOS (*it) >= it->string_nchars)
7758 /* Pad with spaces. */
7759 it->c = ' ', it->len = 1;
7760 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
7762 else if (it->multibyte_p)
7763 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), &it->len);
7764 else
7765 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
7767 return success_p;
7771 /* Set up IT to return characters from an ellipsis, if appropriate.
7772 The definition of the ellipsis glyphs may come from a display table
7773 entry. This function fills IT with the first glyph from the
7774 ellipsis if an ellipsis is to be displayed. */
7776 static int
7777 next_element_from_ellipsis (struct it *it)
7779 if (it->selective_display_ellipsis_p)
7780 setup_for_ellipsis (it, it->len);
7781 else
7783 /* The face at the current position may be different from the
7784 face we find after the invisible text. Remember what it
7785 was in IT->saved_face_id, and signal that it's there by
7786 setting face_before_selective_p. */
7787 it->saved_face_id = it->face_id;
7788 it->method = GET_FROM_BUFFER;
7789 it->object = it->w->contents;
7790 reseat_at_next_visible_line_start (it, 1);
7791 it->face_before_selective_p = 1;
7794 return GET_NEXT_DISPLAY_ELEMENT (it);
7798 /* Deliver an image display element. The iterator IT is already
7799 filled with image information (done in handle_display_prop). Value
7800 is always 1. */
7803 static int
7804 next_element_from_image (struct it *it)
7806 it->what = IT_IMAGE;
7807 it->ignore_overlay_strings_at_pos_p = 0;
7808 return 1;
7812 /* Fill iterator IT with next display element from a stretch glyph
7813 property. IT->object is the value of the text property. Value is
7814 always 1. */
7816 static int
7817 next_element_from_stretch (struct it *it)
7819 it->what = IT_STRETCH;
7820 return 1;
7823 /* Scan backwards from IT's current position until we find a stop
7824 position, or until BEGV. This is called when we find ourself
7825 before both the last known prev_stop and base_level_stop while
7826 reordering bidirectional text. */
7828 static void
7829 compute_stop_pos_backwards (struct it *it)
7831 const int SCAN_BACK_LIMIT = 1000;
7832 struct text_pos pos;
7833 struct display_pos save_current = it->current;
7834 struct text_pos save_position = it->position;
7835 ptrdiff_t charpos = IT_CHARPOS (*it);
7836 ptrdiff_t where_we_are = charpos;
7837 ptrdiff_t save_stop_pos = it->stop_charpos;
7838 ptrdiff_t save_end_pos = it->end_charpos;
7840 eassert (NILP (it->string) && !it->s);
7841 eassert (it->bidi_p);
7842 it->bidi_p = 0;
7845 it->end_charpos = min (charpos + 1, ZV);
7846 charpos = max (charpos - SCAN_BACK_LIMIT, BEGV);
7847 SET_TEXT_POS (pos, charpos, CHAR_TO_BYTE (charpos));
7848 reseat_1 (it, pos, 0);
7849 compute_stop_pos (it);
7850 /* We must advance forward, right? */
7851 if (it->stop_charpos <= charpos)
7852 emacs_abort ();
7854 while (charpos > BEGV && it->stop_charpos >= it->end_charpos);
7856 if (it->stop_charpos <= where_we_are)
7857 it->prev_stop = it->stop_charpos;
7858 else
7859 it->prev_stop = BEGV;
7860 it->bidi_p = 1;
7861 it->current = save_current;
7862 it->position = save_position;
7863 it->stop_charpos = save_stop_pos;
7864 it->end_charpos = save_end_pos;
7867 /* Scan forward from CHARPOS in the current buffer/string, until we
7868 find a stop position > current IT's position. Then handle the stop
7869 position before that. This is called when we bump into a stop
7870 position while reordering bidirectional text. CHARPOS should be
7871 the last previously processed stop_pos (or BEGV/0, if none were
7872 processed yet) whose position is less that IT's current
7873 position. */
7875 static void
7876 handle_stop_backwards (struct it *it, ptrdiff_t charpos)
7878 int bufp = !STRINGP (it->string);
7879 ptrdiff_t where_we_are = (bufp ? IT_CHARPOS (*it) : IT_STRING_CHARPOS (*it));
7880 struct display_pos save_current = it->current;
7881 struct text_pos save_position = it->position;
7882 struct text_pos pos1;
7883 ptrdiff_t next_stop;
7885 /* Scan in strict logical order. */
7886 eassert (it->bidi_p);
7887 it->bidi_p = 0;
7890 it->prev_stop = charpos;
7891 if (bufp)
7893 SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos));
7894 reseat_1 (it, pos1, 0);
7896 else
7897 it->current.string_pos = string_pos (charpos, it->string);
7898 compute_stop_pos (it);
7899 /* We must advance forward, right? */
7900 if (it->stop_charpos <= it->prev_stop)
7901 emacs_abort ();
7902 charpos = it->stop_charpos;
7904 while (charpos <= where_we_are);
7906 it->bidi_p = 1;
7907 it->current = save_current;
7908 it->position = save_position;
7909 next_stop = it->stop_charpos;
7910 it->stop_charpos = it->prev_stop;
7911 handle_stop (it);
7912 it->stop_charpos = next_stop;
7915 /* Load IT with the next display element from current_buffer. Value
7916 is zero if end of buffer reached. IT->stop_charpos is the next
7917 position at which to stop and check for text properties or buffer
7918 end. */
7920 static int
7921 next_element_from_buffer (struct it *it)
7923 int success_p = 1;
7925 eassert (IT_CHARPOS (*it) >= BEGV);
7926 eassert (NILP (it->string) && !it->s);
7927 eassert (!it->bidi_p
7928 || (EQ (it->bidi_it.string.lstring, Qnil)
7929 && it->bidi_it.string.s == NULL));
7931 /* With bidi reordering, the character to display might not be the
7932 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
7933 we were reseat()ed to a new buffer position, which is potentially
7934 a different paragraph. */
7935 if (it->bidi_p && it->bidi_it.first_elt)
7937 get_visually_first_element (it);
7938 SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it));
7941 if (IT_CHARPOS (*it) >= it->stop_charpos)
7943 if (IT_CHARPOS (*it) >= it->end_charpos)
7945 int overlay_strings_follow_p;
7947 /* End of the game, except when overlay strings follow that
7948 haven't been returned yet. */
7949 if (it->overlay_strings_at_end_processed_p)
7950 overlay_strings_follow_p = 0;
7951 else
7953 it->overlay_strings_at_end_processed_p = 1;
7954 overlay_strings_follow_p = get_overlay_strings (it, 0);
7957 if (overlay_strings_follow_p)
7958 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
7959 else
7961 it->what = IT_EOB;
7962 it->position = it->current.pos;
7963 success_p = 0;
7966 else if (!(!it->bidi_p
7967 || BIDI_AT_BASE_LEVEL (it->bidi_it)
7968 || IT_CHARPOS (*it) == it->stop_charpos))
7970 /* With bidi non-linear iteration, we could find ourselves
7971 far beyond the last computed stop_charpos, with several
7972 other stop positions in between that we missed. Scan
7973 them all now, in buffer's logical order, until we find
7974 and handle the last stop_charpos that precedes our
7975 current position. */
7976 handle_stop_backwards (it, it->stop_charpos);
7977 return GET_NEXT_DISPLAY_ELEMENT (it);
7979 else
7981 if (it->bidi_p)
7983 /* Take note of the stop position we just moved across,
7984 for when we will move back across it. */
7985 it->prev_stop = it->stop_charpos;
7986 /* If we are at base paragraph embedding level, take
7987 note of the last stop position seen at this
7988 level. */
7989 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
7990 it->base_level_stop = it->stop_charpos;
7992 handle_stop (it);
7993 return GET_NEXT_DISPLAY_ELEMENT (it);
7996 else if (it->bidi_p
7997 /* If we are before prev_stop, we may have overstepped on
7998 our way backwards a stop_pos, and if so, we need to
7999 handle that stop_pos. */
8000 && IT_CHARPOS (*it) < it->prev_stop
8001 /* We can sometimes back up for reasons that have nothing
8002 to do with bidi reordering. E.g., compositions. The
8003 code below is only needed when we are above the base
8004 embedding level, so test for that explicitly. */
8005 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
8007 if (it->base_level_stop <= 0
8008 || IT_CHARPOS (*it) < it->base_level_stop)
8010 /* If we lost track of base_level_stop, we need to find
8011 prev_stop by looking backwards. This happens, e.g., when
8012 we were reseated to the previous screenful of text by
8013 vertical-motion. */
8014 it->base_level_stop = BEGV;
8015 compute_stop_pos_backwards (it);
8016 handle_stop_backwards (it, it->prev_stop);
8018 else
8019 handle_stop_backwards (it, it->base_level_stop);
8020 return GET_NEXT_DISPLAY_ELEMENT (it);
8022 else
8024 /* No face changes, overlays etc. in sight, so just return a
8025 character from current_buffer. */
8026 unsigned char *p;
8027 ptrdiff_t stop;
8029 /* Maybe run the redisplay end trigger hook. Performance note:
8030 This doesn't seem to cost measurable time. */
8031 if (it->redisplay_end_trigger_charpos
8032 && it->glyph_row
8033 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
8034 run_redisplay_end_trigger_hook (it);
8036 stop = it->bidi_it.scan_dir < 0 ? -1 : it->end_charpos;
8037 if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it),
8038 stop)
8039 && next_element_from_composition (it))
8041 return 1;
8044 /* Get the next character, maybe multibyte. */
8045 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
8046 if (it->multibyte_p && !ASCII_BYTE_P (*p))
8047 it->c = STRING_CHAR_AND_LENGTH (p, it->len);
8048 else
8049 it->c = *p, it->len = 1;
8051 /* Record what we have and where it came from. */
8052 it->what = IT_CHARACTER;
8053 it->object = it->w->contents;
8054 it->position = it->current.pos;
8056 /* Normally we return the character found above, except when we
8057 really want to return an ellipsis for selective display. */
8058 if (it->selective)
8060 if (it->c == '\n')
8062 /* A value of selective > 0 means hide lines indented more
8063 than that number of columns. */
8064 if (it->selective > 0
8065 && IT_CHARPOS (*it) + 1 < ZV
8066 && indented_beyond_p (IT_CHARPOS (*it) + 1,
8067 IT_BYTEPOS (*it) + 1,
8068 it->selective))
8070 success_p = next_element_from_ellipsis (it);
8071 it->dpvec_char_len = -1;
8074 else if (it->c == '\r' && it->selective == -1)
8076 /* A value of selective == -1 means that everything from the
8077 CR to the end of the line is invisible, with maybe an
8078 ellipsis displayed for it. */
8079 success_p = next_element_from_ellipsis (it);
8080 it->dpvec_char_len = -1;
8085 /* Value is zero if end of buffer reached. */
8086 eassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
8087 return success_p;
8091 /* Run the redisplay end trigger hook for IT. */
8093 static void
8094 run_redisplay_end_trigger_hook (struct it *it)
8096 Lisp_Object args[3];
8098 /* IT->glyph_row should be non-null, i.e. we should be actually
8099 displaying something, or otherwise we should not run the hook. */
8100 eassert (it->glyph_row);
8102 /* Set up hook arguments. */
8103 args[0] = Qredisplay_end_trigger_functions;
8104 args[1] = it->window;
8105 XSETINT (args[2], it->redisplay_end_trigger_charpos);
8106 it->redisplay_end_trigger_charpos = 0;
8108 /* Since we are *trying* to run these functions, don't try to run
8109 them again, even if they get an error. */
8110 wset_redisplay_end_trigger (it->w, Qnil);
8111 Frun_hook_with_args (3, args);
8113 /* Notice if it changed the face of the character we are on. */
8114 handle_face_prop (it);
8118 /* Deliver a composition display element. Unlike the other
8119 next_element_from_XXX, this function is not registered in the array
8120 get_next_element[]. It is called from next_element_from_buffer and
8121 next_element_from_string when necessary. */
8123 static int
8124 next_element_from_composition (struct it *it)
8126 it->what = IT_COMPOSITION;
8127 it->len = it->cmp_it.nbytes;
8128 if (STRINGP (it->string))
8130 if (it->c < 0)
8132 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
8133 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
8134 return 0;
8136 it->position = it->current.string_pos;
8137 it->object = it->string;
8138 it->c = composition_update_it (&it->cmp_it, IT_STRING_CHARPOS (*it),
8139 IT_STRING_BYTEPOS (*it), it->string);
8141 else
8143 if (it->c < 0)
8145 IT_CHARPOS (*it) += it->cmp_it.nchars;
8146 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
8147 if (it->bidi_p)
8149 if (it->bidi_it.new_paragraph)
8150 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
8151 /* Resync the bidi iterator with IT's new position.
8152 FIXME: this doesn't support bidirectional text. */
8153 while (it->bidi_it.charpos < IT_CHARPOS (*it))
8154 bidi_move_to_visually_next (&it->bidi_it);
8156 return 0;
8158 it->position = it->current.pos;
8159 it->object = it->w->contents;
8160 it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
8161 IT_BYTEPOS (*it), Qnil);
8163 return 1;
8168 /***********************************************************************
8169 Moving an iterator without producing glyphs
8170 ***********************************************************************/
8172 /* Check if iterator is at a position corresponding to a valid buffer
8173 position after some move_it_ call. */
8175 #define IT_POS_VALID_AFTER_MOVE_P(it) \
8176 ((it)->method == GET_FROM_STRING \
8177 ? IT_STRING_CHARPOS (*it) == 0 \
8178 : 1)
8181 /* Move iterator IT to a specified buffer or X position within one
8182 line on the display without producing glyphs.
8184 OP should be a bit mask including some or all of these bits:
8185 MOVE_TO_X: Stop upon reaching x-position TO_X.
8186 MOVE_TO_POS: Stop upon reaching buffer or string position TO_CHARPOS.
8187 Regardless of OP's value, stop upon reaching the end of the display line.
8189 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
8190 This means, in particular, that TO_X includes window's horizontal
8191 scroll amount.
8193 The return value has several possible values that
8194 say what condition caused the scan to stop:
8196 MOVE_POS_MATCH_OR_ZV
8197 - when TO_POS or ZV was reached.
8199 MOVE_X_REACHED
8200 -when TO_X was reached before TO_POS or ZV were reached.
8202 MOVE_LINE_CONTINUED
8203 - when we reached the end of the display area and the line must
8204 be continued.
8206 MOVE_LINE_TRUNCATED
8207 - when we reached the end of the display area and the line is
8208 truncated.
8210 MOVE_NEWLINE_OR_CR
8211 - when we stopped at a line end, i.e. a newline or a CR and selective
8212 display is on. */
8214 static enum move_it_result
8215 move_it_in_display_line_to (struct it *it,
8216 ptrdiff_t to_charpos, int to_x,
8217 enum move_operation_enum op)
8219 enum move_it_result result = MOVE_UNDEFINED;
8220 struct glyph_row *saved_glyph_row;
8221 struct it wrap_it, atpos_it, atx_it, ppos_it;
8222 void *wrap_data = NULL, *atpos_data = NULL, *atx_data = NULL;
8223 void *ppos_data = NULL;
8224 int may_wrap = 0;
8225 enum it_method prev_method = it->method;
8226 ptrdiff_t prev_pos = IT_CHARPOS (*it);
8227 int saw_smaller_pos = prev_pos < to_charpos;
8229 /* Don't produce glyphs in produce_glyphs. */
8230 saved_glyph_row = it->glyph_row;
8231 it->glyph_row = NULL;
8233 /* Use wrap_it to save a copy of IT wherever a word wrap could
8234 occur. Use atpos_it to save a copy of IT at the desired buffer
8235 position, if found, so that we can scan ahead and check if the
8236 word later overshoots the window edge. Use atx_it similarly, for
8237 pixel positions. */
8238 wrap_it.sp = -1;
8239 atpos_it.sp = -1;
8240 atx_it.sp = -1;
8242 /* Use ppos_it under bidi reordering to save a copy of IT for the
8243 position > CHARPOS that is the closest to CHARPOS. We restore
8244 that position in IT when we have scanned the entire display line
8245 without finding a match for CHARPOS and all the character
8246 positions are greater than CHARPOS. */
8247 if (it->bidi_p)
8249 SAVE_IT (ppos_it, *it, ppos_data);
8250 SET_TEXT_POS (ppos_it.current.pos, ZV, ZV_BYTE);
8251 if ((op & MOVE_TO_POS) && IT_CHARPOS (*it) >= to_charpos)
8252 SAVE_IT (ppos_it, *it, ppos_data);
8255 #define BUFFER_POS_REACHED_P() \
8256 ((op & MOVE_TO_POS) != 0 \
8257 && BUFFERP (it->object) \
8258 && (IT_CHARPOS (*it) == to_charpos \
8259 || ((!it->bidi_p \
8260 || BIDI_AT_BASE_LEVEL (it->bidi_it)) \
8261 && IT_CHARPOS (*it) > to_charpos) \
8262 || (it->what == IT_COMPOSITION \
8263 && ((IT_CHARPOS (*it) > to_charpos \
8264 && to_charpos >= it->cmp_it.charpos) \
8265 || (IT_CHARPOS (*it) < to_charpos \
8266 && to_charpos <= it->cmp_it.charpos)))) \
8267 && (it->method == GET_FROM_BUFFER \
8268 || (it->method == GET_FROM_DISPLAY_VECTOR \
8269 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
8271 /* If there's a line-/wrap-prefix, handle it. */
8272 if (it->hpos == 0 && it->method == GET_FROM_BUFFER
8273 && it->current_y < it->last_visible_y)
8274 handle_line_prefix (it);
8276 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8277 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8279 while (1)
8281 int x, i, ascent = 0, descent = 0;
8283 /* Utility macro to reset an iterator with x, ascent, and descent. */
8284 #define IT_RESET_X_ASCENT_DESCENT(IT) \
8285 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
8286 (IT)->max_descent = descent)
8288 /* Stop if we move beyond TO_CHARPOS (after an image or a
8289 display string or stretch glyph). */
8290 if ((op & MOVE_TO_POS) != 0
8291 && BUFFERP (it->object)
8292 && it->method == GET_FROM_BUFFER
8293 && (((!it->bidi_p
8294 /* When the iterator is at base embedding level, we
8295 are guaranteed that characters are delivered for
8296 display in strictly increasing order of their
8297 buffer positions. */
8298 || BIDI_AT_BASE_LEVEL (it->bidi_it))
8299 && IT_CHARPOS (*it) > to_charpos)
8300 || (it->bidi_p
8301 && (prev_method == GET_FROM_IMAGE
8302 || prev_method == GET_FROM_STRETCH
8303 || prev_method == GET_FROM_STRING)
8304 /* Passed TO_CHARPOS from left to right. */
8305 && ((prev_pos < to_charpos
8306 && IT_CHARPOS (*it) > to_charpos)
8307 /* Passed TO_CHARPOS from right to left. */
8308 || (prev_pos > to_charpos
8309 && IT_CHARPOS (*it) < to_charpos)))))
8311 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8313 result = MOVE_POS_MATCH_OR_ZV;
8314 break;
8316 else if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8317 /* If wrap_it is valid, the current position might be in a
8318 word that is wrapped. So, save the iterator in
8319 atpos_it and continue to see if wrapping happens. */
8320 SAVE_IT (atpos_it, *it, atpos_data);
8323 /* Stop when ZV reached.
8324 We used to stop here when TO_CHARPOS reached as well, but that is
8325 too soon if this glyph does not fit on this line. So we handle it
8326 explicitly below. */
8327 if (!get_next_display_element (it))
8329 result = MOVE_POS_MATCH_OR_ZV;
8330 break;
8333 if (it->line_wrap == TRUNCATE)
8335 if (BUFFER_POS_REACHED_P ())
8337 result = MOVE_POS_MATCH_OR_ZV;
8338 break;
8341 else
8343 if (it->line_wrap == WORD_WRAP)
8345 if (IT_DISPLAYING_WHITESPACE (it))
8346 may_wrap = 1;
8347 else if (may_wrap)
8349 /* We have reached a glyph that follows one or more
8350 whitespace characters. If the position is
8351 already found, we are done. */
8352 if (atpos_it.sp >= 0)
8354 RESTORE_IT (it, &atpos_it, atpos_data);
8355 result = MOVE_POS_MATCH_OR_ZV;
8356 goto done;
8358 if (atx_it.sp >= 0)
8360 RESTORE_IT (it, &atx_it, atx_data);
8361 result = MOVE_X_REACHED;
8362 goto done;
8364 /* Otherwise, we can wrap here. */
8365 SAVE_IT (wrap_it, *it, wrap_data);
8366 may_wrap = 0;
8371 /* Remember the line height for the current line, in case
8372 the next element doesn't fit on the line. */
8373 ascent = it->max_ascent;
8374 descent = it->max_descent;
8376 /* The call to produce_glyphs will get the metrics of the
8377 display element IT is loaded with. Record the x-position
8378 before this display element, in case it doesn't fit on the
8379 line. */
8380 x = it->current_x;
8382 PRODUCE_GLYPHS (it);
8384 if (it->area != TEXT_AREA)
8386 prev_method = it->method;
8387 if (it->method == GET_FROM_BUFFER)
8388 prev_pos = IT_CHARPOS (*it);
8389 set_iterator_to_next (it, 1);
8390 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8391 SET_TEXT_POS (this_line_min_pos,
8392 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8393 if (it->bidi_p
8394 && (op & MOVE_TO_POS)
8395 && IT_CHARPOS (*it) > to_charpos
8396 && IT_CHARPOS (*it) < IT_CHARPOS (ppos_it))
8397 SAVE_IT (ppos_it, *it, ppos_data);
8398 continue;
8401 /* The number of glyphs we get back in IT->nglyphs will normally
8402 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
8403 character on a terminal frame, or (iii) a line end. For the
8404 second case, IT->nglyphs - 1 padding glyphs will be present.
8405 (On X frames, there is only one glyph produced for a
8406 composite character.)
8408 The behavior implemented below means, for continuation lines,
8409 that as many spaces of a TAB as fit on the current line are
8410 displayed there. For terminal frames, as many glyphs of a
8411 multi-glyph character are displayed in the current line, too.
8412 This is what the old redisplay code did, and we keep it that
8413 way. Under X, the whole shape of a complex character must
8414 fit on the line or it will be completely displayed in the
8415 next line.
8417 Note that both for tabs and padding glyphs, all glyphs have
8418 the same width. */
8419 if (it->nglyphs)
8421 /* More than one glyph or glyph doesn't fit on line. All
8422 glyphs have the same width. */
8423 int single_glyph_width = it->pixel_width / it->nglyphs;
8424 int new_x;
8425 int x_before_this_char = x;
8426 int hpos_before_this_char = it->hpos;
8428 for (i = 0; i < it->nglyphs; ++i, x = new_x)
8430 new_x = x + single_glyph_width;
8432 /* We want to leave anything reaching TO_X to the caller. */
8433 if ((op & MOVE_TO_X) && new_x > to_x)
8435 if (BUFFER_POS_REACHED_P ())
8437 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8438 goto buffer_pos_reached;
8439 if (atpos_it.sp < 0)
8441 SAVE_IT (atpos_it, *it, atpos_data);
8442 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8445 else
8447 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8449 it->current_x = x;
8450 result = MOVE_X_REACHED;
8451 break;
8453 if (atx_it.sp < 0)
8455 SAVE_IT (atx_it, *it, atx_data);
8456 IT_RESET_X_ASCENT_DESCENT (&atx_it);
8461 if (/* Lines are continued. */
8462 it->line_wrap != TRUNCATE
8463 && (/* And glyph doesn't fit on the line. */
8464 new_x > it->last_visible_x
8465 /* Or it fits exactly and we're on a window
8466 system frame. */
8467 || (new_x == it->last_visible_x
8468 && FRAME_WINDOW_P (it->f)
8469 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
8470 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8471 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
8473 if (/* IT->hpos == 0 means the very first glyph
8474 doesn't fit on the line, e.g. a wide image. */
8475 it->hpos == 0
8476 || (new_x == it->last_visible_x
8477 && FRAME_WINDOW_P (it->f)))
8479 ++it->hpos;
8480 it->current_x = new_x;
8482 /* The character's last glyph just barely fits
8483 in this row. */
8484 if (i == it->nglyphs - 1)
8486 /* If this is the destination position,
8487 return a position *before* it in this row,
8488 now that we know it fits in this row. */
8489 if (BUFFER_POS_REACHED_P ())
8491 if (it->line_wrap != WORD_WRAP
8492 || wrap_it.sp < 0)
8494 it->hpos = hpos_before_this_char;
8495 it->current_x = x_before_this_char;
8496 result = MOVE_POS_MATCH_OR_ZV;
8497 break;
8499 if (it->line_wrap == WORD_WRAP
8500 && atpos_it.sp < 0)
8502 SAVE_IT (atpos_it, *it, atpos_data);
8503 atpos_it.current_x = x_before_this_char;
8504 atpos_it.hpos = hpos_before_this_char;
8508 prev_method = it->method;
8509 if (it->method == GET_FROM_BUFFER)
8510 prev_pos = IT_CHARPOS (*it);
8511 set_iterator_to_next (it, 1);
8512 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8513 SET_TEXT_POS (this_line_min_pos,
8514 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8515 /* On graphical terminals, newlines may
8516 "overflow" into the fringe if
8517 overflow-newline-into-fringe is non-nil.
8518 On text terminals, and on graphical
8519 terminals with no right margin, newlines
8520 may overflow into the last glyph on the
8521 display line.*/
8522 if (!FRAME_WINDOW_P (it->f)
8523 || ((it->bidi_p
8524 && it->bidi_it.paragraph_dir == R2L)
8525 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8526 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
8527 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8529 if (!get_next_display_element (it))
8531 result = MOVE_POS_MATCH_OR_ZV;
8532 break;
8534 if (BUFFER_POS_REACHED_P ())
8536 if (ITERATOR_AT_END_OF_LINE_P (it))
8537 result = MOVE_POS_MATCH_OR_ZV;
8538 else
8539 result = MOVE_LINE_CONTINUED;
8540 break;
8542 if (ITERATOR_AT_END_OF_LINE_P (it))
8544 result = MOVE_NEWLINE_OR_CR;
8545 break;
8550 else
8551 IT_RESET_X_ASCENT_DESCENT (it);
8553 if (wrap_it.sp >= 0)
8555 RESTORE_IT (it, &wrap_it, wrap_data);
8556 atpos_it.sp = -1;
8557 atx_it.sp = -1;
8560 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
8561 IT_CHARPOS (*it)));
8562 result = MOVE_LINE_CONTINUED;
8563 break;
8566 if (BUFFER_POS_REACHED_P ())
8568 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8569 goto buffer_pos_reached;
8570 if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8572 SAVE_IT (atpos_it, *it, atpos_data);
8573 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8577 if (new_x > it->first_visible_x)
8579 /* Glyph is visible. Increment number of glyphs that
8580 would be displayed. */
8581 ++it->hpos;
8585 if (result != MOVE_UNDEFINED)
8586 break;
8588 else if (BUFFER_POS_REACHED_P ())
8590 buffer_pos_reached:
8591 IT_RESET_X_ASCENT_DESCENT (it);
8592 result = MOVE_POS_MATCH_OR_ZV;
8593 break;
8595 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
8597 /* Stop when TO_X specified and reached. This check is
8598 necessary here because of lines consisting of a line end,
8599 only. The line end will not produce any glyphs and we
8600 would never get MOVE_X_REACHED. */
8601 eassert (it->nglyphs == 0);
8602 result = MOVE_X_REACHED;
8603 break;
8606 /* Is this a line end? If yes, we're done. */
8607 if (ITERATOR_AT_END_OF_LINE_P (it))
8609 /* If we are past TO_CHARPOS, but never saw any character
8610 positions smaller than TO_CHARPOS, return
8611 MOVE_POS_MATCH_OR_ZV, like the unidirectional display
8612 did. */
8613 if (it->bidi_p && (op & MOVE_TO_POS) != 0)
8615 if (!saw_smaller_pos && IT_CHARPOS (*it) > to_charpos)
8617 if (IT_CHARPOS (ppos_it) < ZV)
8619 RESTORE_IT (it, &ppos_it, ppos_data);
8620 result = MOVE_POS_MATCH_OR_ZV;
8622 else
8623 goto buffer_pos_reached;
8625 else if (it->line_wrap == WORD_WRAP && atpos_it.sp >= 0
8626 && IT_CHARPOS (*it) > to_charpos)
8627 goto buffer_pos_reached;
8628 else
8629 result = MOVE_NEWLINE_OR_CR;
8631 else
8632 result = MOVE_NEWLINE_OR_CR;
8633 break;
8636 prev_method = it->method;
8637 if (it->method == GET_FROM_BUFFER)
8638 prev_pos = IT_CHARPOS (*it);
8639 /* The current display element has been consumed. Advance
8640 to the next. */
8641 set_iterator_to_next (it, 1);
8642 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8643 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8644 if (IT_CHARPOS (*it) < to_charpos)
8645 saw_smaller_pos = 1;
8646 if (it->bidi_p
8647 && (op & MOVE_TO_POS)
8648 && IT_CHARPOS (*it) >= to_charpos
8649 && IT_CHARPOS (*it) < IT_CHARPOS (ppos_it))
8650 SAVE_IT (ppos_it, *it, ppos_data);
8652 /* Stop if lines are truncated and IT's current x-position is
8653 past the right edge of the window now. */
8654 if (it->line_wrap == TRUNCATE
8655 && it->current_x >= it->last_visible_x)
8657 if (!FRAME_WINDOW_P (it->f)
8658 || ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
8659 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8660 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
8661 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8663 int at_eob_p = 0;
8665 if ((at_eob_p = !get_next_display_element (it))
8666 || BUFFER_POS_REACHED_P ()
8667 /* If we are past TO_CHARPOS, but never saw any
8668 character positions smaller than TO_CHARPOS,
8669 return MOVE_POS_MATCH_OR_ZV, like the
8670 unidirectional display did. */
8671 || (it->bidi_p && (op & MOVE_TO_POS) != 0
8672 && !saw_smaller_pos
8673 && IT_CHARPOS (*it) > to_charpos))
8675 if (it->bidi_p
8676 && !at_eob_p && IT_CHARPOS (ppos_it) < ZV)
8677 RESTORE_IT (it, &ppos_it, ppos_data);
8678 result = MOVE_POS_MATCH_OR_ZV;
8679 break;
8681 if (ITERATOR_AT_END_OF_LINE_P (it))
8683 result = MOVE_NEWLINE_OR_CR;
8684 break;
8687 else if (it->bidi_p && (op & MOVE_TO_POS) != 0
8688 && !saw_smaller_pos
8689 && IT_CHARPOS (*it) > to_charpos)
8691 if (IT_CHARPOS (ppos_it) < ZV)
8692 RESTORE_IT (it, &ppos_it, ppos_data);
8693 result = MOVE_POS_MATCH_OR_ZV;
8694 break;
8696 result = MOVE_LINE_TRUNCATED;
8697 break;
8699 #undef IT_RESET_X_ASCENT_DESCENT
8702 #undef BUFFER_POS_REACHED_P
8704 /* If we scanned beyond to_pos and didn't find a point to wrap at,
8705 restore the saved iterator. */
8706 if (atpos_it.sp >= 0)
8707 RESTORE_IT (it, &atpos_it, atpos_data);
8708 else if (atx_it.sp >= 0)
8709 RESTORE_IT (it, &atx_it, atx_data);
8711 done:
8713 if (atpos_data)
8714 bidi_unshelve_cache (atpos_data, 1);
8715 if (atx_data)
8716 bidi_unshelve_cache (atx_data, 1);
8717 if (wrap_data)
8718 bidi_unshelve_cache (wrap_data, 1);
8719 if (ppos_data)
8720 bidi_unshelve_cache (ppos_data, 1);
8722 /* Restore the iterator settings altered at the beginning of this
8723 function. */
8724 it->glyph_row = saved_glyph_row;
8725 return result;
8728 /* For external use. */
8729 void
8730 move_it_in_display_line (struct it *it,
8731 ptrdiff_t to_charpos, int to_x,
8732 enum move_operation_enum op)
8734 if (it->line_wrap == WORD_WRAP
8735 && (op & MOVE_TO_X))
8737 struct it save_it;
8738 void *save_data = NULL;
8739 int skip;
8741 SAVE_IT (save_it, *it, save_data);
8742 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
8743 /* When word-wrap is on, TO_X may lie past the end
8744 of a wrapped line. Then it->current is the
8745 character on the next line, so backtrack to the
8746 space before the wrap point. */
8747 if (skip == MOVE_LINE_CONTINUED)
8749 int prev_x = max (it->current_x - 1, 0);
8750 RESTORE_IT (it, &save_it, save_data);
8751 move_it_in_display_line_to
8752 (it, -1, prev_x, MOVE_TO_X);
8754 else
8755 bidi_unshelve_cache (save_data, 1);
8757 else
8758 move_it_in_display_line_to (it, to_charpos, to_x, op);
8762 /* Move IT forward until it satisfies one or more of the criteria in
8763 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
8765 OP is a bit-mask that specifies where to stop, and in particular,
8766 which of those four position arguments makes a difference. See the
8767 description of enum move_operation_enum.
8769 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
8770 screen line, this function will set IT to the next position that is
8771 displayed to the right of TO_CHARPOS on the screen. */
8773 void
8774 move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos, int op)
8776 enum move_it_result skip, skip2 = MOVE_X_REACHED;
8777 int line_height, line_start_x = 0, reached = 0;
8778 void *backup_data = NULL;
8780 for (;;)
8782 if (op & MOVE_TO_VPOS)
8784 /* If no TO_CHARPOS and no TO_X specified, stop at the
8785 start of the line TO_VPOS. */
8786 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
8788 if (it->vpos == to_vpos)
8790 reached = 1;
8791 break;
8793 else
8794 skip = move_it_in_display_line_to (it, -1, -1, 0);
8796 else
8798 /* TO_VPOS >= 0 means stop at TO_X in the line at
8799 TO_VPOS, or at TO_POS, whichever comes first. */
8800 if (it->vpos == to_vpos)
8802 reached = 2;
8803 break;
8806 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
8808 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
8810 reached = 3;
8811 break;
8813 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
8815 /* We have reached TO_X but not in the line we want. */
8816 skip = move_it_in_display_line_to (it, to_charpos,
8817 -1, MOVE_TO_POS);
8818 if (skip == MOVE_POS_MATCH_OR_ZV)
8820 reached = 4;
8821 break;
8826 else if (op & MOVE_TO_Y)
8828 struct it it_backup;
8830 if (it->line_wrap == WORD_WRAP)
8831 SAVE_IT (it_backup, *it, backup_data);
8833 /* TO_Y specified means stop at TO_X in the line containing
8834 TO_Y---or at TO_CHARPOS if this is reached first. The
8835 problem is that we can't really tell whether the line
8836 contains TO_Y before we have completely scanned it, and
8837 this may skip past TO_X. What we do is to first scan to
8838 TO_X.
8840 If TO_X is not specified, use a TO_X of zero. The reason
8841 is to make the outcome of this function more predictable.
8842 If we didn't use TO_X == 0, we would stop at the end of
8843 the line which is probably not what a caller would expect
8844 to happen. */
8845 skip = move_it_in_display_line_to
8846 (it, to_charpos, ((op & MOVE_TO_X) ? to_x : 0),
8847 (MOVE_TO_X | (op & MOVE_TO_POS)));
8849 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
8850 if (skip == MOVE_POS_MATCH_OR_ZV)
8851 reached = 5;
8852 else if (skip == MOVE_X_REACHED)
8854 /* If TO_X was reached, we want to know whether TO_Y is
8855 in the line. We know this is the case if the already
8856 scanned glyphs make the line tall enough. Otherwise,
8857 we must check by scanning the rest of the line. */
8858 line_height = it->max_ascent + it->max_descent;
8859 if (to_y >= it->current_y
8860 && to_y < it->current_y + line_height)
8862 reached = 6;
8863 break;
8865 SAVE_IT (it_backup, *it, backup_data);
8866 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
8867 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
8868 op & MOVE_TO_POS);
8869 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
8870 line_height = it->max_ascent + it->max_descent;
8871 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
8873 if (to_y >= it->current_y
8874 && to_y < it->current_y + line_height)
8876 /* If TO_Y is in this line and TO_X was reached
8877 above, we scanned too far. We have to restore
8878 IT's settings to the ones before skipping. But
8879 keep the more accurate values of max_ascent and
8880 max_descent we've found while skipping the rest
8881 of the line, for the sake of callers, such as
8882 pos_visible_p, that need to know the line
8883 height. */
8884 int max_ascent = it->max_ascent;
8885 int max_descent = it->max_descent;
8887 RESTORE_IT (it, &it_backup, backup_data);
8888 it->max_ascent = max_ascent;
8889 it->max_descent = max_descent;
8890 reached = 6;
8892 else
8894 skip = skip2;
8895 if (skip == MOVE_POS_MATCH_OR_ZV)
8896 reached = 7;
8899 else
8901 /* Check whether TO_Y is in this line. */
8902 line_height = it->max_ascent + it->max_descent;
8903 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
8905 if (to_y >= it->current_y
8906 && to_y < it->current_y + line_height)
8908 /* When word-wrap is on, TO_X may lie past the end
8909 of a wrapped line. Then it->current is the
8910 character on the next line, so backtrack to the
8911 space before the wrap point. */
8912 if (skip == MOVE_LINE_CONTINUED
8913 && it->line_wrap == WORD_WRAP)
8915 int prev_x = max (it->current_x - 1, 0);
8916 RESTORE_IT (it, &it_backup, backup_data);
8917 skip = move_it_in_display_line_to
8918 (it, -1, prev_x, MOVE_TO_X);
8920 reached = 6;
8924 if (reached)
8925 break;
8927 else if (BUFFERP (it->object)
8928 && (it->method == GET_FROM_BUFFER
8929 || it->method == GET_FROM_STRETCH)
8930 && IT_CHARPOS (*it) >= to_charpos
8931 /* Under bidi iteration, a call to set_iterator_to_next
8932 can scan far beyond to_charpos if the initial
8933 portion of the next line needs to be reordered. In
8934 that case, give move_it_in_display_line_to another
8935 chance below. */
8936 && !(it->bidi_p
8937 && it->bidi_it.scan_dir == -1))
8938 skip = MOVE_POS_MATCH_OR_ZV;
8939 else
8940 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
8942 switch (skip)
8944 case MOVE_POS_MATCH_OR_ZV:
8945 reached = 8;
8946 goto out;
8948 case MOVE_NEWLINE_OR_CR:
8949 set_iterator_to_next (it, 1);
8950 it->continuation_lines_width = 0;
8951 break;
8953 case MOVE_LINE_TRUNCATED:
8954 it->continuation_lines_width = 0;
8955 reseat_at_next_visible_line_start (it, 0);
8956 if ((op & MOVE_TO_POS) != 0
8957 && IT_CHARPOS (*it) > to_charpos)
8959 reached = 9;
8960 goto out;
8962 break;
8964 case MOVE_LINE_CONTINUED:
8965 /* For continued lines ending in a tab, some of the glyphs
8966 associated with the tab are displayed on the current
8967 line. Since it->current_x does not include these glyphs,
8968 we use it->last_visible_x instead. */
8969 if (it->c == '\t')
8971 it->continuation_lines_width += it->last_visible_x;
8972 /* When moving by vpos, ensure that the iterator really
8973 advances to the next line (bug#847, bug#969). Fixme:
8974 do we need to do this in other circumstances? */
8975 if (it->current_x != it->last_visible_x
8976 && (op & MOVE_TO_VPOS)
8977 && !(op & (MOVE_TO_X | MOVE_TO_POS)))
8979 line_start_x = it->current_x + it->pixel_width
8980 - it->last_visible_x;
8981 set_iterator_to_next (it, 0);
8984 else
8985 it->continuation_lines_width += it->current_x;
8986 break;
8988 default:
8989 emacs_abort ();
8992 /* Reset/increment for the next run. */
8993 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
8994 it->current_x = line_start_x;
8995 line_start_x = 0;
8996 it->hpos = 0;
8997 it->current_y += it->max_ascent + it->max_descent;
8998 ++it->vpos;
8999 last_height = it->max_ascent + it->max_descent;
9000 it->max_ascent = it->max_descent = 0;
9003 out:
9005 /* On text terminals, we may stop at the end of a line in the middle
9006 of a multi-character glyph. If the glyph itself is continued,
9007 i.e. it is actually displayed on the next line, don't treat this
9008 stopping point as valid; move to the next line instead (unless
9009 that brings us offscreen). */
9010 if (!FRAME_WINDOW_P (it->f)
9011 && op & MOVE_TO_POS
9012 && IT_CHARPOS (*it) == to_charpos
9013 && it->what == IT_CHARACTER
9014 && it->nglyphs > 1
9015 && it->line_wrap == WINDOW_WRAP
9016 && it->current_x == it->last_visible_x - 1
9017 && it->c != '\n'
9018 && it->c != '\t'
9019 && it->vpos < XFASTINT (it->w->window_end_vpos))
9021 it->continuation_lines_width += it->current_x;
9022 it->current_x = it->hpos = it->max_ascent = it->max_descent = 0;
9023 it->current_y += it->max_ascent + it->max_descent;
9024 ++it->vpos;
9025 last_height = it->max_ascent + it->max_descent;
9028 if (backup_data)
9029 bidi_unshelve_cache (backup_data, 1);
9031 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
9035 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
9037 If DY > 0, move IT backward at least that many pixels. DY = 0
9038 means move IT backward to the preceding line start or BEGV. This
9039 function may move over more than DY pixels if IT->current_y - DY
9040 ends up in the middle of a line; in this case IT->current_y will be
9041 set to the top of the line moved to. */
9043 void
9044 move_it_vertically_backward (struct it *it, int dy)
9046 int nlines, h;
9047 struct it it2, it3;
9048 void *it2data = NULL, *it3data = NULL;
9049 ptrdiff_t start_pos;
9050 int nchars_per_row
9051 = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
9052 ptrdiff_t pos_limit;
9054 move_further_back:
9055 eassert (dy >= 0);
9057 start_pos = IT_CHARPOS (*it);
9059 /* Estimate how many newlines we must move back. */
9060 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
9061 if (it->line_wrap == TRUNCATE)
9062 pos_limit = BEGV;
9063 else
9064 pos_limit = max (start_pos - nlines * nchars_per_row, BEGV);
9066 /* Set the iterator's position that many lines back. But don't go
9067 back more than NLINES full screen lines -- this wins a day with
9068 buffers which have very long lines. */
9069 while (nlines-- && IT_CHARPOS (*it) > pos_limit)
9070 back_to_previous_visible_line_start (it);
9072 /* Reseat the iterator here. When moving backward, we don't want
9073 reseat to skip forward over invisible text, set up the iterator
9074 to deliver from overlay strings at the new position etc. So,
9075 use reseat_1 here. */
9076 reseat_1 (it, it->current.pos, 1);
9078 /* We are now surely at a line start. */
9079 it->current_x = it->hpos = 0; /* FIXME: this is incorrect when bidi
9080 reordering is in effect. */
9081 it->continuation_lines_width = 0;
9083 /* Move forward and see what y-distance we moved. First move to the
9084 start of the next line so that we get its height. We need this
9085 height to be able to tell whether we reached the specified
9086 y-distance. */
9087 SAVE_IT (it2, *it, it2data);
9088 it2.max_ascent = it2.max_descent = 0;
9091 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
9092 MOVE_TO_POS | MOVE_TO_VPOS);
9094 while (!(IT_POS_VALID_AFTER_MOVE_P (&it2)
9095 /* If we are in a display string which starts at START_POS,
9096 and that display string includes a newline, and we are
9097 right after that newline (i.e. at the beginning of a
9098 display line), exit the loop, because otherwise we will
9099 infloop, since move_it_to will see that it is already at
9100 START_POS and will not move. */
9101 || (it2.method == GET_FROM_STRING
9102 && IT_CHARPOS (it2) == start_pos
9103 && SREF (it2.string, IT_STRING_BYTEPOS (it2) - 1) == '\n')));
9104 eassert (IT_CHARPOS (*it) >= BEGV);
9105 SAVE_IT (it3, it2, it3data);
9107 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
9108 eassert (IT_CHARPOS (*it) >= BEGV);
9109 /* H is the actual vertical distance from the position in *IT
9110 and the starting position. */
9111 h = it2.current_y - it->current_y;
9112 /* NLINES is the distance in number of lines. */
9113 nlines = it2.vpos - it->vpos;
9115 /* Correct IT's y and vpos position
9116 so that they are relative to the starting point. */
9117 it->vpos -= nlines;
9118 it->current_y -= h;
9120 if (dy == 0)
9122 /* DY == 0 means move to the start of the screen line. The
9123 value of nlines is > 0 if continuation lines were involved,
9124 or if the original IT position was at start of a line. */
9125 RESTORE_IT (it, it, it2data);
9126 if (nlines > 0)
9127 move_it_by_lines (it, nlines);
9128 /* The above code moves us to some position NLINES down,
9129 usually to its first glyph (leftmost in an L2R line), but
9130 that's not necessarily the start of the line, under bidi
9131 reordering. We want to get to the character position
9132 that is immediately after the newline of the previous
9133 line. */
9134 if (it->bidi_p
9135 && !it->continuation_lines_width
9136 && !STRINGP (it->string)
9137 && IT_CHARPOS (*it) > BEGV
9138 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9140 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
9142 DEC_BOTH (cp, bp);
9143 cp = find_newline_no_quit (cp, bp, -1, NULL);
9144 move_it_to (it, cp, -1, -1, -1, MOVE_TO_POS);
9146 bidi_unshelve_cache (it3data, 1);
9148 else
9150 /* The y-position we try to reach, relative to *IT.
9151 Note that H has been subtracted in front of the if-statement. */
9152 int target_y = it->current_y + h - dy;
9153 int y0 = it3.current_y;
9154 int y1;
9155 int line_height;
9157 RESTORE_IT (&it3, &it3, it3data);
9158 y1 = line_bottom_y (&it3);
9159 line_height = y1 - y0;
9160 RESTORE_IT (it, it, it2data);
9161 /* If we did not reach target_y, try to move further backward if
9162 we can. If we moved too far backward, try to move forward. */
9163 if (target_y < it->current_y
9164 /* This is heuristic. In a window that's 3 lines high, with
9165 a line height of 13 pixels each, recentering with point
9166 on the bottom line will try to move -39/2 = 19 pixels
9167 backward. Try to avoid moving into the first line. */
9168 && (it->current_y - target_y
9169 > min (window_box_height (it->w), line_height * 2 / 3))
9170 && IT_CHARPOS (*it) > BEGV)
9172 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
9173 target_y - it->current_y));
9174 dy = it->current_y - target_y;
9175 goto move_further_back;
9177 else if (target_y >= it->current_y + line_height
9178 && IT_CHARPOS (*it) < ZV)
9180 /* Should move forward by at least one line, maybe more.
9182 Note: Calling move_it_by_lines can be expensive on
9183 terminal frames, where compute_motion is used (via
9184 vmotion) to do the job, when there are very long lines
9185 and truncate-lines is nil. That's the reason for
9186 treating terminal frames specially here. */
9188 if (!FRAME_WINDOW_P (it->f))
9189 move_it_vertically (it, target_y - (it->current_y + line_height));
9190 else
9194 move_it_by_lines (it, 1);
9196 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
9203 /* Move IT by a specified amount of pixel lines DY. DY negative means
9204 move backwards. DY = 0 means move to start of screen line. At the
9205 end, IT will be on the start of a screen line. */
9207 void
9208 move_it_vertically (struct it *it, int dy)
9210 if (dy <= 0)
9211 move_it_vertically_backward (it, -dy);
9212 else
9214 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
9215 move_it_to (it, ZV, -1, it->current_y + dy, -1,
9216 MOVE_TO_POS | MOVE_TO_Y);
9217 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
9219 /* If buffer ends in ZV without a newline, move to the start of
9220 the line to satisfy the post-condition. */
9221 if (IT_CHARPOS (*it) == ZV
9222 && ZV > BEGV
9223 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9224 move_it_by_lines (it, 0);
9229 /* Move iterator IT past the end of the text line it is in. */
9231 void
9232 move_it_past_eol (struct it *it)
9234 enum move_it_result rc;
9236 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
9237 if (rc == MOVE_NEWLINE_OR_CR)
9238 set_iterator_to_next (it, 0);
9242 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
9243 negative means move up. DVPOS == 0 means move to the start of the
9244 screen line.
9246 Optimization idea: If we would know that IT->f doesn't use
9247 a face with proportional font, we could be faster for
9248 truncate-lines nil. */
9250 void
9251 move_it_by_lines (struct it *it, ptrdiff_t dvpos)
9254 /* The commented-out optimization uses vmotion on terminals. This
9255 gives bad results, because elements like it->what, on which
9256 callers such as pos_visible_p rely, aren't updated. */
9257 /* struct position pos;
9258 if (!FRAME_WINDOW_P (it->f))
9260 struct text_pos textpos;
9262 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
9263 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
9264 reseat (it, textpos, 1);
9265 it->vpos += pos.vpos;
9266 it->current_y += pos.vpos;
9268 else */
9270 if (dvpos == 0)
9272 /* DVPOS == 0 means move to the start of the screen line. */
9273 move_it_vertically_backward (it, 0);
9274 /* Let next call to line_bottom_y calculate real line height */
9275 last_height = 0;
9277 else if (dvpos > 0)
9279 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
9280 if (!IT_POS_VALID_AFTER_MOVE_P (it))
9282 /* Only move to the next buffer position if we ended up in a
9283 string from display property, not in an overlay string
9284 (before-string or after-string). That is because the
9285 latter don't conceal the underlying buffer position, so
9286 we can ask to move the iterator to the exact position we
9287 are interested in. Note that, even if we are already at
9288 IT_CHARPOS (*it), the call below is not a no-op, as it
9289 will detect that we are at the end of the string, pop the
9290 iterator, and compute it->current_x and it->hpos
9291 correctly. */
9292 move_it_to (it, IT_CHARPOS (*it) + it->string_from_display_prop_p,
9293 -1, -1, -1, MOVE_TO_POS);
9296 else
9298 struct it it2;
9299 void *it2data = NULL;
9300 ptrdiff_t start_charpos, i;
9301 int nchars_per_row
9302 = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
9303 ptrdiff_t pos_limit;
9305 /* Start at the beginning of the screen line containing IT's
9306 position. This may actually move vertically backwards,
9307 in case of overlays, so adjust dvpos accordingly. */
9308 dvpos += it->vpos;
9309 move_it_vertically_backward (it, 0);
9310 dvpos -= it->vpos;
9312 /* Go back -DVPOS buffer lines, but no farther than -DVPOS full
9313 screen lines, and reseat the iterator there. */
9314 start_charpos = IT_CHARPOS (*it);
9315 if (it->line_wrap == TRUNCATE)
9316 pos_limit = BEGV;
9317 else
9318 pos_limit = max (start_charpos + dvpos * nchars_per_row, BEGV);
9319 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > pos_limit; --i)
9320 back_to_previous_visible_line_start (it);
9321 reseat (it, it->current.pos, 1);
9323 /* Move further back if we end up in a string or an image. */
9324 while (!IT_POS_VALID_AFTER_MOVE_P (it))
9326 /* First try to move to start of display line. */
9327 dvpos += it->vpos;
9328 move_it_vertically_backward (it, 0);
9329 dvpos -= it->vpos;
9330 if (IT_POS_VALID_AFTER_MOVE_P (it))
9331 break;
9332 /* If start of line is still in string or image,
9333 move further back. */
9334 back_to_previous_visible_line_start (it);
9335 reseat (it, it->current.pos, 1);
9336 dvpos--;
9339 it->current_x = it->hpos = 0;
9341 /* Above call may have moved too far if continuation lines
9342 are involved. Scan forward and see if it did. */
9343 SAVE_IT (it2, *it, it2data);
9344 it2.vpos = it2.current_y = 0;
9345 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
9346 it->vpos -= it2.vpos;
9347 it->current_y -= it2.current_y;
9348 it->current_x = it->hpos = 0;
9350 /* If we moved too far back, move IT some lines forward. */
9351 if (it2.vpos > -dvpos)
9353 int delta = it2.vpos + dvpos;
9355 RESTORE_IT (&it2, &it2, it2data);
9356 SAVE_IT (it2, *it, it2data);
9357 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
9358 /* Move back again if we got too far ahead. */
9359 if (IT_CHARPOS (*it) >= start_charpos)
9360 RESTORE_IT (it, &it2, it2data);
9361 else
9362 bidi_unshelve_cache (it2data, 1);
9364 else
9365 RESTORE_IT (it, it, it2data);
9369 /* Return 1 if IT points into the middle of a display vector. */
9372 in_display_vector_p (struct it *it)
9374 return (it->method == GET_FROM_DISPLAY_VECTOR
9375 && it->current.dpvec_index > 0
9376 && it->dpvec + it->current.dpvec_index != it->dpend);
9380 /***********************************************************************
9381 Messages
9382 ***********************************************************************/
9385 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
9386 to *Messages*. */
9388 void
9389 add_to_log (const char *format, Lisp_Object arg1, Lisp_Object arg2)
9391 Lisp_Object args[3];
9392 Lisp_Object msg, fmt;
9393 char *buffer;
9394 ptrdiff_t len;
9395 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
9396 USE_SAFE_ALLOCA;
9398 fmt = msg = Qnil;
9399 GCPRO4 (fmt, msg, arg1, arg2);
9401 args[0] = fmt = build_string (format);
9402 args[1] = arg1;
9403 args[2] = arg2;
9404 msg = Fformat (3, args);
9406 len = SBYTES (msg) + 1;
9407 buffer = SAFE_ALLOCA (len);
9408 memcpy (buffer, SDATA (msg), len);
9410 message_dolog (buffer, len - 1, 1, 0);
9411 SAFE_FREE ();
9413 UNGCPRO;
9417 /* Output a newline in the *Messages* buffer if "needs" one. */
9419 void
9420 message_log_maybe_newline (void)
9422 if (message_log_need_newline)
9423 message_dolog ("", 0, 1, 0);
9427 /* Add a string M of length NBYTES to the message log, optionally
9428 terminated with a newline when NLFLAG is true. MULTIBYTE, if
9429 true, means interpret the contents of M as multibyte. This
9430 function calls low-level routines in order to bypass text property
9431 hooks, etc. which might not be safe to run.
9433 This may GC (insert may run before/after change hooks),
9434 so the buffer M must NOT point to a Lisp string. */
9436 void
9437 message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte)
9439 const unsigned char *msg = (const unsigned char *) m;
9441 if (!NILP (Vmemory_full))
9442 return;
9444 if (!NILP (Vmessage_log_max))
9446 struct buffer *oldbuf;
9447 Lisp_Object oldpoint, oldbegv, oldzv;
9448 int old_windows_or_buffers_changed = windows_or_buffers_changed;
9449 ptrdiff_t point_at_end = 0;
9450 ptrdiff_t zv_at_end = 0;
9451 Lisp_Object old_deactivate_mark;
9452 bool shown;
9453 struct gcpro gcpro1;
9455 old_deactivate_mark = Vdeactivate_mark;
9456 oldbuf = current_buffer;
9457 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
9458 bset_undo_list (current_buffer, Qt);
9460 oldpoint = message_dolog_marker1;
9461 set_marker_restricted_both (oldpoint, Qnil, PT, PT_BYTE);
9462 oldbegv = message_dolog_marker2;
9463 set_marker_restricted_both (oldbegv, Qnil, BEGV, BEGV_BYTE);
9464 oldzv = message_dolog_marker3;
9465 set_marker_restricted_both (oldzv, Qnil, ZV, ZV_BYTE);
9466 GCPRO1 (old_deactivate_mark);
9468 if (PT == Z)
9469 point_at_end = 1;
9470 if (ZV == Z)
9471 zv_at_end = 1;
9473 BEGV = BEG;
9474 BEGV_BYTE = BEG_BYTE;
9475 ZV = Z;
9476 ZV_BYTE = Z_BYTE;
9477 TEMP_SET_PT_BOTH (Z, Z_BYTE);
9479 /* Insert the string--maybe converting multibyte to single byte
9480 or vice versa, so that all the text fits the buffer. */
9481 if (multibyte
9482 && NILP (BVAR (current_buffer, enable_multibyte_characters)))
9484 ptrdiff_t i;
9485 int c, char_bytes;
9486 char work[1];
9488 /* Convert a multibyte string to single-byte
9489 for the *Message* buffer. */
9490 for (i = 0; i < nbytes; i += char_bytes)
9492 c = string_char_and_length (msg + i, &char_bytes);
9493 work[0] = (ASCII_CHAR_P (c)
9495 : multibyte_char_to_unibyte (c));
9496 insert_1_both (work, 1, 1, 1, 0, 0);
9499 else if (! multibyte
9500 && ! NILP (BVAR (current_buffer, enable_multibyte_characters)))
9502 ptrdiff_t i;
9503 int c, char_bytes;
9504 unsigned char str[MAX_MULTIBYTE_LENGTH];
9505 /* Convert a single-byte string to multibyte
9506 for the *Message* buffer. */
9507 for (i = 0; i < nbytes; i++)
9509 c = msg[i];
9510 MAKE_CHAR_MULTIBYTE (c);
9511 char_bytes = CHAR_STRING (c, str);
9512 insert_1_both ((char *) str, 1, char_bytes, 1, 0, 0);
9515 else if (nbytes)
9516 insert_1_both (m, chars_in_text (msg, nbytes), nbytes, 1, 0, 0);
9518 if (nlflag)
9520 ptrdiff_t this_bol, this_bol_byte, prev_bol, prev_bol_byte;
9521 printmax_t dups;
9523 insert_1_both ("\n", 1, 1, 1, 0, 0);
9525 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
9526 this_bol = PT;
9527 this_bol_byte = PT_BYTE;
9529 /* See if this line duplicates the previous one.
9530 If so, combine duplicates. */
9531 if (this_bol > BEG)
9533 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
9534 prev_bol = PT;
9535 prev_bol_byte = PT_BYTE;
9537 dups = message_log_check_duplicate (prev_bol_byte,
9538 this_bol_byte);
9539 if (dups)
9541 del_range_both (prev_bol, prev_bol_byte,
9542 this_bol, this_bol_byte, 0);
9543 if (dups > 1)
9545 char dupstr[sizeof " [ times]"
9546 + INT_STRLEN_BOUND (printmax_t)];
9548 /* If you change this format, don't forget to also
9549 change message_log_check_duplicate. */
9550 int duplen = sprintf (dupstr, " [%"pMd" times]", dups);
9551 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
9552 insert_1_both (dupstr, duplen, duplen, 1, 0, 1);
9557 /* If we have more than the desired maximum number of lines
9558 in the *Messages* buffer now, delete the oldest ones.
9559 This is safe because we don't have undo in this buffer. */
9561 if (NATNUMP (Vmessage_log_max))
9563 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
9564 -XFASTINT (Vmessage_log_max) - 1, 0);
9565 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
9568 BEGV = marker_position (oldbegv);
9569 BEGV_BYTE = marker_byte_position (oldbegv);
9571 if (zv_at_end)
9573 ZV = Z;
9574 ZV_BYTE = Z_BYTE;
9576 else
9578 ZV = marker_position (oldzv);
9579 ZV_BYTE = marker_byte_position (oldzv);
9582 if (point_at_end)
9583 TEMP_SET_PT_BOTH (Z, Z_BYTE);
9584 else
9585 /* We can't do Fgoto_char (oldpoint) because it will run some
9586 Lisp code. */
9587 TEMP_SET_PT_BOTH (marker_position (oldpoint),
9588 marker_byte_position (oldpoint));
9590 UNGCPRO;
9591 unchain_marker (XMARKER (oldpoint));
9592 unchain_marker (XMARKER (oldbegv));
9593 unchain_marker (XMARKER (oldzv));
9595 shown = buffer_window_count (current_buffer) > 0;
9596 set_buffer_internal (oldbuf);
9597 /* We called insert_1_both above with its 5th argument (PREPARE)
9598 zero, which prevents insert_1_both from calling
9599 prepare_to_modify_buffer, which in turns prevents us from
9600 incrementing windows_or_buffers_changed even if *Messages* is
9601 shown in some window. So we must manually incrementing
9602 windows_or_buffers_changed here to make up for that. */
9603 if (shown)
9604 windows_or_buffers_changed++;
9605 else
9606 windows_or_buffers_changed = old_windows_or_buffers_changed;
9607 message_log_need_newline = !nlflag;
9608 Vdeactivate_mark = old_deactivate_mark;
9613 /* We are at the end of the buffer after just having inserted a newline.
9614 (Note: We depend on the fact we won't be crossing the gap.)
9615 Check to see if the most recent message looks a lot like the previous one.
9616 Return 0 if different, 1 if the new one should just replace it, or a
9617 value N > 1 if we should also append " [N times]". */
9619 static intmax_t
9620 message_log_check_duplicate (ptrdiff_t prev_bol_byte, ptrdiff_t this_bol_byte)
9622 ptrdiff_t i;
9623 ptrdiff_t len = Z_BYTE - 1 - this_bol_byte;
9624 int seen_dots = 0;
9625 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
9626 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
9628 for (i = 0; i < len; i++)
9630 if (i >= 3 && p1[i - 3] == '.' && p1[i - 2] == '.' && p1[i - 1] == '.')
9631 seen_dots = 1;
9632 if (p1[i] != p2[i])
9633 return seen_dots;
9635 p1 += len;
9636 if (*p1 == '\n')
9637 return 2;
9638 if (*p1++ == ' ' && *p1++ == '[')
9640 char *pend;
9641 intmax_t n = strtoimax ((char *) p1, &pend, 10);
9642 if (0 < n && n < INTMAX_MAX && strncmp (pend, " times]\n", 8) == 0)
9643 return n + 1;
9645 return 0;
9649 /* Display an echo area message M with a specified length of NBYTES
9650 bytes. The string may include null characters. If M is not a
9651 string, clear out any existing message, and let the mini-buffer
9652 text show through.
9654 This function cancels echoing. */
9656 void
9657 message3 (Lisp_Object m)
9659 struct gcpro gcpro1;
9661 GCPRO1 (m);
9662 clear_message (1,1);
9663 cancel_echoing ();
9665 /* First flush out any partial line written with print. */
9666 message_log_maybe_newline ();
9667 if (STRINGP (m))
9669 ptrdiff_t nbytes = SBYTES (m);
9670 bool multibyte = STRING_MULTIBYTE (m);
9671 USE_SAFE_ALLOCA;
9672 char *buffer = SAFE_ALLOCA (nbytes);
9673 memcpy (buffer, SDATA (m), nbytes);
9674 message_dolog (buffer, nbytes, 1, multibyte);
9675 SAFE_FREE ();
9677 message3_nolog (m);
9679 UNGCPRO;
9683 /* The non-logging version of message3.
9684 This does not cancel echoing, because it is used for echoing.
9685 Perhaps we need to make a separate function for echoing
9686 and make this cancel echoing. */
9688 void
9689 message3_nolog (Lisp_Object m)
9691 struct frame *sf = SELECTED_FRAME ();
9693 if (FRAME_INITIAL_P (sf))
9695 if (noninteractive_need_newline)
9696 putc ('\n', stderr);
9697 noninteractive_need_newline = 0;
9698 if (STRINGP (m))
9699 fwrite (SDATA (m), SBYTES (m), 1, stderr);
9700 if (cursor_in_echo_area == 0)
9701 fprintf (stderr, "\n");
9702 fflush (stderr);
9704 /* Error messages get reported properly by cmd_error, so this must be just an
9705 informative message; if the frame hasn't really been initialized yet, just
9706 toss it. */
9707 else if (INTERACTIVE && sf->glyphs_initialized_p)
9709 /* Get the frame containing the mini-buffer
9710 that the selected frame is using. */
9711 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
9712 Lisp_Object frame = XWINDOW (mini_window)->frame;
9713 struct frame *f = XFRAME (frame);
9715 if (FRAME_VISIBLE_P (sf) && !FRAME_VISIBLE_P (f))
9716 Fmake_frame_visible (frame);
9718 if (STRINGP (m) && SCHARS (m) > 0)
9720 set_message (m);
9721 if (minibuffer_auto_raise)
9722 Fraise_frame (frame);
9723 /* Assume we are not echoing.
9724 (If we are, echo_now will override this.) */
9725 echo_message_buffer = Qnil;
9727 else
9728 clear_message (1, 1);
9730 do_pending_window_change (0);
9731 echo_area_display (1);
9732 do_pending_window_change (0);
9733 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
9734 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
9739 /* Display a null-terminated echo area message M. If M is 0, clear
9740 out any existing message, and let the mini-buffer text show through.
9742 The buffer M must continue to exist until after the echo area gets
9743 cleared or some other message gets displayed there. Do not pass
9744 text that is stored in a Lisp string. Do not pass text in a buffer
9745 that was alloca'd. */
9747 void
9748 message1 (const char *m)
9750 message3 (m ? make_unibyte_string (m, strlen (m)) : Qnil);
9754 /* The non-logging counterpart of message1. */
9756 void
9757 message1_nolog (const char *m)
9759 message3_nolog (m ? make_unibyte_string (m, strlen (m)) : Qnil);
9762 /* Display a message M which contains a single %s
9763 which gets replaced with STRING. */
9765 void
9766 message_with_string (const char *m, Lisp_Object string, int log)
9768 CHECK_STRING (string);
9770 if (noninteractive)
9772 if (m)
9774 if (noninteractive_need_newline)
9775 putc ('\n', stderr);
9776 noninteractive_need_newline = 0;
9777 fprintf (stderr, m, SDATA (string));
9778 if (!cursor_in_echo_area)
9779 fprintf (stderr, "\n");
9780 fflush (stderr);
9783 else if (INTERACTIVE)
9785 /* The frame whose minibuffer we're going to display the message on.
9786 It may be larger than the selected frame, so we need
9787 to use its buffer, not the selected frame's buffer. */
9788 Lisp_Object mini_window;
9789 struct frame *f, *sf = SELECTED_FRAME ();
9791 /* Get the frame containing the minibuffer
9792 that the selected frame is using. */
9793 mini_window = FRAME_MINIBUF_WINDOW (sf);
9794 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
9796 /* Error messages get reported properly by cmd_error, so this must be
9797 just an informative message; if the frame hasn't really been
9798 initialized yet, just toss it. */
9799 if (f->glyphs_initialized_p)
9801 Lisp_Object args[2], msg;
9802 struct gcpro gcpro1, gcpro2;
9804 args[0] = build_string (m);
9805 args[1] = msg = string;
9806 GCPRO2 (args[0], msg);
9807 gcpro1.nvars = 2;
9809 msg = Fformat (2, args);
9811 if (log)
9812 message3 (msg);
9813 else
9814 message3_nolog (msg);
9816 UNGCPRO;
9818 /* Print should start at the beginning of the message
9819 buffer next time. */
9820 message_buf_print = 0;
9826 /* Dump an informative message to the minibuf. If M is 0, clear out
9827 any existing message, and let the mini-buffer text show through. */
9829 static void
9830 vmessage (const char *m, va_list ap)
9832 if (noninteractive)
9834 if (m)
9836 if (noninteractive_need_newline)
9837 putc ('\n', stderr);
9838 noninteractive_need_newline = 0;
9839 vfprintf (stderr, m, ap);
9840 if (cursor_in_echo_area == 0)
9841 fprintf (stderr, "\n");
9842 fflush (stderr);
9845 else if (INTERACTIVE)
9847 /* The frame whose mini-buffer we're going to display the message
9848 on. It may be larger than the selected frame, so we need to
9849 use its buffer, not the selected frame's buffer. */
9850 Lisp_Object mini_window;
9851 struct frame *f, *sf = SELECTED_FRAME ();
9853 /* Get the frame containing the mini-buffer
9854 that the selected frame is using. */
9855 mini_window = FRAME_MINIBUF_WINDOW (sf);
9856 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
9858 /* Error messages get reported properly by cmd_error, so this must be
9859 just an informative message; if the frame hasn't really been
9860 initialized yet, just toss it. */
9861 if (f->glyphs_initialized_p)
9863 if (m)
9865 ptrdiff_t len;
9866 ptrdiff_t maxsize = FRAME_MESSAGE_BUF_SIZE (f);
9867 char *message_buf = alloca (maxsize + 1);
9869 len = doprnt (message_buf, maxsize, m, (char *)0, ap);
9871 message3 (make_string (message_buf, len));
9873 else
9874 message1 (0);
9876 /* Print should start at the beginning of the message
9877 buffer next time. */
9878 message_buf_print = 0;
9883 void
9884 message (const char *m, ...)
9886 va_list ap;
9887 va_start (ap, m);
9888 vmessage (m, ap);
9889 va_end (ap);
9893 #if 0
9894 /* The non-logging version of message. */
9896 void
9897 message_nolog (const char *m, ...)
9899 Lisp_Object old_log_max;
9900 va_list ap;
9901 va_start (ap, m);
9902 old_log_max = Vmessage_log_max;
9903 Vmessage_log_max = Qnil;
9904 vmessage (m, ap);
9905 Vmessage_log_max = old_log_max;
9906 va_end (ap);
9908 #endif
9911 /* Display the current message in the current mini-buffer. This is
9912 only called from error handlers in process.c, and is not time
9913 critical. */
9915 void
9916 update_echo_area (void)
9918 if (!NILP (echo_area_buffer[0]))
9920 Lisp_Object string;
9921 string = Fcurrent_message ();
9922 message3 (string);
9927 /* Make sure echo area buffers in `echo_buffers' are live.
9928 If they aren't, make new ones. */
9930 static void
9931 ensure_echo_area_buffers (void)
9933 int i;
9935 for (i = 0; i < 2; ++i)
9936 if (!BUFFERP (echo_buffer[i])
9937 || !BUFFER_LIVE_P (XBUFFER (echo_buffer[i])))
9939 char name[30];
9940 Lisp_Object old_buffer;
9941 int j;
9943 old_buffer = echo_buffer[i];
9944 echo_buffer[i] = Fget_buffer_create
9945 (make_formatted_string (name, " *Echo Area %d*", i));
9946 bset_truncate_lines (XBUFFER (echo_buffer[i]), Qnil);
9947 /* to force word wrap in echo area -
9948 it was decided to postpone this*/
9949 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
9951 for (j = 0; j < 2; ++j)
9952 if (EQ (old_buffer, echo_area_buffer[j]))
9953 echo_area_buffer[j] = echo_buffer[i];
9958 /* Call FN with args A1..A2 with either the current or last displayed
9959 echo_area_buffer as current buffer.
9961 WHICH zero means use the current message buffer
9962 echo_area_buffer[0]. If that is nil, choose a suitable buffer
9963 from echo_buffer[] and clear it.
9965 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
9966 suitable buffer from echo_buffer[] and clear it.
9968 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
9969 that the current message becomes the last displayed one, make
9970 choose a suitable buffer for echo_area_buffer[0], and clear it.
9972 Value is what FN returns. */
9974 static int
9975 with_echo_area_buffer (struct window *w, int which,
9976 int (*fn) (ptrdiff_t, Lisp_Object),
9977 ptrdiff_t a1, Lisp_Object a2)
9979 Lisp_Object buffer;
9980 int this_one, the_other, clear_buffer_p, rc;
9981 ptrdiff_t count = SPECPDL_INDEX ();
9983 /* If buffers aren't live, make new ones. */
9984 ensure_echo_area_buffers ();
9986 clear_buffer_p = 0;
9988 if (which == 0)
9989 this_one = 0, the_other = 1;
9990 else if (which > 0)
9991 this_one = 1, the_other = 0;
9992 else
9994 this_one = 0, the_other = 1;
9995 clear_buffer_p = 1;
9997 /* We need a fresh one in case the current echo buffer equals
9998 the one containing the last displayed echo area message. */
9999 if (!NILP (echo_area_buffer[this_one])
10000 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
10001 echo_area_buffer[this_one] = Qnil;
10004 /* Choose a suitable buffer from echo_buffer[] is we don't
10005 have one. */
10006 if (NILP (echo_area_buffer[this_one]))
10008 echo_area_buffer[this_one]
10009 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
10010 ? echo_buffer[the_other]
10011 : echo_buffer[this_one]);
10012 clear_buffer_p = 1;
10015 buffer = echo_area_buffer[this_one];
10017 /* Don't get confused by reusing the buffer used for echoing
10018 for a different purpose. */
10019 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
10020 cancel_echoing ();
10022 record_unwind_protect (unwind_with_echo_area_buffer,
10023 with_echo_area_buffer_unwind_data (w));
10025 /* Make the echo area buffer current. Note that for display
10026 purposes, it is not necessary that the displayed window's buffer
10027 == current_buffer, except for text property lookup. So, let's
10028 only set that buffer temporarily here without doing a full
10029 Fset_window_buffer. We must also change w->pointm, though,
10030 because otherwise an assertions in unshow_buffer fails, and Emacs
10031 aborts. */
10032 set_buffer_internal_1 (XBUFFER (buffer));
10033 if (w)
10035 wset_buffer (w, buffer);
10036 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
10039 bset_undo_list (current_buffer, Qt);
10040 bset_read_only (current_buffer, Qnil);
10041 specbind (Qinhibit_read_only, Qt);
10042 specbind (Qinhibit_modification_hooks, Qt);
10044 if (clear_buffer_p && Z > BEG)
10045 del_range (BEG, Z);
10047 eassert (BEGV >= BEG);
10048 eassert (ZV <= Z && ZV >= BEGV);
10050 rc = fn (a1, a2);
10052 eassert (BEGV >= BEG);
10053 eassert (ZV <= Z && ZV >= BEGV);
10055 unbind_to (count, Qnil);
10056 return rc;
10060 /* Save state that should be preserved around the call to the function
10061 FN called in with_echo_area_buffer. */
10063 static Lisp_Object
10064 with_echo_area_buffer_unwind_data (struct window *w)
10066 int i = 0;
10067 Lisp_Object vector, tmp;
10069 /* Reduce consing by keeping one vector in
10070 Vwith_echo_area_save_vector. */
10071 vector = Vwith_echo_area_save_vector;
10072 Vwith_echo_area_save_vector = Qnil;
10074 if (NILP (vector))
10075 vector = Fmake_vector (make_number (9), Qnil);
10077 XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
10078 ASET (vector, i, Vdeactivate_mark); ++i;
10079 ASET (vector, i, make_number (windows_or_buffers_changed)); ++i;
10081 if (w)
10083 XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i;
10084 ASET (vector, i, w->contents); ++i;
10085 ASET (vector, i, make_number (marker_position (w->pointm))); ++i;
10086 ASET (vector, i, make_number (marker_byte_position (w->pointm))); ++i;
10087 ASET (vector, i, make_number (marker_position (w->start))); ++i;
10088 ASET (vector, i, make_number (marker_byte_position (w->start))); ++i;
10090 else
10092 int end = i + 6;
10093 for (; i < end; ++i)
10094 ASET (vector, i, Qnil);
10097 eassert (i == ASIZE (vector));
10098 return vector;
10102 /* Restore global state from VECTOR which was created by
10103 with_echo_area_buffer_unwind_data. */
10105 static Lisp_Object
10106 unwind_with_echo_area_buffer (Lisp_Object vector)
10108 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
10109 Vdeactivate_mark = AREF (vector, 1);
10110 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
10112 if (WINDOWP (AREF (vector, 3)))
10114 struct window *w;
10115 Lisp_Object buffer;
10117 w = XWINDOW (AREF (vector, 3));
10118 buffer = AREF (vector, 4);
10120 wset_buffer (w, buffer);
10121 set_marker_both (w->pointm, buffer,
10122 XFASTINT (AREF (vector, 5)),
10123 XFASTINT (AREF (vector, 6)));
10124 set_marker_both (w->start, buffer,
10125 XFASTINT (AREF (vector, 7)),
10126 XFASTINT (AREF (vector, 8)));
10129 Vwith_echo_area_save_vector = vector;
10130 return Qnil;
10134 /* Set up the echo area for use by print functions. MULTIBYTE_P
10135 non-zero means we will print multibyte. */
10137 void
10138 setup_echo_area_for_printing (int multibyte_p)
10140 /* If we can't find an echo area any more, exit. */
10141 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
10142 Fkill_emacs (Qnil);
10144 ensure_echo_area_buffers ();
10146 if (!message_buf_print)
10148 /* A message has been output since the last time we printed.
10149 Choose a fresh echo area buffer. */
10150 if (EQ (echo_area_buffer[1], echo_buffer[0]))
10151 echo_area_buffer[0] = echo_buffer[1];
10152 else
10153 echo_area_buffer[0] = echo_buffer[0];
10155 /* Switch to that buffer and clear it. */
10156 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
10157 bset_truncate_lines (current_buffer, Qnil);
10159 if (Z > BEG)
10161 ptrdiff_t count = SPECPDL_INDEX ();
10162 specbind (Qinhibit_read_only, Qt);
10163 /* Note that undo recording is always disabled. */
10164 del_range (BEG, Z);
10165 unbind_to (count, Qnil);
10167 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
10169 /* Set up the buffer for the multibyteness we need. */
10170 if (multibyte_p
10171 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
10172 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
10174 /* Raise the frame containing the echo area. */
10175 if (minibuffer_auto_raise)
10177 struct frame *sf = SELECTED_FRAME ();
10178 Lisp_Object mini_window;
10179 mini_window = FRAME_MINIBUF_WINDOW (sf);
10180 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
10183 message_log_maybe_newline ();
10184 message_buf_print = 1;
10186 else
10188 if (NILP (echo_area_buffer[0]))
10190 if (EQ (echo_area_buffer[1], echo_buffer[0]))
10191 echo_area_buffer[0] = echo_buffer[1];
10192 else
10193 echo_area_buffer[0] = echo_buffer[0];
10196 if (current_buffer != XBUFFER (echo_area_buffer[0]))
10198 /* Someone switched buffers between print requests. */
10199 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
10200 bset_truncate_lines (current_buffer, Qnil);
10206 /* Display an echo area message in window W. Value is non-zero if W's
10207 height is changed. If display_last_displayed_message_p is
10208 non-zero, display the message that was last displayed, otherwise
10209 display the current message. */
10211 static int
10212 display_echo_area (struct window *w)
10214 int i, no_message_p, window_height_changed_p;
10216 /* Temporarily disable garbage collections while displaying the echo
10217 area. This is done because a GC can print a message itself.
10218 That message would modify the echo area buffer's contents while a
10219 redisplay of the buffer is going on, and seriously confuse
10220 redisplay. */
10221 ptrdiff_t count = inhibit_garbage_collection ();
10223 /* If there is no message, we must call display_echo_area_1
10224 nevertheless because it resizes the window. But we will have to
10225 reset the echo_area_buffer in question to nil at the end because
10226 with_echo_area_buffer will sets it to an empty buffer. */
10227 i = display_last_displayed_message_p ? 1 : 0;
10228 no_message_p = NILP (echo_area_buffer[i]);
10230 window_height_changed_p
10231 = with_echo_area_buffer (w, display_last_displayed_message_p,
10232 display_echo_area_1,
10233 (intptr_t) w, Qnil);
10235 if (no_message_p)
10236 echo_area_buffer[i] = Qnil;
10238 unbind_to (count, Qnil);
10239 return window_height_changed_p;
10243 /* Helper for display_echo_area. Display the current buffer which
10244 contains the current echo area message in window W, a mini-window,
10245 a pointer to which is passed in A1. A2..A4 are currently not used.
10246 Change the height of W so that all of the message is displayed.
10247 Value is non-zero if height of W was changed. */
10249 static int
10250 display_echo_area_1 (ptrdiff_t a1, Lisp_Object a2)
10252 intptr_t i1 = a1;
10253 struct window *w = (struct window *) i1;
10254 Lisp_Object window;
10255 struct text_pos start;
10256 int window_height_changed_p = 0;
10258 /* Do this before displaying, so that we have a large enough glyph
10259 matrix for the display. If we can't get enough space for the
10260 whole text, display the last N lines. That works by setting w->start. */
10261 window_height_changed_p = resize_mini_window (w, 0);
10263 /* Use the starting position chosen by resize_mini_window. */
10264 SET_TEXT_POS_FROM_MARKER (start, w->start);
10266 /* Display. */
10267 clear_glyph_matrix (w->desired_matrix);
10268 XSETWINDOW (window, w);
10269 try_window (window, start, 0);
10271 return window_height_changed_p;
10275 /* Resize the echo area window to exactly the size needed for the
10276 currently displayed message, if there is one. If a mini-buffer
10277 is active, don't shrink it. */
10279 void
10280 resize_echo_area_exactly (void)
10282 if (BUFFERP (echo_area_buffer[0])
10283 && WINDOWP (echo_area_window))
10285 struct window *w = XWINDOW (echo_area_window);
10286 int resized_p;
10287 Lisp_Object resize_exactly;
10289 if (minibuf_level == 0)
10290 resize_exactly = Qt;
10291 else
10292 resize_exactly = Qnil;
10294 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
10295 (intptr_t) w, resize_exactly);
10296 if (resized_p)
10298 ++windows_or_buffers_changed;
10299 ++update_mode_lines;
10300 redisplay_internal ();
10306 /* Callback function for with_echo_area_buffer, when used from
10307 resize_echo_area_exactly. A1 contains a pointer to the window to
10308 resize, EXACTLY non-nil means resize the mini-window exactly to the
10309 size of the text displayed. A3 and A4 are not used. Value is what
10310 resize_mini_window returns. */
10312 static int
10313 resize_mini_window_1 (ptrdiff_t a1, Lisp_Object exactly)
10315 intptr_t i1 = a1;
10316 return resize_mini_window ((struct window *) i1, !NILP (exactly));
10320 /* Resize mini-window W to fit the size of its contents. EXACT_P
10321 means size the window exactly to the size needed. Otherwise, it's
10322 only enlarged until W's buffer is empty.
10324 Set W->start to the right place to begin display. If the whole
10325 contents fit, start at the beginning. Otherwise, start so as
10326 to make the end of the contents appear. This is particularly
10327 important for y-or-n-p, but seems desirable generally.
10329 Value is non-zero if the window height has been changed. */
10332 resize_mini_window (struct window *w, int exact_p)
10334 struct frame *f = XFRAME (w->frame);
10335 int window_height_changed_p = 0;
10337 eassert (MINI_WINDOW_P (w));
10339 /* By default, start display at the beginning. */
10340 set_marker_both (w->start, w->contents,
10341 BUF_BEGV (XBUFFER (w->contents)),
10342 BUF_BEGV_BYTE (XBUFFER (w->contents)));
10344 /* Don't resize windows while redisplaying a window; it would
10345 confuse redisplay functions when the size of the window they are
10346 displaying changes from under them. Such a resizing can happen,
10347 for instance, when which-func prints a long message while
10348 we are running fontification-functions. We're running these
10349 functions with safe_call which binds inhibit-redisplay to t. */
10350 if (!NILP (Vinhibit_redisplay))
10351 return 0;
10353 /* Nil means don't try to resize. */
10354 if (NILP (Vresize_mini_windows)
10355 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
10356 return 0;
10358 if (!FRAME_MINIBUF_ONLY_P (f))
10360 struct it it;
10361 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
10362 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
10363 int height;
10364 EMACS_INT max_height;
10365 int unit = FRAME_LINE_HEIGHT (f);
10366 struct text_pos start;
10367 struct buffer *old_current_buffer = NULL;
10369 if (current_buffer != XBUFFER (w->contents))
10371 old_current_buffer = current_buffer;
10372 set_buffer_internal (XBUFFER (w->contents));
10375 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
10377 /* Compute the max. number of lines specified by the user. */
10378 if (FLOATP (Vmax_mini_window_height))
10379 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
10380 else if (INTEGERP (Vmax_mini_window_height))
10381 max_height = XINT (Vmax_mini_window_height);
10382 else
10383 max_height = total_height / 4;
10385 /* Correct that max. height if it's bogus. */
10386 max_height = clip_to_bounds (1, max_height, total_height);
10388 /* Find out the height of the text in the window. */
10389 if (it.line_wrap == TRUNCATE)
10390 height = 1;
10391 else
10393 last_height = 0;
10394 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
10395 if (it.max_ascent == 0 && it.max_descent == 0)
10396 height = it.current_y + last_height;
10397 else
10398 height = it.current_y + it.max_ascent + it.max_descent;
10399 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
10400 height = (height + unit - 1) / unit;
10403 /* Compute a suitable window start. */
10404 if (height > max_height)
10406 height = max_height;
10407 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
10408 move_it_vertically_backward (&it, (height - 1) * unit);
10409 start = it.current.pos;
10411 else
10412 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
10413 SET_MARKER_FROM_TEXT_POS (w->start, start);
10415 if (EQ (Vresize_mini_windows, Qgrow_only))
10417 /* Let it grow only, until we display an empty message, in which
10418 case the window shrinks again. */
10419 if (height > WINDOW_TOTAL_LINES (w))
10421 int old_height = WINDOW_TOTAL_LINES (w);
10422 freeze_window_starts (f, 1);
10423 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10424 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10426 else if (height < WINDOW_TOTAL_LINES (w)
10427 && (exact_p || BEGV == ZV))
10429 int old_height = WINDOW_TOTAL_LINES (w);
10430 freeze_window_starts (f, 0);
10431 shrink_mini_window (w);
10432 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10435 else
10437 /* Always resize to exact size needed. */
10438 if (height > WINDOW_TOTAL_LINES (w))
10440 int old_height = WINDOW_TOTAL_LINES (w);
10441 freeze_window_starts (f, 1);
10442 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10443 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10445 else if (height < WINDOW_TOTAL_LINES (w))
10447 int old_height = WINDOW_TOTAL_LINES (w);
10448 freeze_window_starts (f, 0);
10449 shrink_mini_window (w);
10451 if (height)
10453 freeze_window_starts (f, 1);
10454 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10457 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10461 if (old_current_buffer)
10462 set_buffer_internal (old_current_buffer);
10465 return window_height_changed_p;
10469 /* Value is the current message, a string, or nil if there is no
10470 current message. */
10472 Lisp_Object
10473 current_message (void)
10475 Lisp_Object msg;
10477 if (!BUFFERP (echo_area_buffer[0]))
10478 msg = Qnil;
10479 else
10481 with_echo_area_buffer (0, 0, current_message_1,
10482 (intptr_t) &msg, Qnil);
10483 if (NILP (msg))
10484 echo_area_buffer[0] = Qnil;
10487 return msg;
10491 static int
10492 current_message_1 (ptrdiff_t a1, Lisp_Object a2)
10494 intptr_t i1 = a1;
10495 Lisp_Object *msg = (Lisp_Object *) i1;
10497 if (Z > BEG)
10498 *msg = make_buffer_string (BEG, Z, 1);
10499 else
10500 *msg = Qnil;
10501 return 0;
10505 /* Push the current message on Vmessage_stack for later restoration
10506 by restore_message. Value is non-zero if the current message isn't
10507 empty. This is a relatively infrequent operation, so it's not
10508 worth optimizing. */
10510 bool
10511 push_message (void)
10513 Lisp_Object msg = current_message ();
10514 Vmessage_stack = Fcons (msg, Vmessage_stack);
10515 return STRINGP (msg);
10519 /* Restore message display from the top of Vmessage_stack. */
10521 void
10522 restore_message (void)
10524 eassert (CONSP (Vmessage_stack));
10525 message3_nolog (XCAR (Vmessage_stack));
10529 /* Handler for record_unwind_protect calling pop_message. */
10531 Lisp_Object
10532 pop_message_unwind (Lisp_Object dummy)
10534 pop_message ();
10535 return Qnil;
10538 /* Pop the top-most entry off Vmessage_stack. */
10540 static void
10541 pop_message (void)
10543 eassert (CONSP (Vmessage_stack));
10544 Vmessage_stack = XCDR (Vmessage_stack);
10548 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
10549 exits. If the stack is not empty, we have a missing pop_message
10550 somewhere. */
10552 void
10553 check_message_stack (void)
10555 if (!NILP (Vmessage_stack))
10556 emacs_abort ();
10560 /* Truncate to NCHARS what will be displayed in the echo area the next
10561 time we display it---but don't redisplay it now. */
10563 void
10564 truncate_echo_area (ptrdiff_t nchars)
10566 if (nchars == 0)
10567 echo_area_buffer[0] = Qnil;
10568 else if (!noninteractive
10569 && INTERACTIVE
10570 && !NILP (echo_area_buffer[0]))
10572 struct frame *sf = SELECTED_FRAME ();
10573 /* Error messages get reported properly by cmd_error, so this must be
10574 just an informative message; if the frame hasn't really been
10575 initialized yet, just toss it. */
10576 if (sf->glyphs_initialized_p)
10577 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil);
10582 /* Helper function for truncate_echo_area. Truncate the current
10583 message to at most NCHARS characters. */
10585 static int
10586 truncate_message_1 (ptrdiff_t nchars, Lisp_Object a2)
10588 if (BEG + nchars < Z)
10589 del_range (BEG + nchars, Z);
10590 if (Z == BEG)
10591 echo_area_buffer[0] = Qnil;
10592 return 0;
10595 /* Set the current message to STRING. */
10597 static void
10598 set_message (Lisp_Object string)
10600 eassert (STRINGP (string));
10602 message_enable_multibyte = STRING_MULTIBYTE (string);
10604 with_echo_area_buffer (0, -1, set_message_1, 0, string);
10605 message_buf_print = 0;
10606 help_echo_showing_p = 0;
10608 if (STRINGP (Vdebug_on_message)
10609 && STRINGP (string)
10610 && fast_string_match (Vdebug_on_message, string) >= 0)
10611 call_debugger (list2 (Qerror, string));
10615 /* Helper function for set_message. First argument is ignored and second
10616 argument has the same meaning as for set_message.
10617 This function is called with the echo area buffer being current. */
10619 static int
10620 set_message_1 (ptrdiff_t a1, Lisp_Object string)
10622 eassert (STRINGP (string));
10624 /* Change multibyteness of the echo buffer appropriately. */
10625 if (message_enable_multibyte
10626 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
10627 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
10629 bset_truncate_lines (current_buffer, message_truncate_lines ? Qt : Qnil);
10630 if (!NILP (BVAR (current_buffer, bidi_display_reordering)))
10631 bset_bidi_paragraph_direction (current_buffer, Qleft_to_right);
10633 /* Insert new message at BEG. */
10634 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
10636 /* This function takes care of single/multibyte conversion.
10637 We just have to ensure that the echo area buffer has the right
10638 setting of enable_multibyte_characters. */
10639 insert_from_string (string, 0, 0, SCHARS (string), SBYTES (string), 1);
10641 return 0;
10645 /* Clear messages. CURRENT_P non-zero means clear the current
10646 message. LAST_DISPLAYED_P non-zero means clear the message
10647 last displayed. */
10649 void
10650 clear_message (int current_p, int last_displayed_p)
10652 if (current_p)
10654 echo_area_buffer[0] = Qnil;
10655 message_cleared_p = 1;
10658 if (last_displayed_p)
10659 echo_area_buffer[1] = Qnil;
10661 message_buf_print = 0;
10664 /* Clear garbaged frames.
10666 This function is used where the old redisplay called
10667 redraw_garbaged_frames which in turn called redraw_frame which in
10668 turn called clear_frame. The call to clear_frame was a source of
10669 flickering. I believe a clear_frame is not necessary. It should
10670 suffice in the new redisplay to invalidate all current matrices,
10671 and ensure a complete redisplay of all windows. */
10673 static void
10674 clear_garbaged_frames (void)
10676 if (frame_garbaged)
10678 Lisp_Object tail, frame;
10679 int changed_count = 0;
10681 FOR_EACH_FRAME (tail, frame)
10683 struct frame *f = XFRAME (frame);
10685 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
10687 if (f->resized_p)
10689 redraw_frame (f);
10690 f->force_flush_display_p = 1;
10692 clear_current_matrices (f);
10693 changed_count++;
10694 f->garbaged = 0;
10695 f->resized_p = 0;
10699 frame_garbaged = 0;
10700 if (changed_count)
10701 ++windows_or_buffers_changed;
10706 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
10707 is non-zero update selected_frame. Value is non-zero if the
10708 mini-windows height has been changed. */
10710 static int
10711 echo_area_display (int update_frame_p)
10713 Lisp_Object mini_window;
10714 struct window *w;
10715 struct frame *f;
10716 int window_height_changed_p = 0;
10717 struct frame *sf = SELECTED_FRAME ();
10719 mini_window = FRAME_MINIBUF_WINDOW (sf);
10720 w = XWINDOW (mini_window);
10721 f = XFRAME (WINDOW_FRAME (w));
10723 /* Don't display if frame is invisible or not yet initialized. */
10724 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
10725 return 0;
10727 #ifdef HAVE_WINDOW_SYSTEM
10728 /* When Emacs starts, selected_frame may be the initial terminal
10729 frame. If we let this through, a message would be displayed on
10730 the terminal. */
10731 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
10732 return 0;
10733 #endif /* HAVE_WINDOW_SYSTEM */
10735 /* Redraw garbaged frames. */
10736 clear_garbaged_frames ();
10738 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
10740 echo_area_window = mini_window;
10741 window_height_changed_p = display_echo_area (w);
10742 w->must_be_updated_p = 1;
10744 /* Update the display, unless called from redisplay_internal.
10745 Also don't update the screen during redisplay itself. The
10746 update will happen at the end of redisplay, and an update
10747 here could cause confusion. */
10748 if (update_frame_p && !redisplaying_p)
10750 int n = 0;
10752 /* If the display update has been interrupted by pending
10753 input, update mode lines in the frame. Due to the
10754 pending input, it might have been that redisplay hasn't
10755 been called, so that mode lines above the echo area are
10756 garbaged. This looks odd, so we prevent it here. */
10757 if (!display_completed)
10758 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
10760 if (window_height_changed_p
10761 /* Don't do this if Emacs is shutting down. Redisplay
10762 needs to run hooks. */
10763 && !NILP (Vrun_hooks))
10765 /* Must update other windows. Likewise as in other
10766 cases, don't let this update be interrupted by
10767 pending input. */
10768 ptrdiff_t count = SPECPDL_INDEX ();
10769 specbind (Qredisplay_dont_pause, Qt);
10770 windows_or_buffers_changed = 1;
10771 redisplay_internal ();
10772 unbind_to (count, Qnil);
10774 else if (FRAME_WINDOW_P (f) && n == 0)
10776 /* Window configuration is the same as before.
10777 Can do with a display update of the echo area,
10778 unless we displayed some mode lines. */
10779 update_single_window (w, 1);
10780 FRAME_RIF (f)->flush_display (f);
10782 else
10783 update_frame (f, 1, 1);
10785 /* If cursor is in the echo area, make sure that the next
10786 redisplay displays the minibuffer, so that the cursor will
10787 be replaced with what the minibuffer wants. */
10788 if (cursor_in_echo_area)
10789 ++windows_or_buffers_changed;
10792 else if (!EQ (mini_window, selected_window))
10793 windows_or_buffers_changed++;
10795 /* Last displayed message is now the current message. */
10796 echo_area_buffer[1] = echo_area_buffer[0];
10797 /* Inform read_char that we're not echoing. */
10798 echo_message_buffer = Qnil;
10800 /* Prevent redisplay optimization in redisplay_internal by resetting
10801 this_line_start_pos. This is done because the mini-buffer now
10802 displays the message instead of its buffer text. */
10803 if (EQ (mini_window, selected_window))
10804 CHARPOS (this_line_start_pos) = 0;
10806 return window_height_changed_p;
10809 /* Nonzero if the current window's buffer is shown in more than one
10810 window and was modified since last redisplay. */
10812 static int
10813 buffer_shared_and_changed (void)
10815 return (buffer_window_count (current_buffer) > 1
10816 && UNCHANGED_MODIFIED < MODIFF);
10819 /* Nonzero if W doesn't reflect the actual state of current buffer due
10820 to its text or overlays change. FIXME: this may be called when
10821 XBUFFER (w->contents) != current_buffer, which looks suspicious. */
10823 static int
10824 window_outdated (struct window *w)
10826 return (w->last_modified < MODIFF
10827 || w->last_overlay_modified < OVERLAY_MODIFF);
10830 /* Nonzero if W's buffer was changed but not saved or Transient Mark mode
10831 is enabled and mark of W's buffer was changed since last W's update. */
10833 static int
10834 window_buffer_changed (struct window *w)
10836 struct buffer *b = XBUFFER (w->contents);
10838 eassert (BUFFER_LIVE_P (b));
10840 return (((BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) != w->last_had_star)
10841 || ((!NILP (Vtransient_mark_mode) && !NILP (BVAR (b, mark_active)))
10842 != (w->region_showing != 0)));
10845 /* Nonzero if W has %c in its mode line and mode line should be updated. */
10847 static int
10848 mode_line_update_needed (struct window *w)
10850 return (w->column_number_displayed != -1
10851 && !(PT == w->last_point && !window_outdated (w))
10852 && (w->column_number_displayed != current_column ()));
10855 /***********************************************************************
10856 Mode Lines and Frame Titles
10857 ***********************************************************************/
10859 /* A buffer for constructing non-propertized mode-line strings and
10860 frame titles in it; allocated from the heap in init_xdisp and
10861 resized as needed in store_mode_line_noprop_char. */
10863 static char *mode_line_noprop_buf;
10865 /* The buffer's end, and a current output position in it. */
10867 static char *mode_line_noprop_buf_end;
10868 static char *mode_line_noprop_ptr;
10870 #define MODE_LINE_NOPROP_LEN(start) \
10871 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
10873 static enum {
10874 MODE_LINE_DISPLAY = 0,
10875 MODE_LINE_TITLE,
10876 MODE_LINE_NOPROP,
10877 MODE_LINE_STRING
10878 } mode_line_target;
10880 /* Alist that caches the results of :propertize.
10881 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
10882 static Lisp_Object mode_line_proptrans_alist;
10884 /* List of strings making up the mode-line. */
10885 static Lisp_Object mode_line_string_list;
10887 /* Base face property when building propertized mode line string. */
10888 static Lisp_Object mode_line_string_face;
10889 static Lisp_Object mode_line_string_face_prop;
10892 /* Unwind data for mode line strings */
10894 static Lisp_Object Vmode_line_unwind_vector;
10896 static Lisp_Object
10897 format_mode_line_unwind_data (struct frame *target_frame,
10898 struct buffer *obuf,
10899 Lisp_Object owin,
10900 int save_proptrans)
10902 Lisp_Object vector, tmp;
10904 /* Reduce consing by keeping one vector in
10905 Vwith_echo_area_save_vector. */
10906 vector = Vmode_line_unwind_vector;
10907 Vmode_line_unwind_vector = Qnil;
10909 if (NILP (vector))
10910 vector = Fmake_vector (make_number (10), Qnil);
10912 ASET (vector, 0, make_number (mode_line_target));
10913 ASET (vector, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
10914 ASET (vector, 2, mode_line_string_list);
10915 ASET (vector, 3, save_proptrans ? mode_line_proptrans_alist : Qt);
10916 ASET (vector, 4, mode_line_string_face);
10917 ASET (vector, 5, mode_line_string_face_prop);
10919 if (obuf)
10920 XSETBUFFER (tmp, obuf);
10921 else
10922 tmp = Qnil;
10923 ASET (vector, 6, tmp);
10924 ASET (vector, 7, owin);
10925 if (target_frame)
10927 /* Similarly to `with-selected-window', if the operation selects
10928 a window on another frame, we must restore that frame's
10929 selected window, and (for a tty) the top-frame. */
10930 ASET (vector, 8, target_frame->selected_window);
10931 if (FRAME_TERMCAP_P (target_frame))
10932 ASET (vector, 9, FRAME_TTY (target_frame)->top_frame);
10935 return vector;
10938 static Lisp_Object
10939 unwind_format_mode_line (Lisp_Object vector)
10941 Lisp_Object old_window = AREF (vector, 7);
10942 Lisp_Object target_frame_window = AREF (vector, 8);
10943 Lisp_Object old_top_frame = AREF (vector, 9);
10945 mode_line_target = XINT (AREF (vector, 0));
10946 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
10947 mode_line_string_list = AREF (vector, 2);
10948 if (! EQ (AREF (vector, 3), Qt))
10949 mode_line_proptrans_alist = AREF (vector, 3);
10950 mode_line_string_face = AREF (vector, 4);
10951 mode_line_string_face_prop = AREF (vector, 5);
10953 /* Select window before buffer, since it may change the buffer. */
10954 if (!NILP (old_window))
10956 /* If the operation that we are unwinding had selected a window
10957 on a different frame, reset its frame-selected-window. For a
10958 text terminal, reset its top-frame if necessary. */
10959 if (!NILP (target_frame_window))
10961 Lisp_Object frame
10962 = WINDOW_FRAME (XWINDOW (target_frame_window));
10964 if (!EQ (frame, WINDOW_FRAME (XWINDOW (old_window))))
10965 Fselect_window (target_frame_window, Qt);
10967 if (!NILP (old_top_frame) && !EQ (old_top_frame, frame))
10968 Fselect_frame (old_top_frame, Qt);
10971 Fselect_window (old_window, Qt);
10974 if (!NILP (AREF (vector, 6)))
10976 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
10977 ASET (vector, 6, Qnil);
10980 Vmode_line_unwind_vector = vector;
10981 return Qnil;
10985 /* Store a single character C for the frame title in mode_line_noprop_buf.
10986 Re-allocate mode_line_noprop_buf if necessary. */
10988 static void
10989 store_mode_line_noprop_char (char c)
10991 /* If output position has reached the end of the allocated buffer,
10992 increase the buffer's size. */
10993 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
10995 ptrdiff_t len = MODE_LINE_NOPROP_LEN (0);
10996 ptrdiff_t size = len;
10997 mode_line_noprop_buf =
10998 xpalloc (mode_line_noprop_buf, &size, 1, STRING_BYTES_BOUND, 1);
10999 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
11000 mode_line_noprop_ptr = mode_line_noprop_buf + len;
11003 *mode_line_noprop_ptr++ = c;
11007 /* Store part of a frame title in mode_line_noprop_buf, beginning at
11008 mode_line_noprop_ptr. STRING is the string to store. Do not copy
11009 characters that yield more columns than PRECISION; PRECISION <= 0
11010 means copy the whole string. Pad with spaces until FIELD_WIDTH
11011 number of characters have been copied; FIELD_WIDTH <= 0 means don't
11012 pad. Called from display_mode_element when it is used to build a
11013 frame title. */
11015 static int
11016 store_mode_line_noprop (const char *string, int field_width, int precision)
11018 const unsigned char *str = (const unsigned char *) string;
11019 int n = 0;
11020 ptrdiff_t dummy, nbytes;
11022 /* Copy at most PRECISION chars from STR. */
11023 nbytes = strlen (string);
11024 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
11025 while (nbytes--)
11026 store_mode_line_noprop_char (*str++);
11028 /* Fill up with spaces until FIELD_WIDTH reached. */
11029 while (field_width > 0
11030 && n < field_width)
11032 store_mode_line_noprop_char (' ');
11033 ++n;
11036 return n;
11039 /***********************************************************************
11040 Frame Titles
11041 ***********************************************************************/
11043 #ifdef HAVE_WINDOW_SYSTEM
11045 /* Set the title of FRAME, if it has changed. The title format is
11046 Vicon_title_format if FRAME is iconified, otherwise it is
11047 frame_title_format. */
11049 static void
11050 x_consider_frame_title (Lisp_Object frame)
11052 struct frame *f = XFRAME (frame);
11054 if (FRAME_WINDOW_P (f)
11055 || FRAME_MINIBUF_ONLY_P (f)
11056 || f->explicit_name)
11058 /* Do we have more than one visible frame on this X display? */
11059 Lisp_Object tail, other_frame, fmt;
11060 ptrdiff_t title_start;
11061 char *title;
11062 ptrdiff_t len;
11063 struct it it;
11064 ptrdiff_t count = SPECPDL_INDEX ();
11066 FOR_EACH_FRAME (tail, other_frame)
11068 struct frame *tf = XFRAME (other_frame);
11070 if (tf != f
11071 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
11072 && !FRAME_MINIBUF_ONLY_P (tf)
11073 && !EQ (other_frame, tip_frame)
11074 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
11075 break;
11078 /* Set global variable indicating that multiple frames exist. */
11079 multiple_frames = CONSP (tail);
11081 /* Switch to the buffer of selected window of the frame. Set up
11082 mode_line_target so that display_mode_element will output into
11083 mode_line_noprop_buf; then display the title. */
11084 record_unwind_protect (unwind_format_mode_line,
11085 format_mode_line_unwind_data
11086 (f, current_buffer, selected_window, 0));
11088 Fselect_window (f->selected_window, Qt);
11089 set_buffer_internal_1
11090 (XBUFFER (XWINDOW (f->selected_window)->contents));
11091 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
11093 mode_line_target = MODE_LINE_TITLE;
11094 title_start = MODE_LINE_NOPROP_LEN (0);
11095 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
11096 NULL, DEFAULT_FACE_ID);
11097 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
11098 len = MODE_LINE_NOPROP_LEN (title_start);
11099 title = mode_line_noprop_buf + title_start;
11100 unbind_to (count, Qnil);
11102 /* Set the title only if it's changed. This avoids consing in
11103 the common case where it hasn't. (If it turns out that we've
11104 already wasted too much time by walking through the list with
11105 display_mode_element, then we might need to optimize at a
11106 higher level than this.) */
11107 if (! STRINGP (f->name)
11108 || SBYTES (f->name) != len
11109 || memcmp (title, SDATA (f->name), len) != 0)
11110 x_implicitly_set_name (f, make_string (title, len), Qnil);
11114 #endif /* not HAVE_WINDOW_SYSTEM */
11117 /***********************************************************************
11118 Menu Bars
11119 ***********************************************************************/
11122 /* Prepare for redisplay by updating menu-bar item lists when
11123 appropriate. This can call eval. */
11125 void
11126 prepare_menu_bars (void)
11128 int all_windows;
11129 struct gcpro gcpro1, gcpro2;
11130 struct frame *f;
11131 Lisp_Object tooltip_frame;
11133 #ifdef HAVE_WINDOW_SYSTEM
11134 tooltip_frame = tip_frame;
11135 #else
11136 tooltip_frame = Qnil;
11137 #endif
11139 /* Update all frame titles based on their buffer names, etc. We do
11140 this before the menu bars so that the buffer-menu will show the
11141 up-to-date frame titles. */
11142 #ifdef HAVE_WINDOW_SYSTEM
11143 if (windows_or_buffers_changed || update_mode_lines)
11145 Lisp_Object tail, frame;
11147 FOR_EACH_FRAME (tail, frame)
11149 f = XFRAME (frame);
11150 if (!EQ (frame, tooltip_frame)
11151 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
11152 x_consider_frame_title (frame);
11155 #endif /* HAVE_WINDOW_SYSTEM */
11157 /* Update the menu bar item lists, if appropriate. This has to be
11158 done before any actual redisplay or generation of display lines. */
11159 all_windows = (update_mode_lines
11160 || buffer_shared_and_changed ()
11161 || windows_or_buffers_changed);
11162 if (all_windows)
11164 Lisp_Object tail, frame;
11165 ptrdiff_t count = SPECPDL_INDEX ();
11166 /* 1 means that update_menu_bar has run its hooks
11167 so any further calls to update_menu_bar shouldn't do so again. */
11168 int menu_bar_hooks_run = 0;
11170 record_unwind_save_match_data ();
11172 FOR_EACH_FRAME (tail, frame)
11174 f = XFRAME (frame);
11176 /* Ignore tooltip frame. */
11177 if (EQ (frame, tooltip_frame))
11178 continue;
11180 /* If a window on this frame changed size, report that to
11181 the user and clear the size-change flag. */
11182 if (FRAME_WINDOW_SIZES_CHANGED (f))
11184 Lisp_Object functions;
11186 /* Clear flag first in case we get an error below. */
11187 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
11188 functions = Vwindow_size_change_functions;
11189 GCPRO2 (tail, functions);
11191 while (CONSP (functions))
11193 if (!EQ (XCAR (functions), Qt))
11194 call1 (XCAR (functions), frame);
11195 functions = XCDR (functions);
11197 UNGCPRO;
11200 GCPRO1 (tail);
11201 menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
11202 #ifdef HAVE_WINDOW_SYSTEM
11203 update_tool_bar (f, 0);
11204 #endif
11205 #ifdef HAVE_NS
11206 if (windows_or_buffers_changed
11207 && FRAME_NS_P (f))
11208 ns_set_doc_edited
11209 (f, Fbuffer_modified_p (XWINDOW (f->selected_window)->contents));
11210 #endif
11211 UNGCPRO;
11214 unbind_to (count, Qnil);
11216 else
11218 struct frame *sf = SELECTED_FRAME ();
11219 update_menu_bar (sf, 1, 0);
11220 #ifdef HAVE_WINDOW_SYSTEM
11221 update_tool_bar (sf, 1);
11222 #endif
11227 /* Update the menu bar item list for frame F. This has to be done
11228 before we start to fill in any display lines, because it can call
11229 eval.
11231 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
11233 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
11234 already ran the menu bar hooks for this redisplay, so there
11235 is no need to run them again. The return value is the
11236 updated value of this flag, to pass to the next call. */
11238 static int
11239 update_menu_bar (struct frame *f, int save_match_data, int hooks_run)
11241 Lisp_Object window;
11242 register struct window *w;
11244 /* If called recursively during a menu update, do nothing. This can
11245 happen when, for instance, an activate-menubar-hook causes a
11246 redisplay. */
11247 if (inhibit_menubar_update)
11248 return hooks_run;
11250 window = FRAME_SELECTED_WINDOW (f);
11251 w = XWINDOW (window);
11253 if (FRAME_WINDOW_P (f)
11255 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11256 || defined (HAVE_NS) || defined (USE_GTK)
11257 FRAME_EXTERNAL_MENU_BAR (f)
11258 #else
11259 FRAME_MENU_BAR_LINES (f) > 0
11260 #endif
11261 : FRAME_MENU_BAR_LINES (f) > 0)
11263 /* If the user has switched buffers or windows, we need to
11264 recompute to reflect the new bindings. But we'll
11265 recompute when update_mode_lines is set too; that means
11266 that people can use force-mode-line-update to request
11267 that the menu bar be recomputed. The adverse effect on
11268 the rest of the redisplay algorithm is about the same as
11269 windows_or_buffers_changed anyway. */
11270 if (windows_or_buffers_changed
11271 /* This used to test w->update_mode_line, but we believe
11272 there is no need to recompute the menu in that case. */
11273 || update_mode_lines
11274 || window_buffer_changed (w))
11276 struct buffer *prev = current_buffer;
11277 ptrdiff_t count = SPECPDL_INDEX ();
11279 specbind (Qinhibit_menubar_update, Qt);
11281 set_buffer_internal_1 (XBUFFER (w->contents));
11282 if (save_match_data)
11283 record_unwind_save_match_data ();
11284 if (NILP (Voverriding_local_map_menu_flag))
11286 specbind (Qoverriding_terminal_local_map, Qnil);
11287 specbind (Qoverriding_local_map, Qnil);
11290 if (!hooks_run)
11292 /* Run the Lucid hook. */
11293 safe_run_hooks (Qactivate_menubar_hook);
11295 /* If it has changed current-menubar from previous value,
11296 really recompute the menu-bar from the value. */
11297 if (! NILP (Vlucid_menu_bar_dirty_flag))
11298 call0 (Qrecompute_lucid_menubar);
11300 safe_run_hooks (Qmenu_bar_update_hook);
11302 hooks_run = 1;
11305 XSETFRAME (Vmenu_updating_frame, f);
11306 fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f)));
11308 /* Redisplay the menu bar in case we changed it. */
11309 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11310 || defined (HAVE_NS) || defined (USE_GTK)
11311 if (FRAME_WINDOW_P (f))
11313 #if defined (HAVE_NS)
11314 /* All frames on Mac OS share the same menubar. So only
11315 the selected frame should be allowed to set it. */
11316 if (f == SELECTED_FRAME ())
11317 #endif
11318 set_frame_menubar (f, 0, 0);
11320 else
11321 /* On a terminal screen, the menu bar is an ordinary screen
11322 line, and this makes it get updated. */
11323 w->update_mode_line = 1;
11324 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11325 /* In the non-toolkit version, the menu bar is an ordinary screen
11326 line, and this makes it get updated. */
11327 w->update_mode_line = 1;
11328 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11330 unbind_to (count, Qnil);
11331 set_buffer_internal_1 (prev);
11335 return hooks_run;
11340 /***********************************************************************
11341 Output Cursor
11342 ***********************************************************************/
11344 #ifdef HAVE_WINDOW_SYSTEM
11346 /* EXPORT:
11347 Nominal cursor position -- where to draw output.
11348 HPOS and VPOS are window relative glyph matrix coordinates.
11349 X and Y are window relative pixel coordinates. */
11351 struct cursor_pos output_cursor;
11354 /* EXPORT:
11355 Set the global variable output_cursor to CURSOR. All cursor
11356 positions are relative to updated_window. */
11358 void
11359 set_output_cursor (struct cursor_pos *cursor)
11361 output_cursor.hpos = cursor->hpos;
11362 output_cursor.vpos = cursor->vpos;
11363 output_cursor.x = cursor->x;
11364 output_cursor.y = cursor->y;
11368 /* EXPORT for RIF:
11369 Set a nominal cursor position.
11371 HPOS and VPOS are column/row positions in a window glyph matrix. X
11372 and Y are window text area relative pixel positions.
11374 If this is done during an update, updated_window will contain the
11375 window that is being updated and the position is the future output
11376 cursor position for that window. If updated_window is null, use
11377 selected_window and display the cursor at the given position. */
11379 void
11380 x_cursor_to (int vpos, int hpos, int y, int x)
11382 struct window *w;
11384 /* If updated_window is not set, work on selected_window. */
11385 if (updated_window)
11386 w = updated_window;
11387 else
11388 w = XWINDOW (selected_window);
11390 /* Set the output cursor. */
11391 output_cursor.hpos = hpos;
11392 output_cursor.vpos = vpos;
11393 output_cursor.x = x;
11394 output_cursor.y = y;
11396 /* If not called as part of an update, really display the cursor.
11397 This will also set the cursor position of W. */
11398 if (updated_window == NULL)
11400 block_input ();
11401 display_and_set_cursor (w, 1, hpos, vpos, x, y);
11402 if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
11403 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
11404 unblock_input ();
11408 #endif /* HAVE_WINDOW_SYSTEM */
11411 /***********************************************************************
11412 Tool-bars
11413 ***********************************************************************/
11415 #ifdef HAVE_WINDOW_SYSTEM
11417 /* Where the mouse was last time we reported a mouse event. */
11419 FRAME_PTR last_mouse_frame;
11421 /* Tool-bar item index of the item on which a mouse button was pressed
11422 or -1. */
11424 int last_tool_bar_item;
11426 /* Select `frame' temporarily without running all the code in
11427 do_switch_frame.
11428 FIXME: Maybe do_switch_frame should be trimmed down similarly
11429 when `norecord' is set. */
11430 static Lisp_Object
11431 fast_set_selected_frame (Lisp_Object frame)
11433 if (!EQ (selected_frame, frame))
11435 selected_frame = frame;
11436 selected_window = XFRAME (frame)->selected_window;
11438 return Qnil;
11441 /* Update the tool-bar item list for frame F. This has to be done
11442 before we start to fill in any display lines. Called from
11443 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
11444 and restore it here. */
11446 static void
11447 update_tool_bar (struct frame *f, int save_match_data)
11449 #if defined (USE_GTK) || defined (HAVE_NS)
11450 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
11451 #else
11452 int do_update = WINDOWP (f->tool_bar_window)
11453 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
11454 #endif
11456 if (do_update)
11458 Lisp_Object window;
11459 struct window *w;
11461 window = FRAME_SELECTED_WINDOW (f);
11462 w = XWINDOW (window);
11464 /* If the user has switched buffers or windows, we need to
11465 recompute to reflect the new bindings. But we'll
11466 recompute when update_mode_lines is set too; that means
11467 that people can use force-mode-line-update to request
11468 that the menu bar be recomputed. The adverse effect on
11469 the rest of the redisplay algorithm is about the same as
11470 windows_or_buffers_changed anyway. */
11471 if (windows_or_buffers_changed
11472 || w->update_mode_line
11473 || update_mode_lines
11474 || window_buffer_changed (w))
11476 struct buffer *prev = current_buffer;
11477 ptrdiff_t count = SPECPDL_INDEX ();
11478 Lisp_Object frame, new_tool_bar;
11479 int new_n_tool_bar;
11480 struct gcpro gcpro1;
11482 /* Set current_buffer to the buffer of the selected
11483 window of the frame, so that we get the right local
11484 keymaps. */
11485 set_buffer_internal_1 (XBUFFER (w->contents));
11487 /* Save match data, if we must. */
11488 if (save_match_data)
11489 record_unwind_save_match_data ();
11491 /* Make sure that we don't accidentally use bogus keymaps. */
11492 if (NILP (Voverriding_local_map_menu_flag))
11494 specbind (Qoverriding_terminal_local_map, Qnil);
11495 specbind (Qoverriding_local_map, Qnil);
11498 GCPRO1 (new_tool_bar);
11500 /* We must temporarily set the selected frame to this frame
11501 before calling tool_bar_items, because the calculation of
11502 the tool-bar keymap uses the selected frame (see
11503 `tool-bar-make-keymap' in tool-bar.el). */
11504 eassert (EQ (selected_window,
11505 /* Since we only explicitly preserve selected_frame,
11506 check that selected_window would be redundant. */
11507 XFRAME (selected_frame)->selected_window));
11508 record_unwind_protect (fast_set_selected_frame, selected_frame);
11509 XSETFRAME (frame, f);
11510 fast_set_selected_frame (frame);
11512 /* Build desired tool-bar items from keymaps. */
11513 new_tool_bar
11514 = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
11515 &new_n_tool_bar);
11517 /* Redisplay the tool-bar if we changed it. */
11518 if (new_n_tool_bar != f->n_tool_bar_items
11519 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
11521 /* Redisplay that happens asynchronously due to an expose event
11522 may access f->tool_bar_items. Make sure we update both
11523 variables within BLOCK_INPUT so no such event interrupts. */
11524 block_input ();
11525 fset_tool_bar_items (f, new_tool_bar);
11526 f->n_tool_bar_items = new_n_tool_bar;
11527 w->update_mode_line = 1;
11528 unblock_input ();
11531 UNGCPRO;
11533 unbind_to (count, Qnil);
11534 set_buffer_internal_1 (prev);
11540 /* Set F->desired_tool_bar_string to a Lisp string representing frame
11541 F's desired tool-bar contents. F->tool_bar_items must have
11542 been set up previously by calling prepare_menu_bars. */
11544 static void
11545 build_desired_tool_bar_string (struct frame *f)
11547 int i, size, size_needed;
11548 struct gcpro gcpro1, gcpro2, gcpro3;
11549 Lisp_Object image, plist, props;
11551 image = plist = props = Qnil;
11552 GCPRO3 (image, plist, props);
11554 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
11555 Otherwise, make a new string. */
11557 /* The size of the string we might be able to reuse. */
11558 size = (STRINGP (f->desired_tool_bar_string)
11559 ? SCHARS (f->desired_tool_bar_string)
11560 : 0);
11562 /* We need one space in the string for each image. */
11563 size_needed = f->n_tool_bar_items;
11565 /* Reuse f->desired_tool_bar_string, if possible. */
11566 if (size < size_needed || NILP (f->desired_tool_bar_string))
11567 fset_desired_tool_bar_string
11568 (f, Fmake_string (make_number (size_needed), make_number (' ')));
11569 else
11571 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
11572 Fremove_text_properties (make_number (0), make_number (size),
11573 props, f->desired_tool_bar_string);
11576 /* Put a `display' property on the string for the images to display,
11577 put a `menu_item' property on tool-bar items with a value that
11578 is the index of the item in F's tool-bar item vector. */
11579 for (i = 0; i < f->n_tool_bar_items; ++i)
11581 #define PROP(IDX) \
11582 AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
11584 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
11585 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
11586 int hmargin, vmargin, relief, idx, end;
11588 /* If image is a vector, choose the image according to the
11589 button state. */
11590 image = PROP (TOOL_BAR_ITEM_IMAGES);
11591 if (VECTORP (image))
11593 if (enabled_p)
11594 idx = (selected_p
11595 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
11596 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
11597 else
11598 idx = (selected_p
11599 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
11600 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
11602 eassert (ASIZE (image) >= idx);
11603 image = AREF (image, idx);
11605 else
11606 idx = -1;
11608 /* Ignore invalid image specifications. */
11609 if (!valid_image_p (image))
11610 continue;
11612 /* Display the tool-bar button pressed, or depressed. */
11613 plist = Fcopy_sequence (XCDR (image));
11615 /* Compute margin and relief to draw. */
11616 relief = (tool_bar_button_relief >= 0
11617 ? tool_bar_button_relief
11618 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
11619 hmargin = vmargin = relief;
11621 if (RANGED_INTEGERP (1, Vtool_bar_button_margin,
11622 INT_MAX - max (hmargin, vmargin)))
11624 hmargin += XFASTINT (Vtool_bar_button_margin);
11625 vmargin += XFASTINT (Vtool_bar_button_margin);
11627 else if (CONSP (Vtool_bar_button_margin))
11629 if (RANGED_INTEGERP (1, XCAR (Vtool_bar_button_margin),
11630 INT_MAX - hmargin))
11631 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
11633 if (RANGED_INTEGERP (1, XCDR (Vtool_bar_button_margin),
11634 INT_MAX - vmargin))
11635 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
11638 if (auto_raise_tool_bar_buttons_p)
11640 /* Add a `:relief' property to the image spec if the item is
11641 selected. */
11642 if (selected_p)
11644 plist = Fplist_put (plist, QCrelief, make_number (-relief));
11645 hmargin -= relief;
11646 vmargin -= relief;
11649 else
11651 /* If image is selected, display it pressed, i.e. with a
11652 negative relief. If it's not selected, display it with a
11653 raised relief. */
11654 plist = Fplist_put (plist, QCrelief,
11655 (selected_p
11656 ? make_number (-relief)
11657 : make_number (relief)));
11658 hmargin -= relief;
11659 vmargin -= relief;
11662 /* Put a margin around the image. */
11663 if (hmargin || vmargin)
11665 if (hmargin == vmargin)
11666 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
11667 else
11668 plist = Fplist_put (plist, QCmargin,
11669 Fcons (make_number (hmargin),
11670 make_number (vmargin)));
11673 /* If button is not enabled, and we don't have special images
11674 for the disabled state, make the image appear disabled by
11675 applying an appropriate algorithm to it. */
11676 if (!enabled_p && idx < 0)
11677 plist = Fplist_put (plist, QCconversion, Qdisabled);
11679 /* Put a `display' text property on the string for the image to
11680 display. Put a `menu-item' property on the string that gives
11681 the start of this item's properties in the tool-bar items
11682 vector. */
11683 image = Fcons (Qimage, plist);
11684 props = list4 (Qdisplay, image,
11685 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
11687 /* Let the last image hide all remaining spaces in the tool bar
11688 string. The string can be longer than needed when we reuse a
11689 previous string. */
11690 if (i + 1 == f->n_tool_bar_items)
11691 end = SCHARS (f->desired_tool_bar_string);
11692 else
11693 end = i + 1;
11694 Fadd_text_properties (make_number (i), make_number (end),
11695 props, f->desired_tool_bar_string);
11696 #undef PROP
11699 UNGCPRO;
11703 /* Display one line of the tool-bar of frame IT->f.
11705 HEIGHT specifies the desired height of the tool-bar line.
11706 If the actual height of the glyph row is less than HEIGHT, the
11707 row's height is increased to HEIGHT, and the icons are centered
11708 vertically in the new height.
11710 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
11711 count a final empty row in case the tool-bar width exactly matches
11712 the window width.
11715 static void
11716 display_tool_bar_line (struct it *it, int height)
11718 struct glyph_row *row = it->glyph_row;
11719 int max_x = it->last_visible_x;
11720 struct glyph *last;
11722 prepare_desired_row (row);
11723 row->y = it->current_y;
11725 /* Note that this isn't made use of if the face hasn't a box,
11726 so there's no need to check the face here. */
11727 it->start_of_box_run_p = 1;
11729 while (it->current_x < max_x)
11731 int x, n_glyphs_before, i, nglyphs;
11732 struct it it_before;
11734 /* Get the next display element. */
11735 if (!get_next_display_element (it))
11737 /* Don't count empty row if we are counting needed tool-bar lines. */
11738 if (height < 0 && !it->hpos)
11739 return;
11740 break;
11743 /* Produce glyphs. */
11744 n_glyphs_before = row->used[TEXT_AREA];
11745 it_before = *it;
11747 PRODUCE_GLYPHS (it);
11749 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
11750 i = 0;
11751 x = it_before.current_x;
11752 while (i < nglyphs)
11754 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
11756 if (x + glyph->pixel_width > max_x)
11758 /* Glyph doesn't fit on line. Backtrack. */
11759 row->used[TEXT_AREA] = n_glyphs_before;
11760 *it = it_before;
11761 /* If this is the only glyph on this line, it will never fit on the
11762 tool-bar, so skip it. But ensure there is at least one glyph,
11763 so we don't accidentally disable the tool-bar. */
11764 if (n_glyphs_before == 0
11765 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
11766 break;
11767 goto out;
11770 ++it->hpos;
11771 x += glyph->pixel_width;
11772 ++i;
11775 /* Stop at line end. */
11776 if (ITERATOR_AT_END_OF_LINE_P (it))
11777 break;
11779 set_iterator_to_next (it, 1);
11782 out:;
11784 row->displays_text_p = row->used[TEXT_AREA] != 0;
11786 /* Use default face for the border below the tool bar.
11788 FIXME: When auto-resize-tool-bars is grow-only, there is
11789 no additional border below the possibly empty tool-bar lines.
11790 So to make the extra empty lines look "normal", we have to
11791 use the tool-bar face for the border too. */
11792 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
11793 && !EQ (Vauto_resize_tool_bars, Qgrow_only))
11794 it->face_id = DEFAULT_FACE_ID;
11796 extend_face_to_end_of_line (it);
11797 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
11798 last->right_box_line_p = 1;
11799 if (last == row->glyphs[TEXT_AREA])
11800 last->left_box_line_p = 1;
11802 /* Make line the desired height and center it vertically. */
11803 if ((height -= it->max_ascent + it->max_descent) > 0)
11805 /* Don't add more than one line height. */
11806 height %= FRAME_LINE_HEIGHT (it->f);
11807 it->max_ascent += height / 2;
11808 it->max_descent += (height + 1) / 2;
11811 compute_line_metrics (it);
11813 /* If line is empty, make it occupy the rest of the tool-bar. */
11814 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row))
11816 row->height = row->phys_height = it->last_visible_y - row->y;
11817 row->visible_height = row->height;
11818 row->ascent = row->phys_ascent = 0;
11819 row->extra_line_spacing = 0;
11822 row->full_width_p = 1;
11823 row->continued_p = 0;
11824 row->truncated_on_left_p = 0;
11825 row->truncated_on_right_p = 0;
11827 it->current_x = it->hpos = 0;
11828 it->current_y += row->height;
11829 ++it->vpos;
11830 ++it->glyph_row;
11834 /* Max tool-bar height. */
11836 #define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
11837 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
11839 /* Value is the number of screen lines needed to make all tool-bar
11840 items of frame F visible. The number of actual rows needed is
11841 returned in *N_ROWS if non-NULL. */
11843 static int
11844 tool_bar_lines_needed (struct frame *f, int *n_rows)
11846 struct window *w = XWINDOW (f->tool_bar_window);
11847 struct it it;
11848 /* tool_bar_lines_needed is called from redisplay_tool_bar after building
11849 the desired matrix, so use (unused) mode-line row as temporary row to
11850 avoid destroying the first tool-bar row. */
11851 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
11853 /* Initialize an iterator for iteration over
11854 F->desired_tool_bar_string in the tool-bar window of frame F. */
11855 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
11856 it.first_visible_x = 0;
11857 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
11858 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
11859 it.paragraph_embedding = L2R;
11861 while (!ITERATOR_AT_END_P (&it))
11863 clear_glyph_row (temp_row);
11864 it.glyph_row = temp_row;
11865 display_tool_bar_line (&it, -1);
11867 clear_glyph_row (temp_row);
11869 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
11870 if (n_rows)
11871 *n_rows = it.vpos > 0 ? it.vpos : -1;
11873 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
11877 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
11878 0, 1, 0,
11879 doc: /* Return the number of lines occupied by the tool bar of FRAME.
11880 If FRAME is nil or omitted, use the selected frame. */)
11881 (Lisp_Object frame)
11883 struct frame *f = decode_any_frame (frame);
11884 struct window *w;
11885 int nlines = 0;
11887 if (WINDOWP (f->tool_bar_window)
11888 && (w = XWINDOW (f->tool_bar_window),
11889 WINDOW_TOTAL_LINES (w) > 0))
11891 update_tool_bar (f, 1);
11892 if (f->n_tool_bar_items)
11894 build_desired_tool_bar_string (f);
11895 nlines = tool_bar_lines_needed (f, NULL);
11899 return make_number (nlines);
11903 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
11904 height should be changed. */
11906 static int
11907 redisplay_tool_bar (struct frame *f)
11909 struct window *w;
11910 struct it it;
11911 struct glyph_row *row;
11913 #if defined (USE_GTK) || defined (HAVE_NS)
11914 if (FRAME_EXTERNAL_TOOL_BAR (f))
11915 update_frame_tool_bar (f);
11916 return 0;
11917 #endif
11919 /* If frame hasn't a tool-bar window or if it is zero-height, don't
11920 do anything. This means you must start with tool-bar-lines
11921 non-zero to get the auto-sizing effect. Or in other words, you
11922 can turn off tool-bars by specifying tool-bar-lines zero. */
11923 if (!WINDOWP (f->tool_bar_window)
11924 || (w = XWINDOW (f->tool_bar_window),
11925 WINDOW_TOTAL_LINES (w) == 0))
11926 return 0;
11928 /* Set up an iterator for the tool-bar window. */
11929 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
11930 it.first_visible_x = 0;
11931 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
11932 row = it.glyph_row;
11934 /* Build a string that represents the contents of the tool-bar. */
11935 build_desired_tool_bar_string (f);
11936 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
11937 /* FIXME: This should be controlled by a user option. But it
11938 doesn't make sense to have an R2L tool bar if the menu bar cannot
11939 be drawn also R2L, and making the menu bar R2L is tricky due
11940 toolkit-specific code that implements it. If an R2L tool bar is
11941 ever supported, display_tool_bar_line should also be augmented to
11942 call unproduce_glyphs like display_line and display_string
11943 do. */
11944 it.paragraph_embedding = L2R;
11946 if (f->n_tool_bar_rows == 0)
11948 int nlines;
11950 if ((nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
11951 nlines != WINDOW_TOTAL_LINES (w)))
11953 Lisp_Object frame;
11954 int old_height = WINDOW_TOTAL_LINES (w);
11956 XSETFRAME (frame, f);
11957 Fmodify_frame_parameters (frame,
11958 Fcons (Fcons (Qtool_bar_lines,
11959 make_number (nlines)),
11960 Qnil));
11961 if (WINDOW_TOTAL_LINES (w) != old_height)
11963 clear_glyph_matrix (w->desired_matrix);
11964 fonts_changed_p = 1;
11965 return 1;
11970 /* Display as many lines as needed to display all tool-bar items. */
11972 if (f->n_tool_bar_rows > 0)
11974 int border, rows, height, extra;
11976 if (TYPE_RANGED_INTEGERP (int, Vtool_bar_border))
11977 border = XINT (Vtool_bar_border);
11978 else if (EQ (Vtool_bar_border, Qinternal_border_width))
11979 border = FRAME_INTERNAL_BORDER_WIDTH (f);
11980 else if (EQ (Vtool_bar_border, Qborder_width))
11981 border = f->border_width;
11982 else
11983 border = 0;
11984 if (border < 0)
11985 border = 0;
11987 rows = f->n_tool_bar_rows;
11988 height = max (1, (it.last_visible_y - border) / rows);
11989 extra = it.last_visible_y - border - height * rows;
11991 while (it.current_y < it.last_visible_y)
11993 int h = 0;
11994 if (extra > 0 && rows-- > 0)
11996 h = (extra + rows - 1) / rows;
11997 extra -= h;
11999 display_tool_bar_line (&it, height + h);
12002 else
12004 while (it.current_y < it.last_visible_y)
12005 display_tool_bar_line (&it, 0);
12008 /* It doesn't make much sense to try scrolling in the tool-bar
12009 window, so don't do it. */
12010 w->desired_matrix->no_scrolling_p = 1;
12011 w->must_be_updated_p = 1;
12013 if (!NILP (Vauto_resize_tool_bars))
12015 int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
12016 int change_height_p = 0;
12018 /* If we couldn't display everything, change the tool-bar's
12019 height if there is room for more. */
12020 if (IT_STRING_CHARPOS (it) < it.end_charpos
12021 && it.current_y < max_tool_bar_height)
12022 change_height_p = 1;
12024 row = it.glyph_row - 1;
12026 /* If there are blank lines at the end, except for a partially
12027 visible blank line at the end that is smaller than
12028 FRAME_LINE_HEIGHT, change the tool-bar's height. */
12029 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
12030 && row->height >= FRAME_LINE_HEIGHT (f))
12031 change_height_p = 1;
12033 /* If row displays tool-bar items, but is partially visible,
12034 change the tool-bar's height. */
12035 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12036 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y
12037 && MATRIX_ROW_BOTTOM_Y (row) < max_tool_bar_height)
12038 change_height_p = 1;
12040 /* Resize windows as needed by changing the `tool-bar-lines'
12041 frame parameter. */
12042 if (change_height_p)
12044 Lisp_Object frame;
12045 int old_height = WINDOW_TOTAL_LINES (w);
12046 int nrows;
12047 int nlines = tool_bar_lines_needed (f, &nrows);
12049 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
12050 && !f->minimize_tool_bar_window_p)
12051 ? (nlines > old_height)
12052 : (nlines != old_height));
12053 f->minimize_tool_bar_window_p = 0;
12055 if (change_height_p)
12057 XSETFRAME (frame, f);
12058 Fmodify_frame_parameters (frame,
12059 Fcons (Fcons (Qtool_bar_lines,
12060 make_number (nlines)),
12061 Qnil));
12062 if (WINDOW_TOTAL_LINES (w) != old_height)
12064 clear_glyph_matrix (w->desired_matrix);
12065 f->n_tool_bar_rows = nrows;
12066 fonts_changed_p = 1;
12067 return 1;
12073 f->minimize_tool_bar_window_p = 0;
12074 return 0;
12078 /* Get information about the tool-bar item which is displayed in GLYPH
12079 on frame F. Return in *PROP_IDX the index where tool-bar item
12080 properties start in F->tool_bar_items. Value is zero if
12081 GLYPH doesn't display a tool-bar item. */
12083 static int
12084 tool_bar_item_info (struct frame *f, struct glyph *glyph, int *prop_idx)
12086 Lisp_Object prop;
12087 int success_p;
12088 int charpos;
12090 /* This function can be called asynchronously, which means we must
12091 exclude any possibility that Fget_text_property signals an
12092 error. */
12093 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
12094 charpos = max (0, charpos);
12096 /* Get the text property `menu-item' at pos. The value of that
12097 property is the start index of this item's properties in
12098 F->tool_bar_items. */
12099 prop = Fget_text_property (make_number (charpos),
12100 Qmenu_item, f->current_tool_bar_string);
12101 if (INTEGERP (prop))
12103 *prop_idx = XINT (prop);
12104 success_p = 1;
12106 else
12107 success_p = 0;
12109 return success_p;
12113 /* Get information about the tool-bar item at position X/Y on frame F.
12114 Return in *GLYPH a pointer to the glyph of the tool-bar item in
12115 the current matrix of the tool-bar window of F, or NULL if not
12116 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
12117 item in F->tool_bar_items. Value is
12119 -1 if X/Y is not on a tool-bar item
12120 0 if X/Y is on the same item that was highlighted before.
12121 1 otherwise. */
12123 static int
12124 get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
12125 int *hpos, int *vpos, int *prop_idx)
12127 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12128 struct window *w = XWINDOW (f->tool_bar_window);
12129 int area;
12131 /* Find the glyph under X/Y. */
12132 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
12133 if (*glyph == NULL)
12134 return -1;
12136 /* Get the start of this tool-bar item's properties in
12137 f->tool_bar_items. */
12138 if (!tool_bar_item_info (f, *glyph, prop_idx))
12139 return -1;
12141 /* Is mouse on the highlighted item? */
12142 if (EQ (f->tool_bar_window, hlinfo->mouse_face_window)
12143 && *vpos >= hlinfo->mouse_face_beg_row
12144 && *vpos <= hlinfo->mouse_face_end_row
12145 && (*vpos > hlinfo->mouse_face_beg_row
12146 || *hpos >= hlinfo->mouse_face_beg_col)
12147 && (*vpos < hlinfo->mouse_face_end_row
12148 || *hpos < hlinfo->mouse_face_end_col
12149 || hlinfo->mouse_face_past_end))
12150 return 0;
12152 return 1;
12156 /* EXPORT:
12157 Handle mouse button event on the tool-bar of frame F, at
12158 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
12159 0 for button release. MODIFIERS is event modifiers for button
12160 release. */
12162 void
12163 handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
12164 int modifiers)
12166 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12167 struct window *w = XWINDOW (f->tool_bar_window);
12168 int hpos, vpos, prop_idx;
12169 struct glyph *glyph;
12170 Lisp_Object enabled_p;
12171 int ts;
12173 /* If not on the highlighted tool-bar item, and mouse-highlight is
12174 non-nil, return. This is so we generate the tool-bar button
12175 click only when the mouse button is released on the same item as
12176 where it was pressed. However, when mouse-highlight is disabled,
12177 generate the click when the button is released regardless of the
12178 highlight, since tool-bar items are not highlighted in that
12179 case. */
12180 frame_to_window_pixel_xy (w, &x, &y);
12181 ts = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
12182 if (ts == -1
12183 || (ts != 0 && !NILP (Vmouse_highlight)))
12184 return;
12186 /* When mouse-highlight is off, generate the click for the item
12187 where the button was pressed, disregarding where it was
12188 released. */
12189 if (NILP (Vmouse_highlight) && !down_p)
12190 prop_idx = last_tool_bar_item;
12192 /* If item is disabled, do nothing. */
12193 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
12194 if (NILP (enabled_p))
12195 return;
12197 if (down_p)
12199 /* Show item in pressed state. */
12200 if (!NILP (Vmouse_highlight))
12201 show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN);
12202 last_tool_bar_item = prop_idx;
12204 else
12206 Lisp_Object key, frame;
12207 struct input_event event;
12208 EVENT_INIT (event);
12210 /* Show item in released state. */
12211 if (!NILP (Vmouse_highlight))
12212 show_mouse_face (hlinfo, DRAW_IMAGE_RAISED);
12214 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
12216 XSETFRAME (frame, f);
12217 event.kind = TOOL_BAR_EVENT;
12218 event.frame_or_window = frame;
12219 event.arg = frame;
12220 kbd_buffer_store_event (&event);
12222 event.kind = TOOL_BAR_EVENT;
12223 event.frame_or_window = frame;
12224 event.arg = key;
12225 event.modifiers = modifiers;
12226 kbd_buffer_store_event (&event);
12227 last_tool_bar_item = -1;
12232 /* Possibly highlight a tool-bar item on frame F when mouse moves to
12233 tool-bar window-relative coordinates X/Y. Called from
12234 note_mouse_highlight. */
12236 static void
12237 note_tool_bar_highlight (struct frame *f, int x, int y)
12239 Lisp_Object window = f->tool_bar_window;
12240 struct window *w = XWINDOW (window);
12241 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
12242 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12243 int hpos, vpos;
12244 struct glyph *glyph;
12245 struct glyph_row *row;
12246 int i;
12247 Lisp_Object enabled_p;
12248 int prop_idx;
12249 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
12250 int mouse_down_p, rc;
12252 /* Function note_mouse_highlight is called with negative X/Y
12253 values when mouse moves outside of the frame. */
12254 if (x <= 0 || y <= 0)
12256 clear_mouse_face (hlinfo);
12257 return;
12260 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
12261 if (rc < 0)
12263 /* Not on tool-bar item. */
12264 clear_mouse_face (hlinfo);
12265 return;
12267 else if (rc == 0)
12268 /* On same tool-bar item as before. */
12269 goto set_help_echo;
12271 clear_mouse_face (hlinfo);
12273 /* Mouse is down, but on different tool-bar item? */
12274 mouse_down_p = (dpyinfo->grabbed
12275 && f == last_mouse_frame
12276 && FRAME_LIVE_P (f));
12277 if (mouse_down_p
12278 && last_tool_bar_item != prop_idx)
12279 return;
12281 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
12283 /* If tool-bar item is not enabled, don't highlight it. */
12284 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
12285 if (!NILP (enabled_p) && !NILP (Vmouse_highlight))
12287 /* Compute the x-position of the glyph. In front and past the
12288 image is a space. We include this in the highlighted area. */
12289 row = MATRIX_ROW (w->current_matrix, vpos);
12290 for (i = x = 0; i < hpos; ++i)
12291 x += row->glyphs[TEXT_AREA][i].pixel_width;
12293 /* Record this as the current active region. */
12294 hlinfo->mouse_face_beg_col = hpos;
12295 hlinfo->mouse_face_beg_row = vpos;
12296 hlinfo->mouse_face_beg_x = x;
12297 hlinfo->mouse_face_beg_y = row->y;
12298 hlinfo->mouse_face_past_end = 0;
12300 hlinfo->mouse_face_end_col = hpos + 1;
12301 hlinfo->mouse_face_end_row = vpos;
12302 hlinfo->mouse_face_end_x = x + glyph->pixel_width;
12303 hlinfo->mouse_face_end_y = row->y;
12304 hlinfo->mouse_face_window = window;
12305 hlinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
12307 /* Display it as active. */
12308 show_mouse_face (hlinfo, draw);
12311 set_help_echo:
12313 /* Set help_echo_string to a help string to display for this tool-bar item.
12314 XTread_socket does the rest. */
12315 help_echo_object = help_echo_window = Qnil;
12316 help_echo_pos = -1;
12317 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
12318 if (NILP (help_echo_string))
12319 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
12322 #endif /* HAVE_WINDOW_SYSTEM */
12326 /************************************************************************
12327 Horizontal scrolling
12328 ************************************************************************/
12330 static int hscroll_window_tree (Lisp_Object);
12331 static int hscroll_windows (Lisp_Object);
12333 /* For all leaf windows in the window tree rooted at WINDOW, set their
12334 hscroll value so that PT is (i) visible in the window, and (ii) so
12335 that it is not within a certain margin at the window's left and
12336 right border. Value is non-zero if any window's hscroll has been
12337 changed. */
12339 static int
12340 hscroll_window_tree (Lisp_Object window)
12342 int hscrolled_p = 0;
12343 int hscroll_relative_p = FLOATP (Vhscroll_step);
12344 int hscroll_step_abs = 0;
12345 double hscroll_step_rel = 0;
12347 if (hscroll_relative_p)
12349 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
12350 if (hscroll_step_rel < 0)
12352 hscroll_relative_p = 0;
12353 hscroll_step_abs = 0;
12356 else if (TYPE_RANGED_INTEGERP (int, Vhscroll_step))
12358 hscroll_step_abs = XINT (Vhscroll_step);
12359 if (hscroll_step_abs < 0)
12360 hscroll_step_abs = 0;
12362 else
12363 hscroll_step_abs = 0;
12365 while (WINDOWP (window))
12367 struct window *w = XWINDOW (window);
12369 if (WINDOWP (w->contents))
12370 hscrolled_p |= hscroll_window_tree (w->contents);
12371 else if (w->cursor.vpos >= 0)
12373 int h_margin;
12374 int text_area_width;
12375 struct glyph_row *current_cursor_row
12376 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
12377 struct glyph_row *desired_cursor_row
12378 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
12379 struct glyph_row *cursor_row
12380 = (desired_cursor_row->enabled_p
12381 ? desired_cursor_row
12382 : current_cursor_row);
12383 int row_r2l_p = cursor_row->reversed_p;
12385 text_area_width = window_box_width (w, TEXT_AREA);
12387 /* Scroll when cursor is inside this scroll margin. */
12388 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
12390 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->contents))
12391 /* For left-to-right rows, hscroll when cursor is either
12392 (i) inside the right hscroll margin, or (ii) if it is
12393 inside the left margin and the window is already
12394 hscrolled. */
12395 && ((!row_r2l_p
12396 && ((w->hscroll
12397 && w->cursor.x <= h_margin)
12398 || (cursor_row->enabled_p
12399 && cursor_row->truncated_on_right_p
12400 && (w->cursor.x >= text_area_width - h_margin))))
12401 /* For right-to-left rows, the logic is similar,
12402 except that rules for scrolling to left and right
12403 are reversed. E.g., if cursor.x <= h_margin, we
12404 need to hscroll "to the right" unconditionally,
12405 and that will scroll the screen to the left so as
12406 to reveal the next portion of the row. */
12407 || (row_r2l_p
12408 && ((cursor_row->enabled_p
12409 /* FIXME: It is confusing to set the
12410 truncated_on_right_p flag when R2L rows
12411 are actually truncated on the left. */
12412 && cursor_row->truncated_on_right_p
12413 && w->cursor.x <= h_margin)
12414 || (w->hscroll
12415 && (w->cursor.x >= text_area_width - h_margin))))))
12417 struct it it;
12418 ptrdiff_t hscroll;
12419 struct buffer *saved_current_buffer;
12420 ptrdiff_t pt;
12421 int wanted_x;
12423 /* Find point in a display of infinite width. */
12424 saved_current_buffer = current_buffer;
12425 current_buffer = XBUFFER (w->contents);
12427 if (w == XWINDOW (selected_window))
12428 pt = PT;
12429 else
12430 pt = clip_to_bounds (BEGV, marker_position (w->pointm), ZV);
12432 /* Move iterator to pt starting at cursor_row->start in
12433 a line with infinite width. */
12434 init_to_row_start (&it, w, cursor_row);
12435 it.last_visible_x = INFINITY;
12436 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
12437 current_buffer = saved_current_buffer;
12439 /* Position cursor in window. */
12440 if (!hscroll_relative_p && hscroll_step_abs == 0)
12441 hscroll = max (0, (it.current_x
12442 - (ITERATOR_AT_END_OF_LINE_P (&it)
12443 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
12444 : (text_area_width / 2))))
12445 / FRAME_COLUMN_WIDTH (it.f);
12446 else if ((!row_r2l_p
12447 && w->cursor.x >= text_area_width - h_margin)
12448 || (row_r2l_p && w->cursor.x <= h_margin))
12450 if (hscroll_relative_p)
12451 wanted_x = text_area_width * (1 - hscroll_step_rel)
12452 - h_margin;
12453 else
12454 wanted_x = text_area_width
12455 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
12456 - h_margin;
12457 hscroll
12458 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
12460 else
12462 if (hscroll_relative_p)
12463 wanted_x = text_area_width * hscroll_step_rel
12464 + h_margin;
12465 else
12466 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
12467 + h_margin;
12468 hscroll
12469 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
12471 hscroll = max (hscroll, w->min_hscroll);
12473 /* Don't prevent redisplay optimizations if hscroll
12474 hasn't changed, as it will unnecessarily slow down
12475 redisplay. */
12476 if (w->hscroll != hscroll)
12478 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
12479 w->hscroll = hscroll;
12480 hscrolled_p = 1;
12485 window = w->next;
12488 /* Value is non-zero if hscroll of any leaf window has been changed. */
12489 return hscrolled_p;
12493 /* Set hscroll so that cursor is visible and not inside horizontal
12494 scroll margins for all windows in the tree rooted at WINDOW. See
12495 also hscroll_window_tree above. Value is non-zero if any window's
12496 hscroll has been changed. If it has, desired matrices on the frame
12497 of WINDOW are cleared. */
12499 static int
12500 hscroll_windows (Lisp_Object window)
12502 int hscrolled_p = hscroll_window_tree (window);
12503 if (hscrolled_p)
12504 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
12505 return hscrolled_p;
12510 /************************************************************************
12511 Redisplay
12512 ************************************************************************/
12514 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
12515 to a non-zero value. This is sometimes handy to have in a debugger
12516 session. */
12518 #ifdef GLYPH_DEBUG
12520 /* First and last unchanged row for try_window_id. */
12522 static int debug_first_unchanged_at_end_vpos;
12523 static int debug_last_unchanged_at_beg_vpos;
12525 /* Delta vpos and y. */
12527 static int debug_dvpos, debug_dy;
12529 /* Delta in characters and bytes for try_window_id. */
12531 static ptrdiff_t debug_delta, debug_delta_bytes;
12533 /* Values of window_end_pos and window_end_vpos at the end of
12534 try_window_id. */
12536 static ptrdiff_t debug_end_vpos;
12538 /* Append a string to W->desired_matrix->method. FMT is a printf
12539 format string. If trace_redisplay_p is non-zero also printf the
12540 resulting string to stderr. */
12542 static void debug_method_add (struct window *, char const *, ...)
12543 ATTRIBUTE_FORMAT_PRINTF (2, 3);
12545 static void
12546 debug_method_add (struct window *w, char const *fmt, ...)
12548 char *method = w->desired_matrix->method;
12549 int len = strlen (method);
12550 int size = sizeof w->desired_matrix->method;
12551 int remaining = size - len - 1;
12552 va_list ap;
12554 if (len && remaining)
12556 method[len] = '|';
12557 --remaining, ++len;
12560 va_start (ap, fmt);
12561 vsnprintf (method + len, remaining + 1, fmt, ap);
12562 va_end (ap);
12564 if (trace_redisplay_p)
12565 fprintf (stderr, "%p (%s): %s\n",
12567 ((BUFFERP (w->contents)
12568 && STRINGP (BVAR (XBUFFER (w->contents), name)))
12569 ? SSDATA (BVAR (XBUFFER (w->contents), name))
12570 : "no buffer"),
12571 method + len);
12574 #endif /* GLYPH_DEBUG */
12577 /* Value is non-zero if all changes in window W, which displays
12578 current_buffer, are in the text between START and END. START is a
12579 buffer position, END is given as a distance from Z. Used in
12580 redisplay_internal for display optimization. */
12582 static int
12583 text_outside_line_unchanged_p (struct window *w,
12584 ptrdiff_t start, ptrdiff_t end)
12586 int unchanged_p = 1;
12588 /* If text or overlays have changed, see where. */
12589 if (window_outdated (w))
12591 /* Gap in the line? */
12592 if (GPT < start || Z - GPT < end)
12593 unchanged_p = 0;
12595 /* Changes start in front of the line, or end after it? */
12596 if (unchanged_p
12597 && (BEG_UNCHANGED < start - 1
12598 || END_UNCHANGED < end))
12599 unchanged_p = 0;
12601 /* If selective display, can't optimize if changes start at the
12602 beginning of the line. */
12603 if (unchanged_p
12604 && INTEGERP (BVAR (current_buffer, selective_display))
12605 && XINT (BVAR (current_buffer, selective_display)) > 0
12606 && (BEG_UNCHANGED < start || GPT <= start))
12607 unchanged_p = 0;
12609 /* If there are overlays at the start or end of the line, these
12610 may have overlay strings with newlines in them. A change at
12611 START, for instance, may actually concern the display of such
12612 overlay strings as well, and they are displayed on different
12613 lines. So, quickly rule out this case. (For the future, it
12614 might be desirable to implement something more telling than
12615 just BEG/END_UNCHANGED.) */
12616 if (unchanged_p)
12618 if (BEG + BEG_UNCHANGED == start
12619 && overlay_touches_p (start))
12620 unchanged_p = 0;
12621 if (END_UNCHANGED == end
12622 && overlay_touches_p (Z - end))
12623 unchanged_p = 0;
12626 /* Under bidi reordering, adding or deleting a character in the
12627 beginning of a paragraph, before the first strong directional
12628 character, can change the base direction of the paragraph (unless
12629 the buffer specifies a fixed paragraph direction), which will
12630 require to redisplay the whole paragraph. It might be worthwhile
12631 to find the paragraph limits and widen the range of redisplayed
12632 lines to that, but for now just give up this optimization. */
12633 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
12634 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
12635 unchanged_p = 0;
12638 return unchanged_p;
12642 /* Do a frame update, taking possible shortcuts into account. This is
12643 the main external entry point for redisplay.
12645 If the last redisplay displayed an echo area message and that message
12646 is no longer requested, we clear the echo area or bring back the
12647 mini-buffer if that is in use. */
12649 void
12650 redisplay (void)
12652 redisplay_internal ();
12656 static Lisp_Object
12657 overlay_arrow_string_or_property (Lisp_Object var)
12659 Lisp_Object val;
12661 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
12662 return val;
12664 return Voverlay_arrow_string;
12667 /* Return 1 if there are any overlay-arrows in current_buffer. */
12668 static int
12669 overlay_arrow_in_current_buffer_p (void)
12671 Lisp_Object vlist;
12673 for (vlist = Voverlay_arrow_variable_list;
12674 CONSP (vlist);
12675 vlist = XCDR (vlist))
12677 Lisp_Object var = XCAR (vlist);
12678 Lisp_Object val;
12680 if (!SYMBOLP (var))
12681 continue;
12682 val = find_symbol_value (var);
12683 if (MARKERP (val)
12684 && current_buffer == XMARKER (val)->buffer)
12685 return 1;
12687 return 0;
12691 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
12692 has changed. */
12694 static int
12695 overlay_arrows_changed_p (void)
12697 Lisp_Object vlist;
12699 for (vlist = Voverlay_arrow_variable_list;
12700 CONSP (vlist);
12701 vlist = XCDR (vlist))
12703 Lisp_Object var = XCAR (vlist);
12704 Lisp_Object val, pstr;
12706 if (!SYMBOLP (var))
12707 continue;
12708 val = find_symbol_value (var);
12709 if (!MARKERP (val))
12710 continue;
12711 if (! EQ (COERCE_MARKER (val),
12712 Fget (var, Qlast_arrow_position))
12713 || ! (pstr = overlay_arrow_string_or_property (var),
12714 EQ (pstr, Fget (var, Qlast_arrow_string))))
12715 return 1;
12717 return 0;
12720 /* Mark overlay arrows to be updated on next redisplay. */
12722 static void
12723 update_overlay_arrows (int up_to_date)
12725 Lisp_Object vlist;
12727 for (vlist = Voverlay_arrow_variable_list;
12728 CONSP (vlist);
12729 vlist = XCDR (vlist))
12731 Lisp_Object var = XCAR (vlist);
12733 if (!SYMBOLP (var))
12734 continue;
12736 if (up_to_date > 0)
12738 Lisp_Object val = find_symbol_value (var);
12739 Fput (var, Qlast_arrow_position,
12740 COERCE_MARKER (val));
12741 Fput (var, Qlast_arrow_string,
12742 overlay_arrow_string_or_property (var));
12744 else if (up_to_date < 0
12745 || !NILP (Fget (var, Qlast_arrow_position)))
12747 Fput (var, Qlast_arrow_position, Qt);
12748 Fput (var, Qlast_arrow_string, Qt);
12754 /* Return overlay arrow string to display at row.
12755 Return integer (bitmap number) for arrow bitmap in left fringe.
12756 Return nil if no overlay arrow. */
12758 static Lisp_Object
12759 overlay_arrow_at_row (struct it *it, struct glyph_row *row)
12761 Lisp_Object vlist;
12763 for (vlist = Voverlay_arrow_variable_list;
12764 CONSP (vlist);
12765 vlist = XCDR (vlist))
12767 Lisp_Object var = XCAR (vlist);
12768 Lisp_Object val;
12770 if (!SYMBOLP (var))
12771 continue;
12773 val = find_symbol_value (var);
12775 if (MARKERP (val)
12776 && current_buffer == XMARKER (val)->buffer
12777 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
12779 if (FRAME_WINDOW_P (it->f)
12780 /* FIXME: if ROW->reversed_p is set, this should test
12781 the right fringe, not the left one. */
12782 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
12784 #ifdef HAVE_WINDOW_SYSTEM
12785 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
12787 int fringe_bitmap;
12788 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
12789 return make_number (fringe_bitmap);
12791 #endif
12792 return make_number (-1); /* Use default arrow bitmap. */
12794 return overlay_arrow_string_or_property (var);
12798 return Qnil;
12801 /* Return 1 if point moved out of or into a composition. Otherwise
12802 return 0. PREV_BUF and PREV_PT are the last point buffer and
12803 position. BUF and PT are the current point buffer and position. */
12805 static int
12806 check_point_in_composition (struct buffer *prev_buf, ptrdiff_t prev_pt,
12807 struct buffer *buf, ptrdiff_t pt)
12809 ptrdiff_t start, end;
12810 Lisp_Object prop;
12811 Lisp_Object buffer;
12813 XSETBUFFER (buffer, buf);
12814 /* Check a composition at the last point if point moved within the
12815 same buffer. */
12816 if (prev_buf == buf)
12818 if (prev_pt == pt)
12819 /* Point didn't move. */
12820 return 0;
12822 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
12823 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
12824 && COMPOSITION_VALID_P (start, end, prop)
12825 && start < prev_pt && end > prev_pt)
12826 /* The last point was within the composition. Return 1 iff
12827 point moved out of the composition. */
12828 return (pt <= start || pt >= end);
12831 /* Check a composition at the current point. */
12832 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
12833 && find_composition (pt, -1, &start, &end, &prop, buffer)
12834 && COMPOSITION_VALID_P (start, end, prop)
12835 && start < pt && end > pt);
12839 /* Reconsider the setting of B->clip_changed which is displayed
12840 in window W. */
12842 static void
12843 reconsider_clip_changes (struct window *w, struct buffer *b)
12845 if (b->clip_changed
12846 && w->window_end_valid
12847 && w->current_matrix->buffer == b
12848 && w->current_matrix->zv == BUF_ZV (b)
12849 && w->current_matrix->begv == BUF_BEGV (b))
12850 b->clip_changed = 0;
12852 /* If display wasn't paused, and W is not a tool bar window, see if
12853 point has been moved into or out of a composition. In that case,
12854 we set b->clip_changed to 1 to force updating the screen. If
12855 b->clip_changed has already been set to 1, we can skip this
12856 check. */
12857 if (!b->clip_changed && BUFFERP (w->contents) && w->window_end_valid)
12859 ptrdiff_t pt;
12861 if (w == XWINDOW (selected_window))
12862 pt = PT;
12863 else
12864 pt = marker_position (w->pointm);
12866 if ((w->current_matrix->buffer != XBUFFER (w->contents)
12867 || pt != w->last_point)
12868 && check_point_in_composition (w->current_matrix->buffer,
12869 w->last_point,
12870 XBUFFER (w->contents), pt))
12871 b->clip_changed = 1;
12876 #define STOP_POLLING \
12877 do { if (! polling_stopped_here) stop_polling (); \
12878 polling_stopped_here = 1; } while (0)
12880 #define RESUME_POLLING \
12881 do { if (polling_stopped_here) start_polling (); \
12882 polling_stopped_here = 0; } while (0)
12885 /* Perhaps in the future avoid recentering windows if it
12886 is not necessary; currently that causes some problems. */
12888 static void
12889 redisplay_internal (void)
12891 struct window *w = XWINDOW (selected_window);
12892 struct window *sw;
12893 struct frame *fr;
12894 int pending;
12895 int must_finish = 0;
12896 struct text_pos tlbufpos, tlendpos;
12897 int number_of_visible_frames;
12898 ptrdiff_t count, count1;
12899 struct frame *sf;
12900 int polling_stopped_here = 0;
12901 Lisp_Object tail, frame;
12903 /* Non-zero means redisplay has to consider all windows on all
12904 frames. Zero means, only selected_window is considered. */
12905 int consider_all_windows_p;
12907 /* Non-zero means redisplay has to redisplay the miniwindow. */
12908 int update_miniwindow_p = 0;
12910 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
12912 /* No redisplay if running in batch mode or frame is not yet fully
12913 initialized, or redisplay is explicitly turned off by setting
12914 Vinhibit_redisplay. */
12915 if (FRAME_INITIAL_P (SELECTED_FRAME ())
12916 || !NILP (Vinhibit_redisplay))
12917 return;
12919 /* Don't examine these until after testing Vinhibit_redisplay.
12920 When Emacs is shutting down, perhaps because its connection to
12921 X has dropped, we should not look at them at all. */
12922 fr = XFRAME (w->frame);
12923 sf = SELECTED_FRAME ();
12925 if (!fr->glyphs_initialized_p)
12926 return;
12928 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
12929 if (popup_activated ())
12930 return;
12931 #endif
12933 /* I don't think this happens but let's be paranoid. */
12934 if (redisplaying_p)
12935 return;
12937 /* Record a function that clears redisplaying_p
12938 when we leave this function. */
12939 count = SPECPDL_INDEX ();
12940 record_unwind_protect (unwind_redisplay, selected_frame);
12941 redisplaying_p = 1;
12942 specbind (Qinhibit_free_realized_faces, Qnil);
12944 /* Record this function, so it appears on the profiler's backtraces. */
12945 record_in_backtrace (Qredisplay_internal, &Qnil, 0);
12947 FOR_EACH_FRAME (tail, frame)
12948 XFRAME (frame)->already_hscrolled_p = 0;
12950 retry:
12951 /* Remember the currently selected window. */
12952 sw = w;
12954 pending = 0;
12955 reconsider_clip_changes (w, current_buffer);
12956 last_escape_glyph_frame = NULL;
12957 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
12958 last_glyphless_glyph_frame = NULL;
12959 last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
12961 /* If new fonts have been loaded that make a glyph matrix adjustment
12962 necessary, do it. */
12963 if (fonts_changed_p)
12965 adjust_glyphs (NULL);
12966 ++windows_or_buffers_changed;
12967 fonts_changed_p = 0;
12970 /* If face_change_count is non-zero, init_iterator will free all
12971 realized faces, which includes the faces referenced from current
12972 matrices. So, we can't reuse current matrices in this case. */
12973 if (face_change_count)
12974 ++windows_or_buffers_changed;
12976 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
12977 && FRAME_TTY (sf)->previous_frame != sf)
12979 /* Since frames on a single ASCII terminal share the same
12980 display area, displaying a different frame means redisplay
12981 the whole thing. */
12982 windows_or_buffers_changed++;
12983 SET_FRAME_GARBAGED (sf);
12984 #ifndef DOS_NT
12985 set_tty_color_mode (FRAME_TTY (sf), sf);
12986 #endif
12987 FRAME_TTY (sf)->previous_frame = sf;
12990 /* Set the visible flags for all frames. Do this before checking for
12991 resized or garbaged frames; they want to know if their frames are
12992 visible. See the comment in frame.h for FRAME_SAMPLE_VISIBILITY. */
12993 number_of_visible_frames = 0;
12995 FOR_EACH_FRAME (tail, frame)
12997 struct frame *f = XFRAME (frame);
12999 if (FRAME_VISIBLE_P (f))
13000 ++number_of_visible_frames;
13001 clear_desired_matrices (f);
13004 /* Notice any pending interrupt request to change frame size. */
13005 do_pending_window_change (1);
13007 /* do_pending_window_change could change the selected_window due to
13008 frame resizing which makes the selected window too small. */
13009 if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw)
13011 sw = w;
13012 reconsider_clip_changes (w, current_buffer);
13015 /* Clear frames marked as garbaged. */
13016 clear_garbaged_frames ();
13018 /* Build menubar and tool-bar items. */
13019 if (NILP (Vmemory_full))
13020 prepare_menu_bars ();
13022 if (windows_or_buffers_changed)
13023 update_mode_lines++;
13025 /* Detect case that we need to write or remove a star in the mode line. */
13026 if ((SAVE_MODIFF < MODIFF) != w->last_had_star)
13028 w->update_mode_line = 1;
13029 if (buffer_shared_and_changed ())
13030 update_mode_lines++;
13033 /* Avoid invocation of point motion hooks by `current_column' below. */
13034 count1 = SPECPDL_INDEX ();
13035 specbind (Qinhibit_point_motion_hooks, Qt);
13037 if (mode_line_update_needed (w))
13038 w->update_mode_line = 1;
13040 unbind_to (count1, Qnil);
13042 consider_all_windows_p = (update_mode_lines
13043 || buffer_shared_and_changed ()
13044 || cursor_type_changed);
13046 /* If specs for an arrow have changed, do thorough redisplay
13047 to ensure we remove any arrow that should no longer exist. */
13048 if (overlay_arrows_changed_p ())
13049 consider_all_windows_p = windows_or_buffers_changed = 1;
13051 /* Normally the message* functions will have already displayed and
13052 updated the echo area, but the frame may have been trashed, or
13053 the update may have been preempted, so display the echo area
13054 again here. Checking message_cleared_p captures the case that
13055 the echo area should be cleared. */
13056 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
13057 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
13058 || (message_cleared_p
13059 && minibuf_level == 0
13060 /* If the mini-window is currently selected, this means the
13061 echo-area doesn't show through. */
13062 && !MINI_WINDOW_P (XWINDOW (selected_window))))
13064 int window_height_changed_p = echo_area_display (0);
13066 if (message_cleared_p)
13067 update_miniwindow_p = 1;
13069 must_finish = 1;
13071 /* If we don't display the current message, don't clear the
13072 message_cleared_p flag, because, if we did, we wouldn't clear
13073 the echo area in the next redisplay which doesn't preserve
13074 the echo area. */
13075 if (!display_last_displayed_message_p)
13076 message_cleared_p = 0;
13078 if (fonts_changed_p)
13079 goto retry;
13080 else if (window_height_changed_p)
13082 consider_all_windows_p = 1;
13083 ++update_mode_lines;
13084 ++windows_or_buffers_changed;
13086 /* If window configuration was changed, frames may have been
13087 marked garbaged. Clear them or we will experience
13088 surprises wrt scrolling. */
13089 clear_garbaged_frames ();
13092 else if (EQ (selected_window, minibuf_window)
13093 && (current_buffer->clip_changed || window_outdated (w))
13094 && resize_mini_window (w, 0))
13096 /* Resized active mini-window to fit the size of what it is
13097 showing if its contents might have changed. */
13098 must_finish = 1;
13099 /* FIXME: this causes all frames to be updated, which seems unnecessary
13100 since only the current frame needs to be considered. This function
13101 needs to be rewritten with two variables, consider_all_windows and
13102 consider_all_frames. */
13103 consider_all_windows_p = 1;
13104 ++windows_or_buffers_changed;
13105 ++update_mode_lines;
13107 /* If window configuration was changed, frames may have been
13108 marked garbaged. Clear them or we will experience
13109 surprises wrt scrolling. */
13110 clear_garbaged_frames ();
13113 /* If showing the region, and mark has changed, we must redisplay
13114 the whole window. The assignment to this_line_start_pos prevents
13115 the optimization directly below this if-statement. */
13116 if (((!NILP (Vtransient_mark_mode)
13117 && !NILP (BVAR (XBUFFER (w->contents), mark_active)))
13118 != (w->region_showing > 0))
13119 || (w->region_showing
13120 && w->region_showing
13121 != XINT (Fmarker_position (BVAR (XBUFFER (w->contents), mark)))))
13122 CHARPOS (this_line_start_pos) = 0;
13124 /* Optimize the case that only the line containing the cursor in the
13125 selected window has changed. Variables starting with this_ are
13126 set in display_line and record information about the line
13127 containing the cursor. */
13128 tlbufpos = this_line_start_pos;
13129 tlendpos = this_line_end_pos;
13130 if (!consider_all_windows_p
13131 && CHARPOS (tlbufpos) > 0
13132 && !w->update_mode_line
13133 && !current_buffer->clip_changed
13134 && !current_buffer->prevent_redisplay_optimizations_p
13135 && FRAME_VISIBLE_P (XFRAME (w->frame))
13136 && !FRAME_OBSCURED_P (XFRAME (w->frame))
13137 /* Make sure recorded data applies to current buffer, etc. */
13138 && this_line_buffer == current_buffer
13139 && current_buffer == XBUFFER (w->contents)
13140 && !w->force_start
13141 && !w->optional_new_start
13142 /* Point must be on the line that we have info recorded about. */
13143 && PT >= CHARPOS (tlbufpos)
13144 && PT <= Z - CHARPOS (tlendpos)
13145 /* All text outside that line, including its final newline,
13146 must be unchanged. */
13147 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
13148 CHARPOS (tlendpos)))
13150 if (CHARPOS (tlbufpos) > BEGV
13151 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
13152 && (CHARPOS (tlbufpos) == ZV
13153 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
13154 /* Former continuation line has disappeared by becoming empty. */
13155 goto cancel;
13156 else if (window_outdated (w) || MINI_WINDOW_P (w))
13158 /* We have to handle the case of continuation around a
13159 wide-column character (see the comment in indent.c around
13160 line 1340).
13162 For instance, in the following case:
13164 -------- Insert --------
13165 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
13166 J_I_ ==> J_I_ `^^' are cursors.
13167 ^^ ^^
13168 -------- --------
13170 As we have to redraw the line above, we cannot use this
13171 optimization. */
13173 struct it it;
13174 int line_height_before = this_line_pixel_height;
13176 /* Note that start_display will handle the case that the
13177 line starting at tlbufpos is a continuation line. */
13178 start_display (&it, w, tlbufpos);
13180 /* Implementation note: It this still necessary? */
13181 if (it.current_x != this_line_start_x)
13182 goto cancel;
13184 TRACE ((stderr, "trying display optimization 1\n"));
13185 w->cursor.vpos = -1;
13186 overlay_arrow_seen = 0;
13187 it.vpos = this_line_vpos;
13188 it.current_y = this_line_y;
13189 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
13190 display_line (&it);
13192 /* If line contains point, is not continued,
13193 and ends at same distance from eob as before, we win. */
13194 if (w->cursor.vpos >= 0
13195 /* Line is not continued, otherwise this_line_start_pos
13196 would have been set to 0 in display_line. */
13197 && CHARPOS (this_line_start_pos)
13198 /* Line ends as before. */
13199 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
13200 /* Line has same height as before. Otherwise other lines
13201 would have to be shifted up or down. */
13202 && this_line_pixel_height == line_height_before)
13204 /* If this is not the window's last line, we must adjust
13205 the charstarts of the lines below. */
13206 if (it.current_y < it.last_visible_y)
13208 struct glyph_row *row
13209 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
13210 ptrdiff_t delta, delta_bytes;
13212 /* We used to distinguish between two cases here,
13213 conditioned by Z - CHARPOS (tlendpos) == ZV, for
13214 when the line ends in a newline or the end of the
13215 buffer's accessible portion. But both cases did
13216 the same, so they were collapsed. */
13217 delta = (Z
13218 - CHARPOS (tlendpos)
13219 - MATRIX_ROW_START_CHARPOS (row));
13220 delta_bytes = (Z_BYTE
13221 - BYTEPOS (tlendpos)
13222 - MATRIX_ROW_START_BYTEPOS (row));
13224 increment_matrix_positions (w->current_matrix,
13225 this_line_vpos + 1,
13226 w->current_matrix->nrows,
13227 delta, delta_bytes);
13230 /* If this row displays text now but previously didn't,
13231 or vice versa, w->window_end_vpos may have to be
13232 adjusted. */
13233 if (MATRIX_ROW_DISPLAYS_TEXT_P (it.glyph_row - 1))
13235 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
13236 wset_window_end_vpos (w, make_number (this_line_vpos));
13238 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
13239 && this_line_vpos > 0)
13240 wset_window_end_vpos (w, make_number (this_line_vpos - 1));
13241 w->window_end_valid = 0;
13243 /* Update hint: No need to try to scroll in update_window. */
13244 w->desired_matrix->no_scrolling_p = 1;
13246 #ifdef GLYPH_DEBUG
13247 *w->desired_matrix->method = 0;
13248 debug_method_add (w, "optimization 1");
13249 #endif
13250 #ifdef HAVE_WINDOW_SYSTEM
13251 update_window_fringes (w, 0);
13252 #endif
13253 goto update;
13255 else
13256 goto cancel;
13258 else if (/* Cursor position hasn't changed. */
13259 PT == w->last_point
13260 /* Make sure the cursor was last displayed
13261 in this window. Otherwise we have to reposition it. */
13262 && 0 <= w->cursor.vpos
13263 && w->cursor.vpos < WINDOW_TOTAL_LINES (w))
13265 if (!must_finish)
13267 do_pending_window_change (1);
13268 /* If selected_window changed, redisplay again. */
13269 if (WINDOWP (selected_window)
13270 && (w = XWINDOW (selected_window)) != sw)
13271 goto retry;
13273 /* We used to always goto end_of_redisplay here, but this
13274 isn't enough if we have a blinking cursor. */
13275 if (w->cursor_off_p == w->last_cursor_off_p)
13276 goto end_of_redisplay;
13278 goto update;
13280 /* If highlighting the region, or if the cursor is in the echo area,
13281 then we can't just move the cursor. */
13282 else if (! (!NILP (Vtransient_mark_mode)
13283 && !NILP (BVAR (current_buffer, mark_active)))
13284 && (EQ (selected_window,
13285 BVAR (current_buffer, last_selected_window))
13286 || highlight_nonselected_windows)
13287 && !w->region_showing
13288 && NILP (Vshow_trailing_whitespace)
13289 && !cursor_in_echo_area)
13291 struct it it;
13292 struct glyph_row *row;
13294 /* Skip from tlbufpos to PT and see where it is. Note that
13295 PT may be in invisible text. If so, we will end at the
13296 next visible position. */
13297 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
13298 NULL, DEFAULT_FACE_ID);
13299 it.current_x = this_line_start_x;
13300 it.current_y = this_line_y;
13301 it.vpos = this_line_vpos;
13303 /* The call to move_it_to stops in front of PT, but
13304 moves over before-strings. */
13305 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
13307 if (it.vpos == this_line_vpos
13308 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
13309 row->enabled_p))
13311 eassert (this_line_vpos == it.vpos);
13312 eassert (this_line_y == it.current_y);
13313 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13314 #ifdef GLYPH_DEBUG
13315 *w->desired_matrix->method = 0;
13316 debug_method_add (w, "optimization 3");
13317 #endif
13318 goto update;
13320 else
13321 goto cancel;
13324 cancel:
13325 /* Text changed drastically or point moved off of line. */
13326 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
13329 CHARPOS (this_line_start_pos) = 0;
13330 consider_all_windows_p |= buffer_shared_and_changed ();
13331 ++clear_face_cache_count;
13332 #ifdef HAVE_WINDOW_SYSTEM
13333 ++clear_image_cache_count;
13334 #endif
13336 /* Build desired matrices, and update the display. If
13337 consider_all_windows_p is non-zero, do it for all windows on all
13338 frames. Otherwise do it for selected_window, only. */
13340 if (consider_all_windows_p)
13342 FOR_EACH_FRAME (tail, frame)
13343 XFRAME (frame)->updated_p = 0;
13345 FOR_EACH_FRAME (tail, frame)
13347 struct frame *f = XFRAME (frame);
13349 /* We don't have to do anything for unselected terminal
13350 frames. */
13351 if ((FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
13352 && !EQ (FRAME_TTY (f)->top_frame, frame))
13353 continue;
13355 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
13357 /* Mark all the scroll bars to be removed; we'll redeem
13358 the ones we want when we redisplay their windows. */
13359 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
13360 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
13362 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
13363 redisplay_windows (FRAME_ROOT_WINDOW (f));
13365 /* The X error handler may have deleted that frame. */
13366 if (!FRAME_LIVE_P (f))
13367 continue;
13369 /* Any scroll bars which redisplay_windows should have
13370 nuked should now go away. */
13371 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
13372 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
13374 /* If fonts changed, display again. */
13375 /* ??? rms: I suspect it is a mistake to jump all the way
13376 back to retry here. It should just retry this frame. */
13377 if (fonts_changed_p)
13378 goto retry;
13380 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
13382 /* See if we have to hscroll. */
13383 if (!f->already_hscrolled_p)
13385 f->already_hscrolled_p = 1;
13386 if (hscroll_windows (f->root_window))
13387 goto retry;
13390 /* Prevent various kinds of signals during display
13391 update. stdio is not robust about handling
13392 signals, which can cause an apparent I/O
13393 error. */
13394 if (interrupt_input)
13395 unrequest_sigio ();
13396 STOP_POLLING;
13398 /* Update the display. */
13399 set_window_update_flags (XWINDOW (f->root_window), 1);
13400 pending |= update_frame (f, 0, 0);
13401 f->updated_p = 1;
13406 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
13408 if (!pending)
13410 /* Do the mark_window_display_accurate after all windows have
13411 been redisplayed because this call resets flags in buffers
13412 which are needed for proper redisplay. */
13413 FOR_EACH_FRAME (tail, frame)
13415 struct frame *f = XFRAME (frame);
13416 if (f->updated_p)
13418 mark_window_display_accurate (f->root_window, 1);
13419 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
13420 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
13425 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
13427 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
13428 struct frame *mini_frame;
13430 displayed_buffer = XBUFFER (XWINDOW (selected_window)->contents);
13431 /* Use list_of_error, not Qerror, so that
13432 we catch only errors and don't run the debugger. */
13433 internal_condition_case_1 (redisplay_window_1, selected_window,
13434 list_of_error,
13435 redisplay_window_error);
13436 if (update_miniwindow_p)
13437 internal_condition_case_1 (redisplay_window_1, mini_window,
13438 list_of_error,
13439 redisplay_window_error);
13441 /* Compare desired and current matrices, perform output. */
13443 update:
13444 /* If fonts changed, display again. */
13445 if (fonts_changed_p)
13446 goto retry;
13448 /* Prevent various kinds of signals during display update.
13449 stdio is not robust about handling signals,
13450 which can cause an apparent I/O error. */
13451 if (interrupt_input)
13452 unrequest_sigio ();
13453 STOP_POLLING;
13455 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
13457 if (hscroll_windows (selected_window))
13458 goto retry;
13460 XWINDOW (selected_window)->must_be_updated_p = 1;
13461 pending = update_frame (sf, 0, 0);
13464 /* We may have called echo_area_display at the top of this
13465 function. If the echo area is on another frame, that may
13466 have put text on a frame other than the selected one, so the
13467 above call to update_frame would not have caught it. Catch
13468 it here. */
13469 mini_window = FRAME_MINIBUF_WINDOW (sf);
13470 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
13472 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
13474 XWINDOW (mini_window)->must_be_updated_p = 1;
13475 pending |= update_frame (mini_frame, 0, 0);
13476 if (!pending && hscroll_windows (mini_window))
13477 goto retry;
13481 /* If display was paused because of pending input, make sure we do a
13482 thorough update the next time. */
13483 if (pending)
13485 /* Prevent the optimization at the beginning of
13486 redisplay_internal that tries a single-line update of the
13487 line containing the cursor in the selected window. */
13488 CHARPOS (this_line_start_pos) = 0;
13490 /* Let the overlay arrow be updated the next time. */
13491 update_overlay_arrows (0);
13493 /* If we pause after scrolling, some rows in the current
13494 matrices of some windows are not valid. */
13495 if (!WINDOW_FULL_WIDTH_P (w)
13496 && !FRAME_WINDOW_P (XFRAME (w->frame)))
13497 update_mode_lines = 1;
13499 else
13501 if (!consider_all_windows_p)
13503 /* This has already been done above if
13504 consider_all_windows_p is set. */
13505 mark_window_display_accurate_1 (w, 1);
13507 /* Say overlay arrows are up to date. */
13508 update_overlay_arrows (1);
13510 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
13511 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
13514 update_mode_lines = 0;
13515 windows_or_buffers_changed = 0;
13516 cursor_type_changed = 0;
13519 /* Start SIGIO interrupts coming again. Having them off during the
13520 code above makes it less likely one will discard output, but not
13521 impossible, since there might be stuff in the system buffer here.
13522 But it is much hairier to try to do anything about that. */
13523 if (interrupt_input)
13524 request_sigio ();
13525 RESUME_POLLING;
13527 /* If a frame has become visible which was not before, redisplay
13528 again, so that we display it. Expose events for such a frame
13529 (which it gets when becoming visible) don't call the parts of
13530 redisplay constructing glyphs, so simply exposing a frame won't
13531 display anything in this case. So, we have to display these
13532 frames here explicitly. */
13533 if (!pending)
13535 int new_count = 0;
13537 FOR_EACH_FRAME (tail, frame)
13539 int this_is_visible = 0;
13541 if (XFRAME (frame)->visible)
13542 this_is_visible = 1;
13544 if (this_is_visible)
13545 new_count++;
13548 if (new_count != number_of_visible_frames)
13549 windows_or_buffers_changed++;
13552 /* Change frame size now if a change is pending. */
13553 do_pending_window_change (1);
13555 /* If we just did a pending size change, or have additional
13556 visible frames, or selected_window changed, redisplay again. */
13557 if ((windows_or_buffers_changed && !pending)
13558 || (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw))
13559 goto retry;
13561 /* Clear the face and image caches.
13563 We used to do this only if consider_all_windows_p. But the cache
13564 needs to be cleared if a timer creates images in the current
13565 buffer (e.g. the test case in Bug#6230). */
13567 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
13569 clear_face_cache (0);
13570 clear_face_cache_count = 0;
13573 #ifdef HAVE_WINDOW_SYSTEM
13574 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
13576 clear_image_caches (Qnil);
13577 clear_image_cache_count = 0;
13579 #endif /* HAVE_WINDOW_SYSTEM */
13581 end_of_redisplay:
13582 unbind_to (count, Qnil);
13583 RESUME_POLLING;
13587 /* Redisplay, but leave alone any recent echo area message unless
13588 another message has been requested in its place.
13590 This is useful in situations where you need to redisplay but no
13591 user action has occurred, making it inappropriate for the message
13592 area to be cleared. See tracking_off and
13593 wait_reading_process_output for examples of these situations.
13595 FROM_WHERE is an integer saying from where this function was
13596 called. This is useful for debugging. */
13598 void
13599 redisplay_preserve_echo_area (int from_where)
13601 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
13603 if (!NILP (echo_area_buffer[1]))
13605 /* We have a previously displayed message, but no current
13606 message. Redisplay the previous message. */
13607 display_last_displayed_message_p = 1;
13608 redisplay_internal ();
13609 display_last_displayed_message_p = 0;
13611 else
13612 redisplay_internal ();
13614 if (FRAME_RIF (SELECTED_FRAME ()) != NULL
13615 && FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
13616 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (NULL);
13620 /* Function registered with record_unwind_protect in redisplay_internal.
13621 Clear redisplaying_p. Also select the previously selected frame. */
13623 static Lisp_Object
13624 unwind_redisplay (Lisp_Object old_frame)
13626 redisplaying_p = 0;
13627 return Qnil;
13631 /* Mark the display of leaf window W as accurate or inaccurate.
13632 If ACCURATE_P is non-zero mark display of W as accurate. If
13633 ACCURATE_P is zero, arrange for W to be redisplayed the next
13634 time redisplay_internal is called. */
13636 static void
13637 mark_window_display_accurate_1 (struct window *w, int accurate_p)
13639 struct buffer *b = XBUFFER (w->contents);
13641 w->last_modified = accurate_p ? BUF_MODIFF (b) : 0;
13642 w->last_overlay_modified = accurate_p ? BUF_OVERLAY_MODIFF (b) : 0;
13643 w->last_had_star = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b);
13645 if (accurate_p)
13647 b->clip_changed = 0;
13648 b->prevent_redisplay_optimizations_p = 0;
13650 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
13651 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
13652 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
13653 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
13655 w->current_matrix->buffer = b;
13656 w->current_matrix->begv = BUF_BEGV (b);
13657 w->current_matrix->zv = BUF_ZV (b);
13659 w->last_cursor = w->cursor;
13660 w->last_cursor_off_p = w->cursor_off_p;
13662 if (w == XWINDOW (selected_window))
13663 w->last_point = BUF_PT (b);
13664 else
13665 w->last_point = marker_position (w->pointm);
13667 w->window_end_valid = 1;
13668 w->update_mode_line = 0;
13673 /* Mark the display of windows in the window tree rooted at WINDOW as
13674 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
13675 windows as accurate. If ACCURATE_P is zero, arrange for windows to
13676 be redisplayed the next time redisplay_internal is called. */
13678 void
13679 mark_window_display_accurate (Lisp_Object window, int accurate_p)
13681 struct window *w;
13683 for (; !NILP (window); window = w->next)
13685 w = XWINDOW (window);
13686 if (WINDOWP (w->contents))
13687 mark_window_display_accurate (w->contents, accurate_p);
13688 else
13689 mark_window_display_accurate_1 (w, accurate_p);
13692 if (accurate_p)
13693 update_overlay_arrows (1);
13694 else
13695 /* Force a thorough redisplay the next time by setting
13696 last_arrow_position and last_arrow_string to t, which is
13697 unequal to any useful value of Voverlay_arrow_... */
13698 update_overlay_arrows (-1);
13702 /* Return value in display table DP (Lisp_Char_Table *) for character
13703 C. Since a display table doesn't have any parent, we don't have to
13704 follow parent. Do not call this function directly but use the
13705 macro DISP_CHAR_VECTOR. */
13707 Lisp_Object
13708 disp_char_vector (struct Lisp_Char_Table *dp, int c)
13710 Lisp_Object val;
13712 if (ASCII_CHAR_P (c))
13714 val = dp->ascii;
13715 if (SUB_CHAR_TABLE_P (val))
13716 val = XSUB_CHAR_TABLE (val)->contents[c];
13718 else
13720 Lisp_Object table;
13722 XSETCHAR_TABLE (table, dp);
13723 val = char_table_ref (table, c);
13725 if (NILP (val))
13726 val = dp->defalt;
13727 return val;
13732 /***********************************************************************
13733 Window Redisplay
13734 ***********************************************************************/
13736 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
13738 static void
13739 redisplay_windows (Lisp_Object window)
13741 while (!NILP (window))
13743 struct window *w = XWINDOW (window);
13745 if (WINDOWP (w->contents))
13746 redisplay_windows (w->contents);
13747 else if (BUFFERP (w->contents))
13749 displayed_buffer = XBUFFER (w->contents);
13750 /* Use list_of_error, not Qerror, so that
13751 we catch only errors and don't run the debugger. */
13752 internal_condition_case_1 (redisplay_window_0, window,
13753 list_of_error,
13754 redisplay_window_error);
13757 window = w->next;
13761 static Lisp_Object
13762 redisplay_window_error (Lisp_Object ignore)
13764 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
13765 return Qnil;
13768 static Lisp_Object
13769 redisplay_window_0 (Lisp_Object window)
13771 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
13772 redisplay_window (window, 0);
13773 return Qnil;
13776 static Lisp_Object
13777 redisplay_window_1 (Lisp_Object window)
13779 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
13780 redisplay_window (window, 1);
13781 return Qnil;
13785 /* Set cursor position of W. PT is assumed to be displayed in ROW.
13786 DELTA and DELTA_BYTES are the numbers of characters and bytes by
13787 which positions recorded in ROW differ from current buffer
13788 positions.
13790 Return 0 if cursor is not on this row, 1 otherwise. */
13792 static int
13793 set_cursor_from_row (struct window *w, struct glyph_row *row,
13794 struct glyph_matrix *matrix,
13795 ptrdiff_t delta, ptrdiff_t delta_bytes,
13796 int dy, int dvpos)
13798 struct glyph *glyph = row->glyphs[TEXT_AREA];
13799 struct glyph *end = glyph + row->used[TEXT_AREA];
13800 struct glyph *cursor = NULL;
13801 /* The last known character position in row. */
13802 ptrdiff_t last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
13803 int x = row->x;
13804 ptrdiff_t pt_old = PT - delta;
13805 ptrdiff_t pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
13806 ptrdiff_t pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
13807 struct glyph *glyph_before = glyph - 1, *glyph_after = end;
13808 /* A glyph beyond the edge of TEXT_AREA which we should never
13809 touch. */
13810 struct glyph *glyphs_end = end;
13811 /* Non-zero means we've found a match for cursor position, but that
13812 glyph has the avoid_cursor_p flag set. */
13813 int match_with_avoid_cursor = 0;
13814 /* Non-zero means we've seen at least one glyph that came from a
13815 display string. */
13816 int string_seen = 0;
13817 /* Largest and smallest buffer positions seen so far during scan of
13818 glyph row. */
13819 ptrdiff_t bpos_max = pos_before;
13820 ptrdiff_t bpos_min = pos_after;
13821 /* Last buffer position covered by an overlay string with an integer
13822 `cursor' property. */
13823 ptrdiff_t bpos_covered = 0;
13824 /* Non-zero means the display string on which to display the cursor
13825 comes from a text property, not from an overlay. */
13826 int string_from_text_prop = 0;
13828 /* Don't even try doing anything if called for a mode-line or
13829 header-line row, since the rest of the code isn't prepared to
13830 deal with such calamities. */
13831 eassert (!row->mode_line_p);
13832 if (row->mode_line_p)
13833 return 0;
13835 /* Skip over glyphs not having an object at the start and the end of
13836 the row. These are special glyphs like truncation marks on
13837 terminal frames. */
13838 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
13840 if (!row->reversed_p)
13842 while (glyph < end
13843 && INTEGERP (glyph->object)
13844 && glyph->charpos < 0)
13846 x += glyph->pixel_width;
13847 ++glyph;
13849 while (end > glyph
13850 && INTEGERP ((end - 1)->object)
13851 /* CHARPOS is zero for blanks and stretch glyphs
13852 inserted by extend_face_to_end_of_line. */
13853 && (end - 1)->charpos <= 0)
13854 --end;
13855 glyph_before = glyph - 1;
13856 glyph_after = end;
13858 else
13860 struct glyph *g;
13862 /* If the glyph row is reversed, we need to process it from back
13863 to front, so swap the edge pointers. */
13864 glyphs_end = end = glyph - 1;
13865 glyph += row->used[TEXT_AREA] - 1;
13867 while (glyph > end + 1
13868 && INTEGERP (glyph->object)
13869 && glyph->charpos < 0)
13871 --glyph;
13872 x -= glyph->pixel_width;
13874 if (INTEGERP (glyph->object) && glyph->charpos < 0)
13875 --glyph;
13876 /* By default, in reversed rows we put the cursor on the
13877 rightmost (first in the reading order) glyph. */
13878 for (g = end + 1; g < glyph; g++)
13879 x += g->pixel_width;
13880 while (end < glyph
13881 && INTEGERP ((end + 1)->object)
13882 && (end + 1)->charpos <= 0)
13883 ++end;
13884 glyph_before = glyph + 1;
13885 glyph_after = end;
13888 else if (row->reversed_p)
13890 /* In R2L rows that don't display text, put the cursor on the
13891 rightmost glyph. Case in point: an empty last line that is
13892 part of an R2L paragraph. */
13893 cursor = end - 1;
13894 /* Avoid placing the cursor on the last glyph of the row, where
13895 on terminal frames we hold the vertical border between
13896 adjacent windows. */
13897 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w))
13898 && !WINDOW_RIGHTMOST_P (w)
13899 && cursor == row->glyphs[LAST_AREA] - 1)
13900 cursor--;
13901 x = -1; /* will be computed below, at label compute_x */
13904 /* Step 1: Try to find the glyph whose character position
13905 corresponds to point. If that's not possible, find 2 glyphs
13906 whose character positions are the closest to point, one before
13907 point, the other after it. */
13908 if (!row->reversed_p)
13909 while (/* not marched to end of glyph row */
13910 glyph < end
13911 /* glyph was not inserted by redisplay for internal purposes */
13912 && !INTEGERP (glyph->object))
13914 if (BUFFERP (glyph->object))
13916 ptrdiff_t dpos = glyph->charpos - pt_old;
13918 if (glyph->charpos > bpos_max)
13919 bpos_max = glyph->charpos;
13920 if (glyph->charpos < bpos_min)
13921 bpos_min = glyph->charpos;
13922 if (!glyph->avoid_cursor_p)
13924 /* If we hit point, we've found the glyph on which to
13925 display the cursor. */
13926 if (dpos == 0)
13928 match_with_avoid_cursor = 0;
13929 break;
13931 /* See if we've found a better approximation to
13932 POS_BEFORE or to POS_AFTER. */
13933 if (0 > dpos && dpos > pos_before - pt_old)
13935 pos_before = glyph->charpos;
13936 glyph_before = glyph;
13938 else if (0 < dpos && dpos < pos_after - pt_old)
13940 pos_after = glyph->charpos;
13941 glyph_after = glyph;
13944 else if (dpos == 0)
13945 match_with_avoid_cursor = 1;
13947 else if (STRINGP (glyph->object))
13949 Lisp_Object chprop;
13950 ptrdiff_t glyph_pos = glyph->charpos;
13952 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
13953 glyph->object);
13954 if (!NILP (chprop))
13956 /* If the string came from a `display' text property,
13957 look up the buffer position of that property and
13958 use that position to update bpos_max, as if we
13959 actually saw such a position in one of the row's
13960 glyphs. This helps with supporting integer values
13961 of `cursor' property on the display string in
13962 situations where most or all of the row's buffer
13963 text is completely covered by display properties,
13964 so that no glyph with valid buffer positions is
13965 ever seen in the row. */
13966 ptrdiff_t prop_pos =
13967 string_buffer_position_lim (glyph->object, pos_before,
13968 pos_after, 0);
13970 if (prop_pos >= pos_before)
13971 bpos_max = prop_pos - 1;
13973 if (INTEGERP (chprop))
13975 bpos_covered = bpos_max + XINT (chprop);
13976 /* If the `cursor' property covers buffer positions up
13977 to and including point, we should display cursor on
13978 this glyph. Note that, if a `cursor' property on one
13979 of the string's characters has an integer value, we
13980 will break out of the loop below _before_ we get to
13981 the position match above. IOW, integer values of
13982 the `cursor' property override the "exact match for
13983 point" strategy of positioning the cursor. */
13984 /* Implementation note: bpos_max == pt_old when, e.g.,
13985 we are in an empty line, where bpos_max is set to
13986 MATRIX_ROW_START_CHARPOS, see above. */
13987 if (bpos_max <= pt_old && bpos_covered >= pt_old)
13989 cursor = glyph;
13990 break;
13994 string_seen = 1;
13996 x += glyph->pixel_width;
13997 ++glyph;
13999 else if (glyph > end) /* row is reversed */
14000 while (!INTEGERP (glyph->object))
14002 if (BUFFERP (glyph->object))
14004 ptrdiff_t dpos = glyph->charpos - pt_old;
14006 if (glyph->charpos > bpos_max)
14007 bpos_max = glyph->charpos;
14008 if (glyph->charpos < bpos_min)
14009 bpos_min = glyph->charpos;
14010 if (!glyph->avoid_cursor_p)
14012 if (dpos == 0)
14014 match_with_avoid_cursor = 0;
14015 break;
14017 if (0 > dpos && dpos > pos_before - pt_old)
14019 pos_before = glyph->charpos;
14020 glyph_before = glyph;
14022 else if (0 < dpos && dpos < pos_after - pt_old)
14024 pos_after = glyph->charpos;
14025 glyph_after = glyph;
14028 else if (dpos == 0)
14029 match_with_avoid_cursor = 1;
14031 else if (STRINGP (glyph->object))
14033 Lisp_Object chprop;
14034 ptrdiff_t glyph_pos = glyph->charpos;
14036 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
14037 glyph->object);
14038 if (!NILP (chprop))
14040 ptrdiff_t prop_pos =
14041 string_buffer_position_lim (glyph->object, pos_before,
14042 pos_after, 0);
14044 if (prop_pos >= pos_before)
14045 bpos_max = prop_pos - 1;
14047 if (INTEGERP (chprop))
14049 bpos_covered = bpos_max + XINT (chprop);
14050 /* If the `cursor' property covers buffer positions up
14051 to and including point, we should display cursor on
14052 this glyph. */
14053 if (bpos_max <= pt_old && bpos_covered >= pt_old)
14055 cursor = glyph;
14056 break;
14059 string_seen = 1;
14061 --glyph;
14062 if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
14064 x--; /* can't use any pixel_width */
14065 break;
14067 x -= glyph->pixel_width;
14070 /* Step 2: If we didn't find an exact match for point, we need to
14071 look for a proper place to put the cursor among glyphs between
14072 GLYPH_BEFORE and GLYPH_AFTER. */
14073 if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
14074 && BUFFERP (glyph->object) && glyph->charpos == pt_old)
14075 && !(bpos_max < pt_old && pt_old <= bpos_covered))
14077 /* An empty line has a single glyph whose OBJECT is zero and
14078 whose CHARPOS is the position of a newline on that line.
14079 Note that on a TTY, there are more glyphs after that, which
14080 were produced by extend_face_to_end_of_line, but their
14081 CHARPOS is zero or negative. */
14082 int empty_line_p =
14083 (row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
14084 && INTEGERP (glyph->object) && glyph->charpos > 0
14085 /* On a TTY, continued and truncated rows also have a glyph at
14086 their end whose OBJECT is zero and whose CHARPOS is
14087 positive (the continuation and truncation glyphs), but such
14088 rows are obviously not "empty". */
14089 && !(row->continued_p || row->truncated_on_right_p);
14091 if (row->ends_in_ellipsis_p && pos_after == last_pos)
14093 ptrdiff_t ellipsis_pos;
14095 /* Scan back over the ellipsis glyphs. */
14096 if (!row->reversed_p)
14098 ellipsis_pos = (glyph - 1)->charpos;
14099 while (glyph > row->glyphs[TEXT_AREA]
14100 && (glyph - 1)->charpos == ellipsis_pos)
14101 glyph--, x -= glyph->pixel_width;
14102 /* That loop always goes one position too far, including
14103 the glyph before the ellipsis. So scan forward over
14104 that one. */
14105 x += glyph->pixel_width;
14106 glyph++;
14108 else /* row is reversed */
14110 ellipsis_pos = (glyph + 1)->charpos;
14111 while (glyph < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14112 && (glyph + 1)->charpos == ellipsis_pos)
14113 glyph++, x += glyph->pixel_width;
14114 x -= glyph->pixel_width;
14115 glyph--;
14118 else if (match_with_avoid_cursor)
14120 cursor = glyph_after;
14121 x = -1;
14123 else if (string_seen)
14125 int incr = row->reversed_p ? -1 : +1;
14127 /* Need to find the glyph that came out of a string which is
14128 present at point. That glyph is somewhere between
14129 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
14130 positioned between POS_BEFORE and POS_AFTER in the
14131 buffer. */
14132 struct glyph *start, *stop;
14133 ptrdiff_t pos = pos_before;
14135 x = -1;
14137 /* If the row ends in a newline from a display string,
14138 reordering could have moved the glyphs belonging to the
14139 string out of the [GLYPH_BEFORE..GLYPH_AFTER] range. So
14140 in this case we extend the search to the last glyph in
14141 the row that was not inserted by redisplay. */
14142 if (row->ends_in_newline_from_string_p)
14144 glyph_after = end;
14145 pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
14148 /* GLYPH_BEFORE and GLYPH_AFTER are the glyphs that
14149 correspond to POS_BEFORE and POS_AFTER, respectively. We
14150 need START and STOP in the order that corresponds to the
14151 row's direction as given by its reversed_p flag. If the
14152 directionality of characters between POS_BEFORE and
14153 POS_AFTER is the opposite of the row's base direction,
14154 these characters will have been reordered for display,
14155 and we need to reverse START and STOP. */
14156 if (!row->reversed_p)
14158 start = min (glyph_before, glyph_after);
14159 stop = max (glyph_before, glyph_after);
14161 else
14163 start = max (glyph_before, glyph_after);
14164 stop = min (glyph_before, glyph_after);
14166 for (glyph = start + incr;
14167 row->reversed_p ? glyph > stop : glyph < stop; )
14170 /* Any glyphs that come from the buffer are here because
14171 of bidi reordering. Skip them, and only pay
14172 attention to glyphs that came from some string. */
14173 if (STRINGP (glyph->object))
14175 Lisp_Object str;
14176 ptrdiff_t tem;
14177 /* If the display property covers the newline, we
14178 need to search for it one position farther. */
14179 ptrdiff_t lim = pos_after
14180 + (pos_after == MATRIX_ROW_END_CHARPOS (row) + delta);
14182 string_from_text_prop = 0;
14183 str = glyph->object;
14184 tem = string_buffer_position_lim (str, pos, lim, 0);
14185 if (tem == 0 /* from overlay */
14186 || pos <= tem)
14188 /* If the string from which this glyph came is
14189 found in the buffer at point, or at position
14190 that is closer to point than pos_after, then
14191 we've found the glyph we've been looking for.
14192 If it comes from an overlay (tem == 0), and
14193 it has the `cursor' property on one of its
14194 glyphs, record that glyph as a candidate for
14195 displaying the cursor. (As in the
14196 unidirectional version, we will display the
14197 cursor on the last candidate we find.) */
14198 if (tem == 0
14199 || tem == pt_old
14200 || (tem - pt_old > 0 && tem < pos_after))
14202 /* The glyphs from this string could have
14203 been reordered. Find the one with the
14204 smallest string position. Or there could
14205 be a character in the string with the
14206 `cursor' property, which means display
14207 cursor on that character's glyph. */
14208 ptrdiff_t strpos = glyph->charpos;
14210 if (tem)
14212 cursor = glyph;
14213 string_from_text_prop = 1;
14215 for ( ;
14216 (row->reversed_p ? glyph > stop : glyph < stop)
14217 && EQ (glyph->object, str);
14218 glyph += incr)
14220 Lisp_Object cprop;
14221 ptrdiff_t gpos = glyph->charpos;
14223 cprop = Fget_char_property (make_number (gpos),
14224 Qcursor,
14225 glyph->object);
14226 if (!NILP (cprop))
14228 cursor = glyph;
14229 break;
14231 if (tem && glyph->charpos < strpos)
14233 strpos = glyph->charpos;
14234 cursor = glyph;
14238 if (tem == pt_old
14239 || (tem - pt_old > 0 && tem < pos_after))
14240 goto compute_x;
14242 if (tem)
14243 pos = tem + 1; /* don't find previous instances */
14245 /* This string is not what we want; skip all of the
14246 glyphs that came from it. */
14247 while ((row->reversed_p ? glyph > stop : glyph < stop)
14248 && EQ (glyph->object, str))
14249 glyph += incr;
14251 else
14252 glyph += incr;
14255 /* If we reached the end of the line, and END was from a string,
14256 the cursor is not on this line. */
14257 if (cursor == NULL
14258 && (row->reversed_p ? glyph <= end : glyph >= end)
14259 && (row->reversed_p ? end > glyphs_end : end < glyphs_end)
14260 && STRINGP (end->object)
14261 && row->continued_p)
14262 return 0;
14264 /* A truncated row may not include PT among its character positions.
14265 Setting the cursor inside the scroll margin will trigger
14266 recalculation of hscroll in hscroll_window_tree. But if a
14267 display string covers point, defer to the string-handling
14268 code below to figure this out. */
14269 else if (row->truncated_on_left_p && pt_old < bpos_min)
14271 cursor = glyph_before;
14272 x = -1;
14274 else if ((row->truncated_on_right_p && pt_old > bpos_max)
14275 /* Zero-width characters produce no glyphs. */
14276 || (!empty_line_p
14277 && (row->reversed_p
14278 ? glyph_after > glyphs_end
14279 : glyph_after < glyphs_end)))
14281 cursor = glyph_after;
14282 x = -1;
14286 compute_x:
14287 if (cursor != NULL)
14288 glyph = cursor;
14289 else if (glyph == glyphs_end
14290 && pos_before == pos_after
14291 && STRINGP ((row->reversed_p
14292 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14293 : row->glyphs[TEXT_AREA])->object))
14295 /* If all the glyphs of this row came from strings, put the
14296 cursor on the first glyph of the row. This avoids having the
14297 cursor outside of the text area in this very rare and hard
14298 use case. */
14299 glyph =
14300 row->reversed_p
14301 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14302 : row->glyphs[TEXT_AREA];
14304 if (x < 0)
14306 struct glyph *g;
14308 /* Need to compute x that corresponds to GLYPH. */
14309 for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++)
14311 if (g >= row->glyphs[TEXT_AREA] + row->used[TEXT_AREA])
14312 emacs_abort ();
14313 x += g->pixel_width;
14317 /* ROW could be part of a continued line, which, under bidi
14318 reordering, might have other rows whose start and end charpos
14319 occlude point. Only set w->cursor if we found a better
14320 approximation to the cursor position than we have from previously
14321 examined candidate rows belonging to the same continued line. */
14322 if (/* we already have a candidate row */
14323 w->cursor.vpos >= 0
14324 /* that candidate is not the row we are processing */
14325 && MATRIX_ROW (matrix, w->cursor.vpos) != row
14326 /* Make sure cursor.vpos specifies a row whose start and end
14327 charpos occlude point, and it is valid candidate for being a
14328 cursor-row. This is because some callers of this function
14329 leave cursor.vpos at the row where the cursor was displayed
14330 during the last redisplay cycle. */
14331 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old
14332 && pt_old <= MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14333 && cursor_row_p (MATRIX_ROW (matrix, w->cursor.vpos)))
14335 struct glyph *g1 =
14336 MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
14338 /* Don't consider glyphs that are outside TEXT_AREA. */
14339 if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
14340 return 0;
14341 /* Keep the candidate whose buffer position is the closest to
14342 point or has the `cursor' property. */
14343 if (/* previous candidate is a glyph in TEXT_AREA of that row */
14344 w->cursor.hpos >= 0
14345 && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
14346 && ((BUFFERP (g1->object)
14347 && (g1->charpos == pt_old /* an exact match always wins */
14348 || (BUFFERP (glyph->object)
14349 && eabs (g1->charpos - pt_old)
14350 < eabs (glyph->charpos - pt_old))))
14351 /* previous candidate is a glyph from a string that has
14352 a non-nil `cursor' property */
14353 || (STRINGP (g1->object)
14354 && (!NILP (Fget_char_property (make_number (g1->charpos),
14355 Qcursor, g1->object))
14356 /* previous candidate is from the same display
14357 string as this one, and the display string
14358 came from a text property */
14359 || (EQ (g1->object, glyph->object)
14360 && string_from_text_prop)
14361 /* this candidate is from newline and its
14362 position is not an exact match */
14363 || (INTEGERP (glyph->object)
14364 && glyph->charpos != pt_old)))))
14365 return 0;
14366 /* If this candidate gives an exact match, use that. */
14367 if (!((BUFFERP (glyph->object) && glyph->charpos == pt_old)
14368 /* If this candidate is a glyph created for the
14369 terminating newline of a line, and point is on that
14370 newline, it wins because it's an exact match. */
14371 || (!row->continued_p
14372 && INTEGERP (glyph->object)
14373 && glyph->charpos == 0
14374 && pt_old == MATRIX_ROW_END_CHARPOS (row) - 1))
14375 /* Otherwise, keep the candidate that comes from a row
14376 spanning less buffer positions. This may win when one or
14377 both candidate positions are on glyphs that came from
14378 display strings, for which we cannot compare buffer
14379 positions. */
14380 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14381 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14382 < MATRIX_ROW_END_CHARPOS (row) - MATRIX_ROW_START_CHARPOS (row))
14383 return 0;
14385 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
14386 w->cursor.x = x;
14387 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
14388 w->cursor.y = row->y + dy;
14390 if (w == XWINDOW (selected_window))
14392 if (!row->continued_p
14393 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
14394 && row->x == 0)
14396 this_line_buffer = XBUFFER (w->contents);
14398 CHARPOS (this_line_start_pos)
14399 = MATRIX_ROW_START_CHARPOS (row) + delta;
14400 BYTEPOS (this_line_start_pos)
14401 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
14403 CHARPOS (this_line_end_pos)
14404 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
14405 BYTEPOS (this_line_end_pos)
14406 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
14408 this_line_y = w->cursor.y;
14409 this_line_pixel_height = row->height;
14410 this_line_vpos = w->cursor.vpos;
14411 this_line_start_x = row->x;
14413 else
14414 CHARPOS (this_line_start_pos) = 0;
14417 return 1;
14421 /* Run window scroll functions, if any, for WINDOW with new window
14422 start STARTP. Sets the window start of WINDOW to that position.
14424 We assume that the window's buffer is really current. */
14426 static struct text_pos
14427 run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
14429 struct window *w = XWINDOW (window);
14430 SET_MARKER_FROM_TEXT_POS (w->start, startp);
14432 if (current_buffer != XBUFFER (w->contents))
14433 emacs_abort ();
14435 if (!NILP (Vwindow_scroll_functions))
14437 run_hook_with_args_2 (Qwindow_scroll_functions, window,
14438 make_number (CHARPOS (startp)));
14439 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14440 /* In case the hook functions switch buffers. */
14441 set_buffer_internal (XBUFFER (w->contents));
14444 return startp;
14448 /* Make sure the line containing the cursor is fully visible.
14449 A value of 1 means there is nothing to be done.
14450 (Either the line is fully visible, or it cannot be made so,
14451 or we cannot tell.)
14453 If FORCE_P is non-zero, return 0 even if partial visible cursor row
14454 is higher than window.
14456 A value of 0 means the caller should do scrolling
14457 as if point had gone off the screen. */
14459 static int
14460 cursor_row_fully_visible_p (struct window *w, int force_p, int current_matrix_p)
14462 struct glyph_matrix *matrix;
14463 struct glyph_row *row;
14464 int window_height;
14466 if (!make_cursor_line_fully_visible_p)
14467 return 1;
14469 /* It's not always possible to find the cursor, e.g, when a window
14470 is full of overlay strings. Don't do anything in that case. */
14471 if (w->cursor.vpos < 0)
14472 return 1;
14474 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
14475 row = MATRIX_ROW (matrix, w->cursor.vpos);
14477 /* If the cursor row is not partially visible, there's nothing to do. */
14478 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
14479 return 1;
14481 /* If the row the cursor is in is taller than the window's height,
14482 it's not clear what to do, so do nothing. */
14483 window_height = window_box_height (w);
14484 if (row->height >= window_height)
14486 if (!force_p || MINI_WINDOW_P (w)
14487 || w->vscroll || w->cursor.vpos == 0)
14488 return 1;
14490 return 0;
14494 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
14495 non-zero means only WINDOW is redisplayed in redisplay_internal.
14496 TEMP_SCROLL_STEP has the same meaning as emacs_scroll_step, and is used
14497 in redisplay_window to bring a partially visible line into view in
14498 the case that only the cursor has moved.
14500 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
14501 last screen line's vertical height extends past the end of the screen.
14503 Value is
14505 1 if scrolling succeeded
14507 0 if scrolling didn't find point.
14509 -1 if new fonts have been loaded so that we must interrupt
14510 redisplay, adjust glyph matrices, and try again. */
14512 enum
14514 SCROLLING_SUCCESS,
14515 SCROLLING_FAILED,
14516 SCROLLING_NEED_LARGER_MATRICES
14519 /* If scroll-conservatively is more than this, never recenter.
14521 If you change this, don't forget to update the doc string of
14522 `scroll-conservatively' and the Emacs manual. */
14523 #define SCROLL_LIMIT 100
14525 static int
14526 try_scrolling (Lisp_Object window, int just_this_one_p,
14527 ptrdiff_t arg_scroll_conservatively, ptrdiff_t scroll_step,
14528 int temp_scroll_step, int last_line_misfit)
14530 struct window *w = XWINDOW (window);
14531 struct frame *f = XFRAME (w->frame);
14532 struct text_pos pos, startp;
14533 struct it it;
14534 int this_scroll_margin, scroll_max, rc, height;
14535 int dy = 0, amount_to_scroll = 0, scroll_down_p = 0;
14536 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
14537 Lisp_Object aggressive;
14538 /* We will never try scrolling more than this number of lines. */
14539 int scroll_limit = SCROLL_LIMIT;
14541 #ifdef GLYPH_DEBUG
14542 debug_method_add (w, "try_scrolling");
14543 #endif
14545 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14547 /* Compute scroll margin height in pixels. We scroll when point is
14548 within this distance from the top or bottom of the window. */
14549 if (scroll_margin > 0)
14550 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
14551 * FRAME_LINE_HEIGHT (f);
14552 else
14553 this_scroll_margin = 0;
14555 /* Force arg_scroll_conservatively to have a reasonable value, to
14556 avoid scrolling too far away with slow move_it_* functions. Note
14557 that the user can supply scroll-conservatively equal to
14558 `most-positive-fixnum', which can be larger than INT_MAX. */
14559 if (arg_scroll_conservatively > scroll_limit)
14561 arg_scroll_conservatively = scroll_limit + 1;
14562 scroll_max = scroll_limit * FRAME_LINE_HEIGHT (f);
14564 else if (scroll_step || arg_scroll_conservatively || temp_scroll_step)
14565 /* Compute how much we should try to scroll maximally to bring
14566 point into view. */
14567 scroll_max = (max (scroll_step,
14568 max (arg_scroll_conservatively, temp_scroll_step))
14569 * FRAME_LINE_HEIGHT (f));
14570 else if (NUMBERP (BVAR (current_buffer, scroll_down_aggressively))
14571 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively)))
14572 /* We're trying to scroll because of aggressive scrolling but no
14573 scroll_step is set. Choose an arbitrary one. */
14574 scroll_max = 10 * FRAME_LINE_HEIGHT (f);
14575 else
14576 scroll_max = 0;
14578 too_near_end:
14580 /* Decide whether to scroll down. */
14581 if (PT > CHARPOS (startp))
14583 int scroll_margin_y;
14585 /* Compute the pixel ypos of the scroll margin, then move IT to
14586 either that ypos or PT, whichever comes first. */
14587 start_display (&it, w, startp);
14588 scroll_margin_y = it.last_visible_y - this_scroll_margin
14589 - FRAME_LINE_HEIGHT (f) * extra_scroll_margin_lines;
14590 move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
14591 (MOVE_TO_POS | MOVE_TO_Y));
14593 if (PT > CHARPOS (it.current.pos))
14595 int y0 = line_bottom_y (&it);
14596 /* Compute how many pixels below window bottom to stop searching
14597 for PT. This avoids costly search for PT that is far away if
14598 the user limited scrolling by a small number of lines, but
14599 always finds PT if scroll_conservatively is set to a large
14600 number, such as most-positive-fixnum. */
14601 int slack = max (scroll_max, 10 * FRAME_LINE_HEIGHT (f));
14602 int y_to_move = it.last_visible_y + slack;
14604 /* Compute the distance from the scroll margin to PT or to
14605 the scroll limit, whichever comes first. This should
14606 include the height of the cursor line, to make that line
14607 fully visible. */
14608 move_it_to (&it, PT, -1, y_to_move,
14609 -1, MOVE_TO_POS | MOVE_TO_Y);
14610 dy = line_bottom_y (&it) - y0;
14612 if (dy > scroll_max)
14613 return SCROLLING_FAILED;
14615 if (dy > 0)
14616 scroll_down_p = 1;
14620 if (scroll_down_p)
14622 /* Point is in or below the bottom scroll margin, so move the
14623 window start down. If scrolling conservatively, move it just
14624 enough down to make point visible. If scroll_step is set,
14625 move it down by scroll_step. */
14626 if (arg_scroll_conservatively)
14627 amount_to_scroll
14628 = min (max (dy, FRAME_LINE_HEIGHT (f)),
14629 FRAME_LINE_HEIGHT (f) * arg_scroll_conservatively);
14630 else if (scroll_step || temp_scroll_step)
14631 amount_to_scroll = scroll_max;
14632 else
14634 aggressive = BVAR (current_buffer, scroll_up_aggressively);
14635 height = WINDOW_BOX_TEXT_HEIGHT (w);
14636 if (NUMBERP (aggressive))
14638 double float_amount = XFLOATINT (aggressive) * height;
14639 int aggressive_scroll = float_amount;
14640 if (aggressive_scroll == 0 && float_amount > 0)
14641 aggressive_scroll = 1;
14642 /* Don't let point enter the scroll margin near top of
14643 the window. This could happen if the value of
14644 scroll_up_aggressively is too large and there are
14645 non-zero margins, because scroll_up_aggressively
14646 means put point that fraction of window height
14647 _from_the_bottom_margin_. */
14648 if (aggressive_scroll + 2*this_scroll_margin > height)
14649 aggressive_scroll = height - 2*this_scroll_margin;
14650 amount_to_scroll = dy + aggressive_scroll;
14654 if (amount_to_scroll <= 0)
14655 return SCROLLING_FAILED;
14657 start_display (&it, w, startp);
14658 if (arg_scroll_conservatively <= scroll_limit)
14659 move_it_vertically (&it, amount_to_scroll);
14660 else
14662 /* Extra precision for users who set scroll-conservatively
14663 to a large number: make sure the amount we scroll
14664 the window start is never less than amount_to_scroll,
14665 which was computed as distance from window bottom to
14666 point. This matters when lines at window top and lines
14667 below window bottom have different height. */
14668 struct it it1;
14669 void *it1data = NULL;
14670 /* We use a temporary it1 because line_bottom_y can modify
14671 its argument, if it moves one line down; see there. */
14672 int start_y;
14674 SAVE_IT (it1, it, it1data);
14675 start_y = line_bottom_y (&it1);
14676 do {
14677 RESTORE_IT (&it, &it, it1data);
14678 move_it_by_lines (&it, 1);
14679 SAVE_IT (it1, it, it1data);
14680 } while (line_bottom_y (&it1) - start_y < amount_to_scroll);
14683 /* If STARTP is unchanged, move it down another screen line. */
14684 if (CHARPOS (it.current.pos) == CHARPOS (startp))
14685 move_it_by_lines (&it, 1);
14686 startp = it.current.pos;
14688 else
14690 struct text_pos scroll_margin_pos = startp;
14691 int y_offset = 0;
14693 /* See if point is inside the scroll margin at the top of the
14694 window. */
14695 if (this_scroll_margin)
14697 int y_start;
14699 start_display (&it, w, startp);
14700 y_start = it.current_y;
14701 move_it_vertically (&it, this_scroll_margin);
14702 scroll_margin_pos = it.current.pos;
14703 /* If we didn't move enough before hitting ZV, request
14704 additional amount of scroll, to move point out of the
14705 scroll margin. */
14706 if (IT_CHARPOS (it) == ZV
14707 && it.current_y - y_start < this_scroll_margin)
14708 y_offset = this_scroll_margin - (it.current_y - y_start);
14711 if (PT < CHARPOS (scroll_margin_pos))
14713 /* Point is in the scroll margin at the top of the window or
14714 above what is displayed in the window. */
14715 int y0, y_to_move;
14717 /* Compute the vertical distance from PT to the scroll
14718 margin position. Move as far as scroll_max allows, or
14719 one screenful, or 10 screen lines, whichever is largest.
14720 Give up if distance is greater than scroll_max or if we
14721 didn't reach the scroll margin position. */
14722 SET_TEXT_POS (pos, PT, PT_BYTE);
14723 start_display (&it, w, pos);
14724 y0 = it.current_y;
14725 y_to_move = max (it.last_visible_y,
14726 max (scroll_max, 10 * FRAME_LINE_HEIGHT (f)));
14727 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
14728 y_to_move, -1,
14729 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
14730 dy = it.current_y - y0;
14731 if (dy > scroll_max
14732 || IT_CHARPOS (it) < CHARPOS (scroll_margin_pos))
14733 return SCROLLING_FAILED;
14735 /* Additional scroll for when ZV was too close to point. */
14736 dy += y_offset;
14738 /* Compute new window start. */
14739 start_display (&it, w, startp);
14741 if (arg_scroll_conservatively)
14742 amount_to_scroll = max (dy, FRAME_LINE_HEIGHT (f) *
14743 max (scroll_step, temp_scroll_step));
14744 else if (scroll_step || temp_scroll_step)
14745 amount_to_scroll = scroll_max;
14746 else
14748 aggressive = BVAR (current_buffer, scroll_down_aggressively);
14749 height = WINDOW_BOX_TEXT_HEIGHT (w);
14750 if (NUMBERP (aggressive))
14752 double float_amount = XFLOATINT (aggressive) * height;
14753 int aggressive_scroll = float_amount;
14754 if (aggressive_scroll == 0 && float_amount > 0)
14755 aggressive_scroll = 1;
14756 /* Don't let point enter the scroll margin near
14757 bottom of the window, if the value of
14758 scroll_down_aggressively happens to be too
14759 large. */
14760 if (aggressive_scroll + 2*this_scroll_margin > height)
14761 aggressive_scroll = height - 2*this_scroll_margin;
14762 amount_to_scroll = dy + aggressive_scroll;
14766 if (amount_to_scroll <= 0)
14767 return SCROLLING_FAILED;
14769 move_it_vertically_backward (&it, amount_to_scroll);
14770 startp = it.current.pos;
14774 /* Run window scroll functions. */
14775 startp = run_window_scroll_functions (window, startp);
14777 /* Display the window. Give up if new fonts are loaded, or if point
14778 doesn't appear. */
14779 if (!try_window (window, startp, 0))
14780 rc = SCROLLING_NEED_LARGER_MATRICES;
14781 else if (w->cursor.vpos < 0)
14783 clear_glyph_matrix (w->desired_matrix);
14784 rc = SCROLLING_FAILED;
14786 else
14788 /* Maybe forget recorded base line for line number display. */
14789 if (!just_this_one_p
14790 || current_buffer->clip_changed
14791 || BEG_UNCHANGED < CHARPOS (startp))
14792 w->base_line_number = 0;
14794 /* If cursor ends up on a partially visible line,
14795 treat that as being off the bottom of the screen. */
14796 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0)
14797 /* It's possible that the cursor is on the first line of the
14798 buffer, which is partially obscured due to a vscroll
14799 (Bug#7537). In that case, avoid looping forever . */
14800 && extra_scroll_margin_lines < w->desired_matrix->nrows - 1)
14802 clear_glyph_matrix (w->desired_matrix);
14803 ++extra_scroll_margin_lines;
14804 goto too_near_end;
14806 rc = SCROLLING_SUCCESS;
14809 return rc;
14813 /* Compute a suitable window start for window W if display of W starts
14814 on a continuation line. Value is non-zero if a new window start
14815 was computed.
14817 The new window start will be computed, based on W's width, starting
14818 from the start of the continued line. It is the start of the
14819 screen line with the minimum distance from the old start W->start. */
14821 static int
14822 compute_window_start_on_continuation_line (struct window *w)
14824 struct text_pos pos, start_pos;
14825 int window_start_changed_p = 0;
14827 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
14829 /* If window start is on a continuation line... Window start may be
14830 < BEGV in case there's invisible text at the start of the
14831 buffer (M-x rmail, for example). */
14832 if (CHARPOS (start_pos) > BEGV
14833 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
14835 struct it it;
14836 struct glyph_row *row;
14838 /* Handle the case that the window start is out of range. */
14839 if (CHARPOS (start_pos) < BEGV)
14840 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
14841 else if (CHARPOS (start_pos) > ZV)
14842 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
14844 /* Find the start of the continued line. This should be fast
14845 because find_newline is fast (newline cache). */
14846 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
14847 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
14848 row, DEFAULT_FACE_ID);
14849 reseat_at_previous_visible_line_start (&it);
14851 /* If the line start is "too far" away from the window start,
14852 say it takes too much time to compute a new window start. */
14853 if (CHARPOS (start_pos) - IT_CHARPOS (it)
14854 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
14856 int min_distance, distance;
14858 /* Move forward by display lines to find the new window
14859 start. If window width was enlarged, the new start can
14860 be expected to be > the old start. If window width was
14861 decreased, the new window start will be < the old start.
14862 So, we're looking for the display line start with the
14863 minimum distance from the old window start. */
14864 pos = it.current.pos;
14865 min_distance = INFINITY;
14866 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
14867 distance < min_distance)
14869 min_distance = distance;
14870 pos = it.current.pos;
14871 move_it_by_lines (&it, 1);
14874 /* Set the window start there. */
14875 SET_MARKER_FROM_TEXT_POS (w->start, pos);
14876 window_start_changed_p = 1;
14880 return window_start_changed_p;
14884 /* Try cursor movement in case text has not changed in window WINDOW,
14885 with window start STARTP. Value is
14887 CURSOR_MOVEMENT_SUCCESS if successful
14889 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
14891 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
14892 display. *SCROLL_STEP is set to 1, under certain circumstances, if
14893 we want to scroll as if scroll-step were set to 1. See the code.
14895 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
14896 which case we have to abort this redisplay, and adjust matrices
14897 first. */
14899 enum
14901 CURSOR_MOVEMENT_SUCCESS,
14902 CURSOR_MOVEMENT_CANNOT_BE_USED,
14903 CURSOR_MOVEMENT_MUST_SCROLL,
14904 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
14907 static int
14908 try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_step)
14910 struct window *w = XWINDOW (window);
14911 struct frame *f = XFRAME (w->frame);
14912 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
14914 #ifdef GLYPH_DEBUG
14915 if (inhibit_try_cursor_movement)
14916 return rc;
14917 #endif
14919 /* Previously, there was a check for Lisp integer in the
14920 if-statement below. Now, this field is converted to
14921 ptrdiff_t, thus zero means invalid position in a buffer. */
14922 eassert (w->last_point > 0);
14924 /* Handle case where text has not changed, only point, and it has
14925 not moved off the frame. */
14926 if (/* Point may be in this window. */
14927 PT >= CHARPOS (startp)
14928 /* Selective display hasn't changed. */
14929 && !current_buffer->clip_changed
14930 /* Function force-mode-line-update is used to force a thorough
14931 redisplay. It sets either windows_or_buffers_changed or
14932 update_mode_lines. So don't take a shortcut here for these
14933 cases. */
14934 && !update_mode_lines
14935 && !windows_or_buffers_changed
14936 && !cursor_type_changed
14937 /* Can't use this case if highlighting a region. When a
14938 region exists, cursor movement has to do more than just
14939 set the cursor. */
14940 && markpos_of_region () < 0
14941 && !w->region_showing
14942 && NILP (Vshow_trailing_whitespace)
14943 /* This code is not used for mini-buffer for the sake of the case
14944 of redisplaying to replace an echo area message; since in
14945 that case the mini-buffer contents per se are usually
14946 unchanged. This code is of no real use in the mini-buffer
14947 since the handling of this_line_start_pos, etc., in redisplay
14948 handles the same cases. */
14949 && !EQ (window, minibuf_window)
14950 /* When splitting windows or for new windows, it happens that
14951 redisplay is called with a nil window_end_vpos or one being
14952 larger than the window. This should really be fixed in
14953 window.c. I don't have this on my list, now, so we do
14954 approximately the same as the old redisplay code. --gerd. */
14955 && INTEGERP (w->window_end_vpos)
14956 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
14957 && (FRAME_WINDOW_P (f)
14958 || !overlay_arrow_in_current_buffer_p ()))
14960 int this_scroll_margin, top_scroll_margin;
14961 struct glyph_row *row = NULL;
14963 #ifdef GLYPH_DEBUG
14964 debug_method_add (w, "cursor movement");
14965 #endif
14967 /* Scroll if point within this distance from the top or bottom
14968 of the window. This is a pixel value. */
14969 if (scroll_margin > 0)
14971 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
14972 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
14974 else
14975 this_scroll_margin = 0;
14977 top_scroll_margin = this_scroll_margin;
14978 if (WINDOW_WANTS_HEADER_LINE_P (w))
14979 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
14981 /* Start with the row the cursor was displayed during the last
14982 not paused redisplay. Give up if that row is not valid. */
14983 if (w->last_cursor.vpos < 0
14984 || w->last_cursor.vpos >= w->current_matrix->nrows)
14985 rc = CURSOR_MOVEMENT_MUST_SCROLL;
14986 else
14988 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
14989 if (row->mode_line_p)
14990 ++row;
14991 if (!row->enabled_p)
14992 rc = CURSOR_MOVEMENT_MUST_SCROLL;
14995 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
14997 int scroll_p = 0, must_scroll = 0;
14998 int last_y = window_text_bottom_y (w) - this_scroll_margin;
15000 if (PT > w->last_point)
15002 /* Point has moved forward. */
15003 while (MATRIX_ROW_END_CHARPOS (row) < PT
15004 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
15006 eassert (row->enabled_p);
15007 ++row;
15010 /* If the end position of a row equals the start
15011 position of the next row, and PT is at that position,
15012 we would rather display cursor in the next line. */
15013 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15014 && MATRIX_ROW_END_CHARPOS (row) == PT
15015 && row < MATRIX_MODE_LINE_ROW (w->current_matrix)
15016 && MATRIX_ROW_START_CHARPOS (row+1) == PT
15017 && !cursor_row_p (row))
15018 ++row;
15020 /* If within the scroll margin, scroll. Note that
15021 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
15022 the next line would be drawn, and that
15023 this_scroll_margin can be zero. */
15024 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
15025 || PT > MATRIX_ROW_END_CHARPOS (row)
15026 /* Line is completely visible last line in window
15027 and PT is to be set in the next line. */
15028 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
15029 && PT == MATRIX_ROW_END_CHARPOS (row)
15030 && !row->ends_at_zv_p
15031 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
15032 scroll_p = 1;
15034 else if (PT < w->last_point)
15036 /* Cursor has to be moved backward. Note that PT >=
15037 CHARPOS (startp) because of the outer if-statement. */
15038 while (!row->mode_line_p
15039 && (MATRIX_ROW_START_CHARPOS (row) > PT
15040 || (MATRIX_ROW_START_CHARPOS (row) == PT
15041 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
15042 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
15043 row > w->current_matrix->rows
15044 && (row-1)->ends_in_newline_from_string_p))))
15045 && (row->y > top_scroll_margin
15046 || CHARPOS (startp) == BEGV))
15048 eassert (row->enabled_p);
15049 --row;
15052 /* Consider the following case: Window starts at BEGV,
15053 there is invisible, intangible text at BEGV, so that
15054 display starts at some point START > BEGV. It can
15055 happen that we are called with PT somewhere between
15056 BEGV and START. Try to handle that case. */
15057 if (row < w->current_matrix->rows
15058 || row->mode_line_p)
15060 row = w->current_matrix->rows;
15061 if (row->mode_line_p)
15062 ++row;
15065 /* Due to newlines in overlay strings, we may have to
15066 skip forward over overlay strings. */
15067 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15068 && MATRIX_ROW_END_CHARPOS (row) == PT
15069 && !cursor_row_p (row))
15070 ++row;
15072 /* If within the scroll margin, scroll. */
15073 if (row->y < top_scroll_margin
15074 && CHARPOS (startp) != BEGV)
15075 scroll_p = 1;
15077 else
15079 /* Cursor did not move. So don't scroll even if cursor line
15080 is partially visible, as it was so before. */
15081 rc = CURSOR_MOVEMENT_SUCCESS;
15084 if (PT < MATRIX_ROW_START_CHARPOS (row)
15085 || PT > MATRIX_ROW_END_CHARPOS (row))
15087 /* if PT is not in the glyph row, give up. */
15088 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15089 must_scroll = 1;
15091 else if (rc != CURSOR_MOVEMENT_SUCCESS
15092 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
15094 struct glyph_row *row1;
15096 /* If rows are bidi-reordered and point moved, back up
15097 until we find a row that does not belong to a
15098 continuation line. This is because we must consider
15099 all rows of a continued line as candidates for the
15100 new cursor positioning, since row start and end
15101 positions change non-linearly with vertical position
15102 in such rows. */
15103 /* FIXME: Revisit this when glyph ``spilling'' in
15104 continuation lines' rows is implemented for
15105 bidi-reordered rows. */
15106 for (row1 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
15107 MATRIX_ROW_CONTINUATION_LINE_P (row);
15108 --row)
15110 /* If we hit the beginning of the displayed portion
15111 without finding the first row of a continued
15112 line, give up. */
15113 if (row <= row1)
15115 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15116 break;
15118 eassert (row->enabled_p);
15121 if (must_scroll)
15123 else if (rc != CURSOR_MOVEMENT_SUCCESS
15124 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
15125 /* Make sure this isn't a header line by any chance, since
15126 then MATRIX_ROW_PARTIALLY_VISIBLE_P might yield non-zero. */
15127 && !row->mode_line_p
15128 && make_cursor_line_fully_visible_p)
15130 if (PT == MATRIX_ROW_END_CHARPOS (row)
15131 && !row->ends_at_zv_p
15132 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
15133 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15134 else if (row->height > window_box_height (w))
15136 /* If we end up in a partially visible line, let's
15137 make it fully visible, except when it's taller
15138 than the window, in which case we can't do much
15139 about it. */
15140 *scroll_step = 1;
15141 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15143 else
15145 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
15146 if (!cursor_row_fully_visible_p (w, 0, 1))
15147 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15148 else
15149 rc = CURSOR_MOVEMENT_SUCCESS;
15152 else if (scroll_p)
15153 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15154 else if (rc != CURSOR_MOVEMENT_SUCCESS
15155 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
15157 /* With bidi-reordered rows, there could be more than
15158 one candidate row whose start and end positions
15159 occlude point. We need to let set_cursor_from_row
15160 find the best candidate. */
15161 /* FIXME: Revisit this when glyph ``spilling'' in
15162 continuation lines' rows is implemented for
15163 bidi-reordered rows. */
15164 int rv = 0;
15168 int at_zv_p = 0, exact_match_p = 0;
15170 if (MATRIX_ROW_START_CHARPOS (row) <= PT
15171 && PT <= MATRIX_ROW_END_CHARPOS (row)
15172 && cursor_row_p (row))
15173 rv |= set_cursor_from_row (w, row, w->current_matrix,
15174 0, 0, 0, 0);
15175 /* As soon as we've found the exact match for point,
15176 or the first suitable row whose ends_at_zv_p flag
15177 is set, we are done. */
15178 at_zv_p =
15179 MATRIX_ROW (w->current_matrix, w->cursor.vpos)->ends_at_zv_p;
15180 if (rv && !at_zv_p
15181 && w->cursor.hpos >= 0
15182 && w->cursor.hpos < MATRIX_ROW_USED (w->current_matrix,
15183 w->cursor.vpos))
15185 struct glyph_row *candidate =
15186 MATRIX_ROW (w->current_matrix, w->cursor.vpos);
15187 struct glyph *g =
15188 candidate->glyphs[TEXT_AREA] + w->cursor.hpos;
15189 ptrdiff_t endpos = MATRIX_ROW_END_CHARPOS (candidate);
15191 exact_match_p =
15192 (BUFFERP (g->object) && g->charpos == PT)
15193 || (INTEGERP (g->object)
15194 && (g->charpos == PT
15195 || (g->charpos == 0 && endpos - 1 == PT)));
15197 if (rv && (at_zv_p || exact_match_p))
15199 rc = CURSOR_MOVEMENT_SUCCESS;
15200 break;
15202 if (MATRIX_ROW_BOTTOM_Y (row) == last_y)
15203 break;
15204 ++row;
15206 while (((MATRIX_ROW_CONTINUATION_LINE_P (row)
15207 || row->continued_p)
15208 && MATRIX_ROW_BOTTOM_Y (row) <= last_y)
15209 || (MATRIX_ROW_START_CHARPOS (row) == PT
15210 && MATRIX_ROW_BOTTOM_Y (row) < last_y));
15211 /* If we didn't find any candidate rows, or exited the
15212 loop before all the candidates were examined, signal
15213 to the caller that this method failed. */
15214 if (rc != CURSOR_MOVEMENT_SUCCESS
15215 && !(rv
15216 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
15217 && !row->continued_p))
15218 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15219 else if (rv)
15220 rc = CURSOR_MOVEMENT_SUCCESS;
15222 else
15226 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
15228 rc = CURSOR_MOVEMENT_SUCCESS;
15229 break;
15231 ++row;
15233 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15234 && MATRIX_ROW_START_CHARPOS (row) == PT
15235 && cursor_row_p (row));
15240 return rc;
15243 #if !defined USE_TOOLKIT_SCROLL_BARS || defined USE_GTK
15244 static
15245 #endif
15246 void
15247 set_vertical_scroll_bar (struct window *w)
15249 ptrdiff_t start, end, whole;
15251 /* Calculate the start and end positions for the current window.
15252 At some point, it would be nice to choose between scrollbars
15253 which reflect the whole buffer size, with special markers
15254 indicating narrowing, and scrollbars which reflect only the
15255 visible region.
15257 Note that mini-buffers sometimes aren't displaying any text. */
15258 if (!MINI_WINDOW_P (w)
15259 || (w == XWINDOW (minibuf_window)
15260 && NILP (echo_area_buffer[0])))
15262 struct buffer *buf = XBUFFER (w->contents);
15263 whole = BUF_ZV (buf) - BUF_BEGV (buf);
15264 start = marker_position (w->start) - BUF_BEGV (buf);
15265 /* I don't think this is guaranteed to be right. For the
15266 moment, we'll pretend it is. */
15267 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
15269 if (end < start)
15270 end = start;
15271 if (whole < (end - start))
15272 whole = end - start;
15274 else
15275 start = end = whole = 0;
15277 /* Indicate what this scroll bar ought to be displaying now. */
15278 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
15279 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
15280 (w, end - start, whole, start);
15284 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
15285 selected_window is redisplayed.
15287 We can return without actually redisplaying the window if
15288 fonts_changed_p. In that case, redisplay_internal will
15289 retry. */
15291 static void
15292 redisplay_window (Lisp_Object window, int just_this_one_p)
15294 struct window *w = XWINDOW (window);
15295 struct frame *f = XFRAME (w->frame);
15296 struct buffer *buffer = XBUFFER (w->contents);
15297 struct buffer *old = current_buffer;
15298 struct text_pos lpoint, opoint, startp;
15299 int update_mode_line;
15300 int tem;
15301 struct it it;
15302 /* Record it now because it's overwritten. */
15303 int current_matrix_up_to_date_p = 0;
15304 int used_current_matrix_p = 0;
15305 /* This is less strict than current_matrix_up_to_date_p.
15306 It indicates that the buffer contents and narrowing are unchanged. */
15307 int buffer_unchanged_p = 0;
15308 int temp_scroll_step = 0;
15309 ptrdiff_t count = SPECPDL_INDEX ();
15310 int rc;
15311 int centering_position = -1;
15312 int last_line_misfit = 0;
15313 ptrdiff_t beg_unchanged, end_unchanged;
15315 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15316 opoint = lpoint;
15318 #ifdef GLYPH_DEBUG
15319 *w->desired_matrix->method = 0;
15320 #endif
15322 /* Make sure that both W's markers are valid. */
15323 eassert (XMARKER (w->start)->buffer == buffer);
15324 eassert (XMARKER (w->pointm)->buffer == buffer);
15326 restart:
15327 reconsider_clip_changes (w, buffer);
15329 /* Has the mode line to be updated? */
15330 update_mode_line = (w->update_mode_line
15331 || update_mode_lines
15332 || buffer->clip_changed
15333 || buffer->prevent_redisplay_optimizations_p);
15335 if (MINI_WINDOW_P (w))
15337 if (w == XWINDOW (echo_area_window)
15338 && !NILP (echo_area_buffer[0]))
15340 if (update_mode_line)
15341 /* We may have to update a tty frame's menu bar or a
15342 tool-bar. Example `M-x C-h C-h C-g'. */
15343 goto finish_menu_bars;
15344 else
15345 /* We've already displayed the echo area glyphs in this window. */
15346 goto finish_scroll_bars;
15348 else if ((w != XWINDOW (minibuf_window)
15349 || minibuf_level == 0)
15350 /* When buffer is nonempty, redisplay window normally. */
15351 && BUF_Z (XBUFFER (w->contents)) == BUF_BEG (XBUFFER (w->contents))
15352 /* Quail displays non-mini buffers in minibuffer window.
15353 In that case, redisplay the window normally. */
15354 && !NILP (Fmemq (w->contents, Vminibuffer_list)))
15356 /* W is a mini-buffer window, but it's not active, so clear
15357 it. */
15358 int yb = window_text_bottom_y (w);
15359 struct glyph_row *row;
15360 int y;
15362 for (y = 0, row = w->desired_matrix->rows;
15363 y < yb;
15364 y += row->height, ++row)
15365 blank_row (w, row, y);
15366 goto finish_scroll_bars;
15369 clear_glyph_matrix (w->desired_matrix);
15372 /* Otherwise set up data on this window; select its buffer and point
15373 value. */
15374 /* Really select the buffer, for the sake of buffer-local
15375 variables. */
15376 set_buffer_internal_1 (XBUFFER (w->contents));
15378 current_matrix_up_to_date_p
15379 = (w->window_end_valid
15380 && !current_buffer->clip_changed
15381 && !current_buffer->prevent_redisplay_optimizations_p
15382 && !window_outdated (w));
15384 /* Run the window-bottom-change-functions
15385 if it is possible that the text on the screen has changed
15386 (either due to modification of the text, or any other reason). */
15387 if (!current_matrix_up_to_date_p
15388 && !NILP (Vwindow_text_change_functions))
15390 safe_run_hooks (Qwindow_text_change_functions);
15391 goto restart;
15394 beg_unchanged = BEG_UNCHANGED;
15395 end_unchanged = END_UNCHANGED;
15397 SET_TEXT_POS (opoint, PT, PT_BYTE);
15399 specbind (Qinhibit_point_motion_hooks, Qt);
15401 buffer_unchanged_p
15402 = (w->window_end_valid
15403 && !current_buffer->clip_changed
15404 && !window_outdated (w));
15406 /* When windows_or_buffers_changed is non-zero, we can't rely on
15407 the window end being valid, so set it to nil there. */
15408 if (windows_or_buffers_changed)
15410 /* If window starts on a continuation line, maybe adjust the
15411 window start in case the window's width changed. */
15412 if (XMARKER (w->start)->buffer == current_buffer)
15413 compute_window_start_on_continuation_line (w);
15415 w->window_end_valid = 0;
15418 /* Some sanity checks. */
15419 CHECK_WINDOW_END (w);
15420 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
15421 emacs_abort ();
15422 if (BYTEPOS (opoint) < CHARPOS (opoint))
15423 emacs_abort ();
15425 if (mode_line_update_needed (w))
15426 update_mode_line = 1;
15428 /* Point refers normally to the selected window. For any other
15429 window, set up appropriate value. */
15430 if (!EQ (window, selected_window))
15432 ptrdiff_t new_pt = marker_position (w->pointm);
15433 ptrdiff_t new_pt_byte = marker_byte_position (w->pointm);
15434 if (new_pt < BEGV)
15436 new_pt = BEGV;
15437 new_pt_byte = BEGV_BYTE;
15438 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
15440 else if (new_pt > (ZV - 1))
15442 new_pt = ZV;
15443 new_pt_byte = ZV_BYTE;
15444 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
15447 /* We don't use SET_PT so that the point-motion hooks don't run. */
15448 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
15451 /* If any of the character widths specified in the display table
15452 have changed, invalidate the width run cache. It's true that
15453 this may be a bit late to catch such changes, but the rest of
15454 redisplay goes (non-fatally) haywire when the display table is
15455 changed, so why should we worry about doing any better? */
15456 if (current_buffer->width_run_cache)
15458 struct Lisp_Char_Table *disptab = buffer_display_table ();
15460 if (! disptab_matches_widthtab
15461 (disptab, XVECTOR (BVAR (current_buffer, width_table))))
15463 invalidate_region_cache (current_buffer,
15464 current_buffer->width_run_cache,
15465 BEG, Z);
15466 recompute_width_table (current_buffer, disptab);
15470 /* If window-start is screwed up, choose a new one. */
15471 if (XMARKER (w->start)->buffer != current_buffer)
15472 goto recenter;
15474 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15476 /* If someone specified a new starting point but did not insist,
15477 check whether it can be used. */
15478 if (w->optional_new_start
15479 && CHARPOS (startp) >= BEGV
15480 && CHARPOS (startp) <= ZV)
15482 w->optional_new_start = 0;
15483 start_display (&it, w, startp);
15484 move_it_to (&it, PT, 0, it.last_visible_y, -1,
15485 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
15486 if (IT_CHARPOS (it) == PT)
15487 w->force_start = 1;
15488 /* IT may overshoot PT if text at PT is invisible. */
15489 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
15490 w->force_start = 1;
15493 force_start:
15495 /* Handle case where place to start displaying has been specified,
15496 unless the specified location is outside the accessible range. */
15497 if (w->force_start || w->frozen_window_start_p)
15499 /* We set this later on if we have to adjust point. */
15500 int new_vpos = -1;
15502 w->force_start = 0;
15503 w->vscroll = 0;
15504 w->window_end_valid = 0;
15506 /* Forget any recorded base line for line number display. */
15507 if (!buffer_unchanged_p)
15508 w->base_line_number = 0;
15510 /* Redisplay the mode line. Select the buffer properly for that.
15511 Also, run the hook window-scroll-functions
15512 because we have scrolled. */
15513 /* Note, we do this after clearing force_start because
15514 if there's an error, it is better to forget about force_start
15515 than to get into an infinite loop calling the hook functions
15516 and having them get more errors. */
15517 if (!update_mode_line
15518 || ! NILP (Vwindow_scroll_functions))
15520 update_mode_line = 1;
15521 w->update_mode_line = 1;
15522 startp = run_window_scroll_functions (window, startp);
15525 w->last_modified = 0;
15526 w->last_overlay_modified = 0;
15527 if (CHARPOS (startp) < BEGV)
15528 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
15529 else if (CHARPOS (startp) > ZV)
15530 SET_TEXT_POS (startp, ZV, ZV_BYTE);
15532 /* Redisplay, then check if cursor has been set during the
15533 redisplay. Give up if new fonts were loaded. */
15534 /* We used to issue a CHECK_MARGINS argument to try_window here,
15535 but this causes scrolling to fail when point begins inside
15536 the scroll margin (bug#148) -- cyd */
15537 if (!try_window (window, startp, 0))
15539 w->force_start = 1;
15540 clear_glyph_matrix (w->desired_matrix);
15541 goto need_larger_matrices;
15544 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
15546 /* If point does not appear, try to move point so it does
15547 appear. The desired matrix has been built above, so we
15548 can use it here. */
15549 new_vpos = window_box_height (w) / 2;
15552 if (!cursor_row_fully_visible_p (w, 0, 0))
15554 /* Point does appear, but on a line partly visible at end of window.
15555 Move it back to a fully-visible line. */
15556 new_vpos = window_box_height (w);
15558 else if (w->cursor.vpos >=0)
15560 /* Some people insist on not letting point enter the scroll
15561 margin, even though this part handles windows that didn't
15562 scroll at all. */
15563 int margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
15564 int pixel_margin = margin * FRAME_LINE_HEIGHT (f);
15565 bool header_line = WINDOW_WANTS_HEADER_LINE_P (w);
15567 /* Note: We add an extra FRAME_LINE_HEIGHT, because the loop
15568 below, which finds the row to move point to, advances by
15569 the Y coordinate of the _next_ row, see the definition of
15570 MATRIX_ROW_BOTTOM_Y. */
15571 if (w->cursor.vpos < margin + header_line)
15572 new_vpos
15573 = pixel_margin + (header_line
15574 ? CURRENT_HEADER_LINE_HEIGHT (w)
15575 : 0) + FRAME_LINE_HEIGHT (f);
15576 else
15578 int window_height = window_box_height (w);
15580 if (header_line)
15581 window_height += CURRENT_HEADER_LINE_HEIGHT (w);
15582 if (w->cursor.y >= window_height - pixel_margin)
15583 new_vpos = window_height - pixel_margin;
15587 /* If we need to move point for either of the above reasons,
15588 now actually do it. */
15589 if (new_vpos >= 0)
15591 struct glyph_row *row;
15593 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
15594 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
15595 ++row;
15597 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
15598 MATRIX_ROW_START_BYTEPOS (row));
15600 if (w != XWINDOW (selected_window))
15601 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
15602 else if (current_buffer == old)
15603 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15605 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
15607 /* If we are highlighting the region, then we just changed
15608 the region, so redisplay to show it. */
15609 if (markpos_of_region () >= 0)
15611 clear_glyph_matrix (w->desired_matrix);
15612 if (!try_window (window, startp, 0))
15613 goto need_larger_matrices;
15617 #ifdef GLYPH_DEBUG
15618 debug_method_add (w, "forced window start");
15619 #endif
15620 goto done;
15623 /* Handle case where text has not changed, only point, and it has
15624 not moved off the frame, and we are not retrying after hscroll.
15625 (current_matrix_up_to_date_p is nonzero when retrying.) */
15626 if (current_matrix_up_to_date_p
15627 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
15628 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
15630 switch (rc)
15632 case CURSOR_MOVEMENT_SUCCESS:
15633 used_current_matrix_p = 1;
15634 goto done;
15636 case CURSOR_MOVEMENT_MUST_SCROLL:
15637 goto try_to_scroll;
15639 default:
15640 emacs_abort ();
15643 /* If current starting point was originally the beginning of a line
15644 but no longer is, find a new starting point. */
15645 else if (w->start_at_line_beg
15646 && !(CHARPOS (startp) <= BEGV
15647 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
15649 #ifdef GLYPH_DEBUG
15650 debug_method_add (w, "recenter 1");
15651 #endif
15652 goto recenter;
15655 /* Try scrolling with try_window_id. Value is > 0 if update has
15656 been done, it is -1 if we know that the same window start will
15657 not work. It is 0 if unsuccessful for some other reason. */
15658 else if ((tem = try_window_id (w)) != 0)
15660 #ifdef GLYPH_DEBUG
15661 debug_method_add (w, "try_window_id %d", tem);
15662 #endif
15664 if (fonts_changed_p)
15665 goto need_larger_matrices;
15666 if (tem > 0)
15667 goto done;
15669 /* Otherwise try_window_id has returned -1 which means that we
15670 don't want the alternative below this comment to execute. */
15672 else if (CHARPOS (startp) >= BEGV
15673 && CHARPOS (startp) <= ZV
15674 && PT >= CHARPOS (startp)
15675 && (CHARPOS (startp) < ZV
15676 /* Avoid starting at end of buffer. */
15677 || CHARPOS (startp) == BEGV
15678 || !window_outdated (w)))
15680 int d1, d2, d3, d4, d5, d6;
15682 /* If first window line is a continuation line, and window start
15683 is inside the modified region, but the first change is before
15684 current window start, we must select a new window start.
15686 However, if this is the result of a down-mouse event (e.g. by
15687 extending the mouse-drag-overlay), we don't want to select a
15688 new window start, since that would change the position under
15689 the mouse, resulting in an unwanted mouse-movement rather
15690 than a simple mouse-click. */
15691 if (!w->start_at_line_beg
15692 && NILP (do_mouse_tracking)
15693 && CHARPOS (startp) > BEGV
15694 && CHARPOS (startp) > BEG + beg_unchanged
15695 && CHARPOS (startp) <= Z - end_unchanged
15696 /* Even if w->start_at_line_beg is nil, a new window may
15697 start at a line_beg, since that's how set_buffer_window
15698 sets it. So, we need to check the return value of
15699 compute_window_start_on_continuation_line. (See also
15700 bug#197). */
15701 && XMARKER (w->start)->buffer == current_buffer
15702 && compute_window_start_on_continuation_line (w)
15703 /* It doesn't make sense to force the window start like we
15704 do at label force_start if it is already known that point
15705 will not be visible in the resulting window, because
15706 doing so will move point from its correct position
15707 instead of scrolling the window to bring point into view.
15708 See bug#9324. */
15709 && pos_visible_p (w, PT, &d1, &d2, &d3, &d4, &d5, &d6))
15711 w->force_start = 1;
15712 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15713 goto force_start;
15716 #ifdef GLYPH_DEBUG
15717 debug_method_add (w, "same window start");
15718 #endif
15720 /* Try to redisplay starting at same place as before.
15721 If point has not moved off frame, accept the results. */
15722 if (!current_matrix_up_to_date_p
15723 /* Don't use try_window_reusing_current_matrix in this case
15724 because a window scroll function can have changed the
15725 buffer. */
15726 || !NILP (Vwindow_scroll_functions)
15727 || MINI_WINDOW_P (w)
15728 || !(used_current_matrix_p
15729 = try_window_reusing_current_matrix (w)))
15731 IF_DEBUG (debug_method_add (w, "1"));
15732 if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
15733 /* -1 means we need to scroll.
15734 0 means we need new matrices, but fonts_changed_p
15735 is set in that case, so we will detect it below. */
15736 goto try_to_scroll;
15739 if (fonts_changed_p)
15740 goto need_larger_matrices;
15742 if (w->cursor.vpos >= 0)
15744 if (!just_this_one_p
15745 || current_buffer->clip_changed
15746 || BEG_UNCHANGED < CHARPOS (startp))
15747 /* Forget any recorded base line for line number display. */
15748 w->base_line_number = 0;
15750 if (!cursor_row_fully_visible_p (w, 1, 0))
15752 clear_glyph_matrix (w->desired_matrix);
15753 last_line_misfit = 1;
15755 /* Drop through and scroll. */
15756 else
15757 goto done;
15759 else
15760 clear_glyph_matrix (w->desired_matrix);
15763 try_to_scroll:
15765 w->last_modified = 0;
15766 w->last_overlay_modified = 0;
15768 /* Redisplay the mode line. Select the buffer properly for that. */
15769 if (!update_mode_line)
15771 update_mode_line = 1;
15772 w->update_mode_line = 1;
15775 /* Try to scroll by specified few lines. */
15776 if ((scroll_conservatively
15777 || emacs_scroll_step
15778 || temp_scroll_step
15779 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively))
15780 || NUMBERP (BVAR (current_buffer, scroll_down_aggressively)))
15781 && CHARPOS (startp) >= BEGV
15782 && CHARPOS (startp) <= ZV)
15784 /* The function returns -1 if new fonts were loaded, 1 if
15785 successful, 0 if not successful. */
15786 int ss = try_scrolling (window, just_this_one_p,
15787 scroll_conservatively,
15788 emacs_scroll_step,
15789 temp_scroll_step, last_line_misfit);
15790 switch (ss)
15792 case SCROLLING_SUCCESS:
15793 goto done;
15795 case SCROLLING_NEED_LARGER_MATRICES:
15796 goto need_larger_matrices;
15798 case SCROLLING_FAILED:
15799 break;
15801 default:
15802 emacs_abort ();
15806 /* Finally, just choose a place to start which positions point
15807 according to user preferences. */
15809 recenter:
15811 #ifdef GLYPH_DEBUG
15812 debug_method_add (w, "recenter");
15813 #endif
15815 /* Forget any previously recorded base line for line number display. */
15816 if (!buffer_unchanged_p)
15817 w->base_line_number = 0;
15819 /* Determine the window start relative to point. */
15820 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
15821 it.current_y = it.last_visible_y;
15822 if (centering_position < 0)
15824 int margin =
15825 scroll_margin > 0
15826 ? min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
15827 : 0;
15828 ptrdiff_t margin_pos = CHARPOS (startp);
15829 Lisp_Object aggressive;
15830 int scrolling_up;
15832 /* If there is a scroll margin at the top of the window, find
15833 its character position. */
15834 if (margin
15835 /* Cannot call start_display if startp is not in the
15836 accessible region of the buffer. This can happen when we
15837 have just switched to a different buffer and/or changed
15838 its restriction. In that case, startp is initialized to
15839 the character position 1 (BEGV) because we did not yet
15840 have chance to display the buffer even once. */
15841 && BEGV <= CHARPOS (startp) && CHARPOS (startp) <= ZV)
15843 struct it it1;
15844 void *it1data = NULL;
15846 SAVE_IT (it1, it, it1data);
15847 start_display (&it1, w, startp);
15848 move_it_vertically (&it1, margin * FRAME_LINE_HEIGHT (f));
15849 margin_pos = IT_CHARPOS (it1);
15850 RESTORE_IT (&it, &it, it1data);
15852 scrolling_up = PT > margin_pos;
15853 aggressive =
15854 scrolling_up
15855 ? BVAR (current_buffer, scroll_up_aggressively)
15856 : BVAR (current_buffer, scroll_down_aggressively);
15858 if (!MINI_WINDOW_P (w)
15859 && (scroll_conservatively > SCROLL_LIMIT || NUMBERP (aggressive)))
15861 int pt_offset = 0;
15863 /* Setting scroll-conservatively overrides
15864 scroll-*-aggressively. */
15865 if (!scroll_conservatively && NUMBERP (aggressive))
15867 double float_amount = XFLOATINT (aggressive);
15869 pt_offset = float_amount * WINDOW_BOX_TEXT_HEIGHT (w);
15870 if (pt_offset == 0 && float_amount > 0)
15871 pt_offset = 1;
15872 if (pt_offset && margin > 0)
15873 margin -= 1;
15875 /* Compute how much to move the window start backward from
15876 point so that point will be displayed where the user
15877 wants it. */
15878 if (scrolling_up)
15880 centering_position = it.last_visible_y;
15881 if (pt_offset)
15882 centering_position -= pt_offset;
15883 centering_position -=
15884 FRAME_LINE_HEIGHT (f) * (1 + margin + (last_line_misfit != 0))
15885 + WINDOW_HEADER_LINE_HEIGHT (w);
15886 /* Don't let point enter the scroll margin near top of
15887 the window. */
15888 if (centering_position < margin * FRAME_LINE_HEIGHT (f))
15889 centering_position = margin * FRAME_LINE_HEIGHT (f);
15891 else
15892 centering_position = margin * FRAME_LINE_HEIGHT (f) + pt_offset;
15894 else
15895 /* Set the window start half the height of the window backward
15896 from point. */
15897 centering_position = window_box_height (w) / 2;
15899 move_it_vertically_backward (&it, centering_position);
15901 eassert (IT_CHARPOS (it) >= BEGV);
15903 /* The function move_it_vertically_backward may move over more
15904 than the specified y-distance. If it->w is small, e.g. a
15905 mini-buffer window, we may end up in front of the window's
15906 display area. Start displaying at the start of the line
15907 containing PT in this case. */
15908 if (it.current_y <= 0)
15910 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
15911 move_it_vertically_backward (&it, 0);
15912 it.current_y = 0;
15915 it.current_x = it.hpos = 0;
15917 /* Set the window start position here explicitly, to avoid an
15918 infinite loop in case the functions in window-scroll-functions
15919 get errors. */
15920 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
15922 /* Run scroll hooks. */
15923 startp = run_window_scroll_functions (window, it.current.pos);
15925 /* Redisplay the window. */
15926 if (!current_matrix_up_to_date_p
15927 || windows_or_buffers_changed
15928 || cursor_type_changed
15929 /* Don't use try_window_reusing_current_matrix in this case
15930 because it can have changed the buffer. */
15931 || !NILP (Vwindow_scroll_functions)
15932 || !just_this_one_p
15933 || MINI_WINDOW_P (w)
15934 || !(used_current_matrix_p
15935 = try_window_reusing_current_matrix (w)))
15936 try_window (window, startp, 0);
15938 /* If new fonts have been loaded (due to fontsets), give up. We
15939 have to start a new redisplay since we need to re-adjust glyph
15940 matrices. */
15941 if (fonts_changed_p)
15942 goto need_larger_matrices;
15944 /* If cursor did not appear assume that the middle of the window is
15945 in the first line of the window. Do it again with the next line.
15946 (Imagine a window of height 100, displaying two lines of height
15947 60. Moving back 50 from it->last_visible_y will end in the first
15948 line.) */
15949 if (w->cursor.vpos < 0)
15951 if (w->window_end_valid && PT >= Z - XFASTINT (w->window_end_pos))
15953 clear_glyph_matrix (w->desired_matrix);
15954 move_it_by_lines (&it, 1);
15955 try_window (window, it.current.pos, 0);
15957 else if (PT < IT_CHARPOS (it))
15959 clear_glyph_matrix (w->desired_matrix);
15960 move_it_by_lines (&it, -1);
15961 try_window (window, it.current.pos, 0);
15963 else
15965 /* Not much we can do about it. */
15969 /* Consider the following case: Window starts at BEGV, there is
15970 invisible, intangible text at BEGV, so that display starts at
15971 some point START > BEGV. It can happen that we are called with
15972 PT somewhere between BEGV and START. Try to handle that case. */
15973 if (w->cursor.vpos < 0)
15975 struct glyph_row *row = w->current_matrix->rows;
15976 if (row->mode_line_p)
15977 ++row;
15978 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
15981 if (!cursor_row_fully_visible_p (w, 0, 0))
15983 /* If vscroll is enabled, disable it and try again. */
15984 if (w->vscroll)
15986 w->vscroll = 0;
15987 clear_glyph_matrix (w->desired_matrix);
15988 goto recenter;
15991 /* Users who set scroll-conservatively to a large number want
15992 point just above/below the scroll margin. If we ended up
15993 with point's row partially visible, move the window start to
15994 make that row fully visible and out of the margin. */
15995 if (scroll_conservatively > SCROLL_LIMIT)
15997 int margin =
15998 scroll_margin > 0
15999 ? min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
16000 : 0;
16001 int move_down = w->cursor.vpos >= WINDOW_TOTAL_LINES (w) / 2;
16003 move_it_by_lines (&it, move_down ? margin + 1 : -(margin + 1));
16004 clear_glyph_matrix (w->desired_matrix);
16005 if (1 == try_window (window, it.current.pos,
16006 TRY_WINDOW_CHECK_MARGINS))
16007 goto done;
16010 /* If centering point failed to make the whole line visible,
16011 put point at the top instead. That has to make the whole line
16012 visible, if it can be done. */
16013 if (centering_position == 0)
16014 goto done;
16016 clear_glyph_matrix (w->desired_matrix);
16017 centering_position = 0;
16018 goto recenter;
16021 done:
16023 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16024 w->start_at_line_beg = (CHARPOS (startp) == BEGV
16025 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n');
16027 /* Display the mode line, if we must. */
16028 if ((update_mode_line
16029 /* If window not full width, must redo its mode line
16030 if (a) the window to its side is being redone and
16031 (b) we do a frame-based redisplay. This is a consequence
16032 of how inverted lines are drawn in frame-based redisplay. */
16033 || (!just_this_one_p
16034 && !FRAME_WINDOW_P (f)
16035 && !WINDOW_FULL_WIDTH_P (w))
16036 /* Line number to display. */
16037 || w->base_line_pos > 0
16038 /* Column number is displayed and different from the one displayed. */
16039 || (w->column_number_displayed != -1
16040 && (w->column_number_displayed != current_column ())))
16041 /* This means that the window has a mode line. */
16042 && (WINDOW_WANTS_MODELINE_P (w)
16043 || WINDOW_WANTS_HEADER_LINE_P (w)))
16045 display_mode_lines (w);
16047 /* If mode line height has changed, arrange for a thorough
16048 immediate redisplay using the correct mode line height. */
16049 if (WINDOW_WANTS_MODELINE_P (w)
16050 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
16052 fonts_changed_p = 1;
16053 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
16054 = DESIRED_MODE_LINE_HEIGHT (w);
16057 /* If header line height has changed, arrange for a thorough
16058 immediate redisplay using the correct header line height. */
16059 if (WINDOW_WANTS_HEADER_LINE_P (w)
16060 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
16062 fonts_changed_p = 1;
16063 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
16064 = DESIRED_HEADER_LINE_HEIGHT (w);
16067 if (fonts_changed_p)
16068 goto need_larger_matrices;
16071 if (!line_number_displayed && w->base_line_pos != -1)
16073 w->base_line_pos = 0;
16074 w->base_line_number = 0;
16077 finish_menu_bars:
16079 /* When we reach a frame's selected window, redo the frame's menu bar. */
16080 if (update_mode_line
16081 && EQ (FRAME_SELECTED_WINDOW (f), window))
16083 int redisplay_menu_p = 0;
16085 if (FRAME_WINDOW_P (f))
16087 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
16088 || defined (HAVE_NS) || defined (USE_GTK)
16089 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
16090 #else
16091 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
16092 #endif
16094 else
16095 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
16097 if (redisplay_menu_p)
16098 display_menu_bar (w);
16100 #ifdef HAVE_WINDOW_SYSTEM
16101 if (FRAME_WINDOW_P (f))
16103 #if defined (USE_GTK) || defined (HAVE_NS)
16104 if (FRAME_EXTERNAL_TOOL_BAR (f))
16105 redisplay_tool_bar (f);
16106 #else
16107 if (WINDOWP (f->tool_bar_window)
16108 && (FRAME_TOOL_BAR_LINES (f) > 0
16109 || !NILP (Vauto_resize_tool_bars))
16110 && redisplay_tool_bar (f))
16111 ignore_mouse_drag_p = 1;
16112 #endif
16114 #endif
16117 #ifdef HAVE_WINDOW_SYSTEM
16118 if (FRAME_WINDOW_P (f)
16119 && update_window_fringes (w, (just_this_one_p
16120 || (!used_current_matrix_p && !overlay_arrow_seen)
16121 || w->pseudo_window_p)))
16123 update_begin (f);
16124 block_input ();
16125 if (draw_window_fringes (w, 1))
16126 x_draw_vertical_border (w);
16127 unblock_input ();
16128 update_end (f);
16130 #endif /* HAVE_WINDOW_SYSTEM */
16132 /* We go to this label, with fonts_changed_p set,
16133 if it is necessary to try again using larger glyph matrices.
16134 We have to redeem the scroll bar even in this case,
16135 because the loop in redisplay_internal expects that. */
16136 need_larger_matrices:
16138 finish_scroll_bars:
16140 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
16142 /* Set the thumb's position and size. */
16143 set_vertical_scroll_bar (w);
16145 /* Note that we actually used the scroll bar attached to this
16146 window, so it shouldn't be deleted at the end of redisplay. */
16147 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
16148 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
16151 /* Restore current_buffer and value of point in it. The window
16152 update may have changed the buffer, so first make sure `opoint'
16153 is still valid (Bug#6177). */
16154 if (CHARPOS (opoint) < BEGV)
16155 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
16156 else if (CHARPOS (opoint) > ZV)
16157 TEMP_SET_PT_BOTH (Z, Z_BYTE);
16158 else
16159 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
16161 set_buffer_internal_1 (old);
16162 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
16163 shorter. This can be caused by log truncation in *Messages*. */
16164 if (CHARPOS (lpoint) <= ZV)
16165 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
16167 unbind_to (count, Qnil);
16171 /* Build the complete desired matrix of WINDOW with a window start
16172 buffer position POS.
16174 Value is 1 if successful. It is zero if fonts were loaded during
16175 redisplay which makes re-adjusting glyph matrices necessary, and -1
16176 if point would appear in the scroll margins.
16177 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
16178 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
16179 set in FLAGS.) */
16182 try_window (Lisp_Object window, struct text_pos pos, int flags)
16184 struct window *w = XWINDOW (window);
16185 struct it it;
16186 struct glyph_row *last_text_row = NULL;
16187 struct frame *f = XFRAME (w->frame);
16189 /* Make POS the new window start. */
16190 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
16192 /* Mark cursor position as unknown. No overlay arrow seen. */
16193 w->cursor.vpos = -1;
16194 overlay_arrow_seen = 0;
16196 /* Initialize iterator and info to start at POS. */
16197 start_display (&it, w, pos);
16199 /* Display all lines of W. */
16200 while (it.current_y < it.last_visible_y)
16202 if (display_line (&it))
16203 last_text_row = it.glyph_row - 1;
16204 if (fonts_changed_p && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
16205 return 0;
16208 /* Don't let the cursor end in the scroll margins. */
16209 if ((flags & TRY_WINDOW_CHECK_MARGINS)
16210 && !MINI_WINDOW_P (w))
16212 int this_scroll_margin;
16214 if (scroll_margin > 0)
16216 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
16217 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
16219 else
16220 this_scroll_margin = 0;
16222 if ((w->cursor.y >= 0 /* not vscrolled */
16223 && w->cursor.y < this_scroll_margin
16224 && CHARPOS (pos) > BEGV
16225 && IT_CHARPOS (it) < ZV)
16226 /* rms: considering make_cursor_line_fully_visible_p here
16227 seems to give wrong results. We don't want to recenter
16228 when the last line is partly visible, we want to allow
16229 that case to be handled in the usual way. */
16230 || w->cursor.y > it.last_visible_y - this_scroll_margin - 1)
16232 w->cursor.vpos = -1;
16233 clear_glyph_matrix (w->desired_matrix);
16234 return -1;
16238 /* If bottom moved off end of frame, change mode line percentage. */
16239 if (XFASTINT (w->window_end_pos) <= 0
16240 && Z != IT_CHARPOS (it))
16241 w->update_mode_line = 1;
16243 /* Set window_end_pos to the offset of the last character displayed
16244 on the window from the end of current_buffer. Set
16245 window_end_vpos to its row number. */
16246 if (last_text_row)
16248 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
16249 w->window_end_bytepos
16250 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16251 wset_window_end_pos
16252 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
16253 wset_window_end_vpos
16254 (w, make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix)));
16255 eassert
16256 (MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->desired_matrix,
16257 XFASTINT (w->window_end_vpos))));
16259 else
16261 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
16262 wset_window_end_pos (w, make_number (Z - ZV));
16263 wset_window_end_vpos (w, make_number (0));
16266 /* But that is not valid info until redisplay finishes. */
16267 w->window_end_valid = 0;
16268 return 1;
16273 /************************************************************************
16274 Window redisplay reusing current matrix when buffer has not changed
16275 ************************************************************************/
16277 /* Try redisplay of window W showing an unchanged buffer with a
16278 different window start than the last time it was displayed by
16279 reusing its current matrix. Value is non-zero if successful.
16280 W->start is the new window start. */
16282 static int
16283 try_window_reusing_current_matrix (struct window *w)
16285 struct frame *f = XFRAME (w->frame);
16286 struct glyph_row *bottom_row;
16287 struct it it;
16288 struct run run;
16289 struct text_pos start, new_start;
16290 int nrows_scrolled, i;
16291 struct glyph_row *last_text_row;
16292 struct glyph_row *last_reused_text_row;
16293 struct glyph_row *start_row;
16294 int start_vpos, min_y, max_y;
16296 #ifdef GLYPH_DEBUG
16297 if (inhibit_try_window_reusing)
16298 return 0;
16299 #endif
16301 if (/* This function doesn't handle terminal frames. */
16302 !FRAME_WINDOW_P (f)
16303 /* Don't try to reuse the display if windows have been split
16304 or such. */
16305 || windows_or_buffers_changed
16306 || cursor_type_changed)
16307 return 0;
16309 /* Can't do this if region may have changed. */
16310 if (markpos_of_region () >= 0
16311 || w->region_showing
16312 || !NILP (Vshow_trailing_whitespace))
16313 return 0;
16315 /* If top-line visibility has changed, give up. */
16316 if (WINDOW_WANTS_HEADER_LINE_P (w)
16317 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
16318 return 0;
16320 /* Give up if old or new display is scrolled vertically. We could
16321 make this function handle this, but right now it doesn't. */
16322 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16323 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
16324 return 0;
16326 /* The variable new_start now holds the new window start. The old
16327 start `start' can be determined from the current matrix. */
16328 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
16329 start = start_row->minpos;
16330 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
16332 /* Clear the desired matrix for the display below. */
16333 clear_glyph_matrix (w->desired_matrix);
16335 if (CHARPOS (new_start) <= CHARPOS (start))
16337 /* Don't use this method if the display starts with an ellipsis
16338 displayed for invisible text. It's not easy to handle that case
16339 below, and it's certainly not worth the effort since this is
16340 not a frequent case. */
16341 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
16342 return 0;
16344 IF_DEBUG (debug_method_add (w, "twu1"));
16346 /* Display up to a row that can be reused. The variable
16347 last_text_row is set to the last row displayed that displays
16348 text. Note that it.vpos == 0 if or if not there is a
16349 header-line; it's not the same as the MATRIX_ROW_VPOS! */
16350 start_display (&it, w, new_start);
16351 w->cursor.vpos = -1;
16352 last_text_row = last_reused_text_row = NULL;
16354 while (it.current_y < it.last_visible_y
16355 && !fonts_changed_p)
16357 /* If we have reached into the characters in the START row,
16358 that means the line boundaries have changed. So we
16359 can't start copying with the row START. Maybe it will
16360 work to start copying with the following row. */
16361 while (IT_CHARPOS (it) > CHARPOS (start))
16363 /* Advance to the next row as the "start". */
16364 start_row++;
16365 start = start_row->minpos;
16366 /* If there are no more rows to try, or just one, give up. */
16367 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
16368 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
16369 || CHARPOS (start) == ZV)
16371 clear_glyph_matrix (w->desired_matrix);
16372 return 0;
16375 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
16377 /* If we have reached alignment, we can copy the rest of the
16378 rows. */
16379 if (IT_CHARPOS (it) == CHARPOS (start)
16380 /* Don't accept "alignment" inside a display vector,
16381 since start_row could have started in the middle of
16382 that same display vector (thus their character
16383 positions match), and we have no way of telling if
16384 that is the case. */
16385 && it.current.dpvec_index < 0)
16386 break;
16388 if (display_line (&it))
16389 last_text_row = it.glyph_row - 1;
16393 /* A value of current_y < last_visible_y means that we stopped
16394 at the previous window start, which in turn means that we
16395 have at least one reusable row. */
16396 if (it.current_y < it.last_visible_y)
16398 struct glyph_row *row;
16400 /* IT.vpos always starts from 0; it counts text lines. */
16401 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
16403 /* Find PT if not already found in the lines displayed. */
16404 if (w->cursor.vpos < 0)
16406 int dy = it.current_y - start_row->y;
16408 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16409 row = row_containing_pos (w, PT, row, NULL, dy);
16410 if (row)
16411 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
16412 dy, nrows_scrolled);
16413 else
16415 clear_glyph_matrix (w->desired_matrix);
16416 return 0;
16420 /* Scroll the display. Do it before the current matrix is
16421 changed. The problem here is that update has not yet
16422 run, i.e. part of the current matrix is not up to date.
16423 scroll_run_hook will clear the cursor, and use the
16424 current matrix to get the height of the row the cursor is
16425 in. */
16426 run.current_y = start_row->y;
16427 run.desired_y = it.current_y;
16428 run.height = it.last_visible_y - it.current_y;
16430 if (run.height > 0 && run.current_y != run.desired_y)
16432 update_begin (f);
16433 FRAME_RIF (f)->update_window_begin_hook (w);
16434 FRAME_RIF (f)->clear_window_mouse_face (w);
16435 FRAME_RIF (f)->scroll_run_hook (w, &run);
16436 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
16437 update_end (f);
16440 /* Shift current matrix down by nrows_scrolled lines. */
16441 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
16442 rotate_matrix (w->current_matrix,
16443 start_vpos,
16444 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
16445 nrows_scrolled);
16447 /* Disable lines that must be updated. */
16448 for (i = 0; i < nrows_scrolled; ++i)
16449 (start_row + i)->enabled_p = 0;
16451 /* Re-compute Y positions. */
16452 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
16453 max_y = it.last_visible_y;
16454 for (row = start_row + nrows_scrolled;
16455 row < bottom_row;
16456 ++row)
16458 row->y = it.current_y;
16459 row->visible_height = row->height;
16461 if (row->y < min_y)
16462 row->visible_height -= min_y - row->y;
16463 if (row->y + row->height > max_y)
16464 row->visible_height -= row->y + row->height - max_y;
16465 if (row->fringe_bitmap_periodic_p)
16466 row->redraw_fringe_bitmaps_p = 1;
16468 it.current_y += row->height;
16470 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16471 last_reused_text_row = row;
16472 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
16473 break;
16476 /* Disable lines in the current matrix which are now
16477 below the window. */
16478 for (++row; row < bottom_row; ++row)
16479 row->enabled_p = row->mode_line_p = 0;
16482 /* Update window_end_pos etc.; last_reused_text_row is the last
16483 reused row from the current matrix containing text, if any.
16484 The value of last_text_row is the last displayed line
16485 containing text. */
16486 if (last_reused_text_row)
16488 w->window_end_bytepos
16489 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
16490 wset_window_end_pos
16491 (w, make_number (Z
16492 - MATRIX_ROW_END_CHARPOS (last_reused_text_row)));
16493 wset_window_end_vpos
16494 (w, make_number (MATRIX_ROW_VPOS (last_reused_text_row,
16495 w->current_matrix)));
16497 else if (last_text_row)
16499 w->window_end_bytepos
16500 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16501 wset_window_end_pos
16502 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
16503 wset_window_end_vpos
16504 (w, make_number (MATRIX_ROW_VPOS (last_text_row,
16505 w->desired_matrix)));
16507 else
16509 /* This window must be completely empty. */
16510 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
16511 wset_window_end_pos (w, make_number (Z - ZV));
16512 wset_window_end_vpos (w, make_number (0));
16514 w->window_end_valid = 0;
16516 /* Update hint: don't try scrolling again in update_window. */
16517 w->desired_matrix->no_scrolling_p = 1;
16519 #ifdef GLYPH_DEBUG
16520 debug_method_add (w, "try_window_reusing_current_matrix 1");
16521 #endif
16522 return 1;
16524 else if (CHARPOS (new_start) > CHARPOS (start))
16526 struct glyph_row *pt_row, *row;
16527 struct glyph_row *first_reusable_row;
16528 struct glyph_row *first_row_to_display;
16529 int dy;
16530 int yb = window_text_bottom_y (w);
16532 /* Find the row starting at new_start, if there is one. Don't
16533 reuse a partially visible line at the end. */
16534 first_reusable_row = start_row;
16535 while (first_reusable_row->enabled_p
16536 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
16537 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
16538 < CHARPOS (new_start)))
16539 ++first_reusable_row;
16541 /* Give up if there is no row to reuse. */
16542 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
16543 || !first_reusable_row->enabled_p
16544 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
16545 != CHARPOS (new_start)))
16546 return 0;
16548 /* We can reuse fully visible rows beginning with
16549 first_reusable_row to the end of the window. Set
16550 first_row_to_display to the first row that cannot be reused.
16551 Set pt_row to the row containing point, if there is any. */
16552 pt_row = NULL;
16553 for (first_row_to_display = first_reusable_row;
16554 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
16555 ++first_row_to_display)
16557 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
16558 && (PT < MATRIX_ROW_END_CHARPOS (first_row_to_display)
16559 || (PT == MATRIX_ROW_END_CHARPOS (first_row_to_display)
16560 && first_row_to_display->ends_at_zv_p
16561 && pt_row == NULL)))
16562 pt_row = first_row_to_display;
16565 /* Start displaying at the start of first_row_to_display. */
16566 eassert (first_row_to_display->y < yb);
16567 init_to_row_start (&it, w, first_row_to_display);
16569 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
16570 - start_vpos);
16571 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
16572 - nrows_scrolled);
16573 it.current_y = (first_row_to_display->y - first_reusable_row->y
16574 + WINDOW_HEADER_LINE_HEIGHT (w));
16576 /* Display lines beginning with first_row_to_display in the
16577 desired matrix. Set last_text_row to the last row displayed
16578 that displays text. */
16579 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
16580 if (pt_row == NULL)
16581 w->cursor.vpos = -1;
16582 last_text_row = NULL;
16583 while (it.current_y < it.last_visible_y && !fonts_changed_p)
16584 if (display_line (&it))
16585 last_text_row = it.glyph_row - 1;
16587 /* If point is in a reused row, adjust y and vpos of the cursor
16588 position. */
16589 if (pt_row)
16591 w->cursor.vpos -= nrows_scrolled;
16592 w->cursor.y -= first_reusable_row->y - start_row->y;
16595 /* Give up if point isn't in a row displayed or reused. (This
16596 also handles the case where w->cursor.vpos < nrows_scrolled
16597 after the calls to display_line, which can happen with scroll
16598 margins. See bug#1295.) */
16599 if (w->cursor.vpos < 0)
16601 clear_glyph_matrix (w->desired_matrix);
16602 return 0;
16605 /* Scroll the display. */
16606 run.current_y = first_reusable_row->y;
16607 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
16608 run.height = it.last_visible_y - run.current_y;
16609 dy = run.current_y - run.desired_y;
16611 if (run.height)
16613 update_begin (f);
16614 FRAME_RIF (f)->update_window_begin_hook (w);
16615 FRAME_RIF (f)->clear_window_mouse_face (w);
16616 FRAME_RIF (f)->scroll_run_hook (w, &run);
16617 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
16618 update_end (f);
16621 /* Adjust Y positions of reused rows. */
16622 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
16623 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
16624 max_y = it.last_visible_y;
16625 for (row = first_reusable_row; row < first_row_to_display; ++row)
16627 row->y -= dy;
16628 row->visible_height = row->height;
16629 if (row->y < min_y)
16630 row->visible_height -= min_y - row->y;
16631 if (row->y + row->height > max_y)
16632 row->visible_height -= row->y + row->height - max_y;
16633 if (row->fringe_bitmap_periodic_p)
16634 row->redraw_fringe_bitmaps_p = 1;
16637 /* Scroll the current matrix. */
16638 eassert (nrows_scrolled > 0);
16639 rotate_matrix (w->current_matrix,
16640 start_vpos,
16641 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
16642 -nrows_scrolled);
16644 /* Disable rows not reused. */
16645 for (row -= nrows_scrolled; row < bottom_row; ++row)
16646 row->enabled_p = 0;
16648 /* Point may have moved to a different line, so we cannot assume that
16649 the previous cursor position is valid; locate the correct row. */
16650 if (pt_row)
16652 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
16653 row < bottom_row
16654 && PT >= MATRIX_ROW_END_CHARPOS (row)
16655 && !row->ends_at_zv_p;
16656 row++)
16658 w->cursor.vpos++;
16659 w->cursor.y = row->y;
16661 if (row < bottom_row)
16663 /* Can't simply scan the row for point with
16664 bidi-reordered glyph rows. Let set_cursor_from_row
16665 figure out where to put the cursor, and if it fails,
16666 give up. */
16667 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
16669 if (!set_cursor_from_row (w, row, w->current_matrix,
16670 0, 0, 0, 0))
16672 clear_glyph_matrix (w->desired_matrix);
16673 return 0;
16676 else
16678 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
16679 struct glyph *end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
16681 for (; glyph < end
16682 && (!BUFFERP (glyph->object)
16683 || glyph->charpos < PT);
16684 glyph++)
16686 w->cursor.hpos++;
16687 w->cursor.x += glyph->pixel_width;
16693 /* Adjust window end. A null value of last_text_row means that
16694 the window end is in reused rows which in turn means that
16695 only its vpos can have changed. */
16696 if (last_text_row)
16698 w->window_end_bytepos
16699 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16700 wset_window_end_pos
16701 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
16702 wset_window_end_vpos
16703 (w, make_number (MATRIX_ROW_VPOS (last_text_row,
16704 w->desired_matrix)));
16706 else
16708 wset_window_end_vpos
16709 (w, make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled));
16712 w->window_end_valid = 0;
16713 w->desired_matrix->no_scrolling_p = 1;
16715 #ifdef GLYPH_DEBUG
16716 debug_method_add (w, "try_window_reusing_current_matrix 2");
16717 #endif
16718 return 1;
16721 return 0;
16726 /************************************************************************
16727 Window redisplay reusing current matrix when buffer has changed
16728 ************************************************************************/
16730 static struct glyph_row *find_last_unchanged_at_beg_row (struct window *);
16731 static struct glyph_row *find_first_unchanged_at_end_row (struct window *,
16732 ptrdiff_t *, ptrdiff_t *);
16733 static struct glyph_row *
16734 find_last_row_displaying_text (struct glyph_matrix *, struct it *,
16735 struct glyph_row *);
16738 /* Return the last row in MATRIX displaying text. If row START is
16739 non-null, start searching with that row. IT gives the dimensions
16740 of the display. Value is null if matrix is empty; otherwise it is
16741 a pointer to the row found. */
16743 static struct glyph_row *
16744 find_last_row_displaying_text (struct glyph_matrix *matrix, struct it *it,
16745 struct glyph_row *start)
16747 struct glyph_row *row, *row_found;
16749 /* Set row_found to the last row in IT->w's current matrix
16750 displaying text. The loop looks funny but think of partially
16751 visible lines. */
16752 row_found = NULL;
16753 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
16754 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16756 eassert (row->enabled_p);
16757 row_found = row;
16758 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
16759 break;
16760 ++row;
16763 return row_found;
16767 /* Return the last row in the current matrix of W that is not affected
16768 by changes at the start of current_buffer that occurred since W's
16769 current matrix was built. Value is null if no such row exists.
16771 BEG_UNCHANGED us the number of characters unchanged at the start of
16772 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
16773 first changed character in current_buffer. Characters at positions <
16774 BEG + BEG_UNCHANGED are at the same buffer positions as they were
16775 when the current matrix was built. */
16777 static struct glyph_row *
16778 find_last_unchanged_at_beg_row (struct window *w)
16780 ptrdiff_t first_changed_pos = BEG + BEG_UNCHANGED;
16781 struct glyph_row *row;
16782 struct glyph_row *row_found = NULL;
16783 int yb = window_text_bottom_y (w);
16785 /* Find the last row displaying unchanged text. */
16786 for (row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16787 MATRIX_ROW_DISPLAYS_TEXT_P (row)
16788 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos;
16789 ++row)
16791 if (/* If row ends before first_changed_pos, it is unchanged,
16792 except in some case. */
16793 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
16794 /* When row ends in ZV and we write at ZV it is not
16795 unchanged. */
16796 && !row->ends_at_zv_p
16797 /* When first_changed_pos is the end of a continued line,
16798 row is not unchanged because it may be no longer
16799 continued. */
16800 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
16801 && (row->continued_p
16802 || row->exact_window_width_line_p))
16803 /* If ROW->end is beyond ZV, then ROW->end is outdated and
16804 needs to be recomputed, so don't consider this row as
16805 unchanged. This happens when the last line was
16806 bidi-reordered and was killed immediately before this
16807 redisplay cycle. In that case, ROW->end stores the
16808 buffer position of the first visual-order character of
16809 the killed text, which is now beyond ZV. */
16810 && CHARPOS (row->end.pos) <= ZV)
16811 row_found = row;
16813 /* Stop if last visible row. */
16814 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
16815 break;
16818 return row_found;
16822 /* Find the first glyph row in the current matrix of W that is not
16823 affected by changes at the end of current_buffer since the
16824 time W's current matrix was built.
16826 Return in *DELTA the number of chars by which buffer positions in
16827 unchanged text at the end of current_buffer must be adjusted.
16829 Return in *DELTA_BYTES the corresponding number of bytes.
16831 Value is null if no such row exists, i.e. all rows are affected by
16832 changes. */
16834 static struct glyph_row *
16835 find_first_unchanged_at_end_row (struct window *w,
16836 ptrdiff_t *delta, ptrdiff_t *delta_bytes)
16838 struct glyph_row *row;
16839 struct glyph_row *row_found = NULL;
16841 *delta = *delta_bytes = 0;
16843 /* Display must not have been paused, otherwise the current matrix
16844 is not up to date. */
16845 eassert (w->window_end_valid);
16847 /* A value of window_end_pos >= END_UNCHANGED means that the window
16848 end is in the range of changed text. If so, there is no
16849 unchanged row at the end of W's current matrix. */
16850 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
16851 return NULL;
16853 /* Set row to the last row in W's current matrix displaying text. */
16854 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
16856 /* If matrix is entirely empty, no unchanged row exists. */
16857 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16859 /* The value of row is the last glyph row in the matrix having a
16860 meaningful buffer position in it. The end position of row
16861 corresponds to window_end_pos. This allows us to translate
16862 buffer positions in the current matrix to current buffer
16863 positions for characters not in changed text. */
16864 ptrdiff_t Z_old =
16865 MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
16866 ptrdiff_t Z_BYTE_old =
16867 MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
16868 ptrdiff_t last_unchanged_pos, last_unchanged_pos_old;
16869 struct glyph_row *first_text_row
16870 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16872 *delta = Z - Z_old;
16873 *delta_bytes = Z_BYTE - Z_BYTE_old;
16875 /* Set last_unchanged_pos to the buffer position of the last
16876 character in the buffer that has not been changed. Z is the
16877 index + 1 of the last character in current_buffer, i.e. by
16878 subtracting END_UNCHANGED we get the index of the last
16879 unchanged character, and we have to add BEG to get its buffer
16880 position. */
16881 last_unchanged_pos = Z - END_UNCHANGED + BEG;
16882 last_unchanged_pos_old = last_unchanged_pos - *delta;
16884 /* Search backward from ROW for a row displaying a line that
16885 starts at a minimum position >= last_unchanged_pos_old. */
16886 for (; row > first_text_row; --row)
16888 /* This used to abort, but it can happen.
16889 It is ok to just stop the search instead here. KFS. */
16890 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
16891 break;
16893 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
16894 row_found = row;
16898 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
16900 return row_found;
16904 /* Make sure that glyph rows in the current matrix of window W
16905 reference the same glyph memory as corresponding rows in the
16906 frame's frame matrix. This function is called after scrolling W's
16907 current matrix on a terminal frame in try_window_id and
16908 try_window_reusing_current_matrix. */
16910 static void
16911 sync_frame_with_window_matrix_rows (struct window *w)
16913 struct frame *f = XFRAME (w->frame);
16914 struct glyph_row *window_row, *window_row_end, *frame_row;
16916 /* Preconditions: W must be a leaf window and full-width. Its frame
16917 must have a frame matrix. */
16918 eassert (BUFFERP (w->contents));
16919 eassert (WINDOW_FULL_WIDTH_P (w));
16920 eassert (!FRAME_WINDOW_P (f));
16922 /* If W is a full-width window, glyph pointers in W's current matrix
16923 have, by definition, to be the same as glyph pointers in the
16924 corresponding frame matrix. Note that frame matrices have no
16925 marginal areas (see build_frame_matrix). */
16926 window_row = w->current_matrix->rows;
16927 window_row_end = window_row + w->current_matrix->nrows;
16928 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
16929 while (window_row < window_row_end)
16931 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
16932 struct glyph *end = window_row->glyphs[LAST_AREA];
16934 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
16935 frame_row->glyphs[TEXT_AREA] = start;
16936 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
16937 frame_row->glyphs[LAST_AREA] = end;
16939 /* Disable frame rows whose corresponding window rows have
16940 been disabled in try_window_id. */
16941 if (!window_row->enabled_p)
16942 frame_row->enabled_p = 0;
16944 ++window_row, ++frame_row;
16949 /* Find the glyph row in window W containing CHARPOS. Consider all
16950 rows between START and END (not inclusive). END null means search
16951 all rows to the end of the display area of W. Value is the row
16952 containing CHARPOS or null. */
16954 struct glyph_row *
16955 row_containing_pos (struct window *w, ptrdiff_t charpos,
16956 struct glyph_row *start, struct glyph_row *end, int dy)
16958 struct glyph_row *row = start;
16959 struct glyph_row *best_row = NULL;
16960 ptrdiff_t mindif = BUF_ZV (XBUFFER (w->contents)) + 1;
16961 int last_y;
16963 /* If we happen to start on a header-line, skip that. */
16964 if (row->mode_line_p)
16965 ++row;
16967 if ((end && row >= end) || !row->enabled_p)
16968 return NULL;
16970 last_y = window_text_bottom_y (w) - dy;
16972 while (1)
16974 /* Give up if we have gone too far. */
16975 if (end && row >= end)
16976 return NULL;
16977 /* This formerly returned if they were equal.
16978 I think that both quantities are of a "last plus one" type;
16979 if so, when they are equal, the row is within the screen. -- rms. */
16980 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
16981 return NULL;
16983 /* If it is in this row, return this row. */
16984 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
16985 || (MATRIX_ROW_END_CHARPOS (row) == charpos
16986 /* The end position of a row equals the start
16987 position of the next row. If CHARPOS is there, we
16988 would rather consider it displayed in the next
16989 line, except when this line ends in ZV. */
16990 && !row_for_charpos_p (row, charpos)))
16991 && charpos >= MATRIX_ROW_START_CHARPOS (row))
16993 struct glyph *g;
16995 if (NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
16996 || (!best_row && !row->continued_p))
16997 return row;
16998 /* In bidi-reordered rows, there could be several rows whose
16999 edges surround CHARPOS, all of these rows belonging to
17000 the same continued line. We need to find the row which
17001 fits CHARPOS the best. */
17002 for (g = row->glyphs[TEXT_AREA];
17003 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
17004 g++)
17006 if (!STRINGP (g->object))
17008 if (g->charpos > 0 && eabs (g->charpos - charpos) < mindif)
17010 mindif = eabs (g->charpos - charpos);
17011 best_row = row;
17012 /* Exact match always wins. */
17013 if (mindif == 0)
17014 return best_row;
17019 else if (best_row && !row->continued_p)
17020 return best_row;
17021 ++row;
17026 /* Try to redisplay window W by reusing its existing display. W's
17027 current matrix must be up to date when this function is called,
17028 i.e. window_end_valid must be nonzero.
17030 Value is
17032 1 if display has been updated
17033 0 if otherwise unsuccessful
17034 -1 if redisplay with same window start is known not to succeed
17036 The following steps are performed:
17038 1. Find the last row in the current matrix of W that is not
17039 affected by changes at the start of current_buffer. If no such row
17040 is found, give up.
17042 2. Find the first row in W's current matrix that is not affected by
17043 changes at the end of current_buffer. Maybe there is no such row.
17045 3. Display lines beginning with the row + 1 found in step 1 to the
17046 row found in step 2 or, if step 2 didn't find a row, to the end of
17047 the window.
17049 4. If cursor is not known to appear on the window, give up.
17051 5. If display stopped at the row found in step 2, scroll the
17052 display and current matrix as needed.
17054 6. Maybe display some lines at the end of W, if we must. This can
17055 happen under various circumstances, like a partially visible line
17056 becoming fully visible, or because newly displayed lines are displayed
17057 in smaller font sizes.
17059 7. Update W's window end information. */
17061 static int
17062 try_window_id (struct window *w)
17064 struct frame *f = XFRAME (w->frame);
17065 struct glyph_matrix *current_matrix = w->current_matrix;
17066 struct glyph_matrix *desired_matrix = w->desired_matrix;
17067 struct glyph_row *last_unchanged_at_beg_row;
17068 struct glyph_row *first_unchanged_at_end_row;
17069 struct glyph_row *row;
17070 struct glyph_row *bottom_row;
17071 int bottom_vpos;
17072 struct it it;
17073 ptrdiff_t delta = 0, delta_bytes = 0, stop_pos;
17074 int dvpos, dy;
17075 struct text_pos start_pos;
17076 struct run run;
17077 int first_unchanged_at_end_vpos = 0;
17078 struct glyph_row *last_text_row, *last_text_row_at_end;
17079 struct text_pos start;
17080 ptrdiff_t first_changed_charpos, last_changed_charpos;
17082 #ifdef GLYPH_DEBUG
17083 if (inhibit_try_window_id)
17084 return 0;
17085 #endif
17087 /* This is handy for debugging. */
17088 #if 0
17089 #define GIVE_UP(X) \
17090 do { \
17091 fprintf (stderr, "try_window_id give up %d\n", (X)); \
17092 return 0; \
17093 } while (0)
17094 #else
17095 #define GIVE_UP(X) return 0
17096 #endif
17098 SET_TEXT_POS_FROM_MARKER (start, w->start);
17100 /* Don't use this for mini-windows because these can show
17101 messages and mini-buffers, and we don't handle that here. */
17102 if (MINI_WINDOW_P (w))
17103 GIVE_UP (1);
17105 /* This flag is used to prevent redisplay optimizations. */
17106 if (windows_or_buffers_changed || cursor_type_changed)
17107 GIVE_UP (2);
17109 /* Verify that narrowing has not changed.
17110 Also verify that we were not told to prevent redisplay optimizations.
17111 It would be nice to further
17112 reduce the number of cases where this prevents try_window_id. */
17113 if (current_buffer->clip_changed
17114 || current_buffer->prevent_redisplay_optimizations_p)
17115 GIVE_UP (3);
17117 /* Window must either use window-based redisplay or be full width. */
17118 if (!FRAME_WINDOW_P (f)
17119 && (!FRAME_LINE_INS_DEL_OK (f)
17120 || !WINDOW_FULL_WIDTH_P (w)))
17121 GIVE_UP (4);
17123 /* Give up if point is known NOT to appear in W. */
17124 if (PT < CHARPOS (start))
17125 GIVE_UP (5);
17127 /* Another way to prevent redisplay optimizations. */
17128 if (w->last_modified == 0)
17129 GIVE_UP (6);
17131 /* Verify that window is not hscrolled. */
17132 if (w->hscroll != 0)
17133 GIVE_UP (7);
17135 /* Verify that display wasn't paused. */
17136 if (!w->window_end_valid)
17137 GIVE_UP (8);
17139 /* Can't use this if highlighting a region because a cursor movement
17140 will do more than just set the cursor. */
17141 if (markpos_of_region () >= 0)
17142 GIVE_UP (9);
17144 /* Likewise if highlighting trailing whitespace. */
17145 if (!NILP (Vshow_trailing_whitespace))
17146 GIVE_UP (11);
17148 /* Likewise if showing a region. */
17149 if (w->region_showing)
17150 GIVE_UP (10);
17152 /* Can't use this if overlay arrow position and/or string have
17153 changed. */
17154 if (overlay_arrows_changed_p ())
17155 GIVE_UP (12);
17157 /* When word-wrap is on, adding a space to the first word of a
17158 wrapped line can change the wrap position, altering the line
17159 above it. It might be worthwhile to handle this more
17160 intelligently, but for now just redisplay from scratch. */
17161 if (!NILP (BVAR (XBUFFER (w->contents), word_wrap)))
17162 GIVE_UP (21);
17164 /* Under bidi reordering, adding or deleting a character in the
17165 beginning of a paragraph, before the first strong directional
17166 character, can change the base direction of the paragraph (unless
17167 the buffer specifies a fixed paragraph direction), which will
17168 require to redisplay the whole paragraph. It might be worthwhile
17169 to find the paragraph limits and widen the range of redisplayed
17170 lines to that, but for now just give up this optimization and
17171 redisplay from scratch. */
17172 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
17173 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
17174 GIVE_UP (22);
17176 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
17177 only if buffer has really changed. The reason is that the gap is
17178 initially at Z for freshly visited files. The code below would
17179 set end_unchanged to 0 in that case. */
17180 if (MODIFF > SAVE_MODIFF
17181 /* This seems to happen sometimes after saving a buffer. */
17182 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
17184 if (GPT - BEG < BEG_UNCHANGED)
17185 BEG_UNCHANGED = GPT - BEG;
17186 if (Z - GPT < END_UNCHANGED)
17187 END_UNCHANGED = Z - GPT;
17190 /* The position of the first and last character that has been changed. */
17191 first_changed_charpos = BEG + BEG_UNCHANGED;
17192 last_changed_charpos = Z - END_UNCHANGED;
17194 /* If window starts after a line end, and the last change is in
17195 front of that newline, then changes don't affect the display.
17196 This case happens with stealth-fontification. Note that although
17197 the display is unchanged, glyph positions in the matrix have to
17198 be adjusted, of course. */
17199 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
17200 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
17201 && ((last_changed_charpos < CHARPOS (start)
17202 && CHARPOS (start) == BEGV)
17203 || (last_changed_charpos < CHARPOS (start) - 1
17204 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
17206 ptrdiff_t Z_old, Z_delta, Z_BYTE_old, Z_delta_bytes;
17207 struct glyph_row *r0;
17209 /* Compute how many chars/bytes have been added to or removed
17210 from the buffer. */
17211 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
17212 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
17213 Z_delta = Z - Z_old;
17214 Z_delta_bytes = Z_BYTE - Z_BYTE_old;
17216 /* Give up if PT is not in the window. Note that it already has
17217 been checked at the start of try_window_id that PT is not in
17218 front of the window start. */
17219 if (PT >= MATRIX_ROW_END_CHARPOS (row) + Z_delta)
17220 GIVE_UP (13);
17222 /* If window start is unchanged, we can reuse the whole matrix
17223 as is, after adjusting glyph positions. No need to compute
17224 the window end again, since its offset from Z hasn't changed. */
17225 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
17226 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + Z_delta
17227 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + Z_delta_bytes
17228 /* PT must not be in a partially visible line. */
17229 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + Z_delta
17230 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
17232 /* Adjust positions in the glyph matrix. */
17233 if (Z_delta || Z_delta_bytes)
17235 struct glyph_row *r1
17236 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
17237 increment_matrix_positions (w->current_matrix,
17238 MATRIX_ROW_VPOS (r0, current_matrix),
17239 MATRIX_ROW_VPOS (r1, current_matrix),
17240 Z_delta, Z_delta_bytes);
17243 /* Set the cursor. */
17244 row = row_containing_pos (w, PT, r0, NULL, 0);
17245 if (row)
17246 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
17247 else
17248 emacs_abort ();
17249 return 1;
17253 /* Handle the case that changes are all below what is displayed in
17254 the window, and that PT is in the window. This shortcut cannot
17255 be taken if ZV is visible in the window, and text has been added
17256 there that is visible in the window. */
17257 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
17258 /* ZV is not visible in the window, or there are no
17259 changes at ZV, actually. */
17260 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
17261 || first_changed_charpos == last_changed_charpos))
17263 struct glyph_row *r0;
17265 /* Give up if PT is not in the window. Note that it already has
17266 been checked at the start of try_window_id that PT is not in
17267 front of the window start. */
17268 if (PT >= MATRIX_ROW_END_CHARPOS (row))
17269 GIVE_UP (14);
17271 /* If window start is unchanged, we can reuse the whole matrix
17272 as is, without changing glyph positions since no text has
17273 been added/removed in front of the window end. */
17274 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
17275 if (TEXT_POS_EQUAL_P (start, r0->minpos)
17276 /* PT must not be in a partially visible line. */
17277 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
17278 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
17280 /* We have to compute the window end anew since text
17281 could have been added/removed after it. */
17282 wset_window_end_pos
17283 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row)));
17284 w->window_end_bytepos
17285 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17287 /* Set the cursor. */
17288 row = row_containing_pos (w, PT, r0, NULL, 0);
17289 if (row)
17290 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
17291 else
17292 emacs_abort ();
17293 return 2;
17297 /* Give up if window start is in the changed area.
17299 The condition used to read
17301 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
17303 but why that was tested escapes me at the moment. */
17304 if (CHARPOS (start) >= first_changed_charpos
17305 && CHARPOS (start) <= last_changed_charpos)
17306 GIVE_UP (15);
17308 /* Check that window start agrees with the start of the first glyph
17309 row in its current matrix. Check this after we know the window
17310 start is not in changed text, otherwise positions would not be
17311 comparable. */
17312 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
17313 if (!TEXT_POS_EQUAL_P (start, row->minpos))
17314 GIVE_UP (16);
17316 /* Give up if the window ends in strings. Overlay strings
17317 at the end are difficult to handle, so don't try. */
17318 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
17319 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
17320 GIVE_UP (20);
17322 /* Compute the position at which we have to start displaying new
17323 lines. Some of the lines at the top of the window might be
17324 reusable because they are not displaying changed text. Find the
17325 last row in W's current matrix not affected by changes at the
17326 start of current_buffer. Value is null if changes start in the
17327 first line of window. */
17328 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
17329 if (last_unchanged_at_beg_row)
17331 /* Avoid starting to display in the middle of a character, a TAB
17332 for instance. This is easier than to set up the iterator
17333 exactly, and it's not a frequent case, so the additional
17334 effort wouldn't really pay off. */
17335 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
17336 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
17337 && last_unchanged_at_beg_row > w->current_matrix->rows)
17338 --last_unchanged_at_beg_row;
17340 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
17341 GIVE_UP (17);
17343 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
17344 GIVE_UP (18);
17345 start_pos = it.current.pos;
17347 /* Start displaying new lines in the desired matrix at the same
17348 vpos we would use in the current matrix, i.e. below
17349 last_unchanged_at_beg_row. */
17350 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
17351 current_matrix);
17352 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
17353 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
17355 eassert (it.hpos == 0 && it.current_x == 0);
17357 else
17359 /* There are no reusable lines at the start of the window.
17360 Start displaying in the first text line. */
17361 start_display (&it, w, start);
17362 it.vpos = it.first_vpos;
17363 start_pos = it.current.pos;
17366 /* Find the first row that is not affected by changes at the end of
17367 the buffer. Value will be null if there is no unchanged row, in
17368 which case we must redisplay to the end of the window. delta
17369 will be set to the value by which buffer positions beginning with
17370 first_unchanged_at_end_row have to be adjusted due to text
17371 changes. */
17372 first_unchanged_at_end_row
17373 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
17374 IF_DEBUG (debug_delta = delta);
17375 IF_DEBUG (debug_delta_bytes = delta_bytes);
17377 /* Set stop_pos to the buffer position up to which we will have to
17378 display new lines. If first_unchanged_at_end_row != NULL, this
17379 is the buffer position of the start of the line displayed in that
17380 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
17381 that we don't stop at a buffer position. */
17382 stop_pos = 0;
17383 if (first_unchanged_at_end_row)
17385 eassert (last_unchanged_at_beg_row == NULL
17386 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
17388 /* If this is a continuation line, move forward to the next one
17389 that isn't. Changes in lines above affect this line.
17390 Caution: this may move first_unchanged_at_end_row to a row
17391 not displaying text. */
17392 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
17393 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
17394 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
17395 < it.last_visible_y))
17396 ++first_unchanged_at_end_row;
17398 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
17399 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
17400 >= it.last_visible_y))
17401 first_unchanged_at_end_row = NULL;
17402 else
17404 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
17405 + delta);
17406 first_unchanged_at_end_vpos
17407 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
17408 eassert (stop_pos >= Z - END_UNCHANGED);
17411 else if (last_unchanged_at_beg_row == NULL)
17412 GIVE_UP (19);
17415 #ifdef GLYPH_DEBUG
17417 /* Either there is no unchanged row at the end, or the one we have
17418 now displays text. This is a necessary condition for the window
17419 end pos calculation at the end of this function. */
17420 eassert (first_unchanged_at_end_row == NULL
17421 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
17423 debug_last_unchanged_at_beg_vpos
17424 = (last_unchanged_at_beg_row
17425 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
17426 : -1);
17427 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
17429 #endif /* GLYPH_DEBUG */
17432 /* Display new lines. Set last_text_row to the last new line
17433 displayed which has text on it, i.e. might end up as being the
17434 line where the window_end_vpos is. */
17435 w->cursor.vpos = -1;
17436 last_text_row = NULL;
17437 overlay_arrow_seen = 0;
17438 while (it.current_y < it.last_visible_y
17439 && !fonts_changed_p
17440 && (first_unchanged_at_end_row == NULL
17441 || IT_CHARPOS (it) < stop_pos))
17443 if (display_line (&it))
17444 last_text_row = it.glyph_row - 1;
17447 if (fonts_changed_p)
17448 return -1;
17451 /* Compute differences in buffer positions, y-positions etc. for
17452 lines reused at the bottom of the window. Compute what we can
17453 scroll. */
17454 if (first_unchanged_at_end_row
17455 /* No lines reused because we displayed everything up to the
17456 bottom of the window. */
17457 && it.current_y < it.last_visible_y)
17459 dvpos = (it.vpos
17460 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
17461 current_matrix));
17462 dy = it.current_y - first_unchanged_at_end_row->y;
17463 run.current_y = first_unchanged_at_end_row->y;
17464 run.desired_y = run.current_y + dy;
17465 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
17467 else
17469 delta = delta_bytes = dvpos = dy
17470 = run.current_y = run.desired_y = run.height = 0;
17471 first_unchanged_at_end_row = NULL;
17473 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
17476 /* Find the cursor if not already found. We have to decide whether
17477 PT will appear on this window (it sometimes doesn't, but this is
17478 not a very frequent case.) This decision has to be made before
17479 the current matrix is altered. A value of cursor.vpos < 0 means
17480 that PT is either in one of the lines beginning at
17481 first_unchanged_at_end_row or below the window. Don't care for
17482 lines that might be displayed later at the window end; as
17483 mentioned, this is not a frequent case. */
17484 if (w->cursor.vpos < 0)
17486 /* Cursor in unchanged rows at the top? */
17487 if (PT < CHARPOS (start_pos)
17488 && last_unchanged_at_beg_row)
17490 row = row_containing_pos (w, PT,
17491 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
17492 last_unchanged_at_beg_row + 1, 0);
17493 if (row)
17494 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
17497 /* Start from first_unchanged_at_end_row looking for PT. */
17498 else if (first_unchanged_at_end_row)
17500 row = row_containing_pos (w, PT - delta,
17501 first_unchanged_at_end_row, NULL, 0);
17502 if (row)
17503 set_cursor_from_row (w, row, w->current_matrix, delta,
17504 delta_bytes, dy, dvpos);
17507 /* Give up if cursor was not found. */
17508 if (w->cursor.vpos < 0)
17510 clear_glyph_matrix (w->desired_matrix);
17511 return -1;
17515 /* Don't let the cursor end in the scroll margins. */
17517 int this_scroll_margin, cursor_height;
17519 this_scroll_margin =
17520 max (0, min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4));
17521 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
17522 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
17524 if ((w->cursor.y < this_scroll_margin
17525 && CHARPOS (start) > BEGV)
17526 /* Old redisplay didn't take scroll margin into account at the bottom,
17527 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
17528 || (w->cursor.y + (make_cursor_line_fully_visible_p
17529 ? cursor_height + this_scroll_margin
17530 : 1)) > it.last_visible_y)
17532 w->cursor.vpos = -1;
17533 clear_glyph_matrix (w->desired_matrix);
17534 return -1;
17538 /* Scroll the display. Do it before changing the current matrix so
17539 that xterm.c doesn't get confused about where the cursor glyph is
17540 found. */
17541 if (dy && run.height)
17543 update_begin (f);
17545 if (FRAME_WINDOW_P (f))
17547 FRAME_RIF (f)->update_window_begin_hook (w);
17548 FRAME_RIF (f)->clear_window_mouse_face (w);
17549 FRAME_RIF (f)->scroll_run_hook (w, &run);
17550 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
17552 else
17554 /* Terminal frame. In this case, dvpos gives the number of
17555 lines to scroll by; dvpos < 0 means scroll up. */
17556 int from_vpos
17557 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
17558 int from = WINDOW_TOP_EDGE_LINE (w) + from_vpos;
17559 int end = (WINDOW_TOP_EDGE_LINE (w)
17560 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
17561 + window_internal_height (w));
17563 #if defined (HAVE_GPM) || defined (MSDOS)
17564 x_clear_window_mouse_face (w);
17565 #endif
17566 /* Perform the operation on the screen. */
17567 if (dvpos > 0)
17569 /* Scroll last_unchanged_at_beg_row to the end of the
17570 window down dvpos lines. */
17571 set_terminal_window (f, end);
17573 /* On dumb terminals delete dvpos lines at the end
17574 before inserting dvpos empty lines. */
17575 if (!FRAME_SCROLL_REGION_OK (f))
17576 ins_del_lines (f, end - dvpos, -dvpos);
17578 /* Insert dvpos empty lines in front of
17579 last_unchanged_at_beg_row. */
17580 ins_del_lines (f, from, dvpos);
17582 else if (dvpos < 0)
17584 /* Scroll up last_unchanged_at_beg_vpos to the end of
17585 the window to last_unchanged_at_beg_vpos - |dvpos|. */
17586 set_terminal_window (f, end);
17588 /* Delete dvpos lines in front of
17589 last_unchanged_at_beg_vpos. ins_del_lines will set
17590 the cursor to the given vpos and emit |dvpos| delete
17591 line sequences. */
17592 ins_del_lines (f, from + dvpos, dvpos);
17594 /* On a dumb terminal insert dvpos empty lines at the
17595 end. */
17596 if (!FRAME_SCROLL_REGION_OK (f))
17597 ins_del_lines (f, end + dvpos, -dvpos);
17600 set_terminal_window (f, 0);
17603 update_end (f);
17606 /* Shift reused rows of the current matrix to the right position.
17607 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
17608 text. */
17609 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
17610 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
17611 if (dvpos < 0)
17613 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
17614 bottom_vpos, dvpos);
17615 clear_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
17616 bottom_vpos);
17618 else if (dvpos > 0)
17620 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
17621 bottom_vpos, dvpos);
17622 clear_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
17623 first_unchanged_at_end_vpos + dvpos);
17626 /* For frame-based redisplay, make sure that current frame and window
17627 matrix are in sync with respect to glyph memory. */
17628 if (!FRAME_WINDOW_P (f))
17629 sync_frame_with_window_matrix_rows (w);
17631 /* Adjust buffer positions in reused rows. */
17632 if (delta || delta_bytes)
17633 increment_matrix_positions (current_matrix,
17634 first_unchanged_at_end_vpos + dvpos,
17635 bottom_vpos, delta, delta_bytes);
17637 /* Adjust Y positions. */
17638 if (dy)
17639 shift_glyph_matrix (w, current_matrix,
17640 first_unchanged_at_end_vpos + dvpos,
17641 bottom_vpos, dy);
17643 if (first_unchanged_at_end_row)
17645 first_unchanged_at_end_row += dvpos;
17646 if (first_unchanged_at_end_row->y >= it.last_visible_y
17647 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
17648 first_unchanged_at_end_row = NULL;
17651 /* If scrolling up, there may be some lines to display at the end of
17652 the window. */
17653 last_text_row_at_end = NULL;
17654 if (dy < 0)
17656 /* Scrolling up can leave for example a partially visible line
17657 at the end of the window to be redisplayed. */
17658 /* Set last_row to the glyph row in the current matrix where the
17659 window end line is found. It has been moved up or down in
17660 the matrix by dvpos. */
17661 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
17662 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
17664 /* If last_row is the window end line, it should display text. */
17665 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_row));
17667 /* If window end line was partially visible before, begin
17668 displaying at that line. Otherwise begin displaying with the
17669 line following it. */
17670 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
17672 init_to_row_start (&it, w, last_row);
17673 it.vpos = last_vpos;
17674 it.current_y = last_row->y;
17676 else
17678 init_to_row_end (&it, w, last_row);
17679 it.vpos = 1 + last_vpos;
17680 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
17681 ++last_row;
17684 /* We may start in a continuation line. If so, we have to
17685 get the right continuation_lines_width and current_x. */
17686 it.continuation_lines_width = last_row->continuation_lines_width;
17687 it.hpos = it.current_x = 0;
17689 /* Display the rest of the lines at the window end. */
17690 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
17691 while (it.current_y < it.last_visible_y
17692 && !fonts_changed_p)
17694 /* Is it always sure that the display agrees with lines in
17695 the current matrix? I don't think so, so we mark rows
17696 displayed invalid in the current matrix by setting their
17697 enabled_p flag to zero. */
17698 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
17699 if (display_line (&it))
17700 last_text_row_at_end = it.glyph_row - 1;
17704 /* Update window_end_pos and window_end_vpos. */
17705 if (first_unchanged_at_end_row
17706 && !last_text_row_at_end)
17708 /* Window end line if one of the preserved rows from the current
17709 matrix. Set row to the last row displaying text in current
17710 matrix starting at first_unchanged_at_end_row, after
17711 scrolling. */
17712 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
17713 row = find_last_row_displaying_text (w->current_matrix, &it,
17714 first_unchanged_at_end_row);
17715 eassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
17717 wset_window_end_pos (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row)));
17718 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17719 wset_window_end_vpos
17720 (w, make_number (MATRIX_ROW_VPOS (row, w->current_matrix)));
17721 eassert (w->window_end_bytepos >= 0);
17722 IF_DEBUG (debug_method_add (w, "A"));
17724 else if (last_text_row_at_end)
17726 wset_window_end_pos
17727 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end)));
17728 w->window_end_bytepos
17729 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
17730 wset_window_end_vpos
17731 (w, make_number (MATRIX_ROW_VPOS (last_text_row_at_end,
17732 desired_matrix)));
17733 eassert (w->window_end_bytepos >= 0);
17734 IF_DEBUG (debug_method_add (w, "B"));
17736 else if (last_text_row)
17738 /* We have displayed either to the end of the window or at the
17739 end of the window, i.e. the last row with text is to be found
17740 in the desired matrix. */
17741 wset_window_end_pos
17742 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
17743 w->window_end_bytepos
17744 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
17745 wset_window_end_vpos
17746 (w, make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix)));
17747 eassert (w->window_end_bytepos >= 0);
17749 else if (first_unchanged_at_end_row == NULL
17750 && last_text_row == NULL
17751 && last_text_row_at_end == NULL)
17753 /* Displayed to end of window, but no line containing text was
17754 displayed. Lines were deleted at the end of the window. */
17755 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
17756 int vpos = XFASTINT (w->window_end_vpos);
17757 struct glyph_row *current_row = current_matrix->rows + vpos;
17758 struct glyph_row *desired_row = desired_matrix->rows + vpos;
17760 for (row = NULL;
17761 row == NULL && vpos >= first_vpos;
17762 --vpos, --current_row, --desired_row)
17764 if (desired_row->enabled_p)
17766 if (MATRIX_ROW_DISPLAYS_TEXT_P (desired_row))
17767 row = desired_row;
17769 else if (MATRIX_ROW_DISPLAYS_TEXT_P (current_row))
17770 row = current_row;
17773 eassert (row != NULL);
17774 wset_window_end_vpos (w, make_number (vpos + 1));
17775 wset_window_end_pos (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row)));
17776 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17777 eassert (w->window_end_bytepos >= 0);
17778 IF_DEBUG (debug_method_add (w, "C"));
17780 else
17781 emacs_abort ();
17783 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
17784 debug_end_vpos = XFASTINT (w->window_end_vpos));
17786 /* Record that display has not been completed. */
17787 w->window_end_valid = 0;
17788 w->desired_matrix->no_scrolling_p = 1;
17789 return 3;
17791 #undef GIVE_UP
17796 /***********************************************************************
17797 More debugging support
17798 ***********************************************************************/
17800 #ifdef GLYPH_DEBUG
17802 void dump_glyph_row (struct glyph_row *, int, int) EXTERNALLY_VISIBLE;
17803 void dump_glyph_matrix (struct glyph_matrix *, int) EXTERNALLY_VISIBLE;
17804 void dump_glyph (struct glyph_row *, struct glyph *, int) EXTERNALLY_VISIBLE;
17807 /* Dump the contents of glyph matrix MATRIX on stderr.
17809 GLYPHS 0 means don't show glyph contents.
17810 GLYPHS 1 means show glyphs in short form
17811 GLYPHS > 1 means show glyphs in long form. */
17813 void
17814 dump_glyph_matrix (struct glyph_matrix *matrix, int glyphs)
17816 int i;
17817 for (i = 0; i < matrix->nrows; ++i)
17818 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
17822 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
17823 the glyph row and area where the glyph comes from. */
17825 void
17826 dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
17828 if (glyph->type == CHAR_GLYPH
17829 || glyph->type == GLYPHLESS_GLYPH)
17831 fprintf (stderr,
17832 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
17833 glyph - row->glyphs[TEXT_AREA],
17834 (glyph->type == CHAR_GLYPH
17835 ? 'C'
17836 : 'G'),
17837 glyph->charpos,
17838 (BUFFERP (glyph->object)
17839 ? 'B'
17840 : (STRINGP (glyph->object)
17841 ? 'S'
17842 : (INTEGERP (glyph->object)
17843 ? '0'
17844 : '-'))),
17845 glyph->pixel_width,
17846 glyph->u.ch,
17847 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
17848 ? glyph->u.ch
17849 : '.'),
17850 glyph->face_id,
17851 glyph->left_box_line_p,
17852 glyph->right_box_line_p);
17854 else if (glyph->type == STRETCH_GLYPH)
17856 fprintf (stderr,
17857 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
17858 glyph - row->glyphs[TEXT_AREA],
17859 'S',
17860 glyph->charpos,
17861 (BUFFERP (glyph->object)
17862 ? 'B'
17863 : (STRINGP (glyph->object)
17864 ? 'S'
17865 : (INTEGERP (glyph->object)
17866 ? '0'
17867 : '-'))),
17868 glyph->pixel_width,
17870 ' ',
17871 glyph->face_id,
17872 glyph->left_box_line_p,
17873 glyph->right_box_line_p);
17875 else if (glyph->type == IMAGE_GLYPH)
17877 fprintf (stderr,
17878 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
17879 glyph - row->glyphs[TEXT_AREA],
17880 'I',
17881 glyph->charpos,
17882 (BUFFERP (glyph->object)
17883 ? 'B'
17884 : (STRINGP (glyph->object)
17885 ? 'S'
17886 : (INTEGERP (glyph->object)
17887 ? '0'
17888 : '-'))),
17889 glyph->pixel_width,
17890 glyph->u.img_id,
17891 '.',
17892 glyph->face_id,
17893 glyph->left_box_line_p,
17894 glyph->right_box_line_p);
17896 else if (glyph->type == COMPOSITE_GLYPH)
17898 fprintf (stderr,
17899 " %5"pD"d %c %9"pI"d %c %3d 0x%06x",
17900 glyph - row->glyphs[TEXT_AREA],
17901 '+',
17902 glyph->charpos,
17903 (BUFFERP (glyph->object)
17904 ? 'B'
17905 : (STRINGP (glyph->object)
17906 ? 'S'
17907 : (INTEGERP (glyph->object)
17908 ? '0'
17909 : '-'))),
17910 glyph->pixel_width,
17911 glyph->u.cmp.id);
17912 if (glyph->u.cmp.automatic)
17913 fprintf (stderr,
17914 "[%d-%d]",
17915 glyph->slice.cmp.from, glyph->slice.cmp.to);
17916 fprintf (stderr, " . %4d %1.1d%1.1d\n",
17917 glyph->face_id,
17918 glyph->left_box_line_p,
17919 glyph->right_box_line_p);
17924 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
17925 GLYPHS 0 means don't show glyph contents.
17926 GLYPHS 1 means show glyphs in short form
17927 GLYPHS > 1 means show glyphs in long form. */
17929 void
17930 dump_glyph_row (struct glyph_row *row, int vpos, int glyphs)
17932 if (glyphs != 1)
17934 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
17935 fprintf (stderr, "==============================================================================\n");
17937 fprintf (stderr, "%3d %9"pI"d %9"pI"d %4d %1.1d%1.1d%1.1d%1.1d\
17938 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
17939 vpos,
17940 MATRIX_ROW_START_CHARPOS (row),
17941 MATRIX_ROW_END_CHARPOS (row),
17942 row->used[TEXT_AREA],
17943 row->contains_overlapping_glyphs_p,
17944 row->enabled_p,
17945 row->truncated_on_left_p,
17946 row->truncated_on_right_p,
17947 row->continued_p,
17948 MATRIX_ROW_CONTINUATION_LINE_P (row),
17949 MATRIX_ROW_DISPLAYS_TEXT_P (row),
17950 row->ends_at_zv_p,
17951 row->fill_line_p,
17952 row->ends_in_middle_of_char_p,
17953 row->starts_in_middle_of_char_p,
17954 row->mouse_face_p,
17955 row->x,
17956 row->y,
17957 row->pixel_width,
17958 row->height,
17959 row->visible_height,
17960 row->ascent,
17961 row->phys_ascent);
17962 /* The next 3 lines should align to "Start" in the header. */
17963 fprintf (stderr, " %9"pD"d %9"pD"d\t%5d\n", row->start.overlay_string_index,
17964 row->end.overlay_string_index,
17965 row->continuation_lines_width);
17966 fprintf (stderr, " %9"pI"d %9"pI"d\n",
17967 CHARPOS (row->start.string_pos),
17968 CHARPOS (row->end.string_pos));
17969 fprintf (stderr, " %9d %9d\n", row->start.dpvec_index,
17970 row->end.dpvec_index);
17973 if (glyphs > 1)
17975 int area;
17977 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
17979 struct glyph *glyph = row->glyphs[area];
17980 struct glyph *glyph_end = glyph + row->used[area];
17982 /* Glyph for a line end in text. */
17983 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
17984 ++glyph_end;
17986 if (glyph < glyph_end)
17987 fprintf (stderr, " Glyph# Type Pos O W Code C Face LR\n");
17989 for (; glyph < glyph_end; ++glyph)
17990 dump_glyph (row, glyph, area);
17993 else if (glyphs == 1)
17995 int area;
17997 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
17999 char *s = alloca (row->used[area] + 4);
18000 int i;
18002 for (i = 0; i < row->used[area]; ++i)
18004 struct glyph *glyph = row->glyphs[area] + i;
18005 if (i == row->used[area] - 1
18006 && area == TEXT_AREA
18007 && INTEGERP (glyph->object)
18008 && glyph->type == CHAR_GLYPH
18009 && glyph->u.ch == ' ')
18011 strcpy (&s[i], "[\\n]");
18012 i += 4;
18014 else if (glyph->type == CHAR_GLYPH
18015 && glyph->u.ch < 0x80
18016 && glyph->u.ch >= ' ')
18017 s[i] = glyph->u.ch;
18018 else
18019 s[i] = '.';
18022 s[i] = '\0';
18023 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
18029 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
18030 Sdump_glyph_matrix, 0, 1, "p",
18031 doc: /* Dump the current matrix of the selected window to stderr.
18032 Shows contents of glyph row structures. With non-nil
18033 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
18034 glyphs in short form, otherwise show glyphs in long form. */)
18035 (Lisp_Object glyphs)
18037 struct window *w = XWINDOW (selected_window);
18038 struct buffer *buffer = XBUFFER (w->contents);
18040 fprintf (stderr, "PT = %"pI"d, BEGV = %"pI"d. ZV = %"pI"d\n",
18041 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
18042 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
18043 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
18044 fprintf (stderr, "=============================================\n");
18045 dump_glyph_matrix (w->current_matrix,
18046 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 0);
18047 return Qnil;
18051 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
18052 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
18053 (void)
18055 struct frame *f = XFRAME (selected_frame);
18056 dump_glyph_matrix (f->current_matrix, 1);
18057 return Qnil;
18061 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
18062 doc: /* Dump glyph row ROW to stderr.
18063 GLYPH 0 means don't dump glyphs.
18064 GLYPH 1 means dump glyphs in short form.
18065 GLYPH > 1 or omitted means dump glyphs in long form. */)
18066 (Lisp_Object row, Lisp_Object glyphs)
18068 struct glyph_matrix *matrix;
18069 EMACS_INT vpos;
18071 CHECK_NUMBER (row);
18072 matrix = XWINDOW (selected_window)->current_matrix;
18073 vpos = XINT (row);
18074 if (vpos >= 0 && vpos < matrix->nrows)
18075 dump_glyph_row (MATRIX_ROW (matrix, vpos),
18076 vpos,
18077 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
18078 return Qnil;
18082 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
18083 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
18084 GLYPH 0 means don't dump glyphs.
18085 GLYPH 1 means dump glyphs in short form.
18086 GLYPH > 1 or omitted means dump glyphs in long form. */)
18087 (Lisp_Object row, Lisp_Object glyphs)
18089 struct frame *sf = SELECTED_FRAME ();
18090 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
18091 EMACS_INT vpos;
18093 CHECK_NUMBER (row);
18094 vpos = XINT (row);
18095 if (vpos >= 0 && vpos < m->nrows)
18096 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
18097 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
18098 return Qnil;
18102 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
18103 doc: /* Toggle tracing of redisplay.
18104 With ARG, turn tracing on if and only if ARG is positive. */)
18105 (Lisp_Object arg)
18107 if (NILP (arg))
18108 trace_redisplay_p = !trace_redisplay_p;
18109 else
18111 arg = Fprefix_numeric_value (arg);
18112 trace_redisplay_p = XINT (arg) > 0;
18115 return Qnil;
18119 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
18120 doc: /* Like `format', but print result to stderr.
18121 usage: (trace-to-stderr STRING &rest OBJECTS) */)
18122 (ptrdiff_t nargs, Lisp_Object *args)
18124 Lisp_Object s = Fformat (nargs, args);
18125 fprintf (stderr, "%s", SDATA (s));
18126 return Qnil;
18129 #endif /* GLYPH_DEBUG */
18133 /***********************************************************************
18134 Building Desired Matrix Rows
18135 ***********************************************************************/
18137 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
18138 Used for non-window-redisplay windows, and for windows w/o left fringe. */
18140 static struct glyph_row *
18141 get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
18143 struct frame *f = XFRAME (WINDOW_FRAME (w));
18144 struct buffer *buffer = XBUFFER (w->contents);
18145 struct buffer *old = current_buffer;
18146 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
18147 int arrow_len = SCHARS (overlay_arrow_string);
18148 const unsigned char *arrow_end = arrow_string + arrow_len;
18149 const unsigned char *p;
18150 struct it it;
18151 bool multibyte_p;
18152 int n_glyphs_before;
18154 set_buffer_temp (buffer);
18155 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
18156 it.glyph_row->used[TEXT_AREA] = 0;
18157 SET_TEXT_POS (it.position, 0, 0);
18159 multibyte_p = !NILP (BVAR (buffer, enable_multibyte_characters));
18160 p = arrow_string;
18161 while (p < arrow_end)
18163 Lisp_Object face, ilisp;
18165 /* Get the next character. */
18166 if (multibyte_p)
18167 it.c = it.char_to_display = string_char_and_length (p, &it.len);
18168 else
18170 it.c = it.char_to_display = *p, it.len = 1;
18171 if (! ASCII_CHAR_P (it.c))
18172 it.char_to_display = BYTE8_TO_CHAR (it.c);
18174 p += it.len;
18176 /* Get its face. */
18177 ilisp = make_number (p - arrow_string);
18178 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
18179 it.face_id = compute_char_face (f, it.char_to_display, face);
18181 /* Compute its width, get its glyphs. */
18182 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
18183 SET_TEXT_POS (it.position, -1, -1);
18184 PRODUCE_GLYPHS (&it);
18186 /* If this character doesn't fit any more in the line, we have
18187 to remove some glyphs. */
18188 if (it.current_x > it.last_visible_x)
18190 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
18191 break;
18195 set_buffer_temp (old);
18196 return it.glyph_row;
18200 /* Insert truncation glyphs at the start of IT->glyph_row. Which
18201 glyphs to insert is determined by produce_special_glyphs. */
18203 static void
18204 insert_left_trunc_glyphs (struct it *it)
18206 struct it truncate_it;
18207 struct glyph *from, *end, *to, *toend;
18209 eassert (!FRAME_WINDOW_P (it->f)
18210 || (!it->glyph_row->reversed_p
18211 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)
18212 || (it->glyph_row->reversed_p
18213 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0));
18215 /* Get the truncation glyphs. */
18216 truncate_it = *it;
18217 truncate_it.current_x = 0;
18218 truncate_it.face_id = DEFAULT_FACE_ID;
18219 truncate_it.glyph_row = &scratch_glyph_row;
18220 truncate_it.glyph_row->used[TEXT_AREA] = 0;
18221 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
18222 truncate_it.object = make_number (0);
18223 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
18225 /* Overwrite glyphs from IT with truncation glyphs. */
18226 if (!it->glyph_row->reversed_p)
18228 short tused = truncate_it.glyph_row->used[TEXT_AREA];
18230 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
18231 end = from + tused;
18232 to = it->glyph_row->glyphs[TEXT_AREA];
18233 toend = to + it->glyph_row->used[TEXT_AREA];
18234 if (FRAME_WINDOW_P (it->f))
18236 /* On GUI frames, when variable-size fonts are displayed,
18237 the truncation glyphs may need more pixels than the row's
18238 glyphs they overwrite. We overwrite more glyphs to free
18239 enough screen real estate, and enlarge the stretch glyph
18240 on the right (see display_line), if there is one, to
18241 preserve the screen position of the truncation glyphs on
18242 the right. */
18243 int w = 0;
18244 struct glyph *g = to;
18245 short used;
18247 /* The first glyph could be partially visible, in which case
18248 it->glyph_row->x will be negative. But we want the left
18249 truncation glyphs to be aligned at the left margin of the
18250 window, so we override the x coordinate at which the row
18251 will begin. */
18252 it->glyph_row->x = 0;
18253 while (g < toend && w < it->truncation_pixel_width)
18255 w += g->pixel_width;
18256 ++g;
18258 if (g - to - tused > 0)
18260 memmove (to + tused, g, (toend - g) * sizeof(*g));
18261 it->glyph_row->used[TEXT_AREA] -= g - to - tused;
18263 used = it->glyph_row->used[TEXT_AREA];
18264 if (it->glyph_row->truncated_on_right_p
18265 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
18266 && it->glyph_row->glyphs[TEXT_AREA][used - 2].type
18267 == STRETCH_GLYPH)
18269 int extra = w - it->truncation_pixel_width;
18271 it->glyph_row->glyphs[TEXT_AREA][used - 2].pixel_width += extra;
18275 while (from < end)
18276 *to++ = *from++;
18278 /* There may be padding glyphs left over. Overwrite them too. */
18279 if (!FRAME_WINDOW_P (it->f))
18281 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
18283 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
18284 while (from < end)
18285 *to++ = *from++;
18289 if (to > toend)
18290 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
18292 else
18294 short tused = truncate_it.glyph_row->used[TEXT_AREA];
18296 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
18297 that back to front. */
18298 end = truncate_it.glyph_row->glyphs[TEXT_AREA];
18299 from = end + truncate_it.glyph_row->used[TEXT_AREA] - 1;
18300 toend = it->glyph_row->glyphs[TEXT_AREA];
18301 to = toend + it->glyph_row->used[TEXT_AREA] - 1;
18302 if (FRAME_WINDOW_P (it->f))
18304 int w = 0;
18305 struct glyph *g = to;
18307 while (g >= toend && w < it->truncation_pixel_width)
18309 w += g->pixel_width;
18310 --g;
18312 if (to - g - tused > 0)
18313 to = g + tused;
18314 if (it->glyph_row->truncated_on_right_p
18315 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0
18316 && it->glyph_row->glyphs[TEXT_AREA][1].type == STRETCH_GLYPH)
18318 int extra = w - it->truncation_pixel_width;
18320 it->glyph_row->glyphs[TEXT_AREA][1].pixel_width += extra;
18324 while (from >= end && to >= toend)
18325 *to-- = *from--;
18326 if (!FRAME_WINDOW_P (it->f))
18328 while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
18330 from =
18331 truncate_it.glyph_row->glyphs[TEXT_AREA]
18332 + truncate_it.glyph_row->used[TEXT_AREA] - 1;
18333 while (from >= end && to >= toend)
18334 *to-- = *from--;
18337 if (from >= end)
18339 /* Need to free some room before prepending additional
18340 glyphs. */
18341 int move_by = from - end + 1;
18342 struct glyph *g0 = it->glyph_row->glyphs[TEXT_AREA];
18343 struct glyph *g = g0 + it->glyph_row->used[TEXT_AREA] - 1;
18345 for ( ; g >= g0; g--)
18346 g[move_by] = *g;
18347 while (from >= end)
18348 *to-- = *from--;
18349 it->glyph_row->used[TEXT_AREA] += move_by;
18354 /* Compute the hash code for ROW. */
18355 unsigned
18356 row_hash (struct glyph_row *row)
18358 int area, k;
18359 unsigned hashval = 0;
18361 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18362 for (k = 0; k < row->used[area]; ++k)
18363 hashval = ((((hashval << 4) + (hashval >> 24)) & 0x0fffffff)
18364 + row->glyphs[area][k].u.val
18365 + row->glyphs[area][k].face_id
18366 + row->glyphs[area][k].padding_p
18367 + (row->glyphs[area][k].type << 2));
18369 return hashval;
18372 /* Compute the pixel height and width of IT->glyph_row.
18374 Most of the time, ascent and height of a display line will be equal
18375 to the max_ascent and max_height values of the display iterator
18376 structure. This is not the case if
18378 1. We hit ZV without displaying anything. In this case, max_ascent
18379 and max_height will be zero.
18381 2. We have some glyphs that don't contribute to the line height.
18382 (The glyph row flag contributes_to_line_height_p is for future
18383 pixmap extensions).
18385 The first case is easily covered by using default values because in
18386 these cases, the line height does not really matter, except that it
18387 must not be zero. */
18389 static void
18390 compute_line_metrics (struct it *it)
18392 struct glyph_row *row = it->glyph_row;
18394 if (FRAME_WINDOW_P (it->f))
18396 int i, min_y, max_y;
18398 /* The line may consist of one space only, that was added to
18399 place the cursor on it. If so, the row's height hasn't been
18400 computed yet. */
18401 if (row->height == 0)
18403 if (it->max_ascent + it->max_descent == 0)
18404 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
18405 row->ascent = it->max_ascent;
18406 row->height = it->max_ascent + it->max_descent;
18407 row->phys_ascent = it->max_phys_ascent;
18408 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
18409 row->extra_line_spacing = it->max_extra_line_spacing;
18412 /* Compute the width of this line. */
18413 row->pixel_width = row->x;
18414 for (i = 0; i < row->used[TEXT_AREA]; ++i)
18415 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
18417 eassert (row->pixel_width >= 0);
18418 eassert (row->ascent >= 0 && row->height > 0);
18420 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
18421 || MATRIX_ROW_OVERLAPS_PRED_P (row));
18423 /* If first line's physical ascent is larger than its logical
18424 ascent, use the physical ascent, and make the row taller.
18425 This makes accented characters fully visible. */
18426 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
18427 && row->phys_ascent > row->ascent)
18429 row->height += row->phys_ascent - row->ascent;
18430 row->ascent = row->phys_ascent;
18433 /* Compute how much of the line is visible. */
18434 row->visible_height = row->height;
18436 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
18437 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
18439 if (row->y < min_y)
18440 row->visible_height -= min_y - row->y;
18441 if (row->y + row->height > max_y)
18442 row->visible_height -= row->y + row->height - max_y;
18444 else
18446 row->pixel_width = row->used[TEXT_AREA];
18447 if (row->continued_p)
18448 row->pixel_width -= it->continuation_pixel_width;
18449 else if (row->truncated_on_right_p)
18450 row->pixel_width -= it->truncation_pixel_width;
18451 row->ascent = row->phys_ascent = 0;
18452 row->height = row->phys_height = row->visible_height = 1;
18453 row->extra_line_spacing = 0;
18456 /* Compute a hash code for this row. */
18457 row->hash = row_hash (row);
18459 it->max_ascent = it->max_descent = 0;
18460 it->max_phys_ascent = it->max_phys_descent = 0;
18464 /* Append one space to the glyph row of iterator IT if doing a
18465 window-based redisplay. The space has the same face as
18466 IT->face_id. Value is non-zero if a space was added.
18468 This function is called to make sure that there is always one glyph
18469 at the end of a glyph row that the cursor can be set on under
18470 window-systems. (If there weren't such a glyph we would not know
18471 how wide and tall a box cursor should be displayed).
18473 At the same time this space let's a nicely handle clearing to the
18474 end of the line if the row ends in italic text. */
18476 static int
18477 append_space_for_newline (struct it *it, int default_face_p)
18479 if (FRAME_WINDOW_P (it->f))
18481 int n = it->glyph_row->used[TEXT_AREA];
18483 if (it->glyph_row->glyphs[TEXT_AREA] + n
18484 < it->glyph_row->glyphs[1 + TEXT_AREA])
18486 /* Save some values that must not be changed.
18487 Must save IT->c and IT->len because otherwise
18488 ITERATOR_AT_END_P wouldn't work anymore after
18489 append_space_for_newline has been called. */
18490 enum display_element_type saved_what = it->what;
18491 int saved_c = it->c, saved_len = it->len;
18492 int saved_char_to_display = it->char_to_display;
18493 int saved_x = it->current_x;
18494 int saved_face_id = it->face_id;
18495 int saved_box_end = it->end_of_box_run_p;
18496 struct text_pos saved_pos;
18497 Lisp_Object saved_object;
18498 struct face *face;
18500 saved_object = it->object;
18501 saved_pos = it->position;
18503 it->what = IT_CHARACTER;
18504 memset (&it->position, 0, sizeof it->position);
18505 it->object = make_number (0);
18506 it->c = it->char_to_display = ' ';
18507 it->len = 1;
18509 /* If the default face was remapped, be sure to use the
18510 remapped face for the appended newline. */
18511 if (default_face_p)
18512 it->face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
18513 else if (it->face_before_selective_p)
18514 it->face_id = it->saved_face_id;
18515 face = FACE_FROM_ID (it->f, it->face_id);
18516 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
18517 /* In R2L rows, we will prepend a stretch glyph that will
18518 have the end_of_box_run_p flag set for it, so there's no
18519 need for the appended newline glyph to have that flag
18520 set. */
18521 if (it->glyph_row->reversed_p
18522 /* But if the appended newline glyph goes all the way to
18523 the end of the row, there will be no stretch glyph,
18524 so leave the box flag set. */
18525 && saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x)
18526 it->end_of_box_run_p = 0;
18528 PRODUCE_GLYPHS (it);
18530 it->override_ascent = -1;
18531 it->constrain_row_ascent_descent_p = 0;
18532 it->current_x = saved_x;
18533 it->object = saved_object;
18534 it->position = saved_pos;
18535 it->what = saved_what;
18536 it->face_id = saved_face_id;
18537 it->len = saved_len;
18538 it->c = saved_c;
18539 it->char_to_display = saved_char_to_display;
18540 it->end_of_box_run_p = saved_box_end;
18541 return 1;
18545 return 0;
18549 /* Extend the face of the last glyph in the text area of IT->glyph_row
18550 to the end of the display line. Called from display_line. If the
18551 glyph row is empty, add a space glyph to it so that we know the
18552 face to draw. Set the glyph row flag fill_line_p. If the glyph
18553 row is R2L, prepend a stretch glyph to cover the empty space to the
18554 left of the leftmost glyph. */
18556 static void
18557 extend_face_to_end_of_line (struct it *it)
18559 struct face *face, *default_face;
18560 struct frame *f = it->f;
18562 /* If line is already filled, do nothing. Non window-system frames
18563 get a grace of one more ``pixel'' because their characters are
18564 1-``pixel'' wide, so they hit the equality too early. This grace
18565 is needed only for R2L rows that are not continued, to produce
18566 one extra blank where we could display the cursor. */
18567 if (it->current_x >= it->last_visible_x
18568 + (!FRAME_WINDOW_P (f)
18569 && it->glyph_row->reversed_p
18570 && !it->glyph_row->continued_p))
18571 return;
18573 /* The default face, possibly remapped. */
18574 default_face = FACE_FROM_ID (f, lookup_basic_face (f, DEFAULT_FACE_ID));
18576 /* Face extension extends the background and box of IT->face_id
18577 to the end of the line. If the background equals the background
18578 of the frame, we don't have to do anything. */
18579 if (it->face_before_selective_p)
18580 face = FACE_FROM_ID (f, it->saved_face_id);
18581 else
18582 face = FACE_FROM_ID (f, it->face_id);
18584 if (FRAME_WINDOW_P (f)
18585 && MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row)
18586 && face->box == FACE_NO_BOX
18587 && face->background == FRAME_BACKGROUND_PIXEL (f)
18588 && !face->stipple
18589 && !it->glyph_row->reversed_p)
18590 return;
18592 /* Set the glyph row flag indicating that the face of the last glyph
18593 in the text area has to be drawn to the end of the text area. */
18594 it->glyph_row->fill_line_p = 1;
18596 /* If current character of IT is not ASCII, make sure we have the
18597 ASCII face. This will be automatically undone the next time
18598 get_next_display_element returns a multibyte character. Note
18599 that the character will always be single byte in unibyte
18600 text. */
18601 if (!ASCII_CHAR_P (it->c))
18603 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
18606 if (FRAME_WINDOW_P (f))
18608 /* If the row is empty, add a space with the current face of IT,
18609 so that we know which face to draw. */
18610 if (it->glyph_row->used[TEXT_AREA] == 0)
18612 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
18613 it->glyph_row->glyphs[TEXT_AREA][0].face_id = face->id;
18614 it->glyph_row->used[TEXT_AREA] = 1;
18616 #ifdef HAVE_WINDOW_SYSTEM
18617 if (it->glyph_row->reversed_p)
18619 /* Prepend a stretch glyph to the row, such that the
18620 rightmost glyph will be drawn flushed all the way to the
18621 right margin of the window. The stretch glyph that will
18622 occupy the empty space, if any, to the left of the
18623 glyphs. */
18624 struct font *font = face->font ? face->font : FRAME_FONT (f);
18625 struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA];
18626 struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA];
18627 struct glyph *g;
18628 int row_width, stretch_ascent, stretch_width;
18629 struct text_pos saved_pos;
18630 int saved_face_id, saved_avoid_cursor, saved_box_start;
18632 for (row_width = 0, g = row_start; g < row_end; g++)
18633 row_width += g->pixel_width;
18634 stretch_width = window_box_width (it->w, TEXT_AREA) - row_width;
18635 if (stretch_width > 0)
18637 stretch_ascent =
18638 (((it->ascent + it->descent)
18639 * FONT_BASE (font)) / FONT_HEIGHT (font));
18640 saved_pos = it->position;
18641 memset (&it->position, 0, sizeof it->position);
18642 saved_avoid_cursor = it->avoid_cursor_p;
18643 it->avoid_cursor_p = 1;
18644 saved_face_id = it->face_id;
18645 saved_box_start = it->start_of_box_run_p;
18646 /* The last row's stretch glyph should get the default
18647 face, to avoid painting the rest of the window with
18648 the region face, if the region ends at ZV. */
18649 if (it->glyph_row->ends_at_zv_p)
18650 it->face_id = default_face->id;
18651 else
18652 it->face_id = face->id;
18653 it->start_of_box_run_p = 0;
18654 append_stretch_glyph (it, make_number (0), stretch_width,
18655 it->ascent + it->descent, stretch_ascent);
18656 it->position = saved_pos;
18657 it->avoid_cursor_p = saved_avoid_cursor;
18658 it->face_id = saved_face_id;
18659 it->start_of_box_run_p = saved_box_start;
18662 #endif /* HAVE_WINDOW_SYSTEM */
18664 else
18666 /* Save some values that must not be changed. */
18667 int saved_x = it->current_x;
18668 struct text_pos saved_pos;
18669 Lisp_Object saved_object;
18670 enum display_element_type saved_what = it->what;
18671 int saved_face_id = it->face_id;
18673 saved_object = it->object;
18674 saved_pos = it->position;
18676 it->what = IT_CHARACTER;
18677 memset (&it->position, 0, sizeof it->position);
18678 it->object = make_number (0);
18679 it->c = it->char_to_display = ' ';
18680 it->len = 1;
18681 /* The last row's blank glyphs should get the default face, to
18682 avoid painting the rest of the window with the region face,
18683 if the region ends at ZV. */
18684 if (it->glyph_row->ends_at_zv_p)
18685 it->face_id = default_face->id;
18686 else
18687 it->face_id = face->id;
18689 PRODUCE_GLYPHS (it);
18691 while (it->current_x <= it->last_visible_x)
18692 PRODUCE_GLYPHS (it);
18694 /* Don't count these blanks really. It would let us insert a left
18695 truncation glyph below and make us set the cursor on them, maybe. */
18696 it->current_x = saved_x;
18697 it->object = saved_object;
18698 it->position = saved_pos;
18699 it->what = saved_what;
18700 it->face_id = saved_face_id;
18705 /* Value is non-zero if text starting at CHARPOS in current_buffer is
18706 trailing whitespace. */
18708 static int
18709 trailing_whitespace_p (ptrdiff_t charpos)
18711 ptrdiff_t bytepos = CHAR_TO_BYTE (charpos);
18712 int c = 0;
18714 while (bytepos < ZV_BYTE
18715 && (c = FETCH_CHAR (bytepos),
18716 c == ' ' || c == '\t'))
18717 ++bytepos;
18719 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
18721 if (bytepos != PT_BYTE)
18722 return 1;
18724 return 0;
18728 /* Highlight trailing whitespace, if any, in ROW. */
18730 static void
18731 highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
18733 int used = row->used[TEXT_AREA];
18735 if (used)
18737 struct glyph *start = row->glyphs[TEXT_AREA];
18738 struct glyph *glyph = start + used - 1;
18740 if (row->reversed_p)
18742 /* Right-to-left rows need to be processed in the opposite
18743 direction, so swap the edge pointers. */
18744 glyph = start;
18745 start = row->glyphs[TEXT_AREA] + used - 1;
18748 /* Skip over glyphs inserted to display the cursor at the
18749 end of a line, for extending the face of the last glyph
18750 to the end of the line on terminals, and for truncation
18751 and continuation glyphs. */
18752 if (!row->reversed_p)
18754 while (glyph >= start
18755 && glyph->type == CHAR_GLYPH
18756 && INTEGERP (glyph->object))
18757 --glyph;
18759 else
18761 while (glyph <= start
18762 && glyph->type == CHAR_GLYPH
18763 && INTEGERP (glyph->object))
18764 ++glyph;
18767 /* If last glyph is a space or stretch, and it's trailing
18768 whitespace, set the face of all trailing whitespace glyphs in
18769 IT->glyph_row to `trailing-whitespace'. */
18770 if ((row->reversed_p ? glyph <= start : glyph >= start)
18771 && BUFFERP (glyph->object)
18772 && (glyph->type == STRETCH_GLYPH
18773 || (glyph->type == CHAR_GLYPH
18774 && glyph->u.ch == ' '))
18775 && trailing_whitespace_p (glyph->charpos))
18777 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
18778 if (face_id < 0)
18779 return;
18781 if (!row->reversed_p)
18783 while (glyph >= start
18784 && BUFFERP (glyph->object)
18785 && (glyph->type == STRETCH_GLYPH
18786 || (glyph->type == CHAR_GLYPH
18787 && glyph->u.ch == ' ')))
18788 (glyph--)->face_id = face_id;
18790 else
18792 while (glyph <= start
18793 && BUFFERP (glyph->object)
18794 && (glyph->type == STRETCH_GLYPH
18795 || (glyph->type == CHAR_GLYPH
18796 && glyph->u.ch == ' ')))
18797 (glyph++)->face_id = face_id;
18804 /* Value is non-zero if glyph row ROW should be
18805 considered to hold the buffer position CHARPOS. */
18807 static int
18808 row_for_charpos_p (struct glyph_row *row, ptrdiff_t charpos)
18810 int result = 1;
18812 if (charpos == CHARPOS (row->end.pos)
18813 || charpos == MATRIX_ROW_END_CHARPOS (row))
18815 /* Suppose the row ends on a string.
18816 Unless the row is continued, that means it ends on a newline
18817 in the string. If it's anything other than a display string
18818 (e.g., a before-string from an overlay), we don't want the
18819 cursor there. (This heuristic seems to give the optimal
18820 behavior for the various types of multi-line strings.)
18821 One exception: if the string has `cursor' property on one of
18822 its characters, we _do_ want the cursor there. */
18823 if (CHARPOS (row->end.string_pos) >= 0)
18825 if (row->continued_p)
18826 result = 1;
18827 else
18829 /* Check for `display' property. */
18830 struct glyph *beg = row->glyphs[TEXT_AREA];
18831 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
18832 struct glyph *glyph;
18834 result = 0;
18835 for (glyph = end; glyph >= beg; --glyph)
18836 if (STRINGP (glyph->object))
18838 Lisp_Object prop
18839 = Fget_char_property (make_number (charpos),
18840 Qdisplay, Qnil);
18841 result =
18842 (!NILP (prop)
18843 && display_prop_string_p (prop, glyph->object));
18844 /* If there's a `cursor' property on one of the
18845 string's characters, this row is a cursor row,
18846 even though this is not a display string. */
18847 if (!result)
18849 Lisp_Object s = glyph->object;
18851 for ( ; glyph >= beg && EQ (glyph->object, s); --glyph)
18853 ptrdiff_t gpos = glyph->charpos;
18855 if (!NILP (Fget_char_property (make_number (gpos),
18856 Qcursor, s)))
18858 result = 1;
18859 break;
18863 break;
18867 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
18869 /* If the row ends in middle of a real character,
18870 and the line is continued, we want the cursor here.
18871 That's because CHARPOS (ROW->end.pos) would equal
18872 PT if PT is before the character. */
18873 if (!row->ends_in_ellipsis_p)
18874 result = row->continued_p;
18875 else
18876 /* If the row ends in an ellipsis, then
18877 CHARPOS (ROW->end.pos) will equal point after the
18878 invisible text. We want that position to be displayed
18879 after the ellipsis. */
18880 result = 0;
18882 /* If the row ends at ZV, display the cursor at the end of that
18883 row instead of at the start of the row below. */
18884 else if (row->ends_at_zv_p)
18885 result = 1;
18886 else
18887 result = 0;
18890 return result;
18893 /* Value is non-zero if glyph row ROW should be
18894 used to hold the cursor. */
18896 static int
18897 cursor_row_p (struct glyph_row *row)
18899 return row_for_charpos_p (row, PT);
18904 /* Push the property PROP so that it will be rendered at the current
18905 position in IT. Return 1 if PROP was successfully pushed, 0
18906 otherwise. Called from handle_line_prefix to handle the
18907 `line-prefix' and `wrap-prefix' properties. */
18909 static int
18910 push_prefix_prop (struct it *it, Lisp_Object prop)
18912 struct text_pos pos =
18913 STRINGP (it->string) ? it->current.string_pos : it->current.pos;
18915 eassert (it->method == GET_FROM_BUFFER
18916 || it->method == GET_FROM_DISPLAY_VECTOR
18917 || it->method == GET_FROM_STRING);
18919 /* We need to save the current buffer/string position, so it will be
18920 restored by pop_it, because iterate_out_of_display_property
18921 depends on that being set correctly, but some situations leave
18922 it->position not yet set when this function is called. */
18923 push_it (it, &pos);
18925 if (STRINGP (prop))
18927 if (SCHARS (prop) == 0)
18929 pop_it (it);
18930 return 0;
18933 it->string = prop;
18934 it->string_from_prefix_prop_p = 1;
18935 it->multibyte_p = STRING_MULTIBYTE (it->string);
18936 it->current.overlay_string_index = -1;
18937 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
18938 it->end_charpos = it->string_nchars = SCHARS (it->string);
18939 it->method = GET_FROM_STRING;
18940 it->stop_charpos = 0;
18941 it->prev_stop = 0;
18942 it->base_level_stop = 0;
18944 /* Force paragraph direction to be that of the parent
18945 buffer/string. */
18946 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
18947 it->paragraph_embedding = it->bidi_it.paragraph_dir;
18948 else
18949 it->paragraph_embedding = L2R;
18951 /* Set up the bidi iterator for this display string. */
18952 if (it->bidi_p)
18954 it->bidi_it.string.lstring = it->string;
18955 it->bidi_it.string.s = NULL;
18956 it->bidi_it.string.schars = it->end_charpos;
18957 it->bidi_it.string.bufpos = IT_CHARPOS (*it);
18958 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
18959 it->bidi_it.string.unibyte = !it->multibyte_p;
18960 it->bidi_it.w = it->w;
18961 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
18964 else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
18966 it->method = GET_FROM_STRETCH;
18967 it->object = prop;
18969 #ifdef HAVE_WINDOW_SYSTEM
18970 else if (IMAGEP (prop))
18972 it->what = IT_IMAGE;
18973 it->image_id = lookup_image (it->f, prop);
18974 it->method = GET_FROM_IMAGE;
18976 #endif /* HAVE_WINDOW_SYSTEM */
18977 else
18979 pop_it (it); /* bogus display property, give up */
18980 return 0;
18983 return 1;
18986 /* Return the character-property PROP at the current position in IT. */
18988 static Lisp_Object
18989 get_it_property (struct it *it, Lisp_Object prop)
18991 Lisp_Object position, object = it->object;
18993 if (STRINGP (object))
18994 position = make_number (IT_STRING_CHARPOS (*it));
18995 else if (BUFFERP (object))
18997 position = make_number (IT_CHARPOS (*it));
18998 object = it->window;
19000 else
19001 return Qnil;
19003 return Fget_char_property (position, prop, object);
19006 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
19008 static void
19009 handle_line_prefix (struct it *it)
19011 Lisp_Object prefix;
19013 if (it->continuation_lines_width > 0)
19015 prefix = get_it_property (it, Qwrap_prefix);
19016 if (NILP (prefix))
19017 prefix = Vwrap_prefix;
19019 else
19021 prefix = get_it_property (it, Qline_prefix);
19022 if (NILP (prefix))
19023 prefix = Vline_prefix;
19025 if (! NILP (prefix) && push_prefix_prop (it, prefix))
19027 /* If the prefix is wider than the window, and we try to wrap
19028 it, it would acquire its own wrap prefix, and so on till the
19029 iterator stack overflows. So, don't wrap the prefix. */
19030 it->line_wrap = TRUNCATE;
19031 it->avoid_cursor_p = 1;
19037 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
19038 only for R2L lines from display_line and display_string, when they
19039 decide that too many glyphs were produced by PRODUCE_GLYPHS, and
19040 the line/string needs to be continued on the next glyph row. */
19041 static void
19042 unproduce_glyphs (struct it *it, int n)
19044 struct glyph *glyph, *end;
19046 eassert (it->glyph_row);
19047 eassert (it->glyph_row->reversed_p);
19048 eassert (it->area == TEXT_AREA);
19049 eassert (n <= it->glyph_row->used[TEXT_AREA]);
19051 if (n > it->glyph_row->used[TEXT_AREA])
19052 n = it->glyph_row->used[TEXT_AREA];
19053 glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
19054 end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
19055 for ( ; glyph < end; glyph++)
19056 glyph[-n] = *glyph;
19059 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
19060 and ROW->maxpos. */
19061 static void
19062 find_row_edges (struct it *it, struct glyph_row *row,
19063 ptrdiff_t min_pos, ptrdiff_t min_bpos,
19064 ptrdiff_t max_pos, ptrdiff_t max_bpos)
19066 /* FIXME: Revisit this when glyph ``spilling'' in continuation
19067 lines' rows is implemented for bidi-reordered rows. */
19069 /* ROW->minpos is the value of min_pos, the minimal buffer position
19070 we have in ROW, or ROW->start.pos if that is smaller. */
19071 if (min_pos <= ZV && min_pos < row->start.pos.charpos)
19072 SET_TEXT_POS (row->minpos, min_pos, min_bpos);
19073 else
19074 /* We didn't find buffer positions smaller than ROW->start, or
19075 didn't find _any_ valid buffer positions in any of the glyphs,
19076 so we must trust the iterator's computed positions. */
19077 row->minpos = row->start.pos;
19078 if (max_pos <= 0)
19080 max_pos = CHARPOS (it->current.pos);
19081 max_bpos = BYTEPOS (it->current.pos);
19084 /* Here are the various use-cases for ending the row, and the
19085 corresponding values for ROW->maxpos:
19087 Line ends in a newline from buffer eol_pos + 1
19088 Line is continued from buffer max_pos + 1
19089 Line is truncated on right it->current.pos
19090 Line ends in a newline from string max_pos + 1(*)
19091 (*) + 1 only when line ends in a forward scan
19092 Line is continued from string max_pos
19093 Line is continued from display vector max_pos
19094 Line is entirely from a string min_pos == max_pos
19095 Line is entirely from a display vector min_pos == max_pos
19096 Line that ends at ZV ZV
19098 If you discover other use-cases, please add them here as
19099 appropriate. */
19100 if (row->ends_at_zv_p)
19101 row->maxpos = it->current.pos;
19102 else if (row->used[TEXT_AREA])
19104 int seen_this_string = 0;
19105 struct glyph_row *r1 = row - 1;
19107 /* Did we see the same display string on the previous row? */
19108 if (STRINGP (it->object)
19109 /* this is not the first row */
19110 && row > it->w->desired_matrix->rows
19111 /* previous row is not the header line */
19112 && !r1->mode_line_p
19113 /* previous row also ends in a newline from a string */
19114 && r1->ends_in_newline_from_string_p)
19116 struct glyph *start, *end;
19118 /* Search for the last glyph of the previous row that came
19119 from buffer or string. Depending on whether the row is
19120 L2R or R2L, we need to process it front to back or the
19121 other way round. */
19122 if (!r1->reversed_p)
19124 start = r1->glyphs[TEXT_AREA];
19125 end = start + r1->used[TEXT_AREA];
19126 /* Glyphs inserted by redisplay have an integer (zero)
19127 as their object. */
19128 while (end > start
19129 && INTEGERP ((end - 1)->object)
19130 && (end - 1)->charpos <= 0)
19131 --end;
19132 if (end > start)
19134 if (EQ ((end - 1)->object, it->object))
19135 seen_this_string = 1;
19137 else
19138 /* If all the glyphs of the previous row were inserted
19139 by redisplay, it means the previous row was
19140 produced from a single newline, which is only
19141 possible if that newline came from the same string
19142 as the one which produced this ROW. */
19143 seen_this_string = 1;
19145 else
19147 end = r1->glyphs[TEXT_AREA] - 1;
19148 start = end + r1->used[TEXT_AREA];
19149 while (end < start
19150 && INTEGERP ((end + 1)->object)
19151 && (end + 1)->charpos <= 0)
19152 ++end;
19153 if (end < start)
19155 if (EQ ((end + 1)->object, it->object))
19156 seen_this_string = 1;
19158 else
19159 seen_this_string = 1;
19162 /* Take note of each display string that covers a newline only
19163 once, the first time we see it. This is for when a display
19164 string includes more than one newline in it. */
19165 if (row->ends_in_newline_from_string_p && !seen_this_string)
19167 /* If we were scanning the buffer forward when we displayed
19168 the string, we want to account for at least one buffer
19169 position that belongs to this row (position covered by
19170 the display string), so that cursor positioning will
19171 consider this row as a candidate when point is at the end
19172 of the visual line represented by this row. This is not
19173 required when scanning back, because max_pos will already
19174 have a much larger value. */
19175 if (CHARPOS (row->end.pos) > max_pos)
19176 INC_BOTH (max_pos, max_bpos);
19177 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19179 else if (CHARPOS (it->eol_pos) > 0)
19180 SET_TEXT_POS (row->maxpos,
19181 CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
19182 else if (row->continued_p)
19184 /* If max_pos is different from IT's current position, it
19185 means IT->method does not belong to the display element
19186 at max_pos. However, it also means that the display
19187 element at max_pos was displayed in its entirety on this
19188 line, which is equivalent to saying that the next line
19189 starts at the next buffer position. */
19190 if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
19191 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19192 else
19194 INC_BOTH (max_pos, max_bpos);
19195 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19198 else if (row->truncated_on_right_p)
19199 /* display_line already called reseat_at_next_visible_line_start,
19200 which puts the iterator at the beginning of the next line, in
19201 the logical order. */
19202 row->maxpos = it->current.pos;
19203 else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
19204 /* A line that is entirely from a string/image/stretch... */
19205 row->maxpos = row->minpos;
19206 else
19207 emacs_abort ();
19209 else
19210 row->maxpos = it->current.pos;
19213 /* Construct the glyph row IT->glyph_row in the desired matrix of
19214 IT->w from text at the current position of IT. See dispextern.h
19215 for an overview of struct it. Value is non-zero if
19216 IT->glyph_row displays text, as opposed to a line displaying ZV
19217 only. */
19219 static int
19220 display_line (struct it *it)
19222 struct glyph_row *row = it->glyph_row;
19223 Lisp_Object overlay_arrow_string;
19224 struct it wrap_it;
19225 void *wrap_data = NULL;
19226 int may_wrap = 0, wrap_x IF_LINT (= 0);
19227 int wrap_row_used = -1;
19228 int wrap_row_ascent IF_LINT (= 0), wrap_row_height IF_LINT (= 0);
19229 int wrap_row_phys_ascent IF_LINT (= 0), wrap_row_phys_height IF_LINT (= 0);
19230 int wrap_row_extra_line_spacing IF_LINT (= 0);
19231 ptrdiff_t wrap_row_min_pos IF_LINT (= 0), wrap_row_min_bpos IF_LINT (= 0);
19232 ptrdiff_t wrap_row_max_pos IF_LINT (= 0), wrap_row_max_bpos IF_LINT (= 0);
19233 int cvpos;
19234 ptrdiff_t min_pos = ZV + 1, max_pos = 0;
19235 ptrdiff_t min_bpos IF_LINT (= 0), max_bpos IF_LINT (= 0);
19237 /* We always start displaying at hpos zero even if hscrolled. */
19238 eassert (it->hpos == 0 && it->current_x == 0);
19240 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
19241 >= it->w->desired_matrix->nrows)
19243 it->w->nrows_scale_factor++;
19244 fonts_changed_p = 1;
19245 return 0;
19248 /* Is IT->w showing the region? */
19249 it->w->region_showing = it->region_beg_charpos > 0 ? it->region_beg_charpos : 0;
19251 /* Clear the result glyph row and enable it. */
19252 prepare_desired_row (row);
19254 row->y = it->current_y;
19255 row->start = it->start;
19256 row->continuation_lines_width = it->continuation_lines_width;
19257 row->displays_text_p = 1;
19258 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
19259 it->starts_in_middle_of_char_p = 0;
19261 /* Arrange the overlays nicely for our purposes. Usually, we call
19262 display_line on only one line at a time, in which case this
19263 can't really hurt too much, or we call it on lines which appear
19264 one after another in the buffer, in which case all calls to
19265 recenter_overlay_lists but the first will be pretty cheap. */
19266 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
19268 /* Move over display elements that are not visible because we are
19269 hscrolled. This may stop at an x-position < IT->first_visible_x
19270 if the first glyph is partially visible or if we hit a line end. */
19271 if (it->current_x < it->first_visible_x)
19273 enum move_it_result move_result;
19275 this_line_min_pos = row->start.pos;
19276 move_result = move_it_in_display_line_to (it, ZV, it->first_visible_x,
19277 MOVE_TO_POS | MOVE_TO_X);
19278 /* If we are under a large hscroll, move_it_in_display_line_to
19279 could hit the end of the line without reaching
19280 it->first_visible_x. Pretend that we did reach it. This is
19281 especially important on a TTY, where we will call
19282 extend_face_to_end_of_line, which needs to know how many
19283 blank glyphs to produce. */
19284 if (it->current_x < it->first_visible_x
19285 && (move_result == MOVE_NEWLINE_OR_CR
19286 || move_result == MOVE_POS_MATCH_OR_ZV))
19287 it->current_x = it->first_visible_x;
19289 /* Record the smallest positions seen while we moved over
19290 display elements that are not visible. This is needed by
19291 redisplay_internal for optimizing the case where the cursor
19292 stays inside the same line. The rest of this function only
19293 considers positions that are actually displayed, so
19294 RECORD_MAX_MIN_POS will not otherwise record positions that
19295 are hscrolled to the left of the left edge of the window. */
19296 min_pos = CHARPOS (this_line_min_pos);
19297 min_bpos = BYTEPOS (this_line_min_pos);
19299 else
19301 /* We only do this when not calling `move_it_in_display_line_to'
19302 above, because move_it_in_display_line_to calls
19303 handle_line_prefix itself. */
19304 handle_line_prefix (it);
19307 /* Get the initial row height. This is either the height of the
19308 text hscrolled, if there is any, or zero. */
19309 row->ascent = it->max_ascent;
19310 row->height = it->max_ascent + it->max_descent;
19311 row->phys_ascent = it->max_phys_ascent;
19312 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
19313 row->extra_line_spacing = it->max_extra_line_spacing;
19315 /* Utility macro to record max and min buffer positions seen until now. */
19316 #define RECORD_MAX_MIN_POS(IT) \
19317 do \
19319 int composition_p = !STRINGP ((IT)->string) \
19320 && ((IT)->what == IT_COMPOSITION); \
19321 ptrdiff_t current_pos = \
19322 composition_p ? (IT)->cmp_it.charpos \
19323 : IT_CHARPOS (*(IT)); \
19324 ptrdiff_t current_bpos = \
19325 composition_p ? CHAR_TO_BYTE (current_pos) \
19326 : IT_BYTEPOS (*(IT)); \
19327 if (current_pos < min_pos) \
19329 min_pos = current_pos; \
19330 min_bpos = current_bpos; \
19332 if (IT_CHARPOS (*it) > max_pos) \
19334 max_pos = IT_CHARPOS (*it); \
19335 max_bpos = IT_BYTEPOS (*it); \
19338 while (0)
19340 /* Loop generating characters. The loop is left with IT on the next
19341 character to display. */
19342 while (1)
19344 int n_glyphs_before, hpos_before, x_before;
19345 int x, nglyphs;
19346 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
19348 /* Retrieve the next thing to display. Value is zero if end of
19349 buffer reached. */
19350 if (!get_next_display_element (it))
19352 /* Maybe add a space at the end of this line that is used to
19353 display the cursor there under X. Set the charpos of the
19354 first glyph of blank lines not corresponding to any text
19355 to -1. */
19356 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19357 row->exact_window_width_line_p = 1;
19358 else if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
19359 || row->used[TEXT_AREA] == 0)
19361 row->glyphs[TEXT_AREA]->charpos = -1;
19362 row->displays_text_p = 0;
19364 if (!NILP (BVAR (XBUFFER (it->w->contents), indicate_empty_lines))
19365 && (!MINI_WINDOW_P (it->w)
19366 || (minibuf_level && EQ (it->window, minibuf_window))))
19367 row->indicate_empty_line_p = 1;
19370 it->continuation_lines_width = 0;
19371 row->ends_at_zv_p = 1;
19372 /* A row that displays right-to-left text must always have
19373 its last face extended all the way to the end of line,
19374 even if this row ends in ZV, because we still write to
19375 the screen left to right. We also need to extend the
19376 last face if the default face is remapped to some
19377 different face, otherwise the functions that clear
19378 portions of the screen will clear with the default face's
19379 background color. */
19380 if (row->reversed_p
19381 || lookup_basic_face (it->f, DEFAULT_FACE_ID) != DEFAULT_FACE_ID)
19382 extend_face_to_end_of_line (it);
19383 break;
19386 /* Now, get the metrics of what we want to display. This also
19387 generates glyphs in `row' (which is IT->glyph_row). */
19388 n_glyphs_before = row->used[TEXT_AREA];
19389 x = it->current_x;
19391 /* Remember the line height so far in case the next element doesn't
19392 fit on the line. */
19393 if (it->line_wrap != TRUNCATE)
19395 ascent = it->max_ascent;
19396 descent = it->max_descent;
19397 phys_ascent = it->max_phys_ascent;
19398 phys_descent = it->max_phys_descent;
19400 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
19402 if (IT_DISPLAYING_WHITESPACE (it))
19403 may_wrap = 1;
19404 else if (may_wrap)
19406 SAVE_IT (wrap_it, *it, wrap_data);
19407 wrap_x = x;
19408 wrap_row_used = row->used[TEXT_AREA];
19409 wrap_row_ascent = row->ascent;
19410 wrap_row_height = row->height;
19411 wrap_row_phys_ascent = row->phys_ascent;
19412 wrap_row_phys_height = row->phys_height;
19413 wrap_row_extra_line_spacing = row->extra_line_spacing;
19414 wrap_row_min_pos = min_pos;
19415 wrap_row_min_bpos = min_bpos;
19416 wrap_row_max_pos = max_pos;
19417 wrap_row_max_bpos = max_bpos;
19418 may_wrap = 0;
19423 PRODUCE_GLYPHS (it);
19425 /* If this display element was in marginal areas, continue with
19426 the next one. */
19427 if (it->area != TEXT_AREA)
19429 row->ascent = max (row->ascent, it->max_ascent);
19430 row->height = max (row->height, it->max_ascent + it->max_descent);
19431 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19432 row->phys_height = max (row->phys_height,
19433 it->max_phys_ascent + it->max_phys_descent);
19434 row->extra_line_spacing = max (row->extra_line_spacing,
19435 it->max_extra_line_spacing);
19436 set_iterator_to_next (it, 1);
19437 continue;
19440 /* Does the display element fit on the line? If we truncate
19441 lines, we should draw past the right edge of the window. If
19442 we don't truncate, we want to stop so that we can display the
19443 continuation glyph before the right margin. If lines are
19444 continued, there are two possible strategies for characters
19445 resulting in more than 1 glyph (e.g. tabs): Display as many
19446 glyphs as possible in this line and leave the rest for the
19447 continuation line, or display the whole element in the next
19448 line. Original redisplay did the former, so we do it also. */
19449 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
19450 hpos_before = it->hpos;
19451 x_before = x;
19453 if (/* Not a newline. */
19454 nglyphs > 0
19455 /* Glyphs produced fit entirely in the line. */
19456 && it->current_x < it->last_visible_x)
19458 it->hpos += nglyphs;
19459 row->ascent = max (row->ascent, it->max_ascent);
19460 row->height = max (row->height, it->max_ascent + it->max_descent);
19461 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19462 row->phys_height = max (row->phys_height,
19463 it->max_phys_ascent + it->max_phys_descent);
19464 row->extra_line_spacing = max (row->extra_line_spacing,
19465 it->max_extra_line_spacing);
19466 if (it->current_x - it->pixel_width < it->first_visible_x)
19467 row->x = x - it->first_visible_x;
19468 /* Record the maximum and minimum buffer positions seen so
19469 far in glyphs that will be displayed by this row. */
19470 if (it->bidi_p)
19471 RECORD_MAX_MIN_POS (it);
19473 else
19475 int i, new_x;
19476 struct glyph *glyph;
19478 for (i = 0; i < nglyphs; ++i, x = new_x)
19480 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
19481 new_x = x + glyph->pixel_width;
19483 if (/* Lines are continued. */
19484 it->line_wrap != TRUNCATE
19485 && (/* Glyph doesn't fit on the line. */
19486 new_x > it->last_visible_x
19487 /* Or it fits exactly on a window system frame. */
19488 || (new_x == it->last_visible_x
19489 && FRAME_WINDOW_P (it->f)
19490 && (row->reversed_p
19491 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19492 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
19494 /* End of a continued line. */
19496 if (it->hpos == 0
19497 || (new_x == it->last_visible_x
19498 && FRAME_WINDOW_P (it->f)
19499 && (row->reversed_p
19500 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19501 : WINDOW_RIGHT_FRINGE_WIDTH (it->w))))
19503 /* Current glyph is the only one on the line or
19504 fits exactly on the line. We must continue
19505 the line because we can't draw the cursor
19506 after the glyph. */
19507 row->continued_p = 1;
19508 it->current_x = new_x;
19509 it->continuation_lines_width += new_x;
19510 ++it->hpos;
19511 if (i == nglyphs - 1)
19513 /* If line-wrap is on, check if a previous
19514 wrap point was found. */
19515 if (wrap_row_used > 0
19516 /* Even if there is a previous wrap
19517 point, continue the line here as
19518 usual, if (i) the previous character
19519 was a space or tab AND (ii) the
19520 current character is not. */
19521 && (!may_wrap
19522 || IT_DISPLAYING_WHITESPACE (it)))
19523 goto back_to_wrap;
19525 /* Record the maximum and minimum buffer
19526 positions seen so far in glyphs that will be
19527 displayed by this row. */
19528 if (it->bidi_p)
19529 RECORD_MAX_MIN_POS (it);
19530 set_iterator_to_next (it, 1);
19531 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19533 if (!get_next_display_element (it))
19535 row->exact_window_width_line_p = 1;
19536 it->continuation_lines_width = 0;
19537 row->continued_p = 0;
19538 row->ends_at_zv_p = 1;
19540 else if (ITERATOR_AT_END_OF_LINE_P (it))
19542 row->continued_p = 0;
19543 row->exact_window_width_line_p = 1;
19547 else if (it->bidi_p)
19548 RECORD_MAX_MIN_POS (it);
19550 else if (CHAR_GLYPH_PADDING_P (*glyph)
19551 && !FRAME_WINDOW_P (it->f))
19553 /* A padding glyph that doesn't fit on this line.
19554 This means the whole character doesn't fit
19555 on the line. */
19556 if (row->reversed_p)
19557 unproduce_glyphs (it, row->used[TEXT_AREA]
19558 - n_glyphs_before);
19559 row->used[TEXT_AREA] = n_glyphs_before;
19561 /* Fill the rest of the row with continuation
19562 glyphs like in 20.x. */
19563 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
19564 < row->glyphs[1 + TEXT_AREA])
19565 produce_special_glyphs (it, IT_CONTINUATION);
19567 row->continued_p = 1;
19568 it->current_x = x_before;
19569 it->continuation_lines_width += x_before;
19571 /* Restore the height to what it was before the
19572 element not fitting on the line. */
19573 it->max_ascent = ascent;
19574 it->max_descent = descent;
19575 it->max_phys_ascent = phys_ascent;
19576 it->max_phys_descent = phys_descent;
19578 else if (wrap_row_used > 0)
19580 back_to_wrap:
19581 if (row->reversed_p)
19582 unproduce_glyphs (it,
19583 row->used[TEXT_AREA] - wrap_row_used);
19584 RESTORE_IT (it, &wrap_it, wrap_data);
19585 it->continuation_lines_width += wrap_x;
19586 row->used[TEXT_AREA] = wrap_row_used;
19587 row->ascent = wrap_row_ascent;
19588 row->height = wrap_row_height;
19589 row->phys_ascent = wrap_row_phys_ascent;
19590 row->phys_height = wrap_row_phys_height;
19591 row->extra_line_spacing = wrap_row_extra_line_spacing;
19592 min_pos = wrap_row_min_pos;
19593 min_bpos = wrap_row_min_bpos;
19594 max_pos = wrap_row_max_pos;
19595 max_bpos = wrap_row_max_bpos;
19596 row->continued_p = 1;
19597 row->ends_at_zv_p = 0;
19598 row->exact_window_width_line_p = 0;
19599 it->continuation_lines_width += x;
19601 /* Make sure that a non-default face is extended
19602 up to the right margin of the window. */
19603 extend_face_to_end_of_line (it);
19605 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
19607 /* A TAB that extends past the right edge of the
19608 window. This produces a single glyph on
19609 window system frames. We leave the glyph in
19610 this row and let it fill the row, but don't
19611 consume the TAB. */
19612 if ((row->reversed_p
19613 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19614 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
19615 produce_special_glyphs (it, IT_CONTINUATION);
19616 it->continuation_lines_width += it->last_visible_x;
19617 row->ends_in_middle_of_char_p = 1;
19618 row->continued_p = 1;
19619 glyph->pixel_width = it->last_visible_x - x;
19620 it->starts_in_middle_of_char_p = 1;
19622 else
19624 /* Something other than a TAB that draws past
19625 the right edge of the window. Restore
19626 positions to values before the element. */
19627 if (row->reversed_p)
19628 unproduce_glyphs (it, row->used[TEXT_AREA]
19629 - (n_glyphs_before + i));
19630 row->used[TEXT_AREA] = n_glyphs_before + i;
19632 /* Display continuation glyphs. */
19633 it->current_x = x_before;
19634 it->continuation_lines_width += x;
19635 if (!FRAME_WINDOW_P (it->f)
19636 || (row->reversed_p
19637 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19638 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
19639 produce_special_glyphs (it, IT_CONTINUATION);
19640 row->continued_p = 1;
19642 extend_face_to_end_of_line (it);
19644 if (nglyphs > 1 && i > 0)
19646 row->ends_in_middle_of_char_p = 1;
19647 it->starts_in_middle_of_char_p = 1;
19650 /* Restore the height to what it was before the
19651 element not fitting on the line. */
19652 it->max_ascent = ascent;
19653 it->max_descent = descent;
19654 it->max_phys_ascent = phys_ascent;
19655 it->max_phys_descent = phys_descent;
19658 break;
19660 else if (new_x > it->first_visible_x)
19662 /* Increment number of glyphs actually displayed. */
19663 ++it->hpos;
19665 /* Record the maximum and minimum buffer positions
19666 seen so far in glyphs that will be displayed by
19667 this row. */
19668 if (it->bidi_p)
19669 RECORD_MAX_MIN_POS (it);
19671 if (x < it->first_visible_x)
19672 /* Glyph is partially visible, i.e. row starts at
19673 negative X position. */
19674 row->x = x - it->first_visible_x;
19676 else
19678 /* Glyph is completely off the left margin of the
19679 window. This should not happen because of the
19680 move_it_in_display_line at the start of this
19681 function, unless the text display area of the
19682 window is empty. */
19683 eassert (it->first_visible_x <= it->last_visible_x);
19686 /* Even if this display element produced no glyphs at all,
19687 we want to record its position. */
19688 if (it->bidi_p && nglyphs == 0)
19689 RECORD_MAX_MIN_POS (it);
19691 row->ascent = max (row->ascent, it->max_ascent);
19692 row->height = max (row->height, it->max_ascent + it->max_descent);
19693 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19694 row->phys_height = max (row->phys_height,
19695 it->max_phys_ascent + it->max_phys_descent);
19696 row->extra_line_spacing = max (row->extra_line_spacing,
19697 it->max_extra_line_spacing);
19699 /* End of this display line if row is continued. */
19700 if (row->continued_p || row->ends_at_zv_p)
19701 break;
19704 at_end_of_line:
19705 /* Is this a line end? If yes, we're also done, after making
19706 sure that a non-default face is extended up to the right
19707 margin of the window. */
19708 if (ITERATOR_AT_END_OF_LINE_P (it))
19710 int used_before = row->used[TEXT_AREA];
19712 row->ends_in_newline_from_string_p = STRINGP (it->object);
19714 /* Add a space at the end of the line that is used to
19715 display the cursor there. */
19716 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19717 append_space_for_newline (it, 0);
19719 /* Extend the face to the end of the line. */
19720 extend_face_to_end_of_line (it);
19722 /* Make sure we have the position. */
19723 if (used_before == 0)
19724 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
19726 /* Record the position of the newline, for use in
19727 find_row_edges. */
19728 it->eol_pos = it->current.pos;
19730 /* Consume the line end. This skips over invisible lines. */
19731 set_iterator_to_next (it, 1);
19732 it->continuation_lines_width = 0;
19733 break;
19736 /* Proceed with next display element. Note that this skips
19737 over lines invisible because of selective display. */
19738 set_iterator_to_next (it, 1);
19740 /* If we truncate lines, we are done when the last displayed
19741 glyphs reach past the right margin of the window. */
19742 if (it->line_wrap == TRUNCATE
19743 && (FRAME_WINDOW_P (it->f) && WINDOW_RIGHT_FRINGE_WIDTH (it->w)
19744 ? (it->current_x >= it->last_visible_x)
19745 : (it->current_x > it->last_visible_x)))
19747 /* Maybe add truncation glyphs. */
19748 if (!FRAME_WINDOW_P (it->f)
19749 || (row->reversed_p
19750 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19751 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
19753 int i, n;
19755 if (!row->reversed_p)
19757 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
19758 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
19759 break;
19761 else
19763 for (i = 0; i < row->used[TEXT_AREA]; i++)
19764 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
19765 break;
19766 /* Remove any padding glyphs at the front of ROW, to
19767 make room for the truncation glyphs we will be
19768 adding below. The loop below always inserts at
19769 least one truncation glyph, so also remove the
19770 last glyph added to ROW. */
19771 unproduce_glyphs (it, i + 1);
19772 /* Adjust i for the loop below. */
19773 i = row->used[TEXT_AREA] - (i + 1);
19776 it->current_x = x_before;
19777 if (!FRAME_WINDOW_P (it->f))
19779 for (n = row->used[TEXT_AREA]; i < n; ++i)
19781 row->used[TEXT_AREA] = i;
19782 produce_special_glyphs (it, IT_TRUNCATION);
19785 else
19787 row->used[TEXT_AREA] = i;
19788 produce_special_glyphs (it, IT_TRUNCATION);
19791 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19793 /* Don't truncate if we can overflow newline into fringe. */
19794 if (!get_next_display_element (it))
19796 it->continuation_lines_width = 0;
19797 row->ends_at_zv_p = 1;
19798 row->exact_window_width_line_p = 1;
19799 break;
19801 if (ITERATOR_AT_END_OF_LINE_P (it))
19803 row->exact_window_width_line_p = 1;
19804 goto at_end_of_line;
19806 it->current_x = x_before;
19809 row->truncated_on_right_p = 1;
19810 it->continuation_lines_width = 0;
19811 reseat_at_next_visible_line_start (it, 0);
19812 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
19813 it->hpos = hpos_before;
19814 break;
19818 if (wrap_data)
19819 bidi_unshelve_cache (wrap_data, 1);
19821 /* If line is not empty and hscrolled, maybe insert truncation glyphs
19822 at the left window margin. */
19823 if (it->first_visible_x
19824 && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
19826 if (!FRAME_WINDOW_P (it->f)
19827 || (row->reversed_p
19828 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
19829 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
19830 insert_left_trunc_glyphs (it);
19831 row->truncated_on_left_p = 1;
19834 /* Remember the position at which this line ends.
19836 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
19837 cannot be before the call to find_row_edges below, since that is
19838 where these positions are determined. */
19839 row->end = it->current;
19840 if (!it->bidi_p)
19842 row->minpos = row->start.pos;
19843 row->maxpos = row->end.pos;
19845 else
19847 /* ROW->minpos and ROW->maxpos must be the smallest and
19848 `1 + the largest' buffer positions in ROW. But if ROW was
19849 bidi-reordered, these two positions can be anywhere in the
19850 row, so we must determine them now. */
19851 find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
19854 /* If the start of this line is the overlay arrow-position, then
19855 mark this glyph row as the one containing the overlay arrow.
19856 This is clearly a mess with variable size fonts. It would be
19857 better to let it be displayed like cursors under X. */
19858 if ((MATRIX_ROW_DISPLAYS_TEXT_P (row) || !overlay_arrow_seen)
19859 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
19860 !NILP (overlay_arrow_string)))
19862 /* Overlay arrow in window redisplay is a fringe bitmap. */
19863 if (STRINGP (overlay_arrow_string))
19865 struct glyph_row *arrow_row
19866 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
19867 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
19868 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
19869 struct glyph *p = row->glyphs[TEXT_AREA];
19870 struct glyph *p2, *end;
19872 /* Copy the arrow glyphs. */
19873 while (glyph < arrow_end)
19874 *p++ = *glyph++;
19876 /* Throw away padding glyphs. */
19877 p2 = p;
19878 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
19879 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
19880 ++p2;
19881 if (p2 > p)
19883 while (p2 < end)
19884 *p++ = *p2++;
19885 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
19888 else
19890 eassert (INTEGERP (overlay_arrow_string));
19891 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
19893 overlay_arrow_seen = 1;
19896 /* Highlight trailing whitespace. */
19897 if (!NILP (Vshow_trailing_whitespace))
19898 highlight_trailing_whitespace (it->f, it->glyph_row);
19900 /* Compute pixel dimensions of this line. */
19901 compute_line_metrics (it);
19903 /* Implementation note: No changes in the glyphs of ROW or in their
19904 faces can be done past this point, because compute_line_metrics
19905 computes ROW's hash value and stores it within the glyph_row
19906 structure. */
19908 /* Record whether this row ends inside an ellipsis. */
19909 row->ends_in_ellipsis_p
19910 = (it->method == GET_FROM_DISPLAY_VECTOR
19911 && it->ellipsis_p);
19913 /* Save fringe bitmaps in this row. */
19914 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
19915 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
19916 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
19917 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
19919 it->left_user_fringe_bitmap = 0;
19920 it->left_user_fringe_face_id = 0;
19921 it->right_user_fringe_bitmap = 0;
19922 it->right_user_fringe_face_id = 0;
19924 /* Maybe set the cursor. */
19925 cvpos = it->w->cursor.vpos;
19926 if ((cvpos < 0
19927 /* In bidi-reordered rows, keep checking for proper cursor
19928 position even if one has been found already, because buffer
19929 positions in such rows change non-linearly with ROW->VPOS,
19930 when a line is continued. One exception: when we are at ZV,
19931 display cursor on the first suitable glyph row, since all
19932 the empty rows after that also have their position set to ZV. */
19933 /* FIXME: Revisit this when glyph ``spilling'' in continuation
19934 lines' rows is implemented for bidi-reordered rows. */
19935 || (it->bidi_p
19936 && !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
19937 && PT >= MATRIX_ROW_START_CHARPOS (row)
19938 && PT <= MATRIX_ROW_END_CHARPOS (row)
19939 && cursor_row_p (row))
19940 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
19942 /* Prepare for the next line. This line starts horizontally at (X
19943 HPOS) = (0 0). Vertical positions are incremented. As a
19944 convenience for the caller, IT->glyph_row is set to the next
19945 row to be used. */
19946 it->current_x = it->hpos = 0;
19947 it->current_y += row->height;
19948 SET_TEXT_POS (it->eol_pos, 0, 0);
19949 ++it->vpos;
19950 ++it->glyph_row;
19951 /* The next row should by default use the same value of the
19952 reversed_p flag as this one. set_iterator_to_next decides when
19953 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
19954 the flag accordingly. */
19955 if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
19956 it->glyph_row->reversed_p = row->reversed_p;
19957 it->start = row->end;
19958 return MATRIX_ROW_DISPLAYS_TEXT_P (row);
19960 #undef RECORD_MAX_MIN_POS
19963 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,
19964 Scurrent_bidi_paragraph_direction, 0, 1, 0,
19965 doc: /* Return paragraph direction at point in BUFFER.
19966 Value is either `left-to-right' or `right-to-left'.
19967 If BUFFER is omitted or nil, it defaults to the current buffer.
19969 Paragraph direction determines how the text in the paragraph is displayed.
19970 In left-to-right paragraphs, text begins at the left margin of the window
19971 and the reading direction is generally left to right. In right-to-left
19972 paragraphs, text begins at the right margin and is read from right to left.
19974 See also `bidi-paragraph-direction'. */)
19975 (Lisp_Object buffer)
19977 struct buffer *buf = current_buffer;
19978 struct buffer *old = buf;
19980 if (! NILP (buffer))
19982 CHECK_BUFFER (buffer);
19983 buf = XBUFFER (buffer);
19986 if (NILP (BVAR (buf, bidi_display_reordering))
19987 || NILP (BVAR (buf, enable_multibyte_characters))
19988 /* When we are loading loadup.el, the character property tables
19989 needed for bidi iteration are not yet available. */
19990 || !NILP (Vpurify_flag))
19991 return Qleft_to_right;
19992 else if (!NILP (BVAR (buf, bidi_paragraph_direction)))
19993 return BVAR (buf, bidi_paragraph_direction);
19994 else
19996 /* Determine the direction from buffer text. We could try to
19997 use current_matrix if it is up to date, but this seems fast
19998 enough as it is. */
19999 struct bidi_it itb;
20000 ptrdiff_t pos = BUF_PT (buf);
20001 ptrdiff_t bytepos = BUF_PT_BYTE (buf);
20002 int c;
20003 void *itb_data = bidi_shelve_cache ();
20005 set_buffer_temp (buf);
20006 /* bidi_paragraph_init finds the base direction of the paragraph
20007 by searching forward from paragraph start. We need the base
20008 direction of the current or _previous_ paragraph, so we need
20009 to make sure we are within that paragraph. To that end, find
20010 the previous non-empty line. */
20011 if (pos >= ZV && pos > BEGV)
20012 DEC_BOTH (pos, bytepos);
20013 if (fast_looking_at (build_string ("[\f\t ]*\n"),
20014 pos, bytepos, ZV, ZV_BYTE, Qnil) > 0)
20016 while ((c = FETCH_BYTE (bytepos)) == '\n'
20017 || c == ' ' || c == '\t' || c == '\f')
20019 if (bytepos <= BEGV_BYTE)
20020 break;
20021 bytepos--;
20022 pos--;
20024 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos)))
20025 bytepos--;
20027 bidi_init_it (pos, bytepos, FRAME_WINDOW_P (SELECTED_FRAME ()), &itb);
20028 itb.paragraph_dir = NEUTRAL_DIR;
20029 itb.string.s = NULL;
20030 itb.string.lstring = Qnil;
20031 itb.string.bufpos = 0;
20032 itb.string.unibyte = 0;
20033 /* We have no window to use here for ignoring window-specific
20034 overlays. Using NULL for window pointer will cause
20035 compute_display_string_pos to use the current buffer. */
20036 itb.w = NULL;
20037 bidi_paragraph_init (NEUTRAL_DIR, &itb, 1);
20038 bidi_unshelve_cache (itb_data, 0);
20039 set_buffer_temp (old);
20040 switch (itb.paragraph_dir)
20042 case L2R:
20043 return Qleft_to_right;
20044 break;
20045 case R2L:
20046 return Qright_to_left;
20047 break;
20048 default:
20049 emacs_abort ();
20054 DEFUN ("move-point-visually", Fmove_point_visually,
20055 Smove_point_visually, 1, 1, 0,
20056 doc: /* Move point in the visual order in the specified DIRECTION.
20057 DIRECTION can be 1, meaning move to the right, or -1, which moves to the
20058 left.
20060 Value is the new character position of point. */)
20061 (Lisp_Object direction)
20063 struct window *w = XWINDOW (selected_window);
20064 struct buffer *b = NULL;
20065 struct glyph_row *row;
20066 int dir;
20067 Lisp_Object paragraph_dir;
20069 #define ROW_GLYPH_NEWLINE_P(ROW,GLYPH) \
20070 (!(ROW)->continued_p \
20071 && INTEGERP ((GLYPH)->object) \
20072 && (GLYPH)->type == CHAR_GLYPH \
20073 && (GLYPH)->u.ch == ' ' \
20074 && (GLYPH)->charpos >= 0 \
20075 && !(GLYPH)->avoid_cursor_p)
20077 CHECK_NUMBER (direction);
20078 dir = XINT (direction);
20079 if (dir > 0)
20080 dir = 1;
20081 else
20082 dir = -1;
20084 if (BUFFERP (w->contents))
20085 b = XBUFFER (w->contents);
20087 /* If current matrix is up-to-date, we can use the information
20088 recorded in the glyphs, at least as long as the goal is on the
20089 screen. */
20090 if (w->window_end_valid
20091 && !windows_or_buffers_changed
20092 && b
20093 && !b->clip_changed
20094 && !b->prevent_redisplay_optimizations_p
20095 && w->last_modified >= BUF_MODIFF (b)
20096 && w->last_overlay_modified >= BUF_OVERLAY_MODIFF (b)
20097 && w->cursor.vpos >= 0
20098 && w->cursor.vpos < w->current_matrix->nrows
20099 && (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos))->enabled_p)
20101 struct glyph *g = row->glyphs[TEXT_AREA];
20102 struct glyph *e = dir > 0 ? g + row->used[TEXT_AREA] : g - 1;
20103 struct glyph *gpt = g + w->cursor.hpos;
20105 for (g = gpt + dir; (dir > 0 ? g < e : g > e); g += dir)
20107 if (BUFFERP (g->object) && g->charpos != PT)
20109 SET_PT (g->charpos);
20110 w->cursor.vpos = -1;
20111 return make_number (PT);
20113 else if (!INTEGERP (g->object) && g->object != gpt->object)
20115 ptrdiff_t new_pos;
20117 if (BUFFERP (gpt->object))
20119 new_pos = PT;
20120 if ((gpt->resolved_level - row->reversed_p) % 2 == 0)
20121 new_pos += (row->reversed_p ? -dir : dir);
20122 else
20123 new_pos -= (row->reversed_p ? -dir : dir);;
20125 else if (BUFFERP (g->object))
20126 new_pos = g->charpos;
20127 else
20128 break;
20129 SET_PT (new_pos);
20130 w->cursor.vpos = -1;
20131 return make_number (PT);
20133 else if (ROW_GLYPH_NEWLINE_P (row, g))
20135 /* Glyphs inserted at the end of a non-empty line for
20136 positioning the cursor have zero charpos, so we must
20137 deduce the value of point by other means. */
20138 if (g->charpos > 0)
20139 SET_PT (g->charpos);
20140 else if (row->ends_at_zv_p && PT != ZV)
20141 SET_PT (ZV);
20142 else if (PT != MATRIX_ROW_END_CHARPOS (row) - 1)
20143 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
20144 else
20145 break;
20146 w->cursor.vpos = -1;
20147 return make_number (PT);
20150 if (g == e || INTEGERP (g->object))
20152 if (row->truncated_on_left_p || row->truncated_on_right_p)
20153 goto simulate_display;
20154 if (!row->reversed_p)
20155 row += dir;
20156 else
20157 row -= dir;
20158 if (row < MATRIX_FIRST_TEXT_ROW (w->current_matrix)
20159 || row > MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
20160 goto simulate_display;
20162 if (dir > 0)
20164 if (row->reversed_p && !row->continued_p)
20166 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
20167 w->cursor.vpos = -1;
20168 return make_number (PT);
20170 g = row->glyphs[TEXT_AREA];
20171 e = g + row->used[TEXT_AREA];
20172 for ( ; g < e; g++)
20174 if (BUFFERP (g->object)
20175 /* Empty lines have only one glyph, which stands
20176 for the newline, and whose charpos is the
20177 buffer position of the newline. */
20178 || ROW_GLYPH_NEWLINE_P (row, g)
20179 /* When the buffer ends in a newline, the line at
20180 EOB also has one glyph, but its charpos is -1. */
20181 || (row->ends_at_zv_p
20182 && !row->reversed_p
20183 && INTEGERP (g->object)
20184 && g->type == CHAR_GLYPH
20185 && g->u.ch == ' '))
20187 if (g->charpos > 0)
20188 SET_PT (g->charpos);
20189 else if (!row->reversed_p
20190 && row->ends_at_zv_p
20191 && PT != ZV)
20192 SET_PT (ZV);
20193 else
20194 continue;
20195 w->cursor.vpos = -1;
20196 return make_number (PT);
20200 else
20202 if (!row->reversed_p && !row->continued_p)
20204 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
20205 w->cursor.vpos = -1;
20206 return make_number (PT);
20208 e = row->glyphs[TEXT_AREA];
20209 g = e + row->used[TEXT_AREA] - 1;
20210 for ( ; g >= e; g--)
20212 if (BUFFERP (g->object)
20213 || (ROW_GLYPH_NEWLINE_P (row, g)
20214 && g->charpos > 0)
20215 /* Empty R2L lines on GUI frames have the buffer
20216 position of the newline stored in the stretch
20217 glyph. */
20218 || g->type == STRETCH_GLYPH
20219 || (row->ends_at_zv_p
20220 && row->reversed_p
20221 && INTEGERP (g->object)
20222 && g->type == CHAR_GLYPH
20223 && g->u.ch == ' '))
20225 if (g->charpos > 0)
20226 SET_PT (g->charpos);
20227 else if (row->reversed_p
20228 && row->ends_at_zv_p
20229 && PT != ZV)
20230 SET_PT (ZV);
20231 else
20232 continue;
20233 w->cursor.vpos = -1;
20234 return make_number (PT);
20241 simulate_display:
20243 /* If we wind up here, we failed to move by using the glyphs, so we
20244 need to simulate display instead. */
20246 if (b)
20247 paragraph_dir = Fcurrent_bidi_paragraph_direction (w->contents);
20248 else
20249 paragraph_dir = Qleft_to_right;
20250 if (EQ (paragraph_dir, Qright_to_left))
20251 dir = -dir;
20252 if (PT <= BEGV && dir < 0)
20253 xsignal0 (Qbeginning_of_buffer);
20254 else if (PT >= ZV && dir > 0)
20255 xsignal0 (Qend_of_buffer);
20256 else
20258 struct text_pos pt;
20259 struct it it;
20260 int pt_x, target_x, pixel_width, pt_vpos;
20261 bool at_eol_p;
20262 bool overshoot_expected = false;
20263 bool target_is_eol_p = false;
20265 /* Setup the arena. */
20266 SET_TEXT_POS (pt, PT, PT_BYTE);
20267 start_display (&it, w, pt);
20269 if (it.cmp_it.id < 0
20270 && it.method == GET_FROM_STRING
20271 && it.area == TEXT_AREA
20272 && it.string_from_display_prop_p
20273 && (it.sp > 0 && it.stack[it.sp - 1].method == GET_FROM_BUFFER))
20274 overshoot_expected = true;
20276 /* Find the X coordinate of point. We start from the beginning
20277 of this or previous line to make sure we are before point in
20278 the logical order (since the move_it_* functions can only
20279 move forward). */
20280 reseat_at_previous_visible_line_start (&it);
20281 it.current_x = it.hpos = it.current_y = it.vpos = 0;
20282 if (IT_CHARPOS (it) != PT)
20283 move_it_to (&it, overshoot_expected ? PT - 1 : PT,
20284 -1, -1, -1, MOVE_TO_POS);
20285 pt_x = it.current_x;
20286 pt_vpos = it.vpos;
20287 if (dir > 0 || overshoot_expected)
20289 struct glyph_row *row = it.glyph_row;
20291 /* When point is at beginning of line, we don't have
20292 information about the glyph there loaded into struct
20293 it. Calling get_next_display_element fixes that. */
20294 if (pt_x == 0)
20295 get_next_display_element (&it);
20296 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
20297 it.glyph_row = NULL;
20298 PRODUCE_GLYPHS (&it); /* compute it.pixel_width */
20299 it.glyph_row = row;
20300 /* PRODUCE_GLYPHS advances it.current_x, so we must restore
20301 it, lest it will become out of sync with it's buffer
20302 position. */
20303 it.current_x = pt_x;
20305 else
20306 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
20307 pixel_width = it.pixel_width;
20308 if (overshoot_expected && at_eol_p)
20309 pixel_width = 0;
20310 else if (pixel_width <= 0)
20311 pixel_width = 1;
20313 /* If there's a display string at point, we are actually at the
20314 glyph to the left of point, so we need to correct the X
20315 coordinate. */
20316 if (overshoot_expected)
20317 pt_x += pixel_width;
20319 /* Compute target X coordinate, either to the left or to the
20320 right of point. On TTY frames, all characters have the same
20321 pixel width of 1, so we can use that. On GUI frames we don't
20322 have an easy way of getting at the pixel width of the
20323 character to the left of point, so we use a different method
20324 of getting to that place. */
20325 if (dir > 0)
20326 target_x = pt_x + pixel_width;
20327 else
20328 target_x = pt_x - (!FRAME_WINDOW_P (it.f)) * pixel_width;
20330 /* Target X coordinate could be one line above or below the line
20331 of point, in which case we need to adjust the target X
20332 coordinate. Also, if moving to the left, we need to begin at
20333 the left edge of the point's screen line. */
20334 if (dir < 0)
20336 if (pt_x > 0)
20338 start_display (&it, w, pt);
20339 reseat_at_previous_visible_line_start (&it);
20340 it.current_x = it.current_y = it.hpos = 0;
20341 if (pt_vpos != 0)
20342 move_it_by_lines (&it, pt_vpos);
20344 else
20346 move_it_by_lines (&it, -1);
20347 target_x = it.last_visible_x - !FRAME_WINDOW_P (it.f);
20348 target_is_eol_p = true;
20351 else
20353 if (at_eol_p
20354 || (target_x >= it.last_visible_x
20355 && it.line_wrap != TRUNCATE))
20357 if (pt_x > 0)
20358 move_it_by_lines (&it, 0);
20359 move_it_by_lines (&it, 1);
20360 target_x = 0;
20364 /* Move to the target X coordinate. */
20365 #ifdef HAVE_WINDOW_SYSTEM
20366 /* On GUI frames, as we don't know the X coordinate of the
20367 character to the left of point, moving point to the left
20368 requires walking, one grapheme cluster at a time, until we
20369 find ourself at a place immediately to the left of the
20370 character at point. */
20371 if (FRAME_WINDOW_P (it.f) && dir < 0)
20373 struct text_pos new_pos = it.current.pos;
20374 enum move_it_result rc = MOVE_X_REACHED;
20376 while (it.current_x + it.pixel_width <= target_x
20377 && rc == MOVE_X_REACHED)
20379 int new_x = it.current_x + it.pixel_width;
20381 new_pos = it.current.pos;
20382 if (new_x == it.current_x)
20383 new_x++;
20384 rc = move_it_in_display_line_to (&it, ZV, new_x,
20385 MOVE_TO_POS | MOVE_TO_X);
20386 if (ITERATOR_AT_END_OF_LINE_P (&it) && !target_is_eol_p)
20387 break;
20389 /* If we ended up on a composed character inside
20390 bidi-reordered text (e.g., Hebrew text with diacriticals),
20391 the iterator gives us the buffer position of the last (in
20392 logical order) character of the composed grapheme cluster,
20393 which is not what we want. So we cheat: we compute the
20394 character position of the character that follows (in the
20395 logical order) the one where the above loop stopped. That
20396 character will appear on display to the left of point. */
20397 if (it.bidi_p
20398 && it.bidi_it.scan_dir == -1
20399 && new_pos.charpos - IT_CHARPOS (it) > 1)
20401 new_pos.charpos = IT_CHARPOS (it) + 1;
20402 new_pos.bytepos = CHAR_TO_BYTE (new_pos.charpos);
20404 it.current.pos = new_pos;
20406 else
20407 #endif
20408 if (it.current_x != target_x)
20409 move_it_in_display_line_to (&it, ZV, target_x, MOVE_TO_POS | MOVE_TO_X);
20411 /* When lines are truncated, the above loop will stop at the
20412 window edge. But we want to get to the end of line, even if
20413 it is beyond the window edge; automatic hscroll will then
20414 scroll the window to show point as appropriate. */
20415 if (target_is_eol_p && it.line_wrap == TRUNCATE
20416 && get_next_display_element (&it))
20418 struct text_pos new_pos = it.current.pos;
20420 while (!ITERATOR_AT_END_OF_LINE_P (&it))
20422 set_iterator_to_next (&it, 0);
20423 if (it.method == GET_FROM_BUFFER)
20424 new_pos = it.current.pos;
20425 if (!get_next_display_element (&it))
20426 break;
20429 it.current.pos = new_pos;
20432 /* If we ended up in a display string that covers point, move to
20433 buffer position to the right in the visual order. */
20434 if (dir > 0)
20436 while (IT_CHARPOS (it) == PT)
20438 set_iterator_to_next (&it, 0);
20439 if (!get_next_display_element (&it))
20440 break;
20444 /* Move point to that position. */
20445 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
20448 return make_number (PT);
20450 #undef ROW_GLYPH_NEWLINE_P
20454 /***********************************************************************
20455 Menu Bar
20456 ***********************************************************************/
20458 /* Redisplay the menu bar in the frame for window W.
20460 The menu bar of X frames that don't have X toolkit support is
20461 displayed in a special window W->frame->menu_bar_window.
20463 The menu bar of terminal frames is treated specially as far as
20464 glyph matrices are concerned. Menu bar lines are not part of
20465 windows, so the update is done directly on the frame matrix rows
20466 for the menu bar. */
20468 static void
20469 display_menu_bar (struct window *w)
20471 struct frame *f = XFRAME (WINDOW_FRAME (w));
20472 struct it it;
20473 Lisp_Object items;
20474 int i;
20476 /* Don't do all this for graphical frames. */
20477 #ifdef HAVE_NTGUI
20478 if (FRAME_W32_P (f))
20479 return;
20480 #endif
20481 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
20482 if (FRAME_X_P (f))
20483 return;
20484 #endif
20486 #ifdef HAVE_NS
20487 if (FRAME_NS_P (f))
20488 return;
20489 #endif /* HAVE_NS */
20491 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
20492 eassert (!FRAME_WINDOW_P (f));
20493 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
20494 it.first_visible_x = 0;
20495 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
20496 #elif defined (HAVE_X_WINDOWS) /* X without toolkit. */
20497 if (FRAME_WINDOW_P (f))
20499 /* Menu bar lines are displayed in the desired matrix of the
20500 dummy window menu_bar_window. */
20501 struct window *menu_w;
20502 menu_w = XWINDOW (f->menu_bar_window);
20503 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
20504 MENU_FACE_ID);
20505 it.first_visible_x = 0;
20506 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
20508 else
20509 #endif /* not USE_X_TOOLKIT and not USE_GTK */
20511 /* This is a TTY frame, i.e. character hpos/vpos are used as
20512 pixel x/y. */
20513 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
20514 MENU_FACE_ID);
20515 it.first_visible_x = 0;
20516 it.last_visible_x = FRAME_COLS (f);
20519 /* FIXME: This should be controlled by a user option. See the
20520 comments in redisplay_tool_bar and display_mode_line about
20521 this. */
20522 it.paragraph_embedding = L2R;
20524 /* Clear all rows of the menu bar. */
20525 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
20527 struct glyph_row *row = it.glyph_row + i;
20528 clear_glyph_row (row);
20529 row->enabled_p = 1;
20530 row->full_width_p = 1;
20533 /* Display all items of the menu bar. */
20534 items = FRAME_MENU_BAR_ITEMS (it.f);
20535 for (i = 0; i < ASIZE (items); i += 4)
20537 Lisp_Object string;
20539 /* Stop at nil string. */
20540 string = AREF (items, i + 1);
20541 if (NILP (string))
20542 break;
20544 /* Remember where item was displayed. */
20545 ASET (items, i + 3, make_number (it.hpos));
20547 /* Display the item, pad with one space. */
20548 if (it.current_x < it.last_visible_x)
20549 display_string (NULL, string, Qnil, 0, 0, &it,
20550 SCHARS (string) + 1, 0, 0, -1);
20553 /* Fill out the line with spaces. */
20554 if (it.current_x < it.last_visible_x)
20555 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
20557 /* Compute the total height of the lines. */
20558 compute_line_metrics (&it);
20563 /***********************************************************************
20564 Mode Line
20565 ***********************************************************************/
20567 /* Redisplay mode lines in the window tree whose root is WINDOW. If
20568 FORCE is non-zero, redisplay mode lines unconditionally.
20569 Otherwise, redisplay only mode lines that are garbaged. Value is
20570 the number of windows whose mode lines were redisplayed. */
20572 static int
20573 redisplay_mode_lines (Lisp_Object window, int force)
20575 int nwindows = 0;
20577 while (!NILP (window))
20579 struct window *w = XWINDOW (window);
20581 if (WINDOWP (w->contents))
20582 nwindows += redisplay_mode_lines (w->contents, force);
20583 else if (force
20584 || FRAME_GARBAGED_P (XFRAME (w->frame))
20585 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
20587 struct text_pos lpoint;
20588 struct buffer *old = current_buffer;
20590 /* Set the window's buffer for the mode line display. */
20591 SET_TEXT_POS (lpoint, PT, PT_BYTE);
20592 set_buffer_internal_1 (XBUFFER (w->contents));
20594 /* Point refers normally to the selected window. For any
20595 other window, set up appropriate value. */
20596 if (!EQ (window, selected_window))
20598 struct text_pos pt;
20600 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
20601 if (CHARPOS (pt) < BEGV)
20602 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
20603 else if (CHARPOS (pt) > (ZV - 1))
20604 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
20605 else
20606 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
20609 /* Display mode lines. */
20610 clear_glyph_matrix (w->desired_matrix);
20611 if (display_mode_lines (w))
20613 ++nwindows;
20614 w->must_be_updated_p = 1;
20617 /* Restore old settings. */
20618 set_buffer_internal_1 (old);
20619 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
20622 window = w->next;
20625 return nwindows;
20629 /* Display the mode and/or header line of window W. Value is the
20630 sum number of mode lines and header lines displayed. */
20632 static int
20633 display_mode_lines (struct window *w)
20635 Lisp_Object old_selected_window = selected_window;
20636 Lisp_Object old_selected_frame = selected_frame;
20637 Lisp_Object new_frame = w->frame;
20638 Lisp_Object old_frame_selected_window = XFRAME (new_frame)->selected_window;
20639 int n = 0;
20641 selected_frame = new_frame;
20642 /* FIXME: If we were to allow the mode-line's computation changing the buffer
20643 or window's point, then we'd need select_window_1 here as well. */
20644 XSETWINDOW (selected_window, w);
20645 XFRAME (new_frame)->selected_window = selected_window;
20647 /* These will be set while the mode line specs are processed. */
20648 line_number_displayed = 0;
20649 w->column_number_displayed = -1;
20651 if (WINDOW_WANTS_MODELINE_P (w))
20653 struct window *sel_w = XWINDOW (old_selected_window);
20655 /* Select mode line face based on the real selected window. */
20656 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
20657 BVAR (current_buffer, mode_line_format));
20658 ++n;
20661 if (WINDOW_WANTS_HEADER_LINE_P (w))
20663 display_mode_line (w, HEADER_LINE_FACE_ID,
20664 BVAR (current_buffer, header_line_format));
20665 ++n;
20668 XFRAME (new_frame)->selected_window = old_frame_selected_window;
20669 selected_frame = old_selected_frame;
20670 selected_window = old_selected_window;
20671 return n;
20675 /* Display mode or header line of window W. FACE_ID specifies which
20676 line to display; it is either MODE_LINE_FACE_ID or
20677 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
20678 display. Value is the pixel height of the mode/header line
20679 displayed. */
20681 static int
20682 display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
20684 struct it it;
20685 struct face *face;
20686 ptrdiff_t count = SPECPDL_INDEX ();
20688 init_iterator (&it, w, -1, -1, NULL, face_id);
20689 /* Don't extend on a previously drawn mode-line.
20690 This may happen if called from pos_visible_p. */
20691 it.glyph_row->enabled_p = 0;
20692 prepare_desired_row (it.glyph_row);
20694 it.glyph_row->mode_line_p = 1;
20696 /* FIXME: This should be controlled by a user option. But
20697 supporting such an option is not trivial, since the mode line is
20698 made up of many separate strings. */
20699 it.paragraph_embedding = L2R;
20701 record_unwind_protect (unwind_format_mode_line,
20702 format_mode_line_unwind_data (NULL, NULL, Qnil, 0));
20704 mode_line_target = MODE_LINE_DISPLAY;
20706 /* Temporarily make frame's keyboard the current kboard so that
20707 kboard-local variables in the mode_line_format will get the right
20708 values. */
20709 push_kboard (FRAME_KBOARD (it.f));
20710 record_unwind_save_match_data ();
20711 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
20712 pop_kboard ();
20714 unbind_to (count, Qnil);
20716 /* Fill up with spaces. */
20717 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
20719 compute_line_metrics (&it);
20720 it.glyph_row->full_width_p = 1;
20721 it.glyph_row->continued_p = 0;
20722 it.glyph_row->truncated_on_left_p = 0;
20723 it.glyph_row->truncated_on_right_p = 0;
20725 /* Make a 3D mode-line have a shadow at its right end. */
20726 face = FACE_FROM_ID (it.f, face_id);
20727 extend_face_to_end_of_line (&it);
20728 if (face->box != FACE_NO_BOX)
20730 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
20731 + it.glyph_row->used[TEXT_AREA] - 1);
20732 last->right_box_line_p = 1;
20735 return it.glyph_row->height;
20738 /* Move element ELT in LIST to the front of LIST.
20739 Return the updated list. */
20741 static Lisp_Object
20742 move_elt_to_front (Lisp_Object elt, Lisp_Object list)
20744 register Lisp_Object tail, prev;
20745 register Lisp_Object tem;
20747 tail = list;
20748 prev = Qnil;
20749 while (CONSP (tail))
20751 tem = XCAR (tail);
20753 if (EQ (elt, tem))
20755 /* Splice out the link TAIL. */
20756 if (NILP (prev))
20757 list = XCDR (tail);
20758 else
20759 Fsetcdr (prev, XCDR (tail));
20761 /* Now make it the first. */
20762 Fsetcdr (tail, list);
20763 return tail;
20765 else
20766 prev = tail;
20767 tail = XCDR (tail);
20768 QUIT;
20771 /* Not found--return unchanged LIST. */
20772 return list;
20775 /* Contribute ELT to the mode line for window IT->w. How it
20776 translates into text depends on its data type.
20778 IT describes the display environment in which we display, as usual.
20780 DEPTH is the depth in recursion. It is used to prevent
20781 infinite recursion here.
20783 FIELD_WIDTH is the number of characters the display of ELT should
20784 occupy in the mode line, and PRECISION is the maximum number of
20785 characters to display from ELT's representation. See
20786 display_string for details.
20788 Returns the hpos of the end of the text generated by ELT.
20790 PROPS is a property list to add to any string we encounter.
20792 If RISKY is nonzero, remove (disregard) any properties in any string
20793 we encounter, and ignore :eval and :propertize.
20795 The global variable `mode_line_target' determines whether the
20796 output is passed to `store_mode_line_noprop',
20797 `store_mode_line_string', or `display_string'. */
20799 static int
20800 display_mode_element (struct it *it, int depth, int field_width, int precision,
20801 Lisp_Object elt, Lisp_Object props, int risky)
20803 int n = 0, field, prec;
20804 int literal = 0;
20806 tail_recurse:
20807 if (depth > 100)
20808 elt = build_string ("*too-deep*");
20810 depth++;
20812 switch (XTYPE (elt))
20814 case Lisp_String:
20816 /* A string: output it and check for %-constructs within it. */
20817 unsigned char c;
20818 ptrdiff_t offset = 0;
20820 if (SCHARS (elt) > 0
20821 && (!NILP (props) || risky))
20823 Lisp_Object oprops, aelt;
20824 oprops = Ftext_properties_at (make_number (0), elt);
20826 /* If the starting string's properties are not what
20827 we want, translate the string. Also, if the string
20828 is risky, do that anyway. */
20830 if (NILP (Fequal (props, oprops)) || risky)
20832 /* If the starting string has properties,
20833 merge the specified ones onto the existing ones. */
20834 if (! NILP (oprops) && !risky)
20836 Lisp_Object tem;
20838 oprops = Fcopy_sequence (oprops);
20839 tem = props;
20840 while (CONSP (tem))
20842 oprops = Fplist_put (oprops, XCAR (tem),
20843 XCAR (XCDR (tem)));
20844 tem = XCDR (XCDR (tem));
20846 props = oprops;
20849 aelt = Fassoc (elt, mode_line_proptrans_alist);
20850 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
20852 /* AELT is what we want. Move it to the front
20853 without consing. */
20854 elt = XCAR (aelt);
20855 mode_line_proptrans_alist
20856 = move_elt_to_front (aelt, mode_line_proptrans_alist);
20858 else
20860 Lisp_Object tem;
20862 /* If AELT has the wrong props, it is useless.
20863 so get rid of it. */
20864 if (! NILP (aelt))
20865 mode_line_proptrans_alist
20866 = Fdelq (aelt, mode_line_proptrans_alist);
20868 elt = Fcopy_sequence (elt);
20869 Fset_text_properties (make_number (0), Flength (elt),
20870 props, elt);
20871 /* Add this item to mode_line_proptrans_alist. */
20872 mode_line_proptrans_alist
20873 = Fcons (Fcons (elt, props),
20874 mode_line_proptrans_alist);
20875 /* Truncate mode_line_proptrans_alist
20876 to at most 50 elements. */
20877 tem = Fnthcdr (make_number (50),
20878 mode_line_proptrans_alist);
20879 if (! NILP (tem))
20880 XSETCDR (tem, Qnil);
20885 offset = 0;
20887 if (literal)
20889 prec = precision - n;
20890 switch (mode_line_target)
20892 case MODE_LINE_NOPROP:
20893 case MODE_LINE_TITLE:
20894 n += store_mode_line_noprop (SSDATA (elt), -1, prec);
20895 break;
20896 case MODE_LINE_STRING:
20897 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
20898 break;
20899 case MODE_LINE_DISPLAY:
20900 n += display_string (NULL, elt, Qnil, 0, 0, it,
20901 0, prec, 0, STRING_MULTIBYTE (elt));
20902 break;
20905 break;
20908 /* Handle the non-literal case. */
20910 while ((precision <= 0 || n < precision)
20911 && SREF (elt, offset) != 0
20912 && (mode_line_target != MODE_LINE_DISPLAY
20913 || it->current_x < it->last_visible_x))
20915 ptrdiff_t last_offset = offset;
20917 /* Advance to end of string or next format specifier. */
20918 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
20921 if (offset - 1 != last_offset)
20923 ptrdiff_t nchars, nbytes;
20925 /* Output to end of string or up to '%'. Field width
20926 is length of string. Don't output more than
20927 PRECISION allows us. */
20928 offset--;
20930 prec = c_string_width (SDATA (elt) + last_offset,
20931 offset - last_offset, precision - n,
20932 &nchars, &nbytes);
20934 switch (mode_line_target)
20936 case MODE_LINE_NOPROP:
20937 case MODE_LINE_TITLE:
20938 n += store_mode_line_noprop (SSDATA (elt) + last_offset, 0, prec);
20939 break;
20940 case MODE_LINE_STRING:
20942 ptrdiff_t bytepos = last_offset;
20943 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
20944 ptrdiff_t endpos = (precision <= 0
20945 ? string_byte_to_char (elt, offset)
20946 : charpos + nchars);
20948 n += store_mode_line_string (NULL,
20949 Fsubstring (elt, make_number (charpos),
20950 make_number (endpos)),
20951 0, 0, 0, Qnil);
20953 break;
20954 case MODE_LINE_DISPLAY:
20956 ptrdiff_t bytepos = last_offset;
20957 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
20959 if (precision <= 0)
20960 nchars = string_byte_to_char (elt, offset) - charpos;
20961 n += display_string (NULL, elt, Qnil, 0, charpos,
20962 it, 0, nchars, 0,
20963 STRING_MULTIBYTE (elt));
20965 break;
20968 else /* c == '%' */
20970 ptrdiff_t percent_position = offset;
20972 /* Get the specified minimum width. Zero means
20973 don't pad. */
20974 field = 0;
20975 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
20976 field = field * 10 + c - '0';
20978 /* Don't pad beyond the total padding allowed. */
20979 if (field_width - n > 0 && field > field_width - n)
20980 field = field_width - n;
20982 /* Note that either PRECISION <= 0 or N < PRECISION. */
20983 prec = precision - n;
20985 if (c == 'M')
20986 n += display_mode_element (it, depth, field, prec,
20987 Vglobal_mode_string, props,
20988 risky);
20989 else if (c != 0)
20991 bool multibyte;
20992 ptrdiff_t bytepos, charpos;
20993 const char *spec;
20994 Lisp_Object string;
20996 bytepos = percent_position;
20997 charpos = (STRING_MULTIBYTE (elt)
20998 ? string_byte_to_char (elt, bytepos)
20999 : bytepos);
21000 spec = decode_mode_spec (it->w, c, field, &string);
21001 multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
21003 switch (mode_line_target)
21005 case MODE_LINE_NOPROP:
21006 case MODE_LINE_TITLE:
21007 n += store_mode_line_noprop (spec, field, prec);
21008 break;
21009 case MODE_LINE_STRING:
21011 Lisp_Object tem = build_string (spec);
21012 props = Ftext_properties_at (make_number (charpos), elt);
21013 /* Should only keep face property in props */
21014 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
21016 break;
21017 case MODE_LINE_DISPLAY:
21019 int nglyphs_before, nwritten;
21021 nglyphs_before = it->glyph_row->used[TEXT_AREA];
21022 nwritten = display_string (spec, string, elt,
21023 charpos, 0, it,
21024 field, prec, 0,
21025 multibyte);
21027 /* Assign to the glyphs written above the
21028 string where the `%x' came from, position
21029 of the `%'. */
21030 if (nwritten > 0)
21032 struct glyph *glyph
21033 = (it->glyph_row->glyphs[TEXT_AREA]
21034 + nglyphs_before);
21035 int i;
21037 for (i = 0; i < nwritten; ++i)
21039 glyph[i].object = elt;
21040 glyph[i].charpos = charpos;
21043 n += nwritten;
21046 break;
21049 else /* c == 0 */
21050 break;
21054 break;
21056 case Lisp_Symbol:
21057 /* A symbol: process the value of the symbol recursively
21058 as if it appeared here directly. Avoid error if symbol void.
21059 Special case: if value of symbol is a string, output the string
21060 literally. */
21062 register Lisp_Object tem;
21064 /* If the variable is not marked as risky to set
21065 then its contents are risky to use. */
21066 if (NILP (Fget (elt, Qrisky_local_variable)))
21067 risky = 1;
21069 tem = Fboundp (elt);
21070 if (!NILP (tem))
21072 tem = Fsymbol_value (elt);
21073 /* If value is a string, output that string literally:
21074 don't check for % within it. */
21075 if (STRINGP (tem))
21076 literal = 1;
21078 if (!EQ (tem, elt))
21080 /* Give up right away for nil or t. */
21081 elt = tem;
21082 goto tail_recurse;
21086 break;
21088 case Lisp_Cons:
21090 register Lisp_Object car, tem;
21092 /* A cons cell: five distinct cases.
21093 If first element is :eval or :propertize, do something special.
21094 If first element is a string or a cons, process all the elements
21095 and effectively concatenate them.
21096 If first element is a negative number, truncate displaying cdr to
21097 at most that many characters. If positive, pad (with spaces)
21098 to at least that many characters.
21099 If first element is a symbol, process the cadr or caddr recursively
21100 according to whether the symbol's value is non-nil or nil. */
21101 car = XCAR (elt);
21102 if (EQ (car, QCeval))
21104 /* An element of the form (:eval FORM) means evaluate FORM
21105 and use the result as mode line elements. */
21107 if (risky)
21108 break;
21110 if (CONSP (XCDR (elt)))
21112 Lisp_Object spec;
21113 spec = safe_eval (XCAR (XCDR (elt)));
21114 n += display_mode_element (it, depth, field_width - n,
21115 precision - n, spec, props,
21116 risky);
21119 else if (EQ (car, QCpropertize))
21121 /* An element of the form (:propertize ELT PROPS...)
21122 means display ELT but applying properties PROPS. */
21124 if (risky)
21125 break;
21127 if (CONSP (XCDR (elt)))
21128 n += display_mode_element (it, depth, field_width - n,
21129 precision - n, XCAR (XCDR (elt)),
21130 XCDR (XCDR (elt)), risky);
21132 else if (SYMBOLP (car))
21134 tem = Fboundp (car);
21135 elt = XCDR (elt);
21136 if (!CONSP (elt))
21137 goto invalid;
21138 /* elt is now the cdr, and we know it is a cons cell.
21139 Use its car if CAR has a non-nil value. */
21140 if (!NILP (tem))
21142 tem = Fsymbol_value (car);
21143 if (!NILP (tem))
21145 elt = XCAR (elt);
21146 goto tail_recurse;
21149 /* Symbol's value is nil (or symbol is unbound)
21150 Get the cddr of the original list
21151 and if possible find the caddr and use that. */
21152 elt = XCDR (elt);
21153 if (NILP (elt))
21154 break;
21155 else if (!CONSP (elt))
21156 goto invalid;
21157 elt = XCAR (elt);
21158 goto tail_recurse;
21160 else if (INTEGERP (car))
21162 register int lim = XINT (car);
21163 elt = XCDR (elt);
21164 if (lim < 0)
21166 /* Negative int means reduce maximum width. */
21167 if (precision <= 0)
21168 precision = -lim;
21169 else
21170 precision = min (precision, -lim);
21172 else if (lim > 0)
21174 /* Padding specified. Don't let it be more than
21175 current maximum. */
21176 if (precision > 0)
21177 lim = min (precision, lim);
21179 /* If that's more padding than already wanted, queue it.
21180 But don't reduce padding already specified even if
21181 that is beyond the current truncation point. */
21182 field_width = max (lim, field_width);
21184 goto tail_recurse;
21186 else if (STRINGP (car) || CONSP (car))
21188 Lisp_Object halftail = elt;
21189 int len = 0;
21191 while (CONSP (elt)
21192 && (precision <= 0 || n < precision))
21194 n += display_mode_element (it, depth,
21195 /* Do padding only after the last
21196 element in the list. */
21197 (! CONSP (XCDR (elt))
21198 ? field_width - n
21199 : 0),
21200 precision - n, XCAR (elt),
21201 props, risky);
21202 elt = XCDR (elt);
21203 len++;
21204 if ((len & 1) == 0)
21205 halftail = XCDR (halftail);
21206 /* Check for cycle. */
21207 if (EQ (halftail, elt))
21208 break;
21212 break;
21214 default:
21215 invalid:
21216 elt = build_string ("*invalid*");
21217 goto tail_recurse;
21220 /* Pad to FIELD_WIDTH. */
21221 if (field_width > 0 && n < field_width)
21223 switch (mode_line_target)
21225 case MODE_LINE_NOPROP:
21226 case MODE_LINE_TITLE:
21227 n += store_mode_line_noprop ("", field_width - n, 0);
21228 break;
21229 case MODE_LINE_STRING:
21230 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
21231 break;
21232 case MODE_LINE_DISPLAY:
21233 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
21234 0, 0, 0);
21235 break;
21239 return n;
21242 /* Store a mode-line string element in mode_line_string_list.
21244 If STRING is non-null, display that C string. Otherwise, the Lisp
21245 string LISP_STRING is displayed.
21247 FIELD_WIDTH is the minimum number of output glyphs to produce.
21248 If STRING has fewer characters than FIELD_WIDTH, pad to the right
21249 with spaces. FIELD_WIDTH <= 0 means don't pad.
21251 PRECISION is the maximum number of characters to output from
21252 STRING. PRECISION <= 0 means don't truncate the string.
21254 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
21255 properties to the string.
21257 PROPS are the properties to add to the string.
21258 The mode_line_string_face face property is always added to the string.
21261 static int
21262 store_mode_line_string (const char *string, Lisp_Object lisp_string, int copy_string,
21263 int field_width, int precision, Lisp_Object props)
21265 ptrdiff_t len;
21266 int n = 0;
21268 if (string != NULL)
21270 len = strlen (string);
21271 if (precision > 0 && len > precision)
21272 len = precision;
21273 lisp_string = make_string (string, len);
21274 if (NILP (props))
21275 props = mode_line_string_face_prop;
21276 else if (!NILP (mode_line_string_face))
21278 Lisp_Object face = Fplist_get (props, Qface);
21279 props = Fcopy_sequence (props);
21280 if (NILP (face))
21281 face = mode_line_string_face;
21282 else
21283 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
21284 props = Fplist_put (props, Qface, face);
21286 Fadd_text_properties (make_number (0), make_number (len),
21287 props, lisp_string);
21289 else
21291 len = XFASTINT (Flength (lisp_string));
21292 if (precision > 0 && len > precision)
21294 len = precision;
21295 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
21296 precision = -1;
21298 if (!NILP (mode_line_string_face))
21300 Lisp_Object face;
21301 if (NILP (props))
21302 props = Ftext_properties_at (make_number (0), lisp_string);
21303 face = Fplist_get (props, Qface);
21304 if (NILP (face))
21305 face = mode_line_string_face;
21306 else
21307 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
21308 props = Fcons (Qface, Fcons (face, Qnil));
21309 if (copy_string)
21310 lisp_string = Fcopy_sequence (lisp_string);
21312 if (!NILP (props))
21313 Fadd_text_properties (make_number (0), make_number (len),
21314 props, lisp_string);
21317 if (len > 0)
21319 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
21320 n += len;
21323 if (field_width > len)
21325 field_width -= len;
21326 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
21327 if (!NILP (props))
21328 Fadd_text_properties (make_number (0), make_number (field_width),
21329 props, lisp_string);
21330 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
21331 n += field_width;
21334 return n;
21338 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
21339 1, 4, 0,
21340 doc: /* Format a string out of a mode line format specification.
21341 First arg FORMAT specifies the mode line format (see `mode-line-format'
21342 for details) to use.
21344 By default, the format is evaluated for the currently selected window.
21346 Optional second arg FACE specifies the face property to put on all
21347 characters for which no face is specified. The value nil means the
21348 default face. The value t means whatever face the window's mode line
21349 currently uses (either `mode-line' or `mode-line-inactive',
21350 depending on whether the window is the selected window or not).
21351 An integer value means the value string has no text
21352 properties.
21354 Optional third and fourth args WINDOW and BUFFER specify the window
21355 and buffer to use as the context for the formatting (defaults
21356 are the selected window and the WINDOW's buffer). */)
21357 (Lisp_Object format, Lisp_Object face,
21358 Lisp_Object window, Lisp_Object buffer)
21360 struct it it;
21361 int len;
21362 struct window *w;
21363 struct buffer *old_buffer = NULL;
21364 int face_id;
21365 int no_props = INTEGERP (face);
21366 ptrdiff_t count = SPECPDL_INDEX ();
21367 Lisp_Object str;
21368 int string_start = 0;
21370 w = decode_any_window (window);
21371 XSETWINDOW (window, w);
21373 if (NILP (buffer))
21374 buffer = w->contents;
21375 CHECK_BUFFER (buffer);
21377 /* Make formatting the modeline a non-op when noninteractive, otherwise
21378 there will be problems later caused by a partially initialized frame. */
21379 if (NILP (format) || noninteractive)
21380 return empty_unibyte_string;
21382 if (no_props)
21383 face = Qnil;
21385 face_id = (NILP (face) || EQ (face, Qdefault)) ? DEFAULT_FACE_ID
21386 : EQ (face, Qt) ? (EQ (window, selected_window)
21387 ? MODE_LINE_FACE_ID : MODE_LINE_INACTIVE_FACE_ID)
21388 : EQ (face, Qmode_line) ? MODE_LINE_FACE_ID
21389 : EQ (face, Qmode_line_inactive) ? MODE_LINE_INACTIVE_FACE_ID
21390 : EQ (face, Qheader_line) ? HEADER_LINE_FACE_ID
21391 : EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID
21392 : DEFAULT_FACE_ID;
21394 old_buffer = current_buffer;
21396 /* Save things including mode_line_proptrans_alist,
21397 and set that to nil so that we don't alter the outer value. */
21398 record_unwind_protect (unwind_format_mode_line,
21399 format_mode_line_unwind_data
21400 (XFRAME (WINDOW_FRAME (w)),
21401 old_buffer, selected_window, 1));
21402 mode_line_proptrans_alist = Qnil;
21404 Fselect_window (window, Qt);
21405 set_buffer_internal_1 (XBUFFER (buffer));
21407 init_iterator (&it, w, -1, -1, NULL, face_id);
21409 if (no_props)
21411 mode_line_target = MODE_LINE_NOPROP;
21412 mode_line_string_face_prop = Qnil;
21413 mode_line_string_list = Qnil;
21414 string_start = MODE_LINE_NOPROP_LEN (0);
21416 else
21418 mode_line_target = MODE_LINE_STRING;
21419 mode_line_string_list = Qnil;
21420 mode_line_string_face = face;
21421 mode_line_string_face_prop
21422 = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil)));
21425 push_kboard (FRAME_KBOARD (it.f));
21426 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
21427 pop_kboard ();
21429 if (no_props)
21431 len = MODE_LINE_NOPROP_LEN (string_start);
21432 str = make_string (mode_line_noprop_buf + string_start, len);
21434 else
21436 mode_line_string_list = Fnreverse (mode_line_string_list);
21437 str = Fmapconcat (intern ("identity"), mode_line_string_list,
21438 empty_unibyte_string);
21441 unbind_to (count, Qnil);
21442 return str;
21445 /* Write a null-terminated, right justified decimal representation of
21446 the positive integer D to BUF using a minimal field width WIDTH. */
21448 static void
21449 pint2str (register char *buf, register int width, register ptrdiff_t d)
21451 register char *p = buf;
21453 if (d <= 0)
21454 *p++ = '0';
21455 else
21457 while (d > 0)
21459 *p++ = d % 10 + '0';
21460 d /= 10;
21464 for (width -= (int) (p - buf); width > 0; --width)
21465 *p++ = ' ';
21466 *p-- = '\0';
21467 while (p > buf)
21469 d = *buf;
21470 *buf++ = *p;
21471 *p-- = d;
21475 /* Write a null-terminated, right justified decimal and "human
21476 readable" representation of the nonnegative integer D to BUF using
21477 a minimal field width WIDTH. D should be smaller than 999.5e24. */
21479 static const char power_letter[] =
21481 0, /* no letter */
21482 'k', /* kilo */
21483 'M', /* mega */
21484 'G', /* giga */
21485 'T', /* tera */
21486 'P', /* peta */
21487 'E', /* exa */
21488 'Z', /* zetta */
21489 'Y' /* yotta */
21492 static void
21493 pint2hrstr (char *buf, int width, ptrdiff_t d)
21495 /* We aim to represent the nonnegative integer D as
21496 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
21497 ptrdiff_t quotient = d;
21498 int remainder = 0;
21499 /* -1 means: do not use TENTHS. */
21500 int tenths = -1;
21501 int exponent = 0;
21503 /* Length of QUOTIENT.TENTHS as a string. */
21504 int length;
21506 char * psuffix;
21507 char * p;
21509 if (quotient >= 1000)
21511 /* Scale to the appropriate EXPONENT. */
21514 remainder = quotient % 1000;
21515 quotient /= 1000;
21516 exponent++;
21518 while (quotient >= 1000);
21520 /* Round to nearest and decide whether to use TENTHS or not. */
21521 if (quotient <= 9)
21523 tenths = remainder / 100;
21524 if (remainder % 100 >= 50)
21526 if (tenths < 9)
21527 tenths++;
21528 else
21530 quotient++;
21531 if (quotient == 10)
21532 tenths = -1;
21533 else
21534 tenths = 0;
21538 else
21539 if (remainder >= 500)
21541 if (quotient < 999)
21542 quotient++;
21543 else
21545 quotient = 1;
21546 exponent++;
21547 tenths = 0;
21552 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
21553 if (tenths == -1 && quotient <= 99)
21554 if (quotient <= 9)
21555 length = 1;
21556 else
21557 length = 2;
21558 else
21559 length = 3;
21560 p = psuffix = buf + max (width, length);
21562 /* Print EXPONENT. */
21563 *psuffix++ = power_letter[exponent];
21564 *psuffix = '\0';
21566 /* Print TENTHS. */
21567 if (tenths >= 0)
21569 *--p = '0' + tenths;
21570 *--p = '.';
21573 /* Print QUOTIENT. */
21576 int digit = quotient % 10;
21577 *--p = '0' + digit;
21579 while ((quotient /= 10) != 0);
21581 /* Print leading spaces. */
21582 while (buf < p)
21583 *--p = ' ';
21586 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
21587 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
21588 type of CODING_SYSTEM. Return updated pointer into BUF. */
21590 static unsigned char invalid_eol_type[] = "(*invalid*)";
21592 static char *
21593 decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_flag)
21595 Lisp_Object val;
21596 bool multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
21597 const unsigned char *eol_str;
21598 int eol_str_len;
21599 /* The EOL conversion we are using. */
21600 Lisp_Object eoltype;
21602 val = CODING_SYSTEM_SPEC (coding_system);
21603 eoltype = Qnil;
21605 if (!VECTORP (val)) /* Not yet decided. */
21607 *buf++ = multibyte ? '-' : ' ';
21608 if (eol_flag)
21609 eoltype = eol_mnemonic_undecided;
21610 /* Don't mention EOL conversion if it isn't decided. */
21612 else
21614 Lisp_Object attrs;
21615 Lisp_Object eolvalue;
21617 attrs = AREF (val, 0);
21618 eolvalue = AREF (val, 2);
21620 *buf++ = multibyte
21621 ? XFASTINT (CODING_ATTR_MNEMONIC (attrs))
21622 : ' ';
21624 if (eol_flag)
21626 /* The EOL conversion that is normal on this system. */
21628 if (NILP (eolvalue)) /* Not yet decided. */
21629 eoltype = eol_mnemonic_undecided;
21630 else if (VECTORP (eolvalue)) /* Not yet decided. */
21631 eoltype = eol_mnemonic_undecided;
21632 else /* eolvalue is Qunix, Qdos, or Qmac. */
21633 eoltype = (EQ (eolvalue, Qunix)
21634 ? eol_mnemonic_unix
21635 : (EQ (eolvalue, Qdos) == 1
21636 ? eol_mnemonic_dos : eol_mnemonic_mac));
21640 if (eol_flag)
21642 /* Mention the EOL conversion if it is not the usual one. */
21643 if (STRINGP (eoltype))
21645 eol_str = SDATA (eoltype);
21646 eol_str_len = SBYTES (eoltype);
21648 else if (CHARACTERP (eoltype))
21650 unsigned char *tmp = alloca (MAX_MULTIBYTE_LENGTH);
21651 int c = XFASTINT (eoltype);
21652 eol_str_len = CHAR_STRING (c, tmp);
21653 eol_str = tmp;
21655 else
21657 eol_str = invalid_eol_type;
21658 eol_str_len = sizeof (invalid_eol_type) - 1;
21660 memcpy (buf, eol_str, eol_str_len);
21661 buf += eol_str_len;
21664 return buf;
21667 /* Return a string for the output of a mode line %-spec for window W,
21668 generated by character C. FIELD_WIDTH > 0 means pad the string
21669 returned with spaces to that value. Return a Lisp string in
21670 *STRING if the resulting string is taken from that Lisp string.
21672 Note we operate on the current buffer for most purposes. */
21674 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
21676 static const char *
21677 decode_mode_spec (struct window *w, register int c, int field_width,
21678 Lisp_Object *string)
21680 Lisp_Object obj;
21681 struct frame *f = XFRAME (WINDOW_FRAME (w));
21682 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
21683 /* We are going to use f->decode_mode_spec_buffer as the buffer to
21684 produce strings from numerical values, so limit preposterously
21685 large values of FIELD_WIDTH to avoid overrunning the buffer's
21686 end. The size of the buffer is enough for FRAME_MESSAGE_BUF_SIZE
21687 bytes plus the terminating null. */
21688 int width = min (field_width, FRAME_MESSAGE_BUF_SIZE (f));
21689 struct buffer *b = current_buffer;
21691 obj = Qnil;
21692 *string = Qnil;
21694 switch (c)
21696 case '*':
21697 if (!NILP (BVAR (b, read_only)))
21698 return "%";
21699 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21700 return "*";
21701 return "-";
21703 case '+':
21704 /* This differs from %* only for a modified read-only buffer. */
21705 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21706 return "*";
21707 if (!NILP (BVAR (b, read_only)))
21708 return "%";
21709 return "-";
21711 case '&':
21712 /* This differs from %* in ignoring read-only-ness. */
21713 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21714 return "*";
21715 return "-";
21717 case '%':
21718 return "%";
21720 case '[':
21722 int i;
21723 char *p;
21725 if (command_loop_level > 5)
21726 return "[[[... ";
21727 p = decode_mode_spec_buf;
21728 for (i = 0; i < command_loop_level; i++)
21729 *p++ = '[';
21730 *p = 0;
21731 return decode_mode_spec_buf;
21734 case ']':
21736 int i;
21737 char *p;
21739 if (command_loop_level > 5)
21740 return " ...]]]";
21741 p = decode_mode_spec_buf;
21742 for (i = 0; i < command_loop_level; i++)
21743 *p++ = ']';
21744 *p = 0;
21745 return decode_mode_spec_buf;
21748 case '-':
21750 register int i;
21752 /* Let lots_of_dashes be a string of infinite length. */
21753 if (mode_line_target == MODE_LINE_NOPROP
21754 || mode_line_target == MODE_LINE_STRING)
21755 return "--";
21756 if (field_width <= 0
21757 || field_width > sizeof (lots_of_dashes))
21759 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
21760 decode_mode_spec_buf[i] = '-';
21761 decode_mode_spec_buf[i] = '\0';
21762 return decode_mode_spec_buf;
21764 else
21765 return lots_of_dashes;
21768 case 'b':
21769 obj = BVAR (b, name);
21770 break;
21772 case 'c':
21773 /* %c and %l are ignored in `frame-title-format'.
21774 (In redisplay_internal, the frame title is drawn _before_ the
21775 windows are updated, so the stuff which depends on actual
21776 window contents (such as %l) may fail to render properly, or
21777 even crash emacs.) */
21778 if (mode_line_target == MODE_LINE_TITLE)
21779 return "";
21780 else
21782 ptrdiff_t col = current_column ();
21783 w->column_number_displayed = col;
21784 pint2str (decode_mode_spec_buf, width, col);
21785 return decode_mode_spec_buf;
21788 case 'e':
21789 #ifndef SYSTEM_MALLOC
21791 if (NILP (Vmemory_full))
21792 return "";
21793 else
21794 return "!MEM FULL! ";
21796 #else
21797 return "";
21798 #endif
21800 case 'F':
21801 /* %F displays the frame name. */
21802 if (!NILP (f->title))
21803 return SSDATA (f->title);
21804 if (f->explicit_name || ! FRAME_WINDOW_P (f))
21805 return SSDATA (f->name);
21806 return "Emacs";
21808 case 'f':
21809 obj = BVAR (b, filename);
21810 break;
21812 case 'i':
21814 ptrdiff_t size = ZV - BEGV;
21815 pint2str (decode_mode_spec_buf, width, size);
21816 return decode_mode_spec_buf;
21819 case 'I':
21821 ptrdiff_t size = ZV - BEGV;
21822 pint2hrstr (decode_mode_spec_buf, width, size);
21823 return decode_mode_spec_buf;
21826 case 'l':
21828 ptrdiff_t startpos, startpos_byte, line, linepos, linepos_byte;
21829 ptrdiff_t topline, nlines, height;
21830 ptrdiff_t junk;
21832 /* %c and %l are ignored in `frame-title-format'. */
21833 if (mode_line_target == MODE_LINE_TITLE)
21834 return "";
21836 startpos = marker_position (w->start);
21837 startpos_byte = marker_byte_position (w->start);
21838 height = WINDOW_TOTAL_LINES (w);
21840 /* If we decided that this buffer isn't suitable for line numbers,
21841 don't forget that too fast. */
21842 if (w->base_line_pos == -1)
21843 goto no_value;
21845 /* If the buffer is very big, don't waste time. */
21846 if (INTEGERP (Vline_number_display_limit)
21847 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
21849 w->base_line_pos = 0;
21850 w->base_line_number = 0;
21851 goto no_value;
21854 if (w->base_line_number > 0
21855 && w->base_line_pos > 0
21856 && w->base_line_pos <= startpos)
21858 line = w->base_line_number;
21859 linepos = w->base_line_pos;
21860 linepos_byte = buf_charpos_to_bytepos (b, linepos);
21862 else
21864 line = 1;
21865 linepos = BUF_BEGV (b);
21866 linepos_byte = BUF_BEGV_BYTE (b);
21869 /* Count lines from base line to window start position. */
21870 nlines = display_count_lines (linepos_byte,
21871 startpos_byte,
21872 startpos, &junk);
21874 topline = nlines + line;
21876 /* Determine a new base line, if the old one is too close
21877 or too far away, or if we did not have one.
21878 "Too close" means it's plausible a scroll-down would
21879 go back past it. */
21880 if (startpos == BUF_BEGV (b))
21882 w->base_line_number = topline;
21883 w->base_line_pos = BUF_BEGV (b);
21885 else if (nlines < height + 25 || nlines > height * 3 + 50
21886 || linepos == BUF_BEGV (b))
21888 ptrdiff_t limit = BUF_BEGV (b);
21889 ptrdiff_t limit_byte = BUF_BEGV_BYTE (b);
21890 ptrdiff_t position;
21891 ptrdiff_t distance =
21892 (height * 2 + 30) * line_number_display_limit_width;
21894 if (startpos - distance > limit)
21896 limit = startpos - distance;
21897 limit_byte = CHAR_TO_BYTE (limit);
21900 nlines = display_count_lines (startpos_byte,
21901 limit_byte,
21902 - (height * 2 + 30),
21903 &position);
21904 /* If we couldn't find the lines we wanted within
21905 line_number_display_limit_width chars per line,
21906 give up on line numbers for this window. */
21907 if (position == limit_byte && limit == startpos - distance)
21909 w->base_line_pos = -1;
21910 w->base_line_number = 0;
21911 goto no_value;
21914 w->base_line_number = topline - nlines;
21915 w->base_line_pos = BYTE_TO_CHAR (position);
21918 /* Now count lines from the start pos to point. */
21919 nlines = display_count_lines (startpos_byte,
21920 PT_BYTE, PT, &junk);
21922 /* Record that we did display the line number. */
21923 line_number_displayed = 1;
21925 /* Make the string to show. */
21926 pint2str (decode_mode_spec_buf, width, topline + nlines);
21927 return decode_mode_spec_buf;
21928 no_value:
21930 char* p = decode_mode_spec_buf;
21931 int pad = width - 2;
21932 while (pad-- > 0)
21933 *p++ = ' ';
21934 *p++ = '?';
21935 *p++ = '?';
21936 *p = '\0';
21937 return decode_mode_spec_buf;
21940 break;
21942 case 'm':
21943 obj = BVAR (b, mode_name);
21944 break;
21946 case 'n':
21947 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
21948 return " Narrow";
21949 break;
21951 case 'p':
21953 ptrdiff_t pos = marker_position (w->start);
21954 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
21956 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
21958 if (pos <= BUF_BEGV (b))
21959 return "All";
21960 else
21961 return "Bottom";
21963 else if (pos <= BUF_BEGV (b))
21964 return "Top";
21965 else
21967 if (total > 1000000)
21968 /* Do it differently for a large value, to avoid overflow. */
21969 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
21970 else
21971 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
21972 /* We can't normally display a 3-digit number,
21973 so get us a 2-digit number that is close. */
21974 if (total == 100)
21975 total = 99;
21976 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
21977 return decode_mode_spec_buf;
21981 /* Display percentage of size above the bottom of the screen. */
21982 case 'P':
21984 ptrdiff_t toppos = marker_position (w->start);
21985 ptrdiff_t botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
21986 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
21988 if (botpos >= BUF_ZV (b))
21990 if (toppos <= BUF_BEGV (b))
21991 return "All";
21992 else
21993 return "Bottom";
21995 else
21997 if (total > 1000000)
21998 /* Do it differently for a large value, to avoid overflow. */
21999 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
22000 else
22001 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
22002 /* We can't normally display a 3-digit number,
22003 so get us a 2-digit number that is close. */
22004 if (total == 100)
22005 total = 99;
22006 if (toppos <= BUF_BEGV (b))
22007 sprintf (decode_mode_spec_buf, "Top%2"pD"d%%", total);
22008 else
22009 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
22010 return decode_mode_spec_buf;
22014 case 's':
22015 /* status of process */
22016 obj = Fget_buffer_process (Fcurrent_buffer ());
22017 if (NILP (obj))
22018 return "no process";
22019 #ifndef MSDOS
22020 obj = Fsymbol_name (Fprocess_status (obj));
22021 #endif
22022 break;
22024 case '@':
22026 ptrdiff_t count = inhibit_garbage_collection ();
22027 Lisp_Object val = call1 (intern ("file-remote-p"),
22028 BVAR (current_buffer, directory));
22029 unbind_to (count, Qnil);
22031 if (NILP (val))
22032 return "-";
22033 else
22034 return "@";
22037 case 'z':
22038 /* coding-system (not including end-of-line format) */
22039 case 'Z':
22040 /* coding-system (including end-of-line type) */
22042 int eol_flag = (c == 'Z');
22043 char *p = decode_mode_spec_buf;
22045 if (! FRAME_WINDOW_P (f))
22047 /* No need to mention EOL here--the terminal never needs
22048 to do EOL conversion. */
22049 p = decode_mode_spec_coding (CODING_ID_NAME
22050 (FRAME_KEYBOARD_CODING (f)->id),
22051 p, 0);
22052 p = decode_mode_spec_coding (CODING_ID_NAME
22053 (FRAME_TERMINAL_CODING (f)->id),
22054 p, 0);
22056 p = decode_mode_spec_coding (BVAR (b, buffer_file_coding_system),
22057 p, eol_flag);
22059 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
22060 #ifdef subprocesses
22061 obj = Fget_buffer_process (Fcurrent_buffer ());
22062 if (PROCESSP (obj))
22064 p = decode_mode_spec_coding
22065 (XPROCESS (obj)->decode_coding_system, p, eol_flag);
22066 p = decode_mode_spec_coding
22067 (XPROCESS (obj)->encode_coding_system, p, eol_flag);
22069 #endif /* subprocesses */
22070 #endif /* 0 */
22071 *p = 0;
22072 return decode_mode_spec_buf;
22076 if (STRINGP (obj))
22078 *string = obj;
22079 return SSDATA (obj);
22081 else
22082 return "";
22086 /* Count up to COUNT lines starting from START_BYTE. COUNT negative
22087 means count lines back from START_BYTE. But don't go beyond
22088 LIMIT_BYTE. Return the number of lines thus found (always
22089 nonnegative).
22091 Set *BYTE_POS_PTR to the byte position where we stopped. This is
22092 either the position COUNT lines after/before START_BYTE, if we
22093 found COUNT lines, or LIMIT_BYTE if we hit the limit before finding
22094 COUNT lines. */
22096 static ptrdiff_t
22097 display_count_lines (ptrdiff_t start_byte,
22098 ptrdiff_t limit_byte, ptrdiff_t count,
22099 ptrdiff_t *byte_pos_ptr)
22101 register unsigned char *cursor;
22102 unsigned char *base;
22104 register ptrdiff_t ceiling;
22105 register unsigned char *ceiling_addr;
22106 ptrdiff_t orig_count = count;
22108 /* If we are not in selective display mode,
22109 check only for newlines. */
22110 int selective_display = (!NILP (BVAR (current_buffer, selective_display))
22111 && !INTEGERP (BVAR (current_buffer, selective_display)));
22113 if (count > 0)
22115 while (start_byte < limit_byte)
22117 ceiling = BUFFER_CEILING_OF (start_byte);
22118 ceiling = min (limit_byte - 1, ceiling);
22119 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
22120 base = (cursor = BYTE_POS_ADDR (start_byte));
22124 if (selective_display)
22126 while (*cursor != '\n' && *cursor != 015
22127 && ++cursor != ceiling_addr)
22128 continue;
22129 if (cursor == ceiling_addr)
22130 break;
22132 else
22134 cursor = memchr (cursor, '\n', ceiling_addr - cursor);
22135 if (! cursor)
22136 break;
22139 cursor++;
22141 if (--count == 0)
22143 start_byte += cursor - base;
22144 *byte_pos_ptr = start_byte;
22145 return orig_count;
22148 while (cursor < ceiling_addr);
22150 start_byte += ceiling_addr - base;
22153 else
22155 while (start_byte > limit_byte)
22157 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
22158 ceiling = max (limit_byte, ceiling);
22159 ceiling_addr = BYTE_POS_ADDR (ceiling);
22160 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
22161 while (1)
22163 if (selective_display)
22165 while (--cursor >= ceiling_addr
22166 && *cursor != '\n' && *cursor != 015)
22167 continue;
22168 if (cursor < ceiling_addr)
22169 break;
22171 else
22173 cursor = memrchr (ceiling_addr, '\n', cursor - ceiling_addr);
22174 if (! cursor)
22175 break;
22178 if (++count == 0)
22180 start_byte += cursor - base + 1;
22181 *byte_pos_ptr = start_byte;
22182 /* When scanning backwards, we should
22183 not count the newline posterior to which we stop. */
22184 return - orig_count - 1;
22187 start_byte += ceiling_addr - base;
22191 *byte_pos_ptr = limit_byte;
22193 if (count < 0)
22194 return - orig_count + count;
22195 return orig_count - count;
22201 /***********************************************************************
22202 Displaying strings
22203 ***********************************************************************/
22205 /* Display a NUL-terminated string, starting with index START.
22207 If STRING is non-null, display that C string. Otherwise, the Lisp
22208 string LISP_STRING is displayed. There's a case that STRING is
22209 non-null and LISP_STRING is not nil. It means STRING is a string
22210 data of LISP_STRING. In that case, we display LISP_STRING while
22211 ignoring its text properties.
22213 If FACE_STRING is not nil, FACE_STRING_POS is a position in
22214 FACE_STRING. Display STRING or LISP_STRING with the face at
22215 FACE_STRING_POS in FACE_STRING:
22217 Display the string in the environment given by IT, but use the
22218 standard display table, temporarily.
22220 FIELD_WIDTH is the minimum number of output glyphs to produce.
22221 If STRING has fewer characters than FIELD_WIDTH, pad to the right
22222 with spaces. If STRING has more characters, more than FIELD_WIDTH
22223 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
22225 PRECISION is the maximum number of characters to output from
22226 STRING. PRECISION < 0 means don't truncate the string.
22228 This is roughly equivalent to printf format specifiers:
22230 FIELD_WIDTH PRECISION PRINTF
22231 ----------------------------------------
22232 -1 -1 %s
22233 -1 10 %.10s
22234 10 -1 %10s
22235 20 10 %20.10s
22237 MULTIBYTE zero means do not display multibyte chars, > 0 means do
22238 display them, and < 0 means obey the current buffer's value of
22239 enable_multibyte_characters.
22241 Value is the number of columns displayed. */
22243 static int
22244 display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_string,
22245 ptrdiff_t face_string_pos, ptrdiff_t start, struct it *it,
22246 int field_width, int precision, int max_x, int multibyte)
22248 int hpos_at_start = it->hpos;
22249 int saved_face_id = it->face_id;
22250 struct glyph_row *row = it->glyph_row;
22251 ptrdiff_t it_charpos;
22253 /* Initialize the iterator IT for iteration over STRING beginning
22254 with index START. */
22255 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
22256 precision, field_width, multibyte);
22257 if (string && STRINGP (lisp_string))
22258 /* LISP_STRING is the one returned by decode_mode_spec. We should
22259 ignore its text properties. */
22260 it->stop_charpos = it->end_charpos;
22262 /* If displaying STRING, set up the face of the iterator from
22263 FACE_STRING, if that's given. */
22264 if (STRINGP (face_string))
22266 ptrdiff_t endptr;
22267 struct face *face;
22269 it->face_id
22270 = face_at_string_position (it->w, face_string, face_string_pos,
22271 0, it->region_beg_charpos,
22272 it->region_end_charpos,
22273 &endptr, it->base_face_id, 0);
22274 face = FACE_FROM_ID (it->f, it->face_id);
22275 it->face_box_p = face->box != FACE_NO_BOX;
22278 /* Set max_x to the maximum allowed X position. Don't let it go
22279 beyond the right edge of the window. */
22280 if (max_x <= 0)
22281 max_x = it->last_visible_x;
22282 else
22283 max_x = min (max_x, it->last_visible_x);
22285 /* Skip over display elements that are not visible. because IT->w is
22286 hscrolled. */
22287 if (it->current_x < it->first_visible_x)
22288 move_it_in_display_line_to (it, 100000, it->first_visible_x,
22289 MOVE_TO_POS | MOVE_TO_X);
22291 row->ascent = it->max_ascent;
22292 row->height = it->max_ascent + it->max_descent;
22293 row->phys_ascent = it->max_phys_ascent;
22294 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
22295 row->extra_line_spacing = it->max_extra_line_spacing;
22297 if (STRINGP (it->string))
22298 it_charpos = IT_STRING_CHARPOS (*it);
22299 else
22300 it_charpos = IT_CHARPOS (*it);
22302 /* This condition is for the case that we are called with current_x
22303 past last_visible_x. */
22304 while (it->current_x < max_x)
22306 int x_before, x, n_glyphs_before, i, nglyphs;
22308 /* Get the next display element. */
22309 if (!get_next_display_element (it))
22310 break;
22312 /* Produce glyphs. */
22313 x_before = it->current_x;
22314 n_glyphs_before = row->used[TEXT_AREA];
22315 PRODUCE_GLYPHS (it);
22317 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
22318 i = 0;
22319 x = x_before;
22320 while (i < nglyphs)
22322 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
22324 if (it->line_wrap != TRUNCATE
22325 && x + glyph->pixel_width > max_x)
22327 /* End of continued line or max_x reached. */
22328 if (CHAR_GLYPH_PADDING_P (*glyph))
22330 /* A wide character is unbreakable. */
22331 if (row->reversed_p)
22332 unproduce_glyphs (it, row->used[TEXT_AREA]
22333 - n_glyphs_before);
22334 row->used[TEXT_AREA] = n_glyphs_before;
22335 it->current_x = x_before;
22337 else
22339 if (row->reversed_p)
22340 unproduce_glyphs (it, row->used[TEXT_AREA]
22341 - (n_glyphs_before + i));
22342 row->used[TEXT_AREA] = n_glyphs_before + i;
22343 it->current_x = x;
22345 break;
22347 else if (x + glyph->pixel_width >= it->first_visible_x)
22349 /* Glyph is at least partially visible. */
22350 ++it->hpos;
22351 if (x < it->first_visible_x)
22352 row->x = x - it->first_visible_x;
22354 else
22356 /* Glyph is off the left margin of the display area.
22357 Should not happen. */
22358 emacs_abort ();
22361 row->ascent = max (row->ascent, it->max_ascent);
22362 row->height = max (row->height, it->max_ascent + it->max_descent);
22363 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
22364 row->phys_height = max (row->phys_height,
22365 it->max_phys_ascent + it->max_phys_descent);
22366 row->extra_line_spacing = max (row->extra_line_spacing,
22367 it->max_extra_line_spacing);
22368 x += glyph->pixel_width;
22369 ++i;
22372 /* Stop if max_x reached. */
22373 if (i < nglyphs)
22374 break;
22376 /* Stop at line ends. */
22377 if (ITERATOR_AT_END_OF_LINE_P (it))
22379 it->continuation_lines_width = 0;
22380 break;
22383 set_iterator_to_next (it, 1);
22384 if (STRINGP (it->string))
22385 it_charpos = IT_STRING_CHARPOS (*it);
22386 else
22387 it_charpos = IT_CHARPOS (*it);
22389 /* Stop if truncating at the right edge. */
22390 if (it->line_wrap == TRUNCATE
22391 && it->current_x >= it->last_visible_x)
22393 /* Add truncation mark, but don't do it if the line is
22394 truncated at a padding space. */
22395 if (it_charpos < it->string_nchars)
22397 if (!FRAME_WINDOW_P (it->f))
22399 int ii, n;
22401 if (it->current_x > it->last_visible_x)
22403 if (!row->reversed_p)
22405 for (ii = row->used[TEXT_AREA] - 1; ii > 0; --ii)
22406 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
22407 break;
22409 else
22411 for (ii = 0; ii < row->used[TEXT_AREA]; ii++)
22412 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
22413 break;
22414 unproduce_glyphs (it, ii + 1);
22415 ii = row->used[TEXT_AREA] - (ii + 1);
22417 for (n = row->used[TEXT_AREA]; ii < n; ++ii)
22419 row->used[TEXT_AREA] = ii;
22420 produce_special_glyphs (it, IT_TRUNCATION);
22423 produce_special_glyphs (it, IT_TRUNCATION);
22425 row->truncated_on_right_p = 1;
22427 break;
22431 /* Maybe insert a truncation at the left. */
22432 if (it->first_visible_x
22433 && it_charpos > 0)
22435 if (!FRAME_WINDOW_P (it->f)
22436 || (row->reversed_p
22437 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
22438 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
22439 insert_left_trunc_glyphs (it);
22440 row->truncated_on_left_p = 1;
22443 it->face_id = saved_face_id;
22445 /* Value is number of columns displayed. */
22446 return it->hpos - hpos_at_start;
22451 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
22452 appears as an element of LIST or as the car of an element of LIST.
22453 If PROPVAL is a list, compare each element against LIST in that
22454 way, and return 1/2 if any element of PROPVAL is found in LIST.
22455 Otherwise return 0. This function cannot quit.
22456 The return value is 2 if the text is invisible but with an ellipsis
22457 and 1 if it's invisible and without an ellipsis. */
22460 invisible_p (register Lisp_Object propval, Lisp_Object list)
22462 register Lisp_Object tail, proptail;
22464 for (tail = list; CONSP (tail); tail = XCDR (tail))
22466 register Lisp_Object tem;
22467 tem = XCAR (tail);
22468 if (EQ (propval, tem))
22469 return 1;
22470 if (CONSP (tem) && EQ (propval, XCAR (tem)))
22471 return NILP (XCDR (tem)) ? 1 : 2;
22474 if (CONSP (propval))
22476 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
22478 Lisp_Object propelt;
22479 propelt = XCAR (proptail);
22480 for (tail = list; CONSP (tail); tail = XCDR (tail))
22482 register Lisp_Object tem;
22483 tem = XCAR (tail);
22484 if (EQ (propelt, tem))
22485 return 1;
22486 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
22487 return NILP (XCDR (tem)) ? 1 : 2;
22492 return 0;
22495 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
22496 doc: /* Non-nil if the property makes the text invisible.
22497 POS-OR-PROP can be a marker or number, in which case it is taken to be
22498 a position in the current buffer and the value of the `invisible' property
22499 is checked; or it can be some other value, which is then presumed to be the
22500 value of the `invisible' property of the text of interest.
22501 The non-nil value returned can be t for truly invisible text or something
22502 else if the text is replaced by an ellipsis. */)
22503 (Lisp_Object pos_or_prop)
22505 Lisp_Object prop
22506 = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
22507 ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
22508 : pos_or_prop);
22509 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
22510 return (invis == 0 ? Qnil
22511 : invis == 1 ? Qt
22512 : make_number (invis));
22515 /* Calculate a width or height in pixels from a specification using
22516 the following elements:
22518 SPEC ::=
22519 NUM - a (fractional) multiple of the default font width/height
22520 (NUM) - specifies exactly NUM pixels
22521 UNIT - a fixed number of pixels, see below.
22522 ELEMENT - size of a display element in pixels, see below.
22523 (NUM . SPEC) - equals NUM * SPEC
22524 (+ SPEC SPEC ...) - add pixel values
22525 (- SPEC SPEC ...) - subtract pixel values
22526 (- SPEC) - negate pixel value
22528 NUM ::=
22529 INT or FLOAT - a number constant
22530 SYMBOL - use symbol's (buffer local) variable binding.
22532 UNIT ::=
22533 in - pixels per inch *)
22534 mm - pixels per 1/1000 meter *)
22535 cm - pixels per 1/100 meter *)
22536 width - width of current font in pixels.
22537 height - height of current font in pixels.
22539 *) using the ratio(s) defined in display-pixels-per-inch.
22541 ELEMENT ::=
22543 left-fringe - left fringe width in pixels
22544 right-fringe - right fringe width in pixels
22546 left-margin - left margin width in pixels
22547 right-margin - right margin width in pixels
22549 scroll-bar - scroll-bar area width in pixels
22551 Examples:
22553 Pixels corresponding to 5 inches:
22554 (5 . in)
22556 Total width of non-text areas on left side of window (if scroll-bar is on left):
22557 '(space :width (+ left-fringe left-margin scroll-bar))
22559 Align to first text column (in header line):
22560 '(space :align-to 0)
22562 Align to middle of text area minus half the width of variable `my-image'
22563 containing a loaded image:
22564 '(space :align-to (0.5 . (- text my-image)))
22566 Width of left margin minus width of 1 character in the default font:
22567 '(space :width (- left-margin 1))
22569 Width of left margin minus width of 2 characters in the current font:
22570 '(space :width (- left-margin (2 . width)))
22572 Center 1 character over left-margin (in header line):
22573 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
22575 Different ways to express width of left fringe plus left margin minus one pixel:
22576 '(space :width (- (+ left-fringe left-margin) (1)))
22577 '(space :width (+ left-fringe left-margin (- (1))))
22578 '(space :width (+ left-fringe left-margin (-1)))
22582 static int
22583 calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
22584 struct font *font, int width_p, int *align_to)
22586 double pixels;
22588 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
22589 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
22591 if (NILP (prop))
22592 return OK_PIXELS (0);
22594 eassert (FRAME_LIVE_P (it->f));
22596 if (SYMBOLP (prop))
22598 if (SCHARS (SYMBOL_NAME (prop)) == 2)
22600 char *unit = SSDATA (SYMBOL_NAME (prop));
22602 if (unit[0] == 'i' && unit[1] == 'n')
22603 pixels = 1.0;
22604 else if (unit[0] == 'm' && unit[1] == 'm')
22605 pixels = 25.4;
22606 else if (unit[0] == 'c' && unit[1] == 'm')
22607 pixels = 2.54;
22608 else
22609 pixels = 0;
22610 if (pixels > 0)
22612 double ppi = (width_p ? FRAME_RES_X (it->f)
22613 : FRAME_RES_Y (it->f));
22615 if (ppi > 0)
22616 return OK_PIXELS (ppi / pixels);
22617 return 0;
22621 #ifdef HAVE_WINDOW_SYSTEM
22622 if (EQ (prop, Qheight))
22623 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
22624 if (EQ (prop, Qwidth))
22625 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
22626 #else
22627 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
22628 return OK_PIXELS (1);
22629 #endif
22631 if (EQ (prop, Qtext))
22632 return OK_PIXELS (width_p
22633 ? window_box_width (it->w, TEXT_AREA)
22634 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
22636 if (align_to && *align_to < 0)
22638 *res = 0;
22639 if (EQ (prop, Qleft))
22640 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
22641 if (EQ (prop, Qright))
22642 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
22643 if (EQ (prop, Qcenter))
22644 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
22645 + window_box_width (it->w, TEXT_AREA) / 2);
22646 if (EQ (prop, Qleft_fringe))
22647 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22648 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
22649 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
22650 if (EQ (prop, Qright_fringe))
22651 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22652 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
22653 : window_box_right_offset (it->w, TEXT_AREA));
22654 if (EQ (prop, Qleft_margin))
22655 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
22656 if (EQ (prop, Qright_margin))
22657 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
22658 if (EQ (prop, Qscroll_bar))
22659 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
22661 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
22662 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22663 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
22664 : 0)));
22666 else
22668 if (EQ (prop, Qleft_fringe))
22669 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
22670 if (EQ (prop, Qright_fringe))
22671 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
22672 if (EQ (prop, Qleft_margin))
22673 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
22674 if (EQ (prop, Qright_margin))
22675 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
22676 if (EQ (prop, Qscroll_bar))
22677 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
22680 prop = buffer_local_value_1 (prop, it->w->contents);
22681 if (EQ (prop, Qunbound))
22682 prop = Qnil;
22685 if (INTEGERP (prop) || FLOATP (prop))
22687 int base_unit = (width_p
22688 ? FRAME_COLUMN_WIDTH (it->f)
22689 : FRAME_LINE_HEIGHT (it->f));
22690 return OK_PIXELS (XFLOATINT (prop) * base_unit);
22693 if (CONSP (prop))
22695 Lisp_Object car = XCAR (prop);
22696 Lisp_Object cdr = XCDR (prop);
22698 if (SYMBOLP (car))
22700 #ifdef HAVE_WINDOW_SYSTEM
22701 if (FRAME_WINDOW_P (it->f)
22702 && valid_image_p (prop))
22704 ptrdiff_t id = lookup_image (it->f, prop);
22705 struct image *img = IMAGE_FROM_ID (it->f, id);
22707 return OK_PIXELS (width_p ? img->width : img->height);
22709 #endif
22710 if (EQ (car, Qplus) || EQ (car, Qminus))
22712 int first = 1;
22713 double px;
22715 pixels = 0;
22716 while (CONSP (cdr))
22718 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
22719 font, width_p, align_to))
22720 return 0;
22721 if (first)
22722 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
22723 else
22724 pixels += px;
22725 cdr = XCDR (cdr);
22727 if (EQ (car, Qminus))
22728 pixels = -pixels;
22729 return OK_PIXELS (pixels);
22732 car = buffer_local_value_1 (car, it->w->contents);
22733 if (EQ (car, Qunbound))
22734 car = Qnil;
22737 if (INTEGERP (car) || FLOATP (car))
22739 double fact;
22740 pixels = XFLOATINT (car);
22741 if (NILP (cdr))
22742 return OK_PIXELS (pixels);
22743 if (calc_pixel_width_or_height (&fact, it, cdr,
22744 font, width_p, align_to))
22745 return OK_PIXELS (pixels * fact);
22746 return 0;
22749 return 0;
22752 return 0;
22756 /***********************************************************************
22757 Glyph Display
22758 ***********************************************************************/
22760 #ifdef HAVE_WINDOW_SYSTEM
22762 #ifdef GLYPH_DEBUG
22764 void
22765 dump_glyph_string (struct glyph_string *s)
22767 fprintf (stderr, "glyph string\n");
22768 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
22769 s->x, s->y, s->width, s->height);
22770 fprintf (stderr, " ybase = %d\n", s->ybase);
22771 fprintf (stderr, " hl = %d\n", s->hl);
22772 fprintf (stderr, " left overhang = %d, right = %d\n",
22773 s->left_overhang, s->right_overhang);
22774 fprintf (stderr, " nchars = %d\n", s->nchars);
22775 fprintf (stderr, " extends to end of line = %d\n",
22776 s->extends_to_end_of_line_p);
22777 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
22778 fprintf (stderr, " bg width = %d\n", s->background_width);
22781 #endif /* GLYPH_DEBUG */
22783 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
22784 of XChar2b structures for S; it can't be allocated in
22785 init_glyph_string because it must be allocated via `alloca'. W
22786 is the window on which S is drawn. ROW and AREA are the glyph row
22787 and area within the row from which S is constructed. START is the
22788 index of the first glyph structure covered by S. HL is a
22789 face-override for drawing S. */
22791 #ifdef HAVE_NTGUI
22792 #define OPTIONAL_HDC(hdc) HDC hdc,
22793 #define DECLARE_HDC(hdc) HDC hdc;
22794 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
22795 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
22796 #endif
22798 #ifndef OPTIONAL_HDC
22799 #define OPTIONAL_HDC(hdc)
22800 #define DECLARE_HDC(hdc)
22801 #define ALLOCATE_HDC(hdc, f)
22802 #define RELEASE_HDC(hdc, f)
22803 #endif
22805 static void
22806 init_glyph_string (struct glyph_string *s,
22807 OPTIONAL_HDC (hdc)
22808 XChar2b *char2b, struct window *w, struct glyph_row *row,
22809 enum glyph_row_area area, int start, enum draw_glyphs_face hl)
22811 memset (s, 0, sizeof *s);
22812 s->w = w;
22813 s->f = XFRAME (w->frame);
22814 #ifdef HAVE_NTGUI
22815 s->hdc = hdc;
22816 #endif
22817 s->display = FRAME_X_DISPLAY (s->f);
22818 s->window = FRAME_X_WINDOW (s->f);
22819 s->char2b = char2b;
22820 s->hl = hl;
22821 s->row = row;
22822 s->area = area;
22823 s->first_glyph = row->glyphs[area] + start;
22824 s->height = row->height;
22825 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
22826 s->ybase = s->y + row->ascent;
22830 /* Append the list of glyph strings with head H and tail T to the list
22831 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
22833 static void
22834 append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
22835 struct glyph_string *h, struct glyph_string *t)
22837 if (h)
22839 if (*head)
22840 (*tail)->next = h;
22841 else
22842 *head = h;
22843 h->prev = *tail;
22844 *tail = t;
22849 /* Prepend the list of glyph strings with head H and tail T to the
22850 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
22851 result. */
22853 static void
22854 prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
22855 struct glyph_string *h, struct glyph_string *t)
22857 if (h)
22859 if (*head)
22860 (*head)->prev = t;
22861 else
22862 *tail = t;
22863 t->next = *head;
22864 *head = h;
22869 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
22870 Set *HEAD and *TAIL to the resulting list. */
22872 static void
22873 append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
22874 struct glyph_string *s)
22876 s->next = s->prev = NULL;
22877 append_glyph_string_lists (head, tail, s, s);
22881 /* Get face and two-byte form of character C in face FACE_ID on frame F.
22882 The encoding of C is returned in *CHAR2B. DISPLAY_P non-zero means
22883 make sure that X resources for the face returned are allocated.
22884 Value is a pointer to a realized face that is ready for display if
22885 DISPLAY_P is non-zero. */
22887 static struct face *
22888 get_char_face_and_encoding (struct frame *f, int c, int face_id,
22889 XChar2b *char2b, int display_p)
22891 struct face *face = FACE_FROM_ID (f, face_id);
22892 unsigned code = 0;
22894 if (face->font)
22896 code = face->font->driver->encode_char (face->font, c);
22898 if (code == FONT_INVALID_CODE)
22899 code = 0;
22901 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
22903 /* Make sure X resources of the face are allocated. */
22904 #ifdef HAVE_X_WINDOWS
22905 if (display_p)
22906 #endif
22908 eassert (face != NULL);
22909 PREPARE_FACE_FOR_DISPLAY (f, face);
22912 return face;
22916 /* Get face and two-byte form of character glyph GLYPH on frame F.
22917 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
22918 a pointer to a realized face that is ready for display. */
22920 static struct face *
22921 get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
22922 XChar2b *char2b, int *two_byte_p)
22924 struct face *face;
22925 unsigned code = 0;
22927 eassert (glyph->type == CHAR_GLYPH);
22928 face = FACE_FROM_ID (f, glyph->face_id);
22930 /* Make sure X resources of the face are allocated. */
22931 eassert (face != NULL);
22932 PREPARE_FACE_FOR_DISPLAY (f, face);
22934 if (two_byte_p)
22935 *two_byte_p = 0;
22937 if (face->font)
22939 if (CHAR_BYTE8_P (glyph->u.ch))
22940 code = CHAR_TO_BYTE8 (glyph->u.ch);
22941 else
22942 code = face->font->driver->encode_char (face->font, glyph->u.ch);
22944 if (code == FONT_INVALID_CODE)
22945 code = 0;
22948 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
22949 return face;
22953 /* Get glyph code of character C in FONT in the two-byte form CHAR2B.
22954 Return 1 if FONT has a glyph for C, otherwise return 0. */
22956 static int
22957 get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
22959 unsigned code;
22961 if (CHAR_BYTE8_P (c))
22962 code = CHAR_TO_BYTE8 (c);
22963 else
22964 code = font->driver->encode_char (font, c);
22966 if (code == FONT_INVALID_CODE)
22967 return 0;
22968 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
22969 return 1;
22973 /* Fill glyph string S with composition components specified by S->cmp.
22975 BASE_FACE is the base face of the composition.
22976 S->cmp_from is the index of the first component for S.
22978 OVERLAPS non-zero means S should draw the foreground only, and use
22979 its physical height for clipping. See also draw_glyphs.
22981 Value is the index of a component not in S. */
22983 static int
22984 fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
22985 int overlaps)
22987 int i;
22988 /* For all glyphs of this composition, starting at the offset
22989 S->cmp_from, until we reach the end of the definition or encounter a
22990 glyph that requires the different face, add it to S. */
22991 struct face *face;
22993 eassert (s);
22995 s->for_overlaps = overlaps;
22996 s->face = NULL;
22997 s->font = NULL;
22998 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
23000 int c = COMPOSITION_GLYPH (s->cmp, i);
23002 /* TAB in a composition means display glyphs with padding space
23003 on the left or right. */
23004 if (c != '\t')
23006 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
23007 -1, Qnil);
23009 face = get_char_face_and_encoding (s->f, c, face_id,
23010 s->char2b + i, 1);
23011 if (face)
23013 if (! s->face)
23015 s->face = face;
23016 s->font = s->face->font;
23018 else if (s->face != face)
23019 break;
23022 ++s->nchars;
23024 s->cmp_to = i;
23026 if (s->face == NULL)
23028 s->face = base_face->ascii_face;
23029 s->font = s->face->font;
23032 /* All glyph strings for the same composition has the same width,
23033 i.e. the width set for the first component of the composition. */
23034 s->width = s->first_glyph->pixel_width;
23036 /* If the specified font could not be loaded, use the frame's
23037 default font, but record the fact that we couldn't load it in
23038 the glyph string so that we can draw rectangles for the
23039 characters of the glyph string. */
23040 if (s->font == NULL)
23042 s->font_not_found_p = 1;
23043 s->font = FRAME_FONT (s->f);
23046 /* Adjust base line for subscript/superscript text. */
23047 s->ybase += s->first_glyph->voffset;
23049 /* This glyph string must always be drawn with 16-bit functions. */
23050 s->two_byte_p = 1;
23052 return s->cmp_to;
23055 static int
23056 fill_gstring_glyph_string (struct glyph_string *s, int face_id,
23057 int start, int end, int overlaps)
23059 struct glyph *glyph, *last;
23060 Lisp_Object lgstring;
23061 int i;
23063 s->for_overlaps = overlaps;
23064 glyph = s->row->glyphs[s->area] + start;
23065 last = s->row->glyphs[s->area] + end;
23066 s->cmp_id = glyph->u.cmp.id;
23067 s->cmp_from = glyph->slice.cmp.from;
23068 s->cmp_to = glyph->slice.cmp.to + 1;
23069 s->face = FACE_FROM_ID (s->f, face_id);
23070 lgstring = composition_gstring_from_id (s->cmp_id);
23071 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
23072 glyph++;
23073 while (glyph < last
23074 && glyph->u.cmp.automatic
23075 && glyph->u.cmp.id == s->cmp_id
23076 && s->cmp_to == glyph->slice.cmp.from)
23077 s->cmp_to = (glyph++)->slice.cmp.to + 1;
23079 for (i = s->cmp_from; i < s->cmp_to; i++)
23081 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
23082 unsigned code = LGLYPH_CODE (lglyph);
23084 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
23086 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
23087 return glyph - s->row->glyphs[s->area];
23091 /* Fill glyph string S from a sequence glyphs for glyphless characters.
23092 See the comment of fill_glyph_string for arguments.
23093 Value is the index of the first glyph not in S. */
23096 static int
23097 fill_glyphless_glyph_string (struct glyph_string *s, int face_id,
23098 int start, int end, int overlaps)
23100 struct glyph *glyph, *last;
23101 int voffset;
23103 eassert (s->first_glyph->type == GLYPHLESS_GLYPH);
23104 s->for_overlaps = overlaps;
23105 glyph = s->row->glyphs[s->area] + start;
23106 last = s->row->glyphs[s->area] + end;
23107 voffset = glyph->voffset;
23108 s->face = FACE_FROM_ID (s->f, face_id);
23109 s->font = s->face->font ? s->face->font : FRAME_FONT (s->f);
23110 s->nchars = 1;
23111 s->width = glyph->pixel_width;
23112 glyph++;
23113 while (glyph < last
23114 && glyph->type == GLYPHLESS_GLYPH
23115 && glyph->voffset == voffset
23116 && glyph->face_id == face_id)
23118 s->nchars++;
23119 s->width += glyph->pixel_width;
23120 glyph++;
23122 s->ybase += voffset;
23123 return glyph - s->row->glyphs[s->area];
23127 /* Fill glyph string S from a sequence of character glyphs.
23129 FACE_ID is the face id of the string. START is the index of the
23130 first glyph to consider, END is the index of the last + 1.
23131 OVERLAPS non-zero means S should draw the foreground only, and use
23132 its physical height for clipping. See also draw_glyphs.
23134 Value is the index of the first glyph not in S. */
23136 static int
23137 fill_glyph_string (struct glyph_string *s, int face_id,
23138 int start, int end, int overlaps)
23140 struct glyph *glyph, *last;
23141 int voffset;
23142 int glyph_not_available_p;
23144 eassert (s->f == XFRAME (s->w->frame));
23145 eassert (s->nchars == 0);
23146 eassert (start >= 0 && end > start);
23148 s->for_overlaps = overlaps;
23149 glyph = s->row->glyphs[s->area] + start;
23150 last = s->row->glyphs[s->area] + end;
23151 voffset = glyph->voffset;
23152 s->padding_p = glyph->padding_p;
23153 glyph_not_available_p = glyph->glyph_not_available_p;
23155 while (glyph < last
23156 && glyph->type == CHAR_GLYPH
23157 && glyph->voffset == voffset
23158 /* Same face id implies same font, nowadays. */
23159 && glyph->face_id == face_id
23160 && glyph->glyph_not_available_p == glyph_not_available_p)
23162 int two_byte_p;
23164 s->face = get_glyph_face_and_encoding (s->f, glyph,
23165 s->char2b + s->nchars,
23166 &two_byte_p);
23167 s->two_byte_p = two_byte_p;
23168 ++s->nchars;
23169 eassert (s->nchars <= end - start);
23170 s->width += glyph->pixel_width;
23171 if (glyph++->padding_p != s->padding_p)
23172 break;
23175 s->font = s->face->font;
23177 /* If the specified font could not be loaded, use the frame's font,
23178 but record the fact that we couldn't load it in
23179 S->font_not_found_p so that we can draw rectangles for the
23180 characters of the glyph string. */
23181 if (s->font == NULL || glyph_not_available_p)
23183 s->font_not_found_p = 1;
23184 s->font = FRAME_FONT (s->f);
23187 /* Adjust base line for subscript/superscript text. */
23188 s->ybase += voffset;
23190 eassert (s->face && s->face->gc);
23191 return glyph - s->row->glyphs[s->area];
23195 /* Fill glyph string S from image glyph S->first_glyph. */
23197 static void
23198 fill_image_glyph_string (struct glyph_string *s)
23200 eassert (s->first_glyph->type == IMAGE_GLYPH);
23201 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
23202 eassert (s->img);
23203 s->slice = s->first_glyph->slice.img;
23204 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
23205 s->font = s->face->font;
23206 s->width = s->first_glyph->pixel_width;
23208 /* Adjust base line for subscript/superscript text. */
23209 s->ybase += s->first_glyph->voffset;
23213 /* Fill glyph string S from a sequence of stretch glyphs.
23215 START is the index of the first glyph to consider,
23216 END is the index of the last + 1.
23218 Value is the index of the first glyph not in S. */
23220 static int
23221 fill_stretch_glyph_string (struct glyph_string *s, int start, int end)
23223 struct glyph *glyph, *last;
23224 int voffset, face_id;
23226 eassert (s->first_glyph->type == STRETCH_GLYPH);
23228 glyph = s->row->glyphs[s->area] + start;
23229 last = s->row->glyphs[s->area] + end;
23230 face_id = glyph->face_id;
23231 s->face = FACE_FROM_ID (s->f, face_id);
23232 s->font = s->face->font;
23233 s->width = glyph->pixel_width;
23234 s->nchars = 1;
23235 voffset = glyph->voffset;
23237 for (++glyph;
23238 (glyph < last
23239 && glyph->type == STRETCH_GLYPH
23240 && glyph->voffset == voffset
23241 && glyph->face_id == face_id);
23242 ++glyph)
23243 s->width += glyph->pixel_width;
23245 /* Adjust base line for subscript/superscript text. */
23246 s->ybase += voffset;
23248 /* The case that face->gc == 0 is handled when drawing the glyph
23249 string by calling PREPARE_FACE_FOR_DISPLAY. */
23250 eassert (s->face);
23251 return glyph - s->row->glyphs[s->area];
23254 static struct font_metrics *
23255 get_per_char_metric (struct font *font, XChar2b *char2b)
23257 static struct font_metrics metrics;
23258 unsigned code;
23260 if (! font)
23261 return NULL;
23262 code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
23263 if (code == FONT_INVALID_CODE)
23264 return NULL;
23265 font->driver->text_extents (font, &code, 1, &metrics);
23266 return &metrics;
23269 /* EXPORT for RIF:
23270 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
23271 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
23272 assumed to be zero. */
23274 void
23275 x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *right)
23277 *left = *right = 0;
23279 if (glyph->type == CHAR_GLYPH)
23281 struct face *face;
23282 XChar2b char2b;
23283 struct font_metrics *pcm;
23285 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
23286 if (face->font && (pcm = get_per_char_metric (face->font, &char2b)))
23288 if (pcm->rbearing > pcm->width)
23289 *right = pcm->rbearing - pcm->width;
23290 if (pcm->lbearing < 0)
23291 *left = -pcm->lbearing;
23294 else if (glyph->type == COMPOSITE_GLYPH)
23296 if (! glyph->u.cmp.automatic)
23298 struct composition *cmp = composition_table[glyph->u.cmp.id];
23300 if (cmp->rbearing > cmp->pixel_width)
23301 *right = cmp->rbearing - cmp->pixel_width;
23302 if (cmp->lbearing < 0)
23303 *left = - cmp->lbearing;
23305 else
23307 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
23308 struct font_metrics metrics;
23310 composition_gstring_width (gstring, glyph->slice.cmp.from,
23311 glyph->slice.cmp.to + 1, &metrics);
23312 if (metrics.rbearing > metrics.width)
23313 *right = metrics.rbearing - metrics.width;
23314 if (metrics.lbearing < 0)
23315 *left = - metrics.lbearing;
23321 /* Return the index of the first glyph preceding glyph string S that
23322 is overwritten by S because of S's left overhang. Value is -1
23323 if no glyphs are overwritten. */
23325 static int
23326 left_overwritten (struct glyph_string *s)
23328 int k;
23330 if (s->left_overhang)
23332 int x = 0, i;
23333 struct glyph *glyphs = s->row->glyphs[s->area];
23334 int first = s->first_glyph - glyphs;
23336 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
23337 x -= glyphs[i].pixel_width;
23339 k = i + 1;
23341 else
23342 k = -1;
23344 return k;
23348 /* Return the index of the first glyph preceding glyph string S that
23349 is overwriting S because of its right overhang. Value is -1 if no
23350 glyph in front of S overwrites S. */
23352 static int
23353 left_overwriting (struct glyph_string *s)
23355 int i, k, x;
23356 struct glyph *glyphs = s->row->glyphs[s->area];
23357 int first = s->first_glyph - glyphs;
23359 k = -1;
23360 x = 0;
23361 for (i = first - 1; i >= 0; --i)
23363 int left, right;
23364 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
23365 if (x + right > 0)
23366 k = i;
23367 x -= glyphs[i].pixel_width;
23370 return k;
23374 /* Return the index of the last glyph following glyph string S that is
23375 overwritten by S because of S's right overhang. Value is -1 if
23376 no such glyph is found. */
23378 static int
23379 right_overwritten (struct glyph_string *s)
23381 int k = -1;
23383 if (s->right_overhang)
23385 int x = 0, i;
23386 struct glyph *glyphs = s->row->glyphs[s->area];
23387 int first = (s->first_glyph - glyphs
23388 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
23389 int end = s->row->used[s->area];
23391 for (i = first; i < end && s->right_overhang > x; ++i)
23392 x += glyphs[i].pixel_width;
23394 k = i;
23397 return k;
23401 /* Return the index of the last glyph following glyph string S that
23402 overwrites S because of its left overhang. Value is negative
23403 if no such glyph is found. */
23405 static int
23406 right_overwriting (struct glyph_string *s)
23408 int i, k, x;
23409 int end = s->row->used[s->area];
23410 struct glyph *glyphs = s->row->glyphs[s->area];
23411 int first = (s->first_glyph - glyphs
23412 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
23414 k = -1;
23415 x = 0;
23416 for (i = first; i < end; ++i)
23418 int left, right;
23419 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
23420 if (x - left < 0)
23421 k = i;
23422 x += glyphs[i].pixel_width;
23425 return k;
23429 /* Set background width of glyph string S. START is the index of the
23430 first glyph following S. LAST_X is the right-most x-position + 1
23431 in the drawing area. */
23433 static void
23434 set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
23436 /* If the face of this glyph string has to be drawn to the end of
23437 the drawing area, set S->extends_to_end_of_line_p. */
23439 if (start == s->row->used[s->area]
23440 && s->area == TEXT_AREA
23441 && ((s->row->fill_line_p
23442 && (s->hl == DRAW_NORMAL_TEXT
23443 || s->hl == DRAW_IMAGE_RAISED
23444 || s->hl == DRAW_IMAGE_SUNKEN))
23445 || s->hl == DRAW_MOUSE_FACE))
23446 s->extends_to_end_of_line_p = 1;
23448 /* If S extends its face to the end of the line, set its
23449 background_width to the distance to the right edge of the drawing
23450 area. */
23451 if (s->extends_to_end_of_line_p)
23452 s->background_width = last_x - s->x + 1;
23453 else
23454 s->background_width = s->width;
23458 /* Compute overhangs and x-positions for glyph string S and its
23459 predecessors, or successors. X is the starting x-position for S.
23460 BACKWARD_P non-zero means process predecessors. */
23462 static void
23463 compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
23465 if (backward_p)
23467 while (s)
23469 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
23470 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
23471 x -= s->width;
23472 s->x = x;
23473 s = s->prev;
23476 else
23478 while (s)
23480 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
23481 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
23482 s->x = x;
23483 x += s->width;
23484 s = s->next;
23491 /* The following macros are only called from draw_glyphs below.
23492 They reference the following parameters of that function directly:
23493 `w', `row', `area', and `overlap_p'
23494 as well as the following local variables:
23495 `s', `f', and `hdc' (in W32) */
23497 #ifdef HAVE_NTGUI
23498 /* On W32, silently add local `hdc' variable to argument list of
23499 init_glyph_string. */
23500 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
23501 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
23502 #else
23503 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
23504 init_glyph_string (s, char2b, w, row, area, start, hl)
23505 #endif
23507 /* Add a glyph string for a stretch glyph to the list of strings
23508 between HEAD and TAIL. START is the index of the stretch glyph in
23509 row area AREA of glyph row ROW. END is the index of the last glyph
23510 in that glyph row area. X is the current output position assigned
23511 to the new glyph string constructed. HL overrides that face of the
23512 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
23513 is the right-most x-position of the drawing area. */
23515 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
23516 and below -- keep them on one line. */
23517 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23518 do \
23520 s = alloca (sizeof *s); \
23521 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23522 START = fill_stretch_glyph_string (s, START, END); \
23523 append_glyph_string (&HEAD, &TAIL, s); \
23524 s->x = (X); \
23526 while (0)
23529 /* Add a glyph string for an image glyph to the list of strings
23530 between HEAD and TAIL. START is the index of the image glyph in
23531 row area AREA of glyph row ROW. END is the index of the last glyph
23532 in that glyph row area. X is the current output position assigned
23533 to the new glyph string constructed. HL overrides that face of the
23534 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
23535 is the right-most x-position of the drawing area. */
23537 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23538 do \
23540 s = alloca (sizeof *s); \
23541 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23542 fill_image_glyph_string (s); \
23543 append_glyph_string (&HEAD, &TAIL, s); \
23544 ++START; \
23545 s->x = (X); \
23547 while (0)
23550 /* Add a glyph string for a sequence of character glyphs to the list
23551 of strings between HEAD and TAIL. START is the index of the first
23552 glyph in row area AREA of glyph row ROW that is part of the new
23553 glyph string. END is the index of the last glyph in that glyph row
23554 area. X is the current output position assigned to the new glyph
23555 string constructed. HL overrides that face of the glyph; e.g. it
23556 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
23557 right-most x-position of the drawing area. */
23559 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
23560 do \
23562 int face_id; \
23563 XChar2b *char2b; \
23565 face_id = (row)->glyphs[area][START].face_id; \
23567 s = alloca (sizeof *s); \
23568 char2b = alloca ((END - START) * sizeof *char2b); \
23569 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23570 append_glyph_string (&HEAD, &TAIL, s); \
23571 s->x = (X); \
23572 START = fill_glyph_string (s, face_id, START, END, overlaps); \
23574 while (0)
23577 /* Add a glyph string for a composite sequence to the list of strings
23578 between HEAD and TAIL. START is the index of the first glyph in
23579 row area AREA of glyph row ROW that is part of the new glyph
23580 string. END is the index of the last glyph in that glyph row area.
23581 X is the current output position assigned to the new glyph string
23582 constructed. HL overrides that face of the glyph; e.g. it is
23583 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
23584 x-position of the drawing area. */
23586 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23587 do { \
23588 int face_id = (row)->glyphs[area][START].face_id; \
23589 struct face *base_face = FACE_FROM_ID (f, face_id); \
23590 ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \
23591 struct composition *cmp = composition_table[cmp_id]; \
23592 XChar2b *char2b; \
23593 struct glyph_string *first_s = NULL; \
23594 int n; \
23596 char2b = alloca (cmp->glyph_len * sizeof *char2b); \
23598 /* Make glyph_strings for each glyph sequence that is drawable by \
23599 the same face, and append them to HEAD/TAIL. */ \
23600 for (n = 0; n < cmp->glyph_len;) \
23602 s = alloca (sizeof *s); \
23603 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23604 append_glyph_string (&(HEAD), &(TAIL), s); \
23605 s->cmp = cmp; \
23606 s->cmp_from = n; \
23607 s->x = (X); \
23608 if (n == 0) \
23609 first_s = s; \
23610 n = fill_composite_glyph_string (s, base_face, overlaps); \
23613 ++START; \
23614 s = first_s; \
23615 } while (0)
23618 /* Add a glyph string for a glyph-string sequence to the list of strings
23619 between HEAD and TAIL. */
23621 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23622 do { \
23623 int face_id; \
23624 XChar2b *char2b; \
23625 Lisp_Object gstring; \
23627 face_id = (row)->glyphs[area][START].face_id; \
23628 gstring = (composition_gstring_from_id \
23629 ((row)->glyphs[area][START].u.cmp.id)); \
23630 s = alloca (sizeof *s); \
23631 char2b = alloca (LGSTRING_GLYPH_LEN (gstring) * sizeof *char2b); \
23632 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23633 append_glyph_string (&(HEAD), &(TAIL), s); \
23634 s->x = (X); \
23635 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
23636 } while (0)
23639 /* Add a glyph string for a sequence of glyphless character's glyphs
23640 to the list of strings between HEAD and TAIL. The meanings of
23641 arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */
23643 #define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23644 do \
23646 int face_id; \
23648 face_id = (row)->glyphs[area][START].face_id; \
23650 s = alloca (sizeof *s); \
23651 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23652 append_glyph_string (&HEAD, &TAIL, s); \
23653 s->x = (X); \
23654 START = fill_glyphless_glyph_string (s, face_id, START, END, \
23655 overlaps); \
23657 while (0)
23660 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
23661 of AREA of glyph row ROW on window W between indices START and END.
23662 HL overrides the face for drawing glyph strings, e.g. it is
23663 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
23664 x-positions of the drawing area.
23666 This is an ugly monster macro construct because we must use alloca
23667 to allocate glyph strings (because draw_glyphs can be called
23668 asynchronously). */
23670 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
23671 do \
23673 HEAD = TAIL = NULL; \
23674 while (START < END) \
23676 struct glyph *first_glyph = (row)->glyphs[area] + START; \
23677 switch (first_glyph->type) \
23679 case CHAR_GLYPH: \
23680 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
23681 HL, X, LAST_X); \
23682 break; \
23684 case COMPOSITE_GLYPH: \
23685 if (first_glyph->u.cmp.automatic) \
23686 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
23687 HL, X, LAST_X); \
23688 else \
23689 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
23690 HL, X, LAST_X); \
23691 break; \
23693 case STRETCH_GLYPH: \
23694 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
23695 HL, X, LAST_X); \
23696 break; \
23698 case IMAGE_GLYPH: \
23699 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
23700 HL, X, LAST_X); \
23701 break; \
23703 case GLYPHLESS_GLYPH: \
23704 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
23705 HL, X, LAST_X); \
23706 break; \
23708 default: \
23709 emacs_abort (); \
23712 if (s) \
23714 set_glyph_string_background_width (s, START, LAST_X); \
23715 (X) += s->width; \
23718 } while (0)
23721 /* Draw glyphs between START and END in AREA of ROW on window W,
23722 starting at x-position X. X is relative to AREA in W. HL is a
23723 face-override with the following meaning:
23725 DRAW_NORMAL_TEXT draw normally
23726 DRAW_CURSOR draw in cursor face
23727 DRAW_MOUSE_FACE draw in mouse face.
23728 DRAW_INVERSE_VIDEO draw in mode line face
23729 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
23730 DRAW_IMAGE_RAISED draw an image with a raised relief around it
23732 If OVERLAPS is non-zero, draw only the foreground of characters and
23733 clip to the physical height of ROW. Non-zero value also defines
23734 the overlapping part to be drawn:
23736 OVERLAPS_PRED overlap with preceding rows
23737 OVERLAPS_SUCC overlap with succeeding rows
23738 OVERLAPS_BOTH overlap with both preceding/succeeding rows
23739 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
23741 Value is the x-position reached, relative to AREA of W. */
23743 static int
23744 draw_glyphs (struct window *w, int x, struct glyph_row *row,
23745 enum glyph_row_area area, ptrdiff_t start, ptrdiff_t end,
23746 enum draw_glyphs_face hl, int overlaps)
23748 struct glyph_string *head, *tail;
23749 struct glyph_string *s;
23750 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
23751 int i, j, x_reached, last_x, area_left = 0;
23752 struct frame *f = XFRAME (WINDOW_FRAME (w));
23753 DECLARE_HDC (hdc);
23755 ALLOCATE_HDC (hdc, f);
23757 /* Let's rather be paranoid than getting a SEGV. */
23758 end = min (end, row->used[area]);
23759 start = clip_to_bounds (0, start, end);
23761 /* Translate X to frame coordinates. Set last_x to the right
23762 end of the drawing area. */
23763 if (row->full_width_p)
23765 /* X is relative to the left edge of W, without scroll bars
23766 or fringes. */
23767 area_left = WINDOW_LEFT_EDGE_X (w);
23768 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
23770 else
23772 area_left = window_box_left (w, area);
23773 last_x = area_left + window_box_width (w, area);
23775 x += area_left;
23777 /* Build a doubly-linked list of glyph_string structures between
23778 head and tail from what we have to draw. Note that the macro
23779 BUILD_GLYPH_STRINGS will modify its start parameter. That's
23780 the reason we use a separate variable `i'. */
23781 i = start;
23782 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
23783 if (tail)
23784 x_reached = tail->x + tail->background_width;
23785 else
23786 x_reached = x;
23788 /* If there are any glyphs with lbearing < 0 or rbearing > width in
23789 the row, redraw some glyphs in front or following the glyph
23790 strings built above. */
23791 if (head && !overlaps && row->contains_overlapping_glyphs_p)
23793 struct glyph_string *h, *t;
23794 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
23795 int mouse_beg_col IF_LINT (= 0), mouse_end_col IF_LINT (= 0);
23796 int check_mouse_face = 0;
23797 int dummy_x = 0;
23799 /* If mouse highlighting is on, we may need to draw adjacent
23800 glyphs using mouse-face highlighting. */
23801 if (area == TEXT_AREA && row->mouse_face_p
23802 && hlinfo->mouse_face_beg_row >= 0
23803 && hlinfo->mouse_face_end_row >= 0)
23805 struct glyph_row *mouse_beg_row, *mouse_end_row;
23807 mouse_beg_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
23808 mouse_end_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
23810 if (row >= mouse_beg_row && row <= mouse_end_row)
23812 check_mouse_face = 1;
23813 mouse_beg_col = (row == mouse_beg_row)
23814 ? hlinfo->mouse_face_beg_col : 0;
23815 mouse_end_col = (row == mouse_end_row)
23816 ? hlinfo->mouse_face_end_col
23817 : row->used[TEXT_AREA];
23821 /* Compute overhangs for all glyph strings. */
23822 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
23823 for (s = head; s; s = s->next)
23824 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
23826 /* Prepend glyph strings for glyphs in front of the first glyph
23827 string that are overwritten because of the first glyph
23828 string's left overhang. The background of all strings
23829 prepended must be drawn because the first glyph string
23830 draws over it. */
23831 i = left_overwritten (head);
23832 if (i >= 0)
23834 enum draw_glyphs_face overlap_hl;
23836 /* If this row contains mouse highlighting, attempt to draw
23837 the overlapped glyphs with the correct highlight. This
23838 code fails if the overlap encompasses more than one glyph
23839 and mouse-highlight spans only some of these glyphs.
23840 However, making it work perfectly involves a lot more
23841 code, and I don't know if the pathological case occurs in
23842 practice, so we'll stick to this for now. --- cyd */
23843 if (check_mouse_face
23844 && mouse_beg_col < start && mouse_end_col > i)
23845 overlap_hl = DRAW_MOUSE_FACE;
23846 else
23847 overlap_hl = DRAW_NORMAL_TEXT;
23849 j = i;
23850 BUILD_GLYPH_STRINGS (j, start, h, t,
23851 overlap_hl, dummy_x, last_x);
23852 start = i;
23853 compute_overhangs_and_x (t, head->x, 1);
23854 prepend_glyph_string_lists (&head, &tail, h, t);
23855 clip_head = head;
23858 /* Prepend glyph strings for glyphs in front of the first glyph
23859 string that overwrite that glyph string because of their
23860 right overhang. For these strings, only the foreground must
23861 be drawn, because it draws over the glyph string at `head'.
23862 The background must not be drawn because this would overwrite
23863 right overhangs of preceding glyphs for which no glyph
23864 strings exist. */
23865 i = left_overwriting (head);
23866 if (i >= 0)
23868 enum draw_glyphs_face overlap_hl;
23870 if (check_mouse_face
23871 && mouse_beg_col < start && mouse_end_col > i)
23872 overlap_hl = DRAW_MOUSE_FACE;
23873 else
23874 overlap_hl = DRAW_NORMAL_TEXT;
23876 clip_head = head;
23877 BUILD_GLYPH_STRINGS (i, start, h, t,
23878 overlap_hl, dummy_x, last_x);
23879 for (s = h; s; s = s->next)
23880 s->background_filled_p = 1;
23881 compute_overhangs_and_x (t, head->x, 1);
23882 prepend_glyph_string_lists (&head, &tail, h, t);
23885 /* Append glyphs strings for glyphs following the last glyph
23886 string tail that are overwritten by tail. The background of
23887 these strings has to be drawn because tail's foreground draws
23888 over it. */
23889 i = right_overwritten (tail);
23890 if (i >= 0)
23892 enum draw_glyphs_face overlap_hl;
23894 if (check_mouse_face
23895 && mouse_beg_col < i && mouse_end_col > end)
23896 overlap_hl = DRAW_MOUSE_FACE;
23897 else
23898 overlap_hl = DRAW_NORMAL_TEXT;
23900 BUILD_GLYPH_STRINGS (end, i, h, t,
23901 overlap_hl, x, last_x);
23902 /* Because BUILD_GLYPH_STRINGS updates the first argument,
23903 we don't have `end = i;' here. */
23904 compute_overhangs_and_x (h, tail->x + tail->width, 0);
23905 append_glyph_string_lists (&head, &tail, h, t);
23906 clip_tail = tail;
23909 /* Append glyph strings for glyphs following the last glyph
23910 string tail that overwrite tail. The foreground of such
23911 glyphs has to be drawn because it writes into the background
23912 of tail. The background must not be drawn because it could
23913 paint over the foreground of following glyphs. */
23914 i = right_overwriting (tail);
23915 if (i >= 0)
23917 enum draw_glyphs_face overlap_hl;
23918 if (check_mouse_face
23919 && mouse_beg_col < i && mouse_end_col > end)
23920 overlap_hl = DRAW_MOUSE_FACE;
23921 else
23922 overlap_hl = DRAW_NORMAL_TEXT;
23924 clip_tail = tail;
23925 i++; /* We must include the Ith glyph. */
23926 BUILD_GLYPH_STRINGS (end, i, h, t,
23927 overlap_hl, x, last_x);
23928 for (s = h; s; s = s->next)
23929 s->background_filled_p = 1;
23930 compute_overhangs_and_x (h, tail->x + tail->width, 0);
23931 append_glyph_string_lists (&head, &tail, h, t);
23933 if (clip_head || clip_tail)
23934 for (s = head; s; s = s->next)
23936 s->clip_head = clip_head;
23937 s->clip_tail = clip_tail;
23941 /* Draw all strings. */
23942 for (s = head; s; s = s->next)
23943 FRAME_RIF (f)->draw_glyph_string (s);
23945 #ifndef HAVE_NS
23946 /* When focus a sole frame and move horizontally, this sets on_p to 0
23947 causing a failure to erase prev cursor position. */
23948 if (area == TEXT_AREA
23949 && !row->full_width_p
23950 /* When drawing overlapping rows, only the glyph strings'
23951 foreground is drawn, which doesn't erase a cursor
23952 completely. */
23953 && !overlaps)
23955 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
23956 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
23957 : (tail ? tail->x + tail->background_width : x));
23958 x0 -= area_left;
23959 x1 -= area_left;
23961 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
23962 row->y, MATRIX_ROW_BOTTOM_Y (row));
23964 #endif
23966 /* Value is the x-position up to which drawn, relative to AREA of W.
23967 This doesn't include parts drawn because of overhangs. */
23968 if (row->full_width_p)
23969 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
23970 else
23971 x_reached -= area_left;
23973 RELEASE_HDC (hdc, f);
23975 return x_reached;
23978 /* Expand row matrix if too narrow. Don't expand if area
23979 is not present. */
23981 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
23983 if (!fonts_changed_p \
23984 && (it->glyph_row->glyphs[area] \
23985 < it->glyph_row->glyphs[area + 1])) \
23987 it->w->ncols_scale_factor++; \
23988 fonts_changed_p = 1; \
23992 /* Store one glyph for IT->char_to_display in IT->glyph_row.
23993 Called from x_produce_glyphs when IT->glyph_row is non-null. */
23995 static void
23996 append_glyph (struct it *it)
23998 struct glyph *glyph;
23999 enum glyph_row_area area = it->area;
24001 eassert (it->glyph_row);
24002 eassert (it->char_to_display != '\n' && it->char_to_display != '\t');
24004 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24005 if (glyph < it->glyph_row->glyphs[area + 1])
24007 /* If the glyph row is reversed, we need to prepend the glyph
24008 rather than append it. */
24009 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24011 struct glyph *g;
24013 /* Make room for the additional glyph. */
24014 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
24015 g[1] = *g;
24016 glyph = it->glyph_row->glyphs[area];
24018 glyph->charpos = CHARPOS (it->position);
24019 glyph->object = it->object;
24020 if (it->pixel_width > 0)
24022 glyph->pixel_width = it->pixel_width;
24023 glyph->padding_p = 0;
24025 else
24027 /* Assure at least 1-pixel width. Otherwise, cursor can't
24028 be displayed correctly. */
24029 glyph->pixel_width = 1;
24030 glyph->padding_p = 1;
24032 glyph->ascent = it->ascent;
24033 glyph->descent = it->descent;
24034 glyph->voffset = it->voffset;
24035 glyph->type = CHAR_GLYPH;
24036 glyph->avoid_cursor_p = it->avoid_cursor_p;
24037 glyph->multibyte_p = it->multibyte_p;
24038 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24040 /* In R2L rows, the left and the right box edges need to be
24041 drawn in reverse direction. */
24042 glyph->right_box_line_p = it->start_of_box_run_p;
24043 glyph->left_box_line_p = it->end_of_box_run_p;
24045 else
24047 glyph->left_box_line_p = it->start_of_box_run_p;
24048 glyph->right_box_line_p = it->end_of_box_run_p;
24050 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
24051 || it->phys_descent > it->descent);
24052 glyph->glyph_not_available_p = it->glyph_not_available_p;
24053 glyph->face_id = it->face_id;
24054 glyph->u.ch = it->char_to_display;
24055 glyph->slice.img = null_glyph_slice;
24056 glyph->font_type = FONT_TYPE_UNKNOWN;
24057 if (it->bidi_p)
24059 glyph->resolved_level = it->bidi_it.resolved_level;
24060 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24061 emacs_abort ();
24062 glyph->bidi_type = it->bidi_it.type;
24064 else
24066 glyph->resolved_level = 0;
24067 glyph->bidi_type = UNKNOWN_BT;
24069 ++it->glyph_row->used[area];
24071 else
24072 IT_EXPAND_MATRIX_WIDTH (it, area);
24075 /* Store one glyph for the composition IT->cmp_it.id in
24076 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
24077 non-null. */
24079 static void
24080 append_composite_glyph (struct it *it)
24082 struct glyph *glyph;
24083 enum glyph_row_area area = it->area;
24085 eassert (it->glyph_row);
24087 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24088 if (glyph < it->glyph_row->glyphs[area + 1])
24090 /* If the glyph row is reversed, we need to prepend the glyph
24091 rather than append it. */
24092 if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
24094 struct glyph *g;
24096 /* Make room for the new glyph. */
24097 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
24098 g[1] = *g;
24099 glyph = it->glyph_row->glyphs[it->area];
24101 glyph->charpos = it->cmp_it.charpos;
24102 glyph->object = it->object;
24103 glyph->pixel_width = it->pixel_width;
24104 glyph->ascent = it->ascent;
24105 glyph->descent = it->descent;
24106 glyph->voffset = it->voffset;
24107 glyph->type = COMPOSITE_GLYPH;
24108 if (it->cmp_it.ch < 0)
24110 glyph->u.cmp.automatic = 0;
24111 glyph->u.cmp.id = it->cmp_it.id;
24112 glyph->slice.cmp.from = glyph->slice.cmp.to = 0;
24114 else
24116 glyph->u.cmp.automatic = 1;
24117 glyph->u.cmp.id = it->cmp_it.id;
24118 glyph->slice.cmp.from = it->cmp_it.from;
24119 glyph->slice.cmp.to = it->cmp_it.to - 1;
24121 glyph->avoid_cursor_p = it->avoid_cursor_p;
24122 glyph->multibyte_p = it->multibyte_p;
24123 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24125 /* In R2L rows, the left and the right box edges need to be
24126 drawn in reverse direction. */
24127 glyph->right_box_line_p = it->start_of_box_run_p;
24128 glyph->left_box_line_p = it->end_of_box_run_p;
24130 else
24132 glyph->left_box_line_p = it->start_of_box_run_p;
24133 glyph->right_box_line_p = it->end_of_box_run_p;
24135 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
24136 || it->phys_descent > it->descent);
24137 glyph->padding_p = 0;
24138 glyph->glyph_not_available_p = 0;
24139 glyph->face_id = it->face_id;
24140 glyph->font_type = FONT_TYPE_UNKNOWN;
24141 if (it->bidi_p)
24143 glyph->resolved_level = it->bidi_it.resolved_level;
24144 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24145 emacs_abort ();
24146 glyph->bidi_type = it->bidi_it.type;
24148 ++it->glyph_row->used[area];
24150 else
24151 IT_EXPAND_MATRIX_WIDTH (it, area);
24155 /* Change IT->ascent and IT->height according to the setting of
24156 IT->voffset. */
24158 static void
24159 take_vertical_position_into_account (struct it *it)
24161 if (it->voffset)
24163 if (it->voffset < 0)
24164 /* Increase the ascent so that we can display the text higher
24165 in the line. */
24166 it->ascent -= it->voffset;
24167 else
24168 /* Increase the descent so that we can display the text lower
24169 in the line. */
24170 it->descent += it->voffset;
24175 /* Produce glyphs/get display metrics for the image IT is loaded with.
24176 See the description of struct display_iterator in dispextern.h for
24177 an overview of struct display_iterator. */
24179 static void
24180 produce_image_glyph (struct it *it)
24182 struct image *img;
24183 struct face *face;
24184 int glyph_ascent, crop;
24185 struct glyph_slice slice;
24187 eassert (it->what == IT_IMAGE);
24189 face = FACE_FROM_ID (it->f, it->face_id);
24190 eassert (face);
24191 /* Make sure X resources of the face is loaded. */
24192 PREPARE_FACE_FOR_DISPLAY (it->f, face);
24194 if (it->image_id < 0)
24196 /* Fringe bitmap. */
24197 it->ascent = it->phys_ascent = 0;
24198 it->descent = it->phys_descent = 0;
24199 it->pixel_width = 0;
24200 it->nglyphs = 0;
24201 return;
24204 img = IMAGE_FROM_ID (it->f, it->image_id);
24205 eassert (img);
24206 /* Make sure X resources of the image is loaded. */
24207 prepare_image_for_display (it->f, img);
24209 slice.x = slice.y = 0;
24210 slice.width = img->width;
24211 slice.height = img->height;
24213 if (INTEGERP (it->slice.x))
24214 slice.x = XINT (it->slice.x);
24215 else if (FLOATP (it->slice.x))
24216 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
24218 if (INTEGERP (it->slice.y))
24219 slice.y = XINT (it->slice.y);
24220 else if (FLOATP (it->slice.y))
24221 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
24223 if (INTEGERP (it->slice.width))
24224 slice.width = XINT (it->slice.width);
24225 else if (FLOATP (it->slice.width))
24226 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
24228 if (INTEGERP (it->slice.height))
24229 slice.height = XINT (it->slice.height);
24230 else if (FLOATP (it->slice.height))
24231 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
24233 if (slice.x >= img->width)
24234 slice.x = img->width;
24235 if (slice.y >= img->height)
24236 slice.y = img->height;
24237 if (slice.x + slice.width >= img->width)
24238 slice.width = img->width - slice.x;
24239 if (slice.y + slice.height > img->height)
24240 slice.height = img->height - slice.y;
24242 if (slice.width == 0 || slice.height == 0)
24243 return;
24245 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
24247 it->descent = slice.height - glyph_ascent;
24248 if (slice.y == 0)
24249 it->descent += img->vmargin;
24250 if (slice.y + slice.height == img->height)
24251 it->descent += img->vmargin;
24252 it->phys_descent = it->descent;
24254 it->pixel_width = slice.width;
24255 if (slice.x == 0)
24256 it->pixel_width += img->hmargin;
24257 if (slice.x + slice.width == img->width)
24258 it->pixel_width += img->hmargin;
24260 /* It's quite possible for images to have an ascent greater than
24261 their height, so don't get confused in that case. */
24262 if (it->descent < 0)
24263 it->descent = 0;
24265 it->nglyphs = 1;
24267 if (face->box != FACE_NO_BOX)
24269 if (face->box_line_width > 0)
24271 if (slice.y == 0)
24272 it->ascent += face->box_line_width;
24273 if (slice.y + slice.height == img->height)
24274 it->descent += face->box_line_width;
24277 if (it->start_of_box_run_p && slice.x == 0)
24278 it->pixel_width += eabs (face->box_line_width);
24279 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
24280 it->pixel_width += eabs (face->box_line_width);
24283 take_vertical_position_into_account (it);
24285 /* Automatically crop wide image glyphs at right edge so we can
24286 draw the cursor on same display row. */
24287 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
24288 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
24290 it->pixel_width -= crop;
24291 slice.width -= crop;
24294 if (it->glyph_row)
24296 struct glyph *glyph;
24297 enum glyph_row_area area = it->area;
24299 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24300 if (glyph < it->glyph_row->glyphs[area + 1])
24302 glyph->charpos = CHARPOS (it->position);
24303 glyph->object = it->object;
24304 glyph->pixel_width = it->pixel_width;
24305 glyph->ascent = glyph_ascent;
24306 glyph->descent = it->descent;
24307 glyph->voffset = it->voffset;
24308 glyph->type = IMAGE_GLYPH;
24309 glyph->avoid_cursor_p = it->avoid_cursor_p;
24310 glyph->multibyte_p = it->multibyte_p;
24311 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24313 /* In R2L rows, the left and the right box edges need to be
24314 drawn in reverse direction. */
24315 glyph->right_box_line_p = it->start_of_box_run_p;
24316 glyph->left_box_line_p = it->end_of_box_run_p;
24318 else
24320 glyph->left_box_line_p = it->start_of_box_run_p;
24321 glyph->right_box_line_p = it->end_of_box_run_p;
24323 glyph->overlaps_vertically_p = 0;
24324 glyph->padding_p = 0;
24325 glyph->glyph_not_available_p = 0;
24326 glyph->face_id = it->face_id;
24327 glyph->u.img_id = img->id;
24328 glyph->slice.img = slice;
24329 glyph->font_type = FONT_TYPE_UNKNOWN;
24330 if (it->bidi_p)
24332 glyph->resolved_level = it->bidi_it.resolved_level;
24333 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24334 emacs_abort ();
24335 glyph->bidi_type = it->bidi_it.type;
24337 ++it->glyph_row->used[area];
24339 else
24340 IT_EXPAND_MATRIX_WIDTH (it, area);
24345 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
24346 of the glyph, WIDTH and HEIGHT are the width and height of the
24347 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
24349 static void
24350 append_stretch_glyph (struct it *it, Lisp_Object object,
24351 int width, int height, int ascent)
24353 struct glyph *glyph;
24354 enum glyph_row_area area = it->area;
24356 eassert (ascent >= 0 && ascent <= height);
24358 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24359 if (glyph < it->glyph_row->glyphs[area + 1])
24361 /* If the glyph row is reversed, we need to prepend the glyph
24362 rather than append it. */
24363 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24365 struct glyph *g;
24367 /* Make room for the additional glyph. */
24368 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
24369 g[1] = *g;
24370 glyph = it->glyph_row->glyphs[area];
24372 glyph->charpos = CHARPOS (it->position);
24373 glyph->object = object;
24374 glyph->pixel_width = width;
24375 glyph->ascent = ascent;
24376 glyph->descent = height - ascent;
24377 glyph->voffset = it->voffset;
24378 glyph->type = STRETCH_GLYPH;
24379 glyph->avoid_cursor_p = it->avoid_cursor_p;
24380 glyph->multibyte_p = it->multibyte_p;
24381 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24383 /* In R2L rows, the left and the right box edges need to be
24384 drawn in reverse direction. */
24385 glyph->right_box_line_p = it->start_of_box_run_p;
24386 glyph->left_box_line_p = it->end_of_box_run_p;
24388 else
24390 glyph->left_box_line_p = it->start_of_box_run_p;
24391 glyph->right_box_line_p = it->end_of_box_run_p;
24393 glyph->overlaps_vertically_p = 0;
24394 glyph->padding_p = 0;
24395 glyph->glyph_not_available_p = 0;
24396 glyph->face_id = it->face_id;
24397 glyph->u.stretch.ascent = ascent;
24398 glyph->u.stretch.height = height;
24399 glyph->slice.img = null_glyph_slice;
24400 glyph->font_type = FONT_TYPE_UNKNOWN;
24401 if (it->bidi_p)
24403 glyph->resolved_level = it->bidi_it.resolved_level;
24404 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24405 emacs_abort ();
24406 glyph->bidi_type = it->bidi_it.type;
24408 else
24410 glyph->resolved_level = 0;
24411 glyph->bidi_type = UNKNOWN_BT;
24413 ++it->glyph_row->used[area];
24415 else
24416 IT_EXPAND_MATRIX_WIDTH (it, area);
24419 #endif /* HAVE_WINDOW_SYSTEM */
24421 /* Produce a stretch glyph for iterator IT. IT->object is the value
24422 of the glyph property displayed. The value must be a list
24423 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
24424 being recognized:
24426 1. `:width WIDTH' specifies that the space should be WIDTH *
24427 canonical char width wide. WIDTH may be an integer or floating
24428 point number.
24430 2. `:relative-width FACTOR' specifies that the width of the stretch
24431 should be computed from the width of the first character having the
24432 `glyph' property, and should be FACTOR times that width.
24434 3. `:align-to HPOS' specifies that the space should be wide enough
24435 to reach HPOS, a value in canonical character units.
24437 Exactly one of the above pairs must be present.
24439 4. `:height HEIGHT' specifies that the height of the stretch produced
24440 should be HEIGHT, measured in canonical character units.
24442 5. `:relative-height FACTOR' specifies that the height of the
24443 stretch should be FACTOR times the height of the characters having
24444 the glyph property.
24446 Either none or exactly one of 4 or 5 must be present.
24448 6. `:ascent ASCENT' specifies that ASCENT percent of the height
24449 of the stretch should be used for the ascent of the stretch.
24450 ASCENT must be in the range 0 <= ASCENT <= 100. */
24452 void
24453 produce_stretch_glyph (struct it *it)
24455 /* (space :width WIDTH :height HEIGHT ...) */
24456 Lisp_Object prop, plist;
24457 int width = 0, height = 0, align_to = -1;
24458 int zero_width_ok_p = 0;
24459 double tem;
24460 struct font *font = NULL;
24462 #ifdef HAVE_WINDOW_SYSTEM
24463 int ascent = 0;
24464 int zero_height_ok_p = 0;
24466 if (FRAME_WINDOW_P (it->f))
24468 struct face *face = FACE_FROM_ID (it->f, it->face_id);
24469 font = face->font ? face->font : FRAME_FONT (it->f);
24470 PREPARE_FACE_FOR_DISPLAY (it->f, face);
24472 #endif
24474 /* List should start with `space'. */
24475 eassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
24476 plist = XCDR (it->object);
24478 /* Compute the width of the stretch. */
24479 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
24480 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
24482 /* Absolute width `:width WIDTH' specified and valid. */
24483 zero_width_ok_p = 1;
24484 width = (int)tem;
24486 #ifdef HAVE_WINDOW_SYSTEM
24487 else if (FRAME_WINDOW_P (it->f)
24488 && (prop = Fplist_get (plist, QCrelative_width), NUMVAL (prop) > 0))
24490 /* Relative width `:relative-width FACTOR' specified and valid.
24491 Compute the width of the characters having the `glyph'
24492 property. */
24493 struct it it2;
24494 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
24496 it2 = *it;
24497 if (it->multibyte_p)
24498 it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
24499 else
24501 it2.c = it2.char_to_display = *p, it2.len = 1;
24502 if (! ASCII_CHAR_P (it2.c))
24503 it2.char_to_display = BYTE8_TO_CHAR (it2.c);
24506 it2.glyph_row = NULL;
24507 it2.what = IT_CHARACTER;
24508 x_produce_glyphs (&it2);
24509 width = NUMVAL (prop) * it2.pixel_width;
24511 #endif /* HAVE_WINDOW_SYSTEM */
24512 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
24513 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
24515 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
24516 align_to = (align_to < 0
24518 : align_to - window_box_left_offset (it->w, TEXT_AREA));
24519 else if (align_to < 0)
24520 align_to = window_box_left_offset (it->w, TEXT_AREA);
24521 width = max (0, (int)tem + align_to - it->current_x);
24522 zero_width_ok_p = 1;
24524 else
24525 /* Nothing specified -> width defaults to canonical char width. */
24526 width = FRAME_COLUMN_WIDTH (it->f);
24528 if (width <= 0 && (width < 0 || !zero_width_ok_p))
24529 width = 1;
24531 #ifdef HAVE_WINDOW_SYSTEM
24532 /* Compute height. */
24533 if (FRAME_WINDOW_P (it->f))
24535 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
24536 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
24538 height = (int)tem;
24539 zero_height_ok_p = 1;
24541 else if (prop = Fplist_get (plist, QCrelative_height),
24542 NUMVAL (prop) > 0)
24543 height = FONT_HEIGHT (font) * NUMVAL (prop);
24544 else
24545 height = FONT_HEIGHT (font);
24547 if (height <= 0 && (height < 0 || !zero_height_ok_p))
24548 height = 1;
24550 /* Compute percentage of height used for ascent. If
24551 `:ascent ASCENT' is present and valid, use that. Otherwise,
24552 derive the ascent from the font in use. */
24553 if (prop = Fplist_get (plist, QCascent),
24554 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
24555 ascent = height * NUMVAL (prop) / 100.0;
24556 else if (!NILP (prop)
24557 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
24558 ascent = min (max (0, (int)tem), height);
24559 else
24560 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
24562 else
24563 #endif /* HAVE_WINDOW_SYSTEM */
24564 height = 1;
24566 if (width > 0 && it->line_wrap != TRUNCATE
24567 && it->current_x + width > it->last_visible_x)
24569 width = it->last_visible_x - it->current_x;
24570 #ifdef HAVE_WINDOW_SYSTEM
24571 /* Subtract one more pixel from the stretch width, but only on
24572 GUI frames, since on a TTY each glyph is one "pixel" wide. */
24573 width -= FRAME_WINDOW_P (it->f);
24574 #endif
24577 if (width > 0 && height > 0 && it->glyph_row)
24579 Lisp_Object o_object = it->object;
24580 Lisp_Object object = it->stack[it->sp - 1].string;
24581 int n = width;
24583 if (!STRINGP (object))
24584 object = it->w->contents;
24585 #ifdef HAVE_WINDOW_SYSTEM
24586 if (FRAME_WINDOW_P (it->f))
24587 append_stretch_glyph (it, object, width, height, ascent);
24588 else
24589 #endif
24591 it->object = object;
24592 it->char_to_display = ' ';
24593 it->pixel_width = it->len = 1;
24594 while (n--)
24595 tty_append_glyph (it);
24596 it->object = o_object;
24600 it->pixel_width = width;
24601 #ifdef HAVE_WINDOW_SYSTEM
24602 if (FRAME_WINDOW_P (it->f))
24604 it->ascent = it->phys_ascent = ascent;
24605 it->descent = it->phys_descent = height - it->ascent;
24606 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
24607 take_vertical_position_into_account (it);
24609 else
24610 #endif
24611 it->nglyphs = width;
24614 /* Get information about special display element WHAT in an
24615 environment described by IT. WHAT is one of IT_TRUNCATION or
24616 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
24617 non-null glyph_row member. This function ensures that fields like
24618 face_id, c, len of IT are left untouched. */
24620 static void
24621 produce_special_glyphs (struct it *it, enum display_element_type what)
24623 struct it temp_it;
24624 Lisp_Object gc;
24625 GLYPH glyph;
24627 temp_it = *it;
24628 temp_it.object = make_number (0);
24629 memset (&temp_it.current, 0, sizeof temp_it.current);
24631 if (what == IT_CONTINUATION)
24633 /* Continuation glyph. For R2L lines, we mirror it by hand. */
24634 if (it->bidi_it.paragraph_dir == R2L)
24635 SET_GLYPH_FROM_CHAR (glyph, '/');
24636 else
24637 SET_GLYPH_FROM_CHAR (glyph, '\\');
24638 if (it->dp
24639 && (gc = DISP_CONTINUE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
24641 /* FIXME: Should we mirror GC for R2L lines? */
24642 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
24643 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
24646 else if (what == IT_TRUNCATION)
24648 /* Truncation glyph. */
24649 SET_GLYPH_FROM_CHAR (glyph, '$');
24650 if (it->dp
24651 && (gc = DISP_TRUNC_GLYPH (it->dp), GLYPH_CODE_P (gc)))
24653 /* FIXME: Should we mirror GC for R2L lines? */
24654 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
24655 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
24658 else
24659 emacs_abort ();
24661 #ifdef HAVE_WINDOW_SYSTEM
24662 /* On a GUI frame, when the right fringe (left fringe for R2L rows)
24663 is turned off, we precede the truncation/continuation glyphs by a
24664 stretch glyph whose width is computed such that these special
24665 glyphs are aligned at the window margin, even when very different
24666 fonts are used in different glyph rows. */
24667 if (FRAME_WINDOW_P (temp_it.f)
24668 /* init_iterator calls this with it->glyph_row == NULL, and it
24669 wants only the pixel width of the truncation/continuation
24670 glyphs. */
24671 && temp_it.glyph_row
24672 /* insert_left_trunc_glyphs calls us at the beginning of the
24673 row, and it has its own calculation of the stretch glyph
24674 width. */
24675 && temp_it.glyph_row->used[TEXT_AREA] > 0
24676 && (temp_it.glyph_row->reversed_p
24677 ? WINDOW_LEFT_FRINGE_WIDTH (temp_it.w)
24678 : WINDOW_RIGHT_FRINGE_WIDTH (temp_it.w)) == 0)
24680 int stretch_width = temp_it.last_visible_x - temp_it.current_x;
24682 if (stretch_width > 0)
24684 struct face *face = FACE_FROM_ID (temp_it.f, temp_it.face_id);
24685 struct font *font =
24686 face->font ? face->font : FRAME_FONT (temp_it.f);
24687 int stretch_ascent =
24688 (((temp_it.ascent + temp_it.descent)
24689 * FONT_BASE (font)) / FONT_HEIGHT (font));
24691 append_stretch_glyph (&temp_it, make_number (0), stretch_width,
24692 temp_it.ascent + temp_it.descent,
24693 stretch_ascent);
24696 #endif
24698 temp_it.dp = NULL;
24699 temp_it.what = IT_CHARACTER;
24700 temp_it.len = 1;
24701 temp_it.c = temp_it.char_to_display = GLYPH_CHAR (glyph);
24702 temp_it.face_id = GLYPH_FACE (glyph);
24703 temp_it.len = CHAR_BYTES (temp_it.c);
24705 PRODUCE_GLYPHS (&temp_it);
24706 it->pixel_width = temp_it.pixel_width;
24707 it->nglyphs = temp_it.pixel_width;
24710 #ifdef HAVE_WINDOW_SYSTEM
24712 /* Calculate line-height and line-spacing properties.
24713 An integer value specifies explicit pixel value.
24714 A float value specifies relative value to current face height.
24715 A cons (float . face-name) specifies relative value to
24716 height of specified face font.
24718 Returns height in pixels, or nil. */
24721 static Lisp_Object
24722 calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
24723 int boff, int override)
24725 Lisp_Object face_name = Qnil;
24726 int ascent, descent, height;
24728 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
24729 return val;
24731 if (CONSP (val))
24733 face_name = XCAR (val);
24734 val = XCDR (val);
24735 if (!NUMBERP (val))
24736 val = make_number (1);
24737 if (NILP (face_name))
24739 height = it->ascent + it->descent;
24740 goto scale;
24744 if (NILP (face_name))
24746 font = FRAME_FONT (it->f);
24747 boff = FRAME_BASELINE_OFFSET (it->f);
24749 else if (EQ (face_name, Qt))
24751 override = 0;
24753 else
24755 int face_id;
24756 struct face *face;
24758 face_id = lookup_named_face (it->f, face_name, 0);
24759 if (face_id < 0)
24760 return make_number (-1);
24762 face = FACE_FROM_ID (it->f, face_id);
24763 font = face->font;
24764 if (font == NULL)
24765 return make_number (-1);
24766 boff = font->baseline_offset;
24767 if (font->vertical_centering)
24768 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
24771 ascent = FONT_BASE (font) + boff;
24772 descent = FONT_DESCENT (font) - boff;
24774 if (override)
24776 it->override_ascent = ascent;
24777 it->override_descent = descent;
24778 it->override_boff = boff;
24781 height = ascent + descent;
24783 scale:
24784 if (FLOATP (val))
24785 height = (int)(XFLOAT_DATA (val) * height);
24786 else if (INTEGERP (val))
24787 height *= XINT (val);
24789 return make_number (height);
24793 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
24794 is a face ID to be used for the glyph. FOR_NO_FONT is nonzero if
24795 and only if this is for a character for which no font was found.
24797 If the display method (it->glyphless_method) is
24798 GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
24799 length of the acronym or the hexadecimal string, UPPER_XOFF and
24800 UPPER_YOFF are pixel offsets for the upper part of the string,
24801 LOWER_XOFF and LOWER_YOFF are for the lower part.
24803 For the other display methods, LEN through LOWER_YOFF are zero. */
24805 static void
24806 append_glyphless_glyph (struct it *it, int face_id, int for_no_font, int len,
24807 short upper_xoff, short upper_yoff,
24808 short lower_xoff, short lower_yoff)
24810 struct glyph *glyph;
24811 enum glyph_row_area area = it->area;
24813 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24814 if (glyph < it->glyph_row->glyphs[area + 1])
24816 /* If the glyph row is reversed, we need to prepend the glyph
24817 rather than append it. */
24818 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24820 struct glyph *g;
24822 /* Make room for the additional glyph. */
24823 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
24824 g[1] = *g;
24825 glyph = it->glyph_row->glyphs[area];
24827 glyph->charpos = CHARPOS (it->position);
24828 glyph->object = it->object;
24829 glyph->pixel_width = it->pixel_width;
24830 glyph->ascent = it->ascent;
24831 glyph->descent = it->descent;
24832 glyph->voffset = it->voffset;
24833 glyph->type = GLYPHLESS_GLYPH;
24834 glyph->u.glyphless.method = it->glyphless_method;
24835 glyph->u.glyphless.for_no_font = for_no_font;
24836 glyph->u.glyphless.len = len;
24837 glyph->u.glyphless.ch = it->c;
24838 glyph->slice.glyphless.upper_xoff = upper_xoff;
24839 glyph->slice.glyphless.upper_yoff = upper_yoff;
24840 glyph->slice.glyphless.lower_xoff = lower_xoff;
24841 glyph->slice.glyphless.lower_yoff = lower_yoff;
24842 glyph->avoid_cursor_p = it->avoid_cursor_p;
24843 glyph->multibyte_p = it->multibyte_p;
24844 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24846 /* In R2L rows, the left and the right box edges need to be
24847 drawn in reverse direction. */
24848 glyph->right_box_line_p = it->start_of_box_run_p;
24849 glyph->left_box_line_p = it->end_of_box_run_p;
24851 else
24853 glyph->left_box_line_p = it->start_of_box_run_p;
24854 glyph->right_box_line_p = it->end_of_box_run_p;
24856 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
24857 || it->phys_descent > it->descent);
24858 glyph->padding_p = 0;
24859 glyph->glyph_not_available_p = 0;
24860 glyph->face_id = face_id;
24861 glyph->font_type = FONT_TYPE_UNKNOWN;
24862 if (it->bidi_p)
24864 glyph->resolved_level = it->bidi_it.resolved_level;
24865 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24866 emacs_abort ();
24867 glyph->bidi_type = it->bidi_it.type;
24869 ++it->glyph_row->used[area];
24871 else
24872 IT_EXPAND_MATRIX_WIDTH (it, area);
24876 /* Produce a glyph for a glyphless character for iterator IT.
24877 IT->glyphless_method specifies which method to use for displaying
24878 the character. See the description of enum
24879 glyphless_display_method in dispextern.h for the detail.
24881 FOR_NO_FONT is nonzero if and only if this is for a character for
24882 which no font was found. ACRONYM, if non-nil, is an acronym string
24883 for the character. */
24885 static void
24886 produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
24888 int face_id;
24889 struct face *face;
24890 struct font *font;
24891 int base_width, base_height, width, height;
24892 short upper_xoff, upper_yoff, lower_xoff, lower_yoff;
24893 int len;
24895 /* Get the metrics of the base font. We always refer to the current
24896 ASCII face. */
24897 face = FACE_FROM_ID (it->f, it->face_id)->ascii_face;
24898 font = face->font ? face->font : FRAME_FONT (it->f);
24899 it->ascent = FONT_BASE (font) + font->baseline_offset;
24900 it->descent = FONT_DESCENT (font) - font->baseline_offset;
24901 base_height = it->ascent + it->descent;
24902 base_width = font->average_width;
24904 /* Get a face ID for the glyph by utilizing a cache (the same way as
24905 done for `escape-glyph' in get_next_display_element). */
24906 if (it->f == last_glyphless_glyph_frame
24907 && it->face_id == last_glyphless_glyph_face_id)
24909 face_id = last_glyphless_glyph_merged_face_id;
24911 else
24913 /* Merge the `glyphless-char' face into the current face. */
24914 face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
24915 last_glyphless_glyph_frame = it->f;
24916 last_glyphless_glyph_face_id = it->face_id;
24917 last_glyphless_glyph_merged_face_id = face_id;
24920 if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
24922 it->pixel_width = THIN_SPACE_WIDTH;
24923 len = 0;
24924 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
24926 else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX)
24928 width = CHAR_WIDTH (it->c);
24929 if (width == 0)
24930 width = 1;
24931 else if (width > 4)
24932 width = 4;
24933 it->pixel_width = base_width * width;
24934 len = 0;
24935 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
24937 else
24939 char buf[7];
24940 const char *str;
24941 unsigned int code[6];
24942 int upper_len;
24943 int ascent, descent;
24944 struct font_metrics metrics_upper, metrics_lower;
24946 face = FACE_FROM_ID (it->f, face_id);
24947 font = face->font ? face->font : FRAME_FONT (it->f);
24948 PREPARE_FACE_FOR_DISPLAY (it->f, face);
24950 if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM)
24952 if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
24953 acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
24954 if (CONSP (acronym))
24955 acronym = XCAR (acronym);
24956 str = STRINGP (acronym) ? SSDATA (acronym) : "";
24958 else
24960 eassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
24961 sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c);
24962 str = buf;
24964 for (len = 0; str[len] && ASCII_BYTE_P (str[len]) && len < 6; len++)
24965 code[len] = font->driver->encode_char (font, str[len]);
24966 upper_len = (len + 1) / 2;
24967 font->driver->text_extents (font, code, upper_len,
24968 &metrics_upper);
24969 font->driver->text_extents (font, code + upper_len, len - upper_len,
24970 &metrics_lower);
24974 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
24975 width = max (metrics_upper.width, metrics_lower.width) + 4;
24976 upper_xoff = upper_yoff = 2; /* the typical case */
24977 if (base_width >= width)
24979 /* Align the upper to the left, the lower to the right. */
24980 it->pixel_width = base_width;
24981 lower_xoff = base_width - 2 - metrics_lower.width;
24983 else
24985 /* Center the shorter one. */
24986 it->pixel_width = width;
24987 if (metrics_upper.width >= metrics_lower.width)
24988 lower_xoff = (width - metrics_lower.width) / 2;
24989 else
24991 /* FIXME: This code doesn't look right. It formerly was
24992 missing the "lower_xoff = 0;", which couldn't have
24993 been right since it left lower_xoff uninitialized. */
24994 lower_xoff = 0;
24995 upper_xoff = (width - metrics_upper.width) / 2;
24999 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
25000 top, bottom, and between upper and lower strings. */
25001 height = (metrics_upper.ascent + metrics_upper.descent
25002 + metrics_lower.ascent + metrics_lower.descent) + 5;
25003 /* Center vertically.
25004 H:base_height, D:base_descent
25005 h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent
25007 ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up
25008 descent = D - H/2 + h/2;
25009 lower_yoff = descent - 2 - ld;
25010 upper_yoff = lower_yoff - la - 1 - ud; */
25011 ascent = - (it->descent - (base_height + height + 1) / 2);
25012 descent = it->descent - (base_height - height) / 2;
25013 lower_yoff = descent - 2 - metrics_lower.descent;
25014 upper_yoff = (lower_yoff - metrics_lower.ascent - 1
25015 - metrics_upper.descent);
25016 /* Don't make the height shorter than the base height. */
25017 if (height > base_height)
25019 it->ascent = ascent;
25020 it->descent = descent;
25024 it->phys_ascent = it->ascent;
25025 it->phys_descent = it->descent;
25026 if (it->glyph_row)
25027 append_glyphless_glyph (it, face_id, for_no_font, len,
25028 upper_xoff, upper_yoff,
25029 lower_xoff, lower_yoff);
25030 it->nglyphs = 1;
25031 take_vertical_position_into_account (it);
25035 /* RIF:
25036 Produce glyphs/get display metrics for the display element IT is
25037 loaded with. See the description of struct it in dispextern.h
25038 for an overview of struct it. */
25040 void
25041 x_produce_glyphs (struct it *it)
25043 int extra_line_spacing = it->extra_line_spacing;
25045 it->glyph_not_available_p = 0;
25047 if (it->what == IT_CHARACTER)
25049 XChar2b char2b;
25050 struct face *face = FACE_FROM_ID (it->f, it->face_id);
25051 struct font *font = face->font;
25052 struct font_metrics *pcm = NULL;
25053 int boff; /* baseline offset */
25055 if (font == NULL)
25057 /* When no suitable font is found, display this character by
25058 the method specified in the first extra slot of
25059 Vglyphless_char_display. */
25060 Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
25062 eassert (it->what == IT_GLYPHLESS);
25063 produce_glyphless_glyph (it, 1, STRINGP (acronym) ? acronym : Qnil);
25064 goto done;
25067 boff = font->baseline_offset;
25068 if (font->vertical_centering)
25069 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
25071 if (it->char_to_display != '\n' && it->char_to_display != '\t')
25073 int stretched_p;
25075 it->nglyphs = 1;
25077 if (it->override_ascent >= 0)
25079 it->ascent = it->override_ascent;
25080 it->descent = it->override_descent;
25081 boff = it->override_boff;
25083 else
25085 it->ascent = FONT_BASE (font) + boff;
25086 it->descent = FONT_DESCENT (font) - boff;
25089 if (get_char_glyph_code (it->char_to_display, font, &char2b))
25091 pcm = get_per_char_metric (font, &char2b);
25092 if (pcm->width == 0
25093 && pcm->rbearing == 0 && pcm->lbearing == 0)
25094 pcm = NULL;
25097 if (pcm)
25099 it->phys_ascent = pcm->ascent + boff;
25100 it->phys_descent = pcm->descent - boff;
25101 it->pixel_width = pcm->width;
25103 else
25105 it->glyph_not_available_p = 1;
25106 it->phys_ascent = it->ascent;
25107 it->phys_descent = it->descent;
25108 it->pixel_width = font->space_width;
25111 if (it->constrain_row_ascent_descent_p)
25113 if (it->descent > it->max_descent)
25115 it->ascent += it->descent - it->max_descent;
25116 it->descent = it->max_descent;
25118 if (it->ascent > it->max_ascent)
25120 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
25121 it->ascent = it->max_ascent;
25123 it->phys_ascent = min (it->phys_ascent, it->ascent);
25124 it->phys_descent = min (it->phys_descent, it->descent);
25125 extra_line_spacing = 0;
25128 /* If this is a space inside a region of text with
25129 `space-width' property, change its width. */
25130 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
25131 if (stretched_p)
25132 it->pixel_width *= XFLOATINT (it->space_width);
25134 /* If face has a box, add the box thickness to the character
25135 height. If character has a box line to the left and/or
25136 right, add the box line width to the character's width. */
25137 if (face->box != FACE_NO_BOX)
25139 int thick = face->box_line_width;
25141 if (thick > 0)
25143 it->ascent += thick;
25144 it->descent += thick;
25146 else
25147 thick = -thick;
25149 if (it->start_of_box_run_p)
25150 it->pixel_width += thick;
25151 if (it->end_of_box_run_p)
25152 it->pixel_width += thick;
25155 /* If face has an overline, add the height of the overline
25156 (1 pixel) and a 1 pixel margin to the character height. */
25157 if (face->overline_p)
25158 it->ascent += overline_margin;
25160 if (it->constrain_row_ascent_descent_p)
25162 if (it->ascent > it->max_ascent)
25163 it->ascent = it->max_ascent;
25164 if (it->descent > it->max_descent)
25165 it->descent = it->max_descent;
25168 take_vertical_position_into_account (it);
25170 /* If we have to actually produce glyphs, do it. */
25171 if (it->glyph_row)
25173 if (stretched_p)
25175 /* Translate a space with a `space-width' property
25176 into a stretch glyph. */
25177 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
25178 / FONT_HEIGHT (font));
25179 append_stretch_glyph (it, it->object, it->pixel_width,
25180 it->ascent + it->descent, ascent);
25182 else
25183 append_glyph (it);
25185 /* If characters with lbearing or rbearing are displayed
25186 in this line, record that fact in a flag of the
25187 glyph row. This is used to optimize X output code. */
25188 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
25189 it->glyph_row->contains_overlapping_glyphs_p = 1;
25191 if (! stretched_p && it->pixel_width == 0)
25192 /* We assure that all visible glyphs have at least 1-pixel
25193 width. */
25194 it->pixel_width = 1;
25196 else if (it->char_to_display == '\n')
25198 /* A newline has no width, but we need the height of the
25199 line. But if previous part of the line sets a height,
25200 don't increase that height */
25202 Lisp_Object height;
25203 Lisp_Object total_height = Qnil;
25205 it->override_ascent = -1;
25206 it->pixel_width = 0;
25207 it->nglyphs = 0;
25209 height = get_it_property (it, Qline_height);
25210 /* Split (line-height total-height) list */
25211 if (CONSP (height)
25212 && CONSP (XCDR (height))
25213 && NILP (XCDR (XCDR (height))))
25215 total_height = XCAR (XCDR (height));
25216 height = XCAR (height);
25218 height = calc_line_height_property (it, height, font, boff, 1);
25220 if (it->override_ascent >= 0)
25222 it->ascent = it->override_ascent;
25223 it->descent = it->override_descent;
25224 boff = it->override_boff;
25226 else
25228 it->ascent = FONT_BASE (font) + boff;
25229 it->descent = FONT_DESCENT (font) - boff;
25232 if (EQ (height, Qt))
25234 if (it->descent > it->max_descent)
25236 it->ascent += it->descent - it->max_descent;
25237 it->descent = it->max_descent;
25239 if (it->ascent > it->max_ascent)
25241 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
25242 it->ascent = it->max_ascent;
25244 it->phys_ascent = min (it->phys_ascent, it->ascent);
25245 it->phys_descent = min (it->phys_descent, it->descent);
25246 it->constrain_row_ascent_descent_p = 1;
25247 extra_line_spacing = 0;
25249 else
25251 Lisp_Object spacing;
25253 it->phys_ascent = it->ascent;
25254 it->phys_descent = it->descent;
25256 if ((it->max_ascent > 0 || it->max_descent > 0)
25257 && face->box != FACE_NO_BOX
25258 && face->box_line_width > 0)
25260 it->ascent += face->box_line_width;
25261 it->descent += face->box_line_width;
25263 if (!NILP (height)
25264 && XINT (height) > it->ascent + it->descent)
25265 it->ascent = XINT (height) - it->descent;
25267 if (!NILP (total_height))
25268 spacing = calc_line_height_property (it, total_height, font, boff, 0);
25269 else
25271 spacing = get_it_property (it, Qline_spacing);
25272 spacing = calc_line_height_property (it, spacing, font, boff, 0);
25274 if (INTEGERP (spacing))
25276 extra_line_spacing = XINT (spacing);
25277 if (!NILP (total_height))
25278 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
25282 else /* i.e. (it->char_to_display == '\t') */
25284 if (font->space_width > 0)
25286 int tab_width = it->tab_width * font->space_width;
25287 int x = it->current_x + it->continuation_lines_width;
25288 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
25290 /* If the distance from the current position to the next tab
25291 stop is less than a space character width, use the
25292 tab stop after that. */
25293 if (next_tab_x - x < font->space_width)
25294 next_tab_x += tab_width;
25296 it->pixel_width = next_tab_x - x;
25297 it->nglyphs = 1;
25298 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
25299 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
25301 if (it->glyph_row)
25303 append_stretch_glyph (it, it->object, it->pixel_width,
25304 it->ascent + it->descent, it->ascent);
25307 else
25309 it->pixel_width = 0;
25310 it->nglyphs = 1;
25314 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
25316 /* A static composition.
25318 Note: A composition is represented as one glyph in the
25319 glyph matrix. There are no padding glyphs.
25321 Important note: pixel_width, ascent, and descent are the
25322 values of what is drawn by draw_glyphs (i.e. the values of
25323 the overall glyphs composed). */
25324 struct face *face = FACE_FROM_ID (it->f, it->face_id);
25325 int boff; /* baseline offset */
25326 struct composition *cmp = composition_table[it->cmp_it.id];
25327 int glyph_len = cmp->glyph_len;
25328 struct font *font = face->font;
25330 it->nglyphs = 1;
25332 /* If we have not yet calculated pixel size data of glyphs of
25333 the composition for the current face font, calculate them
25334 now. Theoretically, we have to check all fonts for the
25335 glyphs, but that requires much time and memory space. So,
25336 here we check only the font of the first glyph. This may
25337 lead to incorrect display, but it's very rare, and C-l
25338 (recenter-top-bottom) can correct the display anyway. */
25339 if (! cmp->font || cmp->font != font)
25341 /* Ascent and descent of the font of the first character
25342 of this composition (adjusted by baseline offset).
25343 Ascent and descent of overall glyphs should not be less
25344 than these, respectively. */
25345 int font_ascent, font_descent, font_height;
25346 /* Bounding box of the overall glyphs. */
25347 int leftmost, rightmost, lowest, highest;
25348 int lbearing, rbearing;
25349 int i, width, ascent, descent;
25350 int left_padded = 0, right_padded = 0;
25351 int c IF_LINT (= 0); /* cmp->glyph_len can't be zero; see Bug#8512 */
25352 XChar2b char2b;
25353 struct font_metrics *pcm;
25354 int font_not_found_p;
25355 ptrdiff_t pos;
25357 for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
25358 if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
25359 break;
25360 if (glyph_len < cmp->glyph_len)
25361 right_padded = 1;
25362 for (i = 0; i < glyph_len; i++)
25364 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
25365 break;
25366 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
25368 if (i > 0)
25369 left_padded = 1;
25371 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
25372 : IT_CHARPOS (*it));
25373 /* If no suitable font is found, use the default font. */
25374 font_not_found_p = font == NULL;
25375 if (font_not_found_p)
25377 face = face->ascii_face;
25378 font = face->font;
25380 boff = font->baseline_offset;
25381 if (font->vertical_centering)
25382 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
25383 font_ascent = FONT_BASE (font) + boff;
25384 font_descent = FONT_DESCENT (font) - boff;
25385 font_height = FONT_HEIGHT (font);
25387 cmp->font = font;
25389 pcm = NULL;
25390 if (! font_not_found_p)
25392 get_char_face_and_encoding (it->f, c, it->face_id,
25393 &char2b, 0);
25394 pcm = get_per_char_metric (font, &char2b);
25397 /* Initialize the bounding box. */
25398 if (pcm)
25400 width = cmp->glyph_len > 0 ? pcm->width : 0;
25401 ascent = pcm->ascent;
25402 descent = pcm->descent;
25403 lbearing = pcm->lbearing;
25404 rbearing = pcm->rbearing;
25406 else
25408 width = cmp->glyph_len > 0 ? font->space_width : 0;
25409 ascent = FONT_BASE (font);
25410 descent = FONT_DESCENT (font);
25411 lbearing = 0;
25412 rbearing = width;
25415 rightmost = width;
25416 leftmost = 0;
25417 lowest = - descent + boff;
25418 highest = ascent + boff;
25420 if (! font_not_found_p
25421 && font->default_ascent
25422 && CHAR_TABLE_P (Vuse_default_ascent)
25423 && !NILP (Faref (Vuse_default_ascent,
25424 make_number (it->char_to_display))))
25425 highest = font->default_ascent + boff;
25427 /* Draw the first glyph at the normal position. It may be
25428 shifted to right later if some other glyphs are drawn
25429 at the left. */
25430 cmp->offsets[i * 2] = 0;
25431 cmp->offsets[i * 2 + 1] = boff;
25432 cmp->lbearing = lbearing;
25433 cmp->rbearing = rbearing;
25435 /* Set cmp->offsets for the remaining glyphs. */
25436 for (i++; i < glyph_len; i++)
25438 int left, right, btm, top;
25439 int ch = COMPOSITION_GLYPH (cmp, i);
25440 int face_id;
25441 struct face *this_face;
25443 if (ch == '\t')
25444 ch = ' ';
25445 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
25446 this_face = FACE_FROM_ID (it->f, face_id);
25447 font = this_face->font;
25449 if (font == NULL)
25450 pcm = NULL;
25451 else
25453 get_char_face_and_encoding (it->f, ch, face_id,
25454 &char2b, 0);
25455 pcm = get_per_char_metric (font, &char2b);
25457 if (! pcm)
25458 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
25459 else
25461 width = pcm->width;
25462 ascent = pcm->ascent;
25463 descent = pcm->descent;
25464 lbearing = pcm->lbearing;
25465 rbearing = pcm->rbearing;
25466 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
25468 /* Relative composition with or without
25469 alternate chars. */
25470 left = (leftmost + rightmost - width) / 2;
25471 btm = - descent + boff;
25472 if (font->relative_compose
25473 && (! CHAR_TABLE_P (Vignore_relative_composition)
25474 || NILP (Faref (Vignore_relative_composition,
25475 make_number (ch)))))
25478 if (- descent >= font->relative_compose)
25479 /* One extra pixel between two glyphs. */
25480 btm = highest + 1;
25481 else if (ascent <= 0)
25482 /* One extra pixel between two glyphs. */
25483 btm = lowest - 1 - ascent - descent;
25486 else
25488 /* A composition rule is specified by an integer
25489 value that encodes global and new reference
25490 points (GREF and NREF). GREF and NREF are
25491 specified by numbers as below:
25493 0---1---2 -- ascent
25497 9--10--11 -- center
25499 ---3---4---5--- baseline
25501 6---7---8 -- descent
25503 int rule = COMPOSITION_RULE (cmp, i);
25504 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
25506 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
25507 grefx = gref % 3, nrefx = nref % 3;
25508 grefy = gref / 3, nrefy = nref / 3;
25509 if (xoff)
25510 xoff = font_height * (xoff - 128) / 256;
25511 if (yoff)
25512 yoff = font_height * (yoff - 128) / 256;
25514 left = (leftmost
25515 + grefx * (rightmost - leftmost) / 2
25516 - nrefx * width / 2
25517 + xoff);
25519 btm = ((grefy == 0 ? highest
25520 : grefy == 1 ? 0
25521 : grefy == 2 ? lowest
25522 : (highest + lowest) / 2)
25523 - (nrefy == 0 ? ascent + descent
25524 : nrefy == 1 ? descent - boff
25525 : nrefy == 2 ? 0
25526 : (ascent + descent) / 2)
25527 + yoff);
25530 cmp->offsets[i * 2] = left;
25531 cmp->offsets[i * 2 + 1] = btm + descent;
25533 /* Update the bounding box of the overall glyphs. */
25534 if (width > 0)
25536 right = left + width;
25537 if (left < leftmost)
25538 leftmost = left;
25539 if (right > rightmost)
25540 rightmost = right;
25542 top = btm + descent + ascent;
25543 if (top > highest)
25544 highest = top;
25545 if (btm < lowest)
25546 lowest = btm;
25548 if (cmp->lbearing > left + lbearing)
25549 cmp->lbearing = left + lbearing;
25550 if (cmp->rbearing < left + rbearing)
25551 cmp->rbearing = left + rbearing;
25555 /* If there are glyphs whose x-offsets are negative,
25556 shift all glyphs to the right and make all x-offsets
25557 non-negative. */
25558 if (leftmost < 0)
25560 for (i = 0; i < cmp->glyph_len; i++)
25561 cmp->offsets[i * 2] -= leftmost;
25562 rightmost -= leftmost;
25563 cmp->lbearing -= leftmost;
25564 cmp->rbearing -= leftmost;
25567 if (left_padded && cmp->lbearing < 0)
25569 for (i = 0; i < cmp->glyph_len; i++)
25570 cmp->offsets[i * 2] -= cmp->lbearing;
25571 rightmost -= cmp->lbearing;
25572 cmp->rbearing -= cmp->lbearing;
25573 cmp->lbearing = 0;
25575 if (right_padded && rightmost < cmp->rbearing)
25577 rightmost = cmp->rbearing;
25580 cmp->pixel_width = rightmost;
25581 cmp->ascent = highest;
25582 cmp->descent = - lowest;
25583 if (cmp->ascent < font_ascent)
25584 cmp->ascent = font_ascent;
25585 if (cmp->descent < font_descent)
25586 cmp->descent = font_descent;
25589 if (it->glyph_row
25590 && (cmp->lbearing < 0
25591 || cmp->rbearing > cmp->pixel_width))
25592 it->glyph_row->contains_overlapping_glyphs_p = 1;
25594 it->pixel_width = cmp->pixel_width;
25595 it->ascent = it->phys_ascent = cmp->ascent;
25596 it->descent = it->phys_descent = cmp->descent;
25597 if (face->box != FACE_NO_BOX)
25599 int thick = face->box_line_width;
25601 if (thick > 0)
25603 it->ascent += thick;
25604 it->descent += thick;
25606 else
25607 thick = - thick;
25609 if (it->start_of_box_run_p)
25610 it->pixel_width += thick;
25611 if (it->end_of_box_run_p)
25612 it->pixel_width += thick;
25615 /* If face has an overline, add the height of the overline
25616 (1 pixel) and a 1 pixel margin to the character height. */
25617 if (face->overline_p)
25618 it->ascent += overline_margin;
25620 take_vertical_position_into_account (it);
25621 if (it->ascent < 0)
25622 it->ascent = 0;
25623 if (it->descent < 0)
25624 it->descent = 0;
25626 if (it->glyph_row && cmp->glyph_len > 0)
25627 append_composite_glyph (it);
25629 else if (it->what == IT_COMPOSITION)
25631 /* A dynamic (automatic) composition. */
25632 struct face *face = FACE_FROM_ID (it->f, it->face_id);
25633 Lisp_Object gstring;
25634 struct font_metrics metrics;
25636 it->nglyphs = 1;
25638 gstring = composition_gstring_from_id (it->cmp_it.id);
25639 it->pixel_width
25640 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
25641 &metrics);
25642 if (it->glyph_row
25643 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
25644 it->glyph_row->contains_overlapping_glyphs_p = 1;
25645 it->ascent = it->phys_ascent = metrics.ascent;
25646 it->descent = it->phys_descent = metrics.descent;
25647 if (face->box != FACE_NO_BOX)
25649 int thick = face->box_line_width;
25651 if (thick > 0)
25653 it->ascent += thick;
25654 it->descent += thick;
25656 else
25657 thick = - thick;
25659 if (it->start_of_box_run_p)
25660 it->pixel_width += thick;
25661 if (it->end_of_box_run_p)
25662 it->pixel_width += thick;
25664 /* If face has an overline, add the height of the overline
25665 (1 pixel) and a 1 pixel margin to the character height. */
25666 if (face->overline_p)
25667 it->ascent += overline_margin;
25668 take_vertical_position_into_account (it);
25669 if (it->ascent < 0)
25670 it->ascent = 0;
25671 if (it->descent < 0)
25672 it->descent = 0;
25674 if (it->glyph_row)
25675 append_composite_glyph (it);
25677 else if (it->what == IT_GLYPHLESS)
25678 produce_glyphless_glyph (it, 0, Qnil);
25679 else if (it->what == IT_IMAGE)
25680 produce_image_glyph (it);
25681 else if (it->what == IT_STRETCH)
25682 produce_stretch_glyph (it);
25684 done:
25685 /* Accumulate dimensions. Note: can't assume that it->descent > 0
25686 because this isn't true for images with `:ascent 100'. */
25687 eassert (it->ascent >= 0 && it->descent >= 0);
25688 if (it->area == TEXT_AREA)
25689 it->current_x += it->pixel_width;
25691 if (extra_line_spacing > 0)
25693 it->descent += extra_line_spacing;
25694 if (extra_line_spacing > it->max_extra_line_spacing)
25695 it->max_extra_line_spacing = extra_line_spacing;
25698 it->max_ascent = max (it->max_ascent, it->ascent);
25699 it->max_descent = max (it->max_descent, it->descent);
25700 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
25701 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
25704 /* EXPORT for RIF:
25705 Output LEN glyphs starting at START at the nominal cursor position.
25706 Advance the nominal cursor over the text. The global variable
25707 updated_window contains the window being updated, updated_row is
25708 the glyph row being updated, and updated_area is the area of that
25709 row being updated. */
25711 void
25712 x_write_glyphs (struct glyph *start, int len)
25714 int x, hpos, chpos = updated_window->phys_cursor.hpos;
25716 eassert (updated_window && updated_row);
25717 /* When the window is hscrolled, cursor hpos can legitimately be out
25718 of bounds, but we draw the cursor at the corresponding window
25719 margin in that case. */
25720 if (!updated_row->reversed_p && chpos < 0)
25721 chpos = 0;
25722 if (updated_row->reversed_p && chpos >= updated_row->used[TEXT_AREA])
25723 chpos = updated_row->used[TEXT_AREA] - 1;
25725 block_input ();
25727 /* Write glyphs. */
25729 hpos = start - updated_row->glyphs[updated_area];
25730 x = draw_glyphs (updated_window, output_cursor.x,
25731 updated_row, updated_area,
25732 hpos, hpos + len,
25733 DRAW_NORMAL_TEXT, 0);
25735 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
25736 if (updated_area == TEXT_AREA
25737 && updated_window->phys_cursor_on_p
25738 && updated_window->phys_cursor.vpos == output_cursor.vpos
25739 && chpos >= hpos
25740 && chpos < hpos + len)
25741 updated_window->phys_cursor_on_p = 0;
25743 unblock_input ();
25745 /* Advance the output cursor. */
25746 output_cursor.hpos += len;
25747 output_cursor.x = x;
25751 /* EXPORT for RIF:
25752 Insert LEN glyphs from START at the nominal cursor position. */
25754 void
25755 x_insert_glyphs (struct glyph *start, int len)
25757 struct frame *f;
25758 struct window *w;
25759 int line_height, shift_by_width, shifted_region_width;
25760 struct glyph_row *row;
25761 struct glyph *glyph;
25762 int frame_x, frame_y;
25763 ptrdiff_t hpos;
25765 eassert (updated_window && updated_row);
25766 block_input ();
25767 w = updated_window;
25768 f = XFRAME (WINDOW_FRAME (w));
25770 /* Get the height of the line we are in. */
25771 row = updated_row;
25772 line_height = row->height;
25774 /* Get the width of the glyphs to insert. */
25775 shift_by_width = 0;
25776 for (glyph = start; glyph < start + len; ++glyph)
25777 shift_by_width += glyph->pixel_width;
25779 /* Get the width of the region to shift right. */
25780 shifted_region_width = (window_box_width (w, updated_area)
25781 - output_cursor.x
25782 - shift_by_width);
25784 /* Shift right. */
25785 frame_x = window_box_left (w, updated_area) + output_cursor.x;
25786 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
25788 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
25789 line_height, shift_by_width);
25791 /* Write the glyphs. */
25792 hpos = start - row->glyphs[updated_area];
25793 draw_glyphs (w, output_cursor.x, row, updated_area,
25794 hpos, hpos + len,
25795 DRAW_NORMAL_TEXT, 0);
25797 /* Advance the output cursor. */
25798 output_cursor.hpos += len;
25799 output_cursor.x += shift_by_width;
25800 unblock_input ();
25804 /* EXPORT for RIF:
25805 Erase the current text line from the nominal cursor position
25806 (inclusive) to pixel column TO_X (exclusive). The idea is that
25807 everything from TO_X onward is already erased.
25809 TO_X is a pixel position relative to updated_area of
25810 updated_window. TO_X == -1 means clear to the end of this area. */
25812 void
25813 x_clear_end_of_line (int to_x)
25815 struct frame *f;
25816 struct window *w = updated_window;
25817 int max_x, min_y, max_y;
25818 int from_x, from_y, to_y;
25820 eassert (updated_window && updated_row);
25821 f = XFRAME (w->frame);
25823 if (updated_row->full_width_p)
25824 max_x = WINDOW_TOTAL_WIDTH (w);
25825 else
25826 max_x = window_box_width (w, updated_area);
25827 max_y = window_text_bottom_y (w);
25829 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
25830 of window. For TO_X > 0, truncate to end of drawing area. */
25831 if (to_x == 0)
25832 return;
25833 else if (to_x < 0)
25834 to_x = max_x;
25835 else
25836 to_x = min (to_x, max_x);
25838 to_y = min (max_y, output_cursor.y + updated_row->height);
25840 /* Notice if the cursor will be cleared by this operation. */
25841 if (!updated_row->full_width_p)
25842 notice_overwritten_cursor (w, updated_area,
25843 output_cursor.x, -1,
25844 updated_row->y,
25845 MATRIX_ROW_BOTTOM_Y (updated_row));
25847 from_x = output_cursor.x;
25849 /* Translate to frame coordinates. */
25850 if (updated_row->full_width_p)
25852 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
25853 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
25855 else
25857 int area_left = window_box_left (w, updated_area);
25858 from_x += area_left;
25859 to_x += area_left;
25862 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
25863 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
25864 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
25866 /* Prevent inadvertently clearing to end of the X window. */
25867 if (to_x > from_x && to_y > from_y)
25869 block_input ();
25870 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
25871 to_x - from_x, to_y - from_y);
25872 unblock_input ();
25876 #endif /* HAVE_WINDOW_SYSTEM */
25880 /***********************************************************************
25881 Cursor types
25882 ***********************************************************************/
25884 /* Value is the internal representation of the specified cursor type
25885 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
25886 of the bar cursor. */
25888 static enum text_cursor_kinds
25889 get_specified_cursor_type (Lisp_Object arg, int *width)
25891 enum text_cursor_kinds type;
25893 if (NILP (arg))
25894 return NO_CURSOR;
25896 if (EQ (arg, Qbox))
25897 return FILLED_BOX_CURSOR;
25899 if (EQ (arg, Qhollow))
25900 return HOLLOW_BOX_CURSOR;
25902 if (EQ (arg, Qbar))
25904 *width = 2;
25905 return BAR_CURSOR;
25908 if (CONSP (arg)
25909 && EQ (XCAR (arg), Qbar)
25910 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
25912 *width = XINT (XCDR (arg));
25913 return BAR_CURSOR;
25916 if (EQ (arg, Qhbar))
25918 *width = 2;
25919 return HBAR_CURSOR;
25922 if (CONSP (arg)
25923 && EQ (XCAR (arg), Qhbar)
25924 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
25926 *width = XINT (XCDR (arg));
25927 return HBAR_CURSOR;
25930 /* Treat anything unknown as "hollow box cursor".
25931 It was bad to signal an error; people have trouble fixing
25932 .Xdefaults with Emacs, when it has something bad in it. */
25933 type = HOLLOW_BOX_CURSOR;
25935 return type;
25938 /* Set the default cursor types for specified frame. */
25939 void
25940 set_frame_cursor_types (struct frame *f, Lisp_Object arg)
25942 int width = 1;
25943 Lisp_Object tem;
25945 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
25946 FRAME_CURSOR_WIDTH (f) = width;
25948 /* By default, set up the blink-off state depending on the on-state. */
25950 tem = Fassoc (arg, Vblink_cursor_alist);
25951 if (!NILP (tem))
25953 FRAME_BLINK_OFF_CURSOR (f)
25954 = get_specified_cursor_type (XCDR (tem), &width);
25955 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
25957 else
25958 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
25962 #ifdef HAVE_WINDOW_SYSTEM
25964 /* Return the cursor we want to be displayed in window W. Return
25965 width of bar/hbar cursor through WIDTH arg. Return with
25966 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
25967 (i.e. if the `system caret' should track this cursor).
25969 In a mini-buffer window, we want the cursor only to appear if we
25970 are reading input from this window. For the selected window, we
25971 want the cursor type given by the frame parameter or buffer local
25972 setting of cursor-type. If explicitly marked off, draw no cursor.
25973 In all other cases, we want a hollow box cursor. */
25975 static enum text_cursor_kinds
25976 get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
25977 int *active_cursor)
25979 struct frame *f = XFRAME (w->frame);
25980 struct buffer *b = XBUFFER (w->contents);
25981 int cursor_type = DEFAULT_CURSOR;
25982 Lisp_Object alt_cursor;
25983 int non_selected = 0;
25985 *active_cursor = 1;
25987 /* Echo area */
25988 if (cursor_in_echo_area
25989 && FRAME_HAS_MINIBUF_P (f)
25990 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
25992 if (w == XWINDOW (echo_area_window))
25994 if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
25996 *width = FRAME_CURSOR_WIDTH (f);
25997 return FRAME_DESIRED_CURSOR (f);
25999 else
26000 return get_specified_cursor_type (BVAR (b, cursor_type), width);
26003 *active_cursor = 0;
26004 non_selected = 1;
26007 /* Detect a nonselected window or nonselected frame. */
26008 else if (w != XWINDOW (f->selected_window)
26009 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame)
26011 *active_cursor = 0;
26013 if (MINI_WINDOW_P (w) && minibuf_level == 0)
26014 return NO_CURSOR;
26016 non_selected = 1;
26019 /* Never display a cursor in a window in which cursor-type is nil. */
26020 if (NILP (BVAR (b, cursor_type)))
26021 return NO_CURSOR;
26023 /* Get the normal cursor type for this window. */
26024 if (EQ (BVAR (b, cursor_type), Qt))
26026 cursor_type = FRAME_DESIRED_CURSOR (f);
26027 *width = FRAME_CURSOR_WIDTH (f);
26029 else
26030 cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
26032 /* Use cursor-in-non-selected-windows instead
26033 for non-selected window or frame. */
26034 if (non_selected)
26036 alt_cursor = BVAR (b, cursor_in_non_selected_windows);
26037 if (!EQ (Qt, alt_cursor))
26038 return get_specified_cursor_type (alt_cursor, width);
26039 /* t means modify the normal cursor type. */
26040 if (cursor_type == FILLED_BOX_CURSOR)
26041 cursor_type = HOLLOW_BOX_CURSOR;
26042 else if (cursor_type == BAR_CURSOR && *width > 1)
26043 --*width;
26044 return cursor_type;
26047 /* Use normal cursor if not blinked off. */
26048 if (!w->cursor_off_p)
26050 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
26052 if (cursor_type == FILLED_BOX_CURSOR)
26054 /* Using a block cursor on large images can be very annoying.
26055 So use a hollow cursor for "large" images.
26056 If image is not transparent (no mask), also use hollow cursor. */
26057 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
26058 if (img != NULL && IMAGEP (img->spec))
26060 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
26061 where N = size of default frame font size.
26062 This should cover most of the "tiny" icons people may use. */
26063 if (!img->mask
26064 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
26065 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
26066 cursor_type = HOLLOW_BOX_CURSOR;
26069 else if (cursor_type != NO_CURSOR)
26071 /* Display current only supports BOX and HOLLOW cursors for images.
26072 So for now, unconditionally use a HOLLOW cursor when cursor is
26073 not a solid box cursor. */
26074 cursor_type = HOLLOW_BOX_CURSOR;
26077 return cursor_type;
26080 /* Cursor is blinked off, so determine how to "toggle" it. */
26082 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
26083 if ((alt_cursor = Fassoc (BVAR (b, cursor_type), Vblink_cursor_alist), !NILP (alt_cursor)))
26084 return get_specified_cursor_type (XCDR (alt_cursor), width);
26086 /* Then see if frame has specified a specific blink off cursor type. */
26087 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
26089 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
26090 return FRAME_BLINK_OFF_CURSOR (f);
26093 #if 0
26094 /* Some people liked having a permanently visible blinking cursor,
26095 while others had very strong opinions against it. So it was
26096 decided to remove it. KFS 2003-09-03 */
26098 /* Finally perform built-in cursor blinking:
26099 filled box <-> hollow box
26100 wide [h]bar <-> narrow [h]bar
26101 narrow [h]bar <-> no cursor
26102 other type <-> no cursor */
26104 if (cursor_type == FILLED_BOX_CURSOR)
26105 return HOLLOW_BOX_CURSOR;
26107 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
26109 *width = 1;
26110 return cursor_type;
26112 #endif
26114 return NO_CURSOR;
26118 /* Notice when the text cursor of window W has been completely
26119 overwritten by a drawing operation that outputs glyphs in AREA
26120 starting at X0 and ending at X1 in the line starting at Y0 and
26121 ending at Y1. X coordinates are area-relative. X1 < 0 means all
26122 the rest of the line after X0 has been written. Y coordinates
26123 are window-relative. */
26125 static void
26126 notice_overwritten_cursor (struct window *w, enum glyph_row_area area,
26127 int x0, int x1, int y0, int y1)
26129 int cx0, cx1, cy0, cy1;
26130 struct glyph_row *row;
26132 if (!w->phys_cursor_on_p)
26133 return;
26134 if (area != TEXT_AREA)
26135 return;
26137 if (w->phys_cursor.vpos < 0
26138 || w->phys_cursor.vpos >= w->current_matrix->nrows
26139 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
26140 !(row->enabled_p && MATRIX_ROW_DISPLAYS_TEXT_P (row))))
26141 return;
26143 if (row->cursor_in_fringe_p)
26145 row->cursor_in_fringe_p = 0;
26146 draw_fringe_bitmap (w, row, row->reversed_p);
26147 w->phys_cursor_on_p = 0;
26148 return;
26151 cx0 = w->phys_cursor.x;
26152 cx1 = cx0 + w->phys_cursor_width;
26153 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
26154 return;
26156 /* The cursor image will be completely removed from the
26157 screen if the output area intersects the cursor area in
26158 y-direction. When we draw in [y0 y1[, and some part of
26159 the cursor is at y < y0, that part must have been drawn
26160 before. When scrolling, the cursor is erased before
26161 actually scrolling, so we don't come here. When not
26162 scrolling, the rows above the old cursor row must have
26163 changed, and in this case these rows must have written
26164 over the cursor image.
26166 Likewise if part of the cursor is below y1, with the
26167 exception of the cursor being in the first blank row at
26168 the buffer and window end because update_text_area
26169 doesn't draw that row. (Except when it does, but
26170 that's handled in update_text_area.) */
26172 cy0 = w->phys_cursor.y;
26173 cy1 = cy0 + w->phys_cursor_height;
26174 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
26175 return;
26177 w->phys_cursor_on_p = 0;
26180 #endif /* HAVE_WINDOW_SYSTEM */
26183 /************************************************************************
26184 Mouse Face
26185 ************************************************************************/
26187 #ifdef HAVE_WINDOW_SYSTEM
26189 /* EXPORT for RIF:
26190 Fix the display of area AREA of overlapping row ROW in window W
26191 with respect to the overlapping part OVERLAPS. */
26193 void
26194 x_fix_overlapping_area (struct window *w, struct glyph_row *row,
26195 enum glyph_row_area area, int overlaps)
26197 int i, x;
26199 block_input ();
26201 x = 0;
26202 for (i = 0; i < row->used[area];)
26204 if (row->glyphs[area][i].overlaps_vertically_p)
26206 int start = i, start_x = x;
26210 x += row->glyphs[area][i].pixel_width;
26211 ++i;
26213 while (i < row->used[area]
26214 && row->glyphs[area][i].overlaps_vertically_p);
26216 draw_glyphs (w, start_x, row, area,
26217 start, i,
26218 DRAW_NORMAL_TEXT, overlaps);
26220 else
26222 x += row->glyphs[area][i].pixel_width;
26223 ++i;
26227 unblock_input ();
26231 /* EXPORT:
26232 Draw the cursor glyph of window W in glyph row ROW. See the
26233 comment of draw_glyphs for the meaning of HL. */
26235 void
26236 draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
26237 enum draw_glyphs_face hl)
26239 /* If cursor hpos is out of bounds, don't draw garbage. This can
26240 happen in mini-buffer windows when switching between echo area
26241 glyphs and mini-buffer. */
26242 if ((row->reversed_p
26243 ? (w->phys_cursor.hpos >= 0)
26244 : (w->phys_cursor.hpos < row->used[TEXT_AREA])))
26246 int on_p = w->phys_cursor_on_p;
26247 int x1;
26248 int hpos = w->phys_cursor.hpos;
26250 /* When the window is hscrolled, cursor hpos can legitimately be
26251 out of bounds, but we draw the cursor at the corresponding
26252 window margin in that case. */
26253 if (!row->reversed_p && hpos < 0)
26254 hpos = 0;
26255 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26256 hpos = row->used[TEXT_AREA] - 1;
26258 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA, hpos, hpos + 1,
26259 hl, 0);
26260 w->phys_cursor_on_p = on_p;
26262 if (hl == DRAW_CURSOR)
26263 w->phys_cursor_width = x1 - w->phys_cursor.x;
26264 /* When we erase the cursor, and ROW is overlapped by other
26265 rows, make sure that these overlapping parts of other rows
26266 are redrawn. */
26267 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
26269 w->phys_cursor_width = x1 - w->phys_cursor.x;
26271 if (row > w->current_matrix->rows
26272 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
26273 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
26274 OVERLAPS_ERASED_CURSOR);
26276 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
26277 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
26278 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
26279 OVERLAPS_ERASED_CURSOR);
26285 /* EXPORT:
26286 Erase the image of a cursor of window W from the screen. */
26288 void
26289 erase_phys_cursor (struct window *w)
26291 struct frame *f = XFRAME (w->frame);
26292 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
26293 int hpos = w->phys_cursor.hpos;
26294 int vpos = w->phys_cursor.vpos;
26295 int mouse_face_here_p = 0;
26296 struct glyph_matrix *active_glyphs = w->current_matrix;
26297 struct glyph_row *cursor_row;
26298 struct glyph *cursor_glyph;
26299 enum draw_glyphs_face hl;
26301 /* No cursor displayed or row invalidated => nothing to do on the
26302 screen. */
26303 if (w->phys_cursor_type == NO_CURSOR)
26304 goto mark_cursor_off;
26306 /* VPOS >= active_glyphs->nrows means that window has been resized.
26307 Don't bother to erase the cursor. */
26308 if (vpos >= active_glyphs->nrows)
26309 goto mark_cursor_off;
26311 /* If row containing cursor is marked invalid, there is nothing we
26312 can do. */
26313 cursor_row = MATRIX_ROW (active_glyphs, vpos);
26314 if (!cursor_row->enabled_p)
26315 goto mark_cursor_off;
26317 /* If line spacing is > 0, old cursor may only be partially visible in
26318 window after split-window. So adjust visible height. */
26319 cursor_row->visible_height = min (cursor_row->visible_height,
26320 window_text_bottom_y (w) - cursor_row->y);
26322 /* If row is completely invisible, don't attempt to delete a cursor which
26323 isn't there. This can happen if cursor is at top of a window, and
26324 we switch to a buffer with a header line in that window. */
26325 if (cursor_row->visible_height <= 0)
26326 goto mark_cursor_off;
26328 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
26329 if (cursor_row->cursor_in_fringe_p)
26331 cursor_row->cursor_in_fringe_p = 0;
26332 draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
26333 goto mark_cursor_off;
26336 /* This can happen when the new row is shorter than the old one.
26337 In this case, either draw_glyphs or clear_end_of_line
26338 should have cleared the cursor. Note that we wouldn't be
26339 able to erase the cursor in this case because we don't have a
26340 cursor glyph at hand. */
26341 if ((cursor_row->reversed_p
26342 ? (w->phys_cursor.hpos < 0)
26343 : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
26344 goto mark_cursor_off;
26346 /* When the window is hscrolled, cursor hpos can legitimately be out
26347 of bounds, but we draw the cursor at the corresponding window
26348 margin in that case. */
26349 if (!cursor_row->reversed_p && hpos < 0)
26350 hpos = 0;
26351 if (cursor_row->reversed_p && hpos >= cursor_row->used[TEXT_AREA])
26352 hpos = cursor_row->used[TEXT_AREA] - 1;
26354 /* If the cursor is in the mouse face area, redisplay that when
26355 we clear the cursor. */
26356 if (! NILP (hlinfo->mouse_face_window)
26357 && coords_in_mouse_face_p (w, hpos, vpos)
26358 /* Don't redraw the cursor's spot in mouse face if it is at the
26359 end of a line (on a newline). The cursor appears there, but
26360 mouse highlighting does not. */
26361 && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
26362 mouse_face_here_p = 1;
26364 /* Maybe clear the display under the cursor. */
26365 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
26367 int x, y, left_x;
26368 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
26369 int width;
26371 cursor_glyph = get_phys_cursor_glyph (w);
26372 if (cursor_glyph == NULL)
26373 goto mark_cursor_off;
26375 width = cursor_glyph->pixel_width;
26376 left_x = window_box_left_offset (w, TEXT_AREA);
26377 x = w->phys_cursor.x;
26378 if (x < left_x)
26379 width -= left_x - x;
26380 width = min (width, window_box_width (w, TEXT_AREA) - x);
26381 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
26382 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
26384 if (width > 0)
26385 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
26388 /* Erase the cursor by redrawing the character underneath it. */
26389 if (mouse_face_here_p)
26390 hl = DRAW_MOUSE_FACE;
26391 else
26392 hl = DRAW_NORMAL_TEXT;
26393 draw_phys_cursor_glyph (w, cursor_row, hl);
26395 mark_cursor_off:
26396 w->phys_cursor_on_p = 0;
26397 w->phys_cursor_type = NO_CURSOR;
26401 /* EXPORT:
26402 Display or clear cursor of window W. If ON is zero, clear the
26403 cursor. If it is non-zero, display the cursor. If ON is nonzero,
26404 where to put the cursor is specified by HPOS, VPOS, X and Y. */
26406 void
26407 display_and_set_cursor (struct window *w, int on,
26408 int hpos, int vpos, int x, int y)
26410 struct frame *f = XFRAME (w->frame);
26411 int new_cursor_type;
26412 int new_cursor_width;
26413 int active_cursor;
26414 struct glyph_row *glyph_row;
26415 struct glyph *glyph;
26417 /* This is pointless on invisible frames, and dangerous on garbaged
26418 windows and frames; in the latter case, the frame or window may
26419 be in the midst of changing its size, and x and y may be off the
26420 window. */
26421 if (! FRAME_VISIBLE_P (f)
26422 || FRAME_GARBAGED_P (f)
26423 || vpos >= w->current_matrix->nrows
26424 || hpos >= w->current_matrix->matrix_w)
26425 return;
26427 /* If cursor is off and we want it off, return quickly. */
26428 if (!on && !w->phys_cursor_on_p)
26429 return;
26431 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
26432 /* If cursor row is not enabled, we don't really know where to
26433 display the cursor. */
26434 if (!glyph_row->enabled_p)
26436 w->phys_cursor_on_p = 0;
26437 return;
26440 glyph = NULL;
26441 if (!glyph_row->exact_window_width_line_p
26442 || (0 <= hpos && hpos < glyph_row->used[TEXT_AREA]))
26443 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
26445 eassert (input_blocked_p ());
26447 /* Set new_cursor_type to the cursor we want to be displayed. */
26448 new_cursor_type = get_window_cursor_type (w, glyph,
26449 &new_cursor_width, &active_cursor);
26451 /* If cursor is currently being shown and we don't want it to be or
26452 it is in the wrong place, or the cursor type is not what we want,
26453 erase it. */
26454 if (w->phys_cursor_on_p
26455 && (!on
26456 || w->phys_cursor.x != x
26457 || w->phys_cursor.y != y
26458 || new_cursor_type != w->phys_cursor_type
26459 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
26460 && new_cursor_width != w->phys_cursor_width)))
26461 erase_phys_cursor (w);
26463 /* Don't check phys_cursor_on_p here because that flag is only set
26464 to zero in some cases where we know that the cursor has been
26465 completely erased, to avoid the extra work of erasing the cursor
26466 twice. In other words, phys_cursor_on_p can be 1 and the cursor
26467 still not be visible, or it has only been partly erased. */
26468 if (on)
26470 w->phys_cursor_ascent = glyph_row->ascent;
26471 w->phys_cursor_height = glyph_row->height;
26473 /* Set phys_cursor_.* before x_draw_.* is called because some
26474 of them may need the information. */
26475 w->phys_cursor.x = x;
26476 w->phys_cursor.y = glyph_row->y;
26477 w->phys_cursor.hpos = hpos;
26478 w->phys_cursor.vpos = vpos;
26481 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
26482 new_cursor_type, new_cursor_width,
26483 on, active_cursor);
26487 /* Switch the display of W's cursor on or off, according to the value
26488 of ON. */
26490 static void
26491 update_window_cursor (struct window *w, int on)
26493 /* Don't update cursor in windows whose frame is in the process
26494 of being deleted. */
26495 if (w->current_matrix)
26497 int hpos = w->phys_cursor.hpos;
26498 int vpos = w->phys_cursor.vpos;
26499 struct glyph_row *row;
26501 if (vpos >= w->current_matrix->nrows
26502 || hpos >= w->current_matrix->matrix_w)
26503 return;
26505 row = MATRIX_ROW (w->current_matrix, vpos);
26507 /* When the window is hscrolled, cursor hpos can legitimately be
26508 out of bounds, but we draw the cursor at the corresponding
26509 window margin in that case. */
26510 if (!row->reversed_p && hpos < 0)
26511 hpos = 0;
26512 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26513 hpos = row->used[TEXT_AREA] - 1;
26515 block_input ();
26516 display_and_set_cursor (w, on, hpos, vpos,
26517 w->phys_cursor.x, w->phys_cursor.y);
26518 unblock_input ();
26523 /* Call update_window_cursor with parameter ON_P on all leaf windows
26524 in the window tree rooted at W. */
26526 static void
26527 update_cursor_in_window_tree (struct window *w, int on_p)
26529 while (w)
26531 if (WINDOWP (w->contents))
26532 update_cursor_in_window_tree (XWINDOW (w->contents), on_p);
26533 else
26534 update_window_cursor (w, on_p);
26536 w = NILP (w->next) ? 0 : XWINDOW (w->next);
26541 /* EXPORT:
26542 Display the cursor on window W, or clear it, according to ON_P.
26543 Don't change the cursor's position. */
26545 void
26546 x_update_cursor (struct frame *f, int on_p)
26548 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
26552 /* EXPORT:
26553 Clear the cursor of window W to background color, and mark the
26554 cursor as not shown. This is used when the text where the cursor
26555 is about to be rewritten. */
26557 void
26558 x_clear_cursor (struct window *w)
26560 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
26561 update_window_cursor (w, 0);
26564 #endif /* HAVE_WINDOW_SYSTEM */
26566 /* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
26567 and MSDOS. */
26568 static void
26569 draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
26570 int start_hpos, int end_hpos,
26571 enum draw_glyphs_face draw)
26573 #ifdef HAVE_WINDOW_SYSTEM
26574 if (FRAME_WINDOW_P (XFRAME (w->frame)))
26576 draw_glyphs (w, start_x, row, TEXT_AREA, start_hpos, end_hpos, draw, 0);
26577 return;
26579 #endif
26580 #if defined (HAVE_GPM) || defined (MSDOS) || defined (WINDOWSNT)
26581 tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
26582 #endif
26585 /* Display the active region described by mouse_face_* according to DRAW. */
26587 static void
26588 show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
26590 struct window *w = XWINDOW (hlinfo->mouse_face_window);
26591 struct frame *f = XFRAME (WINDOW_FRAME (w));
26593 if (/* If window is in the process of being destroyed, don't bother
26594 to do anything. */
26595 w->current_matrix != NULL
26596 /* Don't update mouse highlight if hidden */
26597 && (draw != DRAW_MOUSE_FACE || !hlinfo->mouse_face_hidden)
26598 /* Recognize when we are called to operate on rows that don't exist
26599 anymore. This can happen when a window is split. */
26600 && hlinfo->mouse_face_end_row < w->current_matrix->nrows)
26602 int phys_cursor_on_p = w->phys_cursor_on_p;
26603 struct glyph_row *row, *first, *last;
26605 first = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
26606 last = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
26608 for (row = first; row <= last && row->enabled_p; ++row)
26610 int start_hpos, end_hpos, start_x;
26612 /* For all but the first row, the highlight starts at column 0. */
26613 if (row == first)
26615 /* R2L rows have BEG and END in reversed order, but the
26616 screen drawing geometry is always left to right. So
26617 we need to mirror the beginning and end of the
26618 highlighted area in R2L rows. */
26619 if (!row->reversed_p)
26621 start_hpos = hlinfo->mouse_face_beg_col;
26622 start_x = hlinfo->mouse_face_beg_x;
26624 else if (row == last)
26626 start_hpos = hlinfo->mouse_face_end_col;
26627 start_x = hlinfo->mouse_face_end_x;
26629 else
26631 start_hpos = 0;
26632 start_x = 0;
26635 else if (row->reversed_p && row == last)
26637 start_hpos = hlinfo->mouse_face_end_col;
26638 start_x = hlinfo->mouse_face_end_x;
26640 else
26642 start_hpos = 0;
26643 start_x = 0;
26646 if (row == last)
26648 if (!row->reversed_p)
26649 end_hpos = hlinfo->mouse_face_end_col;
26650 else if (row == first)
26651 end_hpos = hlinfo->mouse_face_beg_col;
26652 else
26654 end_hpos = row->used[TEXT_AREA];
26655 if (draw == DRAW_NORMAL_TEXT)
26656 row->fill_line_p = 1; /* Clear to end of line */
26659 else if (row->reversed_p && row == first)
26660 end_hpos = hlinfo->mouse_face_beg_col;
26661 else
26663 end_hpos = row->used[TEXT_AREA];
26664 if (draw == DRAW_NORMAL_TEXT)
26665 row->fill_line_p = 1; /* Clear to end of line */
26668 if (end_hpos > start_hpos)
26670 draw_row_with_mouse_face (w, start_x, row,
26671 start_hpos, end_hpos, draw);
26673 row->mouse_face_p
26674 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
26678 #ifdef HAVE_WINDOW_SYSTEM
26679 /* When we've written over the cursor, arrange for it to
26680 be displayed again. */
26681 if (FRAME_WINDOW_P (f)
26682 && phys_cursor_on_p && !w->phys_cursor_on_p)
26684 int hpos = w->phys_cursor.hpos;
26686 /* When the window is hscrolled, cursor hpos can legitimately be
26687 out of bounds, but we draw the cursor at the corresponding
26688 window margin in that case. */
26689 if (!row->reversed_p && hpos < 0)
26690 hpos = 0;
26691 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26692 hpos = row->used[TEXT_AREA] - 1;
26694 block_input ();
26695 display_and_set_cursor (w, 1, hpos, w->phys_cursor.vpos,
26696 w->phys_cursor.x, w->phys_cursor.y);
26697 unblock_input ();
26699 #endif /* HAVE_WINDOW_SYSTEM */
26702 #ifdef HAVE_WINDOW_SYSTEM
26703 /* Change the mouse cursor. */
26704 if (FRAME_WINDOW_P (f))
26706 if (draw == DRAW_NORMAL_TEXT
26707 && !EQ (hlinfo->mouse_face_window, f->tool_bar_window))
26708 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
26709 else if (draw == DRAW_MOUSE_FACE)
26710 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
26711 else
26712 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
26714 #endif /* HAVE_WINDOW_SYSTEM */
26717 /* EXPORT:
26718 Clear out the mouse-highlighted active region.
26719 Redraw it un-highlighted first. Value is non-zero if mouse
26720 face was actually drawn unhighlighted. */
26723 clear_mouse_face (Mouse_HLInfo *hlinfo)
26725 int cleared = 0;
26727 if (!hlinfo->mouse_face_hidden && !NILP (hlinfo->mouse_face_window))
26729 show_mouse_face (hlinfo, DRAW_NORMAL_TEXT);
26730 cleared = 1;
26733 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
26734 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
26735 hlinfo->mouse_face_window = Qnil;
26736 hlinfo->mouse_face_overlay = Qnil;
26737 return cleared;
26740 /* Return non-zero if the coordinates HPOS and VPOS on windows W are
26741 within the mouse face on that window. */
26742 static int
26743 coords_in_mouse_face_p (struct window *w, int hpos, int vpos)
26745 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
26747 /* Quickly resolve the easy cases. */
26748 if (!(WINDOWP (hlinfo->mouse_face_window)
26749 && XWINDOW (hlinfo->mouse_face_window) == w))
26750 return 0;
26751 if (vpos < hlinfo->mouse_face_beg_row
26752 || vpos > hlinfo->mouse_face_end_row)
26753 return 0;
26754 if (vpos > hlinfo->mouse_face_beg_row
26755 && vpos < hlinfo->mouse_face_end_row)
26756 return 1;
26758 if (!MATRIX_ROW (w->current_matrix, vpos)->reversed_p)
26760 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
26762 if (hlinfo->mouse_face_beg_col <= hpos && hpos < hlinfo->mouse_face_end_col)
26763 return 1;
26765 else if ((vpos == hlinfo->mouse_face_beg_row
26766 && hpos >= hlinfo->mouse_face_beg_col)
26767 || (vpos == hlinfo->mouse_face_end_row
26768 && hpos < hlinfo->mouse_face_end_col))
26769 return 1;
26771 else
26773 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
26775 if (hlinfo->mouse_face_end_col < hpos && hpos <= hlinfo->mouse_face_beg_col)
26776 return 1;
26778 else if ((vpos == hlinfo->mouse_face_beg_row
26779 && hpos <= hlinfo->mouse_face_beg_col)
26780 || (vpos == hlinfo->mouse_face_end_row
26781 && hpos > hlinfo->mouse_face_end_col))
26782 return 1;
26784 return 0;
26788 /* EXPORT:
26789 Non-zero if physical cursor of window W is within mouse face. */
26792 cursor_in_mouse_face_p (struct window *w)
26794 int hpos = w->phys_cursor.hpos;
26795 int vpos = w->phys_cursor.vpos;
26796 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
26798 /* When the window is hscrolled, cursor hpos can legitimately be out
26799 of bounds, but we draw the cursor at the corresponding window
26800 margin in that case. */
26801 if (!row->reversed_p && hpos < 0)
26802 hpos = 0;
26803 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26804 hpos = row->used[TEXT_AREA] - 1;
26806 return coords_in_mouse_face_p (w, hpos, vpos);
26811 /* Find the glyph rows START_ROW and END_ROW of window W that display
26812 characters between buffer positions START_CHARPOS and END_CHARPOS
26813 (excluding END_CHARPOS). DISP_STRING is a display string that
26814 covers these buffer positions. This is similar to
26815 row_containing_pos, but is more accurate when bidi reordering makes
26816 buffer positions change non-linearly with glyph rows. */
26817 static void
26818 rows_from_pos_range (struct window *w,
26819 ptrdiff_t start_charpos, ptrdiff_t end_charpos,
26820 Lisp_Object disp_string,
26821 struct glyph_row **start, struct glyph_row **end)
26823 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
26824 int last_y = window_text_bottom_y (w);
26825 struct glyph_row *row;
26827 *start = NULL;
26828 *end = NULL;
26830 while (!first->enabled_p
26831 && first < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
26832 first++;
26834 /* Find the START row. */
26835 for (row = first;
26836 row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y;
26837 row++)
26839 /* A row can potentially be the START row if the range of the
26840 characters it displays intersects the range
26841 [START_CHARPOS..END_CHARPOS). */
26842 if (! ((start_charpos < MATRIX_ROW_START_CHARPOS (row)
26843 && end_charpos < MATRIX_ROW_START_CHARPOS (row))
26844 /* See the commentary in row_containing_pos, for the
26845 explanation of the complicated way to check whether
26846 some position is beyond the end of the characters
26847 displayed by a row. */
26848 || ((start_charpos > MATRIX_ROW_END_CHARPOS (row)
26849 || (start_charpos == MATRIX_ROW_END_CHARPOS (row)
26850 && !row->ends_at_zv_p
26851 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
26852 && (end_charpos > MATRIX_ROW_END_CHARPOS (row)
26853 || (end_charpos == MATRIX_ROW_END_CHARPOS (row)
26854 && !row->ends_at_zv_p
26855 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))))))
26857 /* Found a candidate row. Now make sure at least one of the
26858 glyphs it displays has a charpos from the range
26859 [START_CHARPOS..END_CHARPOS).
26861 This is not obvious because bidi reordering could make
26862 buffer positions of a row be 1,2,3,102,101,100, and if we
26863 want to highlight characters in [50..60), we don't want
26864 this row, even though [50..60) does intersect [1..103),
26865 the range of character positions given by the row's start
26866 and end positions. */
26867 struct glyph *g = row->glyphs[TEXT_AREA];
26868 struct glyph *e = g + row->used[TEXT_AREA];
26870 while (g < e)
26872 if (((BUFFERP (g->object) || INTEGERP (g->object))
26873 && start_charpos <= g->charpos && g->charpos < end_charpos)
26874 /* A glyph that comes from DISP_STRING is by
26875 definition to be highlighted. */
26876 || EQ (g->object, disp_string))
26877 *start = row;
26878 g++;
26880 if (*start)
26881 break;
26885 /* Find the END row. */
26886 if (!*start
26887 /* If the last row is partially visible, start looking for END
26888 from that row, instead of starting from FIRST. */
26889 && !(row->enabled_p
26890 && row->y < last_y && MATRIX_ROW_BOTTOM_Y (row) > last_y))
26891 row = first;
26892 for ( ; row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y; row++)
26894 struct glyph_row *next = row + 1;
26895 ptrdiff_t next_start = MATRIX_ROW_START_CHARPOS (next);
26897 if (!next->enabled_p
26898 || next >= MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)
26899 /* The first row >= START whose range of displayed characters
26900 does NOT intersect the range [START_CHARPOS..END_CHARPOS]
26901 is the row END + 1. */
26902 || (start_charpos < next_start
26903 && end_charpos < next_start)
26904 || ((start_charpos > MATRIX_ROW_END_CHARPOS (next)
26905 || (start_charpos == MATRIX_ROW_END_CHARPOS (next)
26906 && !next->ends_at_zv_p
26907 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))
26908 && (end_charpos > MATRIX_ROW_END_CHARPOS (next)
26909 || (end_charpos == MATRIX_ROW_END_CHARPOS (next)
26910 && !next->ends_at_zv_p
26911 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))))
26913 *end = row;
26914 break;
26916 else
26918 /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
26919 but none of the characters it displays are in the range, it is
26920 also END + 1. */
26921 struct glyph *g = next->glyphs[TEXT_AREA];
26922 struct glyph *s = g;
26923 struct glyph *e = g + next->used[TEXT_AREA];
26925 while (g < e)
26927 if (((BUFFERP (g->object) || INTEGERP (g->object))
26928 && ((start_charpos <= g->charpos && g->charpos < end_charpos)
26929 /* If the buffer position of the first glyph in
26930 the row is equal to END_CHARPOS, it means
26931 the last character to be highlighted is the
26932 newline of ROW, and we must consider NEXT as
26933 END, not END+1. */
26934 || (((!next->reversed_p && g == s)
26935 || (next->reversed_p && g == e - 1))
26936 && (g->charpos == end_charpos
26937 /* Special case for when NEXT is an
26938 empty line at ZV. */
26939 || (g->charpos == -1
26940 && !row->ends_at_zv_p
26941 && next_start == end_charpos)))))
26942 /* A glyph that comes from DISP_STRING is by
26943 definition to be highlighted. */
26944 || EQ (g->object, disp_string))
26945 break;
26946 g++;
26948 if (g == e)
26950 *end = row;
26951 break;
26953 /* The first row that ends at ZV must be the last to be
26954 highlighted. */
26955 else if (next->ends_at_zv_p)
26957 *end = next;
26958 break;
26964 /* This function sets the mouse_face_* elements of HLINFO, assuming
26965 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
26966 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
26967 for the overlay or run of text properties specifying the mouse
26968 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
26969 before-string and after-string that must also be highlighted.
26970 DISP_STRING, if non-nil, is a display string that may cover some
26971 or all of the highlighted text. */
26973 static void
26974 mouse_face_from_buffer_pos (Lisp_Object window,
26975 Mouse_HLInfo *hlinfo,
26976 ptrdiff_t mouse_charpos,
26977 ptrdiff_t start_charpos,
26978 ptrdiff_t end_charpos,
26979 Lisp_Object before_string,
26980 Lisp_Object after_string,
26981 Lisp_Object disp_string)
26983 struct window *w = XWINDOW (window);
26984 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
26985 struct glyph_row *r1, *r2;
26986 struct glyph *glyph, *end;
26987 ptrdiff_t ignore, pos;
26988 int x;
26990 eassert (NILP (disp_string) || STRINGP (disp_string));
26991 eassert (NILP (before_string) || STRINGP (before_string));
26992 eassert (NILP (after_string) || STRINGP (after_string));
26994 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
26995 rows_from_pos_range (w, start_charpos, end_charpos, disp_string, &r1, &r2);
26996 if (r1 == NULL)
26997 r1 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
26998 /* If the before-string or display-string contains newlines,
26999 rows_from_pos_range skips to its last row. Move back. */
27000 if (!NILP (before_string) || !NILP (disp_string))
27002 struct glyph_row *prev;
27003 while ((prev = r1 - 1, prev >= first)
27004 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
27005 && prev->used[TEXT_AREA] > 0)
27007 struct glyph *beg = prev->glyphs[TEXT_AREA];
27008 glyph = beg + prev->used[TEXT_AREA];
27009 while (--glyph >= beg && INTEGERP (glyph->object));
27010 if (glyph < beg
27011 || !(EQ (glyph->object, before_string)
27012 || EQ (glyph->object, disp_string)))
27013 break;
27014 r1 = prev;
27017 if (r2 == NULL)
27019 r2 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
27020 hlinfo->mouse_face_past_end = 1;
27022 else if (!NILP (after_string))
27024 /* If the after-string has newlines, advance to its last row. */
27025 struct glyph_row *next;
27026 struct glyph_row *last
27027 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
27029 for (next = r2 + 1;
27030 next <= last
27031 && next->used[TEXT_AREA] > 0
27032 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
27033 ++next)
27034 r2 = next;
27036 /* The rest of the display engine assumes that mouse_face_beg_row is
27037 either above mouse_face_end_row or identical to it. But with
27038 bidi-reordered continued lines, the row for START_CHARPOS could
27039 be below the row for END_CHARPOS. If so, swap the rows and store
27040 them in correct order. */
27041 if (r1->y > r2->y)
27043 struct glyph_row *tem = r2;
27045 r2 = r1;
27046 r1 = tem;
27049 hlinfo->mouse_face_beg_y = r1->y;
27050 hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
27051 hlinfo->mouse_face_end_y = r2->y;
27052 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
27054 /* For a bidi-reordered row, the positions of BEFORE_STRING,
27055 AFTER_STRING, DISP_STRING, START_CHARPOS, and END_CHARPOS
27056 could be anywhere in the row and in any order. The strategy
27057 below is to find the leftmost and the rightmost glyph that
27058 belongs to either of these 3 strings, or whose position is
27059 between START_CHARPOS and END_CHARPOS, and highlight all the
27060 glyphs between those two. This may cover more than just the text
27061 between START_CHARPOS and END_CHARPOS if the range of characters
27062 strides the bidi level boundary, e.g. if the beginning is in R2L
27063 text while the end is in L2R text or vice versa. */
27064 if (!r1->reversed_p)
27066 /* This row is in a left to right paragraph. Scan it left to
27067 right. */
27068 glyph = r1->glyphs[TEXT_AREA];
27069 end = glyph + r1->used[TEXT_AREA];
27070 x = r1->x;
27072 /* Skip truncation glyphs at the start of the glyph row. */
27073 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
27074 for (; glyph < end
27075 && INTEGERP (glyph->object)
27076 && glyph->charpos < 0;
27077 ++glyph)
27078 x += glyph->pixel_width;
27080 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
27081 or DISP_STRING, and the first glyph from buffer whose
27082 position is between START_CHARPOS and END_CHARPOS. */
27083 for (; glyph < end
27084 && !INTEGERP (glyph->object)
27085 && !EQ (glyph->object, disp_string)
27086 && !(BUFFERP (glyph->object)
27087 && (glyph->charpos >= start_charpos
27088 && glyph->charpos < end_charpos));
27089 ++glyph)
27091 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27092 are present at buffer positions between START_CHARPOS and
27093 END_CHARPOS, or if they come from an overlay. */
27094 if (EQ (glyph->object, before_string))
27096 pos = string_buffer_position (before_string,
27097 start_charpos);
27098 /* If pos == 0, it means before_string came from an
27099 overlay, not from a buffer position. */
27100 if (!pos || (pos >= start_charpos && pos < end_charpos))
27101 break;
27103 else if (EQ (glyph->object, after_string))
27105 pos = string_buffer_position (after_string, end_charpos);
27106 if (!pos || (pos >= start_charpos && pos < end_charpos))
27107 break;
27109 x += glyph->pixel_width;
27111 hlinfo->mouse_face_beg_x = x;
27112 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
27114 else
27116 /* This row is in a right to left paragraph. Scan it right to
27117 left. */
27118 struct glyph *g;
27120 end = r1->glyphs[TEXT_AREA] - 1;
27121 glyph = end + r1->used[TEXT_AREA];
27123 /* Skip truncation glyphs at the start of the glyph row. */
27124 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
27125 for (; glyph > end
27126 && INTEGERP (glyph->object)
27127 && glyph->charpos < 0;
27128 --glyph)
27131 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
27132 or DISP_STRING, and the first glyph from buffer whose
27133 position is between START_CHARPOS and END_CHARPOS. */
27134 for (; glyph > end
27135 && !INTEGERP (glyph->object)
27136 && !EQ (glyph->object, disp_string)
27137 && !(BUFFERP (glyph->object)
27138 && (glyph->charpos >= start_charpos
27139 && glyph->charpos < end_charpos));
27140 --glyph)
27142 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27143 are present at buffer positions between START_CHARPOS and
27144 END_CHARPOS, or if they come from an overlay. */
27145 if (EQ (glyph->object, before_string))
27147 pos = string_buffer_position (before_string, start_charpos);
27148 /* If pos == 0, it means before_string came from an
27149 overlay, not from a buffer position. */
27150 if (!pos || (pos >= start_charpos && pos < end_charpos))
27151 break;
27153 else if (EQ (glyph->object, after_string))
27155 pos = string_buffer_position (after_string, end_charpos);
27156 if (!pos || (pos >= start_charpos && pos < end_charpos))
27157 break;
27161 glyph++; /* first glyph to the right of the highlighted area */
27162 for (g = r1->glyphs[TEXT_AREA], x = r1->x; g < glyph; g++)
27163 x += g->pixel_width;
27164 hlinfo->mouse_face_beg_x = x;
27165 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
27168 /* If the highlight ends in a different row, compute GLYPH and END
27169 for the end row. Otherwise, reuse the values computed above for
27170 the row where the highlight begins. */
27171 if (r2 != r1)
27173 if (!r2->reversed_p)
27175 glyph = r2->glyphs[TEXT_AREA];
27176 end = glyph + r2->used[TEXT_AREA];
27177 x = r2->x;
27179 else
27181 end = r2->glyphs[TEXT_AREA] - 1;
27182 glyph = end + r2->used[TEXT_AREA];
27186 if (!r2->reversed_p)
27188 /* Skip truncation and continuation glyphs near the end of the
27189 row, and also blanks and stretch glyphs inserted by
27190 extend_face_to_end_of_line. */
27191 while (end > glyph
27192 && INTEGERP ((end - 1)->object))
27193 --end;
27194 /* Scan the rest of the glyph row from the end, looking for the
27195 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
27196 DISP_STRING, or whose position is between START_CHARPOS
27197 and END_CHARPOS */
27198 for (--end;
27199 end > glyph
27200 && !INTEGERP (end->object)
27201 && !EQ (end->object, disp_string)
27202 && !(BUFFERP (end->object)
27203 && (end->charpos >= start_charpos
27204 && end->charpos < end_charpos));
27205 --end)
27207 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27208 are present at buffer positions between START_CHARPOS and
27209 END_CHARPOS, or if they come from an overlay. */
27210 if (EQ (end->object, before_string))
27212 pos = string_buffer_position (before_string, start_charpos);
27213 if (!pos || (pos >= start_charpos && pos < end_charpos))
27214 break;
27216 else if (EQ (end->object, after_string))
27218 pos = string_buffer_position (after_string, end_charpos);
27219 if (!pos || (pos >= start_charpos && pos < end_charpos))
27220 break;
27223 /* Find the X coordinate of the last glyph to be highlighted. */
27224 for (; glyph <= end; ++glyph)
27225 x += glyph->pixel_width;
27227 hlinfo->mouse_face_end_x = x;
27228 hlinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
27230 else
27232 /* Skip truncation and continuation glyphs near the end of the
27233 row, and also blanks and stretch glyphs inserted by
27234 extend_face_to_end_of_line. */
27235 x = r2->x;
27236 end++;
27237 while (end < glyph
27238 && INTEGERP (end->object))
27240 x += end->pixel_width;
27241 ++end;
27243 /* Scan the rest of the glyph row from the end, looking for the
27244 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
27245 DISP_STRING, or whose position is between START_CHARPOS
27246 and END_CHARPOS */
27247 for ( ;
27248 end < glyph
27249 && !INTEGERP (end->object)
27250 && !EQ (end->object, disp_string)
27251 && !(BUFFERP (end->object)
27252 && (end->charpos >= start_charpos
27253 && end->charpos < end_charpos));
27254 ++end)
27256 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27257 are present at buffer positions between START_CHARPOS and
27258 END_CHARPOS, or if they come from an overlay. */
27259 if (EQ (end->object, before_string))
27261 pos = string_buffer_position (before_string, start_charpos);
27262 if (!pos || (pos >= start_charpos && pos < end_charpos))
27263 break;
27265 else if (EQ (end->object, after_string))
27267 pos = string_buffer_position (after_string, end_charpos);
27268 if (!pos || (pos >= start_charpos && pos < end_charpos))
27269 break;
27271 x += end->pixel_width;
27273 /* If we exited the above loop because we arrived at the last
27274 glyph of the row, and its buffer position is still not in
27275 range, it means the last character in range is the preceding
27276 newline. Bump the end column and x values to get past the
27277 last glyph. */
27278 if (end == glyph
27279 && BUFFERP (end->object)
27280 && (end->charpos < start_charpos
27281 || end->charpos >= end_charpos))
27283 x += end->pixel_width;
27284 ++end;
27286 hlinfo->mouse_face_end_x = x;
27287 hlinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
27290 hlinfo->mouse_face_window = window;
27291 hlinfo->mouse_face_face_id
27292 = face_at_buffer_position (w, mouse_charpos, 0, 0, &ignore,
27293 mouse_charpos + 1,
27294 !hlinfo->mouse_face_hidden, -1);
27295 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
27298 /* The following function is not used anymore (replaced with
27299 mouse_face_from_string_pos), but I leave it here for the time
27300 being, in case someone would. */
27302 #if 0 /* not used */
27304 /* Find the position of the glyph for position POS in OBJECT in
27305 window W's current matrix, and return in *X, *Y the pixel
27306 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
27308 RIGHT_P non-zero means return the position of the right edge of the
27309 glyph, RIGHT_P zero means return the left edge position.
27311 If no glyph for POS exists in the matrix, return the position of
27312 the glyph with the next smaller position that is in the matrix, if
27313 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
27314 exists in the matrix, return the position of the glyph with the
27315 next larger position in OBJECT.
27317 Value is non-zero if a glyph was found. */
27319 static int
27320 fast_find_string_pos (struct window *w, ptrdiff_t pos, Lisp_Object object,
27321 int *hpos, int *vpos, int *x, int *y, int right_p)
27323 int yb = window_text_bottom_y (w);
27324 struct glyph_row *r;
27325 struct glyph *best_glyph = NULL;
27326 struct glyph_row *best_row = NULL;
27327 int best_x = 0;
27329 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
27330 r->enabled_p && r->y < yb;
27331 ++r)
27333 struct glyph *g = r->glyphs[TEXT_AREA];
27334 struct glyph *e = g + r->used[TEXT_AREA];
27335 int gx;
27337 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
27338 if (EQ (g->object, object))
27340 if (g->charpos == pos)
27342 best_glyph = g;
27343 best_x = gx;
27344 best_row = r;
27345 goto found;
27347 else if (best_glyph == NULL
27348 || ((eabs (g->charpos - pos)
27349 < eabs (best_glyph->charpos - pos))
27350 && (right_p
27351 ? g->charpos < pos
27352 : g->charpos > pos)))
27354 best_glyph = g;
27355 best_x = gx;
27356 best_row = r;
27361 found:
27363 if (best_glyph)
27365 *x = best_x;
27366 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
27368 if (right_p)
27370 *x += best_glyph->pixel_width;
27371 ++*hpos;
27374 *y = best_row->y;
27375 *vpos = MATRIX_ROW_VPOS (best_row, w->current_matrix);
27378 return best_glyph != NULL;
27380 #endif /* not used */
27382 /* Find the positions of the first and the last glyphs in window W's
27383 current matrix that occlude positions [STARTPOS..ENDPOS] in OBJECT
27384 (assumed to be a string), and return in HLINFO's mouse_face_*
27385 members the pixel and column/row coordinates of those glyphs. */
27387 static void
27388 mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
27389 Lisp_Object object,
27390 ptrdiff_t startpos, ptrdiff_t endpos)
27392 int yb = window_text_bottom_y (w);
27393 struct glyph_row *r;
27394 struct glyph *g, *e;
27395 int gx;
27396 int found = 0;
27398 /* Find the glyph row with at least one position in the range
27399 [STARTPOS..ENDPOS], and the first glyph in that row whose
27400 position belongs to that range. */
27401 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
27402 r->enabled_p && r->y < yb;
27403 ++r)
27405 if (!r->reversed_p)
27407 g = r->glyphs[TEXT_AREA];
27408 e = g + r->used[TEXT_AREA];
27409 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
27410 if (EQ (g->object, object)
27411 && startpos <= g->charpos && g->charpos <= endpos)
27413 hlinfo->mouse_face_beg_row
27414 = MATRIX_ROW_VPOS (r, w->current_matrix);
27415 hlinfo->mouse_face_beg_y = r->y;
27416 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
27417 hlinfo->mouse_face_beg_x = gx;
27418 found = 1;
27419 break;
27422 else
27424 struct glyph *g1;
27426 e = r->glyphs[TEXT_AREA];
27427 g = e + r->used[TEXT_AREA];
27428 for ( ; g > e; --g)
27429 if (EQ ((g-1)->object, object)
27430 && startpos <= (g-1)->charpos && (g-1)->charpos <= endpos)
27432 hlinfo->mouse_face_beg_row
27433 = MATRIX_ROW_VPOS (r, w->current_matrix);
27434 hlinfo->mouse_face_beg_y = r->y;
27435 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
27436 for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
27437 gx += g1->pixel_width;
27438 hlinfo->mouse_face_beg_x = gx;
27439 found = 1;
27440 break;
27443 if (found)
27444 break;
27447 if (!found)
27448 return;
27450 /* Starting with the next row, look for the first row which does NOT
27451 include any glyphs whose positions are in the range. */
27452 for (++r; r->enabled_p && r->y < yb; ++r)
27454 g = r->glyphs[TEXT_AREA];
27455 e = g + r->used[TEXT_AREA];
27456 found = 0;
27457 for ( ; g < e; ++g)
27458 if (EQ (g->object, object)
27459 && startpos <= g->charpos && g->charpos <= endpos)
27461 found = 1;
27462 break;
27464 if (!found)
27465 break;
27468 /* The highlighted region ends on the previous row. */
27469 r--;
27471 /* Set the end row and its vertical pixel coordinate. */
27472 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r, w->current_matrix);
27473 hlinfo->mouse_face_end_y = r->y;
27475 /* Compute and set the end column and the end column's horizontal
27476 pixel coordinate. */
27477 if (!r->reversed_p)
27479 g = r->glyphs[TEXT_AREA];
27480 e = g + r->used[TEXT_AREA];
27481 for ( ; e > g; --e)
27482 if (EQ ((e-1)->object, object)
27483 && startpos <= (e-1)->charpos && (e-1)->charpos <= endpos)
27484 break;
27485 hlinfo->mouse_face_end_col = e - g;
27487 for (gx = r->x; g < e; ++g)
27488 gx += g->pixel_width;
27489 hlinfo->mouse_face_end_x = gx;
27491 else
27493 e = r->glyphs[TEXT_AREA];
27494 g = e + r->used[TEXT_AREA];
27495 for (gx = r->x ; e < g; ++e)
27497 if (EQ (e->object, object)
27498 && startpos <= e->charpos && e->charpos <= endpos)
27499 break;
27500 gx += e->pixel_width;
27502 hlinfo->mouse_face_end_col = e - r->glyphs[TEXT_AREA];
27503 hlinfo->mouse_face_end_x = gx;
27507 #ifdef HAVE_WINDOW_SYSTEM
27509 /* See if position X, Y is within a hot-spot of an image. */
27511 static int
27512 on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
27514 if (!CONSP (hot_spot))
27515 return 0;
27517 if (EQ (XCAR (hot_spot), Qrect))
27519 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
27520 Lisp_Object rect = XCDR (hot_spot);
27521 Lisp_Object tem;
27522 if (!CONSP (rect))
27523 return 0;
27524 if (!CONSP (XCAR (rect)))
27525 return 0;
27526 if (!CONSP (XCDR (rect)))
27527 return 0;
27528 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
27529 return 0;
27530 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
27531 return 0;
27532 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
27533 return 0;
27534 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
27535 return 0;
27536 return 1;
27538 else if (EQ (XCAR (hot_spot), Qcircle))
27540 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
27541 Lisp_Object circ = XCDR (hot_spot);
27542 Lisp_Object lr, lx0, ly0;
27543 if (CONSP (circ)
27544 && CONSP (XCAR (circ))
27545 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
27546 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
27547 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
27549 double r = XFLOATINT (lr);
27550 double dx = XINT (lx0) - x;
27551 double dy = XINT (ly0) - y;
27552 return (dx * dx + dy * dy <= r * r);
27555 else if (EQ (XCAR (hot_spot), Qpoly))
27557 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
27558 if (VECTORP (XCDR (hot_spot)))
27560 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
27561 Lisp_Object *poly = v->contents;
27562 ptrdiff_t n = v->header.size;
27563 ptrdiff_t i;
27564 int inside = 0;
27565 Lisp_Object lx, ly;
27566 int x0, y0;
27568 /* Need an even number of coordinates, and at least 3 edges. */
27569 if (n < 6 || n & 1)
27570 return 0;
27572 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
27573 If count is odd, we are inside polygon. Pixels on edges
27574 may or may not be included depending on actual geometry of the
27575 polygon. */
27576 if ((lx = poly[n-2], !INTEGERP (lx))
27577 || (ly = poly[n-1], !INTEGERP (lx)))
27578 return 0;
27579 x0 = XINT (lx), y0 = XINT (ly);
27580 for (i = 0; i < n; i += 2)
27582 int x1 = x0, y1 = y0;
27583 if ((lx = poly[i], !INTEGERP (lx))
27584 || (ly = poly[i+1], !INTEGERP (ly)))
27585 return 0;
27586 x0 = XINT (lx), y0 = XINT (ly);
27588 /* Does this segment cross the X line? */
27589 if (x0 >= x)
27591 if (x1 >= x)
27592 continue;
27594 else if (x1 < x)
27595 continue;
27596 if (y > y0 && y > y1)
27597 continue;
27598 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
27599 inside = !inside;
27601 return inside;
27604 return 0;
27607 Lisp_Object
27608 find_hot_spot (Lisp_Object map, int x, int y)
27610 while (CONSP (map))
27612 if (CONSP (XCAR (map))
27613 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
27614 return XCAR (map);
27615 map = XCDR (map);
27618 return Qnil;
27621 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
27622 3, 3, 0,
27623 doc: /* Lookup in image map MAP coordinates X and Y.
27624 An image map is an alist where each element has the format (AREA ID PLIST).
27625 An AREA is specified as either a rectangle, a circle, or a polygon:
27626 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
27627 pixel coordinates of the upper left and bottom right corners.
27628 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
27629 and the radius of the circle; r may be a float or integer.
27630 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
27631 vector describes one corner in the polygon.
27632 Returns the alist element for the first matching AREA in MAP. */)
27633 (Lisp_Object map, Lisp_Object x, Lisp_Object y)
27635 if (NILP (map))
27636 return Qnil;
27638 CHECK_NUMBER (x);
27639 CHECK_NUMBER (y);
27641 return find_hot_spot (map,
27642 clip_to_bounds (INT_MIN, XINT (x), INT_MAX),
27643 clip_to_bounds (INT_MIN, XINT (y), INT_MAX));
27647 /* Display frame CURSOR, optionally using shape defined by POINTER. */
27648 static void
27649 define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
27651 /* Do not change cursor shape while dragging mouse. */
27652 if (!NILP (do_mouse_tracking))
27653 return;
27655 if (!NILP (pointer))
27657 if (EQ (pointer, Qarrow))
27658 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27659 else if (EQ (pointer, Qhand))
27660 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
27661 else if (EQ (pointer, Qtext))
27662 cursor = FRAME_X_OUTPUT (f)->text_cursor;
27663 else if (EQ (pointer, intern ("hdrag")))
27664 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
27665 #ifdef HAVE_X_WINDOWS
27666 else if (EQ (pointer, intern ("vdrag")))
27667 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
27668 #endif
27669 else if (EQ (pointer, intern ("hourglass")))
27670 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
27671 else if (EQ (pointer, Qmodeline))
27672 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
27673 else
27674 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27677 if (cursor != No_Cursor)
27678 FRAME_RIF (f)->define_frame_cursor (f, cursor);
27681 #endif /* HAVE_WINDOW_SYSTEM */
27683 /* Take proper action when mouse has moved to the mode or header line
27684 or marginal area AREA of window W, x-position X and y-position Y.
27685 X is relative to the start of the text display area of W, so the
27686 width of bitmap areas and scroll bars must be subtracted to get a
27687 position relative to the start of the mode line. */
27689 static void
27690 note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
27691 enum window_part area)
27693 struct window *w = XWINDOW (window);
27694 struct frame *f = XFRAME (w->frame);
27695 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
27696 #ifdef HAVE_WINDOW_SYSTEM
27697 Display_Info *dpyinfo;
27698 #endif
27699 Cursor cursor = No_Cursor;
27700 Lisp_Object pointer = Qnil;
27701 int dx, dy, width, height;
27702 ptrdiff_t charpos;
27703 Lisp_Object string, object = Qnil;
27704 Lisp_Object pos IF_LINT (= Qnil), help;
27706 Lisp_Object mouse_face;
27707 int original_x_pixel = x;
27708 struct glyph * glyph = NULL, * row_start_glyph = NULL;
27709 struct glyph_row *row IF_LINT (= 0);
27711 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
27713 int x0;
27714 struct glyph *end;
27716 /* Kludge alert: mode_line_string takes X/Y in pixels, but
27717 returns them in row/column units! */
27718 string = mode_line_string (w, area, &x, &y, &charpos,
27719 &object, &dx, &dy, &width, &height);
27721 row = (area == ON_MODE_LINE
27722 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
27723 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
27725 /* Find the glyph under the mouse pointer. */
27726 if (row->mode_line_p && row->enabled_p)
27728 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
27729 end = glyph + row->used[TEXT_AREA];
27731 for (x0 = original_x_pixel;
27732 glyph < end && x0 >= glyph->pixel_width;
27733 ++glyph)
27734 x0 -= glyph->pixel_width;
27736 if (glyph >= end)
27737 glyph = NULL;
27740 else
27742 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
27743 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
27744 returns them in row/column units! */
27745 string = marginal_area_string (w, area, &x, &y, &charpos,
27746 &object, &dx, &dy, &width, &height);
27749 help = Qnil;
27751 #ifdef HAVE_WINDOW_SYSTEM
27752 if (IMAGEP (object))
27754 Lisp_Object image_map, hotspot;
27755 if ((image_map = Fplist_get (XCDR (object), QCmap),
27756 !NILP (image_map))
27757 && (hotspot = find_hot_spot (image_map, dx, dy),
27758 CONSP (hotspot))
27759 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
27761 Lisp_Object plist;
27763 /* Could check XCAR (hotspot) to see if we enter/leave this hot-spot.
27764 If so, we could look for mouse-enter, mouse-leave
27765 properties in PLIST (and do something...). */
27766 hotspot = XCDR (hotspot);
27767 if (CONSP (hotspot)
27768 && (plist = XCAR (hotspot), CONSP (plist)))
27770 pointer = Fplist_get (plist, Qpointer);
27771 if (NILP (pointer))
27772 pointer = Qhand;
27773 help = Fplist_get (plist, Qhelp_echo);
27774 if (!NILP (help))
27776 help_echo_string = help;
27777 XSETWINDOW (help_echo_window, w);
27778 help_echo_object = w->contents;
27779 help_echo_pos = charpos;
27783 if (NILP (pointer))
27784 pointer = Fplist_get (XCDR (object), QCpointer);
27786 #endif /* HAVE_WINDOW_SYSTEM */
27788 if (STRINGP (string))
27789 pos = make_number (charpos);
27791 /* Set the help text and mouse pointer. If the mouse is on a part
27792 of the mode line without any text (e.g. past the right edge of
27793 the mode line text), use the default help text and pointer. */
27794 if (STRINGP (string) || area == ON_MODE_LINE)
27796 /* Arrange to display the help by setting the global variables
27797 help_echo_string, help_echo_object, and help_echo_pos. */
27798 if (NILP (help))
27800 if (STRINGP (string))
27801 help = Fget_text_property (pos, Qhelp_echo, string);
27803 if (!NILP (help))
27805 help_echo_string = help;
27806 XSETWINDOW (help_echo_window, w);
27807 help_echo_object = string;
27808 help_echo_pos = charpos;
27810 else if (area == ON_MODE_LINE)
27812 Lisp_Object default_help
27813 = buffer_local_value_1 (Qmode_line_default_help_echo,
27814 w->contents);
27816 if (STRINGP (default_help))
27818 help_echo_string = default_help;
27819 XSETWINDOW (help_echo_window, w);
27820 help_echo_object = Qnil;
27821 help_echo_pos = -1;
27826 #ifdef HAVE_WINDOW_SYSTEM
27827 /* Change the mouse pointer according to what is under it. */
27828 if (FRAME_WINDOW_P (f))
27830 dpyinfo = FRAME_X_DISPLAY_INFO (f);
27831 if (STRINGP (string))
27833 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27835 if (NILP (pointer))
27836 pointer = Fget_text_property (pos, Qpointer, string);
27838 /* Change the mouse pointer according to what is under X/Y. */
27839 if (NILP (pointer)
27840 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
27842 Lisp_Object map;
27843 map = Fget_text_property (pos, Qlocal_map, string);
27844 if (!KEYMAPP (map))
27845 map = Fget_text_property (pos, Qkeymap, string);
27846 if (!KEYMAPP (map))
27847 cursor = dpyinfo->vertical_scroll_bar_cursor;
27850 else
27851 /* Default mode-line pointer. */
27852 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
27854 #endif
27857 /* Change the mouse face according to what is under X/Y. */
27858 if (STRINGP (string))
27860 mouse_face = Fget_text_property (pos, Qmouse_face, string);
27861 if (!NILP (Vmouse_highlight) && !NILP (mouse_face)
27862 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
27863 && glyph)
27865 Lisp_Object b, e;
27867 struct glyph * tmp_glyph;
27869 int gpos;
27870 int gseq_length;
27871 int total_pixel_width;
27872 ptrdiff_t begpos, endpos, ignore;
27874 int vpos, hpos;
27876 b = Fprevious_single_property_change (make_number (charpos + 1),
27877 Qmouse_face, string, Qnil);
27878 if (NILP (b))
27879 begpos = 0;
27880 else
27881 begpos = XINT (b);
27883 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
27884 if (NILP (e))
27885 endpos = SCHARS (string);
27886 else
27887 endpos = XINT (e);
27889 /* Calculate the glyph position GPOS of GLYPH in the
27890 displayed string, relative to the beginning of the
27891 highlighted part of the string.
27893 Note: GPOS is different from CHARPOS. CHARPOS is the
27894 position of GLYPH in the internal string object. A mode
27895 line string format has structures which are converted to
27896 a flattened string by the Emacs Lisp interpreter. The
27897 internal string is an element of those structures. The
27898 displayed string is the flattened string. */
27899 tmp_glyph = row_start_glyph;
27900 while (tmp_glyph < glyph
27901 && (!(EQ (tmp_glyph->object, glyph->object)
27902 && begpos <= tmp_glyph->charpos
27903 && tmp_glyph->charpos < endpos)))
27904 tmp_glyph++;
27905 gpos = glyph - tmp_glyph;
27907 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
27908 the highlighted part of the displayed string to which
27909 GLYPH belongs. Note: GSEQ_LENGTH is different from
27910 SCHARS (STRING), because the latter returns the length of
27911 the internal string. */
27912 for (tmp_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
27913 tmp_glyph > glyph
27914 && (!(EQ (tmp_glyph->object, glyph->object)
27915 && begpos <= tmp_glyph->charpos
27916 && tmp_glyph->charpos < endpos));
27917 tmp_glyph--)
27919 gseq_length = gpos + (tmp_glyph - glyph) + 1;
27921 /* Calculate the total pixel width of all the glyphs between
27922 the beginning of the highlighted area and GLYPH. */
27923 total_pixel_width = 0;
27924 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
27925 total_pixel_width += tmp_glyph->pixel_width;
27927 /* Pre calculation of re-rendering position. Note: X is in
27928 column units here, after the call to mode_line_string or
27929 marginal_area_string. */
27930 hpos = x - gpos;
27931 vpos = (area == ON_MODE_LINE
27932 ? (w->current_matrix)->nrows - 1
27933 : 0);
27935 /* If GLYPH's position is included in the region that is
27936 already drawn in mouse face, we have nothing to do. */
27937 if ( EQ (window, hlinfo->mouse_face_window)
27938 && (!row->reversed_p
27939 ? (hlinfo->mouse_face_beg_col <= hpos
27940 && hpos < hlinfo->mouse_face_end_col)
27941 /* In R2L rows we swap BEG and END, see below. */
27942 : (hlinfo->mouse_face_end_col <= hpos
27943 && hpos < hlinfo->mouse_face_beg_col))
27944 && hlinfo->mouse_face_beg_row == vpos )
27945 return;
27947 if (clear_mouse_face (hlinfo))
27948 cursor = No_Cursor;
27950 if (!row->reversed_p)
27952 hlinfo->mouse_face_beg_col = hpos;
27953 hlinfo->mouse_face_beg_x = original_x_pixel
27954 - (total_pixel_width + dx);
27955 hlinfo->mouse_face_end_col = hpos + gseq_length;
27956 hlinfo->mouse_face_end_x = 0;
27958 else
27960 /* In R2L rows, show_mouse_face expects BEG and END
27961 coordinates to be swapped. */
27962 hlinfo->mouse_face_end_col = hpos;
27963 hlinfo->mouse_face_end_x = original_x_pixel
27964 - (total_pixel_width + dx);
27965 hlinfo->mouse_face_beg_col = hpos + gseq_length;
27966 hlinfo->mouse_face_beg_x = 0;
27969 hlinfo->mouse_face_beg_row = vpos;
27970 hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row;
27971 hlinfo->mouse_face_beg_y = 0;
27972 hlinfo->mouse_face_end_y = 0;
27973 hlinfo->mouse_face_past_end = 0;
27974 hlinfo->mouse_face_window = window;
27976 hlinfo->mouse_face_face_id = face_at_string_position (w, string,
27977 charpos,
27978 0, 0, 0,
27979 &ignore,
27980 glyph->face_id,
27982 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
27984 if (NILP (pointer))
27985 pointer = Qhand;
27987 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
27988 clear_mouse_face (hlinfo);
27990 #ifdef HAVE_WINDOW_SYSTEM
27991 if (FRAME_WINDOW_P (f))
27992 define_frame_cursor1 (f, cursor, pointer);
27993 #endif
27997 /* EXPORT:
27998 Take proper action when the mouse has moved to position X, Y on
27999 frame F with regards to highlighting portions of display that have
28000 mouse-face properties. Also de-highlight portions of display where
28001 the mouse was before, set the mouse pointer shape as appropriate
28002 for the mouse coordinates, and activate help echo (tooltips).
28003 X and Y can be negative or out of range. */
28005 void
28006 note_mouse_highlight (struct frame *f, int x, int y)
28008 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
28009 enum window_part part = ON_NOTHING;
28010 Lisp_Object window;
28011 struct window *w;
28012 Cursor cursor = No_Cursor;
28013 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
28014 struct buffer *b;
28016 /* When a menu is active, don't highlight because this looks odd. */
28017 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
28018 if (popup_activated ())
28019 return;
28020 #endif
28022 if (!f->glyphs_initialized_p
28023 || f->pointer_invisible)
28024 return;
28026 hlinfo->mouse_face_mouse_x = x;
28027 hlinfo->mouse_face_mouse_y = y;
28028 hlinfo->mouse_face_mouse_frame = f;
28030 if (hlinfo->mouse_face_defer)
28031 return;
28033 /* Which window is that in? */
28034 window = window_from_coordinates (f, x, y, &part, 1);
28036 /* If displaying active text in another window, clear that. */
28037 if (! EQ (window, hlinfo->mouse_face_window)
28038 /* Also clear if we move out of text area in same window. */
28039 || (!NILP (hlinfo->mouse_face_window)
28040 && !NILP (window)
28041 && part != ON_TEXT
28042 && part != ON_MODE_LINE
28043 && part != ON_HEADER_LINE))
28044 clear_mouse_face (hlinfo);
28046 /* Not on a window -> return. */
28047 if (!WINDOWP (window))
28048 return;
28050 /* Reset help_echo_string. It will get recomputed below. */
28051 help_echo_string = Qnil;
28053 /* Convert to window-relative pixel coordinates. */
28054 w = XWINDOW (window);
28055 frame_to_window_pixel_xy (w, &x, &y);
28057 #ifdef HAVE_WINDOW_SYSTEM
28058 /* Handle tool-bar window differently since it doesn't display a
28059 buffer. */
28060 if (EQ (window, f->tool_bar_window))
28062 note_tool_bar_highlight (f, x, y);
28063 return;
28065 #endif
28067 /* Mouse is on the mode, header line or margin? */
28068 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
28069 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
28071 note_mode_line_or_margin_highlight (window, x, y, part);
28072 return;
28075 #ifdef HAVE_WINDOW_SYSTEM
28076 if (part == ON_VERTICAL_BORDER)
28078 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
28079 help_echo_string = build_string ("drag-mouse-1: resize");
28081 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
28082 || part == ON_SCROLL_BAR)
28083 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
28084 else
28085 cursor = FRAME_X_OUTPUT (f)->text_cursor;
28086 #endif
28088 /* Are we in a window whose display is up to date?
28089 And verify the buffer's text has not changed. */
28090 b = XBUFFER (w->contents);
28091 if (part == ON_TEXT
28092 && w->window_end_valid
28093 && w->last_modified == BUF_MODIFF (b)
28094 && w->last_overlay_modified == BUF_OVERLAY_MODIFF (b))
28096 int hpos, vpos, dx, dy, area = LAST_AREA;
28097 ptrdiff_t pos;
28098 struct glyph *glyph;
28099 Lisp_Object object;
28100 Lisp_Object mouse_face = Qnil, position;
28101 Lisp_Object *overlay_vec = NULL;
28102 ptrdiff_t i, noverlays;
28103 struct buffer *obuf;
28104 ptrdiff_t obegv, ozv;
28105 int same_region;
28107 /* Find the glyph under X/Y. */
28108 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
28110 #ifdef HAVE_WINDOW_SYSTEM
28111 /* Look for :pointer property on image. */
28112 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
28114 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
28115 if (img != NULL && IMAGEP (img->spec))
28117 Lisp_Object image_map, hotspot;
28118 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
28119 !NILP (image_map))
28120 && (hotspot = find_hot_spot (image_map,
28121 glyph->slice.img.x + dx,
28122 glyph->slice.img.y + dy),
28123 CONSP (hotspot))
28124 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
28126 Lisp_Object plist;
28128 /* Could check XCAR (hotspot) to see if we enter/leave
28129 this hot-spot.
28130 If so, we could look for mouse-enter, mouse-leave
28131 properties in PLIST (and do something...). */
28132 hotspot = XCDR (hotspot);
28133 if (CONSP (hotspot)
28134 && (plist = XCAR (hotspot), CONSP (plist)))
28136 pointer = Fplist_get (plist, Qpointer);
28137 if (NILP (pointer))
28138 pointer = Qhand;
28139 help_echo_string = Fplist_get (plist, Qhelp_echo);
28140 if (!NILP (help_echo_string))
28142 help_echo_window = window;
28143 help_echo_object = glyph->object;
28144 help_echo_pos = glyph->charpos;
28148 if (NILP (pointer))
28149 pointer = Fplist_get (XCDR (img->spec), QCpointer);
28152 #endif /* HAVE_WINDOW_SYSTEM */
28154 /* Clear mouse face if X/Y not over text. */
28155 if (glyph == NULL
28156 || area != TEXT_AREA
28157 || !MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->current_matrix, vpos))
28158 /* Glyph's OBJECT is an integer for glyphs inserted by the
28159 display engine for its internal purposes, like truncation
28160 and continuation glyphs and blanks beyond the end of
28161 line's text on text terminals. If we are over such a
28162 glyph, we are not over any text. */
28163 || INTEGERP (glyph->object)
28164 /* R2L rows have a stretch glyph at their front, which
28165 stands for no text, whereas L2R rows have no glyphs at
28166 all beyond the end of text. Treat such stretch glyphs
28167 like we do with NULL glyphs in L2R rows. */
28168 || (MATRIX_ROW (w->current_matrix, vpos)->reversed_p
28169 && glyph == MATRIX_ROW_GLYPH_START (w->current_matrix, vpos)
28170 && glyph->type == STRETCH_GLYPH
28171 && glyph->avoid_cursor_p))
28173 if (clear_mouse_face (hlinfo))
28174 cursor = No_Cursor;
28175 #ifdef HAVE_WINDOW_SYSTEM
28176 if (FRAME_WINDOW_P (f) && NILP (pointer))
28178 if (area != TEXT_AREA)
28179 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
28180 else
28181 pointer = Vvoid_text_area_pointer;
28183 #endif
28184 goto set_cursor;
28187 pos = glyph->charpos;
28188 object = glyph->object;
28189 if (!STRINGP (object) && !BUFFERP (object))
28190 goto set_cursor;
28192 /* If we get an out-of-range value, return now; avoid an error. */
28193 if (BUFFERP (object) && pos > BUF_Z (b))
28194 goto set_cursor;
28196 /* Make the window's buffer temporarily current for
28197 overlays_at and compute_char_face. */
28198 obuf = current_buffer;
28199 current_buffer = b;
28200 obegv = BEGV;
28201 ozv = ZV;
28202 BEGV = BEG;
28203 ZV = Z;
28205 /* Is this char mouse-active or does it have help-echo? */
28206 position = make_number (pos);
28208 if (BUFFERP (object))
28210 /* Put all the overlays we want in a vector in overlay_vec. */
28211 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
28212 /* Sort overlays into increasing priority order. */
28213 noverlays = sort_overlays (overlay_vec, noverlays, w);
28215 else
28216 noverlays = 0;
28218 if (NILP (Vmouse_highlight))
28220 clear_mouse_face (hlinfo);
28221 goto check_help_echo;
28224 same_region = coords_in_mouse_face_p (w, hpos, vpos);
28226 if (same_region)
28227 cursor = No_Cursor;
28229 /* Check mouse-face highlighting. */
28230 if (! same_region
28231 /* If there exists an overlay with mouse-face overlapping
28232 the one we are currently highlighting, we have to
28233 check if we enter the overlapping overlay, and then
28234 highlight only that. */
28235 || (OVERLAYP (hlinfo->mouse_face_overlay)
28236 && mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
28238 /* Find the highest priority overlay with a mouse-face. */
28239 Lisp_Object overlay = Qnil;
28240 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
28242 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
28243 if (!NILP (mouse_face))
28244 overlay = overlay_vec[i];
28247 /* If we're highlighting the same overlay as before, there's
28248 no need to do that again. */
28249 if (!NILP (overlay) && EQ (overlay, hlinfo->mouse_face_overlay))
28250 goto check_help_echo;
28251 hlinfo->mouse_face_overlay = overlay;
28253 /* Clear the display of the old active region, if any. */
28254 if (clear_mouse_face (hlinfo))
28255 cursor = No_Cursor;
28257 /* If no overlay applies, get a text property. */
28258 if (NILP (overlay))
28259 mouse_face = Fget_text_property (position, Qmouse_face, object);
28261 /* Next, compute the bounds of the mouse highlighting and
28262 display it. */
28263 if (!NILP (mouse_face) && STRINGP (object))
28265 /* The mouse-highlighting comes from a display string
28266 with a mouse-face. */
28267 Lisp_Object s, e;
28268 ptrdiff_t ignore;
28270 s = Fprevious_single_property_change
28271 (make_number (pos + 1), Qmouse_face, object, Qnil);
28272 e = Fnext_single_property_change
28273 (position, Qmouse_face, object, Qnil);
28274 if (NILP (s))
28275 s = make_number (0);
28276 if (NILP (e))
28277 e = make_number (SCHARS (object) - 1);
28278 mouse_face_from_string_pos (w, hlinfo, object,
28279 XINT (s), XINT (e));
28280 hlinfo->mouse_face_past_end = 0;
28281 hlinfo->mouse_face_window = window;
28282 hlinfo->mouse_face_face_id
28283 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
28284 glyph->face_id, 1);
28285 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
28286 cursor = No_Cursor;
28288 else
28290 /* The mouse-highlighting, if any, comes from an overlay
28291 or text property in the buffer. */
28292 Lisp_Object buffer IF_LINT (= Qnil);
28293 Lisp_Object disp_string IF_LINT (= Qnil);
28295 if (STRINGP (object))
28297 /* If we are on a display string with no mouse-face,
28298 check if the text under it has one. */
28299 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
28300 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
28301 pos = string_buffer_position (object, start);
28302 if (pos > 0)
28304 mouse_face = get_char_property_and_overlay
28305 (make_number (pos), Qmouse_face, w->contents, &overlay);
28306 buffer = w->contents;
28307 disp_string = object;
28310 else
28312 buffer = object;
28313 disp_string = Qnil;
28316 if (!NILP (mouse_face))
28318 Lisp_Object before, after;
28319 Lisp_Object before_string, after_string;
28320 /* To correctly find the limits of mouse highlight
28321 in a bidi-reordered buffer, we must not use the
28322 optimization of limiting the search in
28323 previous-single-property-change and
28324 next-single-property-change, because
28325 rows_from_pos_range needs the real start and end
28326 positions to DTRT in this case. That's because
28327 the first row visible in a window does not
28328 necessarily display the character whose position
28329 is the smallest. */
28330 Lisp_Object lim1 =
28331 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
28332 ? Fmarker_position (w->start)
28333 : Qnil;
28334 Lisp_Object lim2 =
28335 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
28336 ? make_number (BUF_Z (XBUFFER (buffer))
28337 - XFASTINT (w->window_end_pos))
28338 : Qnil;
28340 if (NILP (overlay))
28342 /* Handle the text property case. */
28343 before = Fprevious_single_property_change
28344 (make_number (pos + 1), Qmouse_face, buffer, lim1);
28345 after = Fnext_single_property_change
28346 (make_number (pos), Qmouse_face, buffer, lim2);
28347 before_string = after_string = Qnil;
28349 else
28351 /* Handle the overlay case. */
28352 before = Foverlay_start (overlay);
28353 after = Foverlay_end (overlay);
28354 before_string = Foverlay_get (overlay, Qbefore_string);
28355 after_string = Foverlay_get (overlay, Qafter_string);
28357 if (!STRINGP (before_string)) before_string = Qnil;
28358 if (!STRINGP (after_string)) after_string = Qnil;
28361 mouse_face_from_buffer_pos (window, hlinfo, pos,
28362 NILP (before)
28364 : XFASTINT (before),
28365 NILP (after)
28366 ? BUF_Z (XBUFFER (buffer))
28367 : XFASTINT (after),
28368 before_string, after_string,
28369 disp_string);
28370 cursor = No_Cursor;
28375 check_help_echo:
28377 /* Look for a `help-echo' property. */
28378 if (NILP (help_echo_string)) {
28379 Lisp_Object help, overlay;
28381 /* Check overlays first. */
28382 help = overlay = Qnil;
28383 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
28385 overlay = overlay_vec[i];
28386 help = Foverlay_get (overlay, Qhelp_echo);
28389 if (!NILP (help))
28391 help_echo_string = help;
28392 help_echo_window = window;
28393 help_echo_object = overlay;
28394 help_echo_pos = pos;
28396 else
28398 Lisp_Object obj = glyph->object;
28399 ptrdiff_t charpos = glyph->charpos;
28401 /* Try text properties. */
28402 if (STRINGP (obj)
28403 && charpos >= 0
28404 && charpos < SCHARS (obj))
28406 help = Fget_text_property (make_number (charpos),
28407 Qhelp_echo, obj);
28408 if (NILP (help))
28410 /* If the string itself doesn't specify a help-echo,
28411 see if the buffer text ``under'' it does. */
28412 struct glyph_row *r
28413 = MATRIX_ROW (w->current_matrix, vpos);
28414 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
28415 ptrdiff_t p = string_buffer_position (obj, start);
28416 if (p > 0)
28418 help = Fget_char_property (make_number (p),
28419 Qhelp_echo, w->contents);
28420 if (!NILP (help))
28422 charpos = p;
28423 obj = w->contents;
28428 else if (BUFFERP (obj)
28429 && charpos >= BEGV
28430 && charpos < ZV)
28431 help = Fget_text_property (make_number (charpos), Qhelp_echo,
28432 obj);
28434 if (!NILP (help))
28436 help_echo_string = help;
28437 help_echo_window = window;
28438 help_echo_object = obj;
28439 help_echo_pos = charpos;
28444 #ifdef HAVE_WINDOW_SYSTEM
28445 /* Look for a `pointer' property. */
28446 if (FRAME_WINDOW_P (f) && NILP (pointer))
28448 /* Check overlays first. */
28449 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
28450 pointer = Foverlay_get (overlay_vec[i], Qpointer);
28452 if (NILP (pointer))
28454 Lisp_Object obj = glyph->object;
28455 ptrdiff_t charpos = glyph->charpos;
28457 /* Try text properties. */
28458 if (STRINGP (obj)
28459 && charpos >= 0
28460 && charpos < SCHARS (obj))
28462 pointer = Fget_text_property (make_number (charpos),
28463 Qpointer, obj);
28464 if (NILP (pointer))
28466 /* If the string itself doesn't specify a pointer,
28467 see if the buffer text ``under'' it does. */
28468 struct glyph_row *r
28469 = MATRIX_ROW (w->current_matrix, vpos);
28470 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
28471 ptrdiff_t p = string_buffer_position (obj, start);
28472 if (p > 0)
28473 pointer = Fget_char_property (make_number (p),
28474 Qpointer, w->contents);
28477 else if (BUFFERP (obj)
28478 && charpos >= BEGV
28479 && charpos < ZV)
28480 pointer = Fget_text_property (make_number (charpos),
28481 Qpointer, obj);
28484 #endif /* HAVE_WINDOW_SYSTEM */
28486 BEGV = obegv;
28487 ZV = ozv;
28488 current_buffer = obuf;
28491 set_cursor:
28493 #ifdef HAVE_WINDOW_SYSTEM
28494 if (FRAME_WINDOW_P (f))
28495 define_frame_cursor1 (f, cursor, pointer);
28496 #else
28497 /* This is here to prevent a compiler error, about "label at end of
28498 compound statement". */
28499 return;
28500 #endif
28504 /* EXPORT for RIF:
28505 Clear any mouse-face on window W. This function is part of the
28506 redisplay interface, and is called from try_window_id and similar
28507 functions to ensure the mouse-highlight is off. */
28509 void
28510 x_clear_window_mouse_face (struct window *w)
28512 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
28513 Lisp_Object window;
28515 block_input ();
28516 XSETWINDOW (window, w);
28517 if (EQ (window, hlinfo->mouse_face_window))
28518 clear_mouse_face (hlinfo);
28519 unblock_input ();
28523 /* EXPORT:
28524 Just discard the mouse face information for frame F, if any.
28525 This is used when the size of F is changed. */
28527 void
28528 cancel_mouse_face (struct frame *f)
28530 Lisp_Object window;
28531 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
28533 window = hlinfo->mouse_face_window;
28534 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
28536 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
28537 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
28538 hlinfo->mouse_face_window = Qnil;
28544 /***********************************************************************
28545 Exposure Events
28546 ***********************************************************************/
28548 #ifdef HAVE_WINDOW_SYSTEM
28550 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
28551 which intersects rectangle R. R is in window-relative coordinates. */
28553 static void
28554 expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
28555 enum glyph_row_area area)
28557 struct glyph *first = row->glyphs[area];
28558 struct glyph *end = row->glyphs[area] + row->used[area];
28559 struct glyph *last;
28560 int first_x, start_x, x;
28562 if (area == TEXT_AREA && row->fill_line_p)
28563 /* If row extends face to end of line write the whole line. */
28564 draw_glyphs (w, 0, row, area,
28565 0, row->used[area],
28566 DRAW_NORMAL_TEXT, 0);
28567 else
28569 /* Set START_X to the window-relative start position for drawing glyphs of
28570 AREA. The first glyph of the text area can be partially visible.
28571 The first glyphs of other areas cannot. */
28572 start_x = window_box_left_offset (w, area);
28573 x = start_x;
28574 if (area == TEXT_AREA)
28575 x += row->x;
28577 /* Find the first glyph that must be redrawn. */
28578 while (first < end
28579 && x + first->pixel_width < r->x)
28581 x += first->pixel_width;
28582 ++first;
28585 /* Find the last one. */
28586 last = first;
28587 first_x = x;
28588 while (last < end
28589 && x < r->x + r->width)
28591 x += last->pixel_width;
28592 ++last;
28595 /* Repaint. */
28596 if (last > first)
28597 draw_glyphs (w, first_x - start_x, row, area,
28598 first - row->glyphs[area], last - row->glyphs[area],
28599 DRAW_NORMAL_TEXT, 0);
28604 /* Redraw the parts of the glyph row ROW on window W intersecting
28605 rectangle R. R is in window-relative coordinates. Value is
28606 non-zero if mouse-face was overwritten. */
28608 static int
28609 expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
28611 eassert (row->enabled_p);
28613 if (row->mode_line_p || w->pseudo_window_p)
28614 draw_glyphs (w, 0, row, TEXT_AREA,
28615 0, row->used[TEXT_AREA],
28616 DRAW_NORMAL_TEXT, 0);
28617 else
28619 if (row->used[LEFT_MARGIN_AREA])
28620 expose_area (w, row, r, LEFT_MARGIN_AREA);
28621 if (row->used[TEXT_AREA])
28622 expose_area (w, row, r, TEXT_AREA);
28623 if (row->used[RIGHT_MARGIN_AREA])
28624 expose_area (w, row, r, RIGHT_MARGIN_AREA);
28625 draw_row_fringe_bitmaps (w, row);
28628 return row->mouse_face_p;
28632 /* Redraw those parts of glyphs rows during expose event handling that
28633 overlap other rows. Redrawing of an exposed line writes over parts
28634 of lines overlapping that exposed line; this function fixes that.
28636 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
28637 row in W's current matrix that is exposed and overlaps other rows.
28638 LAST_OVERLAPPING_ROW is the last such row. */
28640 static void
28641 expose_overlaps (struct window *w,
28642 struct glyph_row *first_overlapping_row,
28643 struct glyph_row *last_overlapping_row,
28644 XRectangle *r)
28646 struct glyph_row *row;
28648 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
28649 if (row->overlapping_p)
28651 eassert (row->enabled_p && !row->mode_line_p);
28653 row->clip = r;
28654 if (row->used[LEFT_MARGIN_AREA])
28655 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
28657 if (row->used[TEXT_AREA])
28658 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
28660 if (row->used[RIGHT_MARGIN_AREA])
28661 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
28662 row->clip = NULL;
28667 /* Return non-zero if W's cursor intersects rectangle R. */
28669 static int
28670 phys_cursor_in_rect_p (struct window *w, XRectangle *r)
28672 XRectangle cr, result;
28673 struct glyph *cursor_glyph;
28674 struct glyph_row *row;
28676 if (w->phys_cursor.vpos >= 0
28677 && w->phys_cursor.vpos < w->current_matrix->nrows
28678 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
28679 row->enabled_p)
28680 && row->cursor_in_fringe_p)
28682 /* Cursor is in the fringe. */
28683 cr.x = window_box_right_offset (w,
28684 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
28685 ? RIGHT_MARGIN_AREA
28686 : TEXT_AREA));
28687 cr.y = row->y;
28688 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
28689 cr.height = row->height;
28690 return x_intersect_rectangles (&cr, r, &result);
28693 cursor_glyph = get_phys_cursor_glyph (w);
28694 if (cursor_glyph)
28696 /* r is relative to W's box, but w->phys_cursor.x is relative
28697 to left edge of W's TEXT area. Adjust it. */
28698 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
28699 cr.y = w->phys_cursor.y;
28700 cr.width = cursor_glyph->pixel_width;
28701 cr.height = w->phys_cursor_height;
28702 /* ++KFS: W32 version used W32-specific IntersectRect here, but
28703 I assume the effect is the same -- and this is portable. */
28704 return x_intersect_rectangles (&cr, r, &result);
28706 /* If we don't understand the format, pretend we're not in the hot-spot. */
28707 return 0;
28711 /* EXPORT:
28712 Draw a vertical window border to the right of window W if W doesn't
28713 have vertical scroll bars. */
28715 void
28716 x_draw_vertical_border (struct window *w)
28718 struct frame *f = XFRAME (WINDOW_FRAME (w));
28720 /* We could do better, if we knew what type of scroll-bar the adjacent
28721 windows (on either side) have... But we don't :-(
28722 However, I think this works ok. ++KFS 2003-04-25 */
28724 /* Redraw borders between horizontally adjacent windows. Don't
28725 do it for frames with vertical scroll bars because either the
28726 right scroll bar of a window, or the left scroll bar of its
28727 neighbor will suffice as a border. */
28728 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
28729 return;
28731 /* Note: It is necessary to redraw both the left and the right
28732 borders, for when only this single window W is being
28733 redisplayed. */
28734 if (!WINDOW_RIGHTMOST_P (w)
28735 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
28737 int x0, x1, y0, y1;
28739 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
28740 y1 -= 1;
28742 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
28743 x1 -= 1;
28745 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
28747 if (!WINDOW_LEFTMOST_P (w)
28748 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
28750 int x0, x1, y0, y1;
28752 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
28753 y1 -= 1;
28755 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
28756 x0 -= 1;
28758 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
28763 /* Redraw the part of window W intersection rectangle FR. Pixel
28764 coordinates in FR are frame-relative. Call this function with
28765 input blocked. Value is non-zero if the exposure overwrites
28766 mouse-face. */
28768 static int
28769 expose_window (struct window *w, XRectangle *fr)
28771 struct frame *f = XFRAME (w->frame);
28772 XRectangle wr, r;
28773 int mouse_face_overwritten_p = 0;
28775 /* If window is not yet fully initialized, do nothing. This can
28776 happen when toolkit scroll bars are used and a window is split.
28777 Reconfiguring the scroll bar will generate an expose for a newly
28778 created window. */
28779 if (w->current_matrix == NULL)
28780 return 0;
28782 /* When we're currently updating the window, display and current
28783 matrix usually don't agree. Arrange for a thorough display
28784 later. */
28785 if (w == updated_window)
28787 SET_FRAME_GARBAGED (f);
28788 return 0;
28791 /* Frame-relative pixel rectangle of W. */
28792 wr.x = WINDOW_LEFT_EDGE_X (w);
28793 wr.y = WINDOW_TOP_EDGE_Y (w);
28794 wr.width = WINDOW_TOTAL_WIDTH (w);
28795 wr.height = WINDOW_TOTAL_HEIGHT (w);
28797 if (x_intersect_rectangles (fr, &wr, &r))
28799 int yb = window_text_bottom_y (w);
28800 struct glyph_row *row;
28801 int cursor_cleared_p, phys_cursor_on_p;
28802 struct glyph_row *first_overlapping_row, *last_overlapping_row;
28804 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
28805 r.x, r.y, r.width, r.height));
28807 /* Convert to window coordinates. */
28808 r.x -= WINDOW_LEFT_EDGE_X (w);
28809 r.y -= WINDOW_TOP_EDGE_Y (w);
28811 /* Turn off the cursor. */
28812 if (!w->pseudo_window_p
28813 && phys_cursor_in_rect_p (w, &r))
28815 x_clear_cursor (w);
28816 cursor_cleared_p = 1;
28818 else
28819 cursor_cleared_p = 0;
28821 /* If the row containing the cursor extends face to end of line,
28822 then expose_area might overwrite the cursor outside the
28823 rectangle and thus notice_overwritten_cursor might clear
28824 w->phys_cursor_on_p. We remember the original value and
28825 check later if it is changed. */
28826 phys_cursor_on_p = w->phys_cursor_on_p;
28828 /* Update lines intersecting rectangle R. */
28829 first_overlapping_row = last_overlapping_row = NULL;
28830 for (row = w->current_matrix->rows;
28831 row->enabled_p;
28832 ++row)
28834 int y0 = row->y;
28835 int y1 = MATRIX_ROW_BOTTOM_Y (row);
28837 if ((y0 >= r.y && y0 < r.y + r.height)
28838 || (y1 > r.y && y1 < r.y + r.height)
28839 || (r.y >= y0 && r.y < y1)
28840 || (r.y + r.height > y0 && r.y + r.height < y1))
28842 /* A header line may be overlapping, but there is no need
28843 to fix overlapping areas for them. KFS 2005-02-12 */
28844 if (row->overlapping_p && !row->mode_line_p)
28846 if (first_overlapping_row == NULL)
28847 first_overlapping_row = row;
28848 last_overlapping_row = row;
28851 row->clip = fr;
28852 if (expose_line (w, row, &r))
28853 mouse_face_overwritten_p = 1;
28854 row->clip = NULL;
28856 else if (row->overlapping_p)
28858 /* We must redraw a row overlapping the exposed area. */
28859 if (y0 < r.y
28860 ? y0 + row->phys_height > r.y
28861 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
28863 if (first_overlapping_row == NULL)
28864 first_overlapping_row = row;
28865 last_overlapping_row = row;
28869 if (y1 >= yb)
28870 break;
28873 /* Display the mode line if there is one. */
28874 if (WINDOW_WANTS_MODELINE_P (w)
28875 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
28876 row->enabled_p)
28877 && row->y < r.y + r.height)
28879 if (expose_line (w, row, &r))
28880 mouse_face_overwritten_p = 1;
28883 if (!w->pseudo_window_p)
28885 /* Fix the display of overlapping rows. */
28886 if (first_overlapping_row)
28887 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
28888 fr);
28890 /* Draw border between windows. */
28891 x_draw_vertical_border (w);
28893 /* Turn the cursor on again. */
28894 if (cursor_cleared_p
28895 || (phys_cursor_on_p && !w->phys_cursor_on_p))
28896 update_window_cursor (w, 1);
28900 return mouse_face_overwritten_p;
28905 /* Redraw (parts) of all windows in the window tree rooted at W that
28906 intersect R. R contains frame pixel coordinates. Value is
28907 non-zero if the exposure overwrites mouse-face. */
28909 static int
28910 expose_window_tree (struct window *w, XRectangle *r)
28912 struct frame *f = XFRAME (w->frame);
28913 int mouse_face_overwritten_p = 0;
28915 while (w && !FRAME_GARBAGED_P (f))
28917 if (WINDOWP (w->contents))
28918 mouse_face_overwritten_p
28919 |= expose_window_tree (XWINDOW (w->contents), r);
28920 else
28921 mouse_face_overwritten_p |= expose_window (w, r);
28923 w = NILP (w->next) ? NULL : XWINDOW (w->next);
28926 return mouse_face_overwritten_p;
28930 /* EXPORT:
28931 Redisplay an exposed area of frame F. X and Y are the upper-left
28932 corner of the exposed rectangle. W and H are width and height of
28933 the exposed area. All are pixel values. W or H zero means redraw
28934 the entire frame. */
28936 void
28937 expose_frame (struct frame *f, int x, int y, int w, int h)
28939 XRectangle r;
28940 int mouse_face_overwritten_p = 0;
28942 TRACE ((stderr, "expose_frame "));
28944 /* No need to redraw if frame will be redrawn soon. */
28945 if (FRAME_GARBAGED_P (f))
28947 TRACE ((stderr, " garbaged\n"));
28948 return;
28951 /* If basic faces haven't been realized yet, there is no point in
28952 trying to redraw anything. This can happen when we get an expose
28953 event while Emacs is starting, e.g. by moving another window. */
28954 if (FRAME_FACE_CACHE (f) == NULL
28955 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
28957 TRACE ((stderr, " no faces\n"));
28958 return;
28961 if (w == 0 || h == 0)
28963 r.x = r.y = 0;
28964 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
28965 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
28967 else
28969 r.x = x;
28970 r.y = y;
28971 r.width = w;
28972 r.height = h;
28975 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
28976 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
28978 if (WINDOWP (f->tool_bar_window))
28979 mouse_face_overwritten_p
28980 |= expose_window (XWINDOW (f->tool_bar_window), &r);
28982 #ifdef HAVE_X_WINDOWS
28983 #ifndef MSDOS
28984 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
28985 if (WINDOWP (f->menu_bar_window))
28986 mouse_face_overwritten_p
28987 |= expose_window (XWINDOW (f->menu_bar_window), &r);
28988 #endif /* not USE_X_TOOLKIT and not USE_GTK */
28989 #endif
28990 #endif
28992 /* Some window managers support a focus-follows-mouse style with
28993 delayed raising of frames. Imagine a partially obscured frame,
28994 and moving the mouse into partially obscured mouse-face on that
28995 frame. The visible part of the mouse-face will be highlighted,
28996 then the WM raises the obscured frame. With at least one WM, KDE
28997 2.1, Emacs is not getting any event for the raising of the frame
28998 (even tried with SubstructureRedirectMask), only Expose events.
28999 These expose events will draw text normally, i.e. not
29000 highlighted. Which means we must redo the highlight here.
29001 Subsume it under ``we love X''. --gerd 2001-08-15 */
29002 /* Included in Windows version because Windows most likely does not
29003 do the right thing if any third party tool offers
29004 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
29005 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
29007 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
29008 if (f == hlinfo->mouse_face_mouse_frame)
29010 int mouse_x = hlinfo->mouse_face_mouse_x;
29011 int mouse_y = hlinfo->mouse_face_mouse_y;
29012 clear_mouse_face (hlinfo);
29013 note_mouse_highlight (f, mouse_x, mouse_y);
29019 /* EXPORT:
29020 Determine the intersection of two rectangles R1 and R2. Return
29021 the intersection in *RESULT. Value is non-zero if RESULT is not
29022 empty. */
29025 x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
29027 XRectangle *left, *right;
29028 XRectangle *upper, *lower;
29029 int intersection_p = 0;
29031 /* Rearrange so that R1 is the left-most rectangle. */
29032 if (r1->x < r2->x)
29033 left = r1, right = r2;
29034 else
29035 left = r2, right = r1;
29037 /* X0 of the intersection is right.x0, if this is inside R1,
29038 otherwise there is no intersection. */
29039 if (right->x <= left->x + left->width)
29041 result->x = right->x;
29043 /* The right end of the intersection is the minimum of
29044 the right ends of left and right. */
29045 result->width = (min (left->x + left->width, right->x + right->width)
29046 - result->x);
29048 /* Same game for Y. */
29049 if (r1->y < r2->y)
29050 upper = r1, lower = r2;
29051 else
29052 upper = r2, lower = r1;
29054 /* The upper end of the intersection is lower.y0, if this is inside
29055 of upper. Otherwise, there is no intersection. */
29056 if (lower->y <= upper->y + upper->height)
29058 result->y = lower->y;
29060 /* The lower end of the intersection is the minimum of the lower
29061 ends of upper and lower. */
29062 result->height = (min (lower->y + lower->height,
29063 upper->y + upper->height)
29064 - result->y);
29065 intersection_p = 1;
29069 return intersection_p;
29072 #endif /* HAVE_WINDOW_SYSTEM */
29075 /***********************************************************************
29076 Initialization
29077 ***********************************************************************/
29079 void
29080 syms_of_xdisp (void)
29082 Vwith_echo_area_save_vector = Qnil;
29083 staticpro (&Vwith_echo_area_save_vector);
29085 Vmessage_stack = Qnil;
29086 staticpro (&Vmessage_stack);
29088 DEFSYM (Qinhibit_redisplay, "inhibit-redisplay");
29089 DEFSYM (Qredisplay_internal, "redisplay_internal (C function)");
29091 message_dolog_marker1 = Fmake_marker ();
29092 staticpro (&message_dolog_marker1);
29093 message_dolog_marker2 = Fmake_marker ();
29094 staticpro (&message_dolog_marker2);
29095 message_dolog_marker3 = Fmake_marker ();
29096 staticpro (&message_dolog_marker3);
29098 #ifdef GLYPH_DEBUG
29099 defsubr (&Sdump_frame_glyph_matrix);
29100 defsubr (&Sdump_glyph_matrix);
29101 defsubr (&Sdump_glyph_row);
29102 defsubr (&Sdump_tool_bar_row);
29103 defsubr (&Strace_redisplay);
29104 defsubr (&Strace_to_stderr);
29105 #endif
29106 #ifdef HAVE_WINDOW_SYSTEM
29107 defsubr (&Stool_bar_lines_needed);
29108 defsubr (&Slookup_image_map);
29109 #endif
29110 defsubr (&Sline_pixel_height);
29111 defsubr (&Sformat_mode_line);
29112 defsubr (&Sinvisible_p);
29113 defsubr (&Scurrent_bidi_paragraph_direction);
29114 defsubr (&Smove_point_visually);
29116 DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook");
29117 DEFSYM (Qoverriding_terminal_local_map, "overriding-terminal-local-map");
29118 DEFSYM (Qoverriding_local_map, "overriding-local-map");
29119 DEFSYM (Qwindow_scroll_functions, "window-scroll-functions");
29120 DEFSYM (Qwindow_text_change_functions, "window-text-change-functions");
29121 DEFSYM (Qredisplay_end_trigger_functions, "redisplay-end-trigger-functions");
29122 DEFSYM (Qinhibit_point_motion_hooks, "inhibit-point-motion-hooks");
29123 DEFSYM (Qeval, "eval");
29124 DEFSYM (QCdata, ":data");
29125 DEFSYM (Qdisplay, "display");
29126 DEFSYM (Qspace_width, "space-width");
29127 DEFSYM (Qraise, "raise");
29128 DEFSYM (Qslice, "slice");
29129 DEFSYM (Qspace, "space");
29130 DEFSYM (Qmargin, "margin");
29131 DEFSYM (Qpointer, "pointer");
29132 DEFSYM (Qleft_margin, "left-margin");
29133 DEFSYM (Qright_margin, "right-margin");
29134 DEFSYM (Qcenter, "center");
29135 DEFSYM (Qline_height, "line-height");
29136 DEFSYM (QCalign_to, ":align-to");
29137 DEFSYM (QCrelative_width, ":relative-width");
29138 DEFSYM (QCrelative_height, ":relative-height");
29139 DEFSYM (QCeval, ":eval");
29140 DEFSYM (QCpropertize, ":propertize");
29141 DEFSYM (QCfile, ":file");
29142 DEFSYM (Qfontified, "fontified");
29143 DEFSYM (Qfontification_functions, "fontification-functions");
29144 DEFSYM (Qtrailing_whitespace, "trailing-whitespace");
29145 DEFSYM (Qescape_glyph, "escape-glyph");
29146 DEFSYM (Qnobreak_space, "nobreak-space");
29147 DEFSYM (Qimage, "image");
29148 DEFSYM (Qtext, "text");
29149 DEFSYM (Qboth, "both");
29150 DEFSYM (Qboth_horiz, "both-horiz");
29151 DEFSYM (Qtext_image_horiz, "text-image-horiz");
29152 DEFSYM (QCmap, ":map");
29153 DEFSYM (QCpointer, ":pointer");
29154 DEFSYM (Qrect, "rect");
29155 DEFSYM (Qcircle, "circle");
29156 DEFSYM (Qpoly, "poly");
29157 DEFSYM (Qmessage_truncate_lines, "message-truncate-lines");
29158 DEFSYM (Qgrow_only, "grow-only");
29159 DEFSYM (Qinhibit_menubar_update, "inhibit-menubar-update");
29160 DEFSYM (Qinhibit_eval_during_redisplay, "inhibit-eval-during-redisplay");
29161 DEFSYM (Qposition, "position");
29162 DEFSYM (Qbuffer_position, "buffer-position");
29163 DEFSYM (Qobject, "object");
29164 DEFSYM (Qbar, "bar");
29165 DEFSYM (Qhbar, "hbar");
29166 DEFSYM (Qbox, "box");
29167 DEFSYM (Qhollow, "hollow");
29168 DEFSYM (Qhand, "hand");
29169 DEFSYM (Qarrow, "arrow");
29170 DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces");
29172 list_of_error = Fcons (Fcons (intern_c_string ("error"),
29173 Fcons (intern_c_string ("void-variable"), Qnil)),
29174 Qnil);
29175 staticpro (&list_of_error);
29177 DEFSYM (Qlast_arrow_position, "last-arrow-position");
29178 DEFSYM (Qlast_arrow_string, "last-arrow-string");
29179 DEFSYM (Qoverlay_arrow_string, "overlay-arrow-string");
29180 DEFSYM (Qoverlay_arrow_bitmap, "overlay-arrow-bitmap");
29182 echo_buffer[0] = echo_buffer[1] = Qnil;
29183 staticpro (&echo_buffer[0]);
29184 staticpro (&echo_buffer[1]);
29186 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
29187 staticpro (&echo_area_buffer[0]);
29188 staticpro (&echo_area_buffer[1]);
29190 Vmessages_buffer_name = build_pure_c_string ("*Messages*");
29191 staticpro (&Vmessages_buffer_name);
29193 mode_line_proptrans_alist = Qnil;
29194 staticpro (&mode_line_proptrans_alist);
29195 mode_line_string_list = Qnil;
29196 staticpro (&mode_line_string_list);
29197 mode_line_string_face = Qnil;
29198 staticpro (&mode_line_string_face);
29199 mode_line_string_face_prop = Qnil;
29200 staticpro (&mode_line_string_face_prop);
29201 Vmode_line_unwind_vector = Qnil;
29202 staticpro (&Vmode_line_unwind_vector);
29204 DEFSYM (Qmode_line_default_help_echo, "mode-line-default-help-echo");
29206 help_echo_string = Qnil;
29207 staticpro (&help_echo_string);
29208 help_echo_object = Qnil;
29209 staticpro (&help_echo_object);
29210 help_echo_window = Qnil;
29211 staticpro (&help_echo_window);
29212 previous_help_echo_string = Qnil;
29213 staticpro (&previous_help_echo_string);
29214 help_echo_pos = -1;
29216 DEFSYM (Qright_to_left, "right-to-left");
29217 DEFSYM (Qleft_to_right, "left-to-right");
29219 #ifdef HAVE_WINDOW_SYSTEM
29220 DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p,
29221 doc: /* Non-nil means draw block cursor as wide as the glyph under it.
29222 For example, if a block cursor is over a tab, it will be drawn as
29223 wide as that tab on the display. */);
29224 x_stretch_cursor_p = 0;
29225 #endif
29227 DEFVAR_LISP ("show-trailing-whitespace", Vshow_trailing_whitespace,
29228 doc: /* Non-nil means highlight trailing whitespace.
29229 The face used for trailing whitespace is `trailing-whitespace'. */);
29230 Vshow_trailing_whitespace = Qnil;
29232 DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display,
29233 doc: /* Control highlighting of non-ASCII space and hyphen chars.
29234 If the value is t, Emacs highlights non-ASCII chars which have the
29235 same appearance as an ASCII space or hyphen, using the `nobreak-space'
29236 or `escape-glyph' face respectively.
29238 U+00A0 (no-break space), U+00AD (soft hyphen), U+2010 (hyphen), and
29239 U+2011 (non-breaking hyphen) are affected.
29241 Any other non-nil value means to display these characters as a escape
29242 glyph followed by an ordinary space or hyphen.
29244 A value of nil means no special handling of these characters. */);
29245 Vnobreak_char_display = Qt;
29247 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer,
29248 doc: /* The pointer shape to show in void text areas.
29249 A value of nil means to show the text pointer. Other options are `arrow',
29250 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
29251 Vvoid_text_area_pointer = Qarrow;
29253 DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay,
29254 doc: /* Non-nil means don't actually do any redisplay.
29255 This is used for internal purposes. */);
29256 Vinhibit_redisplay = Qnil;
29258 DEFVAR_LISP ("global-mode-string", Vglobal_mode_string,
29259 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
29260 Vglobal_mode_string = Qnil;
29262 DEFVAR_LISP ("overlay-arrow-position", Voverlay_arrow_position,
29263 doc: /* Marker for where to display an arrow on top of the buffer text.
29264 This must be the beginning of a line in order to work.
29265 See also `overlay-arrow-string'. */);
29266 Voverlay_arrow_position = Qnil;
29268 DEFVAR_LISP ("overlay-arrow-string", Voverlay_arrow_string,
29269 doc: /* String to display as an arrow in non-window frames.
29270 See also `overlay-arrow-position'. */);
29271 Voverlay_arrow_string = build_pure_c_string ("=>");
29273 DEFVAR_LISP ("overlay-arrow-variable-list", Voverlay_arrow_variable_list,
29274 doc: /* List of variables (symbols) which hold markers for overlay arrows.
29275 The symbols on this list are examined during redisplay to determine
29276 where to display overlay arrows. */);
29277 Voverlay_arrow_variable_list
29278 = Fcons (intern_c_string ("overlay-arrow-position"), Qnil);
29280 DEFVAR_INT ("scroll-step", emacs_scroll_step,
29281 doc: /* The number of lines to try scrolling a window by when point moves out.
29282 If that fails to bring point back on frame, point is centered instead.
29283 If this is zero, point is always centered after it moves off frame.
29284 If you want scrolling to always be a line at a time, you should set
29285 `scroll-conservatively' to a large value rather than set this to 1. */);
29287 DEFVAR_INT ("scroll-conservatively", scroll_conservatively,
29288 doc: /* Scroll up to this many lines, to bring point back on screen.
29289 If point moves off-screen, redisplay will scroll by up to
29290 `scroll-conservatively' lines in order to bring point just barely
29291 onto the screen again. If that cannot be done, then redisplay
29292 recenters point as usual.
29294 If the value is greater than 100, redisplay will never recenter point,
29295 but will always scroll just enough text to bring point into view, even
29296 if you move far away.
29298 A value of zero means always recenter point if it moves off screen. */);
29299 scroll_conservatively = 0;
29301 DEFVAR_INT ("scroll-margin", scroll_margin,
29302 doc: /* Number of lines of margin at the top and bottom of a window.
29303 Recenter the window whenever point gets within this many lines
29304 of the top or bottom of the window. */);
29305 scroll_margin = 0;
29307 DEFVAR_LISP ("display-pixels-per-inch", Vdisplay_pixels_per_inch,
29308 doc: /* Pixels per inch value for non-window system displays.
29309 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
29310 Vdisplay_pixels_per_inch = make_float (72.0);
29312 #ifdef GLYPH_DEBUG
29313 DEFVAR_INT ("debug-end-pos", debug_end_pos, doc: /* Don't ask. */);
29314 #endif
29316 DEFVAR_LISP ("truncate-partial-width-windows",
29317 Vtruncate_partial_width_windows,
29318 doc: /* Non-nil means truncate lines in windows narrower than the frame.
29319 For an integer value, truncate lines in each window narrower than the
29320 full frame width, provided the window width is less than that integer;
29321 otherwise, respect the value of `truncate-lines'.
29323 For any other non-nil value, truncate lines in all windows that do
29324 not span the full frame width.
29326 A value of nil means to respect the value of `truncate-lines'.
29328 If `word-wrap' is enabled, you might want to reduce this. */);
29329 Vtruncate_partial_width_windows = make_number (50);
29331 DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit,
29332 doc: /* Maximum buffer size for which line number should be displayed.
29333 If the buffer is bigger than this, the line number does not appear
29334 in the mode line. A value of nil means no limit. */);
29335 Vline_number_display_limit = Qnil;
29337 DEFVAR_INT ("line-number-display-limit-width",
29338 line_number_display_limit_width,
29339 doc: /* Maximum line width (in characters) for line number display.
29340 If the average length of the lines near point is bigger than this, then the
29341 line number may be omitted from the mode line. */);
29342 line_number_display_limit_width = 200;
29344 DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows,
29345 doc: /* Non-nil means highlight region even in nonselected windows. */);
29346 highlight_nonselected_windows = 0;
29348 DEFVAR_BOOL ("multiple-frames", multiple_frames,
29349 doc: /* Non-nil if more than one frame is visible on this display.
29350 Minibuffer-only frames don't count, but iconified frames do.
29351 This variable is not guaranteed to be accurate except while processing
29352 `frame-title-format' and `icon-title-format'. */);
29354 DEFVAR_LISP ("frame-title-format", Vframe_title_format,
29355 doc: /* Template for displaying the title bar of visible frames.
29356 \(Assuming the window manager supports this feature.)
29358 This variable has the same structure as `mode-line-format', except that
29359 the %c and %l constructs are ignored. It is used only on frames for
29360 which no explicit name has been set \(see `modify-frame-parameters'). */);
29362 DEFVAR_LISP ("icon-title-format", Vicon_title_format,
29363 doc: /* Template for displaying the title bar of an iconified frame.
29364 \(Assuming the window manager supports this feature.)
29365 This variable has the same structure as `mode-line-format' (which see),
29366 and is used only on frames for which no explicit name has been set
29367 \(see `modify-frame-parameters'). */);
29368 Vicon_title_format
29369 = Vframe_title_format
29370 = listn (CONSTYPE_PURE, 3,
29371 intern_c_string ("multiple-frames"),
29372 build_pure_c_string ("%b"),
29373 listn (CONSTYPE_PURE, 4,
29374 empty_unibyte_string,
29375 intern_c_string ("invocation-name"),
29376 build_pure_c_string ("@"),
29377 intern_c_string ("system-name")));
29379 DEFVAR_LISP ("message-log-max", Vmessage_log_max,
29380 doc: /* Maximum number of lines to keep in the message log buffer.
29381 If nil, disable message logging. If t, log messages but don't truncate
29382 the buffer when it becomes large. */);
29383 Vmessage_log_max = make_number (1000);
29385 DEFVAR_LISP ("window-size-change-functions", Vwindow_size_change_functions,
29386 doc: /* Functions called before redisplay, if window sizes have changed.
29387 The value should be a list of functions that take one argument.
29388 Just before redisplay, for each frame, if any of its windows have changed
29389 size since the last redisplay, or have been split or deleted,
29390 all the functions in the list are called, with the frame as argument. */);
29391 Vwindow_size_change_functions = Qnil;
29393 DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions,
29394 doc: /* List of functions to call before redisplaying a window with scrolling.
29395 Each function is called with two arguments, the window and its new
29396 display-start position. Note that these functions are also called by
29397 `set-window-buffer'. Also note that the value of `window-end' is not
29398 valid when these functions are called.
29400 Warning: Do not use this feature to alter the way the window
29401 is scrolled. It is not designed for that, and such use probably won't
29402 work. */);
29403 Vwindow_scroll_functions = Qnil;
29405 DEFVAR_LISP ("window-text-change-functions",
29406 Vwindow_text_change_functions,
29407 doc: /* Functions to call in redisplay when text in the window might change. */);
29408 Vwindow_text_change_functions = Qnil;
29410 DEFVAR_LISP ("redisplay-end-trigger-functions", Vredisplay_end_trigger_functions,
29411 doc: /* Functions called when redisplay of a window reaches the end trigger.
29412 Each function is called with two arguments, the window and the end trigger value.
29413 See `set-window-redisplay-end-trigger'. */);
29414 Vredisplay_end_trigger_functions = Qnil;
29416 DEFVAR_LISP ("mouse-autoselect-window", Vmouse_autoselect_window,
29417 doc: /* Non-nil means autoselect window with mouse pointer.
29418 If nil, do not autoselect windows.
29419 A positive number means delay autoselection by that many seconds: a
29420 window is autoselected only after the mouse has remained in that
29421 window for the duration of the delay.
29422 A negative number has a similar effect, but causes windows to be
29423 autoselected only after the mouse has stopped moving. \(Because of
29424 the way Emacs compares mouse events, you will occasionally wait twice
29425 that time before the window gets selected.\)
29426 Any other value means to autoselect window instantaneously when the
29427 mouse pointer enters it.
29429 Autoselection selects the minibuffer only if it is active, and never
29430 unselects the minibuffer if it is active.
29432 When customizing this variable make sure that the actual value of
29433 `focus-follows-mouse' matches the behavior of your window manager. */);
29434 Vmouse_autoselect_window = Qnil;
29436 DEFVAR_LISP ("auto-resize-tool-bars", Vauto_resize_tool_bars,
29437 doc: /* Non-nil means automatically resize tool-bars.
29438 This dynamically changes the tool-bar's height to the minimum height
29439 that is needed to make all tool-bar items visible.
29440 If value is `grow-only', the tool-bar's height is only increased
29441 automatically; to decrease the tool-bar height, use \\[recenter]. */);
29442 Vauto_resize_tool_bars = Qt;
29444 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p,
29445 doc: /* Non-nil means raise tool-bar buttons when the mouse moves over them. */);
29446 auto_raise_tool_bar_buttons_p = 1;
29448 DEFVAR_BOOL ("make-cursor-line-fully-visible", make_cursor_line_fully_visible_p,
29449 doc: /* Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
29450 make_cursor_line_fully_visible_p = 1;
29452 DEFVAR_LISP ("tool-bar-border", Vtool_bar_border,
29453 doc: /* Border below tool-bar in pixels.
29454 If an integer, use it as the height of the border.
29455 If it is one of `internal-border-width' or `border-width', use the
29456 value of the corresponding frame parameter.
29457 Otherwise, no border is added below the tool-bar. */);
29458 Vtool_bar_border = Qinternal_border_width;
29460 DEFVAR_LISP ("tool-bar-button-margin", Vtool_bar_button_margin,
29461 doc: /* Margin around tool-bar buttons in pixels.
29462 If an integer, use that for both horizontal and vertical margins.
29463 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
29464 HORZ specifying the horizontal margin, and VERT specifying the
29465 vertical margin. */);
29466 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
29468 DEFVAR_INT ("tool-bar-button-relief", tool_bar_button_relief,
29469 doc: /* Relief thickness of tool-bar buttons. */);
29470 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
29472 DEFVAR_LISP ("tool-bar-style", Vtool_bar_style,
29473 doc: /* Tool bar style to use.
29474 It can be one of
29475 image - show images only
29476 text - show text only
29477 both - show both, text below image
29478 both-horiz - show text to the right of the image
29479 text-image-horiz - show text to the left of the image
29480 any other - use system default or image if no system default.
29482 This variable only affects the GTK+ toolkit version of Emacs. */);
29483 Vtool_bar_style = Qnil;
29485 DEFVAR_INT ("tool-bar-max-label-size", tool_bar_max_label_size,
29486 doc: /* Maximum number of characters a label can have to be shown.
29487 The tool bar style must also show labels for this to have any effect, see
29488 `tool-bar-style'. */);
29489 tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
29491 DEFVAR_LISP ("fontification-functions", Vfontification_functions,
29492 doc: /* List of functions to call to fontify regions of text.
29493 Each function is called with one argument POS. Functions must
29494 fontify a region starting at POS in the current buffer, and give
29495 fontified regions the property `fontified'. */);
29496 Vfontification_functions = Qnil;
29497 Fmake_variable_buffer_local (Qfontification_functions);
29499 DEFVAR_BOOL ("unibyte-display-via-language-environment",
29500 unibyte_display_via_language_environment,
29501 doc: /* Non-nil means display unibyte text according to language environment.
29502 Specifically, this means that raw bytes in the range 160-255 decimal
29503 are displayed by converting them to the equivalent multibyte characters
29504 according to the current language environment. As a result, they are
29505 displayed according to the current fontset.
29507 Note that this variable affects only how these bytes are displayed,
29508 but does not change the fact they are interpreted as raw bytes. */);
29509 unibyte_display_via_language_environment = 0;
29511 DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height,
29512 doc: /* Maximum height for resizing mini-windows (the minibuffer and the echo area).
29513 If a float, it specifies a fraction of the mini-window frame's height.
29514 If an integer, it specifies a number of lines. */);
29515 Vmax_mini_window_height = make_float (0.25);
29517 DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows,
29518 doc: /* How to resize mini-windows (the minibuffer and the echo area).
29519 A value of nil means don't automatically resize mini-windows.
29520 A value of t means resize them to fit the text displayed in them.
29521 A value of `grow-only', the default, means let mini-windows grow only;
29522 they return to their normal size when the minibuffer is closed, or the
29523 echo area becomes empty. */);
29524 Vresize_mini_windows = Qgrow_only;
29526 DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist,
29527 doc: /* Alist specifying how to blink the cursor off.
29528 Each element has the form (ON-STATE . OFF-STATE). Whenever the
29529 `cursor-type' frame-parameter or variable equals ON-STATE,
29530 comparing using `equal', Emacs uses OFF-STATE to specify
29531 how to blink it off. ON-STATE and OFF-STATE are values for
29532 the `cursor-type' frame parameter.
29534 If a frame's ON-STATE has no entry in this list,
29535 the frame's other specifications determine how to blink the cursor off. */);
29536 Vblink_cursor_alist = Qnil;
29538 DEFVAR_BOOL ("auto-hscroll-mode", automatic_hscrolling_p,
29539 doc: /* Allow or disallow automatic horizontal scrolling of windows.
29540 If non-nil, windows are automatically scrolled horizontally to make
29541 point visible. */);
29542 automatic_hscrolling_p = 1;
29543 DEFSYM (Qauto_hscroll_mode, "auto-hscroll-mode");
29545 DEFVAR_INT ("hscroll-margin", hscroll_margin,
29546 doc: /* How many columns away from the window edge point is allowed to get
29547 before automatic hscrolling will horizontally scroll the window. */);
29548 hscroll_margin = 5;
29550 DEFVAR_LISP ("hscroll-step", Vhscroll_step,
29551 doc: /* How many columns to scroll the window when point gets too close to the edge.
29552 When point is less than `hscroll-margin' columns from the window
29553 edge, automatic hscrolling will scroll the window by the amount of columns
29554 determined by this variable. If its value is a positive integer, scroll that
29555 many columns. If it's a positive floating-point number, it specifies the
29556 fraction of the window's width to scroll. If it's nil or zero, point will be
29557 centered horizontally after the scroll. Any other value, including negative
29558 numbers, are treated as if the value were zero.
29560 Automatic hscrolling always moves point outside the scroll margin, so if
29561 point was more than scroll step columns inside the margin, the window will
29562 scroll more than the value given by the scroll step.
29564 Note that the lower bound for automatic hscrolling specified by `scroll-left'
29565 and `scroll-right' overrides this variable's effect. */);
29566 Vhscroll_step = make_number (0);
29568 DEFVAR_BOOL ("message-truncate-lines", message_truncate_lines,
29569 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
29570 Bind this around calls to `message' to let it take effect. */);
29571 message_truncate_lines = 0;
29573 DEFVAR_LISP ("menu-bar-update-hook", Vmenu_bar_update_hook,
29574 doc: /* Normal hook run to update the menu bar definitions.
29575 Redisplay runs this hook before it redisplays the menu bar.
29576 This is used to update submenus such as Buffers,
29577 whose contents depend on various data. */);
29578 Vmenu_bar_update_hook = Qnil;
29580 DEFVAR_LISP ("menu-updating-frame", Vmenu_updating_frame,
29581 doc: /* Frame for which we are updating a menu.
29582 The enable predicate for a menu binding should check this variable. */);
29583 Vmenu_updating_frame = Qnil;
29585 DEFVAR_BOOL ("inhibit-menubar-update", inhibit_menubar_update,
29586 doc: /* Non-nil means don't update menu bars. Internal use only. */);
29587 inhibit_menubar_update = 0;
29589 DEFVAR_LISP ("wrap-prefix", Vwrap_prefix,
29590 doc: /* Prefix prepended to all continuation lines at display time.
29591 The value may be a string, an image, or a stretch-glyph; it is
29592 interpreted in the same way as the value of a `display' text property.
29594 This variable is overridden by any `wrap-prefix' text or overlay
29595 property.
29597 To add a prefix to non-continuation lines, use `line-prefix'. */);
29598 Vwrap_prefix = Qnil;
29599 DEFSYM (Qwrap_prefix, "wrap-prefix");
29600 Fmake_variable_buffer_local (Qwrap_prefix);
29602 DEFVAR_LISP ("line-prefix", Vline_prefix,
29603 doc: /* Prefix prepended to all non-continuation lines at display time.
29604 The value may be a string, an image, or a stretch-glyph; it is
29605 interpreted in the same way as the value of a `display' text property.
29607 This variable is overridden by any `line-prefix' text or overlay
29608 property.
29610 To add a prefix to continuation lines, use `wrap-prefix'. */);
29611 Vline_prefix = Qnil;
29612 DEFSYM (Qline_prefix, "line-prefix");
29613 Fmake_variable_buffer_local (Qline_prefix);
29615 DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay,
29616 doc: /* Non-nil means don't eval Lisp during redisplay. */);
29617 inhibit_eval_during_redisplay = 0;
29619 DEFVAR_BOOL ("inhibit-free-realized-faces", inhibit_free_realized_faces,
29620 doc: /* Non-nil means don't free realized faces. Internal use only. */);
29621 inhibit_free_realized_faces = 0;
29623 #ifdef GLYPH_DEBUG
29624 DEFVAR_BOOL ("inhibit-try-window-id", inhibit_try_window_id,
29625 doc: /* Inhibit try_window_id display optimization. */);
29626 inhibit_try_window_id = 0;
29628 DEFVAR_BOOL ("inhibit-try-window-reusing", inhibit_try_window_reusing,
29629 doc: /* Inhibit try_window_reusing display optimization. */);
29630 inhibit_try_window_reusing = 0;
29632 DEFVAR_BOOL ("inhibit-try-cursor-movement", inhibit_try_cursor_movement,
29633 doc: /* Inhibit try_cursor_movement display optimization. */);
29634 inhibit_try_cursor_movement = 0;
29635 #endif /* GLYPH_DEBUG */
29637 DEFVAR_INT ("overline-margin", overline_margin,
29638 doc: /* Space between overline and text, in pixels.
29639 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
29640 margin to the character height. */);
29641 overline_margin = 2;
29643 DEFVAR_INT ("underline-minimum-offset",
29644 underline_minimum_offset,
29645 doc: /* Minimum distance between baseline and underline.
29646 This can improve legibility of underlined text at small font sizes,
29647 particularly when using variable `x-use-underline-position-properties'
29648 with fonts that specify an UNDERLINE_POSITION relatively close to the
29649 baseline. The default value is 1. */);
29650 underline_minimum_offset = 1;
29652 DEFVAR_BOOL ("display-hourglass", display_hourglass_p,
29653 doc: /* Non-nil means show an hourglass pointer, when Emacs is busy.
29654 This feature only works when on a window system that can change
29655 cursor shapes. */);
29656 display_hourglass_p = 1;
29658 DEFVAR_LISP ("hourglass-delay", Vhourglass_delay,
29659 doc: /* Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
29660 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
29662 hourglass_atimer = NULL;
29663 hourglass_shown_p = 0;
29665 DEFSYM (Qglyphless_char, "glyphless-char");
29666 DEFSYM (Qhex_code, "hex-code");
29667 DEFSYM (Qempty_box, "empty-box");
29668 DEFSYM (Qthin_space, "thin-space");
29669 DEFSYM (Qzero_width, "zero-width");
29671 DEFSYM (Qglyphless_char_display, "glyphless-char-display");
29672 /* Intern this now in case it isn't already done.
29673 Setting this variable twice is harmless.
29674 But don't staticpro it here--that is done in alloc.c. */
29675 Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots");
29676 Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
29678 DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display,
29679 doc: /* Char-table defining glyphless characters.
29680 Each element, if non-nil, should be one of the following:
29681 an ASCII acronym string: display this string in a box
29682 `hex-code': display the hexadecimal code of a character in a box
29683 `empty-box': display as an empty box
29684 `thin-space': display as 1-pixel width space
29685 `zero-width': don't display
29686 An element may also be a cons cell (GRAPHICAL . TEXT), which specifies the
29687 display method for graphical terminals and text terminals respectively.
29688 GRAPHICAL and TEXT should each have one of the values listed above.
29690 The char-table has one extra slot to control the display of a character for
29691 which no font is found. This slot only takes effect on graphical terminals.
29692 Its value should be an ASCII acronym string, `hex-code', `empty-box', or
29693 `thin-space'. The default is `empty-box'. */);
29694 Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
29695 Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
29696 Qempty_box);
29698 DEFVAR_LISP ("debug-on-message", Vdebug_on_message,
29699 doc: /* If non-nil, debug if a message matching this regexp is displayed. */);
29700 Vdebug_on_message = Qnil;
29704 /* Initialize this module when Emacs starts. */
29706 void
29707 init_xdisp (void)
29709 current_header_line_height = current_mode_line_height = -1;
29711 CHARPOS (this_line_start_pos) = 0;
29713 if (!noninteractive)
29715 struct window *m = XWINDOW (minibuf_window);
29716 Lisp_Object frame = m->frame;
29717 struct frame *f = XFRAME (frame);
29718 Lisp_Object root = FRAME_ROOT_WINDOW (f);
29719 struct window *r = XWINDOW (root);
29720 int i;
29722 echo_area_window = minibuf_window;
29724 r->top_line = FRAME_TOP_MARGIN (f);
29725 r->total_lines = FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f);
29726 r->total_cols = FRAME_COLS (f);
29728 m->top_line = FRAME_LINES (f) - 1;
29729 m->total_lines = 1;
29730 m->total_cols = FRAME_COLS (f);
29732 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
29733 scratch_glyph_row.glyphs[TEXT_AREA + 1]
29734 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
29736 /* The default ellipsis glyphs `...'. */
29737 for (i = 0; i < 3; ++i)
29738 default_invis_vector[i] = make_number ('.');
29742 /* Allocate the buffer for frame titles.
29743 Also used for `format-mode-line'. */
29744 int size = 100;
29745 mode_line_noprop_buf = xmalloc (size);
29746 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
29747 mode_line_noprop_ptr = mode_line_noprop_buf;
29748 mode_line_target = MODE_LINE_DISPLAY;
29751 help_echo_showing_p = 0;
29754 /* Platform-independent portion of hourglass implementation. */
29756 /* Cancel a currently active hourglass timer, and start a new one. */
29757 void
29758 start_hourglass (void)
29760 #if defined (HAVE_WINDOW_SYSTEM)
29761 EMACS_TIME delay;
29763 cancel_hourglass ();
29765 if (INTEGERP (Vhourglass_delay)
29766 && XINT (Vhourglass_delay) > 0)
29767 delay = make_emacs_time (min (XINT (Vhourglass_delay),
29768 TYPE_MAXIMUM (time_t)),
29770 else if (FLOATP (Vhourglass_delay)
29771 && XFLOAT_DATA (Vhourglass_delay) > 0)
29772 delay = EMACS_TIME_FROM_DOUBLE (XFLOAT_DATA (Vhourglass_delay));
29773 else
29774 delay = make_emacs_time (DEFAULT_HOURGLASS_DELAY, 0);
29776 #ifdef HAVE_NTGUI
29778 extern void w32_note_current_window (void);
29779 w32_note_current_window ();
29781 #endif /* HAVE_NTGUI */
29783 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
29784 show_hourglass, NULL);
29785 #endif
29789 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
29790 shown. */
29791 void
29792 cancel_hourglass (void)
29794 #if defined (HAVE_WINDOW_SYSTEM)
29795 if (hourglass_atimer)
29797 cancel_atimer (hourglass_atimer);
29798 hourglass_atimer = NULL;
29801 if (hourglass_shown_p)
29802 hide_hourglass ();
29803 #endif