* calendar/ChangeLog: Remove prior to merging new version of
[emacs/old-mirror.git] / src / xdisp.c
blob54ea325f642e3e2181fec0acd165ab3c10d531d4
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 ();
20056 /***********************************************************************
20057 Menu Bar
20058 ***********************************************************************/
20060 /* Redisplay the menu bar in the frame for window W.
20062 The menu bar of X frames that don't have X toolkit support is
20063 displayed in a special window W->frame->menu_bar_window.
20065 The menu bar of terminal frames is treated specially as far as
20066 glyph matrices are concerned. Menu bar lines are not part of
20067 windows, so the update is done directly on the frame matrix rows
20068 for the menu bar. */
20070 static void
20071 display_menu_bar (struct window *w)
20073 struct frame *f = XFRAME (WINDOW_FRAME (w));
20074 struct it it;
20075 Lisp_Object items;
20076 int i;
20078 /* Don't do all this for graphical frames. */
20079 #ifdef HAVE_NTGUI
20080 if (FRAME_W32_P (f))
20081 return;
20082 #endif
20083 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
20084 if (FRAME_X_P (f))
20085 return;
20086 #endif
20088 #ifdef HAVE_NS
20089 if (FRAME_NS_P (f))
20090 return;
20091 #endif /* HAVE_NS */
20093 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
20094 eassert (!FRAME_WINDOW_P (f));
20095 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
20096 it.first_visible_x = 0;
20097 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
20098 #elif defined (HAVE_X_WINDOWS) /* X without toolkit. */
20099 if (FRAME_WINDOW_P (f))
20101 /* Menu bar lines are displayed in the desired matrix of the
20102 dummy window menu_bar_window. */
20103 struct window *menu_w;
20104 menu_w = XWINDOW (f->menu_bar_window);
20105 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
20106 MENU_FACE_ID);
20107 it.first_visible_x = 0;
20108 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
20110 else
20111 #endif /* not USE_X_TOOLKIT and not USE_GTK */
20113 /* This is a TTY frame, i.e. character hpos/vpos are used as
20114 pixel x/y. */
20115 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
20116 MENU_FACE_ID);
20117 it.first_visible_x = 0;
20118 it.last_visible_x = FRAME_COLS (f);
20121 /* FIXME: This should be controlled by a user option. See the
20122 comments in redisplay_tool_bar and display_mode_line about
20123 this. */
20124 it.paragraph_embedding = L2R;
20126 /* Clear all rows of the menu bar. */
20127 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
20129 struct glyph_row *row = it.glyph_row + i;
20130 clear_glyph_row (row);
20131 row->enabled_p = 1;
20132 row->full_width_p = 1;
20135 /* Display all items of the menu bar. */
20136 items = FRAME_MENU_BAR_ITEMS (it.f);
20137 for (i = 0; i < ASIZE (items); i += 4)
20139 Lisp_Object string;
20141 /* Stop at nil string. */
20142 string = AREF (items, i + 1);
20143 if (NILP (string))
20144 break;
20146 /* Remember where item was displayed. */
20147 ASET (items, i + 3, make_number (it.hpos));
20149 /* Display the item, pad with one space. */
20150 if (it.current_x < it.last_visible_x)
20151 display_string (NULL, string, Qnil, 0, 0, &it,
20152 SCHARS (string) + 1, 0, 0, -1);
20155 /* Fill out the line with spaces. */
20156 if (it.current_x < it.last_visible_x)
20157 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
20159 /* Compute the total height of the lines. */
20160 compute_line_metrics (&it);
20165 /***********************************************************************
20166 Mode Line
20167 ***********************************************************************/
20169 /* Redisplay mode lines in the window tree whose root is WINDOW. If
20170 FORCE is non-zero, redisplay mode lines unconditionally.
20171 Otherwise, redisplay only mode lines that are garbaged. Value is
20172 the number of windows whose mode lines were redisplayed. */
20174 static int
20175 redisplay_mode_lines (Lisp_Object window, int force)
20177 int nwindows = 0;
20179 while (!NILP (window))
20181 struct window *w = XWINDOW (window);
20183 if (WINDOWP (w->contents))
20184 nwindows += redisplay_mode_lines (w->contents, force);
20185 else if (force
20186 || FRAME_GARBAGED_P (XFRAME (w->frame))
20187 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
20189 struct text_pos lpoint;
20190 struct buffer *old = current_buffer;
20192 /* Set the window's buffer for the mode line display. */
20193 SET_TEXT_POS (lpoint, PT, PT_BYTE);
20194 set_buffer_internal_1 (XBUFFER (w->contents));
20196 /* Point refers normally to the selected window. For any
20197 other window, set up appropriate value. */
20198 if (!EQ (window, selected_window))
20200 struct text_pos pt;
20202 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
20203 if (CHARPOS (pt) < BEGV)
20204 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
20205 else if (CHARPOS (pt) > (ZV - 1))
20206 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
20207 else
20208 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
20211 /* Display mode lines. */
20212 clear_glyph_matrix (w->desired_matrix);
20213 if (display_mode_lines (w))
20215 ++nwindows;
20216 w->must_be_updated_p = 1;
20219 /* Restore old settings. */
20220 set_buffer_internal_1 (old);
20221 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
20224 window = w->next;
20227 return nwindows;
20231 /* Display the mode and/or header line of window W. Value is the
20232 sum number of mode lines and header lines displayed. */
20234 static int
20235 display_mode_lines (struct window *w)
20237 Lisp_Object old_selected_window = selected_window;
20238 Lisp_Object old_selected_frame = selected_frame;
20239 Lisp_Object new_frame = w->frame;
20240 Lisp_Object old_frame_selected_window = XFRAME (new_frame)->selected_window;
20241 int n = 0;
20243 selected_frame = new_frame;
20244 /* FIXME: If we were to allow the mode-line's computation changing the buffer
20245 or window's point, then we'd need select_window_1 here as well. */
20246 XSETWINDOW (selected_window, w);
20247 XFRAME (new_frame)->selected_window = selected_window;
20249 /* These will be set while the mode line specs are processed. */
20250 line_number_displayed = 0;
20251 w->column_number_displayed = -1;
20253 if (WINDOW_WANTS_MODELINE_P (w))
20255 struct window *sel_w = XWINDOW (old_selected_window);
20257 /* Select mode line face based on the real selected window. */
20258 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
20259 BVAR (current_buffer, mode_line_format));
20260 ++n;
20263 if (WINDOW_WANTS_HEADER_LINE_P (w))
20265 display_mode_line (w, HEADER_LINE_FACE_ID,
20266 BVAR (current_buffer, header_line_format));
20267 ++n;
20270 XFRAME (new_frame)->selected_window = old_frame_selected_window;
20271 selected_frame = old_selected_frame;
20272 selected_window = old_selected_window;
20273 return n;
20277 /* Display mode or header line of window W. FACE_ID specifies which
20278 line to display; it is either MODE_LINE_FACE_ID or
20279 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
20280 display. Value is the pixel height of the mode/header line
20281 displayed. */
20283 static int
20284 display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
20286 struct it it;
20287 struct face *face;
20288 ptrdiff_t count = SPECPDL_INDEX ();
20290 init_iterator (&it, w, -1, -1, NULL, face_id);
20291 /* Don't extend on a previously drawn mode-line.
20292 This may happen if called from pos_visible_p. */
20293 it.glyph_row->enabled_p = 0;
20294 prepare_desired_row (it.glyph_row);
20296 it.glyph_row->mode_line_p = 1;
20298 /* FIXME: This should be controlled by a user option. But
20299 supporting such an option is not trivial, since the mode line is
20300 made up of many separate strings. */
20301 it.paragraph_embedding = L2R;
20303 record_unwind_protect (unwind_format_mode_line,
20304 format_mode_line_unwind_data (NULL, NULL, Qnil, 0));
20306 mode_line_target = MODE_LINE_DISPLAY;
20308 /* Temporarily make frame's keyboard the current kboard so that
20309 kboard-local variables in the mode_line_format will get the right
20310 values. */
20311 push_kboard (FRAME_KBOARD (it.f));
20312 record_unwind_save_match_data ();
20313 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
20314 pop_kboard ();
20316 unbind_to (count, Qnil);
20318 /* Fill up with spaces. */
20319 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
20321 compute_line_metrics (&it);
20322 it.glyph_row->full_width_p = 1;
20323 it.glyph_row->continued_p = 0;
20324 it.glyph_row->truncated_on_left_p = 0;
20325 it.glyph_row->truncated_on_right_p = 0;
20327 /* Make a 3D mode-line have a shadow at its right end. */
20328 face = FACE_FROM_ID (it.f, face_id);
20329 extend_face_to_end_of_line (&it);
20330 if (face->box != FACE_NO_BOX)
20332 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
20333 + it.glyph_row->used[TEXT_AREA] - 1);
20334 last->right_box_line_p = 1;
20337 return it.glyph_row->height;
20340 /* Move element ELT in LIST to the front of LIST.
20341 Return the updated list. */
20343 static Lisp_Object
20344 move_elt_to_front (Lisp_Object elt, Lisp_Object list)
20346 register Lisp_Object tail, prev;
20347 register Lisp_Object tem;
20349 tail = list;
20350 prev = Qnil;
20351 while (CONSP (tail))
20353 tem = XCAR (tail);
20355 if (EQ (elt, tem))
20357 /* Splice out the link TAIL. */
20358 if (NILP (prev))
20359 list = XCDR (tail);
20360 else
20361 Fsetcdr (prev, XCDR (tail));
20363 /* Now make it the first. */
20364 Fsetcdr (tail, list);
20365 return tail;
20367 else
20368 prev = tail;
20369 tail = XCDR (tail);
20370 QUIT;
20373 /* Not found--return unchanged LIST. */
20374 return list;
20377 /* Contribute ELT to the mode line for window IT->w. How it
20378 translates into text depends on its data type.
20380 IT describes the display environment in which we display, as usual.
20382 DEPTH is the depth in recursion. It is used to prevent
20383 infinite recursion here.
20385 FIELD_WIDTH is the number of characters the display of ELT should
20386 occupy in the mode line, and PRECISION is the maximum number of
20387 characters to display from ELT's representation. See
20388 display_string for details.
20390 Returns the hpos of the end of the text generated by ELT.
20392 PROPS is a property list to add to any string we encounter.
20394 If RISKY is nonzero, remove (disregard) any properties in any string
20395 we encounter, and ignore :eval and :propertize.
20397 The global variable `mode_line_target' determines whether the
20398 output is passed to `store_mode_line_noprop',
20399 `store_mode_line_string', or `display_string'. */
20401 static int
20402 display_mode_element (struct it *it, int depth, int field_width, int precision,
20403 Lisp_Object elt, Lisp_Object props, int risky)
20405 int n = 0, field, prec;
20406 int literal = 0;
20408 tail_recurse:
20409 if (depth > 100)
20410 elt = build_string ("*too-deep*");
20412 depth++;
20414 switch (XTYPE (elt))
20416 case Lisp_String:
20418 /* A string: output it and check for %-constructs within it. */
20419 unsigned char c;
20420 ptrdiff_t offset = 0;
20422 if (SCHARS (elt) > 0
20423 && (!NILP (props) || risky))
20425 Lisp_Object oprops, aelt;
20426 oprops = Ftext_properties_at (make_number (0), elt);
20428 /* If the starting string's properties are not what
20429 we want, translate the string. Also, if the string
20430 is risky, do that anyway. */
20432 if (NILP (Fequal (props, oprops)) || risky)
20434 /* If the starting string has properties,
20435 merge the specified ones onto the existing ones. */
20436 if (! NILP (oprops) && !risky)
20438 Lisp_Object tem;
20440 oprops = Fcopy_sequence (oprops);
20441 tem = props;
20442 while (CONSP (tem))
20444 oprops = Fplist_put (oprops, XCAR (tem),
20445 XCAR (XCDR (tem)));
20446 tem = XCDR (XCDR (tem));
20448 props = oprops;
20451 aelt = Fassoc (elt, mode_line_proptrans_alist);
20452 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
20454 /* AELT is what we want. Move it to the front
20455 without consing. */
20456 elt = XCAR (aelt);
20457 mode_line_proptrans_alist
20458 = move_elt_to_front (aelt, mode_line_proptrans_alist);
20460 else
20462 Lisp_Object tem;
20464 /* If AELT has the wrong props, it is useless.
20465 so get rid of it. */
20466 if (! NILP (aelt))
20467 mode_line_proptrans_alist
20468 = Fdelq (aelt, mode_line_proptrans_alist);
20470 elt = Fcopy_sequence (elt);
20471 Fset_text_properties (make_number (0), Flength (elt),
20472 props, elt);
20473 /* Add this item to mode_line_proptrans_alist. */
20474 mode_line_proptrans_alist
20475 = Fcons (Fcons (elt, props),
20476 mode_line_proptrans_alist);
20477 /* Truncate mode_line_proptrans_alist
20478 to at most 50 elements. */
20479 tem = Fnthcdr (make_number (50),
20480 mode_line_proptrans_alist);
20481 if (! NILP (tem))
20482 XSETCDR (tem, Qnil);
20487 offset = 0;
20489 if (literal)
20491 prec = precision - n;
20492 switch (mode_line_target)
20494 case MODE_LINE_NOPROP:
20495 case MODE_LINE_TITLE:
20496 n += store_mode_line_noprop (SSDATA (elt), -1, prec);
20497 break;
20498 case MODE_LINE_STRING:
20499 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
20500 break;
20501 case MODE_LINE_DISPLAY:
20502 n += display_string (NULL, elt, Qnil, 0, 0, it,
20503 0, prec, 0, STRING_MULTIBYTE (elt));
20504 break;
20507 break;
20510 /* Handle the non-literal case. */
20512 while ((precision <= 0 || n < precision)
20513 && SREF (elt, offset) != 0
20514 && (mode_line_target != MODE_LINE_DISPLAY
20515 || it->current_x < it->last_visible_x))
20517 ptrdiff_t last_offset = offset;
20519 /* Advance to end of string or next format specifier. */
20520 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
20523 if (offset - 1 != last_offset)
20525 ptrdiff_t nchars, nbytes;
20527 /* Output to end of string or up to '%'. Field width
20528 is length of string. Don't output more than
20529 PRECISION allows us. */
20530 offset--;
20532 prec = c_string_width (SDATA (elt) + last_offset,
20533 offset - last_offset, precision - n,
20534 &nchars, &nbytes);
20536 switch (mode_line_target)
20538 case MODE_LINE_NOPROP:
20539 case MODE_LINE_TITLE:
20540 n += store_mode_line_noprop (SSDATA (elt) + last_offset, 0, prec);
20541 break;
20542 case MODE_LINE_STRING:
20544 ptrdiff_t bytepos = last_offset;
20545 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
20546 ptrdiff_t endpos = (precision <= 0
20547 ? string_byte_to_char (elt, offset)
20548 : charpos + nchars);
20550 n += store_mode_line_string (NULL,
20551 Fsubstring (elt, make_number (charpos),
20552 make_number (endpos)),
20553 0, 0, 0, Qnil);
20555 break;
20556 case MODE_LINE_DISPLAY:
20558 ptrdiff_t bytepos = last_offset;
20559 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
20561 if (precision <= 0)
20562 nchars = string_byte_to_char (elt, offset) - charpos;
20563 n += display_string (NULL, elt, Qnil, 0, charpos,
20564 it, 0, nchars, 0,
20565 STRING_MULTIBYTE (elt));
20567 break;
20570 else /* c == '%' */
20572 ptrdiff_t percent_position = offset;
20574 /* Get the specified minimum width. Zero means
20575 don't pad. */
20576 field = 0;
20577 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
20578 field = field * 10 + c - '0';
20580 /* Don't pad beyond the total padding allowed. */
20581 if (field_width - n > 0 && field > field_width - n)
20582 field = field_width - n;
20584 /* Note that either PRECISION <= 0 or N < PRECISION. */
20585 prec = precision - n;
20587 if (c == 'M')
20588 n += display_mode_element (it, depth, field, prec,
20589 Vglobal_mode_string, props,
20590 risky);
20591 else if (c != 0)
20593 bool multibyte;
20594 ptrdiff_t bytepos, charpos;
20595 const char *spec;
20596 Lisp_Object string;
20598 bytepos = percent_position;
20599 charpos = (STRING_MULTIBYTE (elt)
20600 ? string_byte_to_char (elt, bytepos)
20601 : bytepos);
20602 spec = decode_mode_spec (it->w, c, field, &string);
20603 multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
20605 switch (mode_line_target)
20607 case MODE_LINE_NOPROP:
20608 case MODE_LINE_TITLE:
20609 n += store_mode_line_noprop (spec, field, prec);
20610 break;
20611 case MODE_LINE_STRING:
20613 Lisp_Object tem = build_string (spec);
20614 props = Ftext_properties_at (make_number (charpos), elt);
20615 /* Should only keep face property in props */
20616 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
20618 break;
20619 case MODE_LINE_DISPLAY:
20621 int nglyphs_before, nwritten;
20623 nglyphs_before = it->glyph_row->used[TEXT_AREA];
20624 nwritten = display_string (spec, string, elt,
20625 charpos, 0, it,
20626 field, prec, 0,
20627 multibyte);
20629 /* Assign to the glyphs written above the
20630 string where the `%x' came from, position
20631 of the `%'. */
20632 if (nwritten > 0)
20634 struct glyph *glyph
20635 = (it->glyph_row->glyphs[TEXT_AREA]
20636 + nglyphs_before);
20637 int i;
20639 for (i = 0; i < nwritten; ++i)
20641 glyph[i].object = elt;
20642 glyph[i].charpos = charpos;
20645 n += nwritten;
20648 break;
20651 else /* c == 0 */
20652 break;
20656 break;
20658 case Lisp_Symbol:
20659 /* A symbol: process the value of the symbol recursively
20660 as if it appeared here directly. Avoid error if symbol void.
20661 Special case: if value of symbol is a string, output the string
20662 literally. */
20664 register Lisp_Object tem;
20666 /* If the variable is not marked as risky to set
20667 then its contents are risky to use. */
20668 if (NILP (Fget (elt, Qrisky_local_variable)))
20669 risky = 1;
20671 tem = Fboundp (elt);
20672 if (!NILP (tem))
20674 tem = Fsymbol_value (elt);
20675 /* If value is a string, output that string literally:
20676 don't check for % within it. */
20677 if (STRINGP (tem))
20678 literal = 1;
20680 if (!EQ (tem, elt))
20682 /* Give up right away for nil or t. */
20683 elt = tem;
20684 goto tail_recurse;
20688 break;
20690 case Lisp_Cons:
20692 register Lisp_Object car, tem;
20694 /* A cons cell: five distinct cases.
20695 If first element is :eval or :propertize, do something special.
20696 If first element is a string or a cons, process all the elements
20697 and effectively concatenate them.
20698 If first element is a negative number, truncate displaying cdr to
20699 at most that many characters. If positive, pad (with spaces)
20700 to at least that many characters.
20701 If first element is a symbol, process the cadr or caddr recursively
20702 according to whether the symbol's value is non-nil or nil. */
20703 car = XCAR (elt);
20704 if (EQ (car, QCeval))
20706 /* An element of the form (:eval FORM) means evaluate FORM
20707 and use the result as mode line elements. */
20709 if (risky)
20710 break;
20712 if (CONSP (XCDR (elt)))
20714 Lisp_Object spec;
20715 spec = safe_eval (XCAR (XCDR (elt)));
20716 n += display_mode_element (it, depth, field_width - n,
20717 precision - n, spec, props,
20718 risky);
20721 else if (EQ (car, QCpropertize))
20723 /* An element of the form (:propertize ELT PROPS...)
20724 means display ELT but applying properties PROPS. */
20726 if (risky)
20727 break;
20729 if (CONSP (XCDR (elt)))
20730 n += display_mode_element (it, depth, field_width - n,
20731 precision - n, XCAR (XCDR (elt)),
20732 XCDR (XCDR (elt)), risky);
20734 else if (SYMBOLP (car))
20736 tem = Fboundp (car);
20737 elt = XCDR (elt);
20738 if (!CONSP (elt))
20739 goto invalid;
20740 /* elt is now the cdr, and we know it is a cons cell.
20741 Use its car if CAR has a non-nil value. */
20742 if (!NILP (tem))
20744 tem = Fsymbol_value (car);
20745 if (!NILP (tem))
20747 elt = XCAR (elt);
20748 goto tail_recurse;
20751 /* Symbol's value is nil (or symbol is unbound)
20752 Get the cddr of the original list
20753 and if possible find the caddr and use that. */
20754 elt = XCDR (elt);
20755 if (NILP (elt))
20756 break;
20757 else if (!CONSP (elt))
20758 goto invalid;
20759 elt = XCAR (elt);
20760 goto tail_recurse;
20762 else if (INTEGERP (car))
20764 register int lim = XINT (car);
20765 elt = XCDR (elt);
20766 if (lim < 0)
20768 /* Negative int means reduce maximum width. */
20769 if (precision <= 0)
20770 precision = -lim;
20771 else
20772 precision = min (precision, -lim);
20774 else if (lim > 0)
20776 /* Padding specified. Don't let it be more than
20777 current maximum. */
20778 if (precision > 0)
20779 lim = min (precision, lim);
20781 /* If that's more padding than already wanted, queue it.
20782 But don't reduce padding already specified even if
20783 that is beyond the current truncation point. */
20784 field_width = max (lim, field_width);
20786 goto tail_recurse;
20788 else if (STRINGP (car) || CONSP (car))
20790 Lisp_Object halftail = elt;
20791 int len = 0;
20793 while (CONSP (elt)
20794 && (precision <= 0 || n < precision))
20796 n += display_mode_element (it, depth,
20797 /* Do padding only after the last
20798 element in the list. */
20799 (! CONSP (XCDR (elt))
20800 ? field_width - n
20801 : 0),
20802 precision - n, XCAR (elt),
20803 props, risky);
20804 elt = XCDR (elt);
20805 len++;
20806 if ((len & 1) == 0)
20807 halftail = XCDR (halftail);
20808 /* Check for cycle. */
20809 if (EQ (halftail, elt))
20810 break;
20814 break;
20816 default:
20817 invalid:
20818 elt = build_string ("*invalid*");
20819 goto tail_recurse;
20822 /* Pad to FIELD_WIDTH. */
20823 if (field_width > 0 && n < field_width)
20825 switch (mode_line_target)
20827 case MODE_LINE_NOPROP:
20828 case MODE_LINE_TITLE:
20829 n += store_mode_line_noprop ("", field_width - n, 0);
20830 break;
20831 case MODE_LINE_STRING:
20832 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
20833 break;
20834 case MODE_LINE_DISPLAY:
20835 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
20836 0, 0, 0);
20837 break;
20841 return n;
20844 /* Store a mode-line string element in mode_line_string_list.
20846 If STRING is non-null, display that C string. Otherwise, the Lisp
20847 string LISP_STRING is displayed.
20849 FIELD_WIDTH is the minimum number of output glyphs to produce.
20850 If STRING has fewer characters than FIELD_WIDTH, pad to the right
20851 with spaces. FIELD_WIDTH <= 0 means don't pad.
20853 PRECISION is the maximum number of characters to output from
20854 STRING. PRECISION <= 0 means don't truncate the string.
20856 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
20857 properties to the string.
20859 PROPS are the properties to add to the string.
20860 The mode_line_string_face face property is always added to the string.
20863 static int
20864 store_mode_line_string (const char *string, Lisp_Object lisp_string, int copy_string,
20865 int field_width, int precision, Lisp_Object props)
20867 ptrdiff_t len;
20868 int n = 0;
20870 if (string != NULL)
20872 len = strlen (string);
20873 if (precision > 0 && len > precision)
20874 len = precision;
20875 lisp_string = make_string (string, len);
20876 if (NILP (props))
20877 props = mode_line_string_face_prop;
20878 else if (!NILP (mode_line_string_face))
20880 Lisp_Object face = Fplist_get (props, Qface);
20881 props = Fcopy_sequence (props);
20882 if (NILP (face))
20883 face = mode_line_string_face;
20884 else
20885 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
20886 props = Fplist_put (props, Qface, face);
20888 Fadd_text_properties (make_number (0), make_number (len),
20889 props, lisp_string);
20891 else
20893 len = XFASTINT (Flength (lisp_string));
20894 if (precision > 0 && len > precision)
20896 len = precision;
20897 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
20898 precision = -1;
20900 if (!NILP (mode_line_string_face))
20902 Lisp_Object face;
20903 if (NILP (props))
20904 props = Ftext_properties_at (make_number (0), lisp_string);
20905 face = Fplist_get (props, Qface);
20906 if (NILP (face))
20907 face = mode_line_string_face;
20908 else
20909 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
20910 props = Fcons (Qface, Fcons (face, Qnil));
20911 if (copy_string)
20912 lisp_string = Fcopy_sequence (lisp_string);
20914 if (!NILP (props))
20915 Fadd_text_properties (make_number (0), make_number (len),
20916 props, lisp_string);
20919 if (len > 0)
20921 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
20922 n += len;
20925 if (field_width > len)
20927 field_width -= len;
20928 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
20929 if (!NILP (props))
20930 Fadd_text_properties (make_number (0), make_number (field_width),
20931 props, lisp_string);
20932 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
20933 n += field_width;
20936 return n;
20940 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
20941 1, 4, 0,
20942 doc: /* Format a string out of a mode line format specification.
20943 First arg FORMAT specifies the mode line format (see `mode-line-format'
20944 for details) to use.
20946 By default, the format is evaluated for the currently selected window.
20948 Optional second arg FACE specifies the face property to put on all
20949 characters for which no face is specified. The value nil means the
20950 default face. The value t means whatever face the window's mode line
20951 currently uses (either `mode-line' or `mode-line-inactive',
20952 depending on whether the window is the selected window or not).
20953 An integer value means the value string has no text
20954 properties.
20956 Optional third and fourth args WINDOW and BUFFER specify the window
20957 and buffer to use as the context for the formatting (defaults
20958 are the selected window and the WINDOW's buffer). */)
20959 (Lisp_Object format, Lisp_Object face,
20960 Lisp_Object window, Lisp_Object buffer)
20962 struct it it;
20963 int len;
20964 struct window *w;
20965 struct buffer *old_buffer = NULL;
20966 int face_id;
20967 int no_props = INTEGERP (face);
20968 ptrdiff_t count = SPECPDL_INDEX ();
20969 Lisp_Object str;
20970 int string_start = 0;
20972 w = decode_any_window (window);
20973 XSETWINDOW (window, w);
20975 if (NILP (buffer))
20976 buffer = w->contents;
20977 CHECK_BUFFER (buffer);
20979 /* Make formatting the modeline a non-op when noninteractive, otherwise
20980 there will be problems later caused by a partially initialized frame. */
20981 if (NILP (format) || noninteractive)
20982 return empty_unibyte_string;
20984 if (no_props)
20985 face = Qnil;
20987 face_id = (NILP (face) || EQ (face, Qdefault)) ? DEFAULT_FACE_ID
20988 : EQ (face, Qt) ? (EQ (window, selected_window)
20989 ? MODE_LINE_FACE_ID : MODE_LINE_INACTIVE_FACE_ID)
20990 : EQ (face, Qmode_line) ? MODE_LINE_FACE_ID
20991 : EQ (face, Qmode_line_inactive) ? MODE_LINE_INACTIVE_FACE_ID
20992 : EQ (face, Qheader_line) ? HEADER_LINE_FACE_ID
20993 : EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID
20994 : DEFAULT_FACE_ID;
20996 old_buffer = current_buffer;
20998 /* Save things including mode_line_proptrans_alist,
20999 and set that to nil so that we don't alter the outer value. */
21000 record_unwind_protect (unwind_format_mode_line,
21001 format_mode_line_unwind_data
21002 (XFRAME (WINDOW_FRAME (w)),
21003 old_buffer, selected_window, 1));
21004 mode_line_proptrans_alist = Qnil;
21006 Fselect_window (window, Qt);
21007 set_buffer_internal_1 (XBUFFER (buffer));
21009 init_iterator (&it, w, -1, -1, NULL, face_id);
21011 if (no_props)
21013 mode_line_target = MODE_LINE_NOPROP;
21014 mode_line_string_face_prop = Qnil;
21015 mode_line_string_list = Qnil;
21016 string_start = MODE_LINE_NOPROP_LEN (0);
21018 else
21020 mode_line_target = MODE_LINE_STRING;
21021 mode_line_string_list = Qnil;
21022 mode_line_string_face = face;
21023 mode_line_string_face_prop
21024 = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil)));
21027 push_kboard (FRAME_KBOARD (it.f));
21028 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
21029 pop_kboard ();
21031 if (no_props)
21033 len = MODE_LINE_NOPROP_LEN (string_start);
21034 str = make_string (mode_line_noprop_buf + string_start, len);
21036 else
21038 mode_line_string_list = Fnreverse (mode_line_string_list);
21039 str = Fmapconcat (intern ("identity"), mode_line_string_list,
21040 empty_unibyte_string);
21043 unbind_to (count, Qnil);
21044 return str;
21047 /* Write a null-terminated, right justified decimal representation of
21048 the positive integer D to BUF using a minimal field width WIDTH. */
21050 static void
21051 pint2str (register char *buf, register int width, register ptrdiff_t d)
21053 register char *p = buf;
21055 if (d <= 0)
21056 *p++ = '0';
21057 else
21059 while (d > 0)
21061 *p++ = d % 10 + '0';
21062 d /= 10;
21066 for (width -= (int) (p - buf); width > 0; --width)
21067 *p++ = ' ';
21068 *p-- = '\0';
21069 while (p > buf)
21071 d = *buf;
21072 *buf++ = *p;
21073 *p-- = d;
21077 /* Write a null-terminated, right justified decimal and "human
21078 readable" representation of the nonnegative integer D to BUF using
21079 a minimal field width WIDTH. D should be smaller than 999.5e24. */
21081 static const char power_letter[] =
21083 0, /* no letter */
21084 'k', /* kilo */
21085 'M', /* mega */
21086 'G', /* giga */
21087 'T', /* tera */
21088 'P', /* peta */
21089 'E', /* exa */
21090 'Z', /* zetta */
21091 'Y' /* yotta */
21094 static void
21095 pint2hrstr (char *buf, int width, ptrdiff_t d)
21097 /* We aim to represent the nonnegative integer D as
21098 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
21099 ptrdiff_t quotient = d;
21100 int remainder = 0;
21101 /* -1 means: do not use TENTHS. */
21102 int tenths = -1;
21103 int exponent = 0;
21105 /* Length of QUOTIENT.TENTHS as a string. */
21106 int length;
21108 char * psuffix;
21109 char * p;
21111 if (quotient >= 1000)
21113 /* Scale to the appropriate EXPONENT. */
21116 remainder = quotient % 1000;
21117 quotient /= 1000;
21118 exponent++;
21120 while (quotient >= 1000);
21122 /* Round to nearest and decide whether to use TENTHS or not. */
21123 if (quotient <= 9)
21125 tenths = remainder / 100;
21126 if (remainder % 100 >= 50)
21128 if (tenths < 9)
21129 tenths++;
21130 else
21132 quotient++;
21133 if (quotient == 10)
21134 tenths = -1;
21135 else
21136 tenths = 0;
21140 else
21141 if (remainder >= 500)
21143 if (quotient < 999)
21144 quotient++;
21145 else
21147 quotient = 1;
21148 exponent++;
21149 tenths = 0;
21154 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
21155 if (tenths == -1 && quotient <= 99)
21156 if (quotient <= 9)
21157 length = 1;
21158 else
21159 length = 2;
21160 else
21161 length = 3;
21162 p = psuffix = buf + max (width, length);
21164 /* Print EXPONENT. */
21165 *psuffix++ = power_letter[exponent];
21166 *psuffix = '\0';
21168 /* Print TENTHS. */
21169 if (tenths >= 0)
21171 *--p = '0' + tenths;
21172 *--p = '.';
21175 /* Print QUOTIENT. */
21178 int digit = quotient % 10;
21179 *--p = '0' + digit;
21181 while ((quotient /= 10) != 0);
21183 /* Print leading spaces. */
21184 while (buf < p)
21185 *--p = ' ';
21188 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
21189 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
21190 type of CODING_SYSTEM. Return updated pointer into BUF. */
21192 static unsigned char invalid_eol_type[] = "(*invalid*)";
21194 static char *
21195 decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_flag)
21197 Lisp_Object val;
21198 bool multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
21199 const unsigned char *eol_str;
21200 int eol_str_len;
21201 /* The EOL conversion we are using. */
21202 Lisp_Object eoltype;
21204 val = CODING_SYSTEM_SPEC (coding_system);
21205 eoltype = Qnil;
21207 if (!VECTORP (val)) /* Not yet decided. */
21209 *buf++ = multibyte ? '-' : ' ';
21210 if (eol_flag)
21211 eoltype = eol_mnemonic_undecided;
21212 /* Don't mention EOL conversion if it isn't decided. */
21214 else
21216 Lisp_Object attrs;
21217 Lisp_Object eolvalue;
21219 attrs = AREF (val, 0);
21220 eolvalue = AREF (val, 2);
21222 *buf++ = multibyte
21223 ? XFASTINT (CODING_ATTR_MNEMONIC (attrs))
21224 : ' ';
21226 if (eol_flag)
21228 /* The EOL conversion that is normal on this system. */
21230 if (NILP (eolvalue)) /* Not yet decided. */
21231 eoltype = eol_mnemonic_undecided;
21232 else if (VECTORP (eolvalue)) /* Not yet decided. */
21233 eoltype = eol_mnemonic_undecided;
21234 else /* eolvalue is Qunix, Qdos, or Qmac. */
21235 eoltype = (EQ (eolvalue, Qunix)
21236 ? eol_mnemonic_unix
21237 : (EQ (eolvalue, Qdos) == 1
21238 ? eol_mnemonic_dos : eol_mnemonic_mac));
21242 if (eol_flag)
21244 /* Mention the EOL conversion if it is not the usual one. */
21245 if (STRINGP (eoltype))
21247 eol_str = SDATA (eoltype);
21248 eol_str_len = SBYTES (eoltype);
21250 else if (CHARACTERP (eoltype))
21252 unsigned char *tmp = alloca (MAX_MULTIBYTE_LENGTH);
21253 int c = XFASTINT (eoltype);
21254 eol_str_len = CHAR_STRING (c, tmp);
21255 eol_str = tmp;
21257 else
21259 eol_str = invalid_eol_type;
21260 eol_str_len = sizeof (invalid_eol_type) - 1;
21262 memcpy (buf, eol_str, eol_str_len);
21263 buf += eol_str_len;
21266 return buf;
21269 /* Return a string for the output of a mode line %-spec for window W,
21270 generated by character C. FIELD_WIDTH > 0 means pad the string
21271 returned with spaces to that value. Return a Lisp string in
21272 *STRING if the resulting string is taken from that Lisp string.
21274 Note we operate on the current buffer for most purposes. */
21276 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
21278 static const char *
21279 decode_mode_spec (struct window *w, register int c, int field_width,
21280 Lisp_Object *string)
21282 Lisp_Object obj;
21283 struct frame *f = XFRAME (WINDOW_FRAME (w));
21284 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
21285 /* We are going to use f->decode_mode_spec_buffer as the buffer to
21286 produce strings from numerical values, so limit preposterously
21287 large values of FIELD_WIDTH to avoid overrunning the buffer's
21288 end. The size of the buffer is enough for FRAME_MESSAGE_BUF_SIZE
21289 bytes plus the terminating null. */
21290 int width = min (field_width, FRAME_MESSAGE_BUF_SIZE (f));
21291 struct buffer *b = current_buffer;
21293 obj = Qnil;
21294 *string = Qnil;
21296 switch (c)
21298 case '*':
21299 if (!NILP (BVAR (b, read_only)))
21300 return "%";
21301 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21302 return "*";
21303 return "-";
21305 case '+':
21306 /* This differs from %* only for a modified read-only buffer. */
21307 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21308 return "*";
21309 if (!NILP (BVAR (b, read_only)))
21310 return "%";
21311 return "-";
21313 case '&':
21314 /* This differs from %* in ignoring read-only-ness. */
21315 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21316 return "*";
21317 return "-";
21319 case '%':
21320 return "%";
21322 case '[':
21324 int i;
21325 char *p;
21327 if (command_loop_level > 5)
21328 return "[[[... ";
21329 p = decode_mode_spec_buf;
21330 for (i = 0; i < command_loop_level; i++)
21331 *p++ = '[';
21332 *p = 0;
21333 return decode_mode_spec_buf;
21336 case ']':
21338 int i;
21339 char *p;
21341 if (command_loop_level > 5)
21342 return " ...]]]";
21343 p = decode_mode_spec_buf;
21344 for (i = 0; i < command_loop_level; i++)
21345 *p++ = ']';
21346 *p = 0;
21347 return decode_mode_spec_buf;
21350 case '-':
21352 register int i;
21354 /* Let lots_of_dashes be a string of infinite length. */
21355 if (mode_line_target == MODE_LINE_NOPROP
21356 || mode_line_target == MODE_LINE_STRING)
21357 return "--";
21358 if (field_width <= 0
21359 || field_width > sizeof (lots_of_dashes))
21361 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
21362 decode_mode_spec_buf[i] = '-';
21363 decode_mode_spec_buf[i] = '\0';
21364 return decode_mode_spec_buf;
21366 else
21367 return lots_of_dashes;
21370 case 'b':
21371 obj = BVAR (b, name);
21372 break;
21374 case 'c':
21375 /* %c and %l are ignored in `frame-title-format'.
21376 (In redisplay_internal, the frame title is drawn _before_ the
21377 windows are updated, so the stuff which depends on actual
21378 window contents (such as %l) may fail to render properly, or
21379 even crash emacs.) */
21380 if (mode_line_target == MODE_LINE_TITLE)
21381 return "";
21382 else
21384 ptrdiff_t col = current_column ();
21385 w->column_number_displayed = col;
21386 pint2str (decode_mode_spec_buf, width, col);
21387 return decode_mode_spec_buf;
21390 case 'e':
21391 #ifndef SYSTEM_MALLOC
21393 if (NILP (Vmemory_full))
21394 return "";
21395 else
21396 return "!MEM FULL! ";
21398 #else
21399 return "";
21400 #endif
21402 case 'F':
21403 /* %F displays the frame name. */
21404 if (!NILP (f->title))
21405 return SSDATA (f->title);
21406 if (f->explicit_name || ! FRAME_WINDOW_P (f))
21407 return SSDATA (f->name);
21408 return "Emacs";
21410 case 'f':
21411 obj = BVAR (b, filename);
21412 break;
21414 case 'i':
21416 ptrdiff_t size = ZV - BEGV;
21417 pint2str (decode_mode_spec_buf, width, size);
21418 return decode_mode_spec_buf;
21421 case 'I':
21423 ptrdiff_t size = ZV - BEGV;
21424 pint2hrstr (decode_mode_spec_buf, width, size);
21425 return decode_mode_spec_buf;
21428 case 'l':
21430 ptrdiff_t startpos, startpos_byte, line, linepos, linepos_byte;
21431 ptrdiff_t topline, nlines, height;
21432 ptrdiff_t junk;
21434 /* %c and %l are ignored in `frame-title-format'. */
21435 if (mode_line_target == MODE_LINE_TITLE)
21436 return "";
21438 startpos = marker_position (w->start);
21439 startpos_byte = marker_byte_position (w->start);
21440 height = WINDOW_TOTAL_LINES (w);
21442 /* If we decided that this buffer isn't suitable for line numbers,
21443 don't forget that too fast. */
21444 if (w->base_line_pos == -1)
21445 goto no_value;
21447 /* If the buffer is very big, don't waste time. */
21448 if (INTEGERP (Vline_number_display_limit)
21449 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
21451 w->base_line_pos = 0;
21452 w->base_line_number = 0;
21453 goto no_value;
21456 if (w->base_line_number > 0
21457 && w->base_line_pos > 0
21458 && w->base_line_pos <= startpos)
21460 line = w->base_line_number;
21461 linepos = w->base_line_pos;
21462 linepos_byte = buf_charpos_to_bytepos (b, linepos);
21464 else
21466 line = 1;
21467 linepos = BUF_BEGV (b);
21468 linepos_byte = BUF_BEGV_BYTE (b);
21471 /* Count lines from base line to window start position. */
21472 nlines = display_count_lines (linepos_byte,
21473 startpos_byte,
21474 startpos, &junk);
21476 topline = nlines + line;
21478 /* Determine a new base line, if the old one is too close
21479 or too far away, or if we did not have one.
21480 "Too close" means it's plausible a scroll-down would
21481 go back past it. */
21482 if (startpos == BUF_BEGV (b))
21484 w->base_line_number = topline;
21485 w->base_line_pos = BUF_BEGV (b);
21487 else if (nlines < height + 25 || nlines > height * 3 + 50
21488 || linepos == BUF_BEGV (b))
21490 ptrdiff_t limit = BUF_BEGV (b);
21491 ptrdiff_t limit_byte = BUF_BEGV_BYTE (b);
21492 ptrdiff_t position;
21493 ptrdiff_t distance =
21494 (height * 2 + 30) * line_number_display_limit_width;
21496 if (startpos - distance > limit)
21498 limit = startpos - distance;
21499 limit_byte = CHAR_TO_BYTE (limit);
21502 nlines = display_count_lines (startpos_byte,
21503 limit_byte,
21504 - (height * 2 + 30),
21505 &position);
21506 /* If we couldn't find the lines we wanted within
21507 line_number_display_limit_width chars per line,
21508 give up on line numbers for this window. */
21509 if (position == limit_byte && limit == startpos - distance)
21511 w->base_line_pos = -1;
21512 w->base_line_number = 0;
21513 goto no_value;
21516 w->base_line_number = topline - nlines;
21517 w->base_line_pos = BYTE_TO_CHAR (position);
21520 /* Now count lines from the start pos to point. */
21521 nlines = display_count_lines (startpos_byte,
21522 PT_BYTE, PT, &junk);
21524 /* Record that we did display the line number. */
21525 line_number_displayed = 1;
21527 /* Make the string to show. */
21528 pint2str (decode_mode_spec_buf, width, topline + nlines);
21529 return decode_mode_spec_buf;
21530 no_value:
21532 char* p = decode_mode_spec_buf;
21533 int pad = width - 2;
21534 while (pad-- > 0)
21535 *p++ = ' ';
21536 *p++ = '?';
21537 *p++ = '?';
21538 *p = '\0';
21539 return decode_mode_spec_buf;
21542 break;
21544 case 'm':
21545 obj = BVAR (b, mode_name);
21546 break;
21548 case 'n':
21549 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
21550 return " Narrow";
21551 break;
21553 case 'p':
21555 ptrdiff_t pos = marker_position (w->start);
21556 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
21558 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
21560 if (pos <= BUF_BEGV (b))
21561 return "All";
21562 else
21563 return "Bottom";
21565 else if (pos <= BUF_BEGV (b))
21566 return "Top";
21567 else
21569 if (total > 1000000)
21570 /* Do it differently for a large value, to avoid overflow. */
21571 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
21572 else
21573 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
21574 /* We can't normally display a 3-digit number,
21575 so get us a 2-digit number that is close. */
21576 if (total == 100)
21577 total = 99;
21578 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
21579 return decode_mode_spec_buf;
21583 /* Display percentage of size above the bottom of the screen. */
21584 case 'P':
21586 ptrdiff_t toppos = marker_position (w->start);
21587 ptrdiff_t botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
21588 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
21590 if (botpos >= BUF_ZV (b))
21592 if (toppos <= BUF_BEGV (b))
21593 return "All";
21594 else
21595 return "Bottom";
21597 else
21599 if (total > 1000000)
21600 /* Do it differently for a large value, to avoid overflow. */
21601 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
21602 else
21603 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
21604 /* We can't normally display a 3-digit number,
21605 so get us a 2-digit number that is close. */
21606 if (total == 100)
21607 total = 99;
21608 if (toppos <= BUF_BEGV (b))
21609 sprintf (decode_mode_spec_buf, "Top%2"pD"d%%", total);
21610 else
21611 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
21612 return decode_mode_spec_buf;
21616 case 's':
21617 /* status of process */
21618 obj = Fget_buffer_process (Fcurrent_buffer ());
21619 if (NILP (obj))
21620 return "no process";
21621 #ifndef MSDOS
21622 obj = Fsymbol_name (Fprocess_status (obj));
21623 #endif
21624 break;
21626 case '@':
21628 ptrdiff_t count = inhibit_garbage_collection ();
21629 Lisp_Object val = call1 (intern ("file-remote-p"),
21630 BVAR (current_buffer, directory));
21631 unbind_to (count, Qnil);
21633 if (NILP (val))
21634 return "-";
21635 else
21636 return "@";
21639 case 'z':
21640 /* coding-system (not including end-of-line format) */
21641 case 'Z':
21642 /* coding-system (including end-of-line type) */
21644 int eol_flag = (c == 'Z');
21645 char *p = decode_mode_spec_buf;
21647 if (! FRAME_WINDOW_P (f))
21649 /* No need to mention EOL here--the terminal never needs
21650 to do EOL conversion. */
21651 p = decode_mode_spec_coding (CODING_ID_NAME
21652 (FRAME_KEYBOARD_CODING (f)->id),
21653 p, 0);
21654 p = decode_mode_spec_coding (CODING_ID_NAME
21655 (FRAME_TERMINAL_CODING (f)->id),
21656 p, 0);
21658 p = decode_mode_spec_coding (BVAR (b, buffer_file_coding_system),
21659 p, eol_flag);
21661 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
21662 #ifdef subprocesses
21663 obj = Fget_buffer_process (Fcurrent_buffer ());
21664 if (PROCESSP (obj))
21666 p = decode_mode_spec_coding
21667 (XPROCESS (obj)->decode_coding_system, p, eol_flag);
21668 p = decode_mode_spec_coding
21669 (XPROCESS (obj)->encode_coding_system, p, eol_flag);
21671 #endif /* subprocesses */
21672 #endif /* 0 */
21673 *p = 0;
21674 return decode_mode_spec_buf;
21678 if (STRINGP (obj))
21680 *string = obj;
21681 return SSDATA (obj);
21683 else
21684 return "";
21688 /* Count up to COUNT lines starting from START_BYTE. COUNT negative
21689 means count lines back from START_BYTE. But don't go beyond
21690 LIMIT_BYTE. Return the number of lines thus found (always
21691 nonnegative).
21693 Set *BYTE_POS_PTR to the byte position where we stopped. This is
21694 either the position COUNT lines after/before START_BYTE, if we
21695 found COUNT lines, or LIMIT_BYTE if we hit the limit before finding
21696 COUNT lines. */
21698 static ptrdiff_t
21699 display_count_lines (ptrdiff_t start_byte,
21700 ptrdiff_t limit_byte, ptrdiff_t count,
21701 ptrdiff_t *byte_pos_ptr)
21703 register unsigned char *cursor;
21704 unsigned char *base;
21706 register ptrdiff_t ceiling;
21707 register unsigned char *ceiling_addr;
21708 ptrdiff_t orig_count = count;
21710 /* If we are not in selective display mode,
21711 check only for newlines. */
21712 int selective_display = (!NILP (BVAR (current_buffer, selective_display))
21713 && !INTEGERP (BVAR (current_buffer, selective_display)));
21715 if (count > 0)
21717 while (start_byte < limit_byte)
21719 ceiling = BUFFER_CEILING_OF (start_byte);
21720 ceiling = min (limit_byte - 1, ceiling);
21721 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
21722 base = (cursor = BYTE_POS_ADDR (start_byte));
21726 if (selective_display)
21728 while (*cursor != '\n' && *cursor != 015
21729 && ++cursor != ceiling_addr)
21730 continue;
21731 if (cursor == ceiling_addr)
21732 break;
21734 else
21736 cursor = memchr (cursor, '\n', ceiling_addr - cursor);
21737 if (! cursor)
21738 break;
21741 cursor++;
21743 if (--count == 0)
21745 start_byte += cursor - base;
21746 *byte_pos_ptr = start_byte;
21747 return orig_count;
21750 while (cursor < ceiling_addr);
21752 start_byte += ceiling_addr - base;
21755 else
21757 while (start_byte > limit_byte)
21759 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
21760 ceiling = max (limit_byte, ceiling);
21761 ceiling_addr = BYTE_POS_ADDR (ceiling);
21762 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
21763 while (1)
21765 if (selective_display)
21767 while (--cursor >= ceiling_addr
21768 && *cursor != '\n' && *cursor != 015)
21769 continue;
21770 if (cursor < ceiling_addr)
21771 break;
21773 else
21775 cursor = memrchr (ceiling_addr, '\n', cursor - ceiling_addr);
21776 if (! cursor)
21777 break;
21780 if (++count == 0)
21782 start_byte += cursor - base + 1;
21783 *byte_pos_ptr = start_byte;
21784 /* When scanning backwards, we should
21785 not count the newline posterior to which we stop. */
21786 return - orig_count - 1;
21789 start_byte += ceiling_addr - base;
21793 *byte_pos_ptr = limit_byte;
21795 if (count < 0)
21796 return - orig_count + count;
21797 return orig_count - count;
21803 /***********************************************************************
21804 Displaying strings
21805 ***********************************************************************/
21807 /* Display a NUL-terminated string, starting with index START.
21809 If STRING is non-null, display that C string. Otherwise, the Lisp
21810 string LISP_STRING is displayed. There's a case that STRING is
21811 non-null and LISP_STRING is not nil. It means STRING is a string
21812 data of LISP_STRING. In that case, we display LISP_STRING while
21813 ignoring its text properties.
21815 If FACE_STRING is not nil, FACE_STRING_POS is a position in
21816 FACE_STRING. Display STRING or LISP_STRING with the face at
21817 FACE_STRING_POS in FACE_STRING:
21819 Display the string in the environment given by IT, but use the
21820 standard display table, temporarily.
21822 FIELD_WIDTH is the minimum number of output glyphs to produce.
21823 If STRING has fewer characters than FIELD_WIDTH, pad to the right
21824 with spaces. If STRING has more characters, more than FIELD_WIDTH
21825 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
21827 PRECISION is the maximum number of characters to output from
21828 STRING. PRECISION < 0 means don't truncate the string.
21830 This is roughly equivalent to printf format specifiers:
21832 FIELD_WIDTH PRECISION PRINTF
21833 ----------------------------------------
21834 -1 -1 %s
21835 -1 10 %.10s
21836 10 -1 %10s
21837 20 10 %20.10s
21839 MULTIBYTE zero means do not display multibyte chars, > 0 means do
21840 display them, and < 0 means obey the current buffer's value of
21841 enable_multibyte_characters.
21843 Value is the number of columns displayed. */
21845 static int
21846 display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_string,
21847 ptrdiff_t face_string_pos, ptrdiff_t start, struct it *it,
21848 int field_width, int precision, int max_x, int multibyte)
21850 int hpos_at_start = it->hpos;
21851 int saved_face_id = it->face_id;
21852 struct glyph_row *row = it->glyph_row;
21853 ptrdiff_t it_charpos;
21855 /* Initialize the iterator IT for iteration over STRING beginning
21856 with index START. */
21857 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
21858 precision, field_width, multibyte);
21859 if (string && STRINGP (lisp_string))
21860 /* LISP_STRING is the one returned by decode_mode_spec. We should
21861 ignore its text properties. */
21862 it->stop_charpos = it->end_charpos;
21864 /* If displaying STRING, set up the face of the iterator from
21865 FACE_STRING, if that's given. */
21866 if (STRINGP (face_string))
21868 ptrdiff_t endptr;
21869 struct face *face;
21871 it->face_id
21872 = face_at_string_position (it->w, face_string, face_string_pos,
21873 0, it->region_beg_charpos,
21874 it->region_end_charpos,
21875 &endptr, it->base_face_id, 0);
21876 face = FACE_FROM_ID (it->f, it->face_id);
21877 it->face_box_p = face->box != FACE_NO_BOX;
21880 /* Set max_x to the maximum allowed X position. Don't let it go
21881 beyond the right edge of the window. */
21882 if (max_x <= 0)
21883 max_x = it->last_visible_x;
21884 else
21885 max_x = min (max_x, it->last_visible_x);
21887 /* Skip over display elements that are not visible. because IT->w is
21888 hscrolled. */
21889 if (it->current_x < it->first_visible_x)
21890 move_it_in_display_line_to (it, 100000, it->first_visible_x,
21891 MOVE_TO_POS | MOVE_TO_X);
21893 row->ascent = it->max_ascent;
21894 row->height = it->max_ascent + it->max_descent;
21895 row->phys_ascent = it->max_phys_ascent;
21896 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
21897 row->extra_line_spacing = it->max_extra_line_spacing;
21899 if (STRINGP (it->string))
21900 it_charpos = IT_STRING_CHARPOS (*it);
21901 else
21902 it_charpos = IT_CHARPOS (*it);
21904 /* This condition is for the case that we are called with current_x
21905 past last_visible_x. */
21906 while (it->current_x < max_x)
21908 int x_before, x, n_glyphs_before, i, nglyphs;
21910 /* Get the next display element. */
21911 if (!get_next_display_element (it))
21912 break;
21914 /* Produce glyphs. */
21915 x_before = it->current_x;
21916 n_glyphs_before = row->used[TEXT_AREA];
21917 PRODUCE_GLYPHS (it);
21919 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
21920 i = 0;
21921 x = x_before;
21922 while (i < nglyphs)
21924 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
21926 if (it->line_wrap != TRUNCATE
21927 && x + glyph->pixel_width > max_x)
21929 /* End of continued line or max_x reached. */
21930 if (CHAR_GLYPH_PADDING_P (*glyph))
21932 /* A wide character is unbreakable. */
21933 if (row->reversed_p)
21934 unproduce_glyphs (it, row->used[TEXT_AREA]
21935 - n_glyphs_before);
21936 row->used[TEXT_AREA] = n_glyphs_before;
21937 it->current_x = x_before;
21939 else
21941 if (row->reversed_p)
21942 unproduce_glyphs (it, row->used[TEXT_AREA]
21943 - (n_glyphs_before + i));
21944 row->used[TEXT_AREA] = n_glyphs_before + i;
21945 it->current_x = x;
21947 break;
21949 else if (x + glyph->pixel_width >= it->first_visible_x)
21951 /* Glyph is at least partially visible. */
21952 ++it->hpos;
21953 if (x < it->first_visible_x)
21954 row->x = x - it->first_visible_x;
21956 else
21958 /* Glyph is off the left margin of the display area.
21959 Should not happen. */
21960 emacs_abort ();
21963 row->ascent = max (row->ascent, it->max_ascent);
21964 row->height = max (row->height, it->max_ascent + it->max_descent);
21965 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
21966 row->phys_height = max (row->phys_height,
21967 it->max_phys_ascent + it->max_phys_descent);
21968 row->extra_line_spacing = max (row->extra_line_spacing,
21969 it->max_extra_line_spacing);
21970 x += glyph->pixel_width;
21971 ++i;
21974 /* Stop if max_x reached. */
21975 if (i < nglyphs)
21976 break;
21978 /* Stop at line ends. */
21979 if (ITERATOR_AT_END_OF_LINE_P (it))
21981 it->continuation_lines_width = 0;
21982 break;
21985 set_iterator_to_next (it, 1);
21986 if (STRINGP (it->string))
21987 it_charpos = IT_STRING_CHARPOS (*it);
21988 else
21989 it_charpos = IT_CHARPOS (*it);
21991 /* Stop if truncating at the right edge. */
21992 if (it->line_wrap == TRUNCATE
21993 && it->current_x >= it->last_visible_x)
21995 /* Add truncation mark, but don't do it if the line is
21996 truncated at a padding space. */
21997 if (it_charpos < it->string_nchars)
21999 if (!FRAME_WINDOW_P (it->f))
22001 int ii, n;
22003 if (it->current_x > it->last_visible_x)
22005 if (!row->reversed_p)
22007 for (ii = row->used[TEXT_AREA] - 1; ii > 0; --ii)
22008 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
22009 break;
22011 else
22013 for (ii = 0; ii < row->used[TEXT_AREA]; ii++)
22014 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
22015 break;
22016 unproduce_glyphs (it, ii + 1);
22017 ii = row->used[TEXT_AREA] - (ii + 1);
22019 for (n = row->used[TEXT_AREA]; ii < n; ++ii)
22021 row->used[TEXT_AREA] = ii;
22022 produce_special_glyphs (it, IT_TRUNCATION);
22025 produce_special_glyphs (it, IT_TRUNCATION);
22027 row->truncated_on_right_p = 1;
22029 break;
22033 /* Maybe insert a truncation at the left. */
22034 if (it->first_visible_x
22035 && it_charpos > 0)
22037 if (!FRAME_WINDOW_P (it->f)
22038 || (row->reversed_p
22039 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
22040 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
22041 insert_left_trunc_glyphs (it);
22042 row->truncated_on_left_p = 1;
22045 it->face_id = saved_face_id;
22047 /* Value is number of columns displayed. */
22048 return it->hpos - hpos_at_start;
22053 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
22054 appears as an element of LIST or as the car of an element of LIST.
22055 If PROPVAL is a list, compare each element against LIST in that
22056 way, and return 1/2 if any element of PROPVAL is found in LIST.
22057 Otherwise return 0. This function cannot quit.
22058 The return value is 2 if the text is invisible but with an ellipsis
22059 and 1 if it's invisible and without an ellipsis. */
22062 invisible_p (register Lisp_Object propval, Lisp_Object list)
22064 register Lisp_Object tail, proptail;
22066 for (tail = list; CONSP (tail); tail = XCDR (tail))
22068 register Lisp_Object tem;
22069 tem = XCAR (tail);
22070 if (EQ (propval, tem))
22071 return 1;
22072 if (CONSP (tem) && EQ (propval, XCAR (tem)))
22073 return NILP (XCDR (tem)) ? 1 : 2;
22076 if (CONSP (propval))
22078 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
22080 Lisp_Object propelt;
22081 propelt = XCAR (proptail);
22082 for (tail = list; CONSP (tail); tail = XCDR (tail))
22084 register Lisp_Object tem;
22085 tem = XCAR (tail);
22086 if (EQ (propelt, tem))
22087 return 1;
22088 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
22089 return NILP (XCDR (tem)) ? 1 : 2;
22094 return 0;
22097 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
22098 doc: /* Non-nil if the property makes the text invisible.
22099 POS-OR-PROP can be a marker or number, in which case it is taken to be
22100 a position in the current buffer and the value of the `invisible' property
22101 is checked; or it can be some other value, which is then presumed to be the
22102 value of the `invisible' property of the text of interest.
22103 The non-nil value returned can be t for truly invisible text or something
22104 else if the text is replaced by an ellipsis. */)
22105 (Lisp_Object pos_or_prop)
22107 Lisp_Object prop
22108 = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
22109 ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
22110 : pos_or_prop);
22111 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
22112 return (invis == 0 ? Qnil
22113 : invis == 1 ? Qt
22114 : make_number (invis));
22117 /* Calculate a width or height in pixels from a specification using
22118 the following elements:
22120 SPEC ::=
22121 NUM - a (fractional) multiple of the default font width/height
22122 (NUM) - specifies exactly NUM pixels
22123 UNIT - a fixed number of pixels, see below.
22124 ELEMENT - size of a display element in pixels, see below.
22125 (NUM . SPEC) - equals NUM * SPEC
22126 (+ SPEC SPEC ...) - add pixel values
22127 (- SPEC SPEC ...) - subtract pixel values
22128 (- SPEC) - negate pixel value
22130 NUM ::=
22131 INT or FLOAT - a number constant
22132 SYMBOL - use symbol's (buffer local) variable binding.
22134 UNIT ::=
22135 in - pixels per inch *)
22136 mm - pixels per 1/1000 meter *)
22137 cm - pixels per 1/100 meter *)
22138 width - width of current font in pixels.
22139 height - height of current font in pixels.
22141 *) using the ratio(s) defined in display-pixels-per-inch.
22143 ELEMENT ::=
22145 left-fringe - left fringe width in pixels
22146 right-fringe - right fringe width in pixels
22148 left-margin - left margin width in pixels
22149 right-margin - right margin width in pixels
22151 scroll-bar - scroll-bar area width in pixels
22153 Examples:
22155 Pixels corresponding to 5 inches:
22156 (5 . in)
22158 Total width of non-text areas on left side of window (if scroll-bar is on left):
22159 '(space :width (+ left-fringe left-margin scroll-bar))
22161 Align to first text column (in header line):
22162 '(space :align-to 0)
22164 Align to middle of text area minus half the width of variable `my-image'
22165 containing a loaded image:
22166 '(space :align-to (0.5 . (- text my-image)))
22168 Width of left margin minus width of 1 character in the default font:
22169 '(space :width (- left-margin 1))
22171 Width of left margin minus width of 2 characters in the current font:
22172 '(space :width (- left-margin (2 . width)))
22174 Center 1 character over left-margin (in header line):
22175 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
22177 Different ways to express width of left fringe plus left margin minus one pixel:
22178 '(space :width (- (+ left-fringe left-margin) (1)))
22179 '(space :width (+ left-fringe left-margin (- (1))))
22180 '(space :width (+ left-fringe left-margin (-1)))
22184 static int
22185 calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
22186 struct font *font, int width_p, int *align_to)
22188 double pixels;
22190 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
22191 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
22193 if (NILP (prop))
22194 return OK_PIXELS (0);
22196 eassert (FRAME_LIVE_P (it->f));
22198 if (SYMBOLP (prop))
22200 if (SCHARS (SYMBOL_NAME (prop)) == 2)
22202 char *unit = SSDATA (SYMBOL_NAME (prop));
22204 if (unit[0] == 'i' && unit[1] == 'n')
22205 pixels = 1.0;
22206 else if (unit[0] == 'm' && unit[1] == 'm')
22207 pixels = 25.4;
22208 else if (unit[0] == 'c' && unit[1] == 'm')
22209 pixels = 2.54;
22210 else
22211 pixels = 0;
22212 if (pixels > 0)
22214 double ppi = (width_p ? FRAME_RES_X (it->f)
22215 : FRAME_RES_Y (it->f));
22217 if (ppi > 0)
22218 return OK_PIXELS (ppi / pixels);
22219 return 0;
22223 #ifdef HAVE_WINDOW_SYSTEM
22224 if (EQ (prop, Qheight))
22225 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
22226 if (EQ (prop, Qwidth))
22227 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
22228 #else
22229 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
22230 return OK_PIXELS (1);
22231 #endif
22233 if (EQ (prop, Qtext))
22234 return OK_PIXELS (width_p
22235 ? window_box_width (it->w, TEXT_AREA)
22236 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
22238 if (align_to && *align_to < 0)
22240 *res = 0;
22241 if (EQ (prop, Qleft))
22242 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
22243 if (EQ (prop, Qright))
22244 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
22245 if (EQ (prop, Qcenter))
22246 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
22247 + window_box_width (it->w, TEXT_AREA) / 2);
22248 if (EQ (prop, Qleft_fringe))
22249 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22250 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
22251 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
22252 if (EQ (prop, Qright_fringe))
22253 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22254 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
22255 : window_box_right_offset (it->w, TEXT_AREA));
22256 if (EQ (prop, Qleft_margin))
22257 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
22258 if (EQ (prop, Qright_margin))
22259 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
22260 if (EQ (prop, Qscroll_bar))
22261 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
22263 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
22264 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22265 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
22266 : 0)));
22268 else
22270 if (EQ (prop, Qleft_fringe))
22271 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
22272 if (EQ (prop, Qright_fringe))
22273 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
22274 if (EQ (prop, Qleft_margin))
22275 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
22276 if (EQ (prop, Qright_margin))
22277 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
22278 if (EQ (prop, Qscroll_bar))
22279 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
22282 prop = buffer_local_value_1 (prop, it->w->contents);
22283 if (EQ (prop, Qunbound))
22284 prop = Qnil;
22287 if (INTEGERP (prop) || FLOATP (prop))
22289 int base_unit = (width_p
22290 ? FRAME_COLUMN_WIDTH (it->f)
22291 : FRAME_LINE_HEIGHT (it->f));
22292 return OK_PIXELS (XFLOATINT (prop) * base_unit);
22295 if (CONSP (prop))
22297 Lisp_Object car = XCAR (prop);
22298 Lisp_Object cdr = XCDR (prop);
22300 if (SYMBOLP (car))
22302 #ifdef HAVE_WINDOW_SYSTEM
22303 if (FRAME_WINDOW_P (it->f)
22304 && valid_image_p (prop))
22306 ptrdiff_t id = lookup_image (it->f, prop);
22307 struct image *img = IMAGE_FROM_ID (it->f, id);
22309 return OK_PIXELS (width_p ? img->width : img->height);
22311 #endif
22312 if (EQ (car, Qplus) || EQ (car, Qminus))
22314 int first = 1;
22315 double px;
22317 pixels = 0;
22318 while (CONSP (cdr))
22320 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
22321 font, width_p, align_to))
22322 return 0;
22323 if (first)
22324 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
22325 else
22326 pixels += px;
22327 cdr = XCDR (cdr);
22329 if (EQ (car, Qminus))
22330 pixels = -pixels;
22331 return OK_PIXELS (pixels);
22334 car = buffer_local_value_1 (car, it->w->contents);
22335 if (EQ (car, Qunbound))
22336 car = Qnil;
22339 if (INTEGERP (car) || FLOATP (car))
22341 double fact;
22342 pixels = XFLOATINT (car);
22343 if (NILP (cdr))
22344 return OK_PIXELS (pixels);
22345 if (calc_pixel_width_or_height (&fact, it, cdr,
22346 font, width_p, align_to))
22347 return OK_PIXELS (pixels * fact);
22348 return 0;
22351 return 0;
22354 return 0;
22358 /***********************************************************************
22359 Glyph Display
22360 ***********************************************************************/
22362 #ifdef HAVE_WINDOW_SYSTEM
22364 #ifdef GLYPH_DEBUG
22366 void
22367 dump_glyph_string (struct glyph_string *s)
22369 fprintf (stderr, "glyph string\n");
22370 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
22371 s->x, s->y, s->width, s->height);
22372 fprintf (stderr, " ybase = %d\n", s->ybase);
22373 fprintf (stderr, " hl = %d\n", s->hl);
22374 fprintf (stderr, " left overhang = %d, right = %d\n",
22375 s->left_overhang, s->right_overhang);
22376 fprintf (stderr, " nchars = %d\n", s->nchars);
22377 fprintf (stderr, " extends to end of line = %d\n",
22378 s->extends_to_end_of_line_p);
22379 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
22380 fprintf (stderr, " bg width = %d\n", s->background_width);
22383 #endif /* GLYPH_DEBUG */
22385 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
22386 of XChar2b structures for S; it can't be allocated in
22387 init_glyph_string because it must be allocated via `alloca'. W
22388 is the window on which S is drawn. ROW and AREA are the glyph row
22389 and area within the row from which S is constructed. START is the
22390 index of the first glyph structure covered by S. HL is a
22391 face-override for drawing S. */
22393 #ifdef HAVE_NTGUI
22394 #define OPTIONAL_HDC(hdc) HDC hdc,
22395 #define DECLARE_HDC(hdc) HDC hdc;
22396 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
22397 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
22398 #endif
22400 #ifndef OPTIONAL_HDC
22401 #define OPTIONAL_HDC(hdc)
22402 #define DECLARE_HDC(hdc)
22403 #define ALLOCATE_HDC(hdc, f)
22404 #define RELEASE_HDC(hdc, f)
22405 #endif
22407 static void
22408 init_glyph_string (struct glyph_string *s,
22409 OPTIONAL_HDC (hdc)
22410 XChar2b *char2b, struct window *w, struct glyph_row *row,
22411 enum glyph_row_area area, int start, enum draw_glyphs_face hl)
22413 memset (s, 0, sizeof *s);
22414 s->w = w;
22415 s->f = XFRAME (w->frame);
22416 #ifdef HAVE_NTGUI
22417 s->hdc = hdc;
22418 #endif
22419 s->display = FRAME_X_DISPLAY (s->f);
22420 s->window = FRAME_X_WINDOW (s->f);
22421 s->char2b = char2b;
22422 s->hl = hl;
22423 s->row = row;
22424 s->area = area;
22425 s->first_glyph = row->glyphs[area] + start;
22426 s->height = row->height;
22427 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
22428 s->ybase = s->y + row->ascent;
22432 /* Append the list of glyph strings with head H and tail T to the list
22433 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
22435 static void
22436 append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
22437 struct glyph_string *h, struct glyph_string *t)
22439 if (h)
22441 if (*head)
22442 (*tail)->next = h;
22443 else
22444 *head = h;
22445 h->prev = *tail;
22446 *tail = t;
22451 /* Prepend the list of glyph strings with head H and tail T to the
22452 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
22453 result. */
22455 static void
22456 prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
22457 struct glyph_string *h, struct glyph_string *t)
22459 if (h)
22461 if (*head)
22462 (*head)->prev = t;
22463 else
22464 *tail = t;
22465 t->next = *head;
22466 *head = h;
22471 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
22472 Set *HEAD and *TAIL to the resulting list. */
22474 static void
22475 append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
22476 struct glyph_string *s)
22478 s->next = s->prev = NULL;
22479 append_glyph_string_lists (head, tail, s, s);
22483 /* Get face and two-byte form of character C in face FACE_ID on frame F.
22484 The encoding of C is returned in *CHAR2B. DISPLAY_P non-zero means
22485 make sure that X resources for the face returned are allocated.
22486 Value is a pointer to a realized face that is ready for display if
22487 DISPLAY_P is non-zero. */
22489 static struct face *
22490 get_char_face_and_encoding (struct frame *f, int c, int face_id,
22491 XChar2b *char2b, int display_p)
22493 struct face *face = FACE_FROM_ID (f, face_id);
22494 unsigned code = 0;
22496 if (face->font)
22498 code = face->font->driver->encode_char (face->font, c);
22500 if (code == FONT_INVALID_CODE)
22501 code = 0;
22503 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
22505 /* Make sure X resources of the face are allocated. */
22506 #ifdef HAVE_X_WINDOWS
22507 if (display_p)
22508 #endif
22510 eassert (face != NULL);
22511 PREPARE_FACE_FOR_DISPLAY (f, face);
22514 return face;
22518 /* Get face and two-byte form of character glyph GLYPH on frame F.
22519 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
22520 a pointer to a realized face that is ready for display. */
22522 static struct face *
22523 get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
22524 XChar2b *char2b, int *two_byte_p)
22526 struct face *face;
22527 unsigned code = 0;
22529 eassert (glyph->type == CHAR_GLYPH);
22530 face = FACE_FROM_ID (f, glyph->face_id);
22532 /* Make sure X resources of the face are allocated. */
22533 eassert (face != NULL);
22534 PREPARE_FACE_FOR_DISPLAY (f, face);
22536 if (two_byte_p)
22537 *two_byte_p = 0;
22539 if (face->font)
22541 if (CHAR_BYTE8_P (glyph->u.ch))
22542 code = CHAR_TO_BYTE8 (glyph->u.ch);
22543 else
22544 code = face->font->driver->encode_char (face->font, glyph->u.ch);
22546 if (code == FONT_INVALID_CODE)
22547 code = 0;
22550 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
22551 return face;
22555 /* Get glyph code of character C in FONT in the two-byte form CHAR2B.
22556 Return 1 if FONT has a glyph for C, otherwise return 0. */
22558 static int
22559 get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
22561 unsigned code;
22563 if (CHAR_BYTE8_P (c))
22564 code = CHAR_TO_BYTE8 (c);
22565 else
22566 code = font->driver->encode_char (font, c);
22568 if (code == FONT_INVALID_CODE)
22569 return 0;
22570 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
22571 return 1;
22575 /* Fill glyph string S with composition components specified by S->cmp.
22577 BASE_FACE is the base face of the composition.
22578 S->cmp_from is the index of the first component for S.
22580 OVERLAPS non-zero means S should draw the foreground only, and use
22581 its physical height for clipping. See also draw_glyphs.
22583 Value is the index of a component not in S. */
22585 static int
22586 fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
22587 int overlaps)
22589 int i;
22590 /* For all glyphs of this composition, starting at the offset
22591 S->cmp_from, until we reach the end of the definition or encounter a
22592 glyph that requires the different face, add it to S. */
22593 struct face *face;
22595 eassert (s);
22597 s->for_overlaps = overlaps;
22598 s->face = NULL;
22599 s->font = NULL;
22600 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
22602 int c = COMPOSITION_GLYPH (s->cmp, i);
22604 /* TAB in a composition means display glyphs with padding space
22605 on the left or right. */
22606 if (c != '\t')
22608 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
22609 -1, Qnil);
22611 face = get_char_face_and_encoding (s->f, c, face_id,
22612 s->char2b + i, 1);
22613 if (face)
22615 if (! s->face)
22617 s->face = face;
22618 s->font = s->face->font;
22620 else if (s->face != face)
22621 break;
22624 ++s->nchars;
22626 s->cmp_to = i;
22628 if (s->face == NULL)
22630 s->face = base_face->ascii_face;
22631 s->font = s->face->font;
22634 /* All glyph strings for the same composition has the same width,
22635 i.e. the width set for the first component of the composition. */
22636 s->width = s->first_glyph->pixel_width;
22638 /* If the specified font could not be loaded, use the frame's
22639 default font, but record the fact that we couldn't load it in
22640 the glyph string so that we can draw rectangles for the
22641 characters of the glyph string. */
22642 if (s->font == NULL)
22644 s->font_not_found_p = 1;
22645 s->font = FRAME_FONT (s->f);
22648 /* Adjust base line for subscript/superscript text. */
22649 s->ybase += s->first_glyph->voffset;
22651 /* This glyph string must always be drawn with 16-bit functions. */
22652 s->two_byte_p = 1;
22654 return s->cmp_to;
22657 static int
22658 fill_gstring_glyph_string (struct glyph_string *s, int face_id,
22659 int start, int end, int overlaps)
22661 struct glyph *glyph, *last;
22662 Lisp_Object lgstring;
22663 int i;
22665 s->for_overlaps = overlaps;
22666 glyph = s->row->glyphs[s->area] + start;
22667 last = s->row->glyphs[s->area] + end;
22668 s->cmp_id = glyph->u.cmp.id;
22669 s->cmp_from = glyph->slice.cmp.from;
22670 s->cmp_to = glyph->slice.cmp.to + 1;
22671 s->face = FACE_FROM_ID (s->f, face_id);
22672 lgstring = composition_gstring_from_id (s->cmp_id);
22673 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
22674 glyph++;
22675 while (glyph < last
22676 && glyph->u.cmp.automatic
22677 && glyph->u.cmp.id == s->cmp_id
22678 && s->cmp_to == glyph->slice.cmp.from)
22679 s->cmp_to = (glyph++)->slice.cmp.to + 1;
22681 for (i = s->cmp_from; i < s->cmp_to; i++)
22683 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
22684 unsigned code = LGLYPH_CODE (lglyph);
22686 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
22688 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
22689 return glyph - s->row->glyphs[s->area];
22693 /* Fill glyph string S from a sequence glyphs for glyphless characters.
22694 See the comment of fill_glyph_string for arguments.
22695 Value is the index of the first glyph not in S. */
22698 static int
22699 fill_glyphless_glyph_string (struct glyph_string *s, int face_id,
22700 int start, int end, int overlaps)
22702 struct glyph *glyph, *last;
22703 int voffset;
22705 eassert (s->first_glyph->type == GLYPHLESS_GLYPH);
22706 s->for_overlaps = overlaps;
22707 glyph = s->row->glyphs[s->area] + start;
22708 last = s->row->glyphs[s->area] + end;
22709 voffset = glyph->voffset;
22710 s->face = FACE_FROM_ID (s->f, face_id);
22711 s->font = s->face->font ? s->face->font : FRAME_FONT (s->f);
22712 s->nchars = 1;
22713 s->width = glyph->pixel_width;
22714 glyph++;
22715 while (glyph < last
22716 && glyph->type == GLYPHLESS_GLYPH
22717 && glyph->voffset == voffset
22718 && glyph->face_id == face_id)
22720 s->nchars++;
22721 s->width += glyph->pixel_width;
22722 glyph++;
22724 s->ybase += voffset;
22725 return glyph - s->row->glyphs[s->area];
22729 /* Fill glyph string S from a sequence of character glyphs.
22731 FACE_ID is the face id of the string. START is the index of the
22732 first glyph to consider, END is the index of the last + 1.
22733 OVERLAPS non-zero means S should draw the foreground only, and use
22734 its physical height for clipping. See also draw_glyphs.
22736 Value is the index of the first glyph not in S. */
22738 static int
22739 fill_glyph_string (struct glyph_string *s, int face_id,
22740 int start, int end, int overlaps)
22742 struct glyph *glyph, *last;
22743 int voffset;
22744 int glyph_not_available_p;
22746 eassert (s->f == XFRAME (s->w->frame));
22747 eassert (s->nchars == 0);
22748 eassert (start >= 0 && end > start);
22750 s->for_overlaps = overlaps;
22751 glyph = s->row->glyphs[s->area] + start;
22752 last = s->row->glyphs[s->area] + end;
22753 voffset = glyph->voffset;
22754 s->padding_p = glyph->padding_p;
22755 glyph_not_available_p = glyph->glyph_not_available_p;
22757 while (glyph < last
22758 && glyph->type == CHAR_GLYPH
22759 && glyph->voffset == voffset
22760 /* Same face id implies same font, nowadays. */
22761 && glyph->face_id == face_id
22762 && glyph->glyph_not_available_p == glyph_not_available_p)
22764 int two_byte_p;
22766 s->face = get_glyph_face_and_encoding (s->f, glyph,
22767 s->char2b + s->nchars,
22768 &two_byte_p);
22769 s->two_byte_p = two_byte_p;
22770 ++s->nchars;
22771 eassert (s->nchars <= end - start);
22772 s->width += glyph->pixel_width;
22773 if (glyph++->padding_p != s->padding_p)
22774 break;
22777 s->font = s->face->font;
22779 /* If the specified font could not be loaded, use the frame's font,
22780 but record the fact that we couldn't load it in
22781 S->font_not_found_p so that we can draw rectangles for the
22782 characters of the glyph string. */
22783 if (s->font == NULL || glyph_not_available_p)
22785 s->font_not_found_p = 1;
22786 s->font = FRAME_FONT (s->f);
22789 /* Adjust base line for subscript/superscript text. */
22790 s->ybase += voffset;
22792 eassert (s->face && s->face->gc);
22793 return glyph - s->row->glyphs[s->area];
22797 /* Fill glyph string S from image glyph S->first_glyph. */
22799 static void
22800 fill_image_glyph_string (struct glyph_string *s)
22802 eassert (s->first_glyph->type == IMAGE_GLYPH);
22803 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
22804 eassert (s->img);
22805 s->slice = s->first_glyph->slice.img;
22806 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
22807 s->font = s->face->font;
22808 s->width = s->first_glyph->pixel_width;
22810 /* Adjust base line for subscript/superscript text. */
22811 s->ybase += s->first_glyph->voffset;
22815 /* Fill glyph string S from a sequence of stretch glyphs.
22817 START is the index of the first glyph to consider,
22818 END is the index of the last + 1.
22820 Value is the index of the first glyph not in S. */
22822 static int
22823 fill_stretch_glyph_string (struct glyph_string *s, int start, int end)
22825 struct glyph *glyph, *last;
22826 int voffset, face_id;
22828 eassert (s->first_glyph->type == STRETCH_GLYPH);
22830 glyph = s->row->glyphs[s->area] + start;
22831 last = s->row->glyphs[s->area] + end;
22832 face_id = glyph->face_id;
22833 s->face = FACE_FROM_ID (s->f, face_id);
22834 s->font = s->face->font;
22835 s->width = glyph->pixel_width;
22836 s->nchars = 1;
22837 voffset = glyph->voffset;
22839 for (++glyph;
22840 (glyph < last
22841 && glyph->type == STRETCH_GLYPH
22842 && glyph->voffset == voffset
22843 && glyph->face_id == face_id);
22844 ++glyph)
22845 s->width += glyph->pixel_width;
22847 /* Adjust base line for subscript/superscript text. */
22848 s->ybase += voffset;
22850 /* The case that face->gc == 0 is handled when drawing the glyph
22851 string by calling PREPARE_FACE_FOR_DISPLAY. */
22852 eassert (s->face);
22853 return glyph - s->row->glyphs[s->area];
22856 static struct font_metrics *
22857 get_per_char_metric (struct font *font, XChar2b *char2b)
22859 static struct font_metrics metrics;
22860 unsigned code;
22862 if (! font)
22863 return NULL;
22864 code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
22865 if (code == FONT_INVALID_CODE)
22866 return NULL;
22867 font->driver->text_extents (font, &code, 1, &metrics);
22868 return &metrics;
22871 /* EXPORT for RIF:
22872 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
22873 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
22874 assumed to be zero. */
22876 void
22877 x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *right)
22879 *left = *right = 0;
22881 if (glyph->type == CHAR_GLYPH)
22883 struct face *face;
22884 XChar2b char2b;
22885 struct font_metrics *pcm;
22887 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
22888 if (face->font && (pcm = get_per_char_metric (face->font, &char2b)))
22890 if (pcm->rbearing > pcm->width)
22891 *right = pcm->rbearing - pcm->width;
22892 if (pcm->lbearing < 0)
22893 *left = -pcm->lbearing;
22896 else if (glyph->type == COMPOSITE_GLYPH)
22898 if (! glyph->u.cmp.automatic)
22900 struct composition *cmp = composition_table[glyph->u.cmp.id];
22902 if (cmp->rbearing > cmp->pixel_width)
22903 *right = cmp->rbearing - cmp->pixel_width;
22904 if (cmp->lbearing < 0)
22905 *left = - cmp->lbearing;
22907 else
22909 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
22910 struct font_metrics metrics;
22912 composition_gstring_width (gstring, glyph->slice.cmp.from,
22913 glyph->slice.cmp.to + 1, &metrics);
22914 if (metrics.rbearing > metrics.width)
22915 *right = metrics.rbearing - metrics.width;
22916 if (metrics.lbearing < 0)
22917 *left = - metrics.lbearing;
22923 /* Return the index of the first glyph preceding glyph string S that
22924 is overwritten by S because of S's left overhang. Value is -1
22925 if no glyphs are overwritten. */
22927 static int
22928 left_overwritten (struct glyph_string *s)
22930 int k;
22932 if (s->left_overhang)
22934 int x = 0, i;
22935 struct glyph *glyphs = s->row->glyphs[s->area];
22936 int first = s->first_glyph - glyphs;
22938 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
22939 x -= glyphs[i].pixel_width;
22941 k = i + 1;
22943 else
22944 k = -1;
22946 return k;
22950 /* Return the index of the first glyph preceding glyph string S that
22951 is overwriting S because of its right overhang. Value is -1 if no
22952 glyph in front of S overwrites S. */
22954 static int
22955 left_overwriting (struct glyph_string *s)
22957 int i, k, x;
22958 struct glyph *glyphs = s->row->glyphs[s->area];
22959 int first = s->first_glyph - glyphs;
22961 k = -1;
22962 x = 0;
22963 for (i = first - 1; i >= 0; --i)
22965 int left, right;
22966 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
22967 if (x + right > 0)
22968 k = i;
22969 x -= glyphs[i].pixel_width;
22972 return k;
22976 /* Return the index of the last glyph following glyph string S that is
22977 overwritten by S because of S's right overhang. Value is -1 if
22978 no such glyph is found. */
22980 static int
22981 right_overwritten (struct glyph_string *s)
22983 int k = -1;
22985 if (s->right_overhang)
22987 int x = 0, i;
22988 struct glyph *glyphs = s->row->glyphs[s->area];
22989 int first = (s->first_glyph - glyphs
22990 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
22991 int end = s->row->used[s->area];
22993 for (i = first; i < end && s->right_overhang > x; ++i)
22994 x += glyphs[i].pixel_width;
22996 k = i;
22999 return k;
23003 /* Return the index of the last glyph following glyph string S that
23004 overwrites S because of its left overhang. Value is negative
23005 if no such glyph is found. */
23007 static int
23008 right_overwriting (struct glyph_string *s)
23010 int i, k, x;
23011 int end = s->row->used[s->area];
23012 struct glyph *glyphs = s->row->glyphs[s->area];
23013 int first = (s->first_glyph - glyphs
23014 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
23016 k = -1;
23017 x = 0;
23018 for (i = first; i < end; ++i)
23020 int left, right;
23021 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
23022 if (x - left < 0)
23023 k = i;
23024 x += glyphs[i].pixel_width;
23027 return k;
23031 /* Set background width of glyph string S. START is the index of the
23032 first glyph following S. LAST_X is the right-most x-position + 1
23033 in the drawing area. */
23035 static void
23036 set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
23038 /* If the face of this glyph string has to be drawn to the end of
23039 the drawing area, set S->extends_to_end_of_line_p. */
23041 if (start == s->row->used[s->area]
23042 && s->area == TEXT_AREA
23043 && ((s->row->fill_line_p
23044 && (s->hl == DRAW_NORMAL_TEXT
23045 || s->hl == DRAW_IMAGE_RAISED
23046 || s->hl == DRAW_IMAGE_SUNKEN))
23047 || s->hl == DRAW_MOUSE_FACE))
23048 s->extends_to_end_of_line_p = 1;
23050 /* If S extends its face to the end of the line, set its
23051 background_width to the distance to the right edge of the drawing
23052 area. */
23053 if (s->extends_to_end_of_line_p)
23054 s->background_width = last_x - s->x + 1;
23055 else
23056 s->background_width = s->width;
23060 /* Compute overhangs and x-positions for glyph string S and its
23061 predecessors, or successors. X is the starting x-position for S.
23062 BACKWARD_P non-zero means process predecessors. */
23064 static void
23065 compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
23067 if (backward_p)
23069 while (s)
23071 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
23072 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
23073 x -= s->width;
23074 s->x = x;
23075 s = s->prev;
23078 else
23080 while (s)
23082 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
23083 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
23084 s->x = x;
23085 x += s->width;
23086 s = s->next;
23093 /* The following macros are only called from draw_glyphs below.
23094 They reference the following parameters of that function directly:
23095 `w', `row', `area', and `overlap_p'
23096 as well as the following local variables:
23097 `s', `f', and `hdc' (in W32) */
23099 #ifdef HAVE_NTGUI
23100 /* On W32, silently add local `hdc' variable to argument list of
23101 init_glyph_string. */
23102 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
23103 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
23104 #else
23105 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
23106 init_glyph_string (s, char2b, w, row, area, start, hl)
23107 #endif
23109 /* Add a glyph string for a stretch glyph to the list of strings
23110 between HEAD and TAIL. START is the index of the stretch glyph in
23111 row area AREA of glyph row ROW. END is the index of the last glyph
23112 in that glyph row area. X is the current output position assigned
23113 to the new glyph string constructed. HL overrides that face of the
23114 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
23115 is the right-most x-position of the drawing area. */
23117 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
23118 and below -- keep them on one line. */
23119 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23120 do \
23122 s = alloca (sizeof *s); \
23123 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23124 START = fill_stretch_glyph_string (s, START, END); \
23125 append_glyph_string (&HEAD, &TAIL, s); \
23126 s->x = (X); \
23128 while (0)
23131 /* Add a glyph string for an image glyph to the list of strings
23132 between HEAD and TAIL. START is the index of the image glyph in
23133 row area AREA of glyph row ROW. END is the index of the last glyph
23134 in that glyph row area. X is the current output position assigned
23135 to the new glyph string constructed. HL overrides that face of the
23136 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
23137 is the right-most x-position of the drawing area. */
23139 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23140 do \
23142 s = alloca (sizeof *s); \
23143 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23144 fill_image_glyph_string (s); \
23145 append_glyph_string (&HEAD, &TAIL, s); \
23146 ++START; \
23147 s->x = (X); \
23149 while (0)
23152 /* Add a glyph string for a sequence of character glyphs to the list
23153 of strings between HEAD and TAIL. START is the index of the first
23154 glyph in row area AREA of glyph row ROW that is part of the new
23155 glyph string. END is the index of the last glyph in that glyph row
23156 area. X is the current output position assigned to the new glyph
23157 string constructed. HL overrides that face of the glyph; e.g. it
23158 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
23159 right-most x-position of the drawing area. */
23161 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
23162 do \
23164 int face_id; \
23165 XChar2b *char2b; \
23167 face_id = (row)->glyphs[area][START].face_id; \
23169 s = alloca (sizeof *s); \
23170 char2b = alloca ((END - START) * sizeof *char2b); \
23171 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23172 append_glyph_string (&HEAD, &TAIL, s); \
23173 s->x = (X); \
23174 START = fill_glyph_string (s, face_id, START, END, overlaps); \
23176 while (0)
23179 /* Add a glyph string for a composite sequence to the list of strings
23180 between HEAD and TAIL. START is the index of the first glyph in
23181 row area AREA of glyph row ROW that is part of the new glyph
23182 string. END is the index of the last glyph in that glyph row area.
23183 X is the current output position assigned to the new glyph string
23184 constructed. HL overrides that face of the glyph; e.g. it is
23185 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
23186 x-position of the drawing area. */
23188 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23189 do { \
23190 int face_id = (row)->glyphs[area][START].face_id; \
23191 struct face *base_face = FACE_FROM_ID (f, face_id); \
23192 ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \
23193 struct composition *cmp = composition_table[cmp_id]; \
23194 XChar2b *char2b; \
23195 struct glyph_string *first_s = NULL; \
23196 int n; \
23198 char2b = alloca (cmp->glyph_len * sizeof *char2b); \
23200 /* Make glyph_strings for each glyph sequence that is drawable by \
23201 the same face, and append them to HEAD/TAIL. */ \
23202 for (n = 0; n < cmp->glyph_len;) \
23204 s = alloca (sizeof *s); \
23205 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23206 append_glyph_string (&(HEAD), &(TAIL), s); \
23207 s->cmp = cmp; \
23208 s->cmp_from = n; \
23209 s->x = (X); \
23210 if (n == 0) \
23211 first_s = s; \
23212 n = fill_composite_glyph_string (s, base_face, overlaps); \
23215 ++START; \
23216 s = first_s; \
23217 } while (0)
23220 /* Add a glyph string for a glyph-string sequence to the list of strings
23221 between HEAD and TAIL. */
23223 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23224 do { \
23225 int face_id; \
23226 XChar2b *char2b; \
23227 Lisp_Object gstring; \
23229 face_id = (row)->glyphs[area][START].face_id; \
23230 gstring = (composition_gstring_from_id \
23231 ((row)->glyphs[area][START].u.cmp.id)); \
23232 s = alloca (sizeof *s); \
23233 char2b = alloca (LGSTRING_GLYPH_LEN (gstring) * sizeof *char2b); \
23234 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23235 append_glyph_string (&(HEAD), &(TAIL), s); \
23236 s->x = (X); \
23237 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
23238 } while (0)
23241 /* Add a glyph string for a sequence of glyphless character's glyphs
23242 to the list of strings between HEAD and TAIL. The meanings of
23243 arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */
23245 #define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23246 do \
23248 int face_id; \
23250 face_id = (row)->glyphs[area][START].face_id; \
23252 s = alloca (sizeof *s); \
23253 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23254 append_glyph_string (&HEAD, &TAIL, s); \
23255 s->x = (X); \
23256 START = fill_glyphless_glyph_string (s, face_id, START, END, \
23257 overlaps); \
23259 while (0)
23262 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
23263 of AREA of glyph row ROW on window W between indices START and END.
23264 HL overrides the face for drawing glyph strings, e.g. it is
23265 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
23266 x-positions of the drawing area.
23268 This is an ugly monster macro construct because we must use alloca
23269 to allocate glyph strings (because draw_glyphs can be called
23270 asynchronously). */
23272 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
23273 do \
23275 HEAD = TAIL = NULL; \
23276 while (START < END) \
23278 struct glyph *first_glyph = (row)->glyphs[area] + START; \
23279 switch (first_glyph->type) \
23281 case CHAR_GLYPH: \
23282 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
23283 HL, X, LAST_X); \
23284 break; \
23286 case COMPOSITE_GLYPH: \
23287 if (first_glyph->u.cmp.automatic) \
23288 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
23289 HL, X, LAST_X); \
23290 else \
23291 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
23292 HL, X, LAST_X); \
23293 break; \
23295 case STRETCH_GLYPH: \
23296 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
23297 HL, X, LAST_X); \
23298 break; \
23300 case IMAGE_GLYPH: \
23301 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
23302 HL, X, LAST_X); \
23303 break; \
23305 case GLYPHLESS_GLYPH: \
23306 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
23307 HL, X, LAST_X); \
23308 break; \
23310 default: \
23311 emacs_abort (); \
23314 if (s) \
23316 set_glyph_string_background_width (s, START, LAST_X); \
23317 (X) += s->width; \
23320 } while (0)
23323 /* Draw glyphs between START and END in AREA of ROW on window W,
23324 starting at x-position X. X is relative to AREA in W. HL is a
23325 face-override with the following meaning:
23327 DRAW_NORMAL_TEXT draw normally
23328 DRAW_CURSOR draw in cursor face
23329 DRAW_MOUSE_FACE draw in mouse face.
23330 DRAW_INVERSE_VIDEO draw in mode line face
23331 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
23332 DRAW_IMAGE_RAISED draw an image with a raised relief around it
23334 If OVERLAPS is non-zero, draw only the foreground of characters and
23335 clip to the physical height of ROW. Non-zero value also defines
23336 the overlapping part to be drawn:
23338 OVERLAPS_PRED overlap with preceding rows
23339 OVERLAPS_SUCC overlap with succeeding rows
23340 OVERLAPS_BOTH overlap with both preceding/succeeding rows
23341 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
23343 Value is the x-position reached, relative to AREA of W. */
23345 static int
23346 draw_glyphs (struct window *w, int x, struct glyph_row *row,
23347 enum glyph_row_area area, ptrdiff_t start, ptrdiff_t end,
23348 enum draw_glyphs_face hl, int overlaps)
23350 struct glyph_string *head, *tail;
23351 struct glyph_string *s;
23352 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
23353 int i, j, x_reached, last_x, area_left = 0;
23354 struct frame *f = XFRAME (WINDOW_FRAME (w));
23355 DECLARE_HDC (hdc);
23357 ALLOCATE_HDC (hdc, f);
23359 /* Let's rather be paranoid than getting a SEGV. */
23360 end = min (end, row->used[area]);
23361 start = clip_to_bounds (0, start, end);
23363 /* Translate X to frame coordinates. Set last_x to the right
23364 end of the drawing area. */
23365 if (row->full_width_p)
23367 /* X is relative to the left edge of W, without scroll bars
23368 or fringes. */
23369 area_left = WINDOW_LEFT_EDGE_X (w);
23370 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
23372 else
23374 area_left = window_box_left (w, area);
23375 last_x = area_left + window_box_width (w, area);
23377 x += area_left;
23379 /* Build a doubly-linked list of glyph_string structures between
23380 head and tail from what we have to draw. Note that the macro
23381 BUILD_GLYPH_STRINGS will modify its start parameter. That's
23382 the reason we use a separate variable `i'. */
23383 i = start;
23384 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
23385 if (tail)
23386 x_reached = tail->x + tail->background_width;
23387 else
23388 x_reached = x;
23390 /* If there are any glyphs with lbearing < 0 or rbearing > width in
23391 the row, redraw some glyphs in front or following the glyph
23392 strings built above. */
23393 if (head && !overlaps && row->contains_overlapping_glyphs_p)
23395 struct glyph_string *h, *t;
23396 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
23397 int mouse_beg_col IF_LINT (= 0), mouse_end_col IF_LINT (= 0);
23398 int check_mouse_face = 0;
23399 int dummy_x = 0;
23401 /* If mouse highlighting is on, we may need to draw adjacent
23402 glyphs using mouse-face highlighting. */
23403 if (area == TEXT_AREA && row->mouse_face_p
23404 && hlinfo->mouse_face_beg_row >= 0
23405 && hlinfo->mouse_face_end_row >= 0)
23407 struct glyph_row *mouse_beg_row, *mouse_end_row;
23409 mouse_beg_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
23410 mouse_end_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
23412 if (row >= mouse_beg_row && row <= mouse_end_row)
23414 check_mouse_face = 1;
23415 mouse_beg_col = (row == mouse_beg_row)
23416 ? hlinfo->mouse_face_beg_col : 0;
23417 mouse_end_col = (row == mouse_end_row)
23418 ? hlinfo->mouse_face_end_col
23419 : row->used[TEXT_AREA];
23423 /* Compute overhangs for all glyph strings. */
23424 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
23425 for (s = head; s; s = s->next)
23426 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
23428 /* Prepend glyph strings for glyphs in front of the first glyph
23429 string that are overwritten because of the first glyph
23430 string's left overhang. The background of all strings
23431 prepended must be drawn because the first glyph string
23432 draws over it. */
23433 i = left_overwritten (head);
23434 if (i >= 0)
23436 enum draw_glyphs_face overlap_hl;
23438 /* If this row contains mouse highlighting, attempt to draw
23439 the overlapped glyphs with the correct highlight. This
23440 code fails if the overlap encompasses more than one glyph
23441 and mouse-highlight spans only some of these glyphs.
23442 However, making it work perfectly involves a lot more
23443 code, and I don't know if the pathological case occurs in
23444 practice, so we'll stick to this for now. --- cyd */
23445 if (check_mouse_face
23446 && mouse_beg_col < start && mouse_end_col > i)
23447 overlap_hl = DRAW_MOUSE_FACE;
23448 else
23449 overlap_hl = DRAW_NORMAL_TEXT;
23451 j = i;
23452 BUILD_GLYPH_STRINGS (j, start, h, t,
23453 overlap_hl, dummy_x, last_x);
23454 start = i;
23455 compute_overhangs_and_x (t, head->x, 1);
23456 prepend_glyph_string_lists (&head, &tail, h, t);
23457 clip_head = head;
23460 /* Prepend glyph strings for glyphs in front of the first glyph
23461 string that overwrite that glyph string because of their
23462 right overhang. For these strings, only the foreground must
23463 be drawn, because it draws over the glyph string at `head'.
23464 The background must not be drawn because this would overwrite
23465 right overhangs of preceding glyphs for which no glyph
23466 strings exist. */
23467 i = left_overwriting (head);
23468 if (i >= 0)
23470 enum draw_glyphs_face overlap_hl;
23472 if (check_mouse_face
23473 && mouse_beg_col < start && mouse_end_col > i)
23474 overlap_hl = DRAW_MOUSE_FACE;
23475 else
23476 overlap_hl = DRAW_NORMAL_TEXT;
23478 clip_head = head;
23479 BUILD_GLYPH_STRINGS (i, start, h, t,
23480 overlap_hl, dummy_x, last_x);
23481 for (s = h; s; s = s->next)
23482 s->background_filled_p = 1;
23483 compute_overhangs_and_x (t, head->x, 1);
23484 prepend_glyph_string_lists (&head, &tail, h, t);
23487 /* Append glyphs strings for glyphs following the last glyph
23488 string tail that are overwritten by tail. The background of
23489 these strings has to be drawn because tail's foreground draws
23490 over it. */
23491 i = right_overwritten (tail);
23492 if (i >= 0)
23494 enum draw_glyphs_face overlap_hl;
23496 if (check_mouse_face
23497 && mouse_beg_col < i && mouse_end_col > end)
23498 overlap_hl = DRAW_MOUSE_FACE;
23499 else
23500 overlap_hl = DRAW_NORMAL_TEXT;
23502 BUILD_GLYPH_STRINGS (end, i, h, t,
23503 overlap_hl, x, last_x);
23504 /* Because BUILD_GLYPH_STRINGS updates the first argument,
23505 we don't have `end = i;' here. */
23506 compute_overhangs_and_x (h, tail->x + tail->width, 0);
23507 append_glyph_string_lists (&head, &tail, h, t);
23508 clip_tail = tail;
23511 /* Append glyph strings for glyphs following the last glyph
23512 string tail that overwrite tail. The foreground of such
23513 glyphs has to be drawn because it writes into the background
23514 of tail. The background must not be drawn because it could
23515 paint over the foreground of following glyphs. */
23516 i = right_overwriting (tail);
23517 if (i >= 0)
23519 enum draw_glyphs_face overlap_hl;
23520 if (check_mouse_face
23521 && mouse_beg_col < i && mouse_end_col > end)
23522 overlap_hl = DRAW_MOUSE_FACE;
23523 else
23524 overlap_hl = DRAW_NORMAL_TEXT;
23526 clip_tail = tail;
23527 i++; /* We must include the Ith glyph. */
23528 BUILD_GLYPH_STRINGS (end, i, h, t,
23529 overlap_hl, x, last_x);
23530 for (s = h; s; s = s->next)
23531 s->background_filled_p = 1;
23532 compute_overhangs_and_x (h, tail->x + tail->width, 0);
23533 append_glyph_string_lists (&head, &tail, h, t);
23535 if (clip_head || clip_tail)
23536 for (s = head; s; s = s->next)
23538 s->clip_head = clip_head;
23539 s->clip_tail = clip_tail;
23543 /* Draw all strings. */
23544 for (s = head; s; s = s->next)
23545 FRAME_RIF (f)->draw_glyph_string (s);
23547 #ifndef HAVE_NS
23548 /* When focus a sole frame and move horizontally, this sets on_p to 0
23549 causing a failure to erase prev cursor position. */
23550 if (area == TEXT_AREA
23551 && !row->full_width_p
23552 /* When drawing overlapping rows, only the glyph strings'
23553 foreground is drawn, which doesn't erase a cursor
23554 completely. */
23555 && !overlaps)
23557 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
23558 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
23559 : (tail ? tail->x + tail->background_width : x));
23560 x0 -= area_left;
23561 x1 -= area_left;
23563 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
23564 row->y, MATRIX_ROW_BOTTOM_Y (row));
23566 #endif
23568 /* Value is the x-position up to which drawn, relative to AREA of W.
23569 This doesn't include parts drawn because of overhangs. */
23570 if (row->full_width_p)
23571 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
23572 else
23573 x_reached -= area_left;
23575 RELEASE_HDC (hdc, f);
23577 return x_reached;
23580 /* Expand row matrix if too narrow. Don't expand if area
23581 is not present. */
23583 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
23585 if (!fonts_changed_p \
23586 && (it->glyph_row->glyphs[area] \
23587 < it->glyph_row->glyphs[area + 1])) \
23589 it->w->ncols_scale_factor++; \
23590 fonts_changed_p = 1; \
23594 /* Store one glyph for IT->char_to_display in IT->glyph_row.
23595 Called from x_produce_glyphs when IT->glyph_row is non-null. */
23597 static void
23598 append_glyph (struct it *it)
23600 struct glyph *glyph;
23601 enum glyph_row_area area = it->area;
23603 eassert (it->glyph_row);
23604 eassert (it->char_to_display != '\n' && it->char_to_display != '\t');
23606 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
23607 if (glyph < it->glyph_row->glyphs[area + 1])
23609 /* If the glyph row is reversed, we need to prepend the glyph
23610 rather than append it. */
23611 if (it->glyph_row->reversed_p && area == TEXT_AREA)
23613 struct glyph *g;
23615 /* Make room for the additional glyph. */
23616 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
23617 g[1] = *g;
23618 glyph = it->glyph_row->glyphs[area];
23620 glyph->charpos = CHARPOS (it->position);
23621 glyph->object = it->object;
23622 if (it->pixel_width > 0)
23624 glyph->pixel_width = it->pixel_width;
23625 glyph->padding_p = 0;
23627 else
23629 /* Assure at least 1-pixel width. Otherwise, cursor can't
23630 be displayed correctly. */
23631 glyph->pixel_width = 1;
23632 glyph->padding_p = 1;
23634 glyph->ascent = it->ascent;
23635 glyph->descent = it->descent;
23636 glyph->voffset = it->voffset;
23637 glyph->type = CHAR_GLYPH;
23638 glyph->avoid_cursor_p = it->avoid_cursor_p;
23639 glyph->multibyte_p = it->multibyte_p;
23640 if (it->glyph_row->reversed_p && area == TEXT_AREA)
23642 /* In R2L rows, the left and the right box edges need to be
23643 drawn in reverse direction. */
23644 glyph->right_box_line_p = it->start_of_box_run_p;
23645 glyph->left_box_line_p = it->end_of_box_run_p;
23647 else
23649 glyph->left_box_line_p = it->start_of_box_run_p;
23650 glyph->right_box_line_p = it->end_of_box_run_p;
23652 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
23653 || it->phys_descent > it->descent);
23654 glyph->glyph_not_available_p = it->glyph_not_available_p;
23655 glyph->face_id = it->face_id;
23656 glyph->u.ch = it->char_to_display;
23657 glyph->slice.img = null_glyph_slice;
23658 glyph->font_type = FONT_TYPE_UNKNOWN;
23659 if (it->bidi_p)
23661 glyph->resolved_level = it->bidi_it.resolved_level;
23662 if ((it->bidi_it.type & 7) != it->bidi_it.type)
23663 emacs_abort ();
23664 glyph->bidi_type = it->bidi_it.type;
23666 else
23668 glyph->resolved_level = 0;
23669 glyph->bidi_type = UNKNOWN_BT;
23671 ++it->glyph_row->used[area];
23673 else
23674 IT_EXPAND_MATRIX_WIDTH (it, area);
23677 /* Store one glyph for the composition IT->cmp_it.id in
23678 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
23679 non-null. */
23681 static void
23682 append_composite_glyph (struct it *it)
23684 struct glyph *glyph;
23685 enum glyph_row_area area = it->area;
23687 eassert (it->glyph_row);
23689 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
23690 if (glyph < it->glyph_row->glyphs[area + 1])
23692 /* If the glyph row is reversed, we need to prepend the glyph
23693 rather than append it. */
23694 if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
23696 struct glyph *g;
23698 /* Make room for the new glyph. */
23699 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
23700 g[1] = *g;
23701 glyph = it->glyph_row->glyphs[it->area];
23703 glyph->charpos = it->cmp_it.charpos;
23704 glyph->object = it->object;
23705 glyph->pixel_width = it->pixel_width;
23706 glyph->ascent = it->ascent;
23707 glyph->descent = it->descent;
23708 glyph->voffset = it->voffset;
23709 glyph->type = COMPOSITE_GLYPH;
23710 if (it->cmp_it.ch < 0)
23712 glyph->u.cmp.automatic = 0;
23713 glyph->u.cmp.id = it->cmp_it.id;
23714 glyph->slice.cmp.from = glyph->slice.cmp.to = 0;
23716 else
23718 glyph->u.cmp.automatic = 1;
23719 glyph->u.cmp.id = it->cmp_it.id;
23720 glyph->slice.cmp.from = it->cmp_it.from;
23721 glyph->slice.cmp.to = it->cmp_it.to - 1;
23723 glyph->avoid_cursor_p = it->avoid_cursor_p;
23724 glyph->multibyte_p = it->multibyte_p;
23725 if (it->glyph_row->reversed_p && area == TEXT_AREA)
23727 /* In R2L rows, the left and the right box edges need to be
23728 drawn in reverse direction. */
23729 glyph->right_box_line_p = it->start_of_box_run_p;
23730 glyph->left_box_line_p = it->end_of_box_run_p;
23732 else
23734 glyph->left_box_line_p = it->start_of_box_run_p;
23735 glyph->right_box_line_p = it->end_of_box_run_p;
23737 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
23738 || it->phys_descent > it->descent);
23739 glyph->padding_p = 0;
23740 glyph->glyph_not_available_p = 0;
23741 glyph->face_id = it->face_id;
23742 glyph->font_type = FONT_TYPE_UNKNOWN;
23743 if (it->bidi_p)
23745 glyph->resolved_level = it->bidi_it.resolved_level;
23746 if ((it->bidi_it.type & 7) != it->bidi_it.type)
23747 emacs_abort ();
23748 glyph->bidi_type = it->bidi_it.type;
23750 ++it->glyph_row->used[area];
23752 else
23753 IT_EXPAND_MATRIX_WIDTH (it, area);
23757 /* Change IT->ascent and IT->height according to the setting of
23758 IT->voffset. */
23760 static void
23761 take_vertical_position_into_account (struct it *it)
23763 if (it->voffset)
23765 if (it->voffset < 0)
23766 /* Increase the ascent so that we can display the text higher
23767 in the line. */
23768 it->ascent -= it->voffset;
23769 else
23770 /* Increase the descent so that we can display the text lower
23771 in the line. */
23772 it->descent += it->voffset;
23777 /* Produce glyphs/get display metrics for the image IT is loaded with.
23778 See the description of struct display_iterator in dispextern.h for
23779 an overview of struct display_iterator. */
23781 static void
23782 produce_image_glyph (struct it *it)
23784 struct image *img;
23785 struct face *face;
23786 int glyph_ascent, crop;
23787 struct glyph_slice slice;
23789 eassert (it->what == IT_IMAGE);
23791 face = FACE_FROM_ID (it->f, it->face_id);
23792 eassert (face);
23793 /* Make sure X resources of the face is loaded. */
23794 PREPARE_FACE_FOR_DISPLAY (it->f, face);
23796 if (it->image_id < 0)
23798 /* Fringe bitmap. */
23799 it->ascent = it->phys_ascent = 0;
23800 it->descent = it->phys_descent = 0;
23801 it->pixel_width = 0;
23802 it->nglyphs = 0;
23803 return;
23806 img = IMAGE_FROM_ID (it->f, it->image_id);
23807 eassert (img);
23808 /* Make sure X resources of the image is loaded. */
23809 prepare_image_for_display (it->f, img);
23811 slice.x = slice.y = 0;
23812 slice.width = img->width;
23813 slice.height = img->height;
23815 if (INTEGERP (it->slice.x))
23816 slice.x = XINT (it->slice.x);
23817 else if (FLOATP (it->slice.x))
23818 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
23820 if (INTEGERP (it->slice.y))
23821 slice.y = XINT (it->slice.y);
23822 else if (FLOATP (it->slice.y))
23823 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
23825 if (INTEGERP (it->slice.width))
23826 slice.width = XINT (it->slice.width);
23827 else if (FLOATP (it->slice.width))
23828 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
23830 if (INTEGERP (it->slice.height))
23831 slice.height = XINT (it->slice.height);
23832 else if (FLOATP (it->slice.height))
23833 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
23835 if (slice.x >= img->width)
23836 slice.x = img->width;
23837 if (slice.y >= img->height)
23838 slice.y = img->height;
23839 if (slice.x + slice.width >= img->width)
23840 slice.width = img->width - slice.x;
23841 if (slice.y + slice.height > img->height)
23842 slice.height = img->height - slice.y;
23844 if (slice.width == 0 || slice.height == 0)
23845 return;
23847 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
23849 it->descent = slice.height - glyph_ascent;
23850 if (slice.y == 0)
23851 it->descent += img->vmargin;
23852 if (slice.y + slice.height == img->height)
23853 it->descent += img->vmargin;
23854 it->phys_descent = it->descent;
23856 it->pixel_width = slice.width;
23857 if (slice.x == 0)
23858 it->pixel_width += img->hmargin;
23859 if (slice.x + slice.width == img->width)
23860 it->pixel_width += img->hmargin;
23862 /* It's quite possible for images to have an ascent greater than
23863 their height, so don't get confused in that case. */
23864 if (it->descent < 0)
23865 it->descent = 0;
23867 it->nglyphs = 1;
23869 if (face->box != FACE_NO_BOX)
23871 if (face->box_line_width > 0)
23873 if (slice.y == 0)
23874 it->ascent += face->box_line_width;
23875 if (slice.y + slice.height == img->height)
23876 it->descent += face->box_line_width;
23879 if (it->start_of_box_run_p && slice.x == 0)
23880 it->pixel_width += eabs (face->box_line_width);
23881 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
23882 it->pixel_width += eabs (face->box_line_width);
23885 take_vertical_position_into_account (it);
23887 /* Automatically crop wide image glyphs at right edge so we can
23888 draw the cursor on same display row. */
23889 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
23890 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
23892 it->pixel_width -= crop;
23893 slice.width -= crop;
23896 if (it->glyph_row)
23898 struct glyph *glyph;
23899 enum glyph_row_area area = it->area;
23901 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
23902 if (glyph < it->glyph_row->glyphs[area + 1])
23904 glyph->charpos = CHARPOS (it->position);
23905 glyph->object = it->object;
23906 glyph->pixel_width = it->pixel_width;
23907 glyph->ascent = glyph_ascent;
23908 glyph->descent = it->descent;
23909 glyph->voffset = it->voffset;
23910 glyph->type = IMAGE_GLYPH;
23911 glyph->avoid_cursor_p = it->avoid_cursor_p;
23912 glyph->multibyte_p = it->multibyte_p;
23913 if (it->glyph_row->reversed_p && area == TEXT_AREA)
23915 /* In R2L rows, the left and the right box edges need to be
23916 drawn in reverse direction. */
23917 glyph->right_box_line_p = it->start_of_box_run_p;
23918 glyph->left_box_line_p = it->end_of_box_run_p;
23920 else
23922 glyph->left_box_line_p = it->start_of_box_run_p;
23923 glyph->right_box_line_p = it->end_of_box_run_p;
23925 glyph->overlaps_vertically_p = 0;
23926 glyph->padding_p = 0;
23927 glyph->glyph_not_available_p = 0;
23928 glyph->face_id = it->face_id;
23929 glyph->u.img_id = img->id;
23930 glyph->slice.img = slice;
23931 glyph->font_type = FONT_TYPE_UNKNOWN;
23932 if (it->bidi_p)
23934 glyph->resolved_level = it->bidi_it.resolved_level;
23935 if ((it->bidi_it.type & 7) != it->bidi_it.type)
23936 emacs_abort ();
23937 glyph->bidi_type = it->bidi_it.type;
23939 ++it->glyph_row->used[area];
23941 else
23942 IT_EXPAND_MATRIX_WIDTH (it, area);
23947 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
23948 of the glyph, WIDTH and HEIGHT are the width and height of the
23949 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
23951 static void
23952 append_stretch_glyph (struct it *it, Lisp_Object object,
23953 int width, int height, int ascent)
23955 struct glyph *glyph;
23956 enum glyph_row_area area = it->area;
23958 eassert (ascent >= 0 && ascent <= height);
23960 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
23961 if (glyph < it->glyph_row->glyphs[area + 1])
23963 /* If the glyph row is reversed, we need to prepend the glyph
23964 rather than append it. */
23965 if (it->glyph_row->reversed_p && area == TEXT_AREA)
23967 struct glyph *g;
23969 /* Make room for the additional glyph. */
23970 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
23971 g[1] = *g;
23972 glyph = it->glyph_row->glyphs[area];
23974 glyph->charpos = CHARPOS (it->position);
23975 glyph->object = object;
23976 glyph->pixel_width = width;
23977 glyph->ascent = ascent;
23978 glyph->descent = height - ascent;
23979 glyph->voffset = it->voffset;
23980 glyph->type = STRETCH_GLYPH;
23981 glyph->avoid_cursor_p = it->avoid_cursor_p;
23982 glyph->multibyte_p = it->multibyte_p;
23983 if (it->glyph_row->reversed_p && area == TEXT_AREA)
23985 /* In R2L rows, the left and the right box edges need to be
23986 drawn in reverse direction. */
23987 glyph->right_box_line_p = it->start_of_box_run_p;
23988 glyph->left_box_line_p = it->end_of_box_run_p;
23990 else
23992 glyph->left_box_line_p = it->start_of_box_run_p;
23993 glyph->right_box_line_p = it->end_of_box_run_p;
23995 glyph->overlaps_vertically_p = 0;
23996 glyph->padding_p = 0;
23997 glyph->glyph_not_available_p = 0;
23998 glyph->face_id = it->face_id;
23999 glyph->u.stretch.ascent = ascent;
24000 glyph->u.stretch.height = height;
24001 glyph->slice.img = null_glyph_slice;
24002 glyph->font_type = FONT_TYPE_UNKNOWN;
24003 if (it->bidi_p)
24005 glyph->resolved_level = it->bidi_it.resolved_level;
24006 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24007 emacs_abort ();
24008 glyph->bidi_type = it->bidi_it.type;
24010 else
24012 glyph->resolved_level = 0;
24013 glyph->bidi_type = UNKNOWN_BT;
24015 ++it->glyph_row->used[area];
24017 else
24018 IT_EXPAND_MATRIX_WIDTH (it, area);
24021 #endif /* HAVE_WINDOW_SYSTEM */
24023 /* Produce a stretch glyph for iterator IT. IT->object is the value
24024 of the glyph property displayed. The value must be a list
24025 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
24026 being recognized:
24028 1. `:width WIDTH' specifies that the space should be WIDTH *
24029 canonical char width wide. WIDTH may be an integer or floating
24030 point number.
24032 2. `:relative-width FACTOR' specifies that the width of the stretch
24033 should be computed from the width of the first character having the
24034 `glyph' property, and should be FACTOR times that width.
24036 3. `:align-to HPOS' specifies that the space should be wide enough
24037 to reach HPOS, a value in canonical character units.
24039 Exactly one of the above pairs must be present.
24041 4. `:height HEIGHT' specifies that the height of the stretch produced
24042 should be HEIGHT, measured in canonical character units.
24044 5. `:relative-height FACTOR' specifies that the height of the
24045 stretch should be FACTOR times the height of the characters having
24046 the glyph property.
24048 Either none or exactly one of 4 or 5 must be present.
24050 6. `:ascent ASCENT' specifies that ASCENT percent of the height
24051 of the stretch should be used for the ascent of the stretch.
24052 ASCENT must be in the range 0 <= ASCENT <= 100. */
24054 void
24055 produce_stretch_glyph (struct it *it)
24057 /* (space :width WIDTH :height HEIGHT ...) */
24058 Lisp_Object prop, plist;
24059 int width = 0, height = 0, align_to = -1;
24060 int zero_width_ok_p = 0;
24061 double tem;
24062 struct font *font = NULL;
24064 #ifdef HAVE_WINDOW_SYSTEM
24065 int ascent = 0;
24066 int zero_height_ok_p = 0;
24068 if (FRAME_WINDOW_P (it->f))
24070 struct face *face = FACE_FROM_ID (it->f, it->face_id);
24071 font = face->font ? face->font : FRAME_FONT (it->f);
24072 PREPARE_FACE_FOR_DISPLAY (it->f, face);
24074 #endif
24076 /* List should start with `space'. */
24077 eassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
24078 plist = XCDR (it->object);
24080 /* Compute the width of the stretch. */
24081 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
24082 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
24084 /* Absolute width `:width WIDTH' specified and valid. */
24085 zero_width_ok_p = 1;
24086 width = (int)tem;
24088 #ifdef HAVE_WINDOW_SYSTEM
24089 else if (FRAME_WINDOW_P (it->f)
24090 && (prop = Fplist_get (plist, QCrelative_width), NUMVAL (prop) > 0))
24092 /* Relative width `:relative-width FACTOR' specified and valid.
24093 Compute the width of the characters having the `glyph'
24094 property. */
24095 struct it it2;
24096 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
24098 it2 = *it;
24099 if (it->multibyte_p)
24100 it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
24101 else
24103 it2.c = it2.char_to_display = *p, it2.len = 1;
24104 if (! ASCII_CHAR_P (it2.c))
24105 it2.char_to_display = BYTE8_TO_CHAR (it2.c);
24108 it2.glyph_row = NULL;
24109 it2.what = IT_CHARACTER;
24110 x_produce_glyphs (&it2);
24111 width = NUMVAL (prop) * it2.pixel_width;
24113 #endif /* HAVE_WINDOW_SYSTEM */
24114 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
24115 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
24117 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
24118 align_to = (align_to < 0
24120 : align_to - window_box_left_offset (it->w, TEXT_AREA));
24121 else if (align_to < 0)
24122 align_to = window_box_left_offset (it->w, TEXT_AREA);
24123 width = max (0, (int)tem + align_to - it->current_x);
24124 zero_width_ok_p = 1;
24126 else
24127 /* Nothing specified -> width defaults to canonical char width. */
24128 width = FRAME_COLUMN_WIDTH (it->f);
24130 if (width <= 0 && (width < 0 || !zero_width_ok_p))
24131 width = 1;
24133 #ifdef HAVE_WINDOW_SYSTEM
24134 /* Compute height. */
24135 if (FRAME_WINDOW_P (it->f))
24137 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
24138 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
24140 height = (int)tem;
24141 zero_height_ok_p = 1;
24143 else if (prop = Fplist_get (plist, QCrelative_height),
24144 NUMVAL (prop) > 0)
24145 height = FONT_HEIGHT (font) * NUMVAL (prop);
24146 else
24147 height = FONT_HEIGHT (font);
24149 if (height <= 0 && (height < 0 || !zero_height_ok_p))
24150 height = 1;
24152 /* Compute percentage of height used for ascent. If
24153 `:ascent ASCENT' is present and valid, use that. Otherwise,
24154 derive the ascent from the font in use. */
24155 if (prop = Fplist_get (plist, QCascent),
24156 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
24157 ascent = height * NUMVAL (prop) / 100.0;
24158 else if (!NILP (prop)
24159 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
24160 ascent = min (max (0, (int)tem), height);
24161 else
24162 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
24164 else
24165 #endif /* HAVE_WINDOW_SYSTEM */
24166 height = 1;
24168 if (width > 0 && it->line_wrap != TRUNCATE
24169 && it->current_x + width > it->last_visible_x)
24171 width = it->last_visible_x - it->current_x;
24172 #ifdef HAVE_WINDOW_SYSTEM
24173 /* Subtract one more pixel from the stretch width, but only on
24174 GUI frames, since on a TTY each glyph is one "pixel" wide. */
24175 width -= FRAME_WINDOW_P (it->f);
24176 #endif
24179 if (width > 0 && height > 0 && it->glyph_row)
24181 Lisp_Object o_object = it->object;
24182 Lisp_Object object = it->stack[it->sp - 1].string;
24183 int n = width;
24185 if (!STRINGP (object))
24186 object = it->w->contents;
24187 #ifdef HAVE_WINDOW_SYSTEM
24188 if (FRAME_WINDOW_P (it->f))
24189 append_stretch_glyph (it, object, width, height, ascent);
24190 else
24191 #endif
24193 it->object = object;
24194 it->char_to_display = ' ';
24195 it->pixel_width = it->len = 1;
24196 while (n--)
24197 tty_append_glyph (it);
24198 it->object = o_object;
24202 it->pixel_width = width;
24203 #ifdef HAVE_WINDOW_SYSTEM
24204 if (FRAME_WINDOW_P (it->f))
24206 it->ascent = it->phys_ascent = ascent;
24207 it->descent = it->phys_descent = height - it->ascent;
24208 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
24209 take_vertical_position_into_account (it);
24211 else
24212 #endif
24213 it->nglyphs = width;
24216 /* Get information about special display element WHAT in an
24217 environment described by IT. WHAT is one of IT_TRUNCATION or
24218 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
24219 non-null glyph_row member. This function ensures that fields like
24220 face_id, c, len of IT are left untouched. */
24222 static void
24223 produce_special_glyphs (struct it *it, enum display_element_type what)
24225 struct it temp_it;
24226 Lisp_Object gc;
24227 GLYPH glyph;
24229 temp_it = *it;
24230 temp_it.object = make_number (0);
24231 memset (&temp_it.current, 0, sizeof temp_it.current);
24233 if (what == IT_CONTINUATION)
24235 /* Continuation glyph. For R2L lines, we mirror it by hand. */
24236 if (it->bidi_it.paragraph_dir == R2L)
24237 SET_GLYPH_FROM_CHAR (glyph, '/');
24238 else
24239 SET_GLYPH_FROM_CHAR (glyph, '\\');
24240 if (it->dp
24241 && (gc = DISP_CONTINUE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
24243 /* FIXME: Should we mirror GC for R2L lines? */
24244 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
24245 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
24248 else if (what == IT_TRUNCATION)
24250 /* Truncation glyph. */
24251 SET_GLYPH_FROM_CHAR (glyph, '$');
24252 if (it->dp
24253 && (gc = DISP_TRUNC_GLYPH (it->dp), GLYPH_CODE_P (gc)))
24255 /* FIXME: Should we mirror GC for R2L lines? */
24256 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
24257 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
24260 else
24261 emacs_abort ();
24263 #ifdef HAVE_WINDOW_SYSTEM
24264 /* On a GUI frame, when the right fringe (left fringe for R2L rows)
24265 is turned off, we precede the truncation/continuation glyphs by a
24266 stretch glyph whose width is computed such that these special
24267 glyphs are aligned at the window margin, even when very different
24268 fonts are used in different glyph rows. */
24269 if (FRAME_WINDOW_P (temp_it.f)
24270 /* init_iterator calls this with it->glyph_row == NULL, and it
24271 wants only the pixel width of the truncation/continuation
24272 glyphs. */
24273 && temp_it.glyph_row
24274 /* insert_left_trunc_glyphs calls us at the beginning of the
24275 row, and it has its own calculation of the stretch glyph
24276 width. */
24277 && temp_it.glyph_row->used[TEXT_AREA] > 0
24278 && (temp_it.glyph_row->reversed_p
24279 ? WINDOW_LEFT_FRINGE_WIDTH (temp_it.w)
24280 : WINDOW_RIGHT_FRINGE_WIDTH (temp_it.w)) == 0)
24282 int stretch_width = temp_it.last_visible_x - temp_it.current_x;
24284 if (stretch_width > 0)
24286 struct face *face = FACE_FROM_ID (temp_it.f, temp_it.face_id);
24287 struct font *font =
24288 face->font ? face->font : FRAME_FONT (temp_it.f);
24289 int stretch_ascent =
24290 (((temp_it.ascent + temp_it.descent)
24291 * FONT_BASE (font)) / FONT_HEIGHT (font));
24293 append_stretch_glyph (&temp_it, make_number (0), stretch_width,
24294 temp_it.ascent + temp_it.descent,
24295 stretch_ascent);
24298 #endif
24300 temp_it.dp = NULL;
24301 temp_it.what = IT_CHARACTER;
24302 temp_it.len = 1;
24303 temp_it.c = temp_it.char_to_display = GLYPH_CHAR (glyph);
24304 temp_it.face_id = GLYPH_FACE (glyph);
24305 temp_it.len = CHAR_BYTES (temp_it.c);
24307 PRODUCE_GLYPHS (&temp_it);
24308 it->pixel_width = temp_it.pixel_width;
24309 it->nglyphs = temp_it.pixel_width;
24312 #ifdef HAVE_WINDOW_SYSTEM
24314 /* Calculate line-height and line-spacing properties.
24315 An integer value specifies explicit pixel value.
24316 A float value specifies relative value to current face height.
24317 A cons (float . face-name) specifies relative value to
24318 height of specified face font.
24320 Returns height in pixels, or nil. */
24323 static Lisp_Object
24324 calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
24325 int boff, int override)
24327 Lisp_Object face_name = Qnil;
24328 int ascent, descent, height;
24330 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
24331 return val;
24333 if (CONSP (val))
24335 face_name = XCAR (val);
24336 val = XCDR (val);
24337 if (!NUMBERP (val))
24338 val = make_number (1);
24339 if (NILP (face_name))
24341 height = it->ascent + it->descent;
24342 goto scale;
24346 if (NILP (face_name))
24348 font = FRAME_FONT (it->f);
24349 boff = FRAME_BASELINE_OFFSET (it->f);
24351 else if (EQ (face_name, Qt))
24353 override = 0;
24355 else
24357 int face_id;
24358 struct face *face;
24360 face_id = lookup_named_face (it->f, face_name, 0);
24361 if (face_id < 0)
24362 return make_number (-1);
24364 face = FACE_FROM_ID (it->f, face_id);
24365 font = face->font;
24366 if (font == NULL)
24367 return make_number (-1);
24368 boff = font->baseline_offset;
24369 if (font->vertical_centering)
24370 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
24373 ascent = FONT_BASE (font) + boff;
24374 descent = FONT_DESCENT (font) - boff;
24376 if (override)
24378 it->override_ascent = ascent;
24379 it->override_descent = descent;
24380 it->override_boff = boff;
24383 height = ascent + descent;
24385 scale:
24386 if (FLOATP (val))
24387 height = (int)(XFLOAT_DATA (val) * height);
24388 else if (INTEGERP (val))
24389 height *= XINT (val);
24391 return make_number (height);
24395 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
24396 is a face ID to be used for the glyph. FOR_NO_FONT is nonzero if
24397 and only if this is for a character for which no font was found.
24399 If the display method (it->glyphless_method) is
24400 GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
24401 length of the acronym or the hexadecimal string, UPPER_XOFF and
24402 UPPER_YOFF are pixel offsets for the upper part of the string,
24403 LOWER_XOFF and LOWER_YOFF are for the lower part.
24405 For the other display methods, LEN through LOWER_YOFF are zero. */
24407 static void
24408 append_glyphless_glyph (struct it *it, int face_id, int for_no_font, int len,
24409 short upper_xoff, short upper_yoff,
24410 short lower_xoff, short lower_yoff)
24412 struct glyph *glyph;
24413 enum glyph_row_area area = it->area;
24415 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24416 if (glyph < it->glyph_row->glyphs[area + 1])
24418 /* If the glyph row is reversed, we need to prepend the glyph
24419 rather than append it. */
24420 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24422 struct glyph *g;
24424 /* Make room for the additional glyph. */
24425 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
24426 g[1] = *g;
24427 glyph = it->glyph_row->glyphs[area];
24429 glyph->charpos = CHARPOS (it->position);
24430 glyph->object = it->object;
24431 glyph->pixel_width = it->pixel_width;
24432 glyph->ascent = it->ascent;
24433 glyph->descent = it->descent;
24434 glyph->voffset = it->voffset;
24435 glyph->type = GLYPHLESS_GLYPH;
24436 glyph->u.glyphless.method = it->glyphless_method;
24437 glyph->u.glyphless.for_no_font = for_no_font;
24438 glyph->u.glyphless.len = len;
24439 glyph->u.glyphless.ch = it->c;
24440 glyph->slice.glyphless.upper_xoff = upper_xoff;
24441 glyph->slice.glyphless.upper_yoff = upper_yoff;
24442 glyph->slice.glyphless.lower_xoff = lower_xoff;
24443 glyph->slice.glyphless.lower_yoff = lower_yoff;
24444 glyph->avoid_cursor_p = it->avoid_cursor_p;
24445 glyph->multibyte_p = it->multibyte_p;
24446 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24448 /* In R2L rows, the left and the right box edges need to be
24449 drawn in reverse direction. */
24450 glyph->right_box_line_p = it->start_of_box_run_p;
24451 glyph->left_box_line_p = it->end_of_box_run_p;
24453 else
24455 glyph->left_box_line_p = it->start_of_box_run_p;
24456 glyph->right_box_line_p = it->end_of_box_run_p;
24458 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
24459 || it->phys_descent > it->descent);
24460 glyph->padding_p = 0;
24461 glyph->glyph_not_available_p = 0;
24462 glyph->face_id = face_id;
24463 glyph->font_type = FONT_TYPE_UNKNOWN;
24464 if (it->bidi_p)
24466 glyph->resolved_level = it->bidi_it.resolved_level;
24467 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24468 emacs_abort ();
24469 glyph->bidi_type = it->bidi_it.type;
24471 ++it->glyph_row->used[area];
24473 else
24474 IT_EXPAND_MATRIX_WIDTH (it, area);
24478 /* Produce a glyph for a glyphless character for iterator IT.
24479 IT->glyphless_method specifies which method to use for displaying
24480 the character. See the description of enum
24481 glyphless_display_method in dispextern.h for the detail.
24483 FOR_NO_FONT is nonzero if and only if this is for a character for
24484 which no font was found. ACRONYM, if non-nil, is an acronym string
24485 for the character. */
24487 static void
24488 produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
24490 int face_id;
24491 struct face *face;
24492 struct font *font;
24493 int base_width, base_height, width, height;
24494 short upper_xoff, upper_yoff, lower_xoff, lower_yoff;
24495 int len;
24497 /* Get the metrics of the base font. We always refer to the current
24498 ASCII face. */
24499 face = FACE_FROM_ID (it->f, it->face_id)->ascii_face;
24500 font = face->font ? face->font : FRAME_FONT (it->f);
24501 it->ascent = FONT_BASE (font) + font->baseline_offset;
24502 it->descent = FONT_DESCENT (font) - font->baseline_offset;
24503 base_height = it->ascent + it->descent;
24504 base_width = font->average_width;
24506 /* Get a face ID for the glyph by utilizing a cache (the same way as
24507 done for `escape-glyph' in get_next_display_element). */
24508 if (it->f == last_glyphless_glyph_frame
24509 && it->face_id == last_glyphless_glyph_face_id)
24511 face_id = last_glyphless_glyph_merged_face_id;
24513 else
24515 /* Merge the `glyphless-char' face into the current face. */
24516 face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
24517 last_glyphless_glyph_frame = it->f;
24518 last_glyphless_glyph_face_id = it->face_id;
24519 last_glyphless_glyph_merged_face_id = face_id;
24522 if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
24524 it->pixel_width = THIN_SPACE_WIDTH;
24525 len = 0;
24526 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
24528 else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX)
24530 width = CHAR_WIDTH (it->c);
24531 if (width == 0)
24532 width = 1;
24533 else if (width > 4)
24534 width = 4;
24535 it->pixel_width = base_width * width;
24536 len = 0;
24537 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
24539 else
24541 char buf[7];
24542 const char *str;
24543 unsigned int code[6];
24544 int upper_len;
24545 int ascent, descent;
24546 struct font_metrics metrics_upper, metrics_lower;
24548 face = FACE_FROM_ID (it->f, face_id);
24549 font = face->font ? face->font : FRAME_FONT (it->f);
24550 PREPARE_FACE_FOR_DISPLAY (it->f, face);
24552 if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM)
24554 if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
24555 acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
24556 if (CONSP (acronym))
24557 acronym = XCAR (acronym);
24558 str = STRINGP (acronym) ? SSDATA (acronym) : "";
24560 else
24562 eassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
24563 sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c);
24564 str = buf;
24566 for (len = 0; str[len] && ASCII_BYTE_P (str[len]) && len < 6; len++)
24567 code[len] = font->driver->encode_char (font, str[len]);
24568 upper_len = (len + 1) / 2;
24569 font->driver->text_extents (font, code, upper_len,
24570 &metrics_upper);
24571 font->driver->text_extents (font, code + upper_len, len - upper_len,
24572 &metrics_lower);
24576 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
24577 width = max (metrics_upper.width, metrics_lower.width) + 4;
24578 upper_xoff = upper_yoff = 2; /* the typical case */
24579 if (base_width >= width)
24581 /* Align the upper to the left, the lower to the right. */
24582 it->pixel_width = base_width;
24583 lower_xoff = base_width - 2 - metrics_lower.width;
24585 else
24587 /* Center the shorter one. */
24588 it->pixel_width = width;
24589 if (metrics_upper.width >= metrics_lower.width)
24590 lower_xoff = (width - metrics_lower.width) / 2;
24591 else
24593 /* FIXME: This code doesn't look right. It formerly was
24594 missing the "lower_xoff = 0;", which couldn't have
24595 been right since it left lower_xoff uninitialized. */
24596 lower_xoff = 0;
24597 upper_xoff = (width - metrics_upper.width) / 2;
24601 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
24602 top, bottom, and between upper and lower strings. */
24603 height = (metrics_upper.ascent + metrics_upper.descent
24604 + metrics_lower.ascent + metrics_lower.descent) + 5;
24605 /* Center vertically.
24606 H:base_height, D:base_descent
24607 h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent
24609 ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up
24610 descent = D - H/2 + h/2;
24611 lower_yoff = descent - 2 - ld;
24612 upper_yoff = lower_yoff - la - 1 - ud; */
24613 ascent = - (it->descent - (base_height + height + 1) / 2);
24614 descent = it->descent - (base_height - height) / 2;
24615 lower_yoff = descent - 2 - metrics_lower.descent;
24616 upper_yoff = (lower_yoff - metrics_lower.ascent - 1
24617 - metrics_upper.descent);
24618 /* Don't make the height shorter than the base height. */
24619 if (height > base_height)
24621 it->ascent = ascent;
24622 it->descent = descent;
24626 it->phys_ascent = it->ascent;
24627 it->phys_descent = it->descent;
24628 if (it->glyph_row)
24629 append_glyphless_glyph (it, face_id, for_no_font, len,
24630 upper_xoff, upper_yoff,
24631 lower_xoff, lower_yoff);
24632 it->nglyphs = 1;
24633 take_vertical_position_into_account (it);
24637 /* RIF:
24638 Produce glyphs/get display metrics for the display element IT is
24639 loaded with. See the description of struct it in dispextern.h
24640 for an overview of struct it. */
24642 void
24643 x_produce_glyphs (struct it *it)
24645 int extra_line_spacing = it->extra_line_spacing;
24647 it->glyph_not_available_p = 0;
24649 if (it->what == IT_CHARACTER)
24651 XChar2b char2b;
24652 struct face *face = FACE_FROM_ID (it->f, it->face_id);
24653 struct font *font = face->font;
24654 struct font_metrics *pcm = NULL;
24655 int boff; /* baseline offset */
24657 if (font == NULL)
24659 /* When no suitable font is found, display this character by
24660 the method specified in the first extra slot of
24661 Vglyphless_char_display. */
24662 Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
24664 eassert (it->what == IT_GLYPHLESS);
24665 produce_glyphless_glyph (it, 1, STRINGP (acronym) ? acronym : Qnil);
24666 goto done;
24669 boff = font->baseline_offset;
24670 if (font->vertical_centering)
24671 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
24673 if (it->char_to_display != '\n' && it->char_to_display != '\t')
24675 int stretched_p;
24677 it->nglyphs = 1;
24679 if (it->override_ascent >= 0)
24681 it->ascent = it->override_ascent;
24682 it->descent = it->override_descent;
24683 boff = it->override_boff;
24685 else
24687 it->ascent = FONT_BASE (font) + boff;
24688 it->descent = FONT_DESCENT (font) - boff;
24691 if (get_char_glyph_code (it->char_to_display, font, &char2b))
24693 pcm = get_per_char_metric (font, &char2b);
24694 if (pcm->width == 0
24695 && pcm->rbearing == 0 && pcm->lbearing == 0)
24696 pcm = NULL;
24699 if (pcm)
24701 it->phys_ascent = pcm->ascent + boff;
24702 it->phys_descent = pcm->descent - boff;
24703 it->pixel_width = pcm->width;
24705 else
24707 it->glyph_not_available_p = 1;
24708 it->phys_ascent = it->ascent;
24709 it->phys_descent = it->descent;
24710 it->pixel_width = font->space_width;
24713 if (it->constrain_row_ascent_descent_p)
24715 if (it->descent > it->max_descent)
24717 it->ascent += it->descent - it->max_descent;
24718 it->descent = it->max_descent;
24720 if (it->ascent > it->max_ascent)
24722 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
24723 it->ascent = it->max_ascent;
24725 it->phys_ascent = min (it->phys_ascent, it->ascent);
24726 it->phys_descent = min (it->phys_descent, it->descent);
24727 extra_line_spacing = 0;
24730 /* If this is a space inside a region of text with
24731 `space-width' property, change its width. */
24732 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
24733 if (stretched_p)
24734 it->pixel_width *= XFLOATINT (it->space_width);
24736 /* If face has a box, add the box thickness to the character
24737 height. If character has a box line to the left and/or
24738 right, add the box line width to the character's width. */
24739 if (face->box != FACE_NO_BOX)
24741 int thick = face->box_line_width;
24743 if (thick > 0)
24745 it->ascent += thick;
24746 it->descent += thick;
24748 else
24749 thick = -thick;
24751 if (it->start_of_box_run_p)
24752 it->pixel_width += thick;
24753 if (it->end_of_box_run_p)
24754 it->pixel_width += thick;
24757 /* If face has an overline, add the height of the overline
24758 (1 pixel) and a 1 pixel margin to the character height. */
24759 if (face->overline_p)
24760 it->ascent += overline_margin;
24762 if (it->constrain_row_ascent_descent_p)
24764 if (it->ascent > it->max_ascent)
24765 it->ascent = it->max_ascent;
24766 if (it->descent > it->max_descent)
24767 it->descent = it->max_descent;
24770 take_vertical_position_into_account (it);
24772 /* If we have to actually produce glyphs, do it. */
24773 if (it->glyph_row)
24775 if (stretched_p)
24777 /* Translate a space with a `space-width' property
24778 into a stretch glyph. */
24779 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
24780 / FONT_HEIGHT (font));
24781 append_stretch_glyph (it, it->object, it->pixel_width,
24782 it->ascent + it->descent, ascent);
24784 else
24785 append_glyph (it);
24787 /* If characters with lbearing or rbearing are displayed
24788 in this line, record that fact in a flag of the
24789 glyph row. This is used to optimize X output code. */
24790 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
24791 it->glyph_row->contains_overlapping_glyphs_p = 1;
24793 if (! stretched_p && it->pixel_width == 0)
24794 /* We assure that all visible glyphs have at least 1-pixel
24795 width. */
24796 it->pixel_width = 1;
24798 else if (it->char_to_display == '\n')
24800 /* A newline has no width, but we need the height of the
24801 line. But if previous part of the line sets a height,
24802 don't increase that height */
24804 Lisp_Object height;
24805 Lisp_Object total_height = Qnil;
24807 it->override_ascent = -1;
24808 it->pixel_width = 0;
24809 it->nglyphs = 0;
24811 height = get_it_property (it, Qline_height);
24812 /* Split (line-height total-height) list */
24813 if (CONSP (height)
24814 && CONSP (XCDR (height))
24815 && NILP (XCDR (XCDR (height))))
24817 total_height = XCAR (XCDR (height));
24818 height = XCAR (height);
24820 height = calc_line_height_property (it, height, font, boff, 1);
24822 if (it->override_ascent >= 0)
24824 it->ascent = it->override_ascent;
24825 it->descent = it->override_descent;
24826 boff = it->override_boff;
24828 else
24830 it->ascent = FONT_BASE (font) + boff;
24831 it->descent = FONT_DESCENT (font) - boff;
24834 if (EQ (height, Qt))
24836 if (it->descent > it->max_descent)
24838 it->ascent += it->descent - it->max_descent;
24839 it->descent = it->max_descent;
24841 if (it->ascent > it->max_ascent)
24843 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
24844 it->ascent = it->max_ascent;
24846 it->phys_ascent = min (it->phys_ascent, it->ascent);
24847 it->phys_descent = min (it->phys_descent, it->descent);
24848 it->constrain_row_ascent_descent_p = 1;
24849 extra_line_spacing = 0;
24851 else
24853 Lisp_Object spacing;
24855 it->phys_ascent = it->ascent;
24856 it->phys_descent = it->descent;
24858 if ((it->max_ascent > 0 || it->max_descent > 0)
24859 && face->box != FACE_NO_BOX
24860 && face->box_line_width > 0)
24862 it->ascent += face->box_line_width;
24863 it->descent += face->box_line_width;
24865 if (!NILP (height)
24866 && XINT (height) > it->ascent + it->descent)
24867 it->ascent = XINT (height) - it->descent;
24869 if (!NILP (total_height))
24870 spacing = calc_line_height_property (it, total_height, font, boff, 0);
24871 else
24873 spacing = get_it_property (it, Qline_spacing);
24874 spacing = calc_line_height_property (it, spacing, font, boff, 0);
24876 if (INTEGERP (spacing))
24878 extra_line_spacing = XINT (spacing);
24879 if (!NILP (total_height))
24880 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
24884 else /* i.e. (it->char_to_display == '\t') */
24886 if (font->space_width > 0)
24888 int tab_width = it->tab_width * font->space_width;
24889 int x = it->current_x + it->continuation_lines_width;
24890 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
24892 /* If the distance from the current position to the next tab
24893 stop is less than a space character width, use the
24894 tab stop after that. */
24895 if (next_tab_x - x < font->space_width)
24896 next_tab_x += tab_width;
24898 it->pixel_width = next_tab_x - x;
24899 it->nglyphs = 1;
24900 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
24901 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
24903 if (it->glyph_row)
24905 append_stretch_glyph (it, it->object, it->pixel_width,
24906 it->ascent + it->descent, it->ascent);
24909 else
24911 it->pixel_width = 0;
24912 it->nglyphs = 1;
24916 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
24918 /* A static composition.
24920 Note: A composition is represented as one glyph in the
24921 glyph matrix. There are no padding glyphs.
24923 Important note: pixel_width, ascent, and descent are the
24924 values of what is drawn by draw_glyphs (i.e. the values of
24925 the overall glyphs composed). */
24926 struct face *face = FACE_FROM_ID (it->f, it->face_id);
24927 int boff; /* baseline offset */
24928 struct composition *cmp = composition_table[it->cmp_it.id];
24929 int glyph_len = cmp->glyph_len;
24930 struct font *font = face->font;
24932 it->nglyphs = 1;
24934 /* If we have not yet calculated pixel size data of glyphs of
24935 the composition for the current face font, calculate them
24936 now. Theoretically, we have to check all fonts for the
24937 glyphs, but that requires much time and memory space. So,
24938 here we check only the font of the first glyph. This may
24939 lead to incorrect display, but it's very rare, and C-l
24940 (recenter-top-bottom) can correct the display anyway. */
24941 if (! cmp->font || cmp->font != font)
24943 /* Ascent and descent of the font of the first character
24944 of this composition (adjusted by baseline offset).
24945 Ascent and descent of overall glyphs should not be less
24946 than these, respectively. */
24947 int font_ascent, font_descent, font_height;
24948 /* Bounding box of the overall glyphs. */
24949 int leftmost, rightmost, lowest, highest;
24950 int lbearing, rbearing;
24951 int i, width, ascent, descent;
24952 int left_padded = 0, right_padded = 0;
24953 int c IF_LINT (= 0); /* cmp->glyph_len can't be zero; see Bug#8512 */
24954 XChar2b char2b;
24955 struct font_metrics *pcm;
24956 int font_not_found_p;
24957 ptrdiff_t pos;
24959 for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
24960 if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
24961 break;
24962 if (glyph_len < cmp->glyph_len)
24963 right_padded = 1;
24964 for (i = 0; i < glyph_len; i++)
24966 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
24967 break;
24968 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
24970 if (i > 0)
24971 left_padded = 1;
24973 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
24974 : IT_CHARPOS (*it));
24975 /* If no suitable font is found, use the default font. */
24976 font_not_found_p = font == NULL;
24977 if (font_not_found_p)
24979 face = face->ascii_face;
24980 font = face->font;
24982 boff = font->baseline_offset;
24983 if (font->vertical_centering)
24984 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
24985 font_ascent = FONT_BASE (font) + boff;
24986 font_descent = FONT_DESCENT (font) - boff;
24987 font_height = FONT_HEIGHT (font);
24989 cmp->font = font;
24991 pcm = NULL;
24992 if (! font_not_found_p)
24994 get_char_face_and_encoding (it->f, c, it->face_id,
24995 &char2b, 0);
24996 pcm = get_per_char_metric (font, &char2b);
24999 /* Initialize the bounding box. */
25000 if (pcm)
25002 width = cmp->glyph_len > 0 ? pcm->width : 0;
25003 ascent = pcm->ascent;
25004 descent = pcm->descent;
25005 lbearing = pcm->lbearing;
25006 rbearing = pcm->rbearing;
25008 else
25010 width = cmp->glyph_len > 0 ? font->space_width : 0;
25011 ascent = FONT_BASE (font);
25012 descent = FONT_DESCENT (font);
25013 lbearing = 0;
25014 rbearing = width;
25017 rightmost = width;
25018 leftmost = 0;
25019 lowest = - descent + boff;
25020 highest = ascent + boff;
25022 if (! font_not_found_p
25023 && font->default_ascent
25024 && CHAR_TABLE_P (Vuse_default_ascent)
25025 && !NILP (Faref (Vuse_default_ascent,
25026 make_number (it->char_to_display))))
25027 highest = font->default_ascent + boff;
25029 /* Draw the first glyph at the normal position. It may be
25030 shifted to right later if some other glyphs are drawn
25031 at the left. */
25032 cmp->offsets[i * 2] = 0;
25033 cmp->offsets[i * 2 + 1] = boff;
25034 cmp->lbearing = lbearing;
25035 cmp->rbearing = rbearing;
25037 /* Set cmp->offsets for the remaining glyphs. */
25038 for (i++; i < glyph_len; i++)
25040 int left, right, btm, top;
25041 int ch = COMPOSITION_GLYPH (cmp, i);
25042 int face_id;
25043 struct face *this_face;
25045 if (ch == '\t')
25046 ch = ' ';
25047 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
25048 this_face = FACE_FROM_ID (it->f, face_id);
25049 font = this_face->font;
25051 if (font == NULL)
25052 pcm = NULL;
25053 else
25055 get_char_face_and_encoding (it->f, ch, face_id,
25056 &char2b, 0);
25057 pcm = get_per_char_metric (font, &char2b);
25059 if (! pcm)
25060 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
25061 else
25063 width = pcm->width;
25064 ascent = pcm->ascent;
25065 descent = pcm->descent;
25066 lbearing = pcm->lbearing;
25067 rbearing = pcm->rbearing;
25068 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
25070 /* Relative composition with or without
25071 alternate chars. */
25072 left = (leftmost + rightmost - width) / 2;
25073 btm = - descent + boff;
25074 if (font->relative_compose
25075 && (! CHAR_TABLE_P (Vignore_relative_composition)
25076 || NILP (Faref (Vignore_relative_composition,
25077 make_number (ch)))))
25080 if (- descent >= font->relative_compose)
25081 /* One extra pixel between two glyphs. */
25082 btm = highest + 1;
25083 else if (ascent <= 0)
25084 /* One extra pixel between two glyphs. */
25085 btm = lowest - 1 - ascent - descent;
25088 else
25090 /* A composition rule is specified by an integer
25091 value that encodes global and new reference
25092 points (GREF and NREF). GREF and NREF are
25093 specified by numbers as below:
25095 0---1---2 -- ascent
25099 9--10--11 -- center
25101 ---3---4---5--- baseline
25103 6---7---8 -- descent
25105 int rule = COMPOSITION_RULE (cmp, i);
25106 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
25108 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
25109 grefx = gref % 3, nrefx = nref % 3;
25110 grefy = gref / 3, nrefy = nref / 3;
25111 if (xoff)
25112 xoff = font_height * (xoff - 128) / 256;
25113 if (yoff)
25114 yoff = font_height * (yoff - 128) / 256;
25116 left = (leftmost
25117 + grefx * (rightmost - leftmost) / 2
25118 - nrefx * width / 2
25119 + xoff);
25121 btm = ((grefy == 0 ? highest
25122 : grefy == 1 ? 0
25123 : grefy == 2 ? lowest
25124 : (highest + lowest) / 2)
25125 - (nrefy == 0 ? ascent + descent
25126 : nrefy == 1 ? descent - boff
25127 : nrefy == 2 ? 0
25128 : (ascent + descent) / 2)
25129 + yoff);
25132 cmp->offsets[i * 2] = left;
25133 cmp->offsets[i * 2 + 1] = btm + descent;
25135 /* Update the bounding box of the overall glyphs. */
25136 if (width > 0)
25138 right = left + width;
25139 if (left < leftmost)
25140 leftmost = left;
25141 if (right > rightmost)
25142 rightmost = right;
25144 top = btm + descent + ascent;
25145 if (top > highest)
25146 highest = top;
25147 if (btm < lowest)
25148 lowest = btm;
25150 if (cmp->lbearing > left + lbearing)
25151 cmp->lbearing = left + lbearing;
25152 if (cmp->rbearing < left + rbearing)
25153 cmp->rbearing = left + rbearing;
25157 /* If there are glyphs whose x-offsets are negative,
25158 shift all glyphs to the right and make all x-offsets
25159 non-negative. */
25160 if (leftmost < 0)
25162 for (i = 0; i < cmp->glyph_len; i++)
25163 cmp->offsets[i * 2] -= leftmost;
25164 rightmost -= leftmost;
25165 cmp->lbearing -= leftmost;
25166 cmp->rbearing -= leftmost;
25169 if (left_padded && cmp->lbearing < 0)
25171 for (i = 0; i < cmp->glyph_len; i++)
25172 cmp->offsets[i * 2] -= cmp->lbearing;
25173 rightmost -= cmp->lbearing;
25174 cmp->rbearing -= cmp->lbearing;
25175 cmp->lbearing = 0;
25177 if (right_padded && rightmost < cmp->rbearing)
25179 rightmost = cmp->rbearing;
25182 cmp->pixel_width = rightmost;
25183 cmp->ascent = highest;
25184 cmp->descent = - lowest;
25185 if (cmp->ascent < font_ascent)
25186 cmp->ascent = font_ascent;
25187 if (cmp->descent < font_descent)
25188 cmp->descent = font_descent;
25191 if (it->glyph_row
25192 && (cmp->lbearing < 0
25193 || cmp->rbearing > cmp->pixel_width))
25194 it->glyph_row->contains_overlapping_glyphs_p = 1;
25196 it->pixel_width = cmp->pixel_width;
25197 it->ascent = it->phys_ascent = cmp->ascent;
25198 it->descent = it->phys_descent = cmp->descent;
25199 if (face->box != FACE_NO_BOX)
25201 int thick = face->box_line_width;
25203 if (thick > 0)
25205 it->ascent += thick;
25206 it->descent += thick;
25208 else
25209 thick = - thick;
25211 if (it->start_of_box_run_p)
25212 it->pixel_width += thick;
25213 if (it->end_of_box_run_p)
25214 it->pixel_width += thick;
25217 /* If face has an overline, add the height of the overline
25218 (1 pixel) and a 1 pixel margin to the character height. */
25219 if (face->overline_p)
25220 it->ascent += overline_margin;
25222 take_vertical_position_into_account (it);
25223 if (it->ascent < 0)
25224 it->ascent = 0;
25225 if (it->descent < 0)
25226 it->descent = 0;
25228 if (it->glyph_row && cmp->glyph_len > 0)
25229 append_composite_glyph (it);
25231 else if (it->what == IT_COMPOSITION)
25233 /* A dynamic (automatic) composition. */
25234 struct face *face = FACE_FROM_ID (it->f, it->face_id);
25235 Lisp_Object gstring;
25236 struct font_metrics metrics;
25238 it->nglyphs = 1;
25240 gstring = composition_gstring_from_id (it->cmp_it.id);
25241 it->pixel_width
25242 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
25243 &metrics);
25244 if (it->glyph_row
25245 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
25246 it->glyph_row->contains_overlapping_glyphs_p = 1;
25247 it->ascent = it->phys_ascent = metrics.ascent;
25248 it->descent = it->phys_descent = metrics.descent;
25249 if (face->box != FACE_NO_BOX)
25251 int thick = face->box_line_width;
25253 if (thick > 0)
25255 it->ascent += thick;
25256 it->descent += thick;
25258 else
25259 thick = - thick;
25261 if (it->start_of_box_run_p)
25262 it->pixel_width += thick;
25263 if (it->end_of_box_run_p)
25264 it->pixel_width += thick;
25266 /* If face has an overline, add the height of the overline
25267 (1 pixel) and a 1 pixel margin to the character height. */
25268 if (face->overline_p)
25269 it->ascent += overline_margin;
25270 take_vertical_position_into_account (it);
25271 if (it->ascent < 0)
25272 it->ascent = 0;
25273 if (it->descent < 0)
25274 it->descent = 0;
25276 if (it->glyph_row)
25277 append_composite_glyph (it);
25279 else if (it->what == IT_GLYPHLESS)
25280 produce_glyphless_glyph (it, 0, Qnil);
25281 else if (it->what == IT_IMAGE)
25282 produce_image_glyph (it);
25283 else if (it->what == IT_STRETCH)
25284 produce_stretch_glyph (it);
25286 done:
25287 /* Accumulate dimensions. Note: can't assume that it->descent > 0
25288 because this isn't true for images with `:ascent 100'. */
25289 eassert (it->ascent >= 0 && it->descent >= 0);
25290 if (it->area == TEXT_AREA)
25291 it->current_x += it->pixel_width;
25293 if (extra_line_spacing > 0)
25295 it->descent += extra_line_spacing;
25296 if (extra_line_spacing > it->max_extra_line_spacing)
25297 it->max_extra_line_spacing = extra_line_spacing;
25300 it->max_ascent = max (it->max_ascent, it->ascent);
25301 it->max_descent = max (it->max_descent, it->descent);
25302 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
25303 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
25306 /* EXPORT for RIF:
25307 Output LEN glyphs starting at START at the nominal cursor position.
25308 Advance the nominal cursor over the text. The global variable
25309 updated_window contains the window being updated, updated_row is
25310 the glyph row being updated, and updated_area is the area of that
25311 row being updated. */
25313 void
25314 x_write_glyphs (struct glyph *start, int len)
25316 int x, hpos, chpos = updated_window->phys_cursor.hpos;
25318 eassert (updated_window && updated_row);
25319 /* When the window is hscrolled, cursor hpos can legitimately be out
25320 of bounds, but we draw the cursor at the corresponding window
25321 margin in that case. */
25322 if (!updated_row->reversed_p && chpos < 0)
25323 chpos = 0;
25324 if (updated_row->reversed_p && chpos >= updated_row->used[TEXT_AREA])
25325 chpos = updated_row->used[TEXT_AREA] - 1;
25327 block_input ();
25329 /* Write glyphs. */
25331 hpos = start - updated_row->glyphs[updated_area];
25332 x = draw_glyphs (updated_window, output_cursor.x,
25333 updated_row, updated_area,
25334 hpos, hpos + len,
25335 DRAW_NORMAL_TEXT, 0);
25337 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
25338 if (updated_area == TEXT_AREA
25339 && updated_window->phys_cursor_on_p
25340 && updated_window->phys_cursor.vpos == output_cursor.vpos
25341 && chpos >= hpos
25342 && chpos < hpos + len)
25343 updated_window->phys_cursor_on_p = 0;
25345 unblock_input ();
25347 /* Advance the output cursor. */
25348 output_cursor.hpos += len;
25349 output_cursor.x = x;
25353 /* EXPORT for RIF:
25354 Insert LEN glyphs from START at the nominal cursor position. */
25356 void
25357 x_insert_glyphs (struct glyph *start, int len)
25359 struct frame *f;
25360 struct window *w;
25361 int line_height, shift_by_width, shifted_region_width;
25362 struct glyph_row *row;
25363 struct glyph *glyph;
25364 int frame_x, frame_y;
25365 ptrdiff_t hpos;
25367 eassert (updated_window && updated_row);
25368 block_input ();
25369 w = updated_window;
25370 f = XFRAME (WINDOW_FRAME (w));
25372 /* Get the height of the line we are in. */
25373 row = updated_row;
25374 line_height = row->height;
25376 /* Get the width of the glyphs to insert. */
25377 shift_by_width = 0;
25378 for (glyph = start; glyph < start + len; ++glyph)
25379 shift_by_width += glyph->pixel_width;
25381 /* Get the width of the region to shift right. */
25382 shifted_region_width = (window_box_width (w, updated_area)
25383 - output_cursor.x
25384 - shift_by_width);
25386 /* Shift right. */
25387 frame_x = window_box_left (w, updated_area) + output_cursor.x;
25388 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
25390 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
25391 line_height, shift_by_width);
25393 /* Write the glyphs. */
25394 hpos = start - row->glyphs[updated_area];
25395 draw_glyphs (w, output_cursor.x, row, updated_area,
25396 hpos, hpos + len,
25397 DRAW_NORMAL_TEXT, 0);
25399 /* Advance the output cursor. */
25400 output_cursor.hpos += len;
25401 output_cursor.x += shift_by_width;
25402 unblock_input ();
25406 /* EXPORT for RIF:
25407 Erase the current text line from the nominal cursor position
25408 (inclusive) to pixel column TO_X (exclusive). The idea is that
25409 everything from TO_X onward is already erased.
25411 TO_X is a pixel position relative to updated_area of
25412 updated_window. TO_X == -1 means clear to the end of this area. */
25414 void
25415 x_clear_end_of_line (int to_x)
25417 struct frame *f;
25418 struct window *w = updated_window;
25419 int max_x, min_y, max_y;
25420 int from_x, from_y, to_y;
25422 eassert (updated_window && updated_row);
25423 f = XFRAME (w->frame);
25425 if (updated_row->full_width_p)
25426 max_x = WINDOW_TOTAL_WIDTH (w);
25427 else
25428 max_x = window_box_width (w, updated_area);
25429 max_y = window_text_bottom_y (w);
25431 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
25432 of window. For TO_X > 0, truncate to end of drawing area. */
25433 if (to_x == 0)
25434 return;
25435 else if (to_x < 0)
25436 to_x = max_x;
25437 else
25438 to_x = min (to_x, max_x);
25440 to_y = min (max_y, output_cursor.y + updated_row->height);
25442 /* Notice if the cursor will be cleared by this operation. */
25443 if (!updated_row->full_width_p)
25444 notice_overwritten_cursor (w, updated_area,
25445 output_cursor.x, -1,
25446 updated_row->y,
25447 MATRIX_ROW_BOTTOM_Y (updated_row));
25449 from_x = output_cursor.x;
25451 /* Translate to frame coordinates. */
25452 if (updated_row->full_width_p)
25454 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
25455 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
25457 else
25459 int area_left = window_box_left (w, updated_area);
25460 from_x += area_left;
25461 to_x += area_left;
25464 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
25465 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
25466 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
25468 /* Prevent inadvertently clearing to end of the X window. */
25469 if (to_x > from_x && to_y > from_y)
25471 block_input ();
25472 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
25473 to_x - from_x, to_y - from_y);
25474 unblock_input ();
25478 #endif /* HAVE_WINDOW_SYSTEM */
25482 /***********************************************************************
25483 Cursor types
25484 ***********************************************************************/
25486 /* Value is the internal representation of the specified cursor type
25487 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
25488 of the bar cursor. */
25490 static enum text_cursor_kinds
25491 get_specified_cursor_type (Lisp_Object arg, int *width)
25493 enum text_cursor_kinds type;
25495 if (NILP (arg))
25496 return NO_CURSOR;
25498 if (EQ (arg, Qbox))
25499 return FILLED_BOX_CURSOR;
25501 if (EQ (arg, Qhollow))
25502 return HOLLOW_BOX_CURSOR;
25504 if (EQ (arg, Qbar))
25506 *width = 2;
25507 return BAR_CURSOR;
25510 if (CONSP (arg)
25511 && EQ (XCAR (arg), Qbar)
25512 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
25514 *width = XINT (XCDR (arg));
25515 return BAR_CURSOR;
25518 if (EQ (arg, Qhbar))
25520 *width = 2;
25521 return HBAR_CURSOR;
25524 if (CONSP (arg)
25525 && EQ (XCAR (arg), Qhbar)
25526 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
25528 *width = XINT (XCDR (arg));
25529 return HBAR_CURSOR;
25532 /* Treat anything unknown as "hollow box cursor".
25533 It was bad to signal an error; people have trouble fixing
25534 .Xdefaults with Emacs, when it has something bad in it. */
25535 type = HOLLOW_BOX_CURSOR;
25537 return type;
25540 /* Set the default cursor types for specified frame. */
25541 void
25542 set_frame_cursor_types (struct frame *f, Lisp_Object arg)
25544 int width = 1;
25545 Lisp_Object tem;
25547 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
25548 FRAME_CURSOR_WIDTH (f) = width;
25550 /* By default, set up the blink-off state depending on the on-state. */
25552 tem = Fassoc (arg, Vblink_cursor_alist);
25553 if (!NILP (tem))
25555 FRAME_BLINK_OFF_CURSOR (f)
25556 = get_specified_cursor_type (XCDR (tem), &width);
25557 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
25559 else
25560 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
25564 #ifdef HAVE_WINDOW_SYSTEM
25566 /* Return the cursor we want to be displayed in window W. Return
25567 width of bar/hbar cursor through WIDTH arg. Return with
25568 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
25569 (i.e. if the `system caret' should track this cursor).
25571 In a mini-buffer window, we want the cursor only to appear if we
25572 are reading input from this window. For the selected window, we
25573 want the cursor type given by the frame parameter or buffer local
25574 setting of cursor-type. If explicitly marked off, draw no cursor.
25575 In all other cases, we want a hollow box cursor. */
25577 static enum text_cursor_kinds
25578 get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
25579 int *active_cursor)
25581 struct frame *f = XFRAME (w->frame);
25582 struct buffer *b = XBUFFER (w->contents);
25583 int cursor_type = DEFAULT_CURSOR;
25584 Lisp_Object alt_cursor;
25585 int non_selected = 0;
25587 *active_cursor = 1;
25589 /* Echo area */
25590 if (cursor_in_echo_area
25591 && FRAME_HAS_MINIBUF_P (f)
25592 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
25594 if (w == XWINDOW (echo_area_window))
25596 if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
25598 *width = FRAME_CURSOR_WIDTH (f);
25599 return FRAME_DESIRED_CURSOR (f);
25601 else
25602 return get_specified_cursor_type (BVAR (b, cursor_type), width);
25605 *active_cursor = 0;
25606 non_selected = 1;
25609 /* Detect a nonselected window or nonselected frame. */
25610 else if (w != XWINDOW (f->selected_window)
25611 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame)
25613 *active_cursor = 0;
25615 if (MINI_WINDOW_P (w) && minibuf_level == 0)
25616 return NO_CURSOR;
25618 non_selected = 1;
25621 /* Never display a cursor in a window in which cursor-type is nil. */
25622 if (NILP (BVAR (b, cursor_type)))
25623 return NO_CURSOR;
25625 /* Get the normal cursor type for this window. */
25626 if (EQ (BVAR (b, cursor_type), Qt))
25628 cursor_type = FRAME_DESIRED_CURSOR (f);
25629 *width = FRAME_CURSOR_WIDTH (f);
25631 else
25632 cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
25634 /* Use cursor-in-non-selected-windows instead
25635 for non-selected window or frame. */
25636 if (non_selected)
25638 alt_cursor = BVAR (b, cursor_in_non_selected_windows);
25639 if (!EQ (Qt, alt_cursor))
25640 return get_specified_cursor_type (alt_cursor, width);
25641 /* t means modify the normal cursor type. */
25642 if (cursor_type == FILLED_BOX_CURSOR)
25643 cursor_type = HOLLOW_BOX_CURSOR;
25644 else if (cursor_type == BAR_CURSOR && *width > 1)
25645 --*width;
25646 return cursor_type;
25649 /* Use normal cursor if not blinked off. */
25650 if (!w->cursor_off_p)
25652 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
25654 if (cursor_type == FILLED_BOX_CURSOR)
25656 /* Using a block cursor on large images can be very annoying.
25657 So use a hollow cursor for "large" images.
25658 If image is not transparent (no mask), also use hollow cursor. */
25659 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
25660 if (img != NULL && IMAGEP (img->spec))
25662 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
25663 where N = size of default frame font size.
25664 This should cover most of the "tiny" icons people may use. */
25665 if (!img->mask
25666 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
25667 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
25668 cursor_type = HOLLOW_BOX_CURSOR;
25671 else if (cursor_type != NO_CURSOR)
25673 /* Display current only supports BOX and HOLLOW cursors for images.
25674 So for now, unconditionally use a HOLLOW cursor when cursor is
25675 not a solid box cursor. */
25676 cursor_type = HOLLOW_BOX_CURSOR;
25679 return cursor_type;
25682 /* Cursor is blinked off, so determine how to "toggle" it. */
25684 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
25685 if ((alt_cursor = Fassoc (BVAR (b, cursor_type), Vblink_cursor_alist), !NILP (alt_cursor)))
25686 return get_specified_cursor_type (XCDR (alt_cursor), width);
25688 /* Then see if frame has specified a specific blink off cursor type. */
25689 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
25691 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
25692 return FRAME_BLINK_OFF_CURSOR (f);
25695 #if 0
25696 /* Some people liked having a permanently visible blinking cursor,
25697 while others had very strong opinions against it. So it was
25698 decided to remove it. KFS 2003-09-03 */
25700 /* Finally perform built-in cursor blinking:
25701 filled box <-> hollow box
25702 wide [h]bar <-> narrow [h]bar
25703 narrow [h]bar <-> no cursor
25704 other type <-> no cursor */
25706 if (cursor_type == FILLED_BOX_CURSOR)
25707 return HOLLOW_BOX_CURSOR;
25709 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
25711 *width = 1;
25712 return cursor_type;
25714 #endif
25716 return NO_CURSOR;
25720 /* Notice when the text cursor of window W has been completely
25721 overwritten by a drawing operation that outputs glyphs in AREA
25722 starting at X0 and ending at X1 in the line starting at Y0 and
25723 ending at Y1. X coordinates are area-relative. X1 < 0 means all
25724 the rest of the line after X0 has been written. Y coordinates
25725 are window-relative. */
25727 static void
25728 notice_overwritten_cursor (struct window *w, enum glyph_row_area area,
25729 int x0, int x1, int y0, int y1)
25731 int cx0, cx1, cy0, cy1;
25732 struct glyph_row *row;
25734 if (!w->phys_cursor_on_p)
25735 return;
25736 if (area != TEXT_AREA)
25737 return;
25739 if (w->phys_cursor.vpos < 0
25740 || w->phys_cursor.vpos >= w->current_matrix->nrows
25741 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
25742 !(row->enabled_p && MATRIX_ROW_DISPLAYS_TEXT_P (row))))
25743 return;
25745 if (row->cursor_in_fringe_p)
25747 row->cursor_in_fringe_p = 0;
25748 draw_fringe_bitmap (w, row, row->reversed_p);
25749 w->phys_cursor_on_p = 0;
25750 return;
25753 cx0 = w->phys_cursor.x;
25754 cx1 = cx0 + w->phys_cursor_width;
25755 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
25756 return;
25758 /* The cursor image will be completely removed from the
25759 screen if the output area intersects the cursor area in
25760 y-direction. When we draw in [y0 y1[, and some part of
25761 the cursor is at y < y0, that part must have been drawn
25762 before. When scrolling, the cursor is erased before
25763 actually scrolling, so we don't come here. When not
25764 scrolling, the rows above the old cursor row must have
25765 changed, and in this case these rows must have written
25766 over the cursor image.
25768 Likewise if part of the cursor is below y1, with the
25769 exception of the cursor being in the first blank row at
25770 the buffer and window end because update_text_area
25771 doesn't draw that row. (Except when it does, but
25772 that's handled in update_text_area.) */
25774 cy0 = w->phys_cursor.y;
25775 cy1 = cy0 + w->phys_cursor_height;
25776 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
25777 return;
25779 w->phys_cursor_on_p = 0;
25782 #endif /* HAVE_WINDOW_SYSTEM */
25785 /************************************************************************
25786 Mouse Face
25787 ************************************************************************/
25789 #ifdef HAVE_WINDOW_SYSTEM
25791 /* EXPORT for RIF:
25792 Fix the display of area AREA of overlapping row ROW in window W
25793 with respect to the overlapping part OVERLAPS. */
25795 void
25796 x_fix_overlapping_area (struct window *w, struct glyph_row *row,
25797 enum glyph_row_area area, int overlaps)
25799 int i, x;
25801 block_input ();
25803 x = 0;
25804 for (i = 0; i < row->used[area];)
25806 if (row->glyphs[area][i].overlaps_vertically_p)
25808 int start = i, start_x = x;
25812 x += row->glyphs[area][i].pixel_width;
25813 ++i;
25815 while (i < row->used[area]
25816 && row->glyphs[area][i].overlaps_vertically_p);
25818 draw_glyphs (w, start_x, row, area,
25819 start, i,
25820 DRAW_NORMAL_TEXT, overlaps);
25822 else
25824 x += row->glyphs[area][i].pixel_width;
25825 ++i;
25829 unblock_input ();
25833 /* EXPORT:
25834 Draw the cursor glyph of window W in glyph row ROW. See the
25835 comment of draw_glyphs for the meaning of HL. */
25837 void
25838 draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
25839 enum draw_glyphs_face hl)
25841 /* If cursor hpos is out of bounds, don't draw garbage. This can
25842 happen in mini-buffer windows when switching between echo area
25843 glyphs and mini-buffer. */
25844 if ((row->reversed_p
25845 ? (w->phys_cursor.hpos >= 0)
25846 : (w->phys_cursor.hpos < row->used[TEXT_AREA])))
25848 int on_p = w->phys_cursor_on_p;
25849 int x1;
25850 int hpos = w->phys_cursor.hpos;
25852 /* When the window is hscrolled, cursor hpos can legitimately be
25853 out of bounds, but we draw the cursor at the corresponding
25854 window margin in that case. */
25855 if (!row->reversed_p && hpos < 0)
25856 hpos = 0;
25857 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
25858 hpos = row->used[TEXT_AREA] - 1;
25860 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA, hpos, hpos + 1,
25861 hl, 0);
25862 w->phys_cursor_on_p = on_p;
25864 if (hl == DRAW_CURSOR)
25865 w->phys_cursor_width = x1 - w->phys_cursor.x;
25866 /* When we erase the cursor, and ROW is overlapped by other
25867 rows, make sure that these overlapping parts of other rows
25868 are redrawn. */
25869 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
25871 w->phys_cursor_width = x1 - w->phys_cursor.x;
25873 if (row > w->current_matrix->rows
25874 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
25875 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
25876 OVERLAPS_ERASED_CURSOR);
25878 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
25879 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
25880 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
25881 OVERLAPS_ERASED_CURSOR);
25887 /* EXPORT:
25888 Erase the image of a cursor of window W from the screen. */
25890 void
25891 erase_phys_cursor (struct window *w)
25893 struct frame *f = XFRAME (w->frame);
25894 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
25895 int hpos = w->phys_cursor.hpos;
25896 int vpos = w->phys_cursor.vpos;
25897 int mouse_face_here_p = 0;
25898 struct glyph_matrix *active_glyphs = w->current_matrix;
25899 struct glyph_row *cursor_row;
25900 struct glyph *cursor_glyph;
25901 enum draw_glyphs_face hl;
25903 /* No cursor displayed or row invalidated => nothing to do on the
25904 screen. */
25905 if (w->phys_cursor_type == NO_CURSOR)
25906 goto mark_cursor_off;
25908 /* VPOS >= active_glyphs->nrows means that window has been resized.
25909 Don't bother to erase the cursor. */
25910 if (vpos >= active_glyphs->nrows)
25911 goto mark_cursor_off;
25913 /* If row containing cursor is marked invalid, there is nothing we
25914 can do. */
25915 cursor_row = MATRIX_ROW (active_glyphs, vpos);
25916 if (!cursor_row->enabled_p)
25917 goto mark_cursor_off;
25919 /* If line spacing is > 0, old cursor may only be partially visible in
25920 window after split-window. So adjust visible height. */
25921 cursor_row->visible_height = min (cursor_row->visible_height,
25922 window_text_bottom_y (w) - cursor_row->y);
25924 /* If row is completely invisible, don't attempt to delete a cursor which
25925 isn't there. This can happen if cursor is at top of a window, and
25926 we switch to a buffer with a header line in that window. */
25927 if (cursor_row->visible_height <= 0)
25928 goto mark_cursor_off;
25930 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
25931 if (cursor_row->cursor_in_fringe_p)
25933 cursor_row->cursor_in_fringe_p = 0;
25934 draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
25935 goto mark_cursor_off;
25938 /* This can happen when the new row is shorter than the old one.
25939 In this case, either draw_glyphs or clear_end_of_line
25940 should have cleared the cursor. Note that we wouldn't be
25941 able to erase the cursor in this case because we don't have a
25942 cursor glyph at hand. */
25943 if ((cursor_row->reversed_p
25944 ? (w->phys_cursor.hpos < 0)
25945 : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
25946 goto mark_cursor_off;
25948 /* When the window is hscrolled, cursor hpos can legitimately be out
25949 of bounds, but we draw the cursor at the corresponding window
25950 margin in that case. */
25951 if (!cursor_row->reversed_p && hpos < 0)
25952 hpos = 0;
25953 if (cursor_row->reversed_p && hpos >= cursor_row->used[TEXT_AREA])
25954 hpos = cursor_row->used[TEXT_AREA] - 1;
25956 /* If the cursor is in the mouse face area, redisplay that when
25957 we clear the cursor. */
25958 if (! NILP (hlinfo->mouse_face_window)
25959 && coords_in_mouse_face_p (w, hpos, vpos)
25960 /* Don't redraw the cursor's spot in mouse face if it is at the
25961 end of a line (on a newline). The cursor appears there, but
25962 mouse highlighting does not. */
25963 && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
25964 mouse_face_here_p = 1;
25966 /* Maybe clear the display under the cursor. */
25967 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
25969 int x, y, left_x;
25970 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
25971 int width;
25973 cursor_glyph = get_phys_cursor_glyph (w);
25974 if (cursor_glyph == NULL)
25975 goto mark_cursor_off;
25977 width = cursor_glyph->pixel_width;
25978 left_x = window_box_left_offset (w, TEXT_AREA);
25979 x = w->phys_cursor.x;
25980 if (x < left_x)
25981 width -= left_x - x;
25982 width = min (width, window_box_width (w, TEXT_AREA) - x);
25983 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
25984 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
25986 if (width > 0)
25987 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
25990 /* Erase the cursor by redrawing the character underneath it. */
25991 if (mouse_face_here_p)
25992 hl = DRAW_MOUSE_FACE;
25993 else
25994 hl = DRAW_NORMAL_TEXT;
25995 draw_phys_cursor_glyph (w, cursor_row, hl);
25997 mark_cursor_off:
25998 w->phys_cursor_on_p = 0;
25999 w->phys_cursor_type = NO_CURSOR;
26003 /* EXPORT:
26004 Display or clear cursor of window W. If ON is zero, clear the
26005 cursor. If it is non-zero, display the cursor. If ON is nonzero,
26006 where to put the cursor is specified by HPOS, VPOS, X and Y. */
26008 void
26009 display_and_set_cursor (struct window *w, int on,
26010 int hpos, int vpos, int x, int y)
26012 struct frame *f = XFRAME (w->frame);
26013 int new_cursor_type;
26014 int new_cursor_width;
26015 int active_cursor;
26016 struct glyph_row *glyph_row;
26017 struct glyph *glyph;
26019 /* This is pointless on invisible frames, and dangerous on garbaged
26020 windows and frames; in the latter case, the frame or window may
26021 be in the midst of changing its size, and x and y may be off the
26022 window. */
26023 if (! FRAME_VISIBLE_P (f)
26024 || FRAME_GARBAGED_P (f)
26025 || vpos >= w->current_matrix->nrows
26026 || hpos >= w->current_matrix->matrix_w)
26027 return;
26029 /* If cursor is off and we want it off, return quickly. */
26030 if (!on && !w->phys_cursor_on_p)
26031 return;
26033 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
26034 /* If cursor row is not enabled, we don't really know where to
26035 display the cursor. */
26036 if (!glyph_row->enabled_p)
26038 w->phys_cursor_on_p = 0;
26039 return;
26042 glyph = NULL;
26043 if (!glyph_row->exact_window_width_line_p
26044 || (0 <= hpos && hpos < glyph_row->used[TEXT_AREA]))
26045 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
26047 eassert (input_blocked_p ());
26049 /* Set new_cursor_type to the cursor we want to be displayed. */
26050 new_cursor_type = get_window_cursor_type (w, glyph,
26051 &new_cursor_width, &active_cursor);
26053 /* If cursor is currently being shown and we don't want it to be or
26054 it is in the wrong place, or the cursor type is not what we want,
26055 erase it. */
26056 if (w->phys_cursor_on_p
26057 && (!on
26058 || w->phys_cursor.x != x
26059 || w->phys_cursor.y != y
26060 || new_cursor_type != w->phys_cursor_type
26061 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
26062 && new_cursor_width != w->phys_cursor_width)))
26063 erase_phys_cursor (w);
26065 /* Don't check phys_cursor_on_p here because that flag is only set
26066 to zero in some cases where we know that the cursor has been
26067 completely erased, to avoid the extra work of erasing the cursor
26068 twice. In other words, phys_cursor_on_p can be 1 and the cursor
26069 still not be visible, or it has only been partly erased. */
26070 if (on)
26072 w->phys_cursor_ascent = glyph_row->ascent;
26073 w->phys_cursor_height = glyph_row->height;
26075 /* Set phys_cursor_.* before x_draw_.* is called because some
26076 of them may need the information. */
26077 w->phys_cursor.x = x;
26078 w->phys_cursor.y = glyph_row->y;
26079 w->phys_cursor.hpos = hpos;
26080 w->phys_cursor.vpos = vpos;
26083 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
26084 new_cursor_type, new_cursor_width,
26085 on, active_cursor);
26089 /* Switch the display of W's cursor on or off, according to the value
26090 of ON. */
26092 static void
26093 update_window_cursor (struct window *w, int on)
26095 /* Don't update cursor in windows whose frame is in the process
26096 of being deleted. */
26097 if (w->current_matrix)
26099 int hpos = w->phys_cursor.hpos;
26100 int vpos = w->phys_cursor.vpos;
26101 struct glyph_row *row;
26103 if (vpos >= w->current_matrix->nrows
26104 || hpos >= w->current_matrix->matrix_w)
26105 return;
26107 row = MATRIX_ROW (w->current_matrix, vpos);
26109 /* When the window is hscrolled, cursor hpos can legitimately be
26110 out of bounds, but we draw the cursor at the corresponding
26111 window margin in that case. */
26112 if (!row->reversed_p && hpos < 0)
26113 hpos = 0;
26114 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26115 hpos = row->used[TEXT_AREA] - 1;
26117 block_input ();
26118 display_and_set_cursor (w, on, hpos, vpos,
26119 w->phys_cursor.x, w->phys_cursor.y);
26120 unblock_input ();
26125 /* Call update_window_cursor with parameter ON_P on all leaf windows
26126 in the window tree rooted at W. */
26128 static void
26129 update_cursor_in_window_tree (struct window *w, int on_p)
26131 while (w)
26133 if (WINDOWP (w->contents))
26134 update_cursor_in_window_tree (XWINDOW (w->contents), on_p);
26135 else
26136 update_window_cursor (w, on_p);
26138 w = NILP (w->next) ? 0 : XWINDOW (w->next);
26143 /* EXPORT:
26144 Display the cursor on window W, or clear it, according to ON_P.
26145 Don't change the cursor's position. */
26147 void
26148 x_update_cursor (struct frame *f, int on_p)
26150 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
26154 /* EXPORT:
26155 Clear the cursor of window W to background color, and mark the
26156 cursor as not shown. This is used when the text where the cursor
26157 is about to be rewritten. */
26159 void
26160 x_clear_cursor (struct window *w)
26162 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
26163 update_window_cursor (w, 0);
26166 #endif /* HAVE_WINDOW_SYSTEM */
26168 /* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
26169 and MSDOS. */
26170 static void
26171 draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
26172 int start_hpos, int end_hpos,
26173 enum draw_glyphs_face draw)
26175 #ifdef HAVE_WINDOW_SYSTEM
26176 if (FRAME_WINDOW_P (XFRAME (w->frame)))
26178 draw_glyphs (w, start_x, row, TEXT_AREA, start_hpos, end_hpos, draw, 0);
26179 return;
26181 #endif
26182 #if defined (HAVE_GPM) || defined (MSDOS) || defined (WINDOWSNT)
26183 tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
26184 #endif
26187 /* Display the active region described by mouse_face_* according to DRAW. */
26189 static void
26190 show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
26192 struct window *w = XWINDOW (hlinfo->mouse_face_window);
26193 struct frame *f = XFRAME (WINDOW_FRAME (w));
26195 if (/* If window is in the process of being destroyed, don't bother
26196 to do anything. */
26197 w->current_matrix != NULL
26198 /* Don't update mouse highlight if hidden */
26199 && (draw != DRAW_MOUSE_FACE || !hlinfo->mouse_face_hidden)
26200 /* Recognize when we are called to operate on rows that don't exist
26201 anymore. This can happen when a window is split. */
26202 && hlinfo->mouse_face_end_row < w->current_matrix->nrows)
26204 int phys_cursor_on_p = w->phys_cursor_on_p;
26205 struct glyph_row *row, *first, *last;
26207 first = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
26208 last = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
26210 for (row = first; row <= last && row->enabled_p; ++row)
26212 int start_hpos, end_hpos, start_x;
26214 /* For all but the first row, the highlight starts at column 0. */
26215 if (row == first)
26217 /* R2L rows have BEG and END in reversed order, but the
26218 screen drawing geometry is always left to right. So
26219 we need to mirror the beginning and end of the
26220 highlighted area in R2L rows. */
26221 if (!row->reversed_p)
26223 start_hpos = hlinfo->mouse_face_beg_col;
26224 start_x = hlinfo->mouse_face_beg_x;
26226 else if (row == last)
26228 start_hpos = hlinfo->mouse_face_end_col;
26229 start_x = hlinfo->mouse_face_end_x;
26231 else
26233 start_hpos = 0;
26234 start_x = 0;
26237 else if (row->reversed_p && row == last)
26239 start_hpos = hlinfo->mouse_face_end_col;
26240 start_x = hlinfo->mouse_face_end_x;
26242 else
26244 start_hpos = 0;
26245 start_x = 0;
26248 if (row == last)
26250 if (!row->reversed_p)
26251 end_hpos = hlinfo->mouse_face_end_col;
26252 else if (row == first)
26253 end_hpos = hlinfo->mouse_face_beg_col;
26254 else
26256 end_hpos = row->used[TEXT_AREA];
26257 if (draw == DRAW_NORMAL_TEXT)
26258 row->fill_line_p = 1; /* Clear to end of line */
26261 else if (row->reversed_p && row == first)
26262 end_hpos = hlinfo->mouse_face_beg_col;
26263 else
26265 end_hpos = row->used[TEXT_AREA];
26266 if (draw == DRAW_NORMAL_TEXT)
26267 row->fill_line_p = 1; /* Clear to end of line */
26270 if (end_hpos > start_hpos)
26272 draw_row_with_mouse_face (w, start_x, row,
26273 start_hpos, end_hpos, draw);
26275 row->mouse_face_p
26276 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
26280 #ifdef HAVE_WINDOW_SYSTEM
26281 /* When we've written over the cursor, arrange for it to
26282 be displayed again. */
26283 if (FRAME_WINDOW_P (f)
26284 && phys_cursor_on_p && !w->phys_cursor_on_p)
26286 int hpos = w->phys_cursor.hpos;
26288 /* When the window is hscrolled, cursor hpos can legitimately be
26289 out of bounds, but we draw the cursor at the corresponding
26290 window margin in that case. */
26291 if (!row->reversed_p && hpos < 0)
26292 hpos = 0;
26293 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26294 hpos = row->used[TEXT_AREA] - 1;
26296 block_input ();
26297 display_and_set_cursor (w, 1, hpos, w->phys_cursor.vpos,
26298 w->phys_cursor.x, w->phys_cursor.y);
26299 unblock_input ();
26301 #endif /* HAVE_WINDOW_SYSTEM */
26304 #ifdef HAVE_WINDOW_SYSTEM
26305 /* Change the mouse cursor. */
26306 if (FRAME_WINDOW_P (f))
26308 if (draw == DRAW_NORMAL_TEXT
26309 && !EQ (hlinfo->mouse_face_window, f->tool_bar_window))
26310 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
26311 else if (draw == DRAW_MOUSE_FACE)
26312 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
26313 else
26314 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
26316 #endif /* HAVE_WINDOW_SYSTEM */
26319 /* EXPORT:
26320 Clear out the mouse-highlighted active region.
26321 Redraw it un-highlighted first. Value is non-zero if mouse
26322 face was actually drawn unhighlighted. */
26325 clear_mouse_face (Mouse_HLInfo *hlinfo)
26327 int cleared = 0;
26329 if (!hlinfo->mouse_face_hidden && !NILP (hlinfo->mouse_face_window))
26331 show_mouse_face (hlinfo, DRAW_NORMAL_TEXT);
26332 cleared = 1;
26335 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
26336 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
26337 hlinfo->mouse_face_window = Qnil;
26338 hlinfo->mouse_face_overlay = Qnil;
26339 return cleared;
26342 /* Return non-zero if the coordinates HPOS and VPOS on windows W are
26343 within the mouse face on that window. */
26344 static int
26345 coords_in_mouse_face_p (struct window *w, int hpos, int vpos)
26347 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
26349 /* Quickly resolve the easy cases. */
26350 if (!(WINDOWP (hlinfo->mouse_face_window)
26351 && XWINDOW (hlinfo->mouse_face_window) == w))
26352 return 0;
26353 if (vpos < hlinfo->mouse_face_beg_row
26354 || vpos > hlinfo->mouse_face_end_row)
26355 return 0;
26356 if (vpos > hlinfo->mouse_face_beg_row
26357 && vpos < hlinfo->mouse_face_end_row)
26358 return 1;
26360 if (!MATRIX_ROW (w->current_matrix, vpos)->reversed_p)
26362 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
26364 if (hlinfo->mouse_face_beg_col <= hpos && hpos < hlinfo->mouse_face_end_col)
26365 return 1;
26367 else if ((vpos == hlinfo->mouse_face_beg_row
26368 && hpos >= hlinfo->mouse_face_beg_col)
26369 || (vpos == hlinfo->mouse_face_end_row
26370 && hpos < hlinfo->mouse_face_end_col))
26371 return 1;
26373 else
26375 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
26377 if (hlinfo->mouse_face_end_col < hpos && hpos <= hlinfo->mouse_face_beg_col)
26378 return 1;
26380 else if ((vpos == hlinfo->mouse_face_beg_row
26381 && hpos <= hlinfo->mouse_face_beg_col)
26382 || (vpos == hlinfo->mouse_face_end_row
26383 && hpos > hlinfo->mouse_face_end_col))
26384 return 1;
26386 return 0;
26390 /* EXPORT:
26391 Non-zero if physical cursor of window W is within mouse face. */
26394 cursor_in_mouse_face_p (struct window *w)
26396 int hpos = w->phys_cursor.hpos;
26397 int vpos = w->phys_cursor.vpos;
26398 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
26400 /* When the window is hscrolled, cursor hpos can legitimately be out
26401 of bounds, but we draw the cursor at the corresponding window
26402 margin in that case. */
26403 if (!row->reversed_p && hpos < 0)
26404 hpos = 0;
26405 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26406 hpos = row->used[TEXT_AREA] - 1;
26408 return coords_in_mouse_face_p (w, hpos, vpos);
26413 /* Find the glyph rows START_ROW and END_ROW of window W that display
26414 characters between buffer positions START_CHARPOS and END_CHARPOS
26415 (excluding END_CHARPOS). DISP_STRING is a display string that
26416 covers these buffer positions. This is similar to
26417 row_containing_pos, but is more accurate when bidi reordering makes
26418 buffer positions change non-linearly with glyph rows. */
26419 static void
26420 rows_from_pos_range (struct window *w,
26421 ptrdiff_t start_charpos, ptrdiff_t end_charpos,
26422 Lisp_Object disp_string,
26423 struct glyph_row **start, struct glyph_row **end)
26425 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
26426 int last_y = window_text_bottom_y (w);
26427 struct glyph_row *row;
26429 *start = NULL;
26430 *end = NULL;
26432 while (!first->enabled_p
26433 && first < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
26434 first++;
26436 /* Find the START row. */
26437 for (row = first;
26438 row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y;
26439 row++)
26441 /* A row can potentially be the START row if the range of the
26442 characters it displays intersects the range
26443 [START_CHARPOS..END_CHARPOS). */
26444 if (! ((start_charpos < MATRIX_ROW_START_CHARPOS (row)
26445 && end_charpos < MATRIX_ROW_START_CHARPOS (row))
26446 /* See the commentary in row_containing_pos, for the
26447 explanation of the complicated way to check whether
26448 some position is beyond the end of the characters
26449 displayed by a row. */
26450 || ((start_charpos > MATRIX_ROW_END_CHARPOS (row)
26451 || (start_charpos == MATRIX_ROW_END_CHARPOS (row)
26452 && !row->ends_at_zv_p
26453 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
26454 && (end_charpos > MATRIX_ROW_END_CHARPOS (row)
26455 || (end_charpos == MATRIX_ROW_END_CHARPOS (row)
26456 && !row->ends_at_zv_p
26457 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))))))
26459 /* Found a candidate row. Now make sure at least one of the
26460 glyphs it displays has a charpos from the range
26461 [START_CHARPOS..END_CHARPOS).
26463 This is not obvious because bidi reordering could make
26464 buffer positions of a row be 1,2,3,102,101,100, and if we
26465 want to highlight characters in [50..60), we don't want
26466 this row, even though [50..60) does intersect [1..103),
26467 the range of character positions given by the row's start
26468 and end positions. */
26469 struct glyph *g = row->glyphs[TEXT_AREA];
26470 struct glyph *e = g + row->used[TEXT_AREA];
26472 while (g < e)
26474 if (((BUFFERP (g->object) || INTEGERP (g->object))
26475 && start_charpos <= g->charpos && g->charpos < end_charpos)
26476 /* A glyph that comes from DISP_STRING is by
26477 definition to be highlighted. */
26478 || EQ (g->object, disp_string))
26479 *start = row;
26480 g++;
26482 if (*start)
26483 break;
26487 /* Find the END row. */
26488 if (!*start
26489 /* If the last row is partially visible, start looking for END
26490 from that row, instead of starting from FIRST. */
26491 && !(row->enabled_p
26492 && row->y < last_y && MATRIX_ROW_BOTTOM_Y (row) > last_y))
26493 row = first;
26494 for ( ; row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y; row++)
26496 struct glyph_row *next = row + 1;
26497 ptrdiff_t next_start = MATRIX_ROW_START_CHARPOS (next);
26499 if (!next->enabled_p
26500 || next >= MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)
26501 /* The first row >= START whose range of displayed characters
26502 does NOT intersect the range [START_CHARPOS..END_CHARPOS]
26503 is the row END + 1. */
26504 || (start_charpos < next_start
26505 && end_charpos < next_start)
26506 || ((start_charpos > MATRIX_ROW_END_CHARPOS (next)
26507 || (start_charpos == MATRIX_ROW_END_CHARPOS (next)
26508 && !next->ends_at_zv_p
26509 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))
26510 && (end_charpos > MATRIX_ROW_END_CHARPOS (next)
26511 || (end_charpos == MATRIX_ROW_END_CHARPOS (next)
26512 && !next->ends_at_zv_p
26513 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))))
26515 *end = row;
26516 break;
26518 else
26520 /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
26521 but none of the characters it displays are in the range, it is
26522 also END + 1. */
26523 struct glyph *g = next->glyphs[TEXT_AREA];
26524 struct glyph *s = g;
26525 struct glyph *e = g + next->used[TEXT_AREA];
26527 while (g < e)
26529 if (((BUFFERP (g->object) || INTEGERP (g->object))
26530 && ((start_charpos <= g->charpos && g->charpos < end_charpos)
26531 /* If the buffer position of the first glyph in
26532 the row is equal to END_CHARPOS, it means
26533 the last character to be highlighted is the
26534 newline of ROW, and we must consider NEXT as
26535 END, not END+1. */
26536 || (((!next->reversed_p && g == s)
26537 || (next->reversed_p && g == e - 1))
26538 && (g->charpos == end_charpos
26539 /* Special case for when NEXT is an
26540 empty line at ZV. */
26541 || (g->charpos == -1
26542 && !row->ends_at_zv_p
26543 && next_start == end_charpos)))))
26544 /* A glyph that comes from DISP_STRING is by
26545 definition to be highlighted. */
26546 || EQ (g->object, disp_string))
26547 break;
26548 g++;
26550 if (g == e)
26552 *end = row;
26553 break;
26555 /* The first row that ends at ZV must be the last to be
26556 highlighted. */
26557 else if (next->ends_at_zv_p)
26559 *end = next;
26560 break;
26566 /* This function sets the mouse_face_* elements of HLINFO, assuming
26567 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
26568 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
26569 for the overlay or run of text properties specifying the mouse
26570 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
26571 before-string and after-string that must also be highlighted.
26572 DISP_STRING, if non-nil, is a display string that may cover some
26573 or all of the highlighted text. */
26575 static void
26576 mouse_face_from_buffer_pos (Lisp_Object window,
26577 Mouse_HLInfo *hlinfo,
26578 ptrdiff_t mouse_charpos,
26579 ptrdiff_t start_charpos,
26580 ptrdiff_t end_charpos,
26581 Lisp_Object before_string,
26582 Lisp_Object after_string,
26583 Lisp_Object disp_string)
26585 struct window *w = XWINDOW (window);
26586 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
26587 struct glyph_row *r1, *r2;
26588 struct glyph *glyph, *end;
26589 ptrdiff_t ignore, pos;
26590 int x;
26592 eassert (NILP (disp_string) || STRINGP (disp_string));
26593 eassert (NILP (before_string) || STRINGP (before_string));
26594 eassert (NILP (after_string) || STRINGP (after_string));
26596 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
26597 rows_from_pos_range (w, start_charpos, end_charpos, disp_string, &r1, &r2);
26598 if (r1 == NULL)
26599 r1 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
26600 /* If the before-string or display-string contains newlines,
26601 rows_from_pos_range skips to its last row. Move back. */
26602 if (!NILP (before_string) || !NILP (disp_string))
26604 struct glyph_row *prev;
26605 while ((prev = r1 - 1, prev >= first)
26606 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
26607 && prev->used[TEXT_AREA] > 0)
26609 struct glyph *beg = prev->glyphs[TEXT_AREA];
26610 glyph = beg + prev->used[TEXT_AREA];
26611 while (--glyph >= beg && INTEGERP (glyph->object));
26612 if (glyph < beg
26613 || !(EQ (glyph->object, before_string)
26614 || EQ (glyph->object, disp_string)))
26615 break;
26616 r1 = prev;
26619 if (r2 == NULL)
26621 r2 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
26622 hlinfo->mouse_face_past_end = 1;
26624 else if (!NILP (after_string))
26626 /* If the after-string has newlines, advance to its last row. */
26627 struct glyph_row *next;
26628 struct glyph_row *last
26629 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
26631 for (next = r2 + 1;
26632 next <= last
26633 && next->used[TEXT_AREA] > 0
26634 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
26635 ++next)
26636 r2 = next;
26638 /* The rest of the display engine assumes that mouse_face_beg_row is
26639 either above mouse_face_end_row or identical to it. But with
26640 bidi-reordered continued lines, the row for START_CHARPOS could
26641 be below the row for END_CHARPOS. If so, swap the rows and store
26642 them in correct order. */
26643 if (r1->y > r2->y)
26645 struct glyph_row *tem = r2;
26647 r2 = r1;
26648 r1 = tem;
26651 hlinfo->mouse_face_beg_y = r1->y;
26652 hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
26653 hlinfo->mouse_face_end_y = r2->y;
26654 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
26656 /* For a bidi-reordered row, the positions of BEFORE_STRING,
26657 AFTER_STRING, DISP_STRING, START_CHARPOS, and END_CHARPOS
26658 could be anywhere in the row and in any order. The strategy
26659 below is to find the leftmost and the rightmost glyph that
26660 belongs to either of these 3 strings, or whose position is
26661 between START_CHARPOS and END_CHARPOS, and highlight all the
26662 glyphs between those two. This may cover more than just the text
26663 between START_CHARPOS and END_CHARPOS if the range of characters
26664 strides the bidi level boundary, e.g. if the beginning is in R2L
26665 text while the end is in L2R text or vice versa. */
26666 if (!r1->reversed_p)
26668 /* This row is in a left to right paragraph. Scan it left to
26669 right. */
26670 glyph = r1->glyphs[TEXT_AREA];
26671 end = glyph + r1->used[TEXT_AREA];
26672 x = r1->x;
26674 /* Skip truncation glyphs at the start of the glyph row. */
26675 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
26676 for (; glyph < end
26677 && INTEGERP (glyph->object)
26678 && glyph->charpos < 0;
26679 ++glyph)
26680 x += glyph->pixel_width;
26682 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
26683 or DISP_STRING, and the first glyph from buffer whose
26684 position is between START_CHARPOS and END_CHARPOS. */
26685 for (; glyph < end
26686 && !INTEGERP (glyph->object)
26687 && !EQ (glyph->object, disp_string)
26688 && !(BUFFERP (glyph->object)
26689 && (glyph->charpos >= start_charpos
26690 && glyph->charpos < end_charpos));
26691 ++glyph)
26693 /* BEFORE_STRING or AFTER_STRING are only relevant if they
26694 are present at buffer positions between START_CHARPOS and
26695 END_CHARPOS, or if they come from an overlay. */
26696 if (EQ (glyph->object, before_string))
26698 pos = string_buffer_position (before_string,
26699 start_charpos);
26700 /* If pos == 0, it means before_string came from an
26701 overlay, not from a buffer position. */
26702 if (!pos || (pos >= start_charpos && pos < end_charpos))
26703 break;
26705 else if (EQ (glyph->object, after_string))
26707 pos = string_buffer_position (after_string, end_charpos);
26708 if (!pos || (pos >= start_charpos && pos < end_charpos))
26709 break;
26711 x += glyph->pixel_width;
26713 hlinfo->mouse_face_beg_x = x;
26714 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
26716 else
26718 /* This row is in a right to left paragraph. Scan it right to
26719 left. */
26720 struct glyph *g;
26722 end = r1->glyphs[TEXT_AREA] - 1;
26723 glyph = end + r1->used[TEXT_AREA];
26725 /* Skip truncation glyphs at the start of the glyph row. */
26726 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
26727 for (; glyph > end
26728 && INTEGERP (glyph->object)
26729 && glyph->charpos < 0;
26730 --glyph)
26733 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
26734 or DISP_STRING, and the first glyph from buffer whose
26735 position is between START_CHARPOS and END_CHARPOS. */
26736 for (; glyph > end
26737 && !INTEGERP (glyph->object)
26738 && !EQ (glyph->object, disp_string)
26739 && !(BUFFERP (glyph->object)
26740 && (glyph->charpos >= start_charpos
26741 && glyph->charpos < end_charpos));
26742 --glyph)
26744 /* BEFORE_STRING or AFTER_STRING are only relevant if they
26745 are present at buffer positions between START_CHARPOS and
26746 END_CHARPOS, or if they come from an overlay. */
26747 if (EQ (glyph->object, before_string))
26749 pos = string_buffer_position (before_string, start_charpos);
26750 /* If pos == 0, it means before_string came from an
26751 overlay, not from a buffer position. */
26752 if (!pos || (pos >= start_charpos && pos < end_charpos))
26753 break;
26755 else if (EQ (glyph->object, after_string))
26757 pos = string_buffer_position (after_string, end_charpos);
26758 if (!pos || (pos >= start_charpos && pos < end_charpos))
26759 break;
26763 glyph++; /* first glyph to the right of the highlighted area */
26764 for (g = r1->glyphs[TEXT_AREA], x = r1->x; g < glyph; g++)
26765 x += g->pixel_width;
26766 hlinfo->mouse_face_beg_x = x;
26767 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
26770 /* If the highlight ends in a different row, compute GLYPH and END
26771 for the end row. Otherwise, reuse the values computed above for
26772 the row where the highlight begins. */
26773 if (r2 != r1)
26775 if (!r2->reversed_p)
26777 glyph = r2->glyphs[TEXT_AREA];
26778 end = glyph + r2->used[TEXT_AREA];
26779 x = r2->x;
26781 else
26783 end = r2->glyphs[TEXT_AREA] - 1;
26784 glyph = end + r2->used[TEXT_AREA];
26788 if (!r2->reversed_p)
26790 /* Skip truncation and continuation glyphs near the end of the
26791 row, and also blanks and stretch glyphs inserted by
26792 extend_face_to_end_of_line. */
26793 while (end > glyph
26794 && INTEGERP ((end - 1)->object))
26795 --end;
26796 /* Scan the rest of the glyph row from the end, looking for the
26797 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
26798 DISP_STRING, or whose position is between START_CHARPOS
26799 and END_CHARPOS */
26800 for (--end;
26801 end > glyph
26802 && !INTEGERP (end->object)
26803 && !EQ (end->object, disp_string)
26804 && !(BUFFERP (end->object)
26805 && (end->charpos >= start_charpos
26806 && end->charpos < end_charpos));
26807 --end)
26809 /* BEFORE_STRING or AFTER_STRING are only relevant if they
26810 are present at buffer positions between START_CHARPOS and
26811 END_CHARPOS, or if they come from an overlay. */
26812 if (EQ (end->object, before_string))
26814 pos = string_buffer_position (before_string, start_charpos);
26815 if (!pos || (pos >= start_charpos && pos < end_charpos))
26816 break;
26818 else if (EQ (end->object, after_string))
26820 pos = string_buffer_position (after_string, end_charpos);
26821 if (!pos || (pos >= start_charpos && pos < end_charpos))
26822 break;
26825 /* Find the X coordinate of the last glyph to be highlighted. */
26826 for (; glyph <= end; ++glyph)
26827 x += glyph->pixel_width;
26829 hlinfo->mouse_face_end_x = x;
26830 hlinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
26832 else
26834 /* Skip truncation and continuation glyphs near the end of the
26835 row, and also blanks and stretch glyphs inserted by
26836 extend_face_to_end_of_line. */
26837 x = r2->x;
26838 end++;
26839 while (end < glyph
26840 && INTEGERP (end->object))
26842 x += end->pixel_width;
26843 ++end;
26845 /* Scan the rest of the glyph row from the end, looking for the
26846 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
26847 DISP_STRING, or whose position is between START_CHARPOS
26848 and END_CHARPOS */
26849 for ( ;
26850 end < glyph
26851 && !INTEGERP (end->object)
26852 && !EQ (end->object, disp_string)
26853 && !(BUFFERP (end->object)
26854 && (end->charpos >= start_charpos
26855 && end->charpos < end_charpos));
26856 ++end)
26858 /* BEFORE_STRING or AFTER_STRING are only relevant if they
26859 are present at buffer positions between START_CHARPOS and
26860 END_CHARPOS, or if they come from an overlay. */
26861 if (EQ (end->object, before_string))
26863 pos = string_buffer_position (before_string, start_charpos);
26864 if (!pos || (pos >= start_charpos && pos < end_charpos))
26865 break;
26867 else if (EQ (end->object, after_string))
26869 pos = string_buffer_position (after_string, end_charpos);
26870 if (!pos || (pos >= start_charpos && pos < end_charpos))
26871 break;
26873 x += end->pixel_width;
26875 /* If we exited the above loop because we arrived at the last
26876 glyph of the row, and its buffer position is still not in
26877 range, it means the last character in range is the preceding
26878 newline. Bump the end column and x values to get past the
26879 last glyph. */
26880 if (end == glyph
26881 && BUFFERP (end->object)
26882 && (end->charpos < start_charpos
26883 || end->charpos >= end_charpos))
26885 x += end->pixel_width;
26886 ++end;
26888 hlinfo->mouse_face_end_x = x;
26889 hlinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
26892 hlinfo->mouse_face_window = window;
26893 hlinfo->mouse_face_face_id
26894 = face_at_buffer_position (w, mouse_charpos, 0, 0, &ignore,
26895 mouse_charpos + 1,
26896 !hlinfo->mouse_face_hidden, -1);
26897 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
26900 /* The following function is not used anymore (replaced with
26901 mouse_face_from_string_pos), but I leave it here for the time
26902 being, in case someone would. */
26904 #if 0 /* not used */
26906 /* Find the position of the glyph for position POS in OBJECT in
26907 window W's current matrix, and return in *X, *Y the pixel
26908 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
26910 RIGHT_P non-zero means return the position of the right edge of the
26911 glyph, RIGHT_P zero means return the left edge position.
26913 If no glyph for POS exists in the matrix, return the position of
26914 the glyph with the next smaller position that is in the matrix, if
26915 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
26916 exists in the matrix, return the position of the glyph with the
26917 next larger position in OBJECT.
26919 Value is non-zero if a glyph was found. */
26921 static int
26922 fast_find_string_pos (struct window *w, ptrdiff_t pos, Lisp_Object object,
26923 int *hpos, int *vpos, int *x, int *y, int right_p)
26925 int yb = window_text_bottom_y (w);
26926 struct glyph_row *r;
26927 struct glyph *best_glyph = NULL;
26928 struct glyph_row *best_row = NULL;
26929 int best_x = 0;
26931 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
26932 r->enabled_p && r->y < yb;
26933 ++r)
26935 struct glyph *g = r->glyphs[TEXT_AREA];
26936 struct glyph *e = g + r->used[TEXT_AREA];
26937 int gx;
26939 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
26940 if (EQ (g->object, object))
26942 if (g->charpos == pos)
26944 best_glyph = g;
26945 best_x = gx;
26946 best_row = r;
26947 goto found;
26949 else if (best_glyph == NULL
26950 || ((eabs (g->charpos - pos)
26951 < eabs (best_glyph->charpos - pos))
26952 && (right_p
26953 ? g->charpos < pos
26954 : g->charpos > pos)))
26956 best_glyph = g;
26957 best_x = gx;
26958 best_row = r;
26963 found:
26965 if (best_glyph)
26967 *x = best_x;
26968 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
26970 if (right_p)
26972 *x += best_glyph->pixel_width;
26973 ++*hpos;
26976 *y = best_row->y;
26977 *vpos = MATRIX_ROW_VPOS (best_row, w->current_matrix);
26980 return best_glyph != NULL;
26982 #endif /* not used */
26984 /* Find the positions of the first and the last glyphs in window W's
26985 current matrix that occlude positions [STARTPOS..ENDPOS] in OBJECT
26986 (assumed to be a string), and return in HLINFO's mouse_face_*
26987 members the pixel and column/row coordinates of those glyphs. */
26989 static void
26990 mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
26991 Lisp_Object object,
26992 ptrdiff_t startpos, ptrdiff_t endpos)
26994 int yb = window_text_bottom_y (w);
26995 struct glyph_row *r;
26996 struct glyph *g, *e;
26997 int gx;
26998 int found = 0;
27000 /* Find the glyph row with at least one position in the range
27001 [STARTPOS..ENDPOS], and the first glyph in that row whose
27002 position belongs to that range. */
27003 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
27004 r->enabled_p && r->y < yb;
27005 ++r)
27007 if (!r->reversed_p)
27009 g = r->glyphs[TEXT_AREA];
27010 e = g + r->used[TEXT_AREA];
27011 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
27012 if (EQ (g->object, object)
27013 && startpos <= g->charpos && g->charpos <= endpos)
27015 hlinfo->mouse_face_beg_row
27016 = MATRIX_ROW_VPOS (r, w->current_matrix);
27017 hlinfo->mouse_face_beg_y = r->y;
27018 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
27019 hlinfo->mouse_face_beg_x = gx;
27020 found = 1;
27021 break;
27024 else
27026 struct glyph *g1;
27028 e = r->glyphs[TEXT_AREA];
27029 g = e + r->used[TEXT_AREA];
27030 for ( ; g > e; --g)
27031 if (EQ ((g-1)->object, object)
27032 && startpos <= (g-1)->charpos && (g-1)->charpos <= endpos)
27034 hlinfo->mouse_face_beg_row
27035 = MATRIX_ROW_VPOS (r, w->current_matrix);
27036 hlinfo->mouse_face_beg_y = r->y;
27037 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
27038 for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
27039 gx += g1->pixel_width;
27040 hlinfo->mouse_face_beg_x = gx;
27041 found = 1;
27042 break;
27045 if (found)
27046 break;
27049 if (!found)
27050 return;
27052 /* Starting with the next row, look for the first row which does NOT
27053 include any glyphs whose positions are in the range. */
27054 for (++r; r->enabled_p && r->y < yb; ++r)
27056 g = r->glyphs[TEXT_AREA];
27057 e = g + r->used[TEXT_AREA];
27058 found = 0;
27059 for ( ; g < e; ++g)
27060 if (EQ (g->object, object)
27061 && startpos <= g->charpos && g->charpos <= endpos)
27063 found = 1;
27064 break;
27066 if (!found)
27067 break;
27070 /* The highlighted region ends on the previous row. */
27071 r--;
27073 /* Set the end row and its vertical pixel coordinate. */
27074 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r, w->current_matrix);
27075 hlinfo->mouse_face_end_y = r->y;
27077 /* Compute and set the end column and the end column's horizontal
27078 pixel coordinate. */
27079 if (!r->reversed_p)
27081 g = r->glyphs[TEXT_AREA];
27082 e = g + r->used[TEXT_AREA];
27083 for ( ; e > g; --e)
27084 if (EQ ((e-1)->object, object)
27085 && startpos <= (e-1)->charpos && (e-1)->charpos <= endpos)
27086 break;
27087 hlinfo->mouse_face_end_col = e - g;
27089 for (gx = r->x; g < e; ++g)
27090 gx += g->pixel_width;
27091 hlinfo->mouse_face_end_x = gx;
27093 else
27095 e = r->glyphs[TEXT_AREA];
27096 g = e + r->used[TEXT_AREA];
27097 for (gx = r->x ; e < g; ++e)
27099 if (EQ (e->object, object)
27100 && startpos <= e->charpos && e->charpos <= endpos)
27101 break;
27102 gx += e->pixel_width;
27104 hlinfo->mouse_face_end_col = e - r->glyphs[TEXT_AREA];
27105 hlinfo->mouse_face_end_x = gx;
27109 #ifdef HAVE_WINDOW_SYSTEM
27111 /* See if position X, Y is within a hot-spot of an image. */
27113 static int
27114 on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
27116 if (!CONSP (hot_spot))
27117 return 0;
27119 if (EQ (XCAR (hot_spot), Qrect))
27121 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
27122 Lisp_Object rect = XCDR (hot_spot);
27123 Lisp_Object tem;
27124 if (!CONSP (rect))
27125 return 0;
27126 if (!CONSP (XCAR (rect)))
27127 return 0;
27128 if (!CONSP (XCDR (rect)))
27129 return 0;
27130 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
27131 return 0;
27132 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
27133 return 0;
27134 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
27135 return 0;
27136 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
27137 return 0;
27138 return 1;
27140 else if (EQ (XCAR (hot_spot), Qcircle))
27142 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
27143 Lisp_Object circ = XCDR (hot_spot);
27144 Lisp_Object lr, lx0, ly0;
27145 if (CONSP (circ)
27146 && CONSP (XCAR (circ))
27147 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
27148 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
27149 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
27151 double r = XFLOATINT (lr);
27152 double dx = XINT (lx0) - x;
27153 double dy = XINT (ly0) - y;
27154 return (dx * dx + dy * dy <= r * r);
27157 else if (EQ (XCAR (hot_spot), Qpoly))
27159 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
27160 if (VECTORP (XCDR (hot_spot)))
27162 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
27163 Lisp_Object *poly = v->contents;
27164 ptrdiff_t n = v->header.size;
27165 ptrdiff_t i;
27166 int inside = 0;
27167 Lisp_Object lx, ly;
27168 int x0, y0;
27170 /* Need an even number of coordinates, and at least 3 edges. */
27171 if (n < 6 || n & 1)
27172 return 0;
27174 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
27175 If count is odd, we are inside polygon. Pixels on edges
27176 may or may not be included depending on actual geometry of the
27177 polygon. */
27178 if ((lx = poly[n-2], !INTEGERP (lx))
27179 || (ly = poly[n-1], !INTEGERP (lx)))
27180 return 0;
27181 x0 = XINT (lx), y0 = XINT (ly);
27182 for (i = 0; i < n; i += 2)
27184 int x1 = x0, y1 = y0;
27185 if ((lx = poly[i], !INTEGERP (lx))
27186 || (ly = poly[i+1], !INTEGERP (ly)))
27187 return 0;
27188 x0 = XINT (lx), y0 = XINT (ly);
27190 /* Does this segment cross the X line? */
27191 if (x0 >= x)
27193 if (x1 >= x)
27194 continue;
27196 else if (x1 < x)
27197 continue;
27198 if (y > y0 && y > y1)
27199 continue;
27200 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
27201 inside = !inside;
27203 return inside;
27206 return 0;
27209 Lisp_Object
27210 find_hot_spot (Lisp_Object map, int x, int y)
27212 while (CONSP (map))
27214 if (CONSP (XCAR (map))
27215 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
27216 return XCAR (map);
27217 map = XCDR (map);
27220 return Qnil;
27223 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
27224 3, 3, 0,
27225 doc: /* Lookup in image map MAP coordinates X and Y.
27226 An image map is an alist where each element has the format (AREA ID PLIST).
27227 An AREA is specified as either a rectangle, a circle, or a polygon:
27228 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
27229 pixel coordinates of the upper left and bottom right corners.
27230 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
27231 and the radius of the circle; r may be a float or integer.
27232 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
27233 vector describes one corner in the polygon.
27234 Returns the alist element for the first matching AREA in MAP. */)
27235 (Lisp_Object map, Lisp_Object x, Lisp_Object y)
27237 if (NILP (map))
27238 return Qnil;
27240 CHECK_NUMBER (x);
27241 CHECK_NUMBER (y);
27243 return find_hot_spot (map,
27244 clip_to_bounds (INT_MIN, XINT (x), INT_MAX),
27245 clip_to_bounds (INT_MIN, XINT (y), INT_MAX));
27249 /* Display frame CURSOR, optionally using shape defined by POINTER. */
27250 static void
27251 define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
27253 /* Do not change cursor shape while dragging mouse. */
27254 if (!NILP (do_mouse_tracking))
27255 return;
27257 if (!NILP (pointer))
27259 if (EQ (pointer, Qarrow))
27260 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27261 else if (EQ (pointer, Qhand))
27262 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
27263 else if (EQ (pointer, Qtext))
27264 cursor = FRAME_X_OUTPUT (f)->text_cursor;
27265 else if (EQ (pointer, intern ("hdrag")))
27266 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
27267 #ifdef HAVE_X_WINDOWS
27268 else if (EQ (pointer, intern ("vdrag")))
27269 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
27270 #endif
27271 else if (EQ (pointer, intern ("hourglass")))
27272 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
27273 else if (EQ (pointer, Qmodeline))
27274 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
27275 else
27276 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27279 if (cursor != No_Cursor)
27280 FRAME_RIF (f)->define_frame_cursor (f, cursor);
27283 #endif /* HAVE_WINDOW_SYSTEM */
27285 /* Take proper action when mouse has moved to the mode or header line
27286 or marginal area AREA of window W, x-position X and y-position Y.
27287 X is relative to the start of the text display area of W, so the
27288 width of bitmap areas and scroll bars must be subtracted to get a
27289 position relative to the start of the mode line. */
27291 static void
27292 note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
27293 enum window_part area)
27295 struct window *w = XWINDOW (window);
27296 struct frame *f = XFRAME (w->frame);
27297 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
27298 #ifdef HAVE_WINDOW_SYSTEM
27299 Display_Info *dpyinfo;
27300 #endif
27301 Cursor cursor = No_Cursor;
27302 Lisp_Object pointer = Qnil;
27303 int dx, dy, width, height;
27304 ptrdiff_t charpos;
27305 Lisp_Object string, object = Qnil;
27306 Lisp_Object pos IF_LINT (= Qnil), help;
27308 Lisp_Object mouse_face;
27309 int original_x_pixel = x;
27310 struct glyph * glyph = NULL, * row_start_glyph = NULL;
27311 struct glyph_row *row IF_LINT (= 0);
27313 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
27315 int x0;
27316 struct glyph *end;
27318 /* Kludge alert: mode_line_string takes X/Y in pixels, but
27319 returns them in row/column units! */
27320 string = mode_line_string (w, area, &x, &y, &charpos,
27321 &object, &dx, &dy, &width, &height);
27323 row = (area == ON_MODE_LINE
27324 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
27325 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
27327 /* Find the glyph under the mouse pointer. */
27328 if (row->mode_line_p && row->enabled_p)
27330 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
27331 end = glyph + row->used[TEXT_AREA];
27333 for (x0 = original_x_pixel;
27334 glyph < end && x0 >= glyph->pixel_width;
27335 ++glyph)
27336 x0 -= glyph->pixel_width;
27338 if (glyph >= end)
27339 glyph = NULL;
27342 else
27344 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
27345 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
27346 returns them in row/column units! */
27347 string = marginal_area_string (w, area, &x, &y, &charpos,
27348 &object, &dx, &dy, &width, &height);
27351 help = Qnil;
27353 #ifdef HAVE_WINDOW_SYSTEM
27354 if (IMAGEP (object))
27356 Lisp_Object image_map, hotspot;
27357 if ((image_map = Fplist_get (XCDR (object), QCmap),
27358 !NILP (image_map))
27359 && (hotspot = find_hot_spot (image_map, dx, dy),
27360 CONSP (hotspot))
27361 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
27363 Lisp_Object plist;
27365 /* Could check XCAR (hotspot) to see if we enter/leave this hot-spot.
27366 If so, we could look for mouse-enter, mouse-leave
27367 properties in PLIST (and do something...). */
27368 hotspot = XCDR (hotspot);
27369 if (CONSP (hotspot)
27370 && (plist = XCAR (hotspot), CONSP (plist)))
27372 pointer = Fplist_get (plist, Qpointer);
27373 if (NILP (pointer))
27374 pointer = Qhand;
27375 help = Fplist_get (plist, Qhelp_echo);
27376 if (!NILP (help))
27378 help_echo_string = help;
27379 XSETWINDOW (help_echo_window, w);
27380 help_echo_object = w->contents;
27381 help_echo_pos = charpos;
27385 if (NILP (pointer))
27386 pointer = Fplist_get (XCDR (object), QCpointer);
27388 #endif /* HAVE_WINDOW_SYSTEM */
27390 if (STRINGP (string))
27391 pos = make_number (charpos);
27393 /* Set the help text and mouse pointer. If the mouse is on a part
27394 of the mode line without any text (e.g. past the right edge of
27395 the mode line text), use the default help text and pointer. */
27396 if (STRINGP (string) || area == ON_MODE_LINE)
27398 /* Arrange to display the help by setting the global variables
27399 help_echo_string, help_echo_object, and help_echo_pos. */
27400 if (NILP (help))
27402 if (STRINGP (string))
27403 help = Fget_text_property (pos, Qhelp_echo, string);
27405 if (!NILP (help))
27407 help_echo_string = help;
27408 XSETWINDOW (help_echo_window, w);
27409 help_echo_object = string;
27410 help_echo_pos = charpos;
27412 else if (area == ON_MODE_LINE)
27414 Lisp_Object default_help
27415 = buffer_local_value_1 (Qmode_line_default_help_echo,
27416 w->contents);
27418 if (STRINGP (default_help))
27420 help_echo_string = default_help;
27421 XSETWINDOW (help_echo_window, w);
27422 help_echo_object = Qnil;
27423 help_echo_pos = -1;
27428 #ifdef HAVE_WINDOW_SYSTEM
27429 /* Change the mouse pointer according to what is under it. */
27430 if (FRAME_WINDOW_P (f))
27432 dpyinfo = FRAME_X_DISPLAY_INFO (f);
27433 if (STRINGP (string))
27435 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27437 if (NILP (pointer))
27438 pointer = Fget_text_property (pos, Qpointer, string);
27440 /* Change the mouse pointer according to what is under X/Y. */
27441 if (NILP (pointer)
27442 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
27444 Lisp_Object map;
27445 map = Fget_text_property (pos, Qlocal_map, string);
27446 if (!KEYMAPP (map))
27447 map = Fget_text_property (pos, Qkeymap, string);
27448 if (!KEYMAPP (map))
27449 cursor = dpyinfo->vertical_scroll_bar_cursor;
27452 else
27453 /* Default mode-line pointer. */
27454 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
27456 #endif
27459 /* Change the mouse face according to what is under X/Y. */
27460 if (STRINGP (string))
27462 mouse_face = Fget_text_property (pos, Qmouse_face, string);
27463 if (!NILP (Vmouse_highlight) && !NILP (mouse_face)
27464 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
27465 && glyph)
27467 Lisp_Object b, e;
27469 struct glyph * tmp_glyph;
27471 int gpos;
27472 int gseq_length;
27473 int total_pixel_width;
27474 ptrdiff_t begpos, endpos, ignore;
27476 int vpos, hpos;
27478 b = Fprevious_single_property_change (make_number (charpos + 1),
27479 Qmouse_face, string, Qnil);
27480 if (NILP (b))
27481 begpos = 0;
27482 else
27483 begpos = XINT (b);
27485 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
27486 if (NILP (e))
27487 endpos = SCHARS (string);
27488 else
27489 endpos = XINT (e);
27491 /* Calculate the glyph position GPOS of GLYPH in the
27492 displayed string, relative to the beginning of the
27493 highlighted part of the string.
27495 Note: GPOS is different from CHARPOS. CHARPOS is the
27496 position of GLYPH in the internal string object. A mode
27497 line string format has structures which are converted to
27498 a flattened string by the Emacs Lisp interpreter. The
27499 internal string is an element of those structures. The
27500 displayed string is the flattened string. */
27501 tmp_glyph = row_start_glyph;
27502 while (tmp_glyph < glyph
27503 && (!(EQ (tmp_glyph->object, glyph->object)
27504 && begpos <= tmp_glyph->charpos
27505 && tmp_glyph->charpos < endpos)))
27506 tmp_glyph++;
27507 gpos = glyph - tmp_glyph;
27509 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
27510 the highlighted part of the displayed string to which
27511 GLYPH belongs. Note: GSEQ_LENGTH is different from
27512 SCHARS (STRING), because the latter returns the length of
27513 the internal string. */
27514 for (tmp_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
27515 tmp_glyph > glyph
27516 && (!(EQ (tmp_glyph->object, glyph->object)
27517 && begpos <= tmp_glyph->charpos
27518 && tmp_glyph->charpos < endpos));
27519 tmp_glyph--)
27521 gseq_length = gpos + (tmp_glyph - glyph) + 1;
27523 /* Calculate the total pixel width of all the glyphs between
27524 the beginning of the highlighted area and GLYPH. */
27525 total_pixel_width = 0;
27526 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
27527 total_pixel_width += tmp_glyph->pixel_width;
27529 /* Pre calculation of re-rendering position. Note: X is in
27530 column units here, after the call to mode_line_string or
27531 marginal_area_string. */
27532 hpos = x - gpos;
27533 vpos = (area == ON_MODE_LINE
27534 ? (w->current_matrix)->nrows - 1
27535 : 0);
27537 /* If GLYPH's position is included in the region that is
27538 already drawn in mouse face, we have nothing to do. */
27539 if ( EQ (window, hlinfo->mouse_face_window)
27540 && (!row->reversed_p
27541 ? (hlinfo->mouse_face_beg_col <= hpos
27542 && hpos < hlinfo->mouse_face_end_col)
27543 /* In R2L rows we swap BEG and END, see below. */
27544 : (hlinfo->mouse_face_end_col <= hpos
27545 && hpos < hlinfo->mouse_face_beg_col))
27546 && hlinfo->mouse_face_beg_row == vpos )
27547 return;
27549 if (clear_mouse_face (hlinfo))
27550 cursor = No_Cursor;
27552 if (!row->reversed_p)
27554 hlinfo->mouse_face_beg_col = hpos;
27555 hlinfo->mouse_face_beg_x = original_x_pixel
27556 - (total_pixel_width + dx);
27557 hlinfo->mouse_face_end_col = hpos + gseq_length;
27558 hlinfo->mouse_face_end_x = 0;
27560 else
27562 /* In R2L rows, show_mouse_face expects BEG and END
27563 coordinates to be swapped. */
27564 hlinfo->mouse_face_end_col = hpos;
27565 hlinfo->mouse_face_end_x = original_x_pixel
27566 - (total_pixel_width + dx);
27567 hlinfo->mouse_face_beg_col = hpos + gseq_length;
27568 hlinfo->mouse_face_beg_x = 0;
27571 hlinfo->mouse_face_beg_row = vpos;
27572 hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row;
27573 hlinfo->mouse_face_beg_y = 0;
27574 hlinfo->mouse_face_end_y = 0;
27575 hlinfo->mouse_face_past_end = 0;
27576 hlinfo->mouse_face_window = window;
27578 hlinfo->mouse_face_face_id = face_at_string_position (w, string,
27579 charpos,
27580 0, 0, 0,
27581 &ignore,
27582 glyph->face_id,
27584 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
27586 if (NILP (pointer))
27587 pointer = Qhand;
27589 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
27590 clear_mouse_face (hlinfo);
27592 #ifdef HAVE_WINDOW_SYSTEM
27593 if (FRAME_WINDOW_P (f))
27594 define_frame_cursor1 (f, cursor, pointer);
27595 #endif
27599 /* EXPORT:
27600 Take proper action when the mouse has moved to position X, Y on
27601 frame F with regards to highlighting portions of display that have
27602 mouse-face properties. Also de-highlight portions of display where
27603 the mouse was before, set the mouse pointer shape as appropriate
27604 for the mouse coordinates, and activate help echo (tooltips).
27605 X and Y can be negative or out of range. */
27607 void
27608 note_mouse_highlight (struct frame *f, int x, int y)
27610 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
27611 enum window_part part = ON_NOTHING;
27612 Lisp_Object window;
27613 struct window *w;
27614 Cursor cursor = No_Cursor;
27615 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
27616 struct buffer *b;
27618 /* When a menu is active, don't highlight because this looks odd. */
27619 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
27620 if (popup_activated ())
27621 return;
27622 #endif
27624 if (!f->glyphs_initialized_p
27625 || f->pointer_invisible)
27626 return;
27628 hlinfo->mouse_face_mouse_x = x;
27629 hlinfo->mouse_face_mouse_y = y;
27630 hlinfo->mouse_face_mouse_frame = f;
27632 if (hlinfo->mouse_face_defer)
27633 return;
27635 /* Which window is that in? */
27636 window = window_from_coordinates (f, x, y, &part, 1);
27638 /* If displaying active text in another window, clear that. */
27639 if (! EQ (window, hlinfo->mouse_face_window)
27640 /* Also clear if we move out of text area in same window. */
27641 || (!NILP (hlinfo->mouse_face_window)
27642 && !NILP (window)
27643 && part != ON_TEXT
27644 && part != ON_MODE_LINE
27645 && part != ON_HEADER_LINE))
27646 clear_mouse_face (hlinfo);
27648 /* Not on a window -> return. */
27649 if (!WINDOWP (window))
27650 return;
27652 /* Reset help_echo_string. It will get recomputed below. */
27653 help_echo_string = Qnil;
27655 /* Convert to window-relative pixel coordinates. */
27656 w = XWINDOW (window);
27657 frame_to_window_pixel_xy (w, &x, &y);
27659 #ifdef HAVE_WINDOW_SYSTEM
27660 /* Handle tool-bar window differently since it doesn't display a
27661 buffer. */
27662 if (EQ (window, f->tool_bar_window))
27664 note_tool_bar_highlight (f, x, y);
27665 return;
27667 #endif
27669 /* Mouse is on the mode, header line or margin? */
27670 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
27671 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
27673 note_mode_line_or_margin_highlight (window, x, y, part);
27674 return;
27677 #ifdef HAVE_WINDOW_SYSTEM
27678 if (part == ON_VERTICAL_BORDER)
27680 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
27681 help_echo_string = build_string ("drag-mouse-1: resize");
27683 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
27684 || part == ON_SCROLL_BAR)
27685 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27686 else
27687 cursor = FRAME_X_OUTPUT (f)->text_cursor;
27688 #endif
27690 /* Are we in a window whose display is up to date?
27691 And verify the buffer's text has not changed. */
27692 b = XBUFFER (w->contents);
27693 if (part == ON_TEXT
27694 && w->window_end_valid
27695 && w->last_modified == BUF_MODIFF (b)
27696 && w->last_overlay_modified == BUF_OVERLAY_MODIFF (b))
27698 int hpos, vpos, dx, dy, area = LAST_AREA;
27699 ptrdiff_t pos;
27700 struct glyph *glyph;
27701 Lisp_Object object;
27702 Lisp_Object mouse_face = Qnil, position;
27703 Lisp_Object *overlay_vec = NULL;
27704 ptrdiff_t i, noverlays;
27705 struct buffer *obuf;
27706 ptrdiff_t obegv, ozv;
27707 int same_region;
27709 /* Find the glyph under X/Y. */
27710 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
27712 #ifdef HAVE_WINDOW_SYSTEM
27713 /* Look for :pointer property on image. */
27714 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
27716 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
27717 if (img != NULL && IMAGEP (img->spec))
27719 Lisp_Object image_map, hotspot;
27720 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
27721 !NILP (image_map))
27722 && (hotspot = find_hot_spot (image_map,
27723 glyph->slice.img.x + dx,
27724 glyph->slice.img.y + dy),
27725 CONSP (hotspot))
27726 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
27728 Lisp_Object plist;
27730 /* Could check XCAR (hotspot) to see if we enter/leave
27731 this hot-spot.
27732 If so, we could look for mouse-enter, mouse-leave
27733 properties in PLIST (and do something...). */
27734 hotspot = XCDR (hotspot);
27735 if (CONSP (hotspot)
27736 && (plist = XCAR (hotspot), CONSP (plist)))
27738 pointer = Fplist_get (plist, Qpointer);
27739 if (NILP (pointer))
27740 pointer = Qhand;
27741 help_echo_string = Fplist_get (plist, Qhelp_echo);
27742 if (!NILP (help_echo_string))
27744 help_echo_window = window;
27745 help_echo_object = glyph->object;
27746 help_echo_pos = glyph->charpos;
27750 if (NILP (pointer))
27751 pointer = Fplist_get (XCDR (img->spec), QCpointer);
27754 #endif /* HAVE_WINDOW_SYSTEM */
27756 /* Clear mouse face if X/Y not over text. */
27757 if (glyph == NULL
27758 || area != TEXT_AREA
27759 || !MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->current_matrix, vpos))
27760 /* Glyph's OBJECT is an integer for glyphs inserted by the
27761 display engine for its internal purposes, like truncation
27762 and continuation glyphs and blanks beyond the end of
27763 line's text on text terminals. If we are over such a
27764 glyph, we are not over any text. */
27765 || INTEGERP (glyph->object)
27766 /* R2L rows have a stretch glyph at their front, which
27767 stands for no text, whereas L2R rows have no glyphs at
27768 all beyond the end of text. Treat such stretch glyphs
27769 like we do with NULL glyphs in L2R rows. */
27770 || (MATRIX_ROW (w->current_matrix, vpos)->reversed_p
27771 && glyph == MATRIX_ROW_GLYPH_START (w->current_matrix, vpos)
27772 && glyph->type == STRETCH_GLYPH
27773 && glyph->avoid_cursor_p))
27775 if (clear_mouse_face (hlinfo))
27776 cursor = No_Cursor;
27777 #ifdef HAVE_WINDOW_SYSTEM
27778 if (FRAME_WINDOW_P (f) && NILP (pointer))
27780 if (area != TEXT_AREA)
27781 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27782 else
27783 pointer = Vvoid_text_area_pointer;
27785 #endif
27786 goto set_cursor;
27789 pos = glyph->charpos;
27790 object = glyph->object;
27791 if (!STRINGP (object) && !BUFFERP (object))
27792 goto set_cursor;
27794 /* If we get an out-of-range value, return now; avoid an error. */
27795 if (BUFFERP (object) && pos > BUF_Z (b))
27796 goto set_cursor;
27798 /* Make the window's buffer temporarily current for
27799 overlays_at and compute_char_face. */
27800 obuf = current_buffer;
27801 current_buffer = b;
27802 obegv = BEGV;
27803 ozv = ZV;
27804 BEGV = BEG;
27805 ZV = Z;
27807 /* Is this char mouse-active or does it have help-echo? */
27808 position = make_number (pos);
27810 if (BUFFERP (object))
27812 /* Put all the overlays we want in a vector in overlay_vec. */
27813 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
27814 /* Sort overlays into increasing priority order. */
27815 noverlays = sort_overlays (overlay_vec, noverlays, w);
27817 else
27818 noverlays = 0;
27820 if (NILP (Vmouse_highlight))
27822 clear_mouse_face (hlinfo);
27823 goto check_help_echo;
27826 same_region = coords_in_mouse_face_p (w, hpos, vpos);
27828 if (same_region)
27829 cursor = No_Cursor;
27831 /* Check mouse-face highlighting. */
27832 if (! same_region
27833 /* If there exists an overlay with mouse-face overlapping
27834 the one we are currently highlighting, we have to
27835 check if we enter the overlapping overlay, and then
27836 highlight only that. */
27837 || (OVERLAYP (hlinfo->mouse_face_overlay)
27838 && mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
27840 /* Find the highest priority overlay with a mouse-face. */
27841 Lisp_Object overlay = Qnil;
27842 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
27844 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
27845 if (!NILP (mouse_face))
27846 overlay = overlay_vec[i];
27849 /* If we're highlighting the same overlay as before, there's
27850 no need to do that again. */
27851 if (!NILP (overlay) && EQ (overlay, hlinfo->mouse_face_overlay))
27852 goto check_help_echo;
27853 hlinfo->mouse_face_overlay = overlay;
27855 /* Clear the display of the old active region, if any. */
27856 if (clear_mouse_face (hlinfo))
27857 cursor = No_Cursor;
27859 /* If no overlay applies, get a text property. */
27860 if (NILP (overlay))
27861 mouse_face = Fget_text_property (position, Qmouse_face, object);
27863 /* Next, compute the bounds of the mouse highlighting and
27864 display it. */
27865 if (!NILP (mouse_face) && STRINGP (object))
27867 /* The mouse-highlighting comes from a display string
27868 with a mouse-face. */
27869 Lisp_Object s, e;
27870 ptrdiff_t ignore;
27872 s = Fprevious_single_property_change
27873 (make_number (pos + 1), Qmouse_face, object, Qnil);
27874 e = Fnext_single_property_change
27875 (position, Qmouse_face, object, Qnil);
27876 if (NILP (s))
27877 s = make_number (0);
27878 if (NILP (e))
27879 e = make_number (SCHARS (object) - 1);
27880 mouse_face_from_string_pos (w, hlinfo, object,
27881 XINT (s), XINT (e));
27882 hlinfo->mouse_face_past_end = 0;
27883 hlinfo->mouse_face_window = window;
27884 hlinfo->mouse_face_face_id
27885 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
27886 glyph->face_id, 1);
27887 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
27888 cursor = No_Cursor;
27890 else
27892 /* The mouse-highlighting, if any, comes from an overlay
27893 or text property in the buffer. */
27894 Lisp_Object buffer IF_LINT (= Qnil);
27895 Lisp_Object disp_string IF_LINT (= Qnil);
27897 if (STRINGP (object))
27899 /* If we are on a display string with no mouse-face,
27900 check if the text under it has one. */
27901 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
27902 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
27903 pos = string_buffer_position (object, start);
27904 if (pos > 0)
27906 mouse_face = get_char_property_and_overlay
27907 (make_number (pos), Qmouse_face, w->contents, &overlay);
27908 buffer = w->contents;
27909 disp_string = object;
27912 else
27914 buffer = object;
27915 disp_string = Qnil;
27918 if (!NILP (mouse_face))
27920 Lisp_Object before, after;
27921 Lisp_Object before_string, after_string;
27922 /* To correctly find the limits of mouse highlight
27923 in a bidi-reordered buffer, we must not use the
27924 optimization of limiting the search in
27925 previous-single-property-change and
27926 next-single-property-change, because
27927 rows_from_pos_range needs the real start and end
27928 positions to DTRT in this case. That's because
27929 the first row visible in a window does not
27930 necessarily display the character whose position
27931 is the smallest. */
27932 Lisp_Object lim1 =
27933 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
27934 ? Fmarker_position (w->start)
27935 : Qnil;
27936 Lisp_Object lim2 =
27937 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
27938 ? make_number (BUF_Z (XBUFFER (buffer))
27939 - XFASTINT (w->window_end_pos))
27940 : Qnil;
27942 if (NILP (overlay))
27944 /* Handle the text property case. */
27945 before = Fprevious_single_property_change
27946 (make_number (pos + 1), Qmouse_face, buffer, lim1);
27947 after = Fnext_single_property_change
27948 (make_number (pos), Qmouse_face, buffer, lim2);
27949 before_string = after_string = Qnil;
27951 else
27953 /* Handle the overlay case. */
27954 before = Foverlay_start (overlay);
27955 after = Foverlay_end (overlay);
27956 before_string = Foverlay_get (overlay, Qbefore_string);
27957 after_string = Foverlay_get (overlay, Qafter_string);
27959 if (!STRINGP (before_string)) before_string = Qnil;
27960 if (!STRINGP (after_string)) after_string = Qnil;
27963 mouse_face_from_buffer_pos (window, hlinfo, pos,
27964 NILP (before)
27966 : XFASTINT (before),
27967 NILP (after)
27968 ? BUF_Z (XBUFFER (buffer))
27969 : XFASTINT (after),
27970 before_string, after_string,
27971 disp_string);
27972 cursor = No_Cursor;
27977 check_help_echo:
27979 /* Look for a `help-echo' property. */
27980 if (NILP (help_echo_string)) {
27981 Lisp_Object help, overlay;
27983 /* Check overlays first. */
27984 help = overlay = Qnil;
27985 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
27987 overlay = overlay_vec[i];
27988 help = Foverlay_get (overlay, Qhelp_echo);
27991 if (!NILP (help))
27993 help_echo_string = help;
27994 help_echo_window = window;
27995 help_echo_object = overlay;
27996 help_echo_pos = pos;
27998 else
28000 Lisp_Object obj = glyph->object;
28001 ptrdiff_t charpos = glyph->charpos;
28003 /* Try text properties. */
28004 if (STRINGP (obj)
28005 && charpos >= 0
28006 && charpos < SCHARS (obj))
28008 help = Fget_text_property (make_number (charpos),
28009 Qhelp_echo, obj);
28010 if (NILP (help))
28012 /* If the string itself doesn't specify a help-echo,
28013 see if the buffer text ``under'' it does. */
28014 struct glyph_row *r
28015 = MATRIX_ROW (w->current_matrix, vpos);
28016 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
28017 ptrdiff_t p = string_buffer_position (obj, start);
28018 if (p > 0)
28020 help = Fget_char_property (make_number (p),
28021 Qhelp_echo, w->contents);
28022 if (!NILP (help))
28024 charpos = p;
28025 obj = w->contents;
28030 else if (BUFFERP (obj)
28031 && charpos >= BEGV
28032 && charpos < ZV)
28033 help = Fget_text_property (make_number (charpos), Qhelp_echo,
28034 obj);
28036 if (!NILP (help))
28038 help_echo_string = help;
28039 help_echo_window = window;
28040 help_echo_object = obj;
28041 help_echo_pos = charpos;
28046 #ifdef HAVE_WINDOW_SYSTEM
28047 /* Look for a `pointer' property. */
28048 if (FRAME_WINDOW_P (f) && NILP (pointer))
28050 /* Check overlays first. */
28051 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
28052 pointer = Foverlay_get (overlay_vec[i], Qpointer);
28054 if (NILP (pointer))
28056 Lisp_Object obj = glyph->object;
28057 ptrdiff_t charpos = glyph->charpos;
28059 /* Try text properties. */
28060 if (STRINGP (obj)
28061 && charpos >= 0
28062 && charpos < SCHARS (obj))
28064 pointer = Fget_text_property (make_number (charpos),
28065 Qpointer, obj);
28066 if (NILP (pointer))
28068 /* If the string itself doesn't specify a pointer,
28069 see if the buffer text ``under'' it does. */
28070 struct glyph_row *r
28071 = MATRIX_ROW (w->current_matrix, vpos);
28072 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
28073 ptrdiff_t p = string_buffer_position (obj, start);
28074 if (p > 0)
28075 pointer = Fget_char_property (make_number (p),
28076 Qpointer, w->contents);
28079 else if (BUFFERP (obj)
28080 && charpos >= BEGV
28081 && charpos < ZV)
28082 pointer = Fget_text_property (make_number (charpos),
28083 Qpointer, obj);
28086 #endif /* HAVE_WINDOW_SYSTEM */
28088 BEGV = obegv;
28089 ZV = ozv;
28090 current_buffer = obuf;
28093 set_cursor:
28095 #ifdef HAVE_WINDOW_SYSTEM
28096 if (FRAME_WINDOW_P (f))
28097 define_frame_cursor1 (f, cursor, pointer);
28098 #else
28099 /* This is here to prevent a compiler error, about "label at end of
28100 compound statement". */
28101 return;
28102 #endif
28106 /* EXPORT for RIF:
28107 Clear any mouse-face on window W. This function is part of the
28108 redisplay interface, and is called from try_window_id and similar
28109 functions to ensure the mouse-highlight is off. */
28111 void
28112 x_clear_window_mouse_face (struct window *w)
28114 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
28115 Lisp_Object window;
28117 block_input ();
28118 XSETWINDOW (window, w);
28119 if (EQ (window, hlinfo->mouse_face_window))
28120 clear_mouse_face (hlinfo);
28121 unblock_input ();
28125 /* EXPORT:
28126 Just discard the mouse face information for frame F, if any.
28127 This is used when the size of F is changed. */
28129 void
28130 cancel_mouse_face (struct frame *f)
28132 Lisp_Object window;
28133 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
28135 window = hlinfo->mouse_face_window;
28136 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
28138 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
28139 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
28140 hlinfo->mouse_face_window = Qnil;
28146 /***********************************************************************
28147 Exposure Events
28148 ***********************************************************************/
28150 #ifdef HAVE_WINDOW_SYSTEM
28152 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
28153 which intersects rectangle R. R is in window-relative coordinates. */
28155 static void
28156 expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
28157 enum glyph_row_area area)
28159 struct glyph *first = row->glyphs[area];
28160 struct glyph *end = row->glyphs[area] + row->used[area];
28161 struct glyph *last;
28162 int first_x, start_x, x;
28164 if (area == TEXT_AREA && row->fill_line_p)
28165 /* If row extends face to end of line write the whole line. */
28166 draw_glyphs (w, 0, row, area,
28167 0, row->used[area],
28168 DRAW_NORMAL_TEXT, 0);
28169 else
28171 /* Set START_X to the window-relative start position for drawing glyphs of
28172 AREA. The first glyph of the text area can be partially visible.
28173 The first glyphs of other areas cannot. */
28174 start_x = window_box_left_offset (w, area);
28175 x = start_x;
28176 if (area == TEXT_AREA)
28177 x += row->x;
28179 /* Find the first glyph that must be redrawn. */
28180 while (first < end
28181 && x + first->pixel_width < r->x)
28183 x += first->pixel_width;
28184 ++first;
28187 /* Find the last one. */
28188 last = first;
28189 first_x = x;
28190 while (last < end
28191 && x < r->x + r->width)
28193 x += last->pixel_width;
28194 ++last;
28197 /* Repaint. */
28198 if (last > first)
28199 draw_glyphs (w, first_x - start_x, row, area,
28200 first - row->glyphs[area], last - row->glyphs[area],
28201 DRAW_NORMAL_TEXT, 0);
28206 /* Redraw the parts of the glyph row ROW on window W intersecting
28207 rectangle R. R is in window-relative coordinates. Value is
28208 non-zero if mouse-face was overwritten. */
28210 static int
28211 expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
28213 eassert (row->enabled_p);
28215 if (row->mode_line_p || w->pseudo_window_p)
28216 draw_glyphs (w, 0, row, TEXT_AREA,
28217 0, row->used[TEXT_AREA],
28218 DRAW_NORMAL_TEXT, 0);
28219 else
28221 if (row->used[LEFT_MARGIN_AREA])
28222 expose_area (w, row, r, LEFT_MARGIN_AREA);
28223 if (row->used[TEXT_AREA])
28224 expose_area (w, row, r, TEXT_AREA);
28225 if (row->used[RIGHT_MARGIN_AREA])
28226 expose_area (w, row, r, RIGHT_MARGIN_AREA);
28227 draw_row_fringe_bitmaps (w, row);
28230 return row->mouse_face_p;
28234 /* Redraw those parts of glyphs rows during expose event handling that
28235 overlap other rows. Redrawing of an exposed line writes over parts
28236 of lines overlapping that exposed line; this function fixes that.
28238 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
28239 row in W's current matrix that is exposed and overlaps other rows.
28240 LAST_OVERLAPPING_ROW is the last such row. */
28242 static void
28243 expose_overlaps (struct window *w,
28244 struct glyph_row *first_overlapping_row,
28245 struct glyph_row *last_overlapping_row,
28246 XRectangle *r)
28248 struct glyph_row *row;
28250 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
28251 if (row->overlapping_p)
28253 eassert (row->enabled_p && !row->mode_line_p);
28255 row->clip = r;
28256 if (row->used[LEFT_MARGIN_AREA])
28257 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
28259 if (row->used[TEXT_AREA])
28260 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
28262 if (row->used[RIGHT_MARGIN_AREA])
28263 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
28264 row->clip = NULL;
28269 /* Return non-zero if W's cursor intersects rectangle R. */
28271 static int
28272 phys_cursor_in_rect_p (struct window *w, XRectangle *r)
28274 XRectangle cr, result;
28275 struct glyph *cursor_glyph;
28276 struct glyph_row *row;
28278 if (w->phys_cursor.vpos >= 0
28279 && w->phys_cursor.vpos < w->current_matrix->nrows
28280 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
28281 row->enabled_p)
28282 && row->cursor_in_fringe_p)
28284 /* Cursor is in the fringe. */
28285 cr.x = window_box_right_offset (w,
28286 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
28287 ? RIGHT_MARGIN_AREA
28288 : TEXT_AREA));
28289 cr.y = row->y;
28290 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
28291 cr.height = row->height;
28292 return x_intersect_rectangles (&cr, r, &result);
28295 cursor_glyph = get_phys_cursor_glyph (w);
28296 if (cursor_glyph)
28298 /* r is relative to W's box, but w->phys_cursor.x is relative
28299 to left edge of W's TEXT area. Adjust it. */
28300 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
28301 cr.y = w->phys_cursor.y;
28302 cr.width = cursor_glyph->pixel_width;
28303 cr.height = w->phys_cursor_height;
28304 /* ++KFS: W32 version used W32-specific IntersectRect here, but
28305 I assume the effect is the same -- and this is portable. */
28306 return x_intersect_rectangles (&cr, r, &result);
28308 /* If we don't understand the format, pretend we're not in the hot-spot. */
28309 return 0;
28313 /* EXPORT:
28314 Draw a vertical window border to the right of window W if W doesn't
28315 have vertical scroll bars. */
28317 void
28318 x_draw_vertical_border (struct window *w)
28320 struct frame *f = XFRAME (WINDOW_FRAME (w));
28322 /* We could do better, if we knew what type of scroll-bar the adjacent
28323 windows (on either side) have... But we don't :-(
28324 However, I think this works ok. ++KFS 2003-04-25 */
28326 /* Redraw borders between horizontally adjacent windows. Don't
28327 do it for frames with vertical scroll bars because either the
28328 right scroll bar of a window, or the left scroll bar of its
28329 neighbor will suffice as a border. */
28330 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
28331 return;
28333 /* Note: It is necessary to redraw both the left and the right
28334 borders, for when only this single window W is being
28335 redisplayed. */
28336 if (!WINDOW_RIGHTMOST_P (w)
28337 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
28339 int x0, x1, y0, y1;
28341 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
28342 y1 -= 1;
28344 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
28345 x1 -= 1;
28347 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
28349 if (!WINDOW_LEFTMOST_P (w)
28350 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
28352 int x0, x1, y0, y1;
28354 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
28355 y1 -= 1;
28357 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
28358 x0 -= 1;
28360 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
28365 /* Redraw the part of window W intersection rectangle FR. Pixel
28366 coordinates in FR are frame-relative. Call this function with
28367 input blocked. Value is non-zero if the exposure overwrites
28368 mouse-face. */
28370 static int
28371 expose_window (struct window *w, XRectangle *fr)
28373 struct frame *f = XFRAME (w->frame);
28374 XRectangle wr, r;
28375 int mouse_face_overwritten_p = 0;
28377 /* If window is not yet fully initialized, do nothing. This can
28378 happen when toolkit scroll bars are used and a window is split.
28379 Reconfiguring the scroll bar will generate an expose for a newly
28380 created window. */
28381 if (w->current_matrix == NULL)
28382 return 0;
28384 /* When we're currently updating the window, display and current
28385 matrix usually don't agree. Arrange for a thorough display
28386 later. */
28387 if (w == updated_window)
28389 SET_FRAME_GARBAGED (f);
28390 return 0;
28393 /* Frame-relative pixel rectangle of W. */
28394 wr.x = WINDOW_LEFT_EDGE_X (w);
28395 wr.y = WINDOW_TOP_EDGE_Y (w);
28396 wr.width = WINDOW_TOTAL_WIDTH (w);
28397 wr.height = WINDOW_TOTAL_HEIGHT (w);
28399 if (x_intersect_rectangles (fr, &wr, &r))
28401 int yb = window_text_bottom_y (w);
28402 struct glyph_row *row;
28403 int cursor_cleared_p, phys_cursor_on_p;
28404 struct glyph_row *first_overlapping_row, *last_overlapping_row;
28406 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
28407 r.x, r.y, r.width, r.height));
28409 /* Convert to window coordinates. */
28410 r.x -= WINDOW_LEFT_EDGE_X (w);
28411 r.y -= WINDOW_TOP_EDGE_Y (w);
28413 /* Turn off the cursor. */
28414 if (!w->pseudo_window_p
28415 && phys_cursor_in_rect_p (w, &r))
28417 x_clear_cursor (w);
28418 cursor_cleared_p = 1;
28420 else
28421 cursor_cleared_p = 0;
28423 /* If the row containing the cursor extends face to end of line,
28424 then expose_area might overwrite the cursor outside the
28425 rectangle and thus notice_overwritten_cursor might clear
28426 w->phys_cursor_on_p. We remember the original value and
28427 check later if it is changed. */
28428 phys_cursor_on_p = w->phys_cursor_on_p;
28430 /* Update lines intersecting rectangle R. */
28431 first_overlapping_row = last_overlapping_row = NULL;
28432 for (row = w->current_matrix->rows;
28433 row->enabled_p;
28434 ++row)
28436 int y0 = row->y;
28437 int y1 = MATRIX_ROW_BOTTOM_Y (row);
28439 if ((y0 >= r.y && y0 < r.y + r.height)
28440 || (y1 > r.y && y1 < r.y + r.height)
28441 || (r.y >= y0 && r.y < y1)
28442 || (r.y + r.height > y0 && r.y + r.height < y1))
28444 /* A header line may be overlapping, but there is no need
28445 to fix overlapping areas for them. KFS 2005-02-12 */
28446 if (row->overlapping_p && !row->mode_line_p)
28448 if (first_overlapping_row == NULL)
28449 first_overlapping_row = row;
28450 last_overlapping_row = row;
28453 row->clip = fr;
28454 if (expose_line (w, row, &r))
28455 mouse_face_overwritten_p = 1;
28456 row->clip = NULL;
28458 else if (row->overlapping_p)
28460 /* We must redraw a row overlapping the exposed area. */
28461 if (y0 < r.y
28462 ? y0 + row->phys_height > r.y
28463 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
28465 if (first_overlapping_row == NULL)
28466 first_overlapping_row = row;
28467 last_overlapping_row = row;
28471 if (y1 >= yb)
28472 break;
28475 /* Display the mode line if there is one. */
28476 if (WINDOW_WANTS_MODELINE_P (w)
28477 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
28478 row->enabled_p)
28479 && row->y < r.y + r.height)
28481 if (expose_line (w, row, &r))
28482 mouse_face_overwritten_p = 1;
28485 if (!w->pseudo_window_p)
28487 /* Fix the display of overlapping rows. */
28488 if (first_overlapping_row)
28489 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
28490 fr);
28492 /* Draw border between windows. */
28493 x_draw_vertical_border (w);
28495 /* Turn the cursor on again. */
28496 if (cursor_cleared_p
28497 || (phys_cursor_on_p && !w->phys_cursor_on_p))
28498 update_window_cursor (w, 1);
28502 return mouse_face_overwritten_p;
28507 /* Redraw (parts) of all windows in the window tree rooted at W that
28508 intersect R. R contains frame pixel coordinates. Value is
28509 non-zero if the exposure overwrites mouse-face. */
28511 static int
28512 expose_window_tree (struct window *w, XRectangle *r)
28514 struct frame *f = XFRAME (w->frame);
28515 int mouse_face_overwritten_p = 0;
28517 while (w && !FRAME_GARBAGED_P (f))
28519 if (WINDOWP (w->contents))
28520 mouse_face_overwritten_p
28521 |= expose_window_tree (XWINDOW (w->contents), r);
28522 else
28523 mouse_face_overwritten_p |= expose_window (w, r);
28525 w = NILP (w->next) ? NULL : XWINDOW (w->next);
28528 return mouse_face_overwritten_p;
28532 /* EXPORT:
28533 Redisplay an exposed area of frame F. X and Y are the upper-left
28534 corner of the exposed rectangle. W and H are width and height of
28535 the exposed area. All are pixel values. W or H zero means redraw
28536 the entire frame. */
28538 void
28539 expose_frame (struct frame *f, int x, int y, int w, int h)
28541 XRectangle r;
28542 int mouse_face_overwritten_p = 0;
28544 TRACE ((stderr, "expose_frame "));
28546 /* No need to redraw if frame will be redrawn soon. */
28547 if (FRAME_GARBAGED_P (f))
28549 TRACE ((stderr, " garbaged\n"));
28550 return;
28553 /* If basic faces haven't been realized yet, there is no point in
28554 trying to redraw anything. This can happen when we get an expose
28555 event while Emacs is starting, e.g. by moving another window. */
28556 if (FRAME_FACE_CACHE (f) == NULL
28557 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
28559 TRACE ((stderr, " no faces\n"));
28560 return;
28563 if (w == 0 || h == 0)
28565 r.x = r.y = 0;
28566 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
28567 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
28569 else
28571 r.x = x;
28572 r.y = y;
28573 r.width = w;
28574 r.height = h;
28577 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
28578 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
28580 if (WINDOWP (f->tool_bar_window))
28581 mouse_face_overwritten_p
28582 |= expose_window (XWINDOW (f->tool_bar_window), &r);
28584 #ifdef HAVE_X_WINDOWS
28585 #ifndef MSDOS
28586 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
28587 if (WINDOWP (f->menu_bar_window))
28588 mouse_face_overwritten_p
28589 |= expose_window (XWINDOW (f->menu_bar_window), &r);
28590 #endif /* not USE_X_TOOLKIT and not USE_GTK */
28591 #endif
28592 #endif
28594 /* Some window managers support a focus-follows-mouse style with
28595 delayed raising of frames. Imagine a partially obscured frame,
28596 and moving the mouse into partially obscured mouse-face on that
28597 frame. The visible part of the mouse-face will be highlighted,
28598 then the WM raises the obscured frame. With at least one WM, KDE
28599 2.1, Emacs is not getting any event for the raising of the frame
28600 (even tried with SubstructureRedirectMask), only Expose events.
28601 These expose events will draw text normally, i.e. not
28602 highlighted. Which means we must redo the highlight here.
28603 Subsume it under ``we love X''. --gerd 2001-08-15 */
28604 /* Included in Windows version because Windows most likely does not
28605 do the right thing if any third party tool offers
28606 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
28607 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
28609 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
28610 if (f == hlinfo->mouse_face_mouse_frame)
28612 int mouse_x = hlinfo->mouse_face_mouse_x;
28613 int mouse_y = hlinfo->mouse_face_mouse_y;
28614 clear_mouse_face (hlinfo);
28615 note_mouse_highlight (f, mouse_x, mouse_y);
28621 /* EXPORT:
28622 Determine the intersection of two rectangles R1 and R2. Return
28623 the intersection in *RESULT. Value is non-zero if RESULT is not
28624 empty. */
28627 x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
28629 XRectangle *left, *right;
28630 XRectangle *upper, *lower;
28631 int intersection_p = 0;
28633 /* Rearrange so that R1 is the left-most rectangle. */
28634 if (r1->x < r2->x)
28635 left = r1, right = r2;
28636 else
28637 left = r2, right = r1;
28639 /* X0 of the intersection is right.x0, if this is inside R1,
28640 otherwise there is no intersection. */
28641 if (right->x <= left->x + left->width)
28643 result->x = right->x;
28645 /* The right end of the intersection is the minimum of
28646 the right ends of left and right. */
28647 result->width = (min (left->x + left->width, right->x + right->width)
28648 - result->x);
28650 /* Same game for Y. */
28651 if (r1->y < r2->y)
28652 upper = r1, lower = r2;
28653 else
28654 upper = r2, lower = r1;
28656 /* The upper end of the intersection is lower.y0, if this is inside
28657 of upper. Otherwise, there is no intersection. */
28658 if (lower->y <= upper->y + upper->height)
28660 result->y = lower->y;
28662 /* The lower end of the intersection is the minimum of the lower
28663 ends of upper and lower. */
28664 result->height = (min (lower->y + lower->height,
28665 upper->y + upper->height)
28666 - result->y);
28667 intersection_p = 1;
28671 return intersection_p;
28674 #endif /* HAVE_WINDOW_SYSTEM */
28677 /***********************************************************************
28678 Initialization
28679 ***********************************************************************/
28681 void
28682 syms_of_xdisp (void)
28684 Vwith_echo_area_save_vector = Qnil;
28685 staticpro (&Vwith_echo_area_save_vector);
28687 Vmessage_stack = Qnil;
28688 staticpro (&Vmessage_stack);
28690 DEFSYM (Qinhibit_redisplay, "inhibit-redisplay");
28691 DEFSYM (Qredisplay_internal, "redisplay_internal (C function)");
28693 message_dolog_marker1 = Fmake_marker ();
28694 staticpro (&message_dolog_marker1);
28695 message_dolog_marker2 = Fmake_marker ();
28696 staticpro (&message_dolog_marker2);
28697 message_dolog_marker3 = Fmake_marker ();
28698 staticpro (&message_dolog_marker3);
28700 #ifdef GLYPH_DEBUG
28701 defsubr (&Sdump_frame_glyph_matrix);
28702 defsubr (&Sdump_glyph_matrix);
28703 defsubr (&Sdump_glyph_row);
28704 defsubr (&Sdump_tool_bar_row);
28705 defsubr (&Strace_redisplay);
28706 defsubr (&Strace_to_stderr);
28707 #endif
28708 #ifdef HAVE_WINDOW_SYSTEM
28709 defsubr (&Stool_bar_lines_needed);
28710 defsubr (&Slookup_image_map);
28711 #endif
28712 defsubr (&Sline_pixel_height);
28713 defsubr (&Sformat_mode_line);
28714 defsubr (&Sinvisible_p);
28715 defsubr (&Scurrent_bidi_paragraph_direction);
28717 DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook");
28718 DEFSYM (Qoverriding_terminal_local_map, "overriding-terminal-local-map");
28719 DEFSYM (Qoverriding_local_map, "overriding-local-map");
28720 DEFSYM (Qwindow_scroll_functions, "window-scroll-functions");
28721 DEFSYM (Qwindow_text_change_functions, "window-text-change-functions");
28722 DEFSYM (Qredisplay_end_trigger_functions, "redisplay-end-trigger-functions");
28723 DEFSYM (Qinhibit_point_motion_hooks, "inhibit-point-motion-hooks");
28724 DEFSYM (Qeval, "eval");
28725 DEFSYM (QCdata, ":data");
28726 DEFSYM (Qdisplay, "display");
28727 DEFSYM (Qspace_width, "space-width");
28728 DEFSYM (Qraise, "raise");
28729 DEFSYM (Qslice, "slice");
28730 DEFSYM (Qspace, "space");
28731 DEFSYM (Qmargin, "margin");
28732 DEFSYM (Qpointer, "pointer");
28733 DEFSYM (Qleft_margin, "left-margin");
28734 DEFSYM (Qright_margin, "right-margin");
28735 DEFSYM (Qcenter, "center");
28736 DEFSYM (Qline_height, "line-height");
28737 DEFSYM (QCalign_to, ":align-to");
28738 DEFSYM (QCrelative_width, ":relative-width");
28739 DEFSYM (QCrelative_height, ":relative-height");
28740 DEFSYM (QCeval, ":eval");
28741 DEFSYM (QCpropertize, ":propertize");
28742 DEFSYM (QCfile, ":file");
28743 DEFSYM (Qfontified, "fontified");
28744 DEFSYM (Qfontification_functions, "fontification-functions");
28745 DEFSYM (Qtrailing_whitespace, "trailing-whitespace");
28746 DEFSYM (Qescape_glyph, "escape-glyph");
28747 DEFSYM (Qnobreak_space, "nobreak-space");
28748 DEFSYM (Qimage, "image");
28749 DEFSYM (Qtext, "text");
28750 DEFSYM (Qboth, "both");
28751 DEFSYM (Qboth_horiz, "both-horiz");
28752 DEFSYM (Qtext_image_horiz, "text-image-horiz");
28753 DEFSYM (QCmap, ":map");
28754 DEFSYM (QCpointer, ":pointer");
28755 DEFSYM (Qrect, "rect");
28756 DEFSYM (Qcircle, "circle");
28757 DEFSYM (Qpoly, "poly");
28758 DEFSYM (Qmessage_truncate_lines, "message-truncate-lines");
28759 DEFSYM (Qgrow_only, "grow-only");
28760 DEFSYM (Qinhibit_menubar_update, "inhibit-menubar-update");
28761 DEFSYM (Qinhibit_eval_during_redisplay, "inhibit-eval-during-redisplay");
28762 DEFSYM (Qposition, "position");
28763 DEFSYM (Qbuffer_position, "buffer-position");
28764 DEFSYM (Qobject, "object");
28765 DEFSYM (Qbar, "bar");
28766 DEFSYM (Qhbar, "hbar");
28767 DEFSYM (Qbox, "box");
28768 DEFSYM (Qhollow, "hollow");
28769 DEFSYM (Qhand, "hand");
28770 DEFSYM (Qarrow, "arrow");
28771 DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces");
28773 list_of_error = Fcons (Fcons (intern_c_string ("error"),
28774 Fcons (intern_c_string ("void-variable"), Qnil)),
28775 Qnil);
28776 staticpro (&list_of_error);
28778 DEFSYM (Qlast_arrow_position, "last-arrow-position");
28779 DEFSYM (Qlast_arrow_string, "last-arrow-string");
28780 DEFSYM (Qoverlay_arrow_string, "overlay-arrow-string");
28781 DEFSYM (Qoverlay_arrow_bitmap, "overlay-arrow-bitmap");
28783 echo_buffer[0] = echo_buffer[1] = Qnil;
28784 staticpro (&echo_buffer[0]);
28785 staticpro (&echo_buffer[1]);
28787 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
28788 staticpro (&echo_area_buffer[0]);
28789 staticpro (&echo_area_buffer[1]);
28791 Vmessages_buffer_name = build_pure_c_string ("*Messages*");
28792 staticpro (&Vmessages_buffer_name);
28794 mode_line_proptrans_alist = Qnil;
28795 staticpro (&mode_line_proptrans_alist);
28796 mode_line_string_list = Qnil;
28797 staticpro (&mode_line_string_list);
28798 mode_line_string_face = Qnil;
28799 staticpro (&mode_line_string_face);
28800 mode_line_string_face_prop = Qnil;
28801 staticpro (&mode_line_string_face_prop);
28802 Vmode_line_unwind_vector = Qnil;
28803 staticpro (&Vmode_line_unwind_vector);
28805 DEFSYM (Qmode_line_default_help_echo, "mode-line-default-help-echo");
28807 help_echo_string = Qnil;
28808 staticpro (&help_echo_string);
28809 help_echo_object = Qnil;
28810 staticpro (&help_echo_object);
28811 help_echo_window = Qnil;
28812 staticpro (&help_echo_window);
28813 previous_help_echo_string = Qnil;
28814 staticpro (&previous_help_echo_string);
28815 help_echo_pos = -1;
28817 DEFSYM (Qright_to_left, "right-to-left");
28818 DEFSYM (Qleft_to_right, "left-to-right");
28820 #ifdef HAVE_WINDOW_SYSTEM
28821 DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p,
28822 doc: /* Non-nil means draw block cursor as wide as the glyph under it.
28823 For example, if a block cursor is over a tab, it will be drawn as
28824 wide as that tab on the display. */);
28825 x_stretch_cursor_p = 0;
28826 #endif
28828 DEFVAR_LISP ("show-trailing-whitespace", Vshow_trailing_whitespace,
28829 doc: /* Non-nil means highlight trailing whitespace.
28830 The face used for trailing whitespace is `trailing-whitespace'. */);
28831 Vshow_trailing_whitespace = Qnil;
28833 DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display,
28834 doc: /* Control highlighting of non-ASCII space and hyphen chars.
28835 If the value is t, Emacs highlights non-ASCII chars which have the
28836 same appearance as an ASCII space or hyphen, using the `nobreak-space'
28837 or `escape-glyph' face respectively.
28839 U+00A0 (no-break space), U+00AD (soft hyphen), U+2010 (hyphen), and
28840 U+2011 (non-breaking hyphen) are affected.
28842 Any other non-nil value means to display these characters as a escape
28843 glyph followed by an ordinary space or hyphen.
28845 A value of nil means no special handling of these characters. */);
28846 Vnobreak_char_display = Qt;
28848 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer,
28849 doc: /* The pointer shape to show in void text areas.
28850 A value of nil means to show the text pointer. Other options are `arrow',
28851 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
28852 Vvoid_text_area_pointer = Qarrow;
28854 DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay,
28855 doc: /* Non-nil means don't actually do any redisplay.
28856 This is used for internal purposes. */);
28857 Vinhibit_redisplay = Qnil;
28859 DEFVAR_LISP ("global-mode-string", Vglobal_mode_string,
28860 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
28861 Vglobal_mode_string = Qnil;
28863 DEFVAR_LISP ("overlay-arrow-position", Voverlay_arrow_position,
28864 doc: /* Marker for where to display an arrow on top of the buffer text.
28865 This must be the beginning of a line in order to work.
28866 See also `overlay-arrow-string'. */);
28867 Voverlay_arrow_position = Qnil;
28869 DEFVAR_LISP ("overlay-arrow-string", Voverlay_arrow_string,
28870 doc: /* String to display as an arrow in non-window frames.
28871 See also `overlay-arrow-position'. */);
28872 Voverlay_arrow_string = build_pure_c_string ("=>");
28874 DEFVAR_LISP ("overlay-arrow-variable-list", Voverlay_arrow_variable_list,
28875 doc: /* List of variables (symbols) which hold markers for overlay arrows.
28876 The symbols on this list are examined during redisplay to determine
28877 where to display overlay arrows. */);
28878 Voverlay_arrow_variable_list
28879 = Fcons (intern_c_string ("overlay-arrow-position"), Qnil);
28881 DEFVAR_INT ("scroll-step", emacs_scroll_step,
28882 doc: /* The number of lines to try scrolling a window by when point moves out.
28883 If that fails to bring point back on frame, point is centered instead.
28884 If this is zero, point is always centered after it moves off frame.
28885 If you want scrolling to always be a line at a time, you should set
28886 `scroll-conservatively' to a large value rather than set this to 1. */);
28888 DEFVAR_INT ("scroll-conservatively", scroll_conservatively,
28889 doc: /* Scroll up to this many lines, to bring point back on screen.
28890 If point moves off-screen, redisplay will scroll by up to
28891 `scroll-conservatively' lines in order to bring point just barely
28892 onto the screen again. If that cannot be done, then redisplay
28893 recenters point as usual.
28895 If the value is greater than 100, redisplay will never recenter point,
28896 but will always scroll just enough text to bring point into view, even
28897 if you move far away.
28899 A value of zero means always recenter point if it moves off screen. */);
28900 scroll_conservatively = 0;
28902 DEFVAR_INT ("scroll-margin", scroll_margin,
28903 doc: /* Number of lines of margin at the top and bottom of a window.
28904 Recenter the window whenever point gets within this many lines
28905 of the top or bottom of the window. */);
28906 scroll_margin = 0;
28908 DEFVAR_LISP ("display-pixels-per-inch", Vdisplay_pixels_per_inch,
28909 doc: /* Pixels per inch value for non-window system displays.
28910 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
28911 Vdisplay_pixels_per_inch = make_float (72.0);
28913 #ifdef GLYPH_DEBUG
28914 DEFVAR_INT ("debug-end-pos", debug_end_pos, doc: /* Don't ask. */);
28915 #endif
28917 DEFVAR_LISP ("truncate-partial-width-windows",
28918 Vtruncate_partial_width_windows,
28919 doc: /* Non-nil means truncate lines in windows narrower than the frame.
28920 For an integer value, truncate lines in each window narrower than the
28921 full frame width, provided the window width is less than that integer;
28922 otherwise, respect the value of `truncate-lines'.
28924 For any other non-nil value, truncate lines in all windows that do
28925 not span the full frame width.
28927 A value of nil means to respect the value of `truncate-lines'.
28929 If `word-wrap' is enabled, you might want to reduce this. */);
28930 Vtruncate_partial_width_windows = make_number (50);
28932 DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit,
28933 doc: /* Maximum buffer size for which line number should be displayed.
28934 If the buffer is bigger than this, the line number does not appear
28935 in the mode line. A value of nil means no limit. */);
28936 Vline_number_display_limit = Qnil;
28938 DEFVAR_INT ("line-number-display-limit-width",
28939 line_number_display_limit_width,
28940 doc: /* Maximum line width (in characters) for line number display.
28941 If the average length of the lines near point is bigger than this, then the
28942 line number may be omitted from the mode line. */);
28943 line_number_display_limit_width = 200;
28945 DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows,
28946 doc: /* Non-nil means highlight region even in nonselected windows. */);
28947 highlight_nonselected_windows = 0;
28949 DEFVAR_BOOL ("multiple-frames", multiple_frames,
28950 doc: /* Non-nil if more than one frame is visible on this display.
28951 Minibuffer-only frames don't count, but iconified frames do.
28952 This variable is not guaranteed to be accurate except while processing
28953 `frame-title-format' and `icon-title-format'. */);
28955 DEFVAR_LISP ("frame-title-format", Vframe_title_format,
28956 doc: /* Template for displaying the title bar of visible frames.
28957 \(Assuming the window manager supports this feature.)
28959 This variable has the same structure as `mode-line-format', except that
28960 the %c and %l constructs are ignored. It is used only on frames for
28961 which no explicit name has been set \(see `modify-frame-parameters'). */);
28963 DEFVAR_LISP ("icon-title-format", Vicon_title_format,
28964 doc: /* Template for displaying the title bar of an iconified frame.
28965 \(Assuming the window manager supports this feature.)
28966 This variable has the same structure as `mode-line-format' (which see),
28967 and is used only on frames for which no explicit name has been set
28968 \(see `modify-frame-parameters'). */);
28969 Vicon_title_format
28970 = Vframe_title_format
28971 = listn (CONSTYPE_PURE, 3,
28972 intern_c_string ("multiple-frames"),
28973 build_pure_c_string ("%b"),
28974 listn (CONSTYPE_PURE, 4,
28975 empty_unibyte_string,
28976 intern_c_string ("invocation-name"),
28977 build_pure_c_string ("@"),
28978 intern_c_string ("system-name")));
28980 DEFVAR_LISP ("message-log-max", Vmessage_log_max,
28981 doc: /* Maximum number of lines to keep in the message log buffer.
28982 If nil, disable message logging. If t, log messages but don't truncate
28983 the buffer when it becomes large. */);
28984 Vmessage_log_max = make_number (1000);
28986 DEFVAR_LISP ("window-size-change-functions", Vwindow_size_change_functions,
28987 doc: /* Functions called before redisplay, if window sizes have changed.
28988 The value should be a list of functions that take one argument.
28989 Just before redisplay, for each frame, if any of its windows have changed
28990 size since the last redisplay, or have been split or deleted,
28991 all the functions in the list are called, with the frame as argument. */);
28992 Vwindow_size_change_functions = Qnil;
28994 DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions,
28995 doc: /* List of functions to call before redisplaying a window with scrolling.
28996 Each function is called with two arguments, the window and its new
28997 display-start position. Note that these functions are also called by
28998 `set-window-buffer'. Also note that the value of `window-end' is not
28999 valid when these functions are called.
29001 Warning: Do not use this feature to alter the way the window
29002 is scrolled. It is not designed for that, and such use probably won't
29003 work. */);
29004 Vwindow_scroll_functions = Qnil;
29006 DEFVAR_LISP ("window-text-change-functions",
29007 Vwindow_text_change_functions,
29008 doc: /* Functions to call in redisplay when text in the window might change. */);
29009 Vwindow_text_change_functions = Qnil;
29011 DEFVAR_LISP ("redisplay-end-trigger-functions", Vredisplay_end_trigger_functions,
29012 doc: /* Functions called when redisplay of a window reaches the end trigger.
29013 Each function is called with two arguments, the window and the end trigger value.
29014 See `set-window-redisplay-end-trigger'. */);
29015 Vredisplay_end_trigger_functions = Qnil;
29017 DEFVAR_LISP ("mouse-autoselect-window", Vmouse_autoselect_window,
29018 doc: /* Non-nil means autoselect window with mouse pointer.
29019 If nil, do not autoselect windows.
29020 A positive number means delay autoselection by that many seconds: a
29021 window is autoselected only after the mouse has remained in that
29022 window for the duration of the delay.
29023 A negative number has a similar effect, but causes windows to be
29024 autoselected only after the mouse has stopped moving. \(Because of
29025 the way Emacs compares mouse events, you will occasionally wait twice
29026 that time before the window gets selected.\)
29027 Any other value means to autoselect window instantaneously when the
29028 mouse pointer enters it.
29030 Autoselection selects the minibuffer only if it is active, and never
29031 unselects the minibuffer if it is active.
29033 When customizing this variable make sure that the actual value of
29034 `focus-follows-mouse' matches the behavior of your window manager. */);
29035 Vmouse_autoselect_window = Qnil;
29037 DEFVAR_LISP ("auto-resize-tool-bars", Vauto_resize_tool_bars,
29038 doc: /* Non-nil means automatically resize tool-bars.
29039 This dynamically changes the tool-bar's height to the minimum height
29040 that is needed to make all tool-bar items visible.
29041 If value is `grow-only', the tool-bar's height is only increased
29042 automatically; to decrease the tool-bar height, use \\[recenter]. */);
29043 Vauto_resize_tool_bars = Qt;
29045 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p,
29046 doc: /* Non-nil means raise tool-bar buttons when the mouse moves over them. */);
29047 auto_raise_tool_bar_buttons_p = 1;
29049 DEFVAR_BOOL ("make-cursor-line-fully-visible", make_cursor_line_fully_visible_p,
29050 doc: /* Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
29051 make_cursor_line_fully_visible_p = 1;
29053 DEFVAR_LISP ("tool-bar-border", Vtool_bar_border,
29054 doc: /* Border below tool-bar in pixels.
29055 If an integer, use it as the height of the border.
29056 If it is one of `internal-border-width' or `border-width', use the
29057 value of the corresponding frame parameter.
29058 Otherwise, no border is added below the tool-bar. */);
29059 Vtool_bar_border = Qinternal_border_width;
29061 DEFVAR_LISP ("tool-bar-button-margin", Vtool_bar_button_margin,
29062 doc: /* Margin around tool-bar buttons in pixels.
29063 If an integer, use that for both horizontal and vertical margins.
29064 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
29065 HORZ specifying the horizontal margin, and VERT specifying the
29066 vertical margin. */);
29067 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
29069 DEFVAR_INT ("tool-bar-button-relief", tool_bar_button_relief,
29070 doc: /* Relief thickness of tool-bar buttons. */);
29071 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
29073 DEFVAR_LISP ("tool-bar-style", Vtool_bar_style,
29074 doc: /* Tool bar style to use.
29075 It can be one of
29076 image - show images only
29077 text - show text only
29078 both - show both, text below image
29079 both-horiz - show text to the right of the image
29080 text-image-horiz - show text to the left of the image
29081 any other - use system default or image if no system default.
29083 This variable only affects the GTK+ toolkit version of Emacs. */);
29084 Vtool_bar_style = Qnil;
29086 DEFVAR_INT ("tool-bar-max-label-size", tool_bar_max_label_size,
29087 doc: /* Maximum number of characters a label can have to be shown.
29088 The tool bar style must also show labels for this to have any effect, see
29089 `tool-bar-style'. */);
29090 tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
29092 DEFVAR_LISP ("fontification-functions", Vfontification_functions,
29093 doc: /* List of functions to call to fontify regions of text.
29094 Each function is called with one argument POS. Functions must
29095 fontify a region starting at POS in the current buffer, and give
29096 fontified regions the property `fontified'. */);
29097 Vfontification_functions = Qnil;
29098 Fmake_variable_buffer_local (Qfontification_functions);
29100 DEFVAR_BOOL ("unibyte-display-via-language-environment",
29101 unibyte_display_via_language_environment,
29102 doc: /* Non-nil means display unibyte text according to language environment.
29103 Specifically, this means that raw bytes in the range 160-255 decimal
29104 are displayed by converting them to the equivalent multibyte characters
29105 according to the current language environment. As a result, they are
29106 displayed according to the current fontset.
29108 Note that this variable affects only how these bytes are displayed,
29109 but does not change the fact they are interpreted as raw bytes. */);
29110 unibyte_display_via_language_environment = 0;
29112 DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height,
29113 doc: /* Maximum height for resizing mini-windows (the minibuffer and the echo area).
29114 If a float, it specifies a fraction of the mini-window frame's height.
29115 If an integer, it specifies a number of lines. */);
29116 Vmax_mini_window_height = make_float (0.25);
29118 DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows,
29119 doc: /* How to resize mini-windows (the minibuffer and the echo area).
29120 A value of nil means don't automatically resize mini-windows.
29121 A value of t means resize them to fit the text displayed in them.
29122 A value of `grow-only', the default, means let mini-windows grow only;
29123 they return to their normal size when the minibuffer is closed, or the
29124 echo area becomes empty. */);
29125 Vresize_mini_windows = Qgrow_only;
29127 DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist,
29128 doc: /* Alist specifying how to blink the cursor off.
29129 Each element has the form (ON-STATE . OFF-STATE). Whenever the
29130 `cursor-type' frame-parameter or variable equals ON-STATE,
29131 comparing using `equal', Emacs uses OFF-STATE to specify
29132 how to blink it off. ON-STATE and OFF-STATE are values for
29133 the `cursor-type' frame parameter.
29135 If a frame's ON-STATE has no entry in this list,
29136 the frame's other specifications determine how to blink the cursor off. */);
29137 Vblink_cursor_alist = Qnil;
29139 DEFVAR_BOOL ("auto-hscroll-mode", automatic_hscrolling_p,
29140 doc: /* Allow or disallow automatic horizontal scrolling of windows.
29141 If non-nil, windows are automatically scrolled horizontally to make
29142 point visible. */);
29143 automatic_hscrolling_p = 1;
29144 DEFSYM (Qauto_hscroll_mode, "auto-hscroll-mode");
29146 DEFVAR_INT ("hscroll-margin", hscroll_margin,
29147 doc: /* How many columns away from the window edge point is allowed to get
29148 before automatic hscrolling will horizontally scroll the window. */);
29149 hscroll_margin = 5;
29151 DEFVAR_LISP ("hscroll-step", Vhscroll_step,
29152 doc: /* How many columns to scroll the window when point gets too close to the edge.
29153 When point is less than `hscroll-margin' columns from the window
29154 edge, automatic hscrolling will scroll the window by the amount of columns
29155 determined by this variable. If its value is a positive integer, scroll that
29156 many columns. If it's a positive floating-point number, it specifies the
29157 fraction of the window's width to scroll. If it's nil or zero, point will be
29158 centered horizontally after the scroll. Any other value, including negative
29159 numbers, are treated as if the value were zero.
29161 Automatic hscrolling always moves point outside the scroll margin, so if
29162 point was more than scroll step columns inside the margin, the window will
29163 scroll more than the value given by the scroll step.
29165 Note that the lower bound for automatic hscrolling specified by `scroll-left'
29166 and `scroll-right' overrides this variable's effect. */);
29167 Vhscroll_step = make_number (0);
29169 DEFVAR_BOOL ("message-truncate-lines", message_truncate_lines,
29170 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
29171 Bind this around calls to `message' to let it take effect. */);
29172 message_truncate_lines = 0;
29174 DEFVAR_LISP ("menu-bar-update-hook", Vmenu_bar_update_hook,
29175 doc: /* Normal hook run to update the menu bar definitions.
29176 Redisplay runs this hook before it redisplays the menu bar.
29177 This is used to update submenus such as Buffers,
29178 whose contents depend on various data. */);
29179 Vmenu_bar_update_hook = Qnil;
29181 DEFVAR_LISP ("menu-updating-frame", Vmenu_updating_frame,
29182 doc: /* Frame for which we are updating a menu.
29183 The enable predicate for a menu binding should check this variable. */);
29184 Vmenu_updating_frame = Qnil;
29186 DEFVAR_BOOL ("inhibit-menubar-update", inhibit_menubar_update,
29187 doc: /* Non-nil means don't update menu bars. Internal use only. */);
29188 inhibit_menubar_update = 0;
29190 DEFVAR_LISP ("wrap-prefix", Vwrap_prefix,
29191 doc: /* Prefix prepended to all continuation lines at display time.
29192 The value may be a string, an image, or a stretch-glyph; it is
29193 interpreted in the same way as the value of a `display' text property.
29195 This variable is overridden by any `wrap-prefix' text or overlay
29196 property.
29198 To add a prefix to non-continuation lines, use `line-prefix'. */);
29199 Vwrap_prefix = Qnil;
29200 DEFSYM (Qwrap_prefix, "wrap-prefix");
29201 Fmake_variable_buffer_local (Qwrap_prefix);
29203 DEFVAR_LISP ("line-prefix", Vline_prefix,
29204 doc: /* Prefix prepended to all non-continuation lines at display time.
29205 The value may be a string, an image, or a stretch-glyph; it is
29206 interpreted in the same way as the value of a `display' text property.
29208 This variable is overridden by any `line-prefix' text or overlay
29209 property.
29211 To add a prefix to continuation lines, use `wrap-prefix'. */);
29212 Vline_prefix = Qnil;
29213 DEFSYM (Qline_prefix, "line-prefix");
29214 Fmake_variable_buffer_local (Qline_prefix);
29216 DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay,
29217 doc: /* Non-nil means don't eval Lisp during redisplay. */);
29218 inhibit_eval_during_redisplay = 0;
29220 DEFVAR_BOOL ("inhibit-free-realized-faces", inhibit_free_realized_faces,
29221 doc: /* Non-nil means don't free realized faces. Internal use only. */);
29222 inhibit_free_realized_faces = 0;
29224 #ifdef GLYPH_DEBUG
29225 DEFVAR_BOOL ("inhibit-try-window-id", inhibit_try_window_id,
29226 doc: /* Inhibit try_window_id display optimization. */);
29227 inhibit_try_window_id = 0;
29229 DEFVAR_BOOL ("inhibit-try-window-reusing", inhibit_try_window_reusing,
29230 doc: /* Inhibit try_window_reusing display optimization. */);
29231 inhibit_try_window_reusing = 0;
29233 DEFVAR_BOOL ("inhibit-try-cursor-movement", inhibit_try_cursor_movement,
29234 doc: /* Inhibit try_cursor_movement display optimization. */);
29235 inhibit_try_cursor_movement = 0;
29236 #endif /* GLYPH_DEBUG */
29238 DEFVAR_INT ("overline-margin", overline_margin,
29239 doc: /* Space between overline and text, in pixels.
29240 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
29241 margin to the character height. */);
29242 overline_margin = 2;
29244 DEFVAR_INT ("underline-minimum-offset",
29245 underline_minimum_offset,
29246 doc: /* Minimum distance between baseline and underline.
29247 This can improve legibility of underlined text at small font sizes,
29248 particularly when using variable `x-use-underline-position-properties'
29249 with fonts that specify an UNDERLINE_POSITION relatively close to the
29250 baseline. The default value is 1. */);
29251 underline_minimum_offset = 1;
29253 DEFVAR_BOOL ("display-hourglass", display_hourglass_p,
29254 doc: /* Non-nil means show an hourglass pointer, when Emacs is busy.
29255 This feature only works when on a window system that can change
29256 cursor shapes. */);
29257 display_hourglass_p = 1;
29259 DEFVAR_LISP ("hourglass-delay", Vhourglass_delay,
29260 doc: /* Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
29261 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
29263 hourglass_atimer = NULL;
29264 hourglass_shown_p = 0;
29266 DEFSYM (Qglyphless_char, "glyphless-char");
29267 DEFSYM (Qhex_code, "hex-code");
29268 DEFSYM (Qempty_box, "empty-box");
29269 DEFSYM (Qthin_space, "thin-space");
29270 DEFSYM (Qzero_width, "zero-width");
29272 DEFSYM (Qglyphless_char_display, "glyphless-char-display");
29273 /* Intern this now in case it isn't already done.
29274 Setting this variable twice is harmless.
29275 But don't staticpro it here--that is done in alloc.c. */
29276 Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots");
29277 Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
29279 DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display,
29280 doc: /* Char-table defining glyphless characters.
29281 Each element, if non-nil, should be one of the following:
29282 an ASCII acronym string: display this string in a box
29283 `hex-code': display the hexadecimal code of a character in a box
29284 `empty-box': display as an empty box
29285 `thin-space': display as 1-pixel width space
29286 `zero-width': don't display
29287 An element may also be a cons cell (GRAPHICAL . TEXT), which specifies the
29288 display method for graphical terminals and text terminals respectively.
29289 GRAPHICAL and TEXT should each have one of the values listed above.
29291 The char-table has one extra slot to control the display of a character for
29292 which no font is found. This slot only takes effect on graphical terminals.
29293 Its value should be an ASCII acronym string, `hex-code', `empty-box', or
29294 `thin-space'. The default is `empty-box'. */);
29295 Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
29296 Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
29297 Qempty_box);
29299 DEFVAR_LISP ("debug-on-message", Vdebug_on_message,
29300 doc: /* If non-nil, debug if a message matching this regexp is displayed. */);
29301 Vdebug_on_message = Qnil;
29305 /* Initialize this module when Emacs starts. */
29307 void
29308 init_xdisp (void)
29310 current_header_line_height = current_mode_line_height = -1;
29312 CHARPOS (this_line_start_pos) = 0;
29314 if (!noninteractive)
29316 struct window *m = XWINDOW (minibuf_window);
29317 Lisp_Object frame = m->frame;
29318 struct frame *f = XFRAME (frame);
29319 Lisp_Object root = FRAME_ROOT_WINDOW (f);
29320 struct window *r = XWINDOW (root);
29321 int i;
29323 echo_area_window = minibuf_window;
29325 r->top_line = FRAME_TOP_MARGIN (f);
29326 r->total_lines = FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f);
29327 r->total_cols = FRAME_COLS (f);
29329 m->top_line = FRAME_LINES (f) - 1;
29330 m->total_lines = 1;
29331 m->total_cols = FRAME_COLS (f);
29333 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
29334 scratch_glyph_row.glyphs[TEXT_AREA + 1]
29335 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
29337 /* The default ellipsis glyphs `...'. */
29338 for (i = 0; i < 3; ++i)
29339 default_invis_vector[i] = make_number ('.');
29343 /* Allocate the buffer for frame titles.
29344 Also used for `format-mode-line'. */
29345 int size = 100;
29346 mode_line_noprop_buf = xmalloc (size);
29347 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
29348 mode_line_noprop_ptr = mode_line_noprop_buf;
29349 mode_line_target = MODE_LINE_DISPLAY;
29352 help_echo_showing_p = 0;
29355 /* Platform-independent portion of hourglass implementation. */
29357 /* Cancel a currently active hourglass timer, and start a new one. */
29358 void
29359 start_hourglass (void)
29361 #if defined (HAVE_WINDOW_SYSTEM)
29362 EMACS_TIME delay;
29364 cancel_hourglass ();
29366 if (INTEGERP (Vhourglass_delay)
29367 && XINT (Vhourglass_delay) > 0)
29368 delay = make_emacs_time (min (XINT (Vhourglass_delay),
29369 TYPE_MAXIMUM (time_t)),
29371 else if (FLOATP (Vhourglass_delay)
29372 && XFLOAT_DATA (Vhourglass_delay) > 0)
29373 delay = EMACS_TIME_FROM_DOUBLE (XFLOAT_DATA (Vhourglass_delay));
29374 else
29375 delay = make_emacs_time (DEFAULT_HOURGLASS_DELAY, 0);
29377 #ifdef HAVE_NTGUI
29379 extern void w32_note_current_window (void);
29380 w32_note_current_window ();
29382 #endif /* HAVE_NTGUI */
29384 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
29385 show_hourglass, NULL);
29386 #endif
29390 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
29391 shown. */
29392 void
29393 cancel_hourglass (void)
29395 #if defined (HAVE_WINDOW_SYSTEM)
29396 if (hourglass_atimer)
29398 cancel_atimer (hourglass_atimer);
29399 hourglass_atimer = NULL;
29402 if (hourglass_shown_p)
29403 hide_hourglass ();
29404 #endif