merge master
[emacs.git] / src / xdisp.c
blob1fa19f7b7b7f00b77fabce662d351c47ac95bc92
1 /* Display generation from window structure and buffer text.
3 Copyright (C) 1985-1988, 1993-1995, 1997-2015 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. (The "id" part in the function's
102 name stands for "insert/delete", not for "identification" or
103 somesuch.)
105 . try_window
107 This function performs the full redisplay of a single window
108 assuming that its fonts were not changed and that the cursor
109 will not end up in the scroll margins. (Loading fonts requires
110 re-adjustment of dimensions of glyph matrices, which makes this
111 method impossible to use.)
113 These optimizations are tried in sequence (some can be skipped if
114 it is known that they are not applicable). If none of the
115 optimizations were successful, redisplay calls redisplay_windows,
116 which performs a full redisplay of all windows.
118 Note that there's one more important optimization up Emacs's
119 sleeve, but it is related to actually redrawing the potentially
120 changed portions of the window/frame, not to reproducing the
121 desired matrices of those potentially changed portions. Namely,
122 the function update_frame and its subroutines, which you will find
123 in dispnew.c, compare the desired matrices with the current
124 matrices, and only redraw the portions that changed. So it could
125 happen that the functions in this file for some reason decide that
126 the entire desired matrix needs to be regenerated from scratch, and
127 still only parts of the Emacs display, or even nothing at all, will
128 be actually delivered to the glass, because update_frame has found
129 that the new and the old screen contents are similar or identical.
131 Desired matrices.
133 Desired matrices are always built per Emacs window. The function
134 `display_line' is the central function to look at if you are
135 interested. It constructs one row in a desired matrix given an
136 iterator structure containing both a buffer position and a
137 description of the environment in which the text is to be
138 displayed. But this is too early, read on.
140 Characters and pixmaps displayed for a range of buffer text depend
141 on various settings of buffers and windows, on overlays and text
142 properties, on display tables, on selective display. The good news
143 is that all this hairy stuff is hidden behind a small set of
144 interface functions taking an iterator structure (struct it)
145 argument.
147 Iteration over things to be displayed is then simple. It is
148 started by initializing an iterator with a call to init_iterator,
149 passing it the buffer position where to start iteration. For
150 iteration over strings, pass -1 as the position to init_iterator,
151 and call reseat_to_string when the string is ready, to initialize
152 the iterator for that string. Thereafter, calls to
153 get_next_display_element fill the iterator structure with relevant
154 information about the next thing to display. Calls to
155 set_iterator_to_next move the iterator to the next thing.
157 Besides this, an iterator also contains information about the
158 display environment in which glyphs for display elements are to be
159 produced. It has fields for the width and height of the display,
160 the information whether long lines are truncated or continued, a
161 current X and Y position, and lots of other stuff you can better
162 see in dispextern.h.
164 Glyphs in a desired matrix are normally constructed in a loop
165 calling get_next_display_element and then PRODUCE_GLYPHS. The call
166 to PRODUCE_GLYPHS will fill the iterator structure with pixel
167 information about the element being displayed and at the same time
168 produce glyphs for it. If the display element fits on the line
169 being displayed, set_iterator_to_next is called next, otherwise the
170 glyphs produced are discarded. The function display_line is the
171 workhorse of filling glyph rows in the desired matrix with glyphs.
172 In addition to producing glyphs, it also handles line truncation
173 and continuation, word wrap, and cursor positioning (for the
174 latter, see also set_cursor_from_row).
176 Frame matrices.
178 That just couldn't be all, could it? What about terminal types not
179 supporting operations on sub-windows of the screen? To update the
180 display on such a terminal, window-based glyph matrices are not
181 well suited. To be able to reuse part of the display (scrolling
182 lines up and down), we must instead have a view of the whole
183 screen. This is what `frame matrices' are for. They are a trick.
185 Frames on terminals like above have a glyph pool. Windows on such
186 a frame sub-allocate their glyph memory from their frame's glyph
187 pool. The frame itself is given its own glyph matrices. By
188 coincidence---or maybe something else---rows in window glyph
189 matrices are slices of corresponding rows in frame matrices. Thus
190 writing to window matrices implicitly updates a frame matrix which
191 provides us with the view of the whole screen that we originally
192 wanted to have without having to move many bytes around. To be
193 honest, there is a little bit more done, but not much more. If you
194 plan to extend that code, take a look at dispnew.c. The function
195 build_frame_matrix is a good starting point.
197 Bidirectional display.
199 Bidirectional display adds quite some hair to this already complex
200 design. The good news are that a large portion of that hairy stuff
201 is hidden in bidi.c behind only 3 interfaces. bidi.c implements a
202 reordering engine which is called by set_iterator_to_next and
203 returns the next character to display in the visual order. See
204 commentary on bidi.c for more details. As far as redisplay is
205 concerned, the effect of calling bidi_move_to_visually_next, the
206 main interface of the reordering engine, is that the iterator gets
207 magically placed on the buffer or string position that is to be
208 displayed next. In other words, a linear iteration through the
209 buffer/string is replaced with a non-linear one. All the rest of
210 the redisplay is oblivious to the bidi reordering.
212 Well, almost oblivious---there are still complications, most of
213 them due to the fact that buffer and string positions no longer
214 change monotonously with glyph indices in a glyph row. Moreover,
215 for continued lines, the buffer positions may not even be
216 monotonously changing with vertical positions. Also, accounting
217 for face changes, overlays, etc. becomes more complex because
218 non-linear iteration could potentially skip many positions with
219 changes, and then cross them again on the way back...
221 One other prominent effect of bidirectional display is that some
222 paragraphs of text need to be displayed starting at the right
223 margin of the window---the so-called right-to-left, or R2L
224 paragraphs. R2L paragraphs are displayed with R2L glyph rows,
225 which have their reversed_p flag set. The bidi reordering engine
226 produces characters in such rows starting from the character which
227 should be the rightmost on display. PRODUCE_GLYPHS then reverses
228 the order, when it fills up the glyph row whose reversed_p flag is
229 set, by prepending each new glyph to what is already there, instead
230 of appending it. When the glyph row is complete, the function
231 extend_face_to_end_of_line fills the empty space to the left of the
232 leftmost character with special glyphs, which will display as,
233 well, empty. On text terminals, these special glyphs are simply
234 blank characters. On graphics terminals, there's a single stretch
235 glyph of a suitably computed width. Both the blanks and the
236 stretch glyph are given the face of the background of the line.
237 This way, the terminal-specific back-end can still draw the glyphs
238 left to right, even for R2L lines.
240 Bidirectional display and character compositions
242 Some scripts cannot be displayed by drawing each character
243 individually, because adjacent characters change each other's shape
244 on display. For example, Arabic and Indic scripts belong to this
245 category.
247 Emacs display supports this by providing "character compositions",
248 most of which is implemented in composite.c. During the buffer
249 scan that delivers characters to PRODUCE_GLYPHS, if the next
250 character to be delivered is a composed character, the iteration
251 calls composition_reseat_it and next_element_from_composition. If
252 they succeed to compose the character with one or more of the
253 following characters, the whole sequence of characters that where
254 composed is recorded in the `struct composition_it' object that is
255 part of the buffer iterator. The composed sequence could produce
256 one or more font glyphs (called "grapheme clusters") on the screen.
257 Each of these grapheme clusters is then delivered to PRODUCE_GLYPHS
258 in the direction corresponding to the current bidi scan direction
259 (recorded in the scan_dir member of the `struct bidi_it' object
260 that is part of the buffer iterator). In particular, if the bidi
261 iterator currently scans the buffer backwards, the grapheme
262 clusters are delivered back to front. This reorders the grapheme
263 clusters as appropriate for the current bidi context. Note that
264 this means that the grapheme clusters are always stored in the
265 LGSTRING object (see composite.c) in the logical order.
267 Moving an iterator in bidirectional text
268 without producing glyphs
270 Note one important detail mentioned above: that the bidi reordering
271 engine, driven by the iterator, produces characters in R2L rows
272 starting at the character that will be the rightmost on display.
273 As far as the iterator is concerned, the geometry of such rows is
274 still left to right, i.e. the iterator "thinks" the first character
275 is at the leftmost pixel position. The iterator does not know that
276 PRODUCE_GLYPHS reverses the order of the glyphs that the iterator
277 delivers. This is important when functions from the move_it_*
278 family are used to get to certain screen position or to match
279 screen coordinates with buffer coordinates: these functions use the
280 iterator geometry, which is left to right even in R2L paragraphs.
281 This works well with most callers of move_it_*, because they need
282 to get to a specific column, and columns are still numbered in the
283 reading order, i.e. the rightmost character in a R2L paragraph is
284 still column zero. But some callers do not get well with this; a
285 notable example is mouse clicks that need to find the character
286 that corresponds to certain pixel coordinates. See
287 buffer_posn_from_coords in dispnew.c for how this is handled. */
289 #include <config.h>
290 #include <stdio.h>
291 #include <limits.h>
293 #include "lisp.h"
294 #include "atimer.h"
295 #include "keyboard.h"
296 #include "frame.h"
297 #include "window.h"
298 #include "termchar.h"
299 #include "dispextern.h"
300 #include "character.h"
301 #include "buffer.h"
302 #include "charset.h"
303 #include "indent.h"
304 #include "commands.h"
305 #include "keymap.h"
306 #include "macros.h"
307 #include "disptab.h"
308 #include "termhooks.h"
309 #include "termopts.h"
310 #include "intervals.h"
311 #include "coding.h"
312 #include "process.h"
313 #include "region-cache.h"
314 #include "font.h"
315 #include "fontset.h"
316 #include "blockinput.h"
317 #ifdef HAVE_WINDOW_SYSTEM
318 #include TERM_HEADER
319 #endif /* HAVE_WINDOW_SYSTEM */
321 #include "font.h"
322 #ifdef HAVE_XWIDGETS
323 #include "xwidget.h"
324 #endif
325 #ifndef FRAME_X_OUTPUT
326 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
327 #endif
329 #define INFINITY 10000000
331 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
332 Lisp_Object Qwindow_scroll_functions;
333 static Lisp_Object Qwindow_text_change_functions;
334 static Lisp_Object Qredisplay_end_trigger_functions;
335 Lisp_Object Qinhibit_point_motion_hooks;
336 static Lisp_Object QCeval, QCpropertize;
337 Lisp_Object QCfile, QCdata;
338 static Lisp_Object Qfontified;
339 static Lisp_Object Qgrow_only;
340 static Lisp_Object Qinhibit_eval_during_redisplay;
341 static Lisp_Object Qbuffer_position, Qposition, Qobject;
342 static Lisp_Object Qright_to_left, Qleft_to_right;
344 /* Cursor shapes. */
345 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
347 /* Pointer shapes. */
348 static Lisp_Object Qarrow, Qhand;
349 Lisp_Object Qtext;
351 /* Holds the list (error). */
352 static Lisp_Object list_of_error;
354 Lisp_Object Qfontification_functions;
356 static Lisp_Object Qwrap_prefix;
357 static Lisp_Object Qline_prefix;
358 static Lisp_Object Qredisplay_internal;
360 /* Non-nil means don't actually do any redisplay. */
362 Lisp_Object Qinhibit_redisplay;
364 /* Names of text properties relevant for redisplay. */
366 Lisp_Object Qdisplay;
368 Lisp_Object Qspace, QCalign_to;
369 static Lisp_Object QCrelative_width, QCrelative_height;
370 Lisp_Object Qleft_margin, Qright_margin;
371 static Lisp_Object Qspace_width, Qraise;
372 static Lisp_Object Qslice;
373 Lisp_Object Qcenter;
374 static Lisp_Object Qmargin, Qpointer;
375 static Lisp_Object Qline_height;
377 #ifdef HAVE_WINDOW_SYSTEM
379 /* Test if overflow newline into fringe. Called with iterator IT
380 at or past right window margin, and with IT->current_x set. */
382 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(IT) \
383 (!NILP (Voverflow_newline_into_fringe) \
384 && FRAME_WINDOW_P ((IT)->f) \
385 && ((IT)->bidi_it.paragraph_dir == R2L \
386 ? (WINDOW_LEFT_FRINGE_WIDTH ((IT)->w) > 0) \
387 : (WINDOW_RIGHT_FRINGE_WIDTH ((IT)->w) > 0)) \
388 && (IT)->current_x == (IT)->last_visible_x)
390 #else /* !HAVE_WINDOW_SYSTEM */
391 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) 0
392 #endif /* HAVE_WINDOW_SYSTEM */
394 /* Test if the display element loaded in IT, or the underlying buffer
395 or string character, is a space or a TAB character. This is used
396 to determine where word wrapping can occur. */
398 #define IT_DISPLAYING_WHITESPACE(it) \
399 ((it->what == IT_CHARACTER && (it->c == ' ' || it->c == '\t')) \
400 || ((STRINGP (it->string) \
401 && (SREF (it->string, IT_STRING_BYTEPOS (*it)) == ' ' \
402 || SREF (it->string, IT_STRING_BYTEPOS (*it)) == '\t')) \
403 || (it->s \
404 && (it->s[IT_BYTEPOS (*it)] == ' ' \
405 || it->s[IT_BYTEPOS (*it)] == '\t')) \
406 || (IT_BYTEPOS (*it) < ZV_BYTE \
407 && (*BYTE_POS_ADDR (IT_BYTEPOS (*it)) == ' ' \
408 || *BYTE_POS_ADDR (IT_BYTEPOS (*it)) == '\t')))) \
410 /* Name of the face used to highlight trailing whitespace. */
412 static Lisp_Object Qtrailing_whitespace;
414 /* Name and number of the face used to highlight escape glyphs. */
416 static Lisp_Object Qescape_glyph;
418 /* Name and number of the face used to highlight non-breaking spaces. */
420 static Lisp_Object Qnobreak_space;
422 /* The symbol `image' which is the car of the lists used to represent
423 images in Lisp. Also a tool bar style. */
425 Lisp_Object Qimage;
427 /* The image map types. */
428 Lisp_Object QCmap;
429 static Lisp_Object QCpointer;
430 static Lisp_Object Qrect, Qcircle, Qpoly;
432 /* Tool bar styles */
433 Lisp_Object Qboth, Qboth_horiz, Qtext_image_horiz;
435 /* Non-zero means print newline to stdout before next mini-buffer
436 message. */
438 bool noninteractive_need_newline;
440 /* Non-zero means print newline to message log before next message. */
442 static bool message_log_need_newline;
444 /* Three markers that message_dolog uses.
445 It could allocate them itself, but that causes trouble
446 in handling memory-full errors. */
447 static Lisp_Object message_dolog_marker1;
448 static Lisp_Object message_dolog_marker2;
449 static Lisp_Object message_dolog_marker3;
451 /* The buffer position of the first character appearing entirely or
452 partially on the line of the selected window which contains the
453 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
454 redisplay optimization in redisplay_internal. */
456 static struct text_pos this_line_start_pos;
458 /* Number of characters past the end of the line above, including the
459 terminating newline. */
461 static struct text_pos this_line_end_pos;
463 /* The vertical positions and the height of this line. */
465 static int this_line_vpos;
466 static int this_line_y;
467 static int this_line_pixel_height;
469 /* X position at which this display line starts. Usually zero;
470 negative if first character is partially visible. */
472 static int this_line_start_x;
474 /* The smallest character position seen by move_it_* functions as they
475 move across display lines. Used to set MATRIX_ROW_START_CHARPOS of
476 hscrolled lines, see display_line. */
478 static struct text_pos this_line_min_pos;
480 /* Buffer that this_line_.* variables are referring to. */
482 static struct buffer *this_line_buffer;
485 /* Values of those variables at last redisplay are stored as
486 properties on `overlay-arrow-position' symbol. However, if
487 Voverlay_arrow_position is a marker, last-arrow-position is its
488 numerical position. */
490 static Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
492 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
493 properties on a symbol in overlay-arrow-variable-list. */
495 static Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
497 Lisp_Object Qmenu_bar_update_hook;
499 /* Nonzero if an overlay arrow has been displayed in this window. */
501 static bool overlay_arrow_seen;
503 /* Vector containing glyphs for an ellipsis `...'. */
505 static Lisp_Object default_invis_vector[3];
507 /* This is the window where the echo area message was displayed. It
508 is always a mini-buffer window, but it may not be the same window
509 currently active as a mini-buffer. */
511 Lisp_Object echo_area_window;
513 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
514 pushes the current message and the value of
515 message_enable_multibyte on the stack, the function restore_message
516 pops the stack and displays MESSAGE again. */
518 static Lisp_Object Vmessage_stack;
520 /* Nonzero means multibyte characters were enabled when the echo area
521 message was specified. */
523 static bool message_enable_multibyte;
525 /* Nonzero if we should redraw the mode lines on the next redisplay.
526 If it has value REDISPLAY_SOME, then only redisplay the mode lines where
527 the `redisplay' bit has been set. Otherwise, redisplay all mode lines
528 (the number used is then only used to track down the cause for this
529 full-redisplay). */
531 int update_mode_lines;
533 /* Nonzero if window sizes or contents other than selected-window have changed
534 since last redisplay that finished.
535 If it has value REDISPLAY_SOME, then only redisplay the windows where
536 the `redisplay' bit has been set. Otherwise, redisplay all windows
537 (the number used is then only used to track down the cause for this
538 full-redisplay). */
540 int windows_or_buffers_changed;
542 /* Nonzero after display_mode_line if %l was used and it displayed a
543 line number. */
545 static bool line_number_displayed;
547 /* The name of the *Messages* buffer, a string. */
549 static Lisp_Object Vmessages_buffer_name;
551 /* Current, index 0, and last displayed echo area message. Either
552 buffers from echo_buffers, or nil to indicate no message. */
554 Lisp_Object echo_area_buffer[2];
556 /* The buffers referenced from echo_area_buffer. */
558 static Lisp_Object echo_buffer[2];
560 /* A vector saved used in with_area_buffer to reduce consing. */
562 static Lisp_Object Vwith_echo_area_save_vector;
564 /* Non-zero means display_echo_area should display the last echo area
565 message again. Set by redisplay_preserve_echo_area. */
567 static bool display_last_displayed_message_p;
569 /* Nonzero if echo area is being used by print; zero if being used by
570 message. */
572 static bool message_buf_print;
574 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
576 static Lisp_Object Qinhibit_menubar_update;
577 static Lisp_Object Qmessage_truncate_lines;
579 /* Set to 1 in clear_message to make redisplay_internal aware
580 of an emptied echo area. */
582 static bool message_cleared_p;
584 /* A scratch glyph row with contents used for generating truncation
585 glyphs. Also used in direct_output_for_insert. */
587 #define MAX_SCRATCH_GLYPHS 100
588 static struct glyph_row scratch_glyph_row;
589 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
591 /* Ascent and height of the last line processed by move_it_to. */
593 static int last_height;
595 /* Non-zero if there's a help-echo in the echo area. */
597 bool help_echo_showing_p;
599 /* The maximum distance to look ahead for text properties. Values
600 that are too small let us call compute_char_face and similar
601 functions too often which is expensive. Values that are too large
602 let us call compute_char_face and alike too often because we
603 might not be interested in text properties that far away. */
605 #define TEXT_PROP_DISTANCE_LIMIT 100
607 /* SAVE_IT and RESTORE_IT are called when we save a snapshot of the
608 iterator state and later restore it. This is needed because the
609 bidi iterator on bidi.c keeps a stacked cache of its states, which
610 is really a singleton. When we use scratch iterator objects to
611 move around the buffer, we can cause the bidi cache to be pushed or
612 popped, and therefore we need to restore the cache state when we
613 return to the original iterator. */
614 #define SAVE_IT(ITCOPY,ITORIG,CACHE) \
615 do { \
616 if (CACHE) \
617 bidi_unshelve_cache (CACHE, 1); \
618 ITCOPY = ITORIG; \
619 CACHE = bidi_shelve_cache (); \
620 } while (0)
622 #define RESTORE_IT(pITORIG,pITCOPY,CACHE) \
623 do { \
624 if (pITORIG != pITCOPY) \
625 *(pITORIG) = *(pITCOPY); \
626 bidi_unshelve_cache (CACHE, 0); \
627 CACHE = NULL; \
628 } while (0)
630 /* Functions to mark elements as needing redisplay. */
631 enum { REDISPLAY_SOME = 2}; /* Arbitrary choice. */
633 void
634 redisplay_other_windows (void)
636 if (!windows_or_buffers_changed)
637 windows_or_buffers_changed = REDISPLAY_SOME;
640 void
641 wset_redisplay (struct window *w)
643 /* Beware: selected_window can be nil during early stages. */
644 if (!EQ (make_lisp_ptr (w, Lisp_Vectorlike), selected_window))
645 redisplay_other_windows ();
646 w->redisplay = true;
649 void
650 fset_redisplay (struct frame *f)
652 redisplay_other_windows ();
653 f->redisplay = true;
656 void
657 bset_redisplay (struct buffer *b)
659 int count = buffer_window_count (b);
660 if (count > 0)
662 /* ... it's visible in other window than selected, */
663 if (count > 1 || b != XBUFFER (XWINDOW (selected_window)->contents))
664 redisplay_other_windows ();
665 /* Even if we don't set windows_or_buffers_changed, do set `redisplay'
666 so that if we later set windows_or_buffers_changed, this buffer will
667 not be omitted. */
668 b->text->redisplay = true;
672 void
673 bset_update_mode_line (struct buffer *b)
675 if (!update_mode_lines)
676 update_mode_lines = REDISPLAY_SOME;
677 b->text->redisplay = true;
680 #ifdef GLYPH_DEBUG
682 /* Non-zero means print traces of redisplay if compiled with
683 GLYPH_DEBUG defined. */
685 bool trace_redisplay_p;
687 #endif /* GLYPH_DEBUG */
689 #ifdef DEBUG_TRACE_MOVE
690 /* Non-zero means trace with TRACE_MOVE to stderr. */
691 int trace_move;
693 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
694 #else
695 #define TRACE_MOVE(x) (void) 0
696 #endif
698 static Lisp_Object Qauto_hscroll_mode;
700 /* Buffer being redisplayed -- for redisplay_window_error. */
702 static struct buffer *displayed_buffer;
704 /* Value returned from text property handlers (see below). */
706 enum prop_handled
708 HANDLED_NORMALLY,
709 HANDLED_RECOMPUTE_PROPS,
710 HANDLED_OVERLAY_STRING_CONSUMED,
711 HANDLED_RETURN
714 /* A description of text properties that redisplay is interested
715 in. */
717 struct props
719 /* The name of the property. */
720 Lisp_Object *name;
722 /* A unique index for the property. */
723 enum prop_idx idx;
725 /* A handler function called to set up iterator IT from the property
726 at IT's current position. Value is used to steer handle_stop. */
727 enum prop_handled (*handler) (struct it *it);
730 static enum prop_handled handle_face_prop (struct it *);
731 static enum prop_handled handle_invisible_prop (struct it *);
732 static enum prop_handled handle_display_prop (struct it *);
733 static enum prop_handled handle_composition_prop (struct it *);
734 static enum prop_handled handle_overlay_change (struct it *);
735 static enum prop_handled handle_fontified_prop (struct it *);
737 /* Properties handled by iterators. */
739 static struct props it_props[] =
741 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
742 /* Handle `face' before `display' because some sub-properties of
743 `display' need to know the face. */
744 {&Qface, FACE_PROP_IDX, handle_face_prop},
745 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
746 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
747 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
748 {NULL, 0, NULL}
751 /* Value is the position described by X. If X is a marker, value is
752 the marker_position of X. Otherwise, value is X. */
754 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
756 /* Enumeration returned by some move_it_.* functions internally. */
758 enum move_it_result
760 /* Not used. Undefined value. */
761 MOVE_UNDEFINED,
763 /* Move ended at the requested buffer position or ZV. */
764 MOVE_POS_MATCH_OR_ZV,
766 /* Move ended at the requested X pixel position. */
767 MOVE_X_REACHED,
769 /* Move within a line ended at the end of a line that must be
770 continued. */
771 MOVE_LINE_CONTINUED,
773 /* Move within a line ended at the end of a line that would
774 be displayed truncated. */
775 MOVE_LINE_TRUNCATED,
777 /* Move within a line ended at a line end. */
778 MOVE_NEWLINE_OR_CR
781 /* This counter is used to clear the face cache every once in a while
782 in redisplay_internal. It is incremented for each redisplay.
783 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
784 cleared. */
786 #define CLEAR_FACE_CACHE_COUNT 500
787 static int clear_face_cache_count;
789 /* Similarly for the image cache. */
791 #ifdef HAVE_WINDOW_SYSTEM
792 #define CLEAR_IMAGE_CACHE_COUNT 101
793 static int clear_image_cache_count;
795 /* Null glyph slice */
796 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
797 #endif
799 /* True while redisplay_internal is in progress. */
801 bool redisplaying_p;
803 static Lisp_Object Qinhibit_free_realized_faces;
804 static Lisp_Object Qmode_line_default_help_echo;
806 /* If a string, XTread_socket generates an event to display that string.
807 (The display is done in read_char.) */
809 Lisp_Object help_echo_string;
810 Lisp_Object help_echo_window;
811 Lisp_Object help_echo_object;
812 ptrdiff_t help_echo_pos;
814 /* Temporary variable for XTread_socket. */
816 Lisp_Object previous_help_echo_string;
818 /* Platform-independent portion of hourglass implementation. */
820 #ifdef HAVE_WINDOW_SYSTEM
822 /* Non-zero means an hourglass cursor is currently shown. */
823 static bool hourglass_shown_p;
825 /* If non-null, an asynchronous timer that, when it expires, displays
826 an hourglass cursor on all frames. */
827 static struct atimer *hourglass_atimer;
829 #endif /* HAVE_WINDOW_SYSTEM */
831 /* Name of the face used to display glyphless characters. */
832 static Lisp_Object Qglyphless_char;
834 /* Symbol for the purpose of Vglyphless_char_display. */
835 static Lisp_Object Qglyphless_char_display;
837 /* Method symbols for Vglyphless_char_display. */
838 static Lisp_Object Qhex_code, Qempty_box, Qthin_space, Qzero_width;
840 /* Default number of seconds to wait before displaying an hourglass
841 cursor. */
842 #define DEFAULT_HOURGLASS_DELAY 1
844 #ifdef HAVE_WINDOW_SYSTEM
846 /* Default pixel width of `thin-space' display method. */
847 #define THIN_SPACE_WIDTH 1
849 #endif /* HAVE_WINDOW_SYSTEM */
851 /* Function prototypes. */
853 static void setup_for_ellipsis (struct it *, int);
854 static void set_iterator_to_next (struct it *, int);
855 static void mark_window_display_accurate_1 (struct window *, int);
856 static int single_display_spec_string_p (Lisp_Object, Lisp_Object);
857 static int display_prop_string_p (Lisp_Object, Lisp_Object);
858 static int row_for_charpos_p (struct glyph_row *, ptrdiff_t);
859 static int cursor_row_p (struct glyph_row *);
860 static int redisplay_mode_lines (Lisp_Object, bool);
861 static char *decode_mode_spec_coding (Lisp_Object, char *, int);
863 static Lisp_Object get_it_property (struct it *it, Lisp_Object prop);
865 static void handle_line_prefix (struct it *);
867 static void pint2str (char *, int, ptrdiff_t);
868 static void pint2hrstr (char *, int, ptrdiff_t);
869 static struct text_pos run_window_scroll_functions (Lisp_Object,
870 struct text_pos);
871 static int text_outside_line_unchanged_p (struct window *,
872 ptrdiff_t, ptrdiff_t);
873 static void store_mode_line_noprop_char (char);
874 static int store_mode_line_noprop (const char *, int, int);
875 static void handle_stop (struct it *);
876 static void handle_stop_backwards (struct it *, ptrdiff_t);
877 static void vmessage (const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (1, 0);
878 static void ensure_echo_area_buffers (void);
879 static void unwind_with_echo_area_buffer (Lisp_Object);
880 static Lisp_Object with_echo_area_buffer_unwind_data (struct window *);
881 static int with_echo_area_buffer (struct window *, int,
882 int (*) (ptrdiff_t, Lisp_Object),
883 ptrdiff_t, Lisp_Object);
884 static void clear_garbaged_frames (void);
885 static int current_message_1 (ptrdiff_t, Lisp_Object);
886 static int truncate_message_1 (ptrdiff_t, Lisp_Object);
887 static void set_message (Lisp_Object);
888 static int set_message_1 (ptrdiff_t, Lisp_Object);
889 static int display_echo_area (struct window *);
890 static int display_echo_area_1 (ptrdiff_t, Lisp_Object);
891 static int resize_mini_window_1 (ptrdiff_t, Lisp_Object);
892 static void unwind_redisplay (void);
893 static int string_char_and_length (const unsigned char *, int *);
894 static struct text_pos display_prop_end (struct it *, Lisp_Object,
895 struct text_pos);
896 static int compute_window_start_on_continuation_line (struct window *);
897 static void insert_left_trunc_glyphs (struct it *);
898 static struct glyph_row *get_overlay_arrow_glyph_row (struct window *,
899 Lisp_Object);
900 static void extend_face_to_end_of_line (struct it *);
901 static int append_space_for_newline (struct it *, int);
902 static int cursor_row_fully_visible_p (struct window *, int, int);
903 static int try_scrolling (Lisp_Object, int, ptrdiff_t, ptrdiff_t, int, int);
904 static int try_cursor_movement (Lisp_Object, struct text_pos, int *);
905 static int trailing_whitespace_p (ptrdiff_t);
906 static intmax_t message_log_check_duplicate (ptrdiff_t, ptrdiff_t);
907 static void push_it (struct it *, struct text_pos *);
908 static void iterate_out_of_display_property (struct it *);
909 static void pop_it (struct it *);
910 static void sync_frame_with_window_matrix_rows (struct window *);
911 static void redisplay_internal (void);
912 static bool echo_area_display (bool);
913 static void redisplay_windows (Lisp_Object);
914 static void redisplay_window (Lisp_Object, bool);
915 static Lisp_Object redisplay_window_error (Lisp_Object);
916 static Lisp_Object redisplay_window_0 (Lisp_Object);
917 static Lisp_Object redisplay_window_1 (Lisp_Object);
918 static int set_cursor_from_row (struct window *, struct glyph_row *,
919 struct glyph_matrix *, ptrdiff_t, ptrdiff_t,
920 int, int);
921 static int update_menu_bar (struct frame *, int, int);
922 static int try_window_reusing_current_matrix (struct window *);
923 static int try_window_id (struct window *);
924 static int display_line (struct it *);
925 static int display_mode_lines (struct window *);
926 static int display_mode_line (struct window *, enum face_id, Lisp_Object);
927 static int display_mode_element (struct it *, int, int, int, Lisp_Object, Lisp_Object, int);
928 static int store_mode_line_string (const char *, Lisp_Object, int, int, int, Lisp_Object);
929 static const char *decode_mode_spec (struct window *, int, int, Lisp_Object *);
930 static void display_menu_bar (struct window *);
931 static ptrdiff_t display_count_lines (ptrdiff_t, ptrdiff_t, ptrdiff_t,
932 ptrdiff_t *);
933 static int display_string (const char *, Lisp_Object, Lisp_Object,
934 ptrdiff_t, ptrdiff_t, struct it *, int, int, int, int);
935 static void compute_line_metrics (struct it *);
936 static void run_redisplay_end_trigger_hook (struct it *);
937 static int get_overlay_strings (struct it *, ptrdiff_t);
938 static int get_overlay_strings_1 (struct it *, ptrdiff_t, int);
939 static void next_overlay_string (struct it *);
940 static void reseat (struct it *, struct text_pos, int);
941 static void reseat_1 (struct it *, struct text_pos, int);
942 static void back_to_previous_visible_line_start (struct it *);
943 static void reseat_at_next_visible_line_start (struct it *, int);
944 static int next_element_from_ellipsis (struct it *);
945 static int next_element_from_display_vector (struct it *);
946 static int next_element_from_string (struct it *);
947 static int next_element_from_c_string (struct it *);
948 static int next_element_from_buffer (struct it *);
949 static int next_element_from_composition (struct it *);
950 static int next_element_from_image (struct it *);
951 #ifdef HAVE_XWIDGETS
952 static int next_element_from_xwidget(struct it *);
953 #endif
954 static int next_element_from_stretch (struct it *);
955 static void load_overlay_strings (struct it *, ptrdiff_t);
956 static int init_from_display_pos (struct it *, struct window *,
957 struct display_pos *);
958 static void reseat_to_string (struct it *, const char *,
959 Lisp_Object, ptrdiff_t, ptrdiff_t, int, int);
960 static int get_next_display_element (struct it *);
961 static enum move_it_result
962 move_it_in_display_line_to (struct it *, ptrdiff_t, int,
963 enum move_operation_enum);
964 static void get_visually_first_element (struct it *);
965 static void init_to_row_start (struct it *, struct window *,
966 struct glyph_row *);
967 static int init_to_row_end (struct it *, struct window *,
968 struct glyph_row *);
969 static void back_to_previous_line_start (struct it *);
970 static int forward_to_next_line_start (struct it *, int *, struct bidi_it *);
971 static struct text_pos string_pos_nchars_ahead (struct text_pos,
972 Lisp_Object, ptrdiff_t);
973 static struct text_pos string_pos (ptrdiff_t, Lisp_Object);
974 static struct text_pos c_string_pos (ptrdiff_t, const char *, bool);
975 static ptrdiff_t number_of_chars (const char *, bool);
976 static void compute_stop_pos (struct it *);
977 static void compute_string_pos (struct text_pos *, struct text_pos,
978 Lisp_Object);
979 static int face_before_or_after_it_pos (struct it *, int);
980 static ptrdiff_t next_overlay_change (ptrdiff_t);
981 static int handle_display_spec (struct it *, Lisp_Object, Lisp_Object,
982 Lisp_Object, struct text_pos *, ptrdiff_t, int);
983 static int handle_single_display_spec (struct it *, Lisp_Object,
984 Lisp_Object, Lisp_Object,
985 struct text_pos *, ptrdiff_t, int, int);
986 static int underlying_face_id (struct it *);
987 static int in_ellipses_for_invisible_text_p (struct display_pos *,
988 struct window *);
990 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
991 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
993 #ifdef HAVE_WINDOW_SYSTEM
995 static void x_consider_frame_title (Lisp_Object);
996 static void update_tool_bar (struct frame *, int);
997 static int redisplay_tool_bar (struct frame *);
998 static void x_draw_bottom_divider (struct window *w);
999 static void notice_overwritten_cursor (struct window *,
1000 enum glyph_row_area,
1001 int, int, int, int);
1002 static void append_stretch_glyph (struct it *, Lisp_Object,
1003 int, int, int);
1006 #endif /* HAVE_WINDOW_SYSTEM */
1008 static void produce_special_glyphs (struct it *, enum display_element_type);
1009 static void show_mouse_face (Mouse_HLInfo *, enum draw_glyphs_face);
1010 static bool coords_in_mouse_face_p (struct window *, int, int);
1014 /***********************************************************************
1015 Window display dimensions
1016 ***********************************************************************/
1018 /* Return the bottom boundary y-position for text lines in window W.
1019 This is the first y position at which a line cannot start.
1020 It is relative to the top of the window.
1022 This is the height of W minus the height of a mode line, if any. */
1025 window_text_bottom_y (struct window *w)
1027 int height = WINDOW_PIXEL_HEIGHT (w);
1029 height -= WINDOW_BOTTOM_DIVIDER_WIDTH (w);
1031 if (WINDOW_WANTS_MODELINE_P (w))
1032 height -= CURRENT_MODE_LINE_HEIGHT (w);
1034 height -= WINDOW_SCROLL_BAR_AREA_HEIGHT (w);
1036 return height;
1039 /* Return the pixel width of display area AREA of window W.
1040 ANY_AREA means return the total width of W, not including
1041 fringes to the left and right of the window. */
1044 window_box_width (struct window *w, enum glyph_row_area area)
1046 int width = w->pixel_width;
1048 if (!w->pseudo_window_p)
1050 width -= WINDOW_SCROLL_BAR_AREA_WIDTH (w);
1051 width -= WINDOW_RIGHT_DIVIDER_WIDTH (w);
1053 if (area == TEXT_AREA)
1054 width -= (WINDOW_MARGINS_WIDTH (w)
1055 + WINDOW_FRINGES_WIDTH (w));
1056 else if (area == LEFT_MARGIN_AREA)
1057 width = WINDOW_LEFT_MARGIN_WIDTH (w);
1058 else if (area == RIGHT_MARGIN_AREA)
1059 width = WINDOW_RIGHT_MARGIN_WIDTH (w);
1062 /* With wide margins, fringes, etc. we might end up with a negative
1063 width, correct that here. */
1064 return max (0, width);
1068 /* Return the pixel height of the display area of window W, not
1069 including mode lines of W, if any. */
1072 window_box_height (struct window *w)
1074 struct frame *f = XFRAME (w->frame);
1075 int height = WINDOW_PIXEL_HEIGHT (w);
1077 eassert (height >= 0);
1079 height -= WINDOW_BOTTOM_DIVIDER_WIDTH (w);
1080 height -= WINDOW_SCROLL_BAR_AREA_HEIGHT (w);
1082 /* Note: the code below that determines the mode-line/header-line
1083 height is essentially the same as that contained in the macro
1084 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1085 the appropriate glyph row has its `mode_line_p' flag set,
1086 and if it doesn't, uses estimate_mode_line_height instead. */
1088 if (WINDOW_WANTS_MODELINE_P (w))
1090 struct glyph_row *ml_row
1091 = (w->current_matrix && w->current_matrix->rows
1092 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1093 : 0);
1094 if (ml_row && ml_row->mode_line_p)
1095 height -= ml_row->height;
1096 else
1097 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1100 if (WINDOW_WANTS_HEADER_LINE_P (w))
1102 struct glyph_row *hl_row
1103 = (w->current_matrix && w->current_matrix->rows
1104 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1105 : 0);
1106 if (hl_row && hl_row->mode_line_p)
1107 height -= hl_row->height;
1108 else
1109 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1112 /* With a very small font and a mode-line that's taller than
1113 default, we might end up with a negative height. */
1114 return max (0, height);
1117 /* Return the window-relative coordinate of the left edge of display
1118 area AREA of window W. ANY_AREA means return the left edge of the
1119 whole window, to the right of the left fringe of W. */
1122 window_box_left_offset (struct window *w, enum glyph_row_area area)
1124 int x;
1126 if (w->pseudo_window_p)
1127 return 0;
1129 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1131 if (area == TEXT_AREA)
1132 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1133 + window_box_width (w, LEFT_MARGIN_AREA));
1134 else if (area == RIGHT_MARGIN_AREA)
1135 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1136 + window_box_width (w, LEFT_MARGIN_AREA)
1137 + window_box_width (w, TEXT_AREA)
1138 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1140 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1141 else if (area == LEFT_MARGIN_AREA
1142 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1143 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1145 /* Don't return more than the window's pixel width. */
1146 return min (x, w->pixel_width);
1150 /* Return the window-relative coordinate of the right edge of display
1151 area AREA of window W. ANY_AREA means return the right edge of the
1152 whole window, to the left of the right fringe of W. */
1154 static int
1155 window_box_right_offset (struct window *w, enum glyph_row_area area)
1157 /* Don't return more than the window's pixel width. */
1158 return min (window_box_left_offset (w, area) + window_box_width (w, area),
1159 w->pixel_width);
1162 /* Return the frame-relative coordinate of the left edge of display
1163 area AREA of window W. ANY_AREA means return the left edge of the
1164 whole window, to the right of the left fringe of W. */
1167 window_box_left (struct window *w, enum glyph_row_area area)
1169 struct frame *f = XFRAME (w->frame);
1170 int x;
1172 if (w->pseudo_window_p)
1173 return FRAME_INTERNAL_BORDER_WIDTH (f);
1175 x = (WINDOW_LEFT_EDGE_X (w)
1176 + window_box_left_offset (w, area));
1178 return x;
1182 /* Return the frame-relative coordinate of the right edge of display
1183 area AREA of window W. ANY_AREA means return the right edge of the
1184 whole window, to the left of the right fringe of W. */
1187 window_box_right (struct window *w, enum glyph_row_area area)
1189 return window_box_left (w, area) + window_box_width (w, area);
1192 /* Get the bounding box of the display area AREA of window W, without
1193 mode lines, in frame-relative coordinates. ANY_AREA means the
1194 whole window, not including the left and right fringes of
1195 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1196 coordinates of the upper-left corner of the box. Return in
1197 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1199 void
1200 window_box (struct window *w, enum glyph_row_area area, int *box_x,
1201 int *box_y, int *box_width, int *box_height)
1203 if (box_width)
1204 *box_width = window_box_width (w, area);
1205 if (box_height)
1206 *box_height = window_box_height (w);
1207 if (box_x)
1208 *box_x = window_box_left (w, area);
1209 if (box_y)
1211 *box_y = WINDOW_TOP_EDGE_Y (w);
1212 if (WINDOW_WANTS_HEADER_LINE_P (w))
1213 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1217 #ifdef HAVE_WINDOW_SYSTEM
1219 /* Get the bounding box of the display area AREA of window W, without
1220 mode lines and both fringes of the window. Return in *TOP_LEFT_X
1221 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1222 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1223 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1224 box. */
1226 static void
1227 window_box_edges (struct window *w, int *top_left_x, int *top_left_y,
1228 int *bottom_right_x, int *bottom_right_y)
1230 window_box (w, ANY_AREA, top_left_x, top_left_y,
1231 bottom_right_x, bottom_right_y);
1232 *bottom_right_x += *top_left_x;
1233 *bottom_right_y += *top_left_y;
1236 #endif /* HAVE_WINDOW_SYSTEM */
1238 /***********************************************************************
1239 Utilities
1240 ***********************************************************************/
1242 /* Return the bottom y-position of the line the iterator IT is in.
1243 This can modify IT's settings. */
1246 line_bottom_y (struct it *it)
1248 int line_height = it->max_ascent + it->max_descent;
1249 int line_top_y = it->current_y;
1251 if (line_height == 0)
1253 if (last_height)
1254 line_height = last_height;
1255 else if (IT_CHARPOS (*it) < ZV)
1257 move_it_by_lines (it, 1);
1258 line_height = (it->max_ascent || it->max_descent
1259 ? it->max_ascent + it->max_descent
1260 : last_height);
1262 else
1264 struct glyph_row *row = it->glyph_row;
1266 /* Use the default character height. */
1267 it->glyph_row = NULL;
1268 it->what = IT_CHARACTER;
1269 it->c = ' ';
1270 it->len = 1;
1271 PRODUCE_GLYPHS (it);
1272 line_height = it->ascent + it->descent;
1273 it->glyph_row = row;
1277 return line_top_y + line_height;
1280 DEFUN ("line-pixel-height", Fline_pixel_height,
1281 Sline_pixel_height, 0, 0, 0,
1282 doc: /* Return height in pixels of text line in the selected window.
1284 Value is the height in pixels of the line at point. */)
1285 (void)
1287 struct it it;
1288 struct text_pos pt;
1289 struct window *w = XWINDOW (selected_window);
1290 struct buffer *old_buffer = NULL;
1291 Lisp_Object result;
1293 if (XBUFFER (w->contents) != current_buffer)
1295 old_buffer = current_buffer;
1296 set_buffer_internal_1 (XBUFFER (w->contents));
1298 SET_TEXT_POS (pt, PT, PT_BYTE);
1299 start_display (&it, w, pt);
1300 it.vpos = it.current_y = 0;
1301 last_height = 0;
1302 result = make_number (line_bottom_y (&it));
1303 if (old_buffer)
1304 set_buffer_internal_1 (old_buffer);
1306 return result;
1309 /* Return the default pixel height of text lines in window W. The
1310 value is the canonical height of the W frame's default font, plus
1311 any extra space required by the line-spacing variable or frame
1312 parameter.
1314 Implementation note: this ignores any line-spacing text properties
1315 put on the newline characters. This is because those properties
1316 only affect the _screen_ line ending in the newline (i.e., in a
1317 continued line, only the last screen line will be affected), which
1318 means only a small number of lines in a buffer can ever use this
1319 feature. Since this function is used to compute the default pixel
1320 equivalent of text lines in a window, we can safely ignore those
1321 few lines. For the same reasons, we ignore the line-height
1322 properties. */
1324 default_line_pixel_height (struct window *w)
1326 struct frame *f = WINDOW_XFRAME (w);
1327 int height = FRAME_LINE_HEIGHT (f);
1329 if (!FRAME_INITIAL_P (f) && BUFFERP (w->contents))
1331 struct buffer *b = XBUFFER (w->contents);
1332 Lisp_Object val = BVAR (b, extra_line_spacing);
1334 if (NILP (val))
1335 val = BVAR (&buffer_defaults, extra_line_spacing);
1336 if (!NILP (val))
1338 if (RANGED_INTEGERP (0, val, INT_MAX))
1339 height += XFASTINT (val);
1340 else if (FLOATP (val))
1342 int addon = XFLOAT_DATA (val) * height + 0.5;
1344 if (addon >= 0)
1345 height += addon;
1348 else
1349 height += f->extra_line_spacing;
1352 return height;
1355 /* Subroutine of pos_visible_p below. Extracts a display string, if
1356 any, from the display spec given as its argument. */
1357 static Lisp_Object
1358 string_from_display_spec (Lisp_Object spec)
1360 if (CONSP (spec))
1362 while (CONSP (spec))
1364 if (STRINGP (XCAR (spec)))
1365 return XCAR (spec);
1366 spec = XCDR (spec);
1369 else if (VECTORP (spec))
1371 ptrdiff_t i;
1373 for (i = 0; i < ASIZE (spec); i++)
1375 if (STRINGP (AREF (spec, i)))
1376 return AREF (spec, i);
1378 return Qnil;
1381 return spec;
1385 /* Limit insanely large values of W->hscroll on frame F to the largest
1386 value that will still prevent first_visible_x and last_visible_x of
1387 'struct it' from overflowing an int. */
1388 static int
1389 window_hscroll_limited (struct window *w, struct frame *f)
1391 ptrdiff_t window_hscroll = w->hscroll;
1392 int window_text_width = window_box_width (w, TEXT_AREA);
1393 int colwidth = FRAME_COLUMN_WIDTH (f);
1395 if (window_hscroll > (INT_MAX - window_text_width) / colwidth - 1)
1396 window_hscroll = (INT_MAX - window_text_width) / colwidth - 1;
1398 return window_hscroll;
1401 /* Return 1 if position CHARPOS is visible in window W.
1402 CHARPOS < 0 means return info about WINDOW_END position.
1403 If visible, set *X and *Y to pixel coordinates of top left corner.
1404 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1405 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1408 pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
1409 int *rtop, int *rbot, int *rowh, int *vpos)
1411 struct it it;
1412 void *itdata = bidi_shelve_cache ();
1413 struct text_pos top;
1414 int visible_p = 0;
1415 struct buffer *old_buffer = NULL;
1416 bool r2l = false;
1418 if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w))))
1419 return visible_p;
1421 if (XBUFFER (w->contents) != current_buffer)
1423 old_buffer = current_buffer;
1424 set_buffer_internal_1 (XBUFFER (w->contents));
1427 SET_TEXT_POS_FROM_MARKER (top, w->start);
1428 /* Scrolling a minibuffer window via scroll bar when the echo area
1429 shows long text sometimes resets the minibuffer contents behind
1430 our backs. */
1431 if (CHARPOS (top) > ZV)
1432 SET_TEXT_POS (top, BEGV, BEGV_BYTE);
1434 /* Compute exact mode line heights. */
1435 if (WINDOW_WANTS_MODELINE_P (w))
1436 w->mode_line_height
1437 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1438 BVAR (current_buffer, mode_line_format));
1440 if (WINDOW_WANTS_HEADER_LINE_P (w))
1441 w->header_line_height
1442 = display_mode_line (w, HEADER_LINE_FACE_ID,
1443 BVAR (current_buffer, header_line_format));
1445 start_display (&it, w, top);
1446 move_it_to (&it, charpos, -1, it.last_visible_y - 1, -1,
1447 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
1449 if (charpos >= 0
1450 && (((!it.bidi_p || it.bidi_it.scan_dir != -1)
1451 && IT_CHARPOS (it) >= charpos)
1452 /* When scanning backwards under bidi iteration, move_it_to
1453 stops at or _before_ CHARPOS, because it stops at or to
1454 the _right_ of the character at CHARPOS. */
1455 || (it.bidi_p && it.bidi_it.scan_dir == -1
1456 && IT_CHARPOS (it) <= charpos)))
1458 /* We have reached CHARPOS, or passed it. How the call to
1459 move_it_to can overshoot: (i) If CHARPOS is on invisible text
1460 or covered by a display property, move_it_to stops at the end
1461 of the invisible text, to the right of CHARPOS. (ii) If
1462 CHARPOS is in a display vector, move_it_to stops on its last
1463 glyph. */
1464 int top_x = it.current_x;
1465 int top_y = it.current_y;
1466 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1467 int bottom_y;
1468 struct it save_it;
1469 void *save_it_data = NULL;
1471 /* Calling line_bottom_y may change it.method, it.position, etc. */
1472 SAVE_IT (save_it, it, save_it_data);
1473 last_height = 0;
1474 bottom_y = line_bottom_y (&it);
1475 if (top_y < window_top_y)
1476 visible_p = bottom_y > window_top_y;
1477 else if (top_y < it.last_visible_y)
1478 visible_p = 1;
1479 if (bottom_y >= it.last_visible_y
1480 && it.bidi_p && it.bidi_it.scan_dir == -1
1481 && IT_CHARPOS (it) < charpos)
1483 /* When the last line of the window is scanned backwards
1484 under bidi iteration, we could be duped into thinking
1485 that we have passed CHARPOS, when in fact move_it_to
1486 simply stopped short of CHARPOS because it reached
1487 last_visible_y. To see if that's what happened, we call
1488 move_it_to again with a slightly larger vertical limit,
1489 and see if it actually moved vertically; if it did, we
1490 didn't really reach CHARPOS, which is beyond window end. */
1491 /* Why 10? because we don't know how many canonical lines
1492 will the height of the next line(s) be. So we guess. */
1493 int ten_more_lines = 10 * default_line_pixel_height (w);
1495 move_it_to (&it, charpos, -1, bottom_y + ten_more_lines, -1,
1496 MOVE_TO_POS | MOVE_TO_Y);
1497 if (it.current_y > top_y)
1498 visible_p = 0;
1501 RESTORE_IT (&it, &save_it, save_it_data);
1502 if (visible_p)
1504 if (it.method == GET_FROM_DISPLAY_VECTOR)
1506 /* We stopped on the last glyph of a display vector.
1507 Try and recompute. Hack alert! */
1508 if (charpos < 2 || top.charpos >= charpos)
1509 top_x = it.glyph_row->x;
1510 else
1512 struct it it2, it2_prev;
1513 /* The idea is to get to the previous buffer
1514 position, consume the character there, and use
1515 the pixel coordinates we get after that. But if
1516 the previous buffer position is also displayed
1517 from a display vector, we need to consume all of
1518 the glyphs from that display vector. */
1519 start_display (&it2, w, top);
1520 move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS);
1521 /* If we didn't get to CHARPOS - 1, there's some
1522 replacing display property at that position, and
1523 we stopped after it. That is exactly the place
1524 whose coordinates we want. */
1525 if (IT_CHARPOS (it2) != charpos - 1)
1526 it2_prev = it2;
1527 else
1529 /* Iterate until we get out of the display
1530 vector that displays the character at
1531 CHARPOS - 1. */
1532 do {
1533 get_next_display_element (&it2);
1534 PRODUCE_GLYPHS (&it2);
1535 it2_prev = it2;
1536 set_iterator_to_next (&it2, 1);
1537 } while (it2.method == GET_FROM_DISPLAY_VECTOR
1538 && IT_CHARPOS (it2) < charpos);
1540 if (ITERATOR_AT_END_OF_LINE_P (&it2_prev)
1541 || it2_prev.current_x > it2_prev.last_visible_x)
1542 top_x = it.glyph_row->x;
1543 else
1545 top_x = it2_prev.current_x;
1546 top_y = it2_prev.current_y;
1550 else if (IT_CHARPOS (it) != charpos)
1552 Lisp_Object cpos = make_number (charpos);
1553 Lisp_Object spec = Fget_char_property (cpos, Qdisplay, Qnil);
1554 Lisp_Object string = string_from_display_spec (spec);
1555 struct text_pos tpos;
1556 int replacing_spec_p;
1557 bool newline_in_string
1558 = (STRINGP (string)
1559 && memchr (SDATA (string), '\n', SBYTES (string)));
1561 SET_TEXT_POS (tpos, charpos, CHAR_TO_BYTE (charpos));
1562 replacing_spec_p
1563 = (!NILP (spec)
1564 && handle_display_spec (NULL, spec, Qnil, Qnil, &tpos,
1565 charpos, FRAME_WINDOW_P (it.f)));
1566 /* The tricky code below is needed because there's a
1567 discrepancy between move_it_to and how we set cursor
1568 when PT is at the beginning of a portion of text
1569 covered by a display property or an overlay with a
1570 display property, or the display line ends in a
1571 newline from a display string. move_it_to will stop
1572 _after_ such display strings, whereas
1573 set_cursor_from_row conspires with cursor_row_p to
1574 place the cursor on the first glyph produced from the
1575 display string. */
1577 /* We have overshoot PT because it is covered by a
1578 display property that replaces the text it covers.
1579 If the string includes embedded newlines, we are also
1580 in the wrong display line. Backtrack to the correct
1581 line, where the display property begins. */
1582 if (replacing_spec_p)
1584 Lisp_Object startpos, endpos;
1585 EMACS_INT start, end;
1586 struct it it3;
1587 int it3_moved;
1589 /* Find the first and the last buffer positions
1590 covered by the display string. */
1591 endpos =
1592 Fnext_single_char_property_change (cpos, Qdisplay,
1593 Qnil, Qnil);
1594 startpos =
1595 Fprevious_single_char_property_change (endpos, Qdisplay,
1596 Qnil, Qnil);
1597 start = XFASTINT (startpos);
1598 end = XFASTINT (endpos);
1599 /* Move to the last buffer position before the
1600 display property. */
1601 start_display (&it3, w, top);
1602 if (start > CHARPOS (top))
1603 move_it_to (&it3, start - 1, -1, -1, -1, MOVE_TO_POS);
1604 /* Move forward one more line if the position before
1605 the display string is a newline or if it is the
1606 rightmost character on a line that is
1607 continued or word-wrapped. */
1608 if (it3.method == GET_FROM_BUFFER
1609 && (it3.c == '\n'
1610 || FETCH_BYTE (IT_BYTEPOS (it3)) == '\n'))
1611 move_it_by_lines (&it3, 1);
1612 else if (move_it_in_display_line_to (&it3, -1,
1613 it3.current_x
1614 + it3.pixel_width,
1615 MOVE_TO_X)
1616 == MOVE_LINE_CONTINUED)
1618 move_it_by_lines (&it3, 1);
1619 /* When we are under word-wrap, the #$@%!
1620 move_it_by_lines moves 2 lines, so we need to
1621 fix that up. */
1622 if (it3.line_wrap == WORD_WRAP)
1623 move_it_by_lines (&it3, -1);
1626 /* Record the vertical coordinate of the display
1627 line where we wound up. */
1628 top_y = it3.current_y;
1629 if (it3.bidi_p)
1631 /* When characters are reordered for display,
1632 the character displayed to the left of the
1633 display string could be _after_ the display
1634 property in the logical order. Use the
1635 smallest vertical position of these two. */
1636 start_display (&it3, w, top);
1637 move_it_to (&it3, end + 1, -1, -1, -1, MOVE_TO_POS);
1638 if (it3.current_y < top_y)
1639 top_y = it3.current_y;
1641 /* Move from the top of the window to the beginning
1642 of the display line where the display string
1643 begins. */
1644 start_display (&it3, w, top);
1645 move_it_to (&it3, -1, 0, top_y, -1, MOVE_TO_X | MOVE_TO_Y);
1646 /* If it3_moved stays zero after the 'while' loop
1647 below, that means we already were at a newline
1648 before the loop (e.g., the display string begins
1649 with a newline), so we don't need to (and cannot)
1650 inspect the glyphs of it3.glyph_row, because
1651 PRODUCE_GLYPHS will not produce anything for a
1652 newline, and thus it3.glyph_row stays at its
1653 stale content it got at top of the window. */
1654 it3_moved = 0;
1655 /* Finally, advance the iterator until we hit the
1656 first display element whose character position is
1657 CHARPOS, or until the first newline from the
1658 display string, which signals the end of the
1659 display line. */
1660 while (get_next_display_element (&it3))
1662 PRODUCE_GLYPHS (&it3);
1663 if (IT_CHARPOS (it3) == charpos
1664 || ITERATOR_AT_END_OF_LINE_P (&it3))
1665 break;
1666 it3_moved = 1;
1667 set_iterator_to_next (&it3, 0);
1669 top_x = it3.current_x - it3.pixel_width;
1670 /* Normally, we would exit the above loop because we
1671 found the display element whose character
1672 position is CHARPOS. For the contingency that we
1673 didn't, and stopped at the first newline from the
1674 display string, move back over the glyphs
1675 produced from the string, until we find the
1676 rightmost glyph not from the string. */
1677 if (it3_moved
1678 && newline_in_string
1679 && IT_CHARPOS (it3) != charpos && EQ (it3.object, string))
1681 struct glyph *g = it3.glyph_row->glyphs[TEXT_AREA]
1682 + it3.glyph_row->used[TEXT_AREA];
1684 while (EQ ((g - 1)->object, string))
1686 --g;
1687 top_x -= g->pixel_width;
1689 eassert (g < it3.glyph_row->glyphs[TEXT_AREA]
1690 + it3.glyph_row->used[TEXT_AREA]);
1695 *x = top_x;
1696 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1697 *rtop = max (0, window_top_y - top_y);
1698 *rbot = max (0, bottom_y - it.last_visible_y);
1699 *rowh = max (0, (min (bottom_y, it.last_visible_y)
1700 - max (top_y, window_top_y)));
1701 *vpos = it.vpos;
1702 if (it.bidi_it.paragraph_dir == R2L)
1703 r2l = true;
1706 else
1708 /* Either we were asked to provide info about WINDOW_END, or
1709 CHARPOS is in the partially visible glyph row at end of
1710 window. */
1711 struct it it2;
1712 void *it2data = NULL;
1714 SAVE_IT (it2, it, it2data);
1715 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1716 move_it_by_lines (&it, 1);
1717 if (charpos < IT_CHARPOS (it)
1718 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1720 visible_p = true;
1721 RESTORE_IT (&it2, &it2, it2data);
1722 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1723 *x = it2.current_x;
1724 *y = it2.current_y + it2.max_ascent - it2.ascent;
1725 *rtop = max (0, -it2.current_y);
1726 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1727 - it.last_visible_y));
1728 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
1729 it.last_visible_y)
1730 - max (it2.current_y,
1731 WINDOW_HEADER_LINE_HEIGHT (w))));
1732 *vpos = it2.vpos;
1733 if (it2.bidi_it.paragraph_dir == R2L)
1734 r2l = true;
1736 else
1737 bidi_unshelve_cache (it2data, 1);
1739 bidi_unshelve_cache (itdata, 0);
1741 if (old_buffer)
1742 set_buffer_internal_1 (old_buffer);
1744 if (visible_p)
1746 if (w->hscroll > 0)
1747 *x -=
1748 window_hscroll_limited (w, WINDOW_XFRAME (w))
1749 * WINDOW_FRAME_COLUMN_WIDTH (w);
1750 /* For lines in an R2L paragraph, we need to mirror the X pixel
1751 coordinate wrt the text area. For the reasons, see the
1752 commentary in buffer_posn_from_coords and the explanation of
1753 the geometry used by the move_it_* functions at the end of
1754 the large commentary near the beginning of this file. */
1755 if (r2l)
1756 *x = window_box_width (w, TEXT_AREA) - *x - 1;
1759 #if 0
1760 /* Debugging code. */
1761 if (visible_p)
1762 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1763 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
1764 else
1765 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
1766 #endif
1768 return visible_p;
1772 /* Return the next character from STR. Return in *LEN the length of
1773 the character. This is like STRING_CHAR_AND_LENGTH but never
1774 returns an invalid character. If we find one, we return a `?', but
1775 with the length of the invalid character. */
1777 static int
1778 string_char_and_length (const unsigned char *str, int *len)
1780 int c;
1782 c = STRING_CHAR_AND_LENGTH (str, *len);
1783 if (!CHAR_VALID_P (c))
1784 /* We may not change the length here because other places in Emacs
1785 don't use this function, i.e. they silently accept invalid
1786 characters. */
1787 c = '?';
1789 return c;
1794 /* Given a position POS containing a valid character and byte position
1795 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1797 static struct text_pos
1798 string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, ptrdiff_t nchars)
1800 eassert (STRINGP (string) && nchars >= 0);
1802 if (STRING_MULTIBYTE (string))
1804 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1805 int len;
1807 while (nchars--)
1809 string_char_and_length (p, &len);
1810 p += len;
1811 CHARPOS (pos) += 1;
1812 BYTEPOS (pos) += len;
1815 else
1816 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1818 return pos;
1822 /* Value is the text position, i.e. character and byte position,
1823 for character position CHARPOS in STRING. */
1825 static struct text_pos
1826 string_pos (ptrdiff_t charpos, Lisp_Object string)
1828 struct text_pos pos;
1829 eassert (STRINGP (string));
1830 eassert (charpos >= 0);
1831 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1832 return pos;
1836 /* Value is a text position, i.e. character and byte position, for
1837 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1838 means recognize multibyte characters. */
1840 static struct text_pos
1841 c_string_pos (ptrdiff_t charpos, const char *s, bool multibyte_p)
1843 struct text_pos pos;
1845 eassert (s != NULL);
1846 eassert (charpos >= 0);
1848 if (multibyte_p)
1850 int len;
1852 SET_TEXT_POS (pos, 0, 0);
1853 while (charpos--)
1855 string_char_and_length ((const unsigned char *) s, &len);
1856 s += len;
1857 CHARPOS (pos) += 1;
1858 BYTEPOS (pos) += len;
1861 else
1862 SET_TEXT_POS (pos, charpos, charpos);
1864 return pos;
1868 /* Value is the number of characters in C string S. MULTIBYTE_P
1869 non-zero means recognize multibyte characters. */
1871 static ptrdiff_t
1872 number_of_chars (const char *s, bool multibyte_p)
1874 ptrdiff_t nchars;
1876 if (multibyte_p)
1878 ptrdiff_t rest = strlen (s);
1879 int len;
1880 const unsigned char *p = (const unsigned char *) s;
1882 for (nchars = 0; rest > 0; ++nchars)
1884 string_char_and_length (p, &len);
1885 rest -= len, p += len;
1888 else
1889 nchars = strlen (s);
1891 return nchars;
1895 /* Compute byte position NEWPOS->bytepos corresponding to
1896 NEWPOS->charpos. POS is a known position in string STRING.
1897 NEWPOS->charpos must be >= POS.charpos. */
1899 static void
1900 compute_string_pos (struct text_pos *newpos, struct text_pos pos, Lisp_Object string)
1902 eassert (STRINGP (string));
1903 eassert (CHARPOS (*newpos) >= CHARPOS (pos));
1905 if (STRING_MULTIBYTE (string))
1906 *newpos = string_pos_nchars_ahead (pos, string,
1907 CHARPOS (*newpos) - CHARPOS (pos));
1908 else
1909 BYTEPOS (*newpos) = CHARPOS (*newpos);
1912 /* EXPORT:
1913 Return an estimation of the pixel height of mode or header lines on
1914 frame F. FACE_ID specifies what line's height to estimate. */
1917 estimate_mode_line_height (struct frame *f, enum face_id face_id)
1919 #ifdef HAVE_WINDOW_SYSTEM
1920 if (FRAME_WINDOW_P (f))
1922 int height = FONT_HEIGHT (FRAME_FONT (f));
1924 /* This function is called so early when Emacs starts that the face
1925 cache and mode line face are not yet initialized. */
1926 if (FRAME_FACE_CACHE (f))
1928 struct face *face = FACE_FROM_ID (f, face_id);
1929 if (face)
1931 if (face->font)
1932 height = FONT_HEIGHT (face->font);
1933 if (face->box_line_width > 0)
1934 height += 2 * face->box_line_width;
1938 return height;
1940 #endif
1942 return 1;
1945 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1946 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1947 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1948 not force the value into range. */
1950 void
1951 pixel_to_glyph_coords (struct frame *f, register int pix_x, register int pix_y,
1952 int *x, int *y, NativeRectangle *bounds, int noclip)
1955 #ifdef HAVE_WINDOW_SYSTEM
1956 if (FRAME_WINDOW_P (f))
1958 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1959 even for negative values. */
1960 if (pix_x < 0)
1961 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1962 if (pix_y < 0)
1963 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1965 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1966 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1968 if (bounds)
1969 STORE_NATIVE_RECT (*bounds,
1970 FRAME_COL_TO_PIXEL_X (f, pix_x),
1971 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1972 FRAME_COLUMN_WIDTH (f) - 1,
1973 FRAME_LINE_HEIGHT (f) - 1);
1975 /* PXW: Should we clip pixels before converting to columns/lines? */
1976 if (!noclip)
1978 if (pix_x < 0)
1979 pix_x = 0;
1980 else if (pix_x > FRAME_TOTAL_COLS (f))
1981 pix_x = FRAME_TOTAL_COLS (f);
1983 if (pix_y < 0)
1984 pix_y = 0;
1985 else if (pix_y > FRAME_TOTAL_LINES (f))
1986 pix_y = FRAME_TOTAL_LINES (f);
1989 #endif
1991 *x = pix_x;
1992 *y = pix_y;
1996 /* Find the glyph under window-relative coordinates X/Y in window W.
1997 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1998 strings. Return in *HPOS and *VPOS the row and column number of
1999 the glyph found. Return in *AREA the glyph area containing X.
2000 Value is a pointer to the glyph found or null if X/Y is not on
2001 text, or we can't tell because W's current matrix is not up to
2002 date. */
2004 static struct glyph *
2005 x_y_to_hpos_vpos (struct window *w, int x, int y, int *hpos, int *vpos,
2006 int *dx, int *dy, int *area)
2008 struct glyph *glyph, *end;
2009 struct glyph_row *row = NULL;
2010 int x0, i;
2012 /* Find row containing Y. Give up if some row is not enabled. */
2013 for (i = 0; i < w->current_matrix->nrows; ++i)
2015 row = MATRIX_ROW (w->current_matrix, i);
2016 if (!row->enabled_p)
2017 return NULL;
2018 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
2019 break;
2022 *vpos = i;
2023 *hpos = 0;
2025 /* Give up if Y is not in the window. */
2026 if (i == w->current_matrix->nrows)
2027 return NULL;
2029 /* Get the glyph area containing X. */
2030 if (w->pseudo_window_p)
2032 *area = TEXT_AREA;
2033 x0 = 0;
2035 else
2037 if (x < window_box_left_offset (w, TEXT_AREA))
2039 *area = LEFT_MARGIN_AREA;
2040 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
2042 else if (x < window_box_right_offset (w, TEXT_AREA))
2044 *area = TEXT_AREA;
2045 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
2047 else
2049 *area = RIGHT_MARGIN_AREA;
2050 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
2054 /* Find glyph containing X. */
2055 glyph = row->glyphs[*area];
2056 end = glyph + row->used[*area];
2057 x -= x0;
2058 while (glyph < end && x >= glyph->pixel_width)
2060 x -= glyph->pixel_width;
2061 ++glyph;
2064 if (glyph == end)
2065 return NULL;
2067 if (dx)
2069 *dx = x;
2070 *dy = y - (row->y + row->ascent - glyph->ascent);
2073 *hpos = glyph - row->glyphs[*area];
2074 return glyph;
2077 /* Convert frame-relative x/y to coordinates relative to window W.
2078 Takes pseudo-windows into account. */
2080 static void
2081 frame_to_window_pixel_xy (struct window *w, int *x, int *y)
2083 if (w->pseudo_window_p)
2085 /* A pseudo-window is always full-width, and starts at the
2086 left edge of the frame, plus a frame border. */
2087 struct frame *f = XFRAME (w->frame);
2088 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
2089 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
2091 else
2093 *x -= WINDOW_LEFT_EDGE_X (w);
2094 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
2098 #ifdef HAVE_WINDOW_SYSTEM
2100 /* EXPORT:
2101 Return in RECTS[] at most N clipping rectangles for glyph string S.
2102 Return the number of stored rectangles. */
2105 get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int n)
2107 XRectangle r;
2109 if (n <= 0)
2110 return 0;
2112 if (s->row->full_width_p)
2114 /* Draw full-width. X coordinates are relative to S->w->left_col. */
2115 r.x = WINDOW_LEFT_EDGE_X (s->w);
2116 if (s->row->mode_line_p)
2117 r.width = WINDOW_PIXEL_WIDTH (s->w) - WINDOW_RIGHT_DIVIDER_WIDTH (s->w);
2118 else
2119 r.width = WINDOW_PIXEL_WIDTH (s->w);
2121 /* Unless displaying a mode or menu bar line, which are always
2122 fully visible, clip to the visible part of the row. */
2123 if (s->w->pseudo_window_p)
2124 r.height = s->row->visible_height;
2125 else
2126 r.height = s->height;
2128 else
2130 /* This is a text line that may be partially visible. */
2131 r.x = window_box_left (s->w, s->area);
2132 r.width = window_box_width (s->w, s->area);
2133 r.height = s->row->visible_height;
2136 if (s->clip_head)
2137 if (r.x < s->clip_head->x)
2139 if (r.width >= s->clip_head->x - r.x)
2140 r.width -= s->clip_head->x - r.x;
2141 else
2142 r.width = 0;
2143 r.x = s->clip_head->x;
2145 if (s->clip_tail)
2146 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
2148 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
2149 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
2150 else
2151 r.width = 0;
2154 /* If S draws overlapping rows, it's sufficient to use the top and
2155 bottom of the window for clipping because this glyph string
2156 intentionally draws over other lines. */
2157 if (s->for_overlaps)
2159 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2160 r.height = window_text_bottom_y (s->w) - r.y;
2162 /* Alas, the above simple strategy does not work for the
2163 environments with anti-aliased text: if the same text is
2164 drawn onto the same place multiple times, it gets thicker.
2165 If the overlap we are processing is for the erased cursor, we
2166 take the intersection with the rectangle of the cursor. */
2167 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
2169 XRectangle rc, r_save = r;
2171 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
2172 rc.y = s->w->phys_cursor.y;
2173 rc.width = s->w->phys_cursor_width;
2174 rc.height = s->w->phys_cursor_height;
2176 x_intersect_rectangles (&r_save, &rc, &r);
2179 else
2181 /* Don't use S->y for clipping because it doesn't take partially
2182 visible lines into account. For example, it can be negative for
2183 partially visible lines at the top of a window. */
2184 if (!s->row->full_width_p
2185 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
2186 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2187 else
2188 r.y = max (0, s->row->y);
2191 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
2193 /* If drawing the cursor, don't let glyph draw outside its
2194 advertised boundaries. Cleartype does this under some circumstances. */
2195 if (s->hl == DRAW_CURSOR)
2197 struct glyph *glyph = s->first_glyph;
2198 int height, max_y;
2200 if (s->x > r.x)
2202 if (r.width >= s->x - r.x)
2203 r.width -= s->x - r.x;
2204 else /* R2L hscrolled row with cursor outside text area */
2205 r.width = 0;
2206 r.x = s->x;
2208 r.width = min (r.width, glyph->pixel_width);
2210 /* If r.y is below window bottom, ensure that we still see a cursor. */
2211 height = min (glyph->ascent + glyph->descent,
2212 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
2213 max_y = window_text_bottom_y (s->w) - height;
2214 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
2215 if (s->ybase - glyph->ascent > max_y)
2217 r.y = max_y;
2218 r.height = height;
2220 else
2222 /* Don't draw cursor glyph taller than our actual glyph. */
2223 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
2224 if (height < r.height)
2226 max_y = r.y + r.height;
2227 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
2228 r.height = min (max_y - r.y, height);
2233 if (s->row->clip)
2235 XRectangle r_save = r;
2237 if (! x_intersect_rectangles (&r_save, s->row->clip, &r))
2238 r.width = 0;
2241 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
2242 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
2244 #ifdef CONVERT_FROM_XRECT
2245 CONVERT_FROM_XRECT (r, *rects);
2246 #else
2247 *rects = r;
2248 #endif
2249 return 1;
2251 else
2253 /* If we are processing overlapping and allowed to return
2254 multiple clipping rectangles, we exclude the row of the glyph
2255 string from the clipping rectangle. This is to avoid drawing
2256 the same text on the environment with anti-aliasing. */
2257 #ifdef CONVERT_FROM_XRECT
2258 XRectangle rs[2];
2259 #else
2260 XRectangle *rs = rects;
2261 #endif
2262 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
2264 if (s->for_overlaps & OVERLAPS_PRED)
2266 rs[i] = r;
2267 if (r.y + r.height > row_y)
2269 if (r.y < row_y)
2270 rs[i].height = row_y - r.y;
2271 else
2272 rs[i].height = 0;
2274 i++;
2276 if (s->for_overlaps & OVERLAPS_SUCC)
2278 rs[i] = r;
2279 if (r.y < row_y + s->row->visible_height)
2281 if (r.y + r.height > row_y + s->row->visible_height)
2283 rs[i].y = row_y + s->row->visible_height;
2284 rs[i].height = r.y + r.height - rs[i].y;
2286 else
2287 rs[i].height = 0;
2289 i++;
2292 n = i;
2293 #ifdef CONVERT_FROM_XRECT
2294 for (i = 0; i < n; i++)
2295 CONVERT_FROM_XRECT (rs[i], rects[i]);
2296 #endif
2297 return n;
2301 /* EXPORT:
2302 Return in *NR the clipping rectangle for glyph string S. */
2304 void
2305 get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr)
2307 get_glyph_string_clip_rects (s, nr, 1);
2311 /* EXPORT:
2312 Return the position and height of the phys cursor in window W.
2313 Set w->phys_cursor_width to width of phys cursor.
2316 void
2317 get_phys_cursor_geometry (struct window *w, struct glyph_row *row,
2318 struct glyph *glyph, int *xp, int *yp, int *heightp)
2320 struct frame *f = XFRAME (WINDOW_FRAME (w));
2321 int x, y, wd, h, h0, y0;
2323 /* Compute the width of the rectangle to draw. If on a stretch
2324 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2325 rectangle as wide as the glyph, but use a canonical character
2326 width instead. */
2327 wd = glyph->pixel_width;
2329 x = w->phys_cursor.x;
2330 if (x < 0)
2332 wd += x;
2333 x = 0;
2336 if (glyph->type == STRETCH_GLYPH
2337 && !x_stretch_cursor_p)
2338 wd = min (FRAME_COLUMN_WIDTH (f), wd);
2339 w->phys_cursor_width = wd;
2341 y = w->phys_cursor.y + row->ascent - glyph->ascent;
2343 /* If y is below window bottom, ensure that we still see a cursor. */
2344 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
2346 h = max (h0, glyph->ascent + glyph->descent);
2347 h0 = min (h0, glyph->ascent + glyph->descent);
2349 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
2350 if (y < y0)
2352 h = max (h - (y0 - y) + 1, h0);
2353 y = y0 - 1;
2355 else
2357 y0 = window_text_bottom_y (w) - h0;
2358 if (y > y0)
2360 h += y - y0;
2361 y = y0;
2365 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
2366 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
2367 *heightp = h;
2371 * Remember which glyph the mouse is over.
2374 void
2375 remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
2377 Lisp_Object window;
2378 struct window *w;
2379 struct glyph_row *r, *gr, *end_row;
2380 enum window_part part;
2381 enum glyph_row_area area;
2382 int x, y, width, height;
2384 /* Try to determine frame pixel position and size of the glyph under
2385 frame pixel coordinates X/Y on frame F. */
2387 if (window_resize_pixelwise)
2389 width = height = 1;
2390 goto virtual_glyph;
2392 else if (!f->glyphs_initialized_p
2393 || (window = window_from_coordinates (f, gx, gy, &part, 0),
2394 NILP (window)))
2396 width = FRAME_SMALLEST_CHAR_WIDTH (f);
2397 height = FRAME_SMALLEST_FONT_HEIGHT (f);
2398 goto virtual_glyph;
2401 w = XWINDOW (window);
2402 width = WINDOW_FRAME_COLUMN_WIDTH (w);
2403 height = WINDOW_FRAME_LINE_HEIGHT (w);
2405 x = window_relative_x_coord (w, part, gx);
2406 y = gy - WINDOW_TOP_EDGE_Y (w);
2408 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
2409 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
2411 if (w->pseudo_window_p)
2413 area = TEXT_AREA;
2414 part = ON_MODE_LINE; /* Don't adjust margin. */
2415 goto text_glyph;
2418 switch (part)
2420 case ON_LEFT_MARGIN:
2421 area = LEFT_MARGIN_AREA;
2422 goto text_glyph;
2424 case ON_RIGHT_MARGIN:
2425 area = RIGHT_MARGIN_AREA;
2426 goto text_glyph;
2428 case ON_HEADER_LINE:
2429 case ON_MODE_LINE:
2430 gr = (part == ON_HEADER_LINE
2431 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
2432 : MATRIX_MODE_LINE_ROW (w->current_matrix));
2433 gy = gr->y;
2434 area = TEXT_AREA;
2435 goto text_glyph_row_found;
2437 case ON_TEXT:
2438 area = TEXT_AREA;
2440 text_glyph:
2441 gr = 0; gy = 0;
2442 for (; r <= end_row && r->enabled_p; ++r)
2443 if (r->y + r->height > y)
2445 gr = r; gy = r->y;
2446 break;
2449 text_glyph_row_found:
2450 if (gr && gy <= y)
2452 struct glyph *g = gr->glyphs[area];
2453 struct glyph *end = g + gr->used[area];
2455 height = gr->height;
2456 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2457 if (gx + g->pixel_width > x)
2458 break;
2460 if (g < end)
2462 if (g->type == IMAGE_GLYPH)
2464 /* Don't remember when mouse is over image, as
2465 image may have hot-spots. */
2466 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2467 return;
2469 width = g->pixel_width;
2471 else
2473 /* Use nominal char spacing at end of line. */
2474 x -= gx;
2475 gx += (x / width) * width;
2478 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2480 gx += window_box_left_offset (w, area);
2481 /* Don't expand over the modeline to make sure the vertical
2482 drag cursor is shown early enough. */
2483 height = min (height,
2484 max (0, WINDOW_BOX_HEIGHT_NO_MODE_LINE (w) - gy));
2487 else
2489 /* Use nominal line height at end of window. */
2490 gx = (x / width) * width;
2491 y -= gy;
2492 gy += (y / height) * height;
2493 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2494 /* See comment above. */
2495 height = min (height,
2496 max (0, WINDOW_BOX_HEIGHT_NO_MODE_LINE (w) - gy));
2498 break;
2500 case ON_LEFT_FRINGE:
2501 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2502 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2503 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2504 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2505 goto row_glyph;
2507 case ON_RIGHT_FRINGE:
2508 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2509 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2510 : window_box_right_offset (w, TEXT_AREA));
2511 if (WINDOW_RIGHT_DIVIDER_WIDTH (w) == 0
2512 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w)
2513 && !WINDOW_RIGHTMOST_P (w))
2514 if (gx < WINDOW_PIXEL_WIDTH (w) - width)
2515 /* Make sure the vertical border can get her own glyph to the
2516 right of the one we build here. */
2517 width = WINDOW_RIGHT_FRINGE_WIDTH (w) - width;
2518 else
2519 width = WINDOW_PIXEL_WIDTH (w) - gx;
2520 else
2521 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2523 goto row_glyph;
2525 case ON_VERTICAL_BORDER:
2526 gx = WINDOW_PIXEL_WIDTH (w) - width;
2527 goto row_glyph;
2529 case ON_VERTICAL_SCROLL_BAR:
2530 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2532 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2533 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2534 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2535 : 0)));
2536 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2538 row_glyph:
2539 gr = 0, gy = 0;
2540 for (; r <= end_row && r->enabled_p; ++r)
2541 if (r->y + r->height > y)
2543 gr = r; gy = r->y;
2544 break;
2547 if (gr && gy <= y)
2548 height = gr->height;
2549 else
2551 /* Use nominal line height at end of window. */
2552 y -= gy;
2553 gy += (y / height) * height;
2555 break;
2557 case ON_RIGHT_DIVIDER:
2558 gx = WINDOW_PIXEL_WIDTH (w) - WINDOW_RIGHT_DIVIDER_WIDTH (w);
2559 width = WINDOW_RIGHT_DIVIDER_WIDTH (w);
2560 gy = 0;
2561 /* The bottom divider prevails. */
2562 height = WINDOW_PIXEL_HEIGHT (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
2563 goto add_edge;
2565 case ON_BOTTOM_DIVIDER:
2566 gx = 0;
2567 width = WINDOW_PIXEL_WIDTH (w);
2568 gy = WINDOW_PIXEL_HEIGHT (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
2569 height = WINDOW_BOTTOM_DIVIDER_WIDTH (w);
2570 goto add_edge;
2572 default:
2574 virtual_glyph:
2575 /* If there is no glyph under the mouse, then we divide the screen
2576 into a grid of the smallest glyph in the frame, and use that
2577 as our "glyph". */
2579 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2580 round down even for negative values. */
2581 if (gx < 0)
2582 gx -= width - 1;
2583 if (gy < 0)
2584 gy -= height - 1;
2586 gx = (gx / width) * width;
2587 gy = (gy / height) * height;
2589 goto store_rect;
2592 add_edge:
2593 gx += WINDOW_LEFT_EDGE_X (w);
2594 gy += WINDOW_TOP_EDGE_Y (w);
2596 store_rect:
2597 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2599 /* Visible feedback for debugging. */
2600 #if 0
2601 #if HAVE_X_WINDOWS
2602 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2603 f->output_data.x->normal_gc,
2604 gx, gy, width, height);
2605 #endif
2606 #endif
2610 #endif /* HAVE_WINDOW_SYSTEM */
2612 static void
2613 adjust_window_ends (struct window *w, struct glyph_row *row, bool current)
2615 eassert (w);
2616 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
2617 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
2618 w->window_end_vpos
2619 = MATRIX_ROW_VPOS (row, current ? w->current_matrix : w->desired_matrix);
2622 /***********************************************************************
2623 Lisp form evaluation
2624 ***********************************************************************/
2626 /* Error handler for safe_eval and safe_call. */
2628 static Lisp_Object
2629 safe_eval_handler (Lisp_Object arg, ptrdiff_t nargs, Lisp_Object *args)
2631 add_to_log ("Error during redisplay: %S signaled %S",
2632 Flist (nargs, args), arg);
2633 return Qnil;
2636 /* Call function FUNC with the rest of NARGS - 1 arguments
2637 following. Return the result, or nil if something went
2638 wrong. Prevent redisplay during the evaluation. */
2640 static Lisp_Object
2641 safe__call (bool inhibit_quit, ptrdiff_t nargs, Lisp_Object func, va_list ap)
2643 Lisp_Object val;
2645 if (inhibit_eval_during_redisplay)
2646 val = Qnil;
2647 else
2649 ptrdiff_t i;
2650 ptrdiff_t count = SPECPDL_INDEX ();
2651 Lisp_Object *args;
2652 USE_SAFE_ALLOCA;
2653 SAFE_ALLOCA_LISP (args, nargs);
2655 args[0] = func;
2656 for (i = 1; i < nargs; i++)
2657 args[i] = va_arg (ap, Lisp_Object);
2659 specbind (Qinhibit_redisplay, Qt);
2660 if (inhibit_quit)
2661 specbind (Qinhibit_quit, Qt);
2662 /* Use Qt to ensure debugger does not run,
2663 so there is no possibility of wanting to redisplay. */
2664 val = internal_condition_case_n (Ffuncall, nargs, args, Qt,
2665 safe_eval_handler);
2666 SAFE_FREE ();
2667 val = unbind_to (count, val);
2670 return val;
2673 Lisp_Object
2674 safe_call (ptrdiff_t nargs, Lisp_Object func, ...)
2676 Lisp_Object retval;
2677 va_list ap;
2679 va_start (ap, func);
2680 retval = safe__call (false, nargs, func, ap);
2681 va_end (ap);
2682 return retval;
2685 /* Call function FN with one argument ARG.
2686 Return the result, or nil if something went wrong. */
2688 Lisp_Object
2689 safe_call1 (Lisp_Object fn, Lisp_Object arg)
2691 return safe_call (2, fn, arg);
2694 static Lisp_Object
2695 safe__call1 (bool inhibit_quit, Lisp_Object fn, ...)
2697 Lisp_Object retval;
2698 va_list ap;
2700 va_start (ap, fn);
2701 retval = safe__call (inhibit_quit, 2, fn, ap);
2702 va_end (ap);
2703 return retval;
2706 static Lisp_Object Qeval;
2708 Lisp_Object
2709 safe_eval (Lisp_Object sexpr)
2711 return safe__call1 (false, Qeval, sexpr);
2714 static Lisp_Object
2715 safe__eval (bool inhibit_quit, Lisp_Object sexpr)
2717 return safe__call1 (inhibit_quit, Qeval, sexpr);
2720 /* Call function FN with two arguments ARG1 and ARG2.
2721 Return the result, or nil if something went wrong. */
2723 Lisp_Object
2724 safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
2726 return safe_call (3, fn, arg1, arg2);
2731 /***********************************************************************
2732 Debugging
2733 ***********************************************************************/
2735 #if 0
2737 /* Define CHECK_IT to perform sanity checks on iterators.
2738 This is for debugging. It is too slow to do unconditionally. */
2740 static void
2741 check_it (struct it *it)
2743 if (it->method == GET_FROM_STRING)
2745 eassert (STRINGP (it->string));
2746 eassert (IT_STRING_CHARPOS (*it) >= 0);
2748 else
2750 eassert (IT_STRING_CHARPOS (*it) < 0);
2751 if (it->method == GET_FROM_BUFFER)
2753 /* Check that character and byte positions agree. */
2754 eassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2758 if (it->dpvec)
2759 eassert (it->current.dpvec_index >= 0);
2760 else
2761 eassert (it->current.dpvec_index < 0);
2764 #define CHECK_IT(IT) check_it ((IT))
2766 #else /* not 0 */
2768 #define CHECK_IT(IT) (void) 0
2770 #endif /* not 0 */
2773 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2775 /* Check that the window end of window W is what we expect it
2776 to be---the last row in the current matrix displaying text. */
2778 static void
2779 check_window_end (struct window *w)
2781 if (!MINI_WINDOW_P (w) && w->window_end_valid)
2783 struct glyph_row *row;
2784 eassert ((row = MATRIX_ROW (w->current_matrix, w->window_end_vpos),
2785 !row->enabled_p
2786 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2787 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2791 #define CHECK_WINDOW_END(W) check_window_end ((W))
2793 #else
2795 #define CHECK_WINDOW_END(W) (void) 0
2797 #endif /* GLYPH_DEBUG and ENABLE_CHECKING */
2799 /***********************************************************************
2800 Iterator initialization
2801 ***********************************************************************/
2803 /* Initialize IT for displaying current_buffer in window W, starting
2804 at character position CHARPOS. CHARPOS < 0 means that no buffer
2805 position is specified which is useful when the iterator is assigned
2806 a position later. BYTEPOS is the byte position corresponding to
2807 CHARPOS.
2809 If ROW is not null, calls to produce_glyphs with IT as parameter
2810 will produce glyphs in that row.
2812 BASE_FACE_ID is the id of a base face to use. It must be one of
2813 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2814 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2815 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2817 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2818 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2819 will be initialized to use the corresponding mode line glyph row of
2820 the desired matrix of W. */
2822 void
2823 init_iterator (struct it *it, struct window *w,
2824 ptrdiff_t charpos, ptrdiff_t bytepos,
2825 struct glyph_row *row, enum face_id base_face_id)
2827 enum face_id remapped_base_face_id = base_face_id;
2829 /* Some precondition checks. */
2830 eassert (w != NULL && it != NULL);
2831 eassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2832 && charpos <= ZV));
2834 /* If face attributes have been changed since the last redisplay,
2835 free realized faces now because they depend on face definitions
2836 that might have changed. Don't free faces while there might be
2837 desired matrices pending which reference these faces. */
2838 if (face_change_count && !inhibit_free_realized_faces)
2840 face_change_count = 0;
2841 free_all_realized_faces (Qnil);
2844 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
2845 if (! NILP (Vface_remapping_alist))
2846 remapped_base_face_id
2847 = lookup_basic_face (XFRAME (w->frame), base_face_id);
2849 /* Use one of the mode line rows of W's desired matrix if
2850 appropriate. */
2851 if (row == NULL)
2853 if (base_face_id == MODE_LINE_FACE_ID
2854 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2855 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2856 else if (base_face_id == HEADER_LINE_FACE_ID)
2857 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2860 /* Clear IT. */
2861 memset (it, 0, sizeof *it);
2862 it->current.overlay_string_index = -1;
2863 it->current.dpvec_index = -1;
2864 it->base_face_id = remapped_base_face_id;
2865 it->string = Qnil;
2866 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2867 it->paragraph_embedding = L2R;
2868 it->bidi_it.string.lstring = Qnil;
2869 it->bidi_it.string.s = NULL;
2870 it->bidi_it.string.bufpos = 0;
2871 it->bidi_it.w = w;
2873 /* The window in which we iterate over current_buffer: */
2874 XSETWINDOW (it->window, w);
2875 it->w = w;
2876 it->f = XFRAME (w->frame);
2878 it->cmp_it.id = -1;
2880 /* Extra space between lines (on window systems only). */
2881 if (base_face_id == DEFAULT_FACE_ID
2882 && FRAME_WINDOW_P (it->f))
2884 if (NATNUMP (BVAR (current_buffer, extra_line_spacing)))
2885 it->extra_line_spacing = XFASTINT (BVAR (current_buffer, extra_line_spacing));
2886 else if (FLOATP (BVAR (current_buffer, extra_line_spacing)))
2887 it->extra_line_spacing = (XFLOAT_DATA (BVAR (current_buffer, extra_line_spacing))
2888 * FRAME_LINE_HEIGHT (it->f));
2889 else if (it->f->extra_line_spacing > 0)
2890 it->extra_line_spacing = it->f->extra_line_spacing;
2891 it->max_extra_line_spacing = 0;
2894 /* If realized faces have been removed, e.g. because of face
2895 attribute changes of named faces, recompute them. When running
2896 in batch mode, the face cache of the initial frame is null. If
2897 we happen to get called, make a dummy face cache. */
2898 if (FRAME_FACE_CACHE (it->f) == NULL)
2899 init_frame_faces (it->f);
2900 if (FRAME_FACE_CACHE (it->f)->used == 0)
2901 recompute_basic_faces (it->f);
2903 /* Current value of the `slice', `space-width', and 'height' properties. */
2904 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2905 it->space_width = Qnil;
2906 it->font_height = Qnil;
2907 it->override_ascent = -1;
2909 /* Are control characters displayed as `^C'? */
2910 it->ctl_arrow_p = !NILP (BVAR (current_buffer, ctl_arrow));
2912 /* -1 means everything between a CR and the following line end
2913 is invisible. >0 means lines indented more than this value are
2914 invisible. */
2915 it->selective = (INTEGERP (BVAR (current_buffer, selective_display))
2916 ? (clip_to_bounds
2917 (-1, XINT (BVAR (current_buffer, selective_display)),
2918 PTRDIFF_MAX))
2919 : (!NILP (BVAR (current_buffer, selective_display))
2920 ? -1 : 0));
2921 it->selective_display_ellipsis_p
2922 = !NILP (BVAR (current_buffer, selective_display_ellipses));
2924 /* Display table to use. */
2925 it->dp = window_display_table (w);
2927 /* Are multibyte characters enabled in current_buffer? */
2928 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
2930 /* Get the position at which the redisplay_end_trigger hook should
2931 be run, if it is to be run at all. */
2932 if (MARKERP (w->redisplay_end_trigger)
2933 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2934 it->redisplay_end_trigger_charpos
2935 = marker_position (w->redisplay_end_trigger);
2936 else if (INTEGERP (w->redisplay_end_trigger))
2937 it->redisplay_end_trigger_charpos
2938 = clip_to_bounds (PTRDIFF_MIN, XINT (w->redisplay_end_trigger),
2939 PTRDIFF_MAX);
2941 it->tab_width = SANE_TAB_WIDTH (current_buffer);
2943 /* Are lines in the display truncated? */
2944 if (base_face_id != DEFAULT_FACE_ID
2945 || it->w->hscroll
2946 || (! WINDOW_FULL_WIDTH_P (it->w)
2947 && ((!NILP (Vtruncate_partial_width_windows)
2948 && !INTEGERP (Vtruncate_partial_width_windows))
2949 || (INTEGERP (Vtruncate_partial_width_windows)
2950 /* PXW: Shall we do something about this? */
2951 && (WINDOW_TOTAL_COLS (it->w)
2952 < XINT (Vtruncate_partial_width_windows))))))
2953 it->line_wrap = TRUNCATE;
2954 else if (NILP (BVAR (current_buffer, truncate_lines)))
2955 it->line_wrap = NILP (BVAR (current_buffer, word_wrap))
2956 ? WINDOW_WRAP : WORD_WRAP;
2957 else
2958 it->line_wrap = TRUNCATE;
2960 /* Get dimensions of truncation and continuation glyphs. These are
2961 displayed as fringe bitmaps under X, but we need them for such
2962 frames when the fringes are turned off. But leave the dimensions
2963 zero for tooltip frames, as these glyphs look ugly there and also
2964 sabotage calculations of tooltip dimensions in x-show-tip. */
2965 #ifdef HAVE_WINDOW_SYSTEM
2966 if (!(FRAME_WINDOW_P (it->f)
2967 && FRAMEP (tip_frame)
2968 && it->f == XFRAME (tip_frame)))
2969 #endif
2971 if (it->line_wrap == TRUNCATE)
2973 /* We will need the truncation glyph. */
2974 eassert (it->glyph_row == NULL);
2975 produce_special_glyphs (it, IT_TRUNCATION);
2976 it->truncation_pixel_width = it->pixel_width;
2978 else
2980 /* We will need the continuation glyph. */
2981 eassert (it->glyph_row == NULL);
2982 produce_special_glyphs (it, IT_CONTINUATION);
2983 it->continuation_pixel_width = it->pixel_width;
2987 /* Reset these values to zero because the produce_special_glyphs
2988 above has changed them. */
2989 it->pixel_width = it->ascent = it->descent = 0;
2990 it->phys_ascent = it->phys_descent = 0;
2992 /* Set this after getting the dimensions of truncation and
2993 continuation glyphs, so that we don't produce glyphs when calling
2994 produce_special_glyphs, above. */
2995 it->glyph_row = row;
2996 it->area = TEXT_AREA;
2998 /* Get the dimensions of the display area. The display area
2999 consists of the visible window area plus a horizontally scrolled
3000 part to the left of the window. All x-values are relative to the
3001 start of this total display area. */
3002 if (base_face_id != DEFAULT_FACE_ID)
3004 /* Mode lines, menu bar in terminal frames. */
3005 it->first_visible_x = 0;
3006 it->last_visible_x = WINDOW_PIXEL_WIDTH (w);
3008 else
3010 it->first_visible_x
3011 = window_hscroll_limited (it->w, it->f) * FRAME_COLUMN_WIDTH (it->f);
3012 it->last_visible_x = (it->first_visible_x
3013 + window_box_width (w, TEXT_AREA));
3015 /* If we truncate lines, leave room for the truncation glyph(s) at
3016 the right margin. Otherwise, leave room for the continuation
3017 glyph(s). Done only if the window has no right fringe. */
3018 if (WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0)
3020 if (it->line_wrap == TRUNCATE)
3021 it->last_visible_x -= it->truncation_pixel_width;
3022 else
3023 it->last_visible_x -= it->continuation_pixel_width;
3026 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
3027 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
3030 /* Leave room for a border glyph. */
3031 if (!FRAME_WINDOW_P (it->f)
3032 && !WINDOW_RIGHTMOST_P (it->w))
3033 it->last_visible_x -= 1;
3035 it->last_visible_y = window_text_bottom_y (w);
3037 /* For mode lines and alike, arrange for the first glyph having a
3038 left box line if the face specifies a box. */
3039 if (base_face_id != DEFAULT_FACE_ID)
3041 struct face *face;
3043 it->face_id = remapped_base_face_id;
3045 /* If we have a boxed mode line, make the first character appear
3046 with a left box line. */
3047 face = FACE_FROM_ID (it->f, remapped_base_face_id);
3048 if (face && face->box != FACE_NO_BOX)
3049 it->start_of_box_run_p = true;
3052 /* If a buffer position was specified, set the iterator there,
3053 getting overlays and face properties from that position. */
3054 if (charpos >= BUF_BEG (current_buffer))
3056 it->stop_charpos = charpos;
3057 it->end_charpos = ZV;
3058 eassert (charpos == BYTE_TO_CHAR (bytepos));
3059 IT_CHARPOS (*it) = charpos;
3060 IT_BYTEPOS (*it) = bytepos;
3062 /* We will rely on `reseat' to set this up properly, via
3063 handle_face_prop. */
3064 it->face_id = it->base_face_id;
3066 it->start = it->current;
3067 /* Do we need to reorder bidirectional text? Not if this is a
3068 unibyte buffer: by definition, none of the single-byte
3069 characters are strong R2L, so no reordering is needed. And
3070 bidi.c doesn't support unibyte buffers anyway. Also, don't
3071 reorder while we are loading loadup.el, since the tables of
3072 character properties needed for reordering are not yet
3073 available. */
3074 it->bidi_p =
3075 NILP (Vpurify_flag)
3076 && !NILP (BVAR (current_buffer, bidi_display_reordering))
3077 && it->multibyte_p;
3079 /* If we are to reorder bidirectional text, init the bidi
3080 iterator. */
3081 if (it->bidi_p)
3083 /* Since we don't know at this point whether there will be
3084 any R2L lines in the window, we reserve space for
3085 truncation/continuation glyphs even if only the left
3086 fringe is absent. */
3087 if (base_face_id == DEFAULT_FACE_ID
3088 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0
3089 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) != 0)
3091 if (it->line_wrap == TRUNCATE)
3092 it->last_visible_x -= it->truncation_pixel_width;
3093 else
3094 it->last_visible_x -= it->continuation_pixel_width;
3096 /* Note the paragraph direction that this buffer wants to
3097 use. */
3098 if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
3099 Qleft_to_right))
3100 it->paragraph_embedding = L2R;
3101 else if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
3102 Qright_to_left))
3103 it->paragraph_embedding = R2L;
3104 else
3105 it->paragraph_embedding = NEUTRAL_DIR;
3106 bidi_unshelve_cache (NULL, 0);
3107 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
3108 &it->bidi_it);
3111 /* Compute faces etc. */
3112 reseat (it, it->current.pos, 1);
3115 CHECK_IT (it);
3119 /* Initialize IT for the display of window W with window start POS. */
3121 void
3122 start_display (struct it *it, struct window *w, struct text_pos pos)
3124 struct glyph_row *row;
3125 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
3127 row = w->desired_matrix->rows + first_vpos;
3128 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
3129 it->first_vpos = first_vpos;
3131 /* Don't reseat to previous visible line start if current start
3132 position is in a string or image. */
3133 if (it->method == GET_FROM_BUFFER && it->line_wrap != TRUNCATE)
3135 int start_at_line_beg_p;
3136 int first_y = it->current_y;
3138 /* If window start is not at a line start, skip forward to POS to
3139 get the correct continuation lines width. */
3140 start_at_line_beg_p = (CHARPOS (pos) == BEGV
3141 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
3142 if (!start_at_line_beg_p)
3144 int new_x;
3146 reseat_at_previous_visible_line_start (it);
3147 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
3149 new_x = it->current_x + it->pixel_width;
3151 /* If lines are continued, this line may end in the middle
3152 of a multi-glyph character (e.g. a control character
3153 displayed as \003, or in the middle of an overlay
3154 string). In this case move_it_to above will not have
3155 taken us to the start of the continuation line but to the
3156 end of the continued line. */
3157 if (it->current_x > 0
3158 && it->line_wrap != TRUNCATE /* Lines are continued. */
3159 && (/* And glyph doesn't fit on the line. */
3160 new_x > it->last_visible_x
3161 /* Or it fits exactly and we're on a window
3162 system frame. */
3163 || (new_x == it->last_visible_x
3164 && FRAME_WINDOW_P (it->f)
3165 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
3166 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
3167 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
3169 if ((it->current.dpvec_index >= 0
3170 || it->current.overlay_string_index >= 0)
3171 /* If we are on a newline from a display vector or
3172 overlay string, then we are already at the end of
3173 a screen line; no need to go to the next line in
3174 that case, as this line is not really continued.
3175 (If we do go to the next line, C-e will not DTRT.) */
3176 && it->c != '\n')
3178 set_iterator_to_next (it, 1);
3179 move_it_in_display_line_to (it, -1, -1, 0);
3182 it->continuation_lines_width += it->current_x;
3184 /* If the character at POS is displayed via a display
3185 vector, move_it_to above stops at the final glyph of
3186 IT->dpvec. To make the caller redisplay that character
3187 again (a.k.a. start at POS), we need to reset the
3188 dpvec_index to the beginning of IT->dpvec. */
3189 else if (it->current.dpvec_index >= 0)
3190 it->current.dpvec_index = 0;
3192 /* We're starting a new display line, not affected by the
3193 height of the continued line, so clear the appropriate
3194 fields in the iterator structure. */
3195 it->max_ascent = it->max_descent = 0;
3196 it->max_phys_ascent = it->max_phys_descent = 0;
3198 it->current_y = first_y;
3199 it->vpos = 0;
3200 it->current_x = it->hpos = 0;
3206 /* Return 1 if POS is a position in ellipses displayed for invisible
3207 text. W is the window we display, for text property lookup. */
3209 static int
3210 in_ellipses_for_invisible_text_p (struct display_pos *pos, struct window *w)
3212 Lisp_Object prop, window;
3213 int ellipses_p = 0;
3214 ptrdiff_t charpos = CHARPOS (pos->pos);
3216 /* If POS specifies a position in a display vector, this might
3217 be for an ellipsis displayed for invisible text. We won't
3218 get the iterator set up for delivering that ellipsis unless
3219 we make sure that it gets aware of the invisible text. */
3220 if (pos->dpvec_index >= 0
3221 && pos->overlay_string_index < 0
3222 && CHARPOS (pos->string_pos) < 0
3223 && charpos > BEGV
3224 && (XSETWINDOW (window, w),
3225 prop = Fget_char_property (make_number (charpos),
3226 Qinvisible, window),
3227 !TEXT_PROP_MEANS_INVISIBLE (prop)))
3229 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
3230 window);
3231 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
3234 return ellipses_p;
3238 /* Initialize IT for stepping through current_buffer in window W,
3239 starting at position POS that includes overlay string and display
3240 vector/ control character translation position information. Value
3241 is zero if there are overlay strings with newlines at POS. */
3243 static int
3244 init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos)
3246 ptrdiff_t charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
3247 int i, overlay_strings_with_newlines = 0;
3249 /* If POS specifies a position in a display vector, this might
3250 be for an ellipsis displayed for invisible text. We won't
3251 get the iterator set up for delivering that ellipsis unless
3252 we make sure that it gets aware of the invisible text. */
3253 if (in_ellipses_for_invisible_text_p (pos, w))
3255 --charpos;
3256 bytepos = 0;
3259 /* Keep in mind: the call to reseat in init_iterator skips invisible
3260 text, so we might end up at a position different from POS. This
3261 is only a problem when POS is a row start after a newline and an
3262 overlay starts there with an after-string, and the overlay has an
3263 invisible property. Since we don't skip invisible text in
3264 display_line and elsewhere immediately after consuming the
3265 newline before the row start, such a POS will not be in a string,
3266 but the call to init_iterator below will move us to the
3267 after-string. */
3268 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
3270 /* This only scans the current chunk -- it should scan all chunks.
3271 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
3272 to 16 in 22.1 to make this a lesser problem. */
3273 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
3275 const char *s = SSDATA (it->overlay_strings[i]);
3276 const char *e = s + SBYTES (it->overlay_strings[i]);
3278 while (s < e && *s != '\n')
3279 ++s;
3281 if (s < e)
3283 overlay_strings_with_newlines = 1;
3284 break;
3288 /* If position is within an overlay string, set up IT to the right
3289 overlay string. */
3290 if (pos->overlay_string_index >= 0)
3292 int relative_index;
3294 /* If the first overlay string happens to have a `display'
3295 property for an image, the iterator will be set up for that
3296 image, and we have to undo that setup first before we can
3297 correct the overlay string index. */
3298 if (it->method == GET_FROM_IMAGE)
3299 pop_it (it);
3301 /* We already have the first chunk of overlay strings in
3302 IT->overlay_strings. Load more until the one for
3303 pos->overlay_string_index is in IT->overlay_strings. */
3304 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
3306 ptrdiff_t n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
3307 it->current.overlay_string_index = 0;
3308 while (n--)
3310 load_overlay_strings (it, 0);
3311 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
3315 it->current.overlay_string_index = pos->overlay_string_index;
3316 relative_index = (it->current.overlay_string_index
3317 % OVERLAY_STRING_CHUNK_SIZE);
3318 it->string = it->overlay_strings[relative_index];
3319 eassert (STRINGP (it->string));
3320 it->current.string_pos = pos->string_pos;
3321 it->method = GET_FROM_STRING;
3322 it->end_charpos = SCHARS (it->string);
3323 /* Set up the bidi iterator for this overlay string. */
3324 if (it->bidi_p)
3326 it->bidi_it.string.lstring = it->string;
3327 it->bidi_it.string.s = NULL;
3328 it->bidi_it.string.schars = SCHARS (it->string);
3329 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
3330 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
3331 it->bidi_it.string.unibyte = !it->multibyte_p;
3332 it->bidi_it.w = it->w;
3333 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3334 FRAME_WINDOW_P (it->f), &it->bidi_it);
3336 /* Synchronize the state of the bidi iterator with
3337 pos->string_pos. For any string position other than
3338 zero, this will be done automagically when we resume
3339 iteration over the string and get_visually_first_element
3340 is called. But if string_pos is zero, and the string is
3341 to be reordered for display, we need to resync manually,
3342 since it could be that the iteration state recorded in
3343 pos ended at string_pos of 0 moving backwards in string. */
3344 if (CHARPOS (pos->string_pos) == 0)
3346 get_visually_first_element (it);
3347 if (IT_STRING_CHARPOS (*it) != 0)
3348 do {
3349 /* Paranoia. */
3350 eassert (it->bidi_it.charpos < it->bidi_it.string.schars);
3351 bidi_move_to_visually_next (&it->bidi_it);
3352 } while (it->bidi_it.charpos != 0);
3354 eassert (IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
3355 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos);
3359 if (CHARPOS (pos->string_pos) >= 0)
3361 /* Recorded position is not in an overlay string, but in another
3362 string. This can only be a string from a `display' property.
3363 IT should already be filled with that string. */
3364 it->current.string_pos = pos->string_pos;
3365 eassert (STRINGP (it->string));
3366 if (it->bidi_p)
3367 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3368 FRAME_WINDOW_P (it->f), &it->bidi_it);
3371 /* Restore position in display vector translations, control
3372 character translations or ellipses. */
3373 if (pos->dpvec_index >= 0)
3375 if (it->dpvec == NULL)
3376 get_next_display_element (it);
3377 eassert (it->dpvec && it->current.dpvec_index == 0);
3378 it->current.dpvec_index = pos->dpvec_index;
3381 CHECK_IT (it);
3382 return !overlay_strings_with_newlines;
3386 /* Initialize IT for stepping through current_buffer in window W
3387 starting at ROW->start. */
3389 static void
3390 init_to_row_start (struct it *it, struct window *w, struct glyph_row *row)
3392 init_from_display_pos (it, w, &row->start);
3393 it->start = row->start;
3394 it->continuation_lines_width = row->continuation_lines_width;
3395 CHECK_IT (it);
3399 /* Initialize IT for stepping through current_buffer in window W
3400 starting in the line following ROW, i.e. starting at ROW->end.
3401 Value is zero if there are overlay strings with newlines at ROW's
3402 end position. */
3404 static int
3405 init_to_row_end (struct it *it, struct window *w, struct glyph_row *row)
3407 int success = 0;
3409 if (init_from_display_pos (it, w, &row->end))
3411 if (row->continued_p)
3412 it->continuation_lines_width
3413 = row->continuation_lines_width + row->pixel_width;
3414 CHECK_IT (it);
3415 success = 1;
3418 return success;
3424 /***********************************************************************
3425 Text properties
3426 ***********************************************************************/
3428 /* Called when IT reaches IT->stop_charpos. Handle text property and
3429 overlay changes. Set IT->stop_charpos to the next position where
3430 to stop. */
3432 static void
3433 handle_stop (struct it *it)
3435 enum prop_handled handled;
3436 int handle_overlay_change_p;
3437 struct props *p;
3439 it->dpvec = NULL;
3440 it->current.dpvec_index = -1;
3441 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
3442 it->ignore_overlay_strings_at_pos_p = 0;
3443 it->ellipsis_p = 0;
3445 /* Use face of preceding text for ellipsis (if invisible) */
3446 if (it->selective_display_ellipsis_p)
3447 it->saved_face_id = it->face_id;
3449 /* Here's the description of the semantics of, and the logic behind,
3450 the various HANDLED_* statuses:
3452 HANDLED_NORMALLY means the handler did its job, and the loop
3453 should proceed to calling the next handler in order.
3455 HANDLED_RECOMPUTE_PROPS means the handler caused a significant
3456 change in the properties and overlays at current position, so the
3457 loop should be restarted, to re-invoke the handlers that were
3458 already called. This happens when fontification-functions were
3459 called by handle_fontified_prop, and actually fontified
3460 something. Another case where HANDLED_RECOMPUTE_PROPS is
3461 returned is when we discover overlay strings that need to be
3462 displayed right away. The loop below will continue for as long
3463 as the status is HANDLED_RECOMPUTE_PROPS.
3465 HANDLED_RETURN means return immediately to the caller, to
3466 continue iteration without calling any further handlers. This is
3467 used when we need to act on some property right away, for example
3468 when we need to display the ellipsis or a replacing display
3469 property, such as display string or image.
3471 HANDLED_OVERLAY_STRING_CONSUMED means an overlay string was just
3472 consumed, and the handler switched to the next overlay string.
3473 This signals the loop below to refrain from looking for more
3474 overlays before all the overlay strings of the current overlay
3475 are processed.
3477 Some of the handlers called by the loop push the iterator state
3478 onto the stack (see 'push_it'), and arrange for the iteration to
3479 continue with another object, such as an image, a display string,
3480 or an overlay string. In most such cases, it->stop_charpos is
3481 set to the first character of the string, so that when the
3482 iteration resumes, this function will immediately be called
3483 again, to examine the properties at the beginning of the string.
3485 When a display or overlay string is exhausted, the iterator state
3486 is popped (see 'pop_it'), and iteration continues with the
3487 previous object. Again, in many such cases this function is
3488 called again to find the next position where properties might
3489 change. */
3493 handled = HANDLED_NORMALLY;
3495 /* Call text property handlers. */
3496 for (p = it_props; p->handler; ++p)
3498 handled = p->handler (it);
3500 if (handled == HANDLED_RECOMPUTE_PROPS)
3501 break;
3502 else if (handled == HANDLED_RETURN)
3504 /* We still want to show before and after strings from
3505 overlays even if the actual buffer text is replaced. */
3506 if (!handle_overlay_change_p
3507 || it->sp > 1
3508 /* Don't call get_overlay_strings_1 if we already
3509 have overlay strings loaded, because doing so
3510 will load them again and push the iterator state
3511 onto the stack one more time, which is not
3512 expected by the rest of the code that processes
3513 overlay strings. */
3514 || (it->current.overlay_string_index < 0
3515 ? !get_overlay_strings_1 (it, 0, 0)
3516 : 0))
3518 if (it->ellipsis_p)
3519 setup_for_ellipsis (it, 0);
3520 /* When handling a display spec, we might load an
3521 empty string. In that case, discard it here. We
3522 used to discard it in handle_single_display_spec,
3523 but that causes get_overlay_strings_1, above, to
3524 ignore overlay strings that we must check. */
3525 if (STRINGP (it->string) && !SCHARS (it->string))
3526 pop_it (it);
3527 return;
3529 else if (STRINGP (it->string) && !SCHARS (it->string))
3530 pop_it (it);
3531 else
3533 it->ignore_overlay_strings_at_pos_p = true;
3534 it->string_from_display_prop_p = 0;
3535 it->from_disp_prop_p = 0;
3536 handle_overlay_change_p = 0;
3538 handled = HANDLED_RECOMPUTE_PROPS;
3539 break;
3541 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
3542 handle_overlay_change_p = 0;
3545 if (handled != HANDLED_RECOMPUTE_PROPS)
3547 /* Don't check for overlay strings below when set to deliver
3548 characters from a display vector. */
3549 if (it->method == GET_FROM_DISPLAY_VECTOR)
3550 handle_overlay_change_p = 0;
3552 /* Handle overlay changes.
3553 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
3554 if it finds overlays. */
3555 if (handle_overlay_change_p)
3556 handled = handle_overlay_change (it);
3559 if (it->ellipsis_p)
3561 setup_for_ellipsis (it, 0);
3562 break;
3565 while (handled == HANDLED_RECOMPUTE_PROPS);
3567 /* Determine where to stop next. */
3568 if (handled == HANDLED_NORMALLY)
3569 compute_stop_pos (it);
3573 /* Compute IT->stop_charpos from text property and overlay change
3574 information for IT's current position. */
3576 static void
3577 compute_stop_pos (struct it *it)
3579 register INTERVAL iv, next_iv;
3580 Lisp_Object object, limit, position;
3581 ptrdiff_t charpos, bytepos;
3583 if (STRINGP (it->string))
3585 /* Strings are usually short, so don't limit the search for
3586 properties. */
3587 it->stop_charpos = it->end_charpos;
3588 object = it->string;
3589 limit = Qnil;
3590 charpos = IT_STRING_CHARPOS (*it);
3591 bytepos = IT_STRING_BYTEPOS (*it);
3593 else
3595 ptrdiff_t pos;
3597 /* If end_charpos is out of range for some reason, such as a
3598 misbehaving display function, rationalize it (Bug#5984). */
3599 if (it->end_charpos > ZV)
3600 it->end_charpos = ZV;
3601 it->stop_charpos = it->end_charpos;
3603 /* If next overlay change is in front of the current stop pos
3604 (which is IT->end_charpos), stop there. Note: value of
3605 next_overlay_change is point-max if no overlay change
3606 follows. */
3607 charpos = IT_CHARPOS (*it);
3608 bytepos = IT_BYTEPOS (*it);
3609 pos = next_overlay_change (charpos);
3610 if (pos < it->stop_charpos)
3611 it->stop_charpos = pos;
3613 /* Set up variables for computing the stop position from text
3614 property changes. */
3615 XSETBUFFER (object, current_buffer);
3616 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3619 /* Get the interval containing IT's position. Value is a null
3620 interval if there isn't such an interval. */
3621 position = make_number (charpos);
3622 iv = validate_interval_range (object, &position, &position, 0);
3623 if (iv)
3625 Lisp_Object values_here[LAST_PROP_IDX];
3626 struct props *p;
3628 /* Get properties here. */
3629 for (p = it_props; p->handler; ++p)
3630 values_here[p->idx] = textget (iv->plist, *p->name);
3632 /* Look for an interval following iv that has different
3633 properties. */
3634 for (next_iv = next_interval (iv);
3635 (next_iv
3636 && (NILP (limit)
3637 || XFASTINT (limit) > next_iv->position));
3638 next_iv = next_interval (next_iv))
3640 for (p = it_props; p->handler; ++p)
3642 Lisp_Object new_value;
3644 new_value = textget (next_iv->plist, *p->name);
3645 if (!EQ (values_here[p->idx], new_value))
3646 break;
3649 if (p->handler)
3650 break;
3653 if (next_iv)
3655 if (INTEGERP (limit)
3656 && next_iv->position >= XFASTINT (limit))
3657 /* No text property change up to limit. */
3658 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3659 else
3660 /* Text properties change in next_iv. */
3661 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3665 if (it->cmp_it.id < 0)
3667 ptrdiff_t stoppos = it->end_charpos;
3669 if (it->bidi_p && it->bidi_it.scan_dir < 0)
3670 stoppos = -1;
3671 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
3672 stoppos, it->string);
3675 eassert (STRINGP (it->string)
3676 || (it->stop_charpos >= BEGV
3677 && it->stop_charpos >= IT_CHARPOS (*it)));
3681 /* Return the position of the next overlay change after POS in
3682 current_buffer. Value is point-max if no overlay change
3683 follows. This is like `next-overlay-change' but doesn't use
3684 xmalloc. */
3686 static ptrdiff_t
3687 next_overlay_change (ptrdiff_t pos)
3689 ptrdiff_t i, noverlays;
3690 ptrdiff_t endpos;
3691 Lisp_Object *overlays;
3692 USE_SAFE_ALLOCA;
3694 /* Get all overlays at the given position. */
3695 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
3697 /* If any of these overlays ends before endpos,
3698 use its ending point instead. */
3699 for (i = 0; i < noverlays; ++i)
3701 Lisp_Object oend;
3702 ptrdiff_t oendpos;
3704 oend = OVERLAY_END (overlays[i]);
3705 oendpos = OVERLAY_POSITION (oend);
3706 endpos = min (endpos, oendpos);
3709 SAFE_FREE ();
3710 return endpos;
3713 /* How many characters forward to search for a display property or
3714 display string. Searching too far forward makes the bidi display
3715 sluggish, especially in small windows. */
3716 #define MAX_DISP_SCAN 250
3718 /* Return the character position of a display string at or after
3719 position specified by POSITION. If no display string exists at or
3720 after POSITION, return ZV. A display string is either an overlay
3721 with `display' property whose value is a string, or a `display'
3722 text property whose value is a string. STRING is data about the
3723 string to iterate; if STRING->lstring is nil, we are iterating a
3724 buffer. FRAME_WINDOW_P is non-zero when we are displaying a window
3725 on a GUI frame. DISP_PROP is set to zero if we searched
3726 MAX_DISP_SCAN characters forward without finding any display
3727 strings, non-zero otherwise. It is set to 2 if the display string
3728 uses any kind of `(space ...)' spec that will produce a stretch of
3729 white space in the text area. */
3730 ptrdiff_t
3731 compute_display_string_pos (struct text_pos *position,
3732 struct bidi_string_data *string,
3733 struct window *w,
3734 int frame_window_p, int *disp_prop)
3736 /* OBJECT = nil means current buffer. */
3737 Lisp_Object object, object1;
3738 Lisp_Object pos, spec, limpos;
3739 int string_p = (string && (STRINGP (string->lstring) || string->s));
3740 ptrdiff_t eob = string_p ? string->schars : ZV;
3741 ptrdiff_t begb = string_p ? 0 : BEGV;
3742 ptrdiff_t bufpos, charpos = CHARPOS (*position);
3743 ptrdiff_t lim =
3744 (charpos < eob - MAX_DISP_SCAN) ? charpos + MAX_DISP_SCAN : eob;
3745 struct text_pos tpos;
3746 int rv = 0;
3748 if (string && STRINGP (string->lstring))
3749 object1 = object = string->lstring;
3750 else if (w && !string_p)
3752 XSETWINDOW (object, w);
3753 object1 = Qnil;
3755 else
3756 object1 = object = Qnil;
3758 *disp_prop = 1;
3760 if (charpos >= eob
3761 /* We don't support display properties whose values are strings
3762 that have display string properties. */
3763 || string->from_disp_str
3764 /* C strings cannot have display properties. */
3765 || (string->s && !STRINGP (object)))
3767 *disp_prop = 0;
3768 return eob;
3771 /* If the character at CHARPOS is where the display string begins,
3772 return CHARPOS. */
3773 pos = make_number (charpos);
3774 if (STRINGP (object))
3775 bufpos = string->bufpos;
3776 else
3777 bufpos = charpos;
3778 tpos = *position;
3779 if (!NILP (spec = Fget_char_property (pos, Qdisplay, object))
3780 && (charpos <= begb
3781 || !EQ (Fget_char_property (make_number (charpos - 1), Qdisplay,
3782 object),
3783 spec))
3784 && (rv = handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
3785 frame_window_p)))
3787 if (rv == 2)
3788 *disp_prop = 2;
3789 return charpos;
3792 /* Look forward for the first character with a `display' property
3793 that will replace the underlying text when displayed. */
3794 limpos = make_number (lim);
3795 do {
3796 pos = Fnext_single_char_property_change (pos, Qdisplay, object1, limpos);
3797 CHARPOS (tpos) = XFASTINT (pos);
3798 if (CHARPOS (tpos) >= lim)
3800 *disp_prop = 0;
3801 break;
3803 if (STRINGP (object))
3804 BYTEPOS (tpos) = string_char_to_byte (object, CHARPOS (tpos));
3805 else
3806 BYTEPOS (tpos) = CHAR_TO_BYTE (CHARPOS (tpos));
3807 spec = Fget_char_property (pos, Qdisplay, object);
3808 if (!STRINGP (object))
3809 bufpos = CHARPOS (tpos);
3810 } while (NILP (spec)
3811 || !(rv = handle_display_spec (NULL, spec, object, Qnil, &tpos,
3812 bufpos, frame_window_p)));
3813 if (rv == 2)
3814 *disp_prop = 2;
3816 return CHARPOS (tpos);
3819 /* Return the character position of the end of the display string that
3820 started at CHARPOS. If there's no display string at CHARPOS,
3821 return -1. A display string is either an overlay with `display'
3822 property whose value is a string or a `display' text property whose
3823 value is a string. */
3824 ptrdiff_t
3825 compute_display_string_end (ptrdiff_t charpos, struct bidi_string_data *string)
3827 /* OBJECT = nil means current buffer. */
3828 Lisp_Object object =
3829 (string && STRINGP (string->lstring)) ? string->lstring : Qnil;
3830 Lisp_Object pos = make_number (charpos);
3831 ptrdiff_t eob =
3832 (STRINGP (object) || (string && string->s)) ? string->schars : ZV;
3834 if (charpos >= eob || (string->s && !STRINGP (object)))
3835 return eob;
3837 /* It could happen that the display property or overlay was removed
3838 since we found it in compute_display_string_pos above. One way
3839 this can happen is if JIT font-lock was called (through
3840 handle_fontified_prop), and jit-lock-functions remove text
3841 properties or overlays from the portion of buffer that includes
3842 CHARPOS. Muse mode is known to do that, for example. In this
3843 case, we return -1 to the caller, to signal that no display
3844 string is actually present at CHARPOS. See bidi_fetch_char for
3845 how this is handled.
3847 An alternative would be to never look for display properties past
3848 it->stop_charpos. But neither compute_display_string_pos nor
3849 bidi_fetch_char that calls it know or care where the next
3850 stop_charpos is. */
3851 if (NILP (Fget_char_property (pos, Qdisplay, object)))
3852 return -1;
3854 /* Look forward for the first character where the `display' property
3855 changes. */
3856 pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil);
3858 return XFASTINT (pos);
3863 /***********************************************************************
3864 Fontification
3865 ***********************************************************************/
3867 /* Handle changes in the `fontified' property of the current buffer by
3868 calling hook functions from Qfontification_functions to fontify
3869 regions of text. */
3871 static enum prop_handled
3872 handle_fontified_prop (struct it *it)
3874 Lisp_Object prop, pos;
3875 enum prop_handled handled = HANDLED_NORMALLY;
3877 if (!NILP (Vmemory_full))
3878 return handled;
3880 /* Get the value of the `fontified' property at IT's current buffer
3881 position. (The `fontified' property doesn't have a special
3882 meaning in strings.) If the value is nil, call functions from
3883 Qfontification_functions. */
3884 if (!STRINGP (it->string)
3885 && it->s == NULL
3886 && !NILP (Vfontification_functions)
3887 && !NILP (Vrun_hooks)
3888 && (pos = make_number (IT_CHARPOS (*it)),
3889 prop = Fget_char_property (pos, Qfontified, Qnil),
3890 /* Ignore the special cased nil value always present at EOB since
3891 no amount of fontifying will be able to change it. */
3892 NILP (prop) && IT_CHARPOS (*it) < Z))
3894 ptrdiff_t count = SPECPDL_INDEX ();
3895 Lisp_Object val;
3896 struct buffer *obuf = current_buffer;
3897 ptrdiff_t begv = BEGV, zv = ZV;
3898 bool old_clip_changed = current_buffer->clip_changed;
3900 val = Vfontification_functions;
3901 specbind (Qfontification_functions, Qnil);
3903 eassert (it->end_charpos == ZV);
3905 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3906 safe_call1 (val, pos);
3907 else
3909 Lisp_Object fns, fn;
3910 struct gcpro gcpro1, gcpro2;
3912 fns = Qnil;
3913 GCPRO2 (val, fns);
3915 for (; CONSP (val); val = XCDR (val))
3917 fn = XCAR (val);
3919 if (EQ (fn, Qt))
3921 /* A value of t indicates this hook has a local
3922 binding; it means to run the global binding too.
3923 In a global value, t should not occur. If it
3924 does, we must ignore it to avoid an endless
3925 loop. */
3926 for (fns = Fdefault_value (Qfontification_functions);
3927 CONSP (fns);
3928 fns = XCDR (fns))
3930 fn = XCAR (fns);
3931 if (!EQ (fn, Qt))
3932 safe_call1 (fn, pos);
3935 else
3936 safe_call1 (fn, pos);
3939 UNGCPRO;
3942 unbind_to (count, Qnil);
3944 /* Fontification functions routinely call `save-restriction'.
3945 Normally, this tags clip_changed, which can confuse redisplay
3946 (see discussion in Bug#6671). Since we don't perform any
3947 special handling of fontification changes in the case where
3948 `save-restriction' isn't called, there's no point doing so in
3949 this case either. So, if the buffer's restrictions are
3950 actually left unchanged, reset clip_changed. */
3951 if (obuf == current_buffer)
3953 if (begv == BEGV && zv == ZV)
3954 current_buffer->clip_changed = old_clip_changed;
3956 /* There isn't much we can reasonably do to protect against
3957 misbehaving fontification, but here's a fig leaf. */
3958 else if (BUFFER_LIVE_P (obuf))
3959 set_buffer_internal_1 (obuf);
3961 /* The fontification code may have added/removed text.
3962 It could do even a lot worse, but let's at least protect against
3963 the most obvious case where only the text past `pos' gets changed',
3964 as is/was done in grep.el where some escapes sequences are turned
3965 into face properties (bug#7876). */
3966 it->end_charpos = ZV;
3968 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3969 something. This avoids an endless loop if they failed to
3970 fontify the text for which reason ever. */
3971 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3972 handled = HANDLED_RECOMPUTE_PROPS;
3975 return handled;
3980 /***********************************************************************
3981 Faces
3982 ***********************************************************************/
3984 /* Set up iterator IT from face properties at its current position.
3985 Called from handle_stop. */
3987 static enum prop_handled
3988 handle_face_prop (struct it *it)
3990 int new_face_id;
3991 ptrdiff_t next_stop;
3993 if (!STRINGP (it->string))
3995 new_face_id
3996 = face_at_buffer_position (it->w,
3997 IT_CHARPOS (*it),
3998 &next_stop,
3999 (IT_CHARPOS (*it)
4000 + TEXT_PROP_DISTANCE_LIMIT),
4001 0, it->base_face_id);
4003 /* Is this a start of a run of characters with box face?
4004 Caveat: this can be called for a freshly initialized
4005 iterator; face_id is -1 in this case. We know that the new
4006 face will not change until limit, i.e. if the new face has a
4007 box, all characters up to limit will have one. But, as
4008 usual, we don't know whether limit is really the end. */
4009 if (new_face_id != it->face_id)
4011 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
4012 /* If it->face_id is -1, old_face below will be NULL, see
4013 the definition of FACE_FROM_ID. This will happen if this
4014 is the initial call that gets the face. */
4015 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
4017 /* If the value of face_id of the iterator is -1, we have to
4018 look in front of IT's position and see whether there is a
4019 face there that's different from new_face_id. */
4020 if (!old_face && IT_CHARPOS (*it) > BEG)
4022 int prev_face_id = face_before_it_pos (it);
4024 old_face = FACE_FROM_ID (it->f, prev_face_id);
4027 /* If the new face has a box, but the old face does not,
4028 this is the start of a run of characters with box face,
4029 i.e. this character has a shadow on the left side. */
4030 it->start_of_box_run_p = (new_face->box != FACE_NO_BOX
4031 && (old_face == NULL || !old_face->box));
4032 it->face_box_p = new_face->box != FACE_NO_BOX;
4035 else
4037 int base_face_id;
4038 ptrdiff_t bufpos;
4039 int i;
4040 Lisp_Object from_overlay
4041 = (it->current.overlay_string_index >= 0
4042 ? it->string_overlays[it->current.overlay_string_index
4043 % OVERLAY_STRING_CHUNK_SIZE]
4044 : Qnil);
4046 /* See if we got to this string directly or indirectly from
4047 an overlay property. That includes the before-string or
4048 after-string of an overlay, strings in display properties
4049 provided by an overlay, their text properties, etc.
4051 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
4052 if (! NILP (from_overlay))
4053 for (i = it->sp - 1; i >= 0; i--)
4055 if (it->stack[i].current.overlay_string_index >= 0)
4056 from_overlay
4057 = it->string_overlays[it->stack[i].current.overlay_string_index
4058 % OVERLAY_STRING_CHUNK_SIZE];
4059 else if (! NILP (it->stack[i].from_overlay))
4060 from_overlay = it->stack[i].from_overlay;
4062 if (!NILP (from_overlay))
4063 break;
4066 if (! NILP (from_overlay))
4068 bufpos = IT_CHARPOS (*it);
4069 /* For a string from an overlay, the base face depends
4070 only on text properties and ignores overlays. */
4071 base_face_id
4072 = face_for_overlay_string (it->w,
4073 IT_CHARPOS (*it),
4074 &next_stop,
4075 (IT_CHARPOS (*it)
4076 + TEXT_PROP_DISTANCE_LIMIT),
4078 from_overlay);
4080 else
4082 bufpos = 0;
4084 /* For strings from a `display' property, use the face at
4085 IT's current buffer position as the base face to merge
4086 with, so that overlay strings appear in the same face as
4087 surrounding text, unless they specify their own faces.
4088 For strings from wrap-prefix and line-prefix properties,
4089 use the default face, possibly remapped via
4090 Vface_remapping_alist. */
4091 /* Note that the fact that we use the face at _buffer_
4092 position means that a 'display' property on an overlay
4093 string will not inherit the face of that overlay string,
4094 but will instead revert to the face of buffer text
4095 covered by the overlay. This is visible, e.g., when the
4096 overlay specifies a box face, but neither the buffer nor
4097 the display string do. This sounds like a design bug,
4098 but Emacs always did that since v21.1, so changing that
4099 might be a big deal. */
4100 base_face_id = it->string_from_prefix_prop_p
4101 ? (!NILP (Vface_remapping_alist)
4102 ? lookup_basic_face (it->f, DEFAULT_FACE_ID)
4103 : DEFAULT_FACE_ID)
4104 : underlying_face_id (it);
4107 new_face_id = face_at_string_position (it->w,
4108 it->string,
4109 IT_STRING_CHARPOS (*it),
4110 bufpos,
4111 &next_stop,
4112 base_face_id, 0);
4114 /* Is this a start of a run of characters with box? Caveat:
4115 this can be called for a freshly allocated iterator; face_id
4116 is -1 is this case. We know that the new face will not
4117 change until the next check pos, i.e. if the new face has a
4118 box, all characters up to that position will have a
4119 box. But, as usual, we don't know whether that position
4120 is really the end. */
4121 if (new_face_id != it->face_id)
4123 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
4124 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
4126 /* If new face has a box but old face hasn't, this is the
4127 start of a run of characters with box, i.e. it has a
4128 shadow on the left side. */
4129 it->start_of_box_run_p
4130 = new_face->box && (old_face == NULL || !old_face->box);
4131 it->face_box_p = new_face->box != FACE_NO_BOX;
4135 it->face_id = new_face_id;
4136 return HANDLED_NORMALLY;
4140 /* Return the ID of the face ``underlying'' IT's current position,
4141 which is in a string. If the iterator is associated with a
4142 buffer, return the face at IT's current buffer position.
4143 Otherwise, use the iterator's base_face_id. */
4145 static int
4146 underlying_face_id (struct it *it)
4148 int face_id = it->base_face_id, i;
4150 eassert (STRINGP (it->string));
4152 for (i = it->sp - 1; i >= 0; --i)
4153 if (NILP (it->stack[i].string))
4154 face_id = it->stack[i].face_id;
4156 return face_id;
4160 /* Compute the face one character before or after the current position
4161 of IT, in the visual order. BEFORE_P non-zero means get the face
4162 in front (to the left in L2R paragraphs, to the right in R2L
4163 paragraphs) of IT's screen position. Value is the ID of the face. */
4165 static int
4166 face_before_or_after_it_pos (struct it *it, int before_p)
4168 int face_id, limit;
4169 ptrdiff_t next_check_charpos;
4170 struct it it_copy;
4171 void *it_copy_data = NULL;
4173 eassert (it->s == NULL);
4175 if (STRINGP (it->string))
4177 ptrdiff_t bufpos, charpos;
4178 int base_face_id;
4180 /* No face change past the end of the string (for the case
4181 we are padding with spaces). No face change before the
4182 string start. */
4183 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
4184 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
4185 return it->face_id;
4187 if (!it->bidi_p)
4189 /* Set charpos to the position before or after IT's current
4190 position, in the logical order, which in the non-bidi
4191 case is the same as the visual order. */
4192 if (before_p)
4193 charpos = IT_STRING_CHARPOS (*it) - 1;
4194 else if (it->what == IT_COMPOSITION)
4195 /* For composition, we must check the character after the
4196 composition. */
4197 charpos = IT_STRING_CHARPOS (*it) + it->cmp_it.nchars;
4198 else
4199 charpos = IT_STRING_CHARPOS (*it) + 1;
4201 else
4203 if (before_p)
4205 /* With bidi iteration, the character before the current
4206 in the visual order cannot be found by simple
4207 iteration, because "reverse" reordering is not
4208 supported. Instead, we need to use the move_it_*
4209 family of functions. */
4210 /* Ignore face changes before the first visible
4211 character on this display line. */
4212 if (it->current_x <= it->first_visible_x)
4213 return it->face_id;
4214 SAVE_IT (it_copy, *it, it_copy_data);
4215 /* Implementation note: Since move_it_in_display_line
4216 works in the iterator geometry, and thinks the first
4217 character is always the leftmost, even in R2L lines,
4218 we don't need to distinguish between the R2L and L2R
4219 cases here. */
4220 move_it_in_display_line (&it_copy, SCHARS (it_copy.string),
4221 it_copy.current_x - 1, MOVE_TO_X);
4222 charpos = IT_STRING_CHARPOS (it_copy);
4223 RESTORE_IT (it, it, it_copy_data);
4225 else
4227 /* Set charpos to the string position of the character
4228 that comes after IT's current position in the visual
4229 order. */
4230 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
4232 it_copy = *it;
4233 while (n--)
4234 bidi_move_to_visually_next (&it_copy.bidi_it);
4236 charpos = it_copy.bidi_it.charpos;
4239 eassert (0 <= charpos && charpos <= SCHARS (it->string));
4241 if (it->current.overlay_string_index >= 0)
4242 bufpos = IT_CHARPOS (*it);
4243 else
4244 bufpos = 0;
4246 base_face_id = underlying_face_id (it);
4248 /* Get the face for ASCII, or unibyte. */
4249 face_id = face_at_string_position (it->w,
4250 it->string,
4251 charpos,
4252 bufpos,
4253 &next_check_charpos,
4254 base_face_id, 0);
4256 /* Correct the face for charsets different from ASCII. Do it
4257 for the multibyte case only. The face returned above is
4258 suitable for unibyte text if IT->string is unibyte. */
4259 if (STRING_MULTIBYTE (it->string))
4261 struct text_pos pos1 = string_pos (charpos, it->string);
4262 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos1);
4263 int c, len;
4264 struct face *face = FACE_FROM_ID (it->f, face_id);
4266 c = string_char_and_length (p, &len);
4267 face_id = FACE_FOR_CHAR (it->f, face, c, charpos, it->string);
4270 else
4272 struct text_pos pos;
4274 if ((IT_CHARPOS (*it) >= ZV && !before_p)
4275 || (IT_CHARPOS (*it) <= BEGV && before_p))
4276 return it->face_id;
4278 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
4279 pos = it->current.pos;
4281 if (!it->bidi_p)
4283 if (before_p)
4284 DEC_TEXT_POS (pos, it->multibyte_p);
4285 else
4287 if (it->what == IT_COMPOSITION)
4289 /* For composition, we must check the position after
4290 the composition. */
4291 pos.charpos += it->cmp_it.nchars;
4292 pos.bytepos += it->len;
4294 else
4295 INC_TEXT_POS (pos, it->multibyte_p);
4298 else
4300 if (before_p)
4302 /* With bidi iteration, the character before the current
4303 in the visual order cannot be found by simple
4304 iteration, because "reverse" reordering is not
4305 supported. Instead, we need to use the move_it_*
4306 family of functions. */
4307 /* Ignore face changes before the first visible
4308 character on this display line. */
4309 if (it->current_x <= it->first_visible_x)
4310 return it->face_id;
4311 SAVE_IT (it_copy, *it, it_copy_data);
4312 /* Implementation note: Since move_it_in_display_line
4313 works in the iterator geometry, and thinks the first
4314 character is always the leftmost, even in R2L lines,
4315 we don't need to distinguish between the R2L and L2R
4316 cases here. */
4317 move_it_in_display_line (&it_copy, ZV,
4318 it_copy.current_x - 1, MOVE_TO_X);
4319 pos = it_copy.current.pos;
4320 RESTORE_IT (it, it, it_copy_data);
4322 else
4324 /* Set charpos to the buffer position of the character
4325 that comes after IT's current position in the visual
4326 order. */
4327 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
4329 it_copy = *it;
4330 while (n--)
4331 bidi_move_to_visually_next (&it_copy.bidi_it);
4333 SET_TEXT_POS (pos,
4334 it_copy.bidi_it.charpos, it_copy.bidi_it.bytepos);
4337 eassert (BEGV <= CHARPOS (pos) && CHARPOS (pos) <= ZV);
4339 /* Determine face for CHARSET_ASCII, or unibyte. */
4340 face_id = face_at_buffer_position (it->w,
4341 CHARPOS (pos),
4342 &next_check_charpos,
4343 limit, 0, -1);
4345 /* Correct the face for charsets different from ASCII. Do it
4346 for the multibyte case only. The face returned above is
4347 suitable for unibyte text if current_buffer is unibyte. */
4348 if (it->multibyte_p)
4350 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
4351 struct face *face = FACE_FROM_ID (it->f, face_id);
4352 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
4356 return face_id;
4361 /***********************************************************************
4362 Invisible text
4363 ***********************************************************************/
4365 /* Set up iterator IT from invisible properties at its current
4366 position. Called from handle_stop. */
4368 static enum prop_handled
4369 handle_invisible_prop (struct it *it)
4371 enum prop_handled handled = HANDLED_NORMALLY;
4372 int invis_p;
4373 Lisp_Object prop;
4375 if (STRINGP (it->string))
4377 Lisp_Object end_charpos, limit, charpos;
4379 /* Get the value of the invisible text property at the
4380 current position. Value will be nil if there is no such
4381 property. */
4382 charpos = make_number (IT_STRING_CHARPOS (*it));
4383 prop = Fget_text_property (charpos, Qinvisible, it->string);
4384 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4386 if (invis_p && IT_STRING_CHARPOS (*it) < it->end_charpos)
4388 /* Record whether we have to display an ellipsis for the
4389 invisible text. */
4390 int display_ellipsis_p = (invis_p == 2);
4391 ptrdiff_t len, endpos;
4393 handled = HANDLED_RECOMPUTE_PROPS;
4395 /* Get the position at which the next visible text can be
4396 found in IT->string, if any. */
4397 endpos = len = SCHARS (it->string);
4398 XSETINT (limit, len);
4401 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
4402 it->string, limit);
4403 if (INTEGERP (end_charpos))
4405 endpos = XFASTINT (end_charpos);
4406 prop = Fget_text_property (end_charpos, Qinvisible, it->string);
4407 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4408 if (invis_p == 2)
4409 display_ellipsis_p = true;
4412 while (invis_p && endpos < len);
4414 if (display_ellipsis_p)
4415 it->ellipsis_p = true;
4417 if (endpos < len)
4419 /* Text at END_CHARPOS is visible. Move IT there. */
4420 struct text_pos old;
4421 ptrdiff_t oldpos;
4423 old = it->current.string_pos;
4424 oldpos = CHARPOS (old);
4425 if (it->bidi_p)
4427 if (it->bidi_it.first_elt
4428 && it->bidi_it.charpos < SCHARS (it->string))
4429 bidi_paragraph_init (it->paragraph_embedding,
4430 &it->bidi_it, 1);
4431 /* Bidi-iterate out of the invisible text. */
4434 bidi_move_to_visually_next (&it->bidi_it);
4436 while (oldpos <= it->bidi_it.charpos
4437 && it->bidi_it.charpos < endpos);
4439 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
4440 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
4441 if (IT_CHARPOS (*it) >= endpos)
4442 it->prev_stop = endpos;
4444 else
4446 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
4447 compute_string_pos (&it->current.string_pos, old, it->string);
4450 else
4452 /* The rest of the string is invisible. If this is an
4453 overlay string, proceed with the next overlay string
4454 or whatever comes and return a character from there. */
4455 if (it->current.overlay_string_index >= 0
4456 && !display_ellipsis_p)
4458 next_overlay_string (it);
4459 /* Don't check for overlay strings when we just
4460 finished processing them. */
4461 handled = HANDLED_OVERLAY_STRING_CONSUMED;
4463 else
4465 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
4466 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
4471 else
4473 ptrdiff_t newpos, next_stop, start_charpos, tem;
4474 Lisp_Object pos, overlay;
4476 /* First of all, is there invisible text at this position? */
4477 tem = start_charpos = IT_CHARPOS (*it);
4478 pos = make_number (tem);
4479 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
4480 &overlay);
4481 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4483 /* If we are on invisible text, skip over it. */
4484 if (invis_p && start_charpos < it->end_charpos)
4486 /* Record whether we have to display an ellipsis for the
4487 invisible text. */
4488 int display_ellipsis_p = invis_p == 2;
4490 handled = HANDLED_RECOMPUTE_PROPS;
4492 /* Loop skipping over invisible text. The loop is left at
4493 ZV or with IT on the first char being visible again. */
4496 /* Try to skip some invisible text. Return value is the
4497 position reached which can be equal to where we start
4498 if there is nothing invisible there. This skips both
4499 over invisible text properties and overlays with
4500 invisible property. */
4501 newpos = skip_invisible (tem, &next_stop, ZV, it->window);
4503 /* If we skipped nothing at all we weren't at invisible
4504 text in the first place. If everything to the end of
4505 the buffer was skipped, end the loop. */
4506 if (newpos == tem || newpos >= ZV)
4507 invis_p = 0;
4508 else
4510 /* We skipped some characters but not necessarily
4511 all there are. Check if we ended up on visible
4512 text. Fget_char_property returns the property of
4513 the char before the given position, i.e. if we
4514 get invis_p = 0, this means that the char at
4515 newpos is visible. */
4516 pos = make_number (newpos);
4517 prop = Fget_char_property (pos, Qinvisible, it->window);
4518 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4521 /* If we ended up on invisible text, proceed to
4522 skip starting with next_stop. */
4523 if (invis_p)
4524 tem = next_stop;
4526 /* If there are adjacent invisible texts, don't lose the
4527 second one's ellipsis. */
4528 if (invis_p == 2)
4529 display_ellipsis_p = true;
4531 while (invis_p);
4533 /* The position newpos is now either ZV or on visible text. */
4534 if (it->bidi_p)
4536 ptrdiff_t bpos = CHAR_TO_BYTE (newpos);
4537 int on_newline
4538 = bpos == ZV_BYTE || FETCH_BYTE (bpos) == '\n';
4539 int after_newline
4540 = newpos <= BEGV || FETCH_BYTE (bpos - 1) == '\n';
4542 /* If the invisible text ends on a newline or on a
4543 character after a newline, we can avoid the costly,
4544 character by character, bidi iteration to NEWPOS, and
4545 instead simply reseat the iterator there. That's
4546 because all bidi reordering information is tossed at
4547 the newline. This is a big win for modes that hide
4548 complete lines, like Outline, Org, etc. */
4549 if (on_newline || after_newline)
4551 struct text_pos tpos;
4552 bidi_dir_t pdir = it->bidi_it.paragraph_dir;
4554 SET_TEXT_POS (tpos, newpos, bpos);
4555 reseat_1 (it, tpos, 0);
4556 /* If we reseat on a newline/ZV, we need to prep the
4557 bidi iterator for advancing to the next character
4558 after the newline/EOB, keeping the current paragraph
4559 direction (so that PRODUCE_GLYPHS does TRT wrt
4560 prepending/appending glyphs to a glyph row). */
4561 if (on_newline)
4563 it->bidi_it.first_elt = 0;
4564 it->bidi_it.paragraph_dir = pdir;
4565 it->bidi_it.ch = (bpos == ZV_BYTE) ? -1 : '\n';
4566 it->bidi_it.nchars = 1;
4567 it->bidi_it.ch_len = 1;
4570 else /* Must use the slow method. */
4572 /* With bidi iteration, the region of invisible text
4573 could start and/or end in the middle of a
4574 non-base embedding level. Therefore, we need to
4575 skip invisible text using the bidi iterator,
4576 starting at IT's current position, until we find
4577 ourselves outside of the invisible text.
4578 Skipping invisible text _after_ bidi iteration
4579 avoids affecting the visual order of the
4580 displayed text when invisible properties are
4581 added or removed. */
4582 if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV)
4584 /* If we were `reseat'ed to a new paragraph,
4585 determine the paragraph base direction. We
4586 need to do it now because
4587 next_element_from_buffer may not have a
4588 chance to do it, if we are going to skip any
4589 text at the beginning, which resets the
4590 FIRST_ELT flag. */
4591 bidi_paragraph_init (it->paragraph_embedding,
4592 &it->bidi_it, 1);
4596 bidi_move_to_visually_next (&it->bidi_it);
4598 while (it->stop_charpos <= it->bidi_it.charpos
4599 && it->bidi_it.charpos < newpos);
4600 IT_CHARPOS (*it) = it->bidi_it.charpos;
4601 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
4602 /* If we overstepped NEWPOS, record its position in
4603 the iterator, so that we skip invisible text if
4604 later the bidi iteration lands us in the
4605 invisible region again. */
4606 if (IT_CHARPOS (*it) >= newpos)
4607 it->prev_stop = newpos;
4610 else
4612 IT_CHARPOS (*it) = newpos;
4613 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
4616 /* If there are before-strings at the start of invisible
4617 text, and the text is invisible because of a text
4618 property, arrange to show before-strings because 20.x did
4619 it that way. (If the text is invisible because of an
4620 overlay property instead of a text property, this is
4621 already handled in the overlay code.) */
4622 if (NILP (overlay)
4623 && get_overlay_strings (it, it->stop_charpos))
4625 handled = HANDLED_RECOMPUTE_PROPS;
4626 if (it->sp > 0)
4628 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
4629 /* The call to get_overlay_strings above recomputes
4630 it->stop_charpos, but it only considers changes
4631 in properties and overlays beyond iterator's
4632 current position. This causes us to miss changes
4633 that happen exactly where the invisible property
4634 ended. So we play it safe here and force the
4635 iterator to check for potential stop positions
4636 immediately after the invisible text. Note that
4637 if get_overlay_strings returns non-zero, it
4638 normally also pushed the iterator stack, so we
4639 need to update the stop position in the slot
4640 below the current one. */
4641 it->stack[it->sp - 1].stop_charpos
4642 = CHARPOS (it->stack[it->sp - 1].current.pos);
4645 else if (display_ellipsis_p)
4647 /* Make sure that the glyphs of the ellipsis will get
4648 correct `charpos' values. If we would not update
4649 it->position here, the glyphs would belong to the
4650 last visible character _before_ the invisible
4651 text, which confuses `set_cursor_from_row'.
4653 We use the last invisible position instead of the
4654 first because this way the cursor is always drawn on
4655 the first "." of the ellipsis, whenever PT is inside
4656 the invisible text. Otherwise the cursor would be
4657 placed _after_ the ellipsis when the point is after the
4658 first invisible character. */
4659 if (!STRINGP (it->object))
4661 it->position.charpos = newpos - 1;
4662 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
4664 it->ellipsis_p = true;
4665 /* Let the ellipsis display before
4666 considering any properties of the following char.
4667 Fixes jasonr@gnu.org 01 Oct 07 bug. */
4668 handled = HANDLED_RETURN;
4673 return handled;
4677 /* Make iterator IT return `...' next.
4678 Replaces LEN characters from buffer. */
4680 static void
4681 setup_for_ellipsis (struct it *it, int len)
4683 /* Use the display table definition for `...'. Invalid glyphs
4684 will be handled by the method returning elements from dpvec. */
4685 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
4687 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
4688 it->dpvec = v->contents;
4689 it->dpend = v->contents + v->header.size;
4691 else
4693 /* Default `...'. */
4694 it->dpvec = default_invis_vector;
4695 it->dpend = default_invis_vector + 3;
4698 it->dpvec_char_len = len;
4699 it->current.dpvec_index = 0;
4700 it->dpvec_face_id = -1;
4702 /* Remember the current face id in case glyphs specify faces.
4703 IT's face is restored in set_iterator_to_next.
4704 saved_face_id was set to preceding char's face in handle_stop. */
4705 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
4706 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
4708 it->method = GET_FROM_DISPLAY_VECTOR;
4709 it->ellipsis_p = true;
4714 /***********************************************************************
4715 'display' property
4716 ***********************************************************************/
4718 /* Set up iterator IT from `display' property at its current position.
4719 Called from handle_stop.
4720 We return HANDLED_RETURN if some part of the display property
4721 overrides the display of the buffer text itself.
4722 Otherwise we return HANDLED_NORMALLY. */
4724 static enum prop_handled
4725 handle_display_prop (struct it *it)
4727 Lisp_Object propval, object, overlay;
4728 struct text_pos *position;
4729 ptrdiff_t bufpos;
4730 /* Nonzero if some property replaces the display of the text itself. */
4731 int display_replaced_p = 0;
4733 if (STRINGP (it->string))
4735 object = it->string;
4736 position = &it->current.string_pos;
4737 bufpos = CHARPOS (it->current.pos);
4739 else
4741 XSETWINDOW (object, it->w);
4742 position = &it->current.pos;
4743 bufpos = CHARPOS (*position);
4746 /* Reset those iterator values set from display property values. */
4747 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
4748 it->space_width = Qnil;
4749 it->font_height = Qnil;
4750 it->voffset = 0;
4752 /* We don't support recursive `display' properties, i.e. string
4753 values that have a string `display' property, that have a string
4754 `display' property etc. */
4755 if (!it->string_from_display_prop_p)
4756 it->area = TEXT_AREA;
4758 propval = get_char_property_and_overlay (make_number (position->charpos),
4759 Qdisplay, object, &overlay);
4760 if (NILP (propval))
4761 return HANDLED_NORMALLY;
4762 /* Now OVERLAY is the overlay that gave us this property, or nil
4763 if it was a text property. */
4765 if (!STRINGP (it->string))
4766 object = it->w->contents;
4768 display_replaced_p = handle_display_spec (it, propval, object, overlay,
4769 position, bufpos,
4770 FRAME_WINDOW_P (it->f));
4772 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
4775 /* Subroutine of handle_display_prop. Returns non-zero if the display
4776 specification in SPEC is a replacing specification, i.e. it would
4777 replace the text covered by `display' property with something else,
4778 such as an image or a display string. If SPEC includes any kind or
4779 `(space ...) specification, the value is 2; this is used by
4780 compute_display_string_pos, which see.
4782 See handle_single_display_spec for documentation of arguments.
4783 frame_window_p is non-zero if the window being redisplayed is on a
4784 GUI frame; this argument is used only if IT is NULL, see below.
4786 IT can be NULL, if this is called by the bidi reordering code
4787 through compute_display_string_pos, which see. In that case, this
4788 function only examines SPEC, but does not otherwise "handle" it, in
4789 the sense that it doesn't set up members of IT from the display
4790 spec. */
4791 static int
4792 handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4793 Lisp_Object overlay, struct text_pos *position,
4794 ptrdiff_t bufpos, int frame_window_p)
4796 int replacing_p = 0;
4797 int rv;
4799 if (CONSP (spec)
4800 /* Simple specifications. */
4801 && !EQ (XCAR (spec), Qimage)
4802 #ifdef HAVE_XWIDGETS
4803 && !EQ (XCAR (spec), Qxwidget)
4804 #endif
4805 && !EQ (XCAR (spec), Qspace)
4806 && !EQ (XCAR (spec), Qwhen)
4807 && !EQ (XCAR (spec), Qslice)
4808 && !EQ (XCAR (spec), Qspace_width)
4809 && !EQ (XCAR (spec), Qheight)
4810 && !EQ (XCAR (spec), Qraise)
4811 /* Marginal area specifications. */
4812 && !(CONSP (XCAR (spec)) && EQ (XCAR (XCAR (spec)), Qmargin))
4813 && !EQ (XCAR (spec), Qleft_fringe)
4814 && !EQ (XCAR (spec), Qright_fringe)
4815 && !NILP (XCAR (spec)))
4817 for (; CONSP (spec); spec = XCDR (spec))
4819 if ((rv = handle_single_display_spec (it, XCAR (spec), object,
4820 overlay, position, bufpos,
4821 replacing_p, frame_window_p)))
4823 replacing_p = rv;
4824 /* If some text in a string is replaced, `position' no
4825 longer points to the position of `object'. */
4826 if (!it || STRINGP (object))
4827 break;
4831 else if (VECTORP (spec))
4833 ptrdiff_t i;
4834 for (i = 0; i < ASIZE (spec); ++i)
4835 if ((rv = handle_single_display_spec (it, AREF (spec, i), object,
4836 overlay, position, bufpos,
4837 replacing_p, frame_window_p)))
4839 replacing_p = rv;
4840 /* If some text in a string is replaced, `position' no
4841 longer points to the position of `object'. */
4842 if (!it || STRINGP (object))
4843 break;
4846 else
4848 if ((rv = handle_single_display_spec (it, spec, object, overlay,
4849 position, bufpos, 0,
4850 frame_window_p)))
4851 replacing_p = rv;
4854 return replacing_p;
4857 /* Value is the position of the end of the `display' property starting
4858 at START_POS in OBJECT. */
4860 static struct text_pos
4861 display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
4863 Lisp_Object end;
4864 struct text_pos end_pos;
4866 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
4867 Qdisplay, object, Qnil);
4868 CHARPOS (end_pos) = XFASTINT (end);
4869 if (STRINGP (object))
4870 compute_string_pos (&end_pos, start_pos, it->string);
4871 else
4872 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
4874 return end_pos;
4878 /* Set up IT from a single `display' property specification SPEC. OBJECT
4879 is the object in which the `display' property was found. *POSITION
4880 is the position in OBJECT at which the `display' property was found.
4881 BUFPOS is the buffer position of OBJECT (different from POSITION if
4882 OBJECT is not a buffer). DISPLAY_REPLACED_P non-zero means that we
4883 previously saw a display specification which already replaced text
4884 display with something else, for example an image; we ignore such
4885 properties after the first one has been processed.
4887 OVERLAY is the overlay this `display' property came from,
4888 or nil if it was a text property.
4890 If SPEC is a `space' or `image' specification, and in some other
4891 cases too, set *POSITION to the position where the `display'
4892 property ends.
4894 If IT is NULL, only examine the property specification in SPEC, but
4895 don't set up IT. In that case, FRAME_WINDOW_P non-zero means SPEC
4896 is intended to be displayed in a window on a GUI frame.
4898 Value is non-zero if something was found which replaces the display
4899 of buffer or string text. */
4901 static int
4902 handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4903 Lisp_Object overlay, struct text_pos *position,
4904 ptrdiff_t bufpos, int display_replaced_p,
4905 int frame_window_p)
4907 Lisp_Object form;
4908 Lisp_Object location, value;
4909 struct text_pos start_pos = *position;
4910 int valid_p;
4912 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4913 If the result is non-nil, use VALUE instead of SPEC. */
4914 form = Qt;
4915 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
4917 spec = XCDR (spec);
4918 if (!CONSP (spec))
4919 return 0;
4920 form = XCAR (spec);
4921 spec = XCDR (spec);
4924 if (!NILP (form) && !EQ (form, Qt))
4926 ptrdiff_t count = SPECPDL_INDEX ();
4927 struct gcpro gcpro1;
4929 /* Bind `object' to the object having the `display' property, a
4930 buffer or string. Bind `position' to the position in the
4931 object where the property was found, and `buffer-position'
4932 to the current position in the buffer. */
4934 if (NILP (object))
4935 XSETBUFFER (object, current_buffer);
4936 specbind (Qobject, object);
4937 specbind (Qposition, make_number (CHARPOS (*position)));
4938 specbind (Qbuffer_position, make_number (bufpos));
4939 GCPRO1 (form);
4940 form = safe_eval (form);
4941 UNGCPRO;
4942 unbind_to (count, Qnil);
4945 if (NILP (form))
4946 return 0;
4948 /* Handle `(height HEIGHT)' specifications. */
4949 if (CONSP (spec)
4950 && EQ (XCAR (spec), Qheight)
4951 && CONSP (XCDR (spec)))
4953 if (it)
4955 if (!FRAME_WINDOW_P (it->f))
4956 return 0;
4958 it->font_height = XCAR (XCDR (spec));
4959 if (!NILP (it->font_height))
4961 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4962 int new_height = -1;
4964 if (CONSP (it->font_height)
4965 && (EQ (XCAR (it->font_height), Qplus)
4966 || EQ (XCAR (it->font_height), Qminus))
4967 && CONSP (XCDR (it->font_height))
4968 && RANGED_INTEGERP (0, XCAR (XCDR (it->font_height)), INT_MAX))
4970 /* `(+ N)' or `(- N)' where N is an integer. */
4971 int steps = XINT (XCAR (XCDR (it->font_height)));
4972 if (EQ (XCAR (it->font_height), Qplus))
4973 steps = - steps;
4974 it->face_id = smaller_face (it->f, it->face_id, steps);
4976 else if (FUNCTIONP (it->font_height))
4978 /* Call function with current height as argument.
4979 Value is the new height. */
4980 Lisp_Object height;
4981 height = safe_call1 (it->font_height,
4982 face->lface[LFACE_HEIGHT_INDEX]);
4983 if (NUMBERP (height))
4984 new_height = XFLOATINT (height);
4986 else if (NUMBERP (it->font_height))
4988 /* Value is a multiple of the canonical char height. */
4989 struct face *f;
4991 f = FACE_FROM_ID (it->f,
4992 lookup_basic_face (it->f, DEFAULT_FACE_ID));
4993 new_height = (XFLOATINT (it->font_height)
4994 * XINT (f->lface[LFACE_HEIGHT_INDEX]));
4996 else
4998 /* Evaluate IT->font_height with `height' bound to the
4999 current specified height to get the new height. */
5000 ptrdiff_t count = SPECPDL_INDEX ();
5002 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
5003 value = safe_eval (it->font_height);
5004 unbind_to (count, Qnil);
5006 if (NUMBERP (value))
5007 new_height = XFLOATINT (value);
5010 if (new_height > 0)
5011 it->face_id = face_with_height (it->f, it->face_id, new_height);
5015 return 0;
5018 /* Handle `(space-width WIDTH)'. */
5019 if (CONSP (spec)
5020 && EQ (XCAR (spec), Qspace_width)
5021 && CONSP (XCDR (spec)))
5023 if (it)
5025 if (!FRAME_WINDOW_P (it->f))
5026 return 0;
5028 value = XCAR (XCDR (spec));
5029 if (NUMBERP (value) && XFLOATINT (value) > 0)
5030 it->space_width = value;
5033 return 0;
5036 /* Handle `(slice X Y WIDTH HEIGHT)'. */
5037 if (CONSP (spec)
5038 && EQ (XCAR (spec), Qslice))
5040 Lisp_Object tem;
5042 if (it)
5044 if (!FRAME_WINDOW_P (it->f))
5045 return 0;
5047 if (tem = XCDR (spec), CONSP (tem))
5049 it->slice.x = XCAR (tem);
5050 if (tem = XCDR (tem), CONSP (tem))
5052 it->slice.y = XCAR (tem);
5053 if (tem = XCDR (tem), CONSP (tem))
5055 it->slice.width = XCAR (tem);
5056 if (tem = XCDR (tem), CONSP (tem))
5057 it->slice.height = XCAR (tem);
5063 return 0;
5066 /* Handle `(raise FACTOR)'. */
5067 if (CONSP (spec)
5068 && EQ (XCAR (spec), Qraise)
5069 && CONSP (XCDR (spec)))
5071 if (it)
5073 if (!FRAME_WINDOW_P (it->f))
5074 return 0;
5076 #ifdef HAVE_WINDOW_SYSTEM
5077 value = XCAR (XCDR (spec));
5078 if (NUMBERP (value))
5080 struct face *face = FACE_FROM_ID (it->f, it->face_id);
5081 it->voffset = - (XFLOATINT (value)
5082 * (FONT_HEIGHT (face->font)));
5084 #endif /* HAVE_WINDOW_SYSTEM */
5087 return 0;
5090 /* Don't handle the other kinds of display specifications
5091 inside a string that we got from a `display' property. */
5092 if (it && it->string_from_display_prop_p)
5093 return 0;
5095 /* Characters having this form of property are not displayed, so
5096 we have to find the end of the property. */
5097 if (it)
5099 start_pos = *position;
5100 *position = display_prop_end (it, object, start_pos);
5102 value = Qnil;
5104 /* Stop the scan at that end position--we assume that all
5105 text properties change there. */
5106 if (it)
5107 it->stop_charpos = position->charpos;
5109 /* Handle `(left-fringe BITMAP [FACE])'
5110 and `(right-fringe BITMAP [FACE])'. */
5111 if (CONSP (spec)
5112 && (EQ (XCAR (spec), Qleft_fringe)
5113 || EQ (XCAR (spec), Qright_fringe))
5114 && CONSP (XCDR (spec)))
5116 int fringe_bitmap;
5118 if (it)
5120 if (!FRAME_WINDOW_P (it->f))
5121 /* If we return here, POSITION has been advanced
5122 across the text with this property. */
5124 /* Synchronize the bidi iterator with POSITION. This is
5125 needed because we are not going to push the iterator
5126 on behalf of this display property, so there will be
5127 no pop_it call to do this synchronization for us. */
5128 if (it->bidi_p)
5130 it->position = *position;
5131 iterate_out_of_display_property (it);
5132 *position = it->position;
5134 /* If we were to display this fringe bitmap,
5135 next_element_from_image would have reset this flag.
5136 Do the same, to avoid affecting overlays that
5137 follow. */
5138 it->ignore_overlay_strings_at_pos_p = 0;
5139 return 1;
5142 else if (!frame_window_p)
5143 return 1;
5145 #ifdef HAVE_WINDOW_SYSTEM
5146 value = XCAR (XCDR (spec));
5147 if (!SYMBOLP (value)
5148 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
5149 /* If we return here, POSITION has been advanced
5150 across the text with this property. */
5152 if (it && it->bidi_p)
5154 it->position = *position;
5155 iterate_out_of_display_property (it);
5156 *position = it->position;
5158 if (it)
5159 /* Reset this flag like next_element_from_image would. */
5160 it->ignore_overlay_strings_at_pos_p = 0;
5161 return 1;
5164 if (it)
5166 int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
5168 if (CONSP (XCDR (XCDR (spec))))
5170 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
5171 int face_id2 = lookup_derived_face (it->f, face_name,
5172 FRINGE_FACE_ID, 0);
5173 if (face_id2 >= 0)
5174 face_id = face_id2;
5177 /* Save current settings of IT so that we can restore them
5178 when we are finished with the glyph property value. */
5179 push_it (it, position);
5181 it->area = TEXT_AREA;
5182 it->what = IT_IMAGE;
5183 it->image_id = -1; /* no image */
5184 it->position = start_pos;
5185 it->object = NILP (object) ? it->w->contents : object;
5186 it->method = GET_FROM_IMAGE;
5187 it->from_overlay = Qnil;
5188 it->face_id = face_id;
5189 it->from_disp_prop_p = true;
5191 /* Say that we haven't consumed the characters with
5192 `display' property yet. The call to pop_it in
5193 set_iterator_to_next will clean this up. */
5194 *position = start_pos;
5196 if (EQ (XCAR (spec), Qleft_fringe))
5198 it->left_user_fringe_bitmap = fringe_bitmap;
5199 it->left_user_fringe_face_id = face_id;
5201 else
5203 it->right_user_fringe_bitmap = fringe_bitmap;
5204 it->right_user_fringe_face_id = face_id;
5207 #endif /* HAVE_WINDOW_SYSTEM */
5208 return 1;
5211 /* Prepare to handle `((margin left-margin) ...)',
5212 `((margin right-margin) ...)' and `((margin nil) ...)'
5213 prefixes for display specifications. */
5214 location = Qunbound;
5215 if (CONSP (spec) && CONSP (XCAR (spec)))
5217 Lisp_Object tem;
5219 value = XCDR (spec);
5220 if (CONSP (value))
5221 value = XCAR (value);
5223 tem = XCAR (spec);
5224 if (EQ (XCAR (tem), Qmargin)
5225 && (tem = XCDR (tem),
5226 tem = CONSP (tem) ? XCAR (tem) : Qnil,
5227 (NILP (tem)
5228 || EQ (tem, Qleft_margin)
5229 || EQ (tem, Qright_margin))))
5230 location = tem;
5233 if (EQ (location, Qunbound))
5235 location = Qnil;
5236 value = spec;
5239 /* After this point, VALUE is the property after any
5240 margin prefix has been stripped. It must be a string,
5241 an image specification, or `(space ...)'.
5243 LOCATION specifies where to display: `left-margin',
5244 `right-margin' or nil. */
5246 valid_p = (STRINGP (value)
5247 #ifdef HAVE_WINDOW_SYSTEM
5248 || ((it ? FRAME_WINDOW_P (it->f) : frame_window_p)
5249 && valid_image_p (value))
5250 #endif /* not HAVE_WINDOW_SYSTEM */
5251 || (CONSP (value) && EQ (XCAR (value), Qspace))
5252 #ifdef HAVE_XWIDGETS
5253 || valid_xwidget_spec_p(value)
5254 #endif
5257 if (valid_p && !display_replaced_p)
5259 int retval = 1;
5261 if (!it)
5263 /* Callers need to know whether the display spec is any kind
5264 of `(space ...)' spec that is about to affect text-area
5265 display. */
5266 if (CONSP (value) && EQ (XCAR (value), Qspace) && NILP (location))
5267 retval = 2;
5268 return retval;
5271 /* Save current settings of IT so that we can restore them
5272 when we are finished with the glyph property value. */
5273 push_it (it, position);
5274 it->from_overlay = overlay;
5275 it->from_disp_prop_p = true;
5277 if (NILP (location))
5278 it->area = TEXT_AREA;
5279 else if (EQ (location, Qleft_margin))
5280 it->area = LEFT_MARGIN_AREA;
5281 else
5282 it->area = RIGHT_MARGIN_AREA;
5284 if (STRINGP (value))
5286 it->string = value;
5287 it->multibyte_p = STRING_MULTIBYTE (it->string);
5288 it->current.overlay_string_index = -1;
5289 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5290 it->end_charpos = it->string_nchars = SCHARS (it->string);
5291 it->method = GET_FROM_STRING;
5292 it->stop_charpos = 0;
5293 it->prev_stop = 0;
5294 it->base_level_stop = 0;
5295 it->string_from_display_prop_p = true;
5296 /* Say that we haven't consumed the characters with
5297 `display' property yet. The call to pop_it in
5298 set_iterator_to_next will clean this up. */
5299 if (BUFFERP (object))
5300 *position = start_pos;
5302 /* Force paragraph direction to be that of the parent
5303 object. If the parent object's paragraph direction is
5304 not yet determined, default to L2R. */
5305 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
5306 it->paragraph_embedding = it->bidi_it.paragraph_dir;
5307 else
5308 it->paragraph_embedding = L2R;
5310 /* Set up the bidi iterator for this display string. */
5311 if (it->bidi_p)
5313 it->bidi_it.string.lstring = it->string;
5314 it->bidi_it.string.s = NULL;
5315 it->bidi_it.string.schars = it->end_charpos;
5316 it->bidi_it.string.bufpos = bufpos;
5317 it->bidi_it.string.from_disp_str = 1;
5318 it->bidi_it.string.unibyte = !it->multibyte_p;
5319 it->bidi_it.w = it->w;
5320 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5323 else if (CONSP (value) && EQ (XCAR (value), Qspace))
5325 it->method = GET_FROM_STRETCH;
5326 it->object = value;
5327 *position = it->position = start_pos;
5328 retval = 1 + (it->area == TEXT_AREA);
5330 #ifdef HAVE_XWIDGETS
5331 else if (valid_xwidget_spec_p(value))
5333 //printf("handle_single_display_spec: im an xwidget!!\n");
5334 it->what = IT_XWIDGET;
5335 it->method = GET_FROM_XWIDGET;
5336 it->position = start_pos;
5337 it->object = NILP (object) ? it->w->contents : object;
5338 *position = start_pos;
5340 it->xwidget = lookup_xwidget(value);
5342 #endif
5343 #ifdef HAVE_WINDOW_SYSTEM
5344 else
5346 it->what = IT_IMAGE;
5347 it->image_id = lookup_image (it->f, value);
5348 it->position = start_pos;
5349 it->object = NILP (object) ? it->w->contents : object;
5350 it->method = GET_FROM_IMAGE;
5352 /* Say that we haven't consumed the characters with
5353 `display' property yet. The call to pop_it in
5354 set_iterator_to_next will clean this up. */
5355 *position = start_pos;
5357 #endif /* HAVE_WINDOW_SYSTEM */
5359 return retval;
5362 /* Invalid property or property not supported. Restore
5363 POSITION to what it was before. */
5364 *position = start_pos;
5365 return 0;
5368 /* Check if PROP is a display property value whose text should be
5369 treated as intangible. OVERLAY is the overlay from which PROP
5370 came, or nil if it came from a text property. CHARPOS and BYTEPOS
5371 specify the buffer position covered by PROP. */
5374 display_prop_intangible_p (Lisp_Object prop, Lisp_Object overlay,
5375 ptrdiff_t charpos, ptrdiff_t bytepos)
5377 int frame_window_p = FRAME_WINDOW_P (XFRAME (selected_frame));
5378 struct text_pos position;
5380 SET_TEXT_POS (position, charpos, bytepos);
5381 return handle_display_spec (NULL, prop, Qnil, overlay,
5382 &position, charpos, frame_window_p);
5386 /* Return 1 if PROP is a display sub-property value containing STRING.
5388 Implementation note: this and the following function are really
5389 special cases of handle_display_spec and
5390 handle_single_display_spec, and should ideally use the same code.
5391 Until they do, these two pairs must be consistent and must be
5392 modified in sync. */
5394 static int
5395 single_display_spec_string_p (Lisp_Object prop, Lisp_Object string)
5397 if (EQ (string, prop))
5398 return 1;
5400 /* Skip over `when FORM'. */
5401 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
5403 prop = XCDR (prop);
5404 if (!CONSP (prop))
5405 return 0;
5406 /* Actually, the condition following `when' should be eval'ed,
5407 like handle_single_display_spec does, and we should return
5408 zero if it evaluates to nil. However, this function is
5409 called only when the buffer was already displayed and some
5410 glyph in the glyph matrix was found to come from a display
5411 string. Therefore, the condition was already evaluated, and
5412 the result was non-nil, otherwise the display string wouldn't
5413 have been displayed and we would have never been called for
5414 this property. Thus, we can skip the evaluation and assume
5415 its result is non-nil. */
5416 prop = XCDR (prop);
5419 if (CONSP (prop))
5420 /* Skip over `margin LOCATION'. */
5421 if (EQ (XCAR (prop), Qmargin))
5423 prop = XCDR (prop);
5424 if (!CONSP (prop))
5425 return 0;
5427 prop = XCDR (prop);
5428 if (!CONSP (prop))
5429 return 0;
5432 return EQ (prop, string) || (CONSP (prop) && EQ (XCAR (prop), string));
5436 /* Return 1 if STRING appears in the `display' property PROP. */
5438 static int
5439 display_prop_string_p (Lisp_Object prop, Lisp_Object string)
5441 if (CONSP (prop)
5442 && !EQ (XCAR (prop), Qwhen)
5443 && !(CONSP (XCAR (prop)) && EQ (Qmargin, XCAR (XCAR (prop)))))
5445 /* A list of sub-properties. */
5446 while (CONSP (prop))
5448 if (single_display_spec_string_p (XCAR (prop), string))
5449 return 1;
5450 prop = XCDR (prop);
5453 else if (VECTORP (prop))
5455 /* A vector of sub-properties. */
5456 ptrdiff_t i;
5457 for (i = 0; i < ASIZE (prop); ++i)
5458 if (single_display_spec_string_p (AREF (prop, i), string))
5459 return 1;
5461 else
5462 return single_display_spec_string_p (prop, string);
5464 return 0;
5467 /* Look for STRING in overlays and text properties in the current
5468 buffer, between character positions FROM and TO (excluding TO).
5469 BACK_P non-zero means look back (in this case, TO is supposed to be
5470 less than FROM).
5471 Value is the first character position where STRING was found, or
5472 zero if it wasn't found before hitting TO.
5474 This function may only use code that doesn't eval because it is
5475 called asynchronously from note_mouse_highlight. */
5477 static ptrdiff_t
5478 string_buffer_position_lim (Lisp_Object string,
5479 ptrdiff_t from, ptrdiff_t to, int back_p)
5481 Lisp_Object limit, prop, pos;
5482 int found = 0;
5484 pos = make_number (max (from, BEGV));
5486 if (!back_p) /* looking forward */
5488 limit = make_number (min (to, ZV));
5489 while (!found && !EQ (pos, limit))
5491 prop = Fget_char_property (pos, Qdisplay, Qnil);
5492 if (!NILP (prop) && display_prop_string_p (prop, string))
5493 found = 1;
5494 else
5495 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil,
5496 limit);
5499 else /* looking back */
5501 limit = make_number (max (to, BEGV));
5502 while (!found && !EQ (pos, limit))
5504 prop = Fget_char_property (pos, Qdisplay, Qnil);
5505 if (!NILP (prop) && display_prop_string_p (prop, string))
5506 found = 1;
5507 else
5508 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
5509 limit);
5513 return found ? XINT (pos) : 0;
5516 /* Determine which buffer position in current buffer STRING comes from.
5517 AROUND_CHARPOS is an approximate position where it could come from.
5518 Value is the buffer position or 0 if it couldn't be determined.
5520 This function is necessary because we don't record buffer positions
5521 in glyphs generated from strings (to keep struct glyph small).
5522 This function may only use code that doesn't eval because it is
5523 called asynchronously from note_mouse_highlight. */
5525 static ptrdiff_t
5526 string_buffer_position (Lisp_Object string, ptrdiff_t around_charpos)
5528 const int MAX_DISTANCE = 1000;
5529 ptrdiff_t found = string_buffer_position_lim (string, around_charpos,
5530 around_charpos + MAX_DISTANCE,
5533 if (!found)
5534 found = string_buffer_position_lim (string, around_charpos,
5535 around_charpos - MAX_DISTANCE, 1);
5536 return found;
5541 /***********************************************************************
5542 `composition' property
5543 ***********************************************************************/
5545 /* Set up iterator IT from `composition' property at its current
5546 position. Called from handle_stop. */
5548 static enum prop_handled
5549 handle_composition_prop (struct it *it)
5551 Lisp_Object prop, string;
5552 ptrdiff_t pos, pos_byte, start, end;
5554 if (STRINGP (it->string))
5556 unsigned char *s;
5558 pos = IT_STRING_CHARPOS (*it);
5559 pos_byte = IT_STRING_BYTEPOS (*it);
5560 string = it->string;
5561 s = SDATA (string) + pos_byte;
5562 it->c = STRING_CHAR (s);
5564 else
5566 pos = IT_CHARPOS (*it);
5567 pos_byte = IT_BYTEPOS (*it);
5568 string = Qnil;
5569 it->c = FETCH_CHAR (pos_byte);
5572 /* If there's a valid composition and point is not inside of the
5573 composition (in the case that the composition is from the current
5574 buffer), draw a glyph composed from the composition components. */
5575 if (find_composition (pos, -1, &start, &end, &prop, string)
5576 && composition_valid_p (start, end, prop)
5577 && (STRINGP (it->string) || (PT <= start || PT >= end)))
5579 if (start < pos)
5580 /* As we can't handle this situation (perhaps font-lock added
5581 a new composition), we just return here hoping that next
5582 redisplay will detect this composition much earlier. */
5583 return HANDLED_NORMALLY;
5584 if (start != pos)
5586 if (STRINGP (it->string))
5587 pos_byte = string_char_to_byte (it->string, start);
5588 else
5589 pos_byte = CHAR_TO_BYTE (start);
5591 it->cmp_it.id = get_composition_id (start, pos_byte, end - start,
5592 prop, string);
5594 if (it->cmp_it.id >= 0)
5596 it->cmp_it.ch = -1;
5597 it->cmp_it.nchars = COMPOSITION_LENGTH (prop);
5598 it->cmp_it.nglyphs = -1;
5602 return HANDLED_NORMALLY;
5607 /***********************************************************************
5608 Overlay strings
5609 ***********************************************************************/
5611 /* The following structure is used to record overlay strings for
5612 later sorting in load_overlay_strings. */
5614 struct overlay_entry
5616 Lisp_Object overlay;
5617 Lisp_Object string;
5618 EMACS_INT priority;
5619 int after_string_p;
5623 /* Set up iterator IT from overlay strings at its current position.
5624 Called from handle_stop. */
5626 static enum prop_handled
5627 handle_overlay_change (struct it *it)
5629 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
5630 return HANDLED_RECOMPUTE_PROPS;
5631 else
5632 return HANDLED_NORMALLY;
5636 /* Set up the next overlay string for delivery by IT, if there is an
5637 overlay string to deliver. Called by set_iterator_to_next when the
5638 end of the current overlay string is reached. If there are more
5639 overlay strings to display, IT->string and
5640 IT->current.overlay_string_index are set appropriately here.
5641 Otherwise IT->string is set to nil. */
5643 static void
5644 next_overlay_string (struct it *it)
5646 ++it->current.overlay_string_index;
5647 if (it->current.overlay_string_index == it->n_overlay_strings)
5649 /* No more overlay strings. Restore IT's settings to what
5650 they were before overlay strings were processed, and
5651 continue to deliver from current_buffer. */
5653 it->ellipsis_p = (it->stack[it->sp - 1].display_ellipsis_p != 0);
5654 pop_it (it);
5655 eassert (it->sp > 0
5656 || (NILP (it->string)
5657 && it->method == GET_FROM_BUFFER
5658 && it->stop_charpos >= BEGV
5659 && it->stop_charpos <= it->end_charpos));
5660 it->current.overlay_string_index = -1;
5661 it->n_overlay_strings = 0;
5662 it->overlay_strings_charpos = -1;
5663 /* If there's an empty display string on the stack, pop the
5664 stack, to resync the bidi iterator with IT's position. Such
5665 empty strings are pushed onto the stack in
5666 get_overlay_strings_1. */
5667 if (it->sp > 0 && STRINGP (it->string) && !SCHARS (it->string))
5668 pop_it (it);
5670 /* If we're at the end of the buffer, record that we have
5671 processed the overlay strings there already, so that
5672 next_element_from_buffer doesn't try it again. */
5673 if (NILP (it->string) && IT_CHARPOS (*it) >= it->end_charpos)
5674 it->overlay_strings_at_end_processed_p = true;
5676 else
5678 /* There are more overlay strings to process. If
5679 IT->current.overlay_string_index has advanced to a position
5680 where we must load IT->overlay_strings with more strings, do
5681 it. We must load at the IT->overlay_strings_charpos where
5682 IT->n_overlay_strings was originally computed; when invisible
5683 text is present, this might not be IT_CHARPOS (Bug#7016). */
5684 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
5686 if (it->current.overlay_string_index && i == 0)
5687 load_overlay_strings (it, it->overlay_strings_charpos);
5689 /* Initialize IT to deliver display elements from the overlay
5690 string. */
5691 it->string = it->overlay_strings[i];
5692 it->multibyte_p = STRING_MULTIBYTE (it->string);
5693 SET_TEXT_POS (it->current.string_pos, 0, 0);
5694 it->method = GET_FROM_STRING;
5695 it->stop_charpos = 0;
5696 it->end_charpos = SCHARS (it->string);
5697 if (it->cmp_it.stop_pos >= 0)
5698 it->cmp_it.stop_pos = 0;
5699 it->prev_stop = 0;
5700 it->base_level_stop = 0;
5702 /* Set up the bidi iterator for this overlay string. */
5703 if (it->bidi_p)
5705 it->bidi_it.string.lstring = it->string;
5706 it->bidi_it.string.s = NULL;
5707 it->bidi_it.string.schars = SCHARS (it->string);
5708 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
5709 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5710 it->bidi_it.string.unibyte = !it->multibyte_p;
5711 it->bidi_it.w = it->w;
5712 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5716 CHECK_IT (it);
5720 /* Compare two overlay_entry structures E1 and E2. Used as a
5721 comparison function for qsort in load_overlay_strings. Overlay
5722 strings for the same position are sorted so that
5724 1. All after-strings come in front of before-strings, except
5725 when they come from the same overlay.
5727 2. Within after-strings, strings are sorted so that overlay strings
5728 from overlays with higher priorities come first.
5730 2. Within before-strings, strings are sorted so that overlay
5731 strings from overlays with higher priorities come last.
5733 Value is analogous to strcmp. */
5736 static int
5737 compare_overlay_entries (const void *e1, const void *e2)
5739 struct overlay_entry const *entry1 = e1;
5740 struct overlay_entry const *entry2 = e2;
5741 int result;
5743 if (entry1->after_string_p != entry2->after_string_p)
5745 /* Let after-strings appear in front of before-strings if
5746 they come from different overlays. */
5747 if (EQ (entry1->overlay, entry2->overlay))
5748 result = entry1->after_string_p ? 1 : -1;
5749 else
5750 result = entry1->after_string_p ? -1 : 1;
5752 else if (entry1->priority != entry2->priority)
5754 if (entry1->after_string_p)
5755 /* After-strings sorted in order of decreasing priority. */
5756 result = entry2->priority < entry1->priority ? -1 : 1;
5757 else
5758 /* Before-strings sorted in order of increasing priority. */
5759 result = entry1->priority < entry2->priority ? -1 : 1;
5761 else
5762 result = 0;
5764 return result;
5768 /* Load the vector IT->overlay_strings with overlay strings from IT's
5769 current buffer position, or from CHARPOS if that is > 0. Set
5770 IT->n_overlays to the total number of overlay strings found.
5772 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
5773 a time. On entry into load_overlay_strings,
5774 IT->current.overlay_string_index gives the number of overlay
5775 strings that have already been loaded by previous calls to this
5776 function.
5778 IT->add_overlay_start contains an additional overlay start
5779 position to consider for taking overlay strings from, if non-zero.
5780 This position comes into play when the overlay has an `invisible'
5781 property, and both before and after-strings. When we've skipped to
5782 the end of the overlay, because of its `invisible' property, we
5783 nevertheless want its before-string to appear.
5784 IT->add_overlay_start will contain the overlay start position
5785 in this case.
5787 Overlay strings are sorted so that after-string strings come in
5788 front of before-string strings. Within before and after-strings,
5789 strings are sorted by overlay priority. See also function
5790 compare_overlay_entries. */
5792 static void
5793 load_overlay_strings (struct it *it, ptrdiff_t charpos)
5795 Lisp_Object overlay, window, str, invisible;
5796 struct Lisp_Overlay *ov;
5797 ptrdiff_t start, end;
5798 ptrdiff_t n = 0, i, j;
5799 int invis_p;
5800 struct overlay_entry entriesbuf[20];
5801 ptrdiff_t size = ARRAYELTS (entriesbuf);
5802 struct overlay_entry *entries = entriesbuf;
5803 USE_SAFE_ALLOCA;
5805 if (charpos <= 0)
5806 charpos = IT_CHARPOS (*it);
5808 /* Append the overlay string STRING of overlay OVERLAY to vector
5809 `entries' which has size `size' and currently contains `n'
5810 elements. AFTER_P non-zero means STRING is an after-string of
5811 OVERLAY. */
5812 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
5813 do \
5815 Lisp_Object priority; \
5817 if (n == size) \
5819 struct overlay_entry *old = entries; \
5820 SAFE_NALLOCA (entries, 2, size); \
5821 memcpy (entries, old, size * sizeof *entries); \
5822 size *= 2; \
5825 entries[n].string = (STRING); \
5826 entries[n].overlay = (OVERLAY); \
5827 priority = Foverlay_get ((OVERLAY), Qpriority); \
5828 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
5829 entries[n].after_string_p = (AFTER_P); \
5830 ++n; \
5832 while (0)
5834 /* Process overlay before the overlay center. */
5835 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
5837 XSETMISC (overlay, ov);
5838 eassert (OVERLAYP (overlay));
5839 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5840 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5842 if (end < charpos)
5843 break;
5845 /* Skip this overlay if it doesn't start or end at IT's current
5846 position. */
5847 if (end != charpos && start != charpos)
5848 continue;
5850 /* Skip this overlay if it doesn't apply to IT->w. */
5851 window = Foverlay_get (overlay, Qwindow);
5852 if (WINDOWP (window) && XWINDOW (window) != it->w)
5853 continue;
5855 /* If the text ``under'' the overlay is invisible, both before-
5856 and after-strings from this overlay are visible; start and
5857 end position are indistinguishable. */
5858 invisible = Foverlay_get (overlay, Qinvisible);
5859 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5861 /* If overlay has a non-empty before-string, record it. */
5862 if ((start == charpos || (end == charpos && invis_p))
5863 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5864 && SCHARS (str))
5865 RECORD_OVERLAY_STRING (overlay, str, 0);
5867 /* If overlay has a non-empty after-string, record it. */
5868 if ((end == charpos || (start == charpos && invis_p))
5869 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5870 && SCHARS (str))
5871 RECORD_OVERLAY_STRING (overlay, str, 1);
5874 /* Process overlays after the overlay center. */
5875 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
5877 XSETMISC (overlay, ov);
5878 eassert (OVERLAYP (overlay));
5879 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5880 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5882 if (start > charpos)
5883 break;
5885 /* Skip this overlay if it doesn't start or end at IT's current
5886 position. */
5887 if (end != charpos && start != charpos)
5888 continue;
5890 /* Skip this overlay if it doesn't apply to IT->w. */
5891 window = Foverlay_get (overlay, Qwindow);
5892 if (WINDOWP (window) && XWINDOW (window) != it->w)
5893 continue;
5895 /* If the text ``under'' the overlay is invisible, it has a zero
5896 dimension, and both before- and after-strings apply. */
5897 invisible = Foverlay_get (overlay, Qinvisible);
5898 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5900 /* If overlay has a non-empty before-string, record it. */
5901 if ((start == charpos || (end == charpos && invis_p))
5902 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5903 && SCHARS (str))
5904 RECORD_OVERLAY_STRING (overlay, str, 0);
5906 /* If overlay has a non-empty after-string, record it. */
5907 if ((end == charpos || (start == charpos && invis_p))
5908 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5909 && SCHARS (str))
5910 RECORD_OVERLAY_STRING (overlay, str, 1);
5913 #undef RECORD_OVERLAY_STRING
5915 /* Sort entries. */
5916 if (n > 1)
5917 qsort (entries, n, sizeof *entries, compare_overlay_entries);
5919 /* Record number of overlay strings, and where we computed it. */
5920 it->n_overlay_strings = n;
5921 it->overlay_strings_charpos = charpos;
5923 /* IT->current.overlay_string_index is the number of overlay strings
5924 that have already been consumed by IT. Copy some of the
5925 remaining overlay strings to IT->overlay_strings. */
5926 i = 0;
5927 j = it->current.overlay_string_index;
5928 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
5930 it->overlay_strings[i] = entries[j].string;
5931 it->string_overlays[i++] = entries[j++].overlay;
5934 CHECK_IT (it);
5935 SAFE_FREE ();
5939 /* Get the first chunk of overlay strings at IT's current buffer
5940 position, or at CHARPOS if that is > 0. Value is non-zero if at
5941 least one overlay string was found. */
5943 static int
5944 get_overlay_strings_1 (struct it *it, ptrdiff_t charpos, int compute_stop_p)
5946 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
5947 process. This fills IT->overlay_strings with strings, and sets
5948 IT->n_overlay_strings to the total number of strings to process.
5949 IT->pos.overlay_string_index has to be set temporarily to zero
5950 because load_overlay_strings needs this; it must be set to -1
5951 when no overlay strings are found because a zero value would
5952 indicate a position in the first overlay string. */
5953 it->current.overlay_string_index = 0;
5954 load_overlay_strings (it, charpos);
5956 /* If we found overlay strings, set up IT to deliver display
5957 elements from the first one. Otherwise set up IT to deliver
5958 from current_buffer. */
5959 if (it->n_overlay_strings)
5961 /* Make sure we know settings in current_buffer, so that we can
5962 restore meaningful values when we're done with the overlay
5963 strings. */
5964 if (compute_stop_p)
5965 compute_stop_pos (it);
5966 eassert (it->face_id >= 0);
5968 /* Save IT's settings. They are restored after all overlay
5969 strings have been processed. */
5970 eassert (!compute_stop_p || it->sp == 0);
5972 /* When called from handle_stop, there might be an empty display
5973 string loaded. In that case, don't bother saving it. But
5974 don't use this optimization with the bidi iterator, since we
5975 need the corresponding pop_it call to resync the bidi
5976 iterator's position with IT's position, after we are done
5977 with the overlay strings. (The corresponding call to pop_it
5978 in case of an empty display string is in
5979 next_overlay_string.) */
5980 if (!(!it->bidi_p
5981 && STRINGP (it->string) && !SCHARS (it->string)))
5982 push_it (it, NULL);
5984 /* Set up IT to deliver display elements from the first overlay
5985 string. */
5986 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5987 it->string = it->overlay_strings[0];
5988 it->from_overlay = Qnil;
5989 it->stop_charpos = 0;
5990 eassert (STRINGP (it->string));
5991 it->end_charpos = SCHARS (it->string);
5992 it->prev_stop = 0;
5993 it->base_level_stop = 0;
5994 it->multibyte_p = STRING_MULTIBYTE (it->string);
5995 it->method = GET_FROM_STRING;
5996 it->from_disp_prop_p = 0;
5998 /* Force paragraph direction to be that of the parent
5999 buffer. */
6000 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
6001 it->paragraph_embedding = it->bidi_it.paragraph_dir;
6002 else
6003 it->paragraph_embedding = L2R;
6005 /* Set up the bidi iterator for this overlay string. */
6006 if (it->bidi_p)
6008 ptrdiff_t pos = (charpos > 0 ? charpos : IT_CHARPOS (*it));
6010 it->bidi_it.string.lstring = it->string;
6011 it->bidi_it.string.s = NULL;
6012 it->bidi_it.string.schars = SCHARS (it->string);
6013 it->bidi_it.string.bufpos = pos;
6014 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
6015 it->bidi_it.string.unibyte = !it->multibyte_p;
6016 it->bidi_it.w = it->w;
6017 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
6019 return 1;
6022 it->current.overlay_string_index = -1;
6023 return 0;
6026 static int
6027 get_overlay_strings (struct it *it, ptrdiff_t charpos)
6029 it->string = Qnil;
6030 it->method = GET_FROM_BUFFER;
6032 (void) get_overlay_strings_1 (it, charpos, 1);
6034 CHECK_IT (it);
6036 /* Value is non-zero if we found at least one overlay string. */
6037 return STRINGP (it->string);
6042 /***********************************************************************
6043 Saving and restoring state
6044 ***********************************************************************/
6046 /* Save current settings of IT on IT->stack. Called, for example,
6047 before setting up IT for an overlay string, to be able to restore
6048 IT's settings to what they were after the overlay string has been
6049 processed. If POSITION is non-NULL, it is the position to save on
6050 the stack instead of IT->position. */
6052 static void
6053 push_it (struct it *it, struct text_pos *position)
6055 struct iterator_stack_entry *p;
6057 eassert (it->sp < IT_STACK_SIZE);
6058 p = it->stack + it->sp;
6060 p->stop_charpos = it->stop_charpos;
6061 p->prev_stop = it->prev_stop;
6062 p->base_level_stop = it->base_level_stop;
6063 p->cmp_it = it->cmp_it;
6064 eassert (it->face_id >= 0);
6065 p->face_id = it->face_id;
6066 p->string = it->string;
6067 p->method = it->method;
6068 p->from_overlay = it->from_overlay;
6069 switch (p->method)
6071 case GET_FROM_IMAGE:
6072 p->u.image.object = it->object;
6073 p->u.image.image_id = it->image_id;
6074 p->u.image.slice = it->slice;
6075 break;
6076 case GET_FROM_STRETCH:
6077 p->u.stretch.object = it->object;
6078 break;
6079 #ifdef HAVE_XWIDGETS
6080 case GET_FROM_XWIDGET:
6081 p->u.xwidget.object = it->object;
6082 break;
6083 #endif
6085 p->position = position ? *position : it->position;
6086 p->current = it->current;
6087 p->end_charpos = it->end_charpos;
6088 p->string_nchars = it->string_nchars;
6089 p->area = it->area;
6090 p->multibyte_p = it->multibyte_p;
6091 p->avoid_cursor_p = it->avoid_cursor_p;
6092 p->space_width = it->space_width;
6093 p->font_height = it->font_height;
6094 p->voffset = it->voffset;
6095 p->string_from_display_prop_p = it->string_from_display_prop_p;
6096 p->string_from_prefix_prop_p = it->string_from_prefix_prop_p;
6097 p->display_ellipsis_p = 0;
6098 p->line_wrap = it->line_wrap;
6099 p->bidi_p = it->bidi_p;
6100 p->paragraph_embedding = it->paragraph_embedding;
6101 p->from_disp_prop_p = it->from_disp_prop_p;
6102 ++it->sp;
6104 /* Save the state of the bidi iterator as well. */
6105 if (it->bidi_p)
6106 bidi_push_it (&it->bidi_it);
6109 static void
6110 iterate_out_of_display_property (struct it *it)
6112 int buffer_p = !STRINGP (it->string);
6113 ptrdiff_t eob = (buffer_p ? ZV : it->end_charpos);
6114 ptrdiff_t bob = (buffer_p ? BEGV : 0);
6116 eassert (eob >= CHARPOS (it->position) && CHARPOS (it->position) >= bob);
6118 /* Maybe initialize paragraph direction. If we are at the beginning
6119 of a new paragraph, next_element_from_buffer may not have a
6120 chance to do that. */
6121 if (it->bidi_it.first_elt && it->bidi_it.charpos < eob)
6122 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
6123 /* prev_stop can be zero, so check against BEGV as well. */
6124 while (it->bidi_it.charpos >= bob
6125 && it->prev_stop <= it->bidi_it.charpos
6126 && it->bidi_it.charpos < CHARPOS (it->position)
6127 && it->bidi_it.charpos < eob)
6128 bidi_move_to_visually_next (&it->bidi_it);
6129 /* Record the stop_pos we just crossed, for when we cross it
6130 back, maybe. */
6131 if (it->bidi_it.charpos > CHARPOS (it->position))
6132 it->prev_stop = CHARPOS (it->position);
6133 /* If we ended up not where pop_it put us, resync IT's
6134 positional members with the bidi iterator. */
6135 if (it->bidi_it.charpos != CHARPOS (it->position))
6136 SET_TEXT_POS (it->position, it->bidi_it.charpos, it->bidi_it.bytepos);
6137 if (buffer_p)
6138 it->current.pos = it->position;
6139 else
6140 it->current.string_pos = it->position;
6143 /* Restore IT's settings from IT->stack. Called, for example, when no
6144 more overlay strings must be processed, and we return to delivering
6145 display elements from a buffer, or when the end of a string from a
6146 `display' property is reached and we return to delivering display
6147 elements from an overlay string, or from a buffer. */
6149 static void
6150 pop_it (struct it *it)
6152 struct iterator_stack_entry *p;
6153 int from_display_prop = it->from_disp_prop_p;
6155 eassert (it->sp > 0);
6156 --it->sp;
6157 p = it->stack + it->sp;
6158 it->stop_charpos = p->stop_charpos;
6159 it->prev_stop = p->prev_stop;
6160 it->base_level_stop = p->base_level_stop;
6161 it->cmp_it = p->cmp_it;
6162 it->face_id = p->face_id;
6163 it->current = p->current;
6164 it->position = p->position;
6165 it->string = p->string;
6166 it->from_overlay = p->from_overlay;
6167 if (NILP (it->string))
6168 SET_TEXT_POS (it->current.string_pos, -1, -1);
6169 it->method = p->method;
6170 switch (it->method)
6172 case GET_FROM_IMAGE:
6173 it->image_id = p->u.image.image_id;
6174 it->object = p->u.image.object;
6175 it->slice = p->u.image.slice;
6176 break;
6177 #ifdef HAVE_XWIDGETS
6178 case GET_FROM_XWIDGET:
6179 it->object = p->u.xwidget.object;
6180 break;
6181 #endif
6182 case GET_FROM_STRETCH:
6183 it->object = p->u.stretch.object;
6184 break;
6185 case GET_FROM_BUFFER:
6186 it->object = it->w->contents;
6187 break;
6188 case GET_FROM_STRING:
6190 struct face *face = FACE_FROM_ID (it->f, it->face_id);
6192 /* Restore the face_box_p flag, since it could have been
6193 overwritten by the face of the object that we just finished
6194 displaying. */
6195 if (face)
6196 it->face_box_p = face->box != FACE_NO_BOX;
6197 it->object = it->string;
6199 break;
6200 case GET_FROM_DISPLAY_VECTOR:
6201 if (it->s)
6202 it->method = GET_FROM_C_STRING;
6203 else if (STRINGP (it->string))
6204 it->method = GET_FROM_STRING;
6205 else
6207 it->method = GET_FROM_BUFFER;
6208 it->object = it->w->contents;
6211 it->end_charpos = p->end_charpos;
6212 it->string_nchars = p->string_nchars;
6213 it->area = p->area;
6214 it->multibyte_p = p->multibyte_p;
6215 it->avoid_cursor_p = p->avoid_cursor_p;
6216 it->space_width = p->space_width;
6217 it->font_height = p->font_height;
6218 it->voffset = p->voffset;
6219 it->string_from_display_prop_p = p->string_from_display_prop_p;
6220 it->string_from_prefix_prop_p = p->string_from_prefix_prop_p;
6221 it->line_wrap = p->line_wrap;
6222 it->bidi_p = p->bidi_p;
6223 it->paragraph_embedding = p->paragraph_embedding;
6224 it->from_disp_prop_p = p->from_disp_prop_p;
6225 if (it->bidi_p)
6227 bidi_pop_it (&it->bidi_it);
6228 /* Bidi-iterate until we get out of the portion of text, if any,
6229 covered by a `display' text property or by an overlay with
6230 `display' property. (We cannot just jump there, because the
6231 internal coherency of the bidi iterator state can not be
6232 preserved across such jumps.) We also must determine the
6233 paragraph base direction if the overlay we just processed is
6234 at the beginning of a new paragraph. */
6235 if (from_display_prop
6236 && (it->method == GET_FROM_BUFFER || it->method == GET_FROM_STRING))
6237 iterate_out_of_display_property (it);
6239 eassert ((BUFFERP (it->object)
6240 && IT_CHARPOS (*it) == it->bidi_it.charpos
6241 && IT_BYTEPOS (*it) == it->bidi_it.bytepos)
6242 || (STRINGP (it->object)
6243 && IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
6244 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos)
6245 || (CONSP (it->object) && it->method == GET_FROM_STRETCH));
6251 /***********************************************************************
6252 Moving over lines
6253 ***********************************************************************/
6255 /* Set IT's current position to the previous line start. */
6257 static void
6258 back_to_previous_line_start (struct it *it)
6260 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
6262 DEC_BOTH (cp, bp);
6263 IT_CHARPOS (*it) = find_newline_no_quit (cp, bp, -1, &IT_BYTEPOS (*it));
6267 /* Move IT to the next line start.
6269 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
6270 we skipped over part of the text (as opposed to moving the iterator
6271 continuously over the text). Otherwise, don't change the value
6272 of *SKIPPED_P.
6274 If BIDI_IT_PREV is non-NULL, store into it the state of the bidi
6275 iterator on the newline, if it was found.
6277 Newlines may come from buffer text, overlay strings, or strings
6278 displayed via the `display' property. That's the reason we can't
6279 simply use find_newline_no_quit.
6281 Note that this function may not skip over invisible text that is so
6282 because of text properties and immediately follows a newline. If
6283 it would, function reseat_at_next_visible_line_start, when called
6284 from set_iterator_to_next, would effectively make invisible
6285 characters following a newline part of the wrong glyph row, which
6286 leads to wrong cursor motion. */
6288 static int
6289 forward_to_next_line_start (struct it *it, int *skipped_p,
6290 struct bidi_it *bidi_it_prev)
6292 ptrdiff_t old_selective;
6293 int newline_found_p, n;
6294 const int MAX_NEWLINE_DISTANCE = 500;
6296 /* If already on a newline, just consume it to avoid unintended
6297 skipping over invisible text below. */
6298 if (it->what == IT_CHARACTER
6299 && it->c == '\n'
6300 && CHARPOS (it->position) == IT_CHARPOS (*it))
6302 if (it->bidi_p && bidi_it_prev)
6303 *bidi_it_prev = it->bidi_it;
6304 set_iterator_to_next (it, 0);
6305 it->c = 0;
6306 return 1;
6309 /* Don't handle selective display in the following. It's (a)
6310 unnecessary because it's done by the caller, and (b) leads to an
6311 infinite recursion because next_element_from_ellipsis indirectly
6312 calls this function. */
6313 old_selective = it->selective;
6314 it->selective = 0;
6316 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
6317 from buffer text. */
6318 for (n = newline_found_p = 0;
6319 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
6320 n += STRINGP (it->string) ? 0 : 1)
6322 if (!get_next_display_element (it))
6323 return 0;
6324 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
6325 if (newline_found_p && it->bidi_p && bidi_it_prev)
6326 *bidi_it_prev = it->bidi_it;
6327 set_iterator_to_next (it, 0);
6330 /* If we didn't find a newline near enough, see if we can use a
6331 short-cut. */
6332 if (!newline_found_p)
6334 ptrdiff_t bytepos, start = IT_CHARPOS (*it);
6335 ptrdiff_t limit = find_newline_no_quit (start, IT_BYTEPOS (*it),
6336 1, &bytepos);
6337 Lisp_Object pos;
6339 eassert (!STRINGP (it->string));
6341 /* If there isn't any `display' property in sight, and no
6342 overlays, we can just use the position of the newline in
6343 buffer text. */
6344 if (it->stop_charpos >= limit
6345 || ((pos = Fnext_single_property_change (make_number (start),
6346 Qdisplay, Qnil,
6347 make_number (limit)),
6348 NILP (pos))
6349 && next_overlay_change (start) == ZV))
6351 if (!it->bidi_p)
6353 IT_CHARPOS (*it) = limit;
6354 IT_BYTEPOS (*it) = bytepos;
6356 else
6358 struct bidi_it bprev;
6360 /* Help bidi.c avoid expensive searches for display
6361 properties and overlays, by telling it that there are
6362 none up to `limit'. */
6363 if (it->bidi_it.disp_pos < limit)
6365 it->bidi_it.disp_pos = limit;
6366 it->bidi_it.disp_prop = 0;
6368 do {
6369 bprev = it->bidi_it;
6370 bidi_move_to_visually_next (&it->bidi_it);
6371 } while (it->bidi_it.charpos != limit);
6372 IT_CHARPOS (*it) = limit;
6373 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6374 if (bidi_it_prev)
6375 *bidi_it_prev = bprev;
6377 *skipped_p = newline_found_p = true;
6379 else
6381 while (get_next_display_element (it)
6382 && !newline_found_p)
6384 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
6385 if (newline_found_p && it->bidi_p && bidi_it_prev)
6386 *bidi_it_prev = it->bidi_it;
6387 set_iterator_to_next (it, 0);
6392 it->selective = old_selective;
6393 return newline_found_p;
6397 /* Set IT's current position to the previous visible line start. Skip
6398 invisible text that is so either due to text properties or due to
6399 selective display. Caution: this does not change IT->current_x and
6400 IT->hpos. */
6402 static void
6403 back_to_previous_visible_line_start (struct it *it)
6405 while (IT_CHARPOS (*it) > BEGV)
6407 back_to_previous_line_start (it);
6409 if (IT_CHARPOS (*it) <= BEGV)
6410 break;
6412 /* If selective > 0, then lines indented more than its value are
6413 invisible. */
6414 if (it->selective > 0
6415 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6416 it->selective))
6417 continue;
6419 /* Check the newline before point for invisibility. */
6421 Lisp_Object prop;
6422 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
6423 Qinvisible, it->window);
6424 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6425 continue;
6428 if (IT_CHARPOS (*it) <= BEGV)
6429 break;
6432 struct it it2;
6433 void *it2data = NULL;
6434 ptrdiff_t pos;
6435 ptrdiff_t beg, end;
6436 Lisp_Object val, overlay;
6438 SAVE_IT (it2, *it, it2data);
6440 /* If newline is part of a composition, continue from start of composition */
6441 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
6442 && beg < IT_CHARPOS (*it))
6443 goto replaced;
6445 /* If newline is replaced by a display property, find start of overlay
6446 or interval and continue search from that point. */
6447 pos = --IT_CHARPOS (it2);
6448 --IT_BYTEPOS (it2);
6449 it2.sp = 0;
6450 bidi_unshelve_cache (NULL, 0);
6451 it2.string_from_display_prop_p = 0;
6452 it2.from_disp_prop_p = 0;
6453 if (handle_display_prop (&it2) == HANDLED_RETURN
6454 && !NILP (val = get_char_property_and_overlay
6455 (make_number (pos), Qdisplay, Qnil, &overlay))
6456 && (OVERLAYP (overlay)
6457 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
6458 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
6460 RESTORE_IT (it, it, it2data);
6461 goto replaced;
6464 /* Newline is not replaced by anything -- so we are done. */
6465 RESTORE_IT (it, it, it2data);
6466 break;
6468 replaced:
6469 if (beg < BEGV)
6470 beg = BEGV;
6471 IT_CHARPOS (*it) = beg;
6472 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
6476 it->continuation_lines_width = 0;
6478 eassert (IT_CHARPOS (*it) >= BEGV);
6479 eassert (IT_CHARPOS (*it) == BEGV
6480 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6481 CHECK_IT (it);
6485 /* Reseat iterator IT at the previous visible line start. Skip
6486 invisible text that is so either due to text properties or due to
6487 selective display. At the end, update IT's overlay information,
6488 face information etc. */
6490 void
6491 reseat_at_previous_visible_line_start (struct it *it)
6493 back_to_previous_visible_line_start (it);
6494 reseat (it, it->current.pos, 1);
6495 CHECK_IT (it);
6499 /* Reseat iterator IT on the next visible line start in the current
6500 buffer. ON_NEWLINE_P non-zero means position IT on the newline
6501 preceding the line start. Skip over invisible text that is so
6502 because of selective display. Compute faces, overlays etc at the
6503 new position. Note that this function does not skip over text that
6504 is invisible because of text properties. */
6506 static void
6507 reseat_at_next_visible_line_start (struct it *it, int on_newline_p)
6509 int newline_found_p, skipped_p = 0;
6510 struct bidi_it bidi_it_prev;
6512 newline_found_p = forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6514 /* Skip over lines that are invisible because they are indented
6515 more than the value of IT->selective. */
6516 if (it->selective > 0)
6517 while (IT_CHARPOS (*it) < ZV
6518 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6519 it->selective))
6521 eassert (IT_BYTEPOS (*it) == BEGV
6522 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6523 newline_found_p =
6524 forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6527 /* Position on the newline if that's what's requested. */
6528 if (on_newline_p && newline_found_p)
6530 if (STRINGP (it->string))
6532 if (IT_STRING_CHARPOS (*it) > 0)
6534 if (!it->bidi_p)
6536 --IT_STRING_CHARPOS (*it);
6537 --IT_STRING_BYTEPOS (*it);
6539 else
6541 /* We need to restore the bidi iterator to the state
6542 it had on the newline, and resync the IT's
6543 position with that. */
6544 it->bidi_it = bidi_it_prev;
6545 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
6546 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
6550 else if (IT_CHARPOS (*it) > BEGV)
6552 if (!it->bidi_p)
6554 --IT_CHARPOS (*it);
6555 --IT_BYTEPOS (*it);
6557 else
6559 /* We need to restore the bidi iterator to the state it
6560 had on the newline and resync IT with that. */
6561 it->bidi_it = bidi_it_prev;
6562 IT_CHARPOS (*it) = it->bidi_it.charpos;
6563 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6565 reseat (it, it->current.pos, 0);
6568 else if (skipped_p)
6569 reseat (it, it->current.pos, 0);
6571 CHECK_IT (it);
6576 /***********************************************************************
6577 Changing an iterator's position
6578 ***********************************************************************/
6580 /* Change IT's current position to POS in current_buffer. If FORCE_P
6581 is non-zero, always check for text properties at the new position.
6582 Otherwise, text properties are only looked up if POS >=
6583 IT->check_charpos of a property. */
6585 static void
6586 reseat (struct it *it, struct text_pos pos, int force_p)
6588 ptrdiff_t original_pos = IT_CHARPOS (*it);
6590 reseat_1 (it, pos, 0);
6592 /* Determine where to check text properties. Avoid doing it
6593 where possible because text property lookup is very expensive. */
6594 if (force_p
6595 || CHARPOS (pos) > it->stop_charpos
6596 || CHARPOS (pos) < original_pos)
6598 if (it->bidi_p)
6600 /* For bidi iteration, we need to prime prev_stop and
6601 base_level_stop with our best estimations. */
6602 /* Implementation note: Of course, POS is not necessarily a
6603 stop position, so assigning prev_pos to it is a lie; we
6604 should have called compute_stop_backwards. However, if
6605 the current buffer does not include any R2L characters,
6606 that call would be a waste of cycles, because the
6607 iterator will never move back, and thus never cross this
6608 "fake" stop position. So we delay that backward search
6609 until the time we really need it, in next_element_from_buffer. */
6610 if (CHARPOS (pos) != it->prev_stop)
6611 it->prev_stop = CHARPOS (pos);
6612 if (CHARPOS (pos) < it->base_level_stop)
6613 it->base_level_stop = 0; /* meaning it's unknown */
6614 handle_stop (it);
6616 else
6618 handle_stop (it);
6619 it->prev_stop = it->base_level_stop = 0;
6624 CHECK_IT (it);
6628 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
6629 IT->stop_pos to POS, also. */
6631 static void
6632 reseat_1 (struct it *it, struct text_pos pos, int set_stop_p)
6634 /* Don't call this function when scanning a C string. */
6635 eassert (it->s == NULL);
6637 /* POS must be a reasonable value. */
6638 eassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
6640 it->current.pos = it->position = pos;
6641 it->end_charpos = ZV;
6642 it->dpvec = NULL;
6643 it->current.dpvec_index = -1;
6644 it->current.overlay_string_index = -1;
6645 IT_STRING_CHARPOS (*it) = -1;
6646 IT_STRING_BYTEPOS (*it) = -1;
6647 it->string = Qnil;
6648 it->method = GET_FROM_BUFFER;
6649 it->object = it->w->contents;
6650 it->area = TEXT_AREA;
6651 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
6652 it->sp = 0;
6653 it->string_from_display_prop_p = 0;
6654 it->string_from_prefix_prop_p = 0;
6656 it->from_disp_prop_p = 0;
6657 it->face_before_selective_p = 0;
6658 if (it->bidi_p)
6660 bidi_init_it (IT_CHARPOS (*it), IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6661 &it->bidi_it);
6662 bidi_unshelve_cache (NULL, 0);
6663 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6664 it->bidi_it.string.s = NULL;
6665 it->bidi_it.string.lstring = Qnil;
6666 it->bidi_it.string.bufpos = 0;
6667 it->bidi_it.string.from_disp_str = 0;
6668 it->bidi_it.string.unibyte = 0;
6669 it->bidi_it.w = it->w;
6672 if (set_stop_p)
6674 it->stop_charpos = CHARPOS (pos);
6675 it->base_level_stop = CHARPOS (pos);
6677 /* This make the information stored in it->cmp_it invalidate. */
6678 it->cmp_it.id = -1;
6682 /* Set up IT for displaying a string, starting at CHARPOS in window W.
6683 If S is non-null, it is a C string to iterate over. Otherwise,
6684 STRING gives a Lisp string to iterate over.
6686 If PRECISION > 0, don't return more then PRECISION number of
6687 characters from the string.
6689 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
6690 characters have been returned. FIELD_WIDTH < 0 means an infinite
6691 field width.
6693 MULTIBYTE = 0 means disable processing of multibyte characters,
6694 MULTIBYTE > 0 means enable it,
6695 MULTIBYTE < 0 means use IT->multibyte_p.
6697 IT must be initialized via a prior call to init_iterator before
6698 calling this function. */
6700 static void
6701 reseat_to_string (struct it *it, const char *s, Lisp_Object string,
6702 ptrdiff_t charpos, ptrdiff_t precision, int field_width,
6703 int multibyte)
6705 /* No text property checks performed by default, but see below. */
6706 it->stop_charpos = -1;
6708 /* Set iterator position and end position. */
6709 memset (&it->current, 0, sizeof it->current);
6710 it->current.overlay_string_index = -1;
6711 it->current.dpvec_index = -1;
6712 eassert (charpos >= 0);
6714 /* If STRING is specified, use its multibyteness, otherwise use the
6715 setting of MULTIBYTE, if specified. */
6716 if (multibyte >= 0)
6717 it->multibyte_p = multibyte > 0;
6719 /* Bidirectional reordering of strings is controlled by the default
6720 value of bidi-display-reordering. Don't try to reorder while
6721 loading loadup.el, as the necessary character property tables are
6722 not yet available. */
6723 it->bidi_p =
6724 NILP (Vpurify_flag)
6725 && !NILP (BVAR (&buffer_defaults, bidi_display_reordering));
6727 if (s == NULL)
6729 eassert (STRINGP (string));
6730 it->string = string;
6731 it->s = NULL;
6732 it->end_charpos = it->string_nchars = SCHARS (string);
6733 it->method = GET_FROM_STRING;
6734 it->current.string_pos = string_pos (charpos, string);
6736 if (it->bidi_p)
6738 it->bidi_it.string.lstring = string;
6739 it->bidi_it.string.s = NULL;
6740 it->bidi_it.string.schars = it->end_charpos;
6741 it->bidi_it.string.bufpos = 0;
6742 it->bidi_it.string.from_disp_str = 0;
6743 it->bidi_it.string.unibyte = !it->multibyte_p;
6744 it->bidi_it.w = it->w;
6745 bidi_init_it (charpos, IT_STRING_BYTEPOS (*it),
6746 FRAME_WINDOW_P (it->f), &it->bidi_it);
6749 else
6751 it->s = (const unsigned char *) s;
6752 it->string = Qnil;
6754 /* Note that we use IT->current.pos, not it->current.string_pos,
6755 for displaying C strings. */
6756 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
6757 if (it->multibyte_p)
6759 it->current.pos = c_string_pos (charpos, s, 1);
6760 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
6762 else
6764 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
6765 it->end_charpos = it->string_nchars = strlen (s);
6768 if (it->bidi_p)
6770 it->bidi_it.string.lstring = Qnil;
6771 it->bidi_it.string.s = (const unsigned char *) s;
6772 it->bidi_it.string.schars = it->end_charpos;
6773 it->bidi_it.string.bufpos = 0;
6774 it->bidi_it.string.from_disp_str = 0;
6775 it->bidi_it.string.unibyte = !it->multibyte_p;
6776 it->bidi_it.w = it->w;
6777 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6778 &it->bidi_it);
6780 it->method = GET_FROM_C_STRING;
6783 /* PRECISION > 0 means don't return more than PRECISION characters
6784 from the string. */
6785 if (precision > 0 && it->end_charpos - charpos > precision)
6787 it->end_charpos = it->string_nchars = charpos + precision;
6788 if (it->bidi_p)
6789 it->bidi_it.string.schars = it->end_charpos;
6792 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
6793 characters have been returned. FIELD_WIDTH == 0 means don't pad,
6794 FIELD_WIDTH < 0 means infinite field width. This is useful for
6795 padding with `-' at the end of a mode line. */
6796 if (field_width < 0)
6797 field_width = INFINITY;
6798 /* Implementation note: We deliberately don't enlarge
6799 it->bidi_it.string.schars here to fit it->end_charpos, because
6800 the bidi iterator cannot produce characters out of thin air. */
6801 if (field_width > it->end_charpos - charpos)
6802 it->end_charpos = charpos + field_width;
6804 /* Use the standard display table for displaying strings. */
6805 if (DISP_TABLE_P (Vstandard_display_table))
6806 it->dp = XCHAR_TABLE (Vstandard_display_table);
6808 it->stop_charpos = charpos;
6809 it->prev_stop = charpos;
6810 it->base_level_stop = 0;
6811 if (it->bidi_p)
6813 it->bidi_it.first_elt = 1;
6814 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6815 it->bidi_it.disp_pos = -1;
6817 if (s == NULL && it->multibyte_p)
6819 ptrdiff_t endpos = SCHARS (it->string);
6820 if (endpos > it->end_charpos)
6821 endpos = it->end_charpos;
6822 composition_compute_stop_pos (&it->cmp_it, charpos, -1, endpos,
6823 it->string);
6825 CHECK_IT (it);
6830 /***********************************************************************
6831 Iteration
6832 ***********************************************************************/
6834 /* Map enum it_method value to corresponding next_element_from_* function. */
6836 static int (* get_next_element[NUM_IT_METHODS]) (struct it *it) =
6838 next_element_from_buffer,
6839 next_element_from_display_vector,
6840 next_element_from_string,
6841 next_element_from_c_string,
6842 next_element_from_image,
6843 next_element_from_stretch
6844 #ifdef HAVE_XWIDGETS
6845 ,next_element_from_xwidget
6846 #endif
6849 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
6852 /* Return 1 iff a character at CHARPOS (and BYTEPOS) is composed
6853 (possibly with the following characters). */
6855 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS) \
6856 ((IT)->cmp_it.id >= 0 \
6857 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
6858 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
6859 END_CHARPOS, (IT)->w, \
6860 FACE_FROM_ID ((IT)->f, (IT)->face_id), \
6861 (IT)->string)))
6864 /* Lookup the char-table Vglyphless_char_display for character C (-1
6865 if we want information for no-font case), and return the display
6866 method symbol. By side-effect, update it->what and
6867 it->glyphless_method. This function is called from
6868 get_next_display_element for each character element, and from
6869 x_produce_glyphs when no suitable font was found. */
6871 Lisp_Object
6872 lookup_glyphless_char_display (int c, struct it *it)
6874 Lisp_Object glyphless_method = Qnil;
6876 if (CHAR_TABLE_P (Vglyphless_char_display)
6877 && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display)) >= 1)
6879 if (c >= 0)
6881 glyphless_method = CHAR_TABLE_REF (Vglyphless_char_display, c);
6882 if (CONSP (glyphless_method))
6883 glyphless_method = FRAME_WINDOW_P (it->f)
6884 ? XCAR (glyphless_method)
6885 : XCDR (glyphless_method);
6887 else
6888 glyphless_method = XCHAR_TABLE (Vglyphless_char_display)->extras[0];
6891 retry:
6892 if (NILP (glyphless_method))
6894 if (c >= 0)
6895 /* The default is to display the character by a proper font. */
6896 return Qnil;
6897 /* The default for the no-font case is to display an empty box. */
6898 glyphless_method = Qempty_box;
6900 if (EQ (glyphless_method, Qzero_width))
6902 if (c >= 0)
6903 return glyphless_method;
6904 /* This method can't be used for the no-font case. */
6905 glyphless_method = Qempty_box;
6907 if (EQ (glyphless_method, Qthin_space))
6908 it->glyphless_method = GLYPHLESS_DISPLAY_THIN_SPACE;
6909 else if (EQ (glyphless_method, Qempty_box))
6910 it->glyphless_method = GLYPHLESS_DISPLAY_EMPTY_BOX;
6911 else if (EQ (glyphless_method, Qhex_code))
6912 it->glyphless_method = GLYPHLESS_DISPLAY_HEX_CODE;
6913 else if (STRINGP (glyphless_method))
6914 it->glyphless_method = GLYPHLESS_DISPLAY_ACRONYM;
6915 else
6917 /* Invalid value. We use the default method. */
6918 glyphless_method = Qnil;
6919 goto retry;
6921 it->what = IT_GLYPHLESS;
6922 return glyphless_method;
6925 /* Merge escape glyph face and cache the result. */
6927 static struct frame *last_escape_glyph_frame = NULL;
6928 static int last_escape_glyph_face_id = (1 << FACE_ID_BITS);
6929 static int last_escape_glyph_merged_face_id = 0;
6931 static int
6932 merge_escape_glyph_face (struct it *it)
6934 int face_id;
6936 if (it->f == last_escape_glyph_frame
6937 && it->face_id == last_escape_glyph_face_id)
6938 face_id = last_escape_glyph_merged_face_id;
6939 else
6941 /* Merge the `escape-glyph' face into the current face. */
6942 face_id = merge_faces (it->f, Qescape_glyph, 0, it->face_id);
6943 last_escape_glyph_frame = it->f;
6944 last_escape_glyph_face_id = it->face_id;
6945 last_escape_glyph_merged_face_id = face_id;
6947 return face_id;
6950 /* Likewise for glyphless glyph face. */
6952 static struct frame *last_glyphless_glyph_frame = NULL;
6953 static int last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
6954 static int last_glyphless_glyph_merged_face_id = 0;
6957 merge_glyphless_glyph_face (struct it *it)
6959 int face_id;
6961 if (it->f == last_glyphless_glyph_frame
6962 && it->face_id == last_glyphless_glyph_face_id)
6963 face_id = last_glyphless_glyph_merged_face_id;
6964 else
6966 /* Merge the `glyphless-char' face into the current face. */
6967 face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
6968 last_glyphless_glyph_frame = it->f;
6969 last_glyphless_glyph_face_id = it->face_id;
6970 last_glyphless_glyph_merged_face_id = face_id;
6972 return face_id;
6975 /* Load IT's display element fields with information about the next
6976 display element from the current position of IT. Value is zero if
6977 end of buffer (or C string) is reached. */
6979 static int
6980 get_next_display_element (struct it *it)
6982 /* Non-zero means that we found a display element. Zero means that
6983 we hit the end of what we iterate over. Performance note: the
6984 function pointer `method' used here turns out to be faster than
6985 using a sequence of if-statements. */
6986 int success_p;
6988 get_next:
6989 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
6991 if (it->what == IT_CHARACTER)
6993 /* UAX#9, L4: "A character is depicted by a mirrored glyph if
6994 and only if (a) the resolved directionality of that character
6995 is R..." */
6996 /* FIXME: Do we need an exception for characters from display
6997 tables? */
6998 if (it->bidi_p && it->bidi_it.type == STRONG_R
6999 && !inhibit_bidi_mirroring)
7000 it->c = bidi_mirror_char (it->c);
7001 /* Map via display table or translate control characters.
7002 IT->c, IT->len etc. have been set to the next character by
7003 the function call above. If we have a display table, and it
7004 contains an entry for IT->c, translate it. Don't do this if
7005 IT->c itself comes from a display table, otherwise we could
7006 end up in an infinite recursion. (An alternative could be to
7007 count the recursion depth of this function and signal an
7008 error when a certain maximum depth is reached.) Is it worth
7009 it? */
7010 if (success_p && it->dpvec == NULL)
7012 Lisp_Object dv;
7013 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
7014 int nonascii_space_p = 0;
7015 int nonascii_hyphen_p = 0;
7016 int c = it->c; /* This is the character to display. */
7018 if (! it->multibyte_p && ! ASCII_CHAR_P (c))
7020 eassert (SINGLE_BYTE_CHAR_P (c));
7021 if (unibyte_display_via_language_environment)
7023 c = DECODE_CHAR (unibyte, c);
7024 if (c < 0)
7025 c = BYTE8_TO_CHAR (it->c);
7027 else
7028 c = BYTE8_TO_CHAR (it->c);
7031 if (it->dp
7032 && (dv = DISP_CHAR_VECTOR (it->dp, c),
7033 VECTORP (dv)))
7035 struct Lisp_Vector *v = XVECTOR (dv);
7037 /* Return the first character from the display table
7038 entry, if not empty. If empty, don't display the
7039 current character. */
7040 if (v->header.size)
7042 it->dpvec_char_len = it->len;
7043 it->dpvec = v->contents;
7044 it->dpend = v->contents + v->header.size;
7045 it->current.dpvec_index = 0;
7046 it->dpvec_face_id = -1;
7047 it->saved_face_id = it->face_id;
7048 it->method = GET_FROM_DISPLAY_VECTOR;
7049 it->ellipsis_p = 0;
7051 else
7053 set_iterator_to_next (it, 0);
7055 goto get_next;
7058 if (! NILP (lookup_glyphless_char_display (c, it)))
7060 if (it->what == IT_GLYPHLESS)
7061 goto done;
7062 /* Don't display this character. */
7063 set_iterator_to_next (it, 0);
7064 goto get_next;
7067 /* If `nobreak-char-display' is non-nil, we display
7068 non-ASCII spaces and hyphens specially. */
7069 if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
7071 if (c == 0xA0)
7072 nonascii_space_p = true;
7073 else if (c == 0xAD || c == 0x2010 || c == 0x2011)
7074 nonascii_hyphen_p = true;
7077 /* Translate control characters into `\003' or `^C' form.
7078 Control characters coming from a display table entry are
7079 currently not translated because we use IT->dpvec to hold
7080 the translation. This could easily be changed but I
7081 don't believe that it is worth doing.
7083 The characters handled by `nobreak-char-display' must be
7084 translated too.
7086 Non-printable characters and raw-byte characters are also
7087 translated to octal form. */
7088 if (((c < ' ' || c == 127) /* ASCII control chars. */
7089 ? (it->area != TEXT_AREA
7090 /* In mode line, treat \n, \t like other crl chars. */
7091 || (c != '\t'
7092 && it->glyph_row
7093 && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
7094 || (c != '\n' && c != '\t'))
7095 : (nonascii_space_p
7096 || nonascii_hyphen_p
7097 || CHAR_BYTE8_P (c)
7098 || ! CHAR_PRINTABLE_P (c))))
7100 /* C is a control character, non-ASCII space/hyphen,
7101 raw-byte, or a non-printable character which must be
7102 displayed either as '\003' or as `^C' where the '\\'
7103 and '^' can be defined in the display table. Fill
7104 IT->ctl_chars with glyphs for what we have to
7105 display. Then, set IT->dpvec to these glyphs. */
7106 Lisp_Object gc;
7107 int ctl_len;
7108 int face_id;
7109 int lface_id = 0;
7110 int escape_glyph;
7112 /* Handle control characters with ^. */
7114 if (ASCII_CHAR_P (c) && it->ctl_arrow_p)
7116 int g;
7118 g = '^'; /* default glyph for Control */
7119 /* Set IT->ctl_chars[0] to the glyph for `^'. */
7120 if (it->dp
7121 && (gc = DISP_CTRL_GLYPH (it->dp), GLYPH_CODE_P (gc)))
7123 g = GLYPH_CODE_CHAR (gc);
7124 lface_id = GLYPH_CODE_FACE (gc);
7127 face_id = (lface_id
7128 ? merge_faces (it->f, Qt, lface_id, it->face_id)
7129 : merge_escape_glyph_face (it));
7131 XSETINT (it->ctl_chars[0], g);
7132 XSETINT (it->ctl_chars[1], c ^ 0100);
7133 ctl_len = 2;
7134 goto display_control;
7137 /* Handle non-ascii space in the mode where it only gets
7138 highlighting. */
7140 if (nonascii_space_p && EQ (Vnobreak_char_display, Qt))
7142 /* Merge `nobreak-space' into the current face. */
7143 face_id = merge_faces (it->f, Qnobreak_space, 0,
7144 it->face_id);
7145 XSETINT (it->ctl_chars[0], ' ');
7146 ctl_len = 1;
7147 goto display_control;
7150 /* Handle sequences that start with the "escape glyph". */
7152 /* the default escape glyph is \. */
7153 escape_glyph = '\\';
7155 if (it->dp
7156 && (gc = DISP_ESCAPE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
7158 escape_glyph = GLYPH_CODE_CHAR (gc);
7159 lface_id = GLYPH_CODE_FACE (gc);
7162 face_id = (lface_id
7163 ? merge_faces (it->f, Qt, lface_id, it->face_id)
7164 : merge_escape_glyph_face (it));
7166 /* Draw non-ASCII hyphen with just highlighting: */
7168 if (nonascii_hyphen_p && EQ (Vnobreak_char_display, Qt))
7170 XSETINT (it->ctl_chars[0], '-');
7171 ctl_len = 1;
7172 goto display_control;
7175 /* Draw non-ASCII space/hyphen with escape glyph: */
7177 if (nonascii_space_p || nonascii_hyphen_p)
7179 XSETINT (it->ctl_chars[0], escape_glyph);
7180 XSETINT (it->ctl_chars[1], nonascii_space_p ? ' ' : '-');
7181 ctl_len = 2;
7182 goto display_control;
7186 char str[10];
7187 int len, i;
7189 if (CHAR_BYTE8_P (c))
7190 /* Display \200 instead of \17777600. */
7191 c = CHAR_TO_BYTE8 (c);
7192 len = sprintf (str, "%03o", c);
7194 XSETINT (it->ctl_chars[0], escape_glyph);
7195 for (i = 0; i < len; i++)
7196 XSETINT (it->ctl_chars[i + 1], str[i]);
7197 ctl_len = len + 1;
7200 display_control:
7201 /* Set up IT->dpvec and return first character from it. */
7202 it->dpvec_char_len = it->len;
7203 it->dpvec = it->ctl_chars;
7204 it->dpend = it->dpvec + ctl_len;
7205 it->current.dpvec_index = 0;
7206 it->dpvec_face_id = face_id;
7207 it->saved_face_id = it->face_id;
7208 it->method = GET_FROM_DISPLAY_VECTOR;
7209 it->ellipsis_p = 0;
7210 goto get_next;
7212 it->char_to_display = c;
7214 else if (success_p)
7216 it->char_to_display = it->c;
7220 #ifdef HAVE_WINDOW_SYSTEM
7221 /* Adjust face id for a multibyte character. There are no multibyte
7222 character in unibyte text. */
7223 if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
7224 && it->multibyte_p
7225 && success_p
7226 && FRAME_WINDOW_P (it->f))
7228 struct face *face = FACE_FROM_ID (it->f, it->face_id);
7230 if (it->what == IT_COMPOSITION && it->cmp_it.ch >= 0)
7232 /* Automatic composition with glyph-string. */
7233 Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id);
7235 it->face_id = face_for_font (it->f, LGSTRING_FONT (gstring), face);
7237 else
7239 ptrdiff_t pos = (it->s ? -1
7240 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
7241 : IT_CHARPOS (*it));
7242 int c;
7244 if (it->what == IT_CHARACTER)
7245 c = it->char_to_display;
7246 else
7248 struct composition *cmp = composition_table[it->cmp_it.id];
7249 int i;
7251 c = ' ';
7252 for (i = 0; i < cmp->glyph_len; i++)
7253 /* TAB in a composition means display glyphs with
7254 padding space on the left or right. */
7255 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
7256 break;
7258 it->face_id = FACE_FOR_CHAR (it->f, face, c, pos, it->string);
7261 #endif /* HAVE_WINDOW_SYSTEM */
7263 done:
7264 /* Is this character the last one of a run of characters with
7265 box? If yes, set IT->end_of_box_run_p to 1. */
7266 if (it->face_box_p
7267 && it->s == NULL)
7269 if (it->method == GET_FROM_STRING && it->sp)
7271 int face_id = underlying_face_id (it);
7272 struct face *face = FACE_FROM_ID (it->f, face_id);
7274 if (face)
7276 if (face->box == FACE_NO_BOX)
7278 /* If the box comes from face properties in a
7279 display string, check faces in that string. */
7280 int string_face_id = face_after_it_pos (it);
7281 it->end_of_box_run_p
7282 = (FACE_FROM_ID (it->f, string_face_id)->box
7283 == FACE_NO_BOX);
7285 /* Otherwise, the box comes from the underlying face.
7286 If this is the last string character displayed, check
7287 the next buffer location. */
7288 else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1)
7289 /* n_overlay_strings is unreliable unless
7290 overlay_string_index is non-negative. */
7291 && ((it->current.overlay_string_index >= 0
7292 && (it->current.overlay_string_index
7293 == it->n_overlay_strings - 1))
7294 /* A string from display property. */
7295 || it->from_disp_prop_p))
7297 ptrdiff_t ignore;
7298 int next_face_id;
7299 struct text_pos pos = it->current.pos;
7301 /* For a string from a display property, the next
7302 buffer position is stored in the 'position'
7303 member of the iteration stack slot below the
7304 current one, see handle_single_display_spec. By
7305 contrast, it->current.pos was is not yet updated
7306 to point to that buffer position; that will
7307 happen in pop_it, after we finish displaying the
7308 current string. Note that we already checked
7309 above that it->sp is positive, so subtracting one
7310 from it is safe. */
7311 if (it->from_disp_prop_p)
7312 pos = (it->stack + it->sp - 1)->position;
7313 else
7314 INC_TEXT_POS (pos, it->multibyte_p);
7316 if (CHARPOS (pos) >= ZV)
7317 it->end_of_box_run_p = true;
7318 else
7320 next_face_id = face_at_buffer_position
7321 (it->w, CHARPOS (pos), &ignore,
7322 CHARPOS (pos) + TEXT_PROP_DISTANCE_LIMIT, 0, -1);
7323 it->end_of_box_run_p
7324 = (FACE_FROM_ID (it->f, next_face_id)->box
7325 == FACE_NO_BOX);
7330 /* next_element_from_display_vector sets this flag according to
7331 faces of the display vector glyphs, see there. */
7332 else if (it->method != GET_FROM_DISPLAY_VECTOR)
7334 int face_id = face_after_it_pos (it);
7335 it->end_of_box_run_p
7336 = (face_id != it->face_id
7337 && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX);
7340 /* If we reached the end of the object we've been iterating (e.g., a
7341 display string or an overlay string), and there's something on
7342 IT->stack, proceed with what's on the stack. It doesn't make
7343 sense to return zero if there's unprocessed stuff on the stack,
7344 because otherwise that stuff will never be displayed. */
7345 if (!success_p && it->sp > 0)
7347 set_iterator_to_next (it, 0);
7348 success_p = get_next_display_element (it);
7351 /* Value is 0 if end of buffer or string reached. */
7352 return success_p;
7356 /* Move IT to the next display element.
7358 RESEAT_P non-zero means if called on a newline in buffer text,
7359 skip to the next visible line start.
7361 Functions get_next_display_element and set_iterator_to_next are
7362 separate because I find this arrangement easier to handle than a
7363 get_next_display_element function that also increments IT's
7364 position. The way it is we can first look at an iterator's current
7365 display element, decide whether it fits on a line, and if it does,
7366 increment the iterator position. The other way around we probably
7367 would either need a flag indicating whether the iterator has to be
7368 incremented the next time, or we would have to implement a
7369 decrement position function which would not be easy to write. */
7371 void
7372 set_iterator_to_next (struct it *it, int reseat_p)
7374 /* Reset flags indicating start and end of a sequence of characters
7375 with box. Reset them at the start of this function because
7376 moving the iterator to a new position might set them. */
7377 it->start_of_box_run_p = it->end_of_box_run_p = 0;
7379 switch (it->method)
7381 case GET_FROM_BUFFER:
7382 /* The current display element of IT is a character from
7383 current_buffer. Advance in the buffer, and maybe skip over
7384 invisible lines that are so because of selective display. */
7385 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
7386 reseat_at_next_visible_line_start (it, 0);
7387 else if (it->cmp_it.id >= 0)
7389 /* We are currently getting glyphs from a composition. */
7390 if (! it->bidi_p)
7392 IT_CHARPOS (*it) += it->cmp_it.nchars;
7393 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
7395 else
7397 int i;
7399 /* Update IT's char/byte positions to point to the first
7400 character of the next grapheme cluster, or to the
7401 character visually after the current composition. */
7402 for (i = 0; i < it->cmp_it.nchars; i++)
7403 bidi_move_to_visually_next (&it->bidi_it);
7404 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7405 IT_CHARPOS (*it) = it->bidi_it.charpos;
7408 if ((! it->bidi_p || ! it->cmp_it.reversed_p)
7409 && it->cmp_it.to < it->cmp_it.nglyphs)
7411 /* Composition created while scanning forward. Proceed
7412 to the next grapheme cluster. */
7413 it->cmp_it.from = it->cmp_it.to;
7415 else if ((it->bidi_p && it->cmp_it.reversed_p)
7416 && it->cmp_it.from > 0)
7418 /* Composition created while scanning backward. Proceed
7419 to the previous grapheme cluster. */
7420 it->cmp_it.to = it->cmp_it.from;
7422 else
7424 /* No more grapheme clusters in this composition.
7425 Find the next stop position. */
7426 ptrdiff_t stop = it->end_charpos;
7428 if (it->bidi_it.scan_dir < 0)
7429 /* Now we are scanning backward and don't know
7430 where to stop. */
7431 stop = -1;
7432 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7433 IT_BYTEPOS (*it), stop, Qnil);
7436 else
7438 eassert (it->len != 0);
7440 if (!it->bidi_p)
7442 IT_BYTEPOS (*it) += it->len;
7443 IT_CHARPOS (*it) += 1;
7445 else
7447 int prev_scan_dir = it->bidi_it.scan_dir;
7448 /* If this is a new paragraph, determine its base
7449 direction (a.k.a. its base embedding level). */
7450 if (it->bidi_it.new_paragraph)
7451 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
7452 bidi_move_to_visually_next (&it->bidi_it);
7453 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7454 IT_CHARPOS (*it) = it->bidi_it.charpos;
7455 if (prev_scan_dir != it->bidi_it.scan_dir)
7457 /* As the scan direction was changed, we must
7458 re-compute the stop position for composition. */
7459 ptrdiff_t stop = it->end_charpos;
7460 if (it->bidi_it.scan_dir < 0)
7461 stop = -1;
7462 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7463 IT_BYTEPOS (*it), stop, Qnil);
7466 eassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
7468 break;
7470 case GET_FROM_C_STRING:
7471 /* Current display element of IT is from a C string. */
7472 if (!it->bidi_p
7473 /* If the string position is beyond string's end, it means
7474 next_element_from_c_string is padding the string with
7475 blanks, in which case we bypass the bidi iterator,
7476 because it cannot deal with such virtual characters. */
7477 || IT_CHARPOS (*it) >= it->bidi_it.string.schars)
7479 IT_BYTEPOS (*it) += it->len;
7480 IT_CHARPOS (*it) += 1;
7482 else
7484 bidi_move_to_visually_next (&it->bidi_it);
7485 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7486 IT_CHARPOS (*it) = it->bidi_it.charpos;
7488 break;
7490 case GET_FROM_DISPLAY_VECTOR:
7491 /* Current display element of IT is from a display table entry.
7492 Advance in the display table definition. Reset it to null if
7493 end reached, and continue with characters from buffers/
7494 strings. */
7495 ++it->current.dpvec_index;
7497 /* Restore face of the iterator to what they were before the
7498 display vector entry (these entries may contain faces). */
7499 it->face_id = it->saved_face_id;
7501 if (it->dpvec + it->current.dpvec_index >= it->dpend)
7503 int recheck_faces = it->ellipsis_p;
7505 if (it->s)
7506 it->method = GET_FROM_C_STRING;
7507 else if (STRINGP (it->string))
7508 it->method = GET_FROM_STRING;
7509 else
7511 it->method = GET_FROM_BUFFER;
7512 it->object = it->w->contents;
7515 it->dpvec = NULL;
7516 it->current.dpvec_index = -1;
7518 /* Skip over characters which were displayed via IT->dpvec. */
7519 if (it->dpvec_char_len < 0)
7520 reseat_at_next_visible_line_start (it, 1);
7521 else if (it->dpvec_char_len > 0)
7523 if (it->method == GET_FROM_STRING
7524 && it->current.overlay_string_index >= 0
7525 && it->n_overlay_strings > 0)
7526 it->ignore_overlay_strings_at_pos_p = true;
7527 it->len = it->dpvec_char_len;
7528 set_iterator_to_next (it, reseat_p);
7531 /* Maybe recheck faces after display vector. */
7532 if (recheck_faces)
7533 it->stop_charpos = IT_CHARPOS (*it);
7535 break;
7537 case GET_FROM_STRING:
7538 /* Current display element is a character from a Lisp string. */
7539 eassert (it->s == NULL && STRINGP (it->string));
7540 /* Don't advance past string end. These conditions are true
7541 when set_iterator_to_next is called at the end of
7542 get_next_display_element, in which case the Lisp string is
7543 already exhausted, and all we want is pop the iterator
7544 stack. */
7545 if (it->current.overlay_string_index >= 0)
7547 /* This is an overlay string, so there's no padding with
7548 spaces, and the number of characters in the string is
7549 where the string ends. */
7550 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7551 goto consider_string_end;
7553 else
7555 /* Not an overlay string. There could be padding, so test
7556 against it->end_charpos. */
7557 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7558 goto consider_string_end;
7560 if (it->cmp_it.id >= 0)
7562 /* We are delivering display elements from a composition.
7563 Update the string position past the grapheme cluster
7564 we've just processed. */
7565 if (! it->bidi_p)
7567 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
7568 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
7570 else
7572 int i;
7574 for (i = 0; i < it->cmp_it.nchars; i++)
7575 bidi_move_to_visually_next (&it->bidi_it);
7576 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7577 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7580 /* Did we exhaust all the grapheme clusters of this
7581 composition? */
7582 if ((! it->bidi_p || ! it->cmp_it.reversed_p)
7583 && (it->cmp_it.to < it->cmp_it.nglyphs))
7585 /* Not all the grapheme clusters were processed yet;
7586 advance to the next cluster. */
7587 it->cmp_it.from = it->cmp_it.to;
7589 else if ((it->bidi_p && it->cmp_it.reversed_p)
7590 && it->cmp_it.from > 0)
7592 /* Likewise: advance to the next cluster, but going in
7593 the reverse direction. */
7594 it->cmp_it.to = it->cmp_it.from;
7596 else
7598 /* This composition was fully processed; find the next
7599 candidate place for checking for composed
7600 characters. */
7601 /* Always limit string searches to the string length;
7602 any padding spaces are not part of the string, and
7603 there cannot be any compositions in that padding. */
7604 ptrdiff_t stop = SCHARS (it->string);
7606 if (it->bidi_p && it->bidi_it.scan_dir < 0)
7607 stop = -1;
7608 else if (it->end_charpos < stop)
7610 /* Cf. PRECISION in reseat_to_string: we might be
7611 limited in how many of the string characters we
7612 need to deliver. */
7613 stop = it->end_charpos;
7615 composition_compute_stop_pos (&it->cmp_it,
7616 IT_STRING_CHARPOS (*it),
7617 IT_STRING_BYTEPOS (*it), stop,
7618 it->string);
7621 else
7623 if (!it->bidi_p
7624 /* If the string position is beyond string's end, it
7625 means next_element_from_string is padding the string
7626 with blanks, in which case we bypass the bidi
7627 iterator, because it cannot deal with such virtual
7628 characters. */
7629 || IT_STRING_CHARPOS (*it) >= it->bidi_it.string.schars)
7631 IT_STRING_BYTEPOS (*it) += it->len;
7632 IT_STRING_CHARPOS (*it) += 1;
7634 else
7636 int prev_scan_dir = it->bidi_it.scan_dir;
7638 bidi_move_to_visually_next (&it->bidi_it);
7639 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7640 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7641 /* If the scan direction changes, we may need to update
7642 the place where to check for composed characters. */
7643 if (prev_scan_dir != it->bidi_it.scan_dir)
7645 ptrdiff_t stop = SCHARS (it->string);
7647 if (it->bidi_it.scan_dir < 0)
7648 stop = -1;
7649 else if (it->end_charpos < stop)
7650 stop = it->end_charpos;
7652 composition_compute_stop_pos (&it->cmp_it,
7653 IT_STRING_CHARPOS (*it),
7654 IT_STRING_BYTEPOS (*it), stop,
7655 it->string);
7660 consider_string_end:
7662 if (it->current.overlay_string_index >= 0)
7664 /* IT->string is an overlay string. Advance to the
7665 next, if there is one. */
7666 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7668 it->ellipsis_p = 0;
7669 next_overlay_string (it);
7670 if (it->ellipsis_p)
7671 setup_for_ellipsis (it, 0);
7674 else
7676 /* IT->string is not an overlay string. If we reached
7677 its end, and there is something on IT->stack, proceed
7678 with what is on the stack. This can be either another
7679 string, this time an overlay string, or a buffer. */
7680 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
7681 && it->sp > 0)
7683 pop_it (it);
7684 if (it->method == GET_FROM_STRING)
7685 goto consider_string_end;
7688 break;
7690 case GET_FROM_IMAGE:
7691 case GET_FROM_STRETCH:
7692 #ifdef HAVE_XWIDGETS
7693 case GET_FROM_XWIDGET:
7695 /* The position etc with which we have to proceed are on
7696 the stack. The position may be at the end of a string,
7697 if the `display' property takes up the whole string. */
7698 eassert (it->sp > 0);
7699 pop_it (it);
7700 if (it->method == GET_FROM_STRING)
7701 goto consider_string_end;
7702 break;
7703 #endif
7704 default:
7705 /* There are no other methods defined, so this should be a bug. */
7706 emacs_abort ();
7709 eassert (it->method != GET_FROM_STRING
7710 || (STRINGP (it->string)
7711 && IT_STRING_CHARPOS (*it) >= 0));
7714 /* Load IT's display element fields with information about the next
7715 display element which comes from a display table entry or from the
7716 result of translating a control character to one of the forms `^C'
7717 or `\003'.
7719 IT->dpvec holds the glyphs to return as characters.
7720 IT->saved_face_id holds the face id before the display vector--it
7721 is restored into IT->face_id in set_iterator_to_next. */
7723 static int
7724 next_element_from_display_vector (struct it *it)
7726 Lisp_Object gc;
7727 int prev_face_id = it->face_id;
7728 int next_face_id;
7730 /* Precondition. */
7731 eassert (it->dpvec && it->current.dpvec_index >= 0);
7733 it->face_id = it->saved_face_id;
7735 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
7736 That seemed totally bogus - so I changed it... */
7737 gc = it->dpvec[it->current.dpvec_index];
7739 if (GLYPH_CODE_P (gc))
7741 struct face *this_face, *prev_face, *next_face;
7743 it->c = GLYPH_CODE_CHAR (gc);
7744 it->len = CHAR_BYTES (it->c);
7746 /* The entry may contain a face id to use. Such a face id is
7747 the id of a Lisp face, not a realized face. A face id of
7748 zero means no face is specified. */
7749 if (it->dpvec_face_id >= 0)
7750 it->face_id = it->dpvec_face_id;
7751 else
7753 int lface_id = GLYPH_CODE_FACE (gc);
7754 if (lface_id > 0)
7755 it->face_id = merge_faces (it->f, Qt, lface_id,
7756 it->saved_face_id);
7759 /* Glyphs in the display vector could have the box face, so we
7760 need to set the related flags in the iterator, as
7761 appropriate. */
7762 this_face = FACE_FROM_ID (it->f, it->face_id);
7763 prev_face = FACE_FROM_ID (it->f, prev_face_id);
7765 /* Is this character the first character of a box-face run? */
7766 it->start_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX
7767 && (!prev_face
7768 || prev_face->box == FACE_NO_BOX));
7770 /* For the last character of the box-face run, we need to look
7771 either at the next glyph from the display vector, or at the
7772 face we saw before the display vector. */
7773 next_face_id = it->saved_face_id;
7774 if (it->current.dpvec_index < it->dpend - it->dpvec - 1)
7776 if (it->dpvec_face_id >= 0)
7777 next_face_id = it->dpvec_face_id;
7778 else
7780 int lface_id =
7781 GLYPH_CODE_FACE (it->dpvec[it->current.dpvec_index + 1]);
7783 if (lface_id > 0)
7784 next_face_id = merge_faces (it->f, Qt, lface_id,
7785 it->saved_face_id);
7788 next_face = FACE_FROM_ID (it->f, next_face_id);
7789 it->end_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX
7790 && (!next_face
7791 || next_face->box == FACE_NO_BOX));
7792 it->face_box_p = this_face && this_face->box != FACE_NO_BOX;
7794 else
7795 /* Display table entry is invalid. Return a space. */
7796 it->c = ' ', it->len = 1;
7798 /* Don't change position and object of the iterator here. They are
7799 still the values of the character that had this display table
7800 entry or was translated, and that's what we want. */
7801 it->what = IT_CHARACTER;
7802 return 1;
7805 /* Get the first element of string/buffer in the visual order, after
7806 being reseated to a new position in a string or a buffer. */
7807 static void
7808 get_visually_first_element (struct it *it)
7810 int string_p = STRINGP (it->string) || it->s;
7811 ptrdiff_t eob = (string_p ? it->bidi_it.string.schars : ZV);
7812 ptrdiff_t bob = (string_p ? 0 : BEGV);
7814 if (STRINGP (it->string))
7816 it->bidi_it.charpos = IT_STRING_CHARPOS (*it);
7817 it->bidi_it.bytepos = IT_STRING_BYTEPOS (*it);
7819 else
7821 it->bidi_it.charpos = IT_CHARPOS (*it);
7822 it->bidi_it.bytepos = IT_BYTEPOS (*it);
7825 if (it->bidi_it.charpos == eob)
7827 /* Nothing to do, but reset the FIRST_ELT flag, like
7828 bidi_paragraph_init does, because we are not going to
7829 call it. */
7830 it->bidi_it.first_elt = 0;
7832 else if (it->bidi_it.charpos == bob
7833 || (!string_p
7834 && (FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n'
7835 || FETCH_CHAR (it->bidi_it.bytepos) == '\n')))
7837 /* If we are at the beginning of a line/string, we can produce
7838 the next element right away. */
7839 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
7840 bidi_move_to_visually_next (&it->bidi_it);
7842 else
7844 ptrdiff_t orig_bytepos = it->bidi_it.bytepos;
7846 /* We need to prime the bidi iterator starting at the line's or
7847 string's beginning, before we will be able to produce the
7848 next element. */
7849 if (string_p)
7850 it->bidi_it.charpos = it->bidi_it.bytepos = 0;
7851 else
7852 it->bidi_it.charpos = find_newline_no_quit (IT_CHARPOS (*it),
7853 IT_BYTEPOS (*it), -1,
7854 &it->bidi_it.bytepos);
7855 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
7858 /* Now return to buffer/string position where we were asked
7859 to get the next display element, and produce that. */
7860 bidi_move_to_visually_next (&it->bidi_it);
7862 while (it->bidi_it.bytepos != orig_bytepos
7863 && it->bidi_it.charpos < eob);
7866 /* Adjust IT's position information to where we ended up. */
7867 if (STRINGP (it->string))
7869 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7870 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7872 else
7874 IT_CHARPOS (*it) = it->bidi_it.charpos;
7875 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7878 if (STRINGP (it->string) || !it->s)
7880 ptrdiff_t stop, charpos, bytepos;
7882 if (STRINGP (it->string))
7884 eassert (!it->s);
7885 stop = SCHARS (it->string);
7886 if (stop > it->end_charpos)
7887 stop = it->end_charpos;
7888 charpos = IT_STRING_CHARPOS (*it);
7889 bytepos = IT_STRING_BYTEPOS (*it);
7891 else
7893 stop = it->end_charpos;
7894 charpos = IT_CHARPOS (*it);
7895 bytepos = IT_BYTEPOS (*it);
7897 if (it->bidi_it.scan_dir < 0)
7898 stop = -1;
7899 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos, stop,
7900 it->string);
7904 /* Load IT with the next display element from Lisp string IT->string.
7905 IT->current.string_pos is the current position within the string.
7906 If IT->current.overlay_string_index >= 0, the Lisp string is an
7907 overlay string. */
7909 static int
7910 next_element_from_string (struct it *it)
7912 struct text_pos position;
7914 eassert (STRINGP (it->string));
7915 eassert (!it->bidi_p || EQ (it->string, it->bidi_it.string.lstring));
7916 eassert (IT_STRING_CHARPOS (*it) >= 0);
7917 position = it->current.string_pos;
7919 /* With bidi reordering, the character to display might not be the
7920 character at IT_STRING_CHARPOS. BIDI_IT.FIRST_ELT non-zero means
7921 that we were reseat()ed to a new string, whose paragraph
7922 direction is not known. */
7923 if (it->bidi_p && it->bidi_it.first_elt)
7925 get_visually_first_element (it);
7926 SET_TEXT_POS (position, IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it));
7929 /* Time to check for invisible text? */
7930 if (IT_STRING_CHARPOS (*it) < it->end_charpos)
7932 if (IT_STRING_CHARPOS (*it) >= it->stop_charpos)
7934 if (!(!it->bidi_p
7935 || BIDI_AT_BASE_LEVEL (it->bidi_it)
7936 || IT_STRING_CHARPOS (*it) == it->stop_charpos))
7938 /* With bidi non-linear iteration, we could find
7939 ourselves far beyond the last computed stop_charpos,
7940 with several other stop positions in between that we
7941 missed. Scan them all now, in buffer's logical
7942 order, until we find and handle the last stop_charpos
7943 that precedes our current position. */
7944 handle_stop_backwards (it, it->stop_charpos);
7945 return GET_NEXT_DISPLAY_ELEMENT (it);
7947 else
7949 if (it->bidi_p)
7951 /* Take note of the stop position we just moved
7952 across, for when we will move back across it. */
7953 it->prev_stop = it->stop_charpos;
7954 /* If we are at base paragraph embedding level, take
7955 note of the last stop position seen at this
7956 level. */
7957 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
7958 it->base_level_stop = it->stop_charpos;
7960 handle_stop (it);
7962 /* Since a handler may have changed IT->method, we must
7963 recurse here. */
7964 return GET_NEXT_DISPLAY_ELEMENT (it);
7967 else if (it->bidi_p
7968 /* If we are before prev_stop, we may have overstepped
7969 on our way backwards a stop_pos, and if so, we need
7970 to handle that stop_pos. */
7971 && IT_STRING_CHARPOS (*it) < it->prev_stop
7972 /* We can sometimes back up for reasons that have nothing
7973 to do with bidi reordering. E.g., compositions. The
7974 code below is only needed when we are above the base
7975 embedding level, so test for that explicitly. */
7976 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
7978 /* If we lost track of base_level_stop, we have no better
7979 place for handle_stop_backwards to start from than string
7980 beginning. This happens, e.g., when we were reseated to
7981 the previous screenful of text by vertical-motion. */
7982 if (it->base_level_stop <= 0
7983 || IT_STRING_CHARPOS (*it) < it->base_level_stop)
7984 it->base_level_stop = 0;
7985 handle_stop_backwards (it, it->base_level_stop);
7986 return GET_NEXT_DISPLAY_ELEMENT (it);
7990 if (it->current.overlay_string_index >= 0)
7992 /* Get the next character from an overlay string. In overlay
7993 strings, there is no field width or padding with spaces to
7994 do. */
7995 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7997 it->what = IT_EOB;
7998 return 0;
8000 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
8001 IT_STRING_BYTEPOS (*it),
8002 it->bidi_it.scan_dir < 0
8003 ? -1
8004 : SCHARS (it->string))
8005 && next_element_from_composition (it))
8007 return 1;
8009 else if (STRING_MULTIBYTE (it->string))
8011 const unsigned char *s = (SDATA (it->string)
8012 + IT_STRING_BYTEPOS (*it));
8013 it->c = string_char_and_length (s, &it->len);
8015 else
8017 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
8018 it->len = 1;
8021 else
8023 /* Get the next character from a Lisp string that is not an
8024 overlay string. Such strings come from the mode line, for
8025 example. We may have to pad with spaces, or truncate the
8026 string. See also next_element_from_c_string. */
8027 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
8029 it->what = IT_EOB;
8030 return 0;
8032 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
8034 /* Pad with spaces. */
8035 it->c = ' ', it->len = 1;
8036 CHARPOS (position) = BYTEPOS (position) = -1;
8038 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
8039 IT_STRING_BYTEPOS (*it),
8040 it->bidi_it.scan_dir < 0
8041 ? -1
8042 : it->string_nchars)
8043 && next_element_from_composition (it))
8045 return 1;
8047 else if (STRING_MULTIBYTE (it->string))
8049 const unsigned char *s = (SDATA (it->string)
8050 + IT_STRING_BYTEPOS (*it));
8051 it->c = string_char_and_length (s, &it->len);
8053 else
8055 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
8056 it->len = 1;
8060 /* Record what we have and where it came from. */
8061 it->what = IT_CHARACTER;
8062 it->object = it->string;
8063 it->position = position;
8064 return 1;
8068 /* Load IT with next display element from C string IT->s.
8069 IT->string_nchars is the maximum number of characters to return
8070 from the string. IT->end_charpos may be greater than
8071 IT->string_nchars when this function is called, in which case we
8072 may have to return padding spaces. Value is zero if end of string
8073 reached, including padding spaces. */
8075 static int
8076 next_element_from_c_string (struct it *it)
8078 bool success_p = true;
8080 eassert (it->s);
8081 eassert (!it->bidi_p || it->s == it->bidi_it.string.s);
8082 it->what = IT_CHARACTER;
8083 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
8084 it->object = Qnil;
8086 /* With bidi reordering, the character to display might not be the
8087 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
8088 we were reseated to a new string, whose paragraph direction is
8089 not known. */
8090 if (it->bidi_p && it->bidi_it.first_elt)
8091 get_visually_first_element (it);
8093 /* IT's position can be greater than IT->string_nchars in case a
8094 field width or precision has been specified when the iterator was
8095 initialized. */
8096 if (IT_CHARPOS (*it) >= it->end_charpos)
8098 /* End of the game. */
8099 it->what = IT_EOB;
8100 success_p = 0;
8102 else if (IT_CHARPOS (*it) >= it->string_nchars)
8104 /* Pad with spaces. */
8105 it->c = ' ', it->len = 1;
8106 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
8108 else if (it->multibyte_p)
8109 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), &it->len);
8110 else
8111 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
8113 return success_p;
8117 /* Set up IT to return characters from an ellipsis, if appropriate.
8118 The definition of the ellipsis glyphs may come from a display table
8119 entry. This function fills IT with the first glyph from the
8120 ellipsis if an ellipsis is to be displayed. */
8122 static int
8123 next_element_from_ellipsis (struct it *it)
8125 if (it->selective_display_ellipsis_p)
8126 setup_for_ellipsis (it, it->len);
8127 else
8129 /* The face at the current position may be different from the
8130 face we find after the invisible text. Remember what it
8131 was in IT->saved_face_id, and signal that it's there by
8132 setting face_before_selective_p. */
8133 it->saved_face_id = it->face_id;
8134 it->method = GET_FROM_BUFFER;
8135 it->object = it->w->contents;
8136 reseat_at_next_visible_line_start (it, 1);
8137 it->face_before_selective_p = true;
8140 return GET_NEXT_DISPLAY_ELEMENT (it);
8144 /* Deliver an image display element. The iterator IT is already
8145 filled with image information (done in handle_display_prop). Value
8146 is always 1. */
8149 static int
8150 next_element_from_image (struct it *it)
8152 it->what = IT_IMAGE;
8153 it->ignore_overlay_strings_at_pos_p = 0;
8154 return 1;
8157 #ifdef HAVE_XWIDGETS
8158 /* im not sure about this FIXME JAVE*/
8159 static int
8160 next_element_from_xwidget (struct it *it)
8162 it->what = IT_XWIDGET;
8163 //assert_valid_xwidget_id(it->xwidget_id,"next_element_from_xwidget");
8164 //this is shaky because why do we set "what" if we dont set the other parts??
8165 //printf("xwidget_id %d: in next_element_from_xwidget: FIXME \n", it->xwidget_id);
8166 return 1;
8168 #endif
8171 /* Fill iterator IT with next display element from a stretch glyph
8172 property. IT->object is the value of the text property. Value is
8173 always 1. */
8175 static int
8176 next_element_from_stretch (struct it *it)
8178 it->what = IT_STRETCH;
8179 return 1;
8182 /* Scan backwards from IT's current position until we find a stop
8183 position, or until BEGV. This is called when we find ourself
8184 before both the last known prev_stop and base_level_stop while
8185 reordering bidirectional text. */
8187 static void
8188 compute_stop_pos_backwards (struct it *it)
8190 const int SCAN_BACK_LIMIT = 1000;
8191 struct text_pos pos;
8192 struct display_pos save_current = it->current;
8193 struct text_pos save_position = it->position;
8194 ptrdiff_t charpos = IT_CHARPOS (*it);
8195 ptrdiff_t where_we_are = charpos;
8196 ptrdiff_t save_stop_pos = it->stop_charpos;
8197 ptrdiff_t save_end_pos = it->end_charpos;
8199 eassert (NILP (it->string) && !it->s);
8200 eassert (it->bidi_p);
8201 it->bidi_p = 0;
8204 it->end_charpos = min (charpos + 1, ZV);
8205 charpos = max (charpos - SCAN_BACK_LIMIT, BEGV);
8206 SET_TEXT_POS (pos, charpos, CHAR_TO_BYTE (charpos));
8207 reseat_1 (it, pos, 0);
8208 compute_stop_pos (it);
8209 /* We must advance forward, right? */
8210 if (it->stop_charpos <= charpos)
8211 emacs_abort ();
8213 while (charpos > BEGV && it->stop_charpos >= it->end_charpos);
8215 if (it->stop_charpos <= where_we_are)
8216 it->prev_stop = it->stop_charpos;
8217 else
8218 it->prev_stop = BEGV;
8219 it->bidi_p = true;
8220 it->current = save_current;
8221 it->position = save_position;
8222 it->stop_charpos = save_stop_pos;
8223 it->end_charpos = save_end_pos;
8226 /* Scan forward from CHARPOS in the current buffer/string, until we
8227 find a stop position > current IT's position. Then handle the stop
8228 position before that. This is called when we bump into a stop
8229 position while reordering bidirectional text. CHARPOS should be
8230 the last previously processed stop_pos (or BEGV/0, if none were
8231 processed yet) whose position is less that IT's current
8232 position. */
8234 static void
8235 handle_stop_backwards (struct it *it, ptrdiff_t charpos)
8237 int bufp = !STRINGP (it->string);
8238 ptrdiff_t where_we_are = (bufp ? IT_CHARPOS (*it) : IT_STRING_CHARPOS (*it));
8239 struct display_pos save_current = it->current;
8240 struct text_pos save_position = it->position;
8241 struct text_pos pos1;
8242 ptrdiff_t next_stop;
8244 /* Scan in strict logical order. */
8245 eassert (it->bidi_p);
8246 it->bidi_p = 0;
8249 it->prev_stop = charpos;
8250 if (bufp)
8252 SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos));
8253 reseat_1 (it, pos1, 0);
8255 else
8256 it->current.string_pos = string_pos (charpos, it->string);
8257 compute_stop_pos (it);
8258 /* We must advance forward, right? */
8259 if (it->stop_charpos <= it->prev_stop)
8260 emacs_abort ();
8261 charpos = it->stop_charpos;
8263 while (charpos <= where_we_are);
8265 it->bidi_p = true;
8266 it->current = save_current;
8267 it->position = save_position;
8268 next_stop = it->stop_charpos;
8269 it->stop_charpos = it->prev_stop;
8270 handle_stop (it);
8271 it->stop_charpos = next_stop;
8274 /* Load IT with the next display element from current_buffer. Value
8275 is zero if end of buffer reached. IT->stop_charpos is the next
8276 position at which to stop and check for text properties or buffer
8277 end. */
8279 static int
8280 next_element_from_buffer (struct it *it)
8282 bool success_p = true;
8284 eassert (IT_CHARPOS (*it) >= BEGV);
8285 eassert (NILP (it->string) && !it->s);
8286 eassert (!it->bidi_p
8287 || (EQ (it->bidi_it.string.lstring, Qnil)
8288 && it->bidi_it.string.s == NULL));
8290 /* With bidi reordering, the character to display might not be the
8291 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
8292 we were reseat()ed to a new buffer position, which is potentially
8293 a different paragraph. */
8294 if (it->bidi_p && it->bidi_it.first_elt)
8296 get_visually_first_element (it);
8297 SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8300 if (IT_CHARPOS (*it) >= it->stop_charpos)
8302 if (IT_CHARPOS (*it) >= it->end_charpos)
8304 int overlay_strings_follow_p;
8306 /* End of the game, except when overlay strings follow that
8307 haven't been returned yet. */
8308 if (it->overlay_strings_at_end_processed_p)
8309 overlay_strings_follow_p = 0;
8310 else
8312 it->overlay_strings_at_end_processed_p = true;
8313 overlay_strings_follow_p = get_overlay_strings (it, 0);
8316 if (overlay_strings_follow_p)
8317 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
8318 else
8320 it->what = IT_EOB;
8321 it->position = it->current.pos;
8322 success_p = 0;
8325 else if (!(!it->bidi_p
8326 || BIDI_AT_BASE_LEVEL (it->bidi_it)
8327 || IT_CHARPOS (*it) == it->stop_charpos))
8329 /* With bidi non-linear iteration, we could find ourselves
8330 far beyond the last computed stop_charpos, with several
8331 other stop positions in between that we missed. Scan
8332 them all now, in buffer's logical order, until we find
8333 and handle the last stop_charpos that precedes our
8334 current position. */
8335 handle_stop_backwards (it, it->stop_charpos);
8336 return GET_NEXT_DISPLAY_ELEMENT (it);
8338 else
8340 if (it->bidi_p)
8342 /* Take note of the stop position we just moved across,
8343 for when we will move back across it. */
8344 it->prev_stop = it->stop_charpos;
8345 /* If we are at base paragraph embedding level, take
8346 note of the last stop position seen at this
8347 level. */
8348 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
8349 it->base_level_stop = it->stop_charpos;
8351 handle_stop (it);
8352 return GET_NEXT_DISPLAY_ELEMENT (it);
8355 else if (it->bidi_p
8356 /* If we are before prev_stop, we may have overstepped on
8357 our way backwards a stop_pos, and if so, we need to
8358 handle that stop_pos. */
8359 && IT_CHARPOS (*it) < it->prev_stop
8360 /* We can sometimes back up for reasons that have nothing
8361 to do with bidi reordering. E.g., compositions. The
8362 code below is only needed when we are above the base
8363 embedding level, so test for that explicitly. */
8364 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
8366 if (it->base_level_stop <= 0
8367 || IT_CHARPOS (*it) < it->base_level_stop)
8369 /* If we lost track of base_level_stop, we need to find
8370 prev_stop by looking backwards. This happens, e.g., when
8371 we were reseated to the previous screenful of text by
8372 vertical-motion. */
8373 it->base_level_stop = BEGV;
8374 compute_stop_pos_backwards (it);
8375 handle_stop_backwards (it, it->prev_stop);
8377 else
8378 handle_stop_backwards (it, it->base_level_stop);
8379 return GET_NEXT_DISPLAY_ELEMENT (it);
8381 else
8383 /* No face changes, overlays etc. in sight, so just return a
8384 character from current_buffer. */
8385 unsigned char *p;
8386 ptrdiff_t stop;
8388 /* We moved to the next buffer position, so any info about
8389 previously seen overlays is no longer valid. */
8390 it->ignore_overlay_strings_at_pos_p = 0;
8392 /* Maybe run the redisplay end trigger hook. Performance note:
8393 This doesn't seem to cost measurable time. */
8394 if (it->redisplay_end_trigger_charpos
8395 && it->glyph_row
8396 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
8397 run_redisplay_end_trigger_hook (it);
8399 stop = it->bidi_it.scan_dir < 0 ? -1 : it->end_charpos;
8400 if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it),
8401 stop)
8402 && next_element_from_composition (it))
8404 return 1;
8407 /* Get the next character, maybe multibyte. */
8408 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
8409 if (it->multibyte_p && !ASCII_CHAR_P (*p))
8410 it->c = STRING_CHAR_AND_LENGTH (p, it->len);
8411 else
8412 it->c = *p, it->len = 1;
8414 /* Record what we have and where it came from. */
8415 it->what = IT_CHARACTER;
8416 it->object = it->w->contents;
8417 it->position = it->current.pos;
8419 /* Normally we return the character found above, except when we
8420 really want to return an ellipsis for selective display. */
8421 if (it->selective)
8423 if (it->c == '\n')
8425 /* A value of selective > 0 means hide lines indented more
8426 than that number of columns. */
8427 if (it->selective > 0
8428 && IT_CHARPOS (*it) + 1 < ZV
8429 && indented_beyond_p (IT_CHARPOS (*it) + 1,
8430 IT_BYTEPOS (*it) + 1,
8431 it->selective))
8433 success_p = next_element_from_ellipsis (it);
8434 it->dpvec_char_len = -1;
8437 else if (it->c == '\r' && it->selective == -1)
8439 /* A value of selective == -1 means that everything from the
8440 CR to the end of the line is invisible, with maybe an
8441 ellipsis displayed for it. */
8442 success_p = next_element_from_ellipsis (it);
8443 it->dpvec_char_len = -1;
8448 /* Value is zero if end of buffer reached. */
8449 eassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
8450 return success_p;
8454 /* Run the redisplay end trigger hook for IT. */
8456 static void
8457 run_redisplay_end_trigger_hook (struct it *it)
8459 Lisp_Object args[3];
8461 /* IT->glyph_row should be non-null, i.e. we should be actually
8462 displaying something, or otherwise we should not run the hook. */
8463 eassert (it->glyph_row);
8465 /* Set up hook arguments. */
8466 args[0] = Qredisplay_end_trigger_functions;
8467 args[1] = it->window;
8468 XSETINT (args[2], it->redisplay_end_trigger_charpos);
8469 it->redisplay_end_trigger_charpos = 0;
8471 /* Since we are *trying* to run these functions, don't try to run
8472 them again, even if they get an error. */
8473 wset_redisplay_end_trigger (it->w, Qnil);
8474 Frun_hook_with_args (3, args);
8476 /* Notice if it changed the face of the character we are on. */
8477 handle_face_prop (it);
8481 /* Deliver a composition display element. Unlike the other
8482 next_element_from_XXX, this function is not registered in the array
8483 get_next_element[]. It is called from next_element_from_buffer and
8484 next_element_from_string when necessary. */
8486 static int
8487 next_element_from_composition (struct it *it)
8489 it->what = IT_COMPOSITION;
8490 it->len = it->cmp_it.nbytes;
8491 if (STRINGP (it->string))
8493 if (it->c < 0)
8495 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
8496 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
8497 return 0;
8499 it->position = it->current.string_pos;
8500 it->object = it->string;
8501 it->c = composition_update_it (&it->cmp_it, IT_STRING_CHARPOS (*it),
8502 IT_STRING_BYTEPOS (*it), it->string);
8504 else
8506 if (it->c < 0)
8508 IT_CHARPOS (*it) += it->cmp_it.nchars;
8509 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
8510 if (it->bidi_p)
8512 if (it->bidi_it.new_paragraph)
8513 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
8514 /* Resync the bidi iterator with IT's new position.
8515 FIXME: this doesn't support bidirectional text. */
8516 while (it->bidi_it.charpos < IT_CHARPOS (*it))
8517 bidi_move_to_visually_next (&it->bidi_it);
8519 return 0;
8521 it->position = it->current.pos;
8522 it->object = it->w->contents;
8523 it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
8524 IT_BYTEPOS (*it), Qnil);
8526 return 1;
8531 /***********************************************************************
8532 Moving an iterator without producing glyphs
8533 ***********************************************************************/
8535 /* Check if iterator is at a position corresponding to a valid buffer
8536 position after some move_it_ call. */
8538 #define IT_POS_VALID_AFTER_MOVE_P(it) \
8539 ((it)->method == GET_FROM_STRING \
8540 ? IT_STRING_CHARPOS (*it) == 0 \
8541 : 1)
8544 /* Move iterator IT to a specified buffer or X position within one
8545 line on the display without producing glyphs.
8547 OP should be a bit mask including some or all of these bits:
8548 MOVE_TO_X: Stop upon reaching x-position TO_X.
8549 MOVE_TO_POS: Stop upon reaching buffer or string position TO_CHARPOS.
8550 Regardless of OP's value, stop upon reaching the end of the display line.
8552 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
8553 This means, in particular, that TO_X includes window's horizontal
8554 scroll amount.
8556 The return value has several possible values that
8557 say what condition caused the scan to stop:
8559 MOVE_POS_MATCH_OR_ZV
8560 - when TO_POS or ZV was reached.
8562 MOVE_X_REACHED
8563 -when TO_X was reached before TO_POS or ZV were reached.
8565 MOVE_LINE_CONTINUED
8566 - when we reached the end of the display area and the line must
8567 be continued.
8569 MOVE_LINE_TRUNCATED
8570 - when we reached the end of the display area and the line is
8571 truncated.
8573 MOVE_NEWLINE_OR_CR
8574 - when we stopped at a line end, i.e. a newline or a CR and selective
8575 display is on. */
8577 static enum move_it_result
8578 move_it_in_display_line_to (struct it *it,
8579 ptrdiff_t to_charpos, int to_x,
8580 enum move_operation_enum op)
8582 enum move_it_result result = MOVE_UNDEFINED;
8583 struct glyph_row *saved_glyph_row;
8584 struct it wrap_it, atpos_it, atx_it, ppos_it;
8585 void *wrap_data = NULL, *atpos_data = NULL, *atx_data = NULL;
8586 void *ppos_data = NULL;
8587 int may_wrap = 0;
8588 enum it_method prev_method = it->method;
8589 ptrdiff_t closest_pos IF_LINT (= 0), prev_pos = IT_CHARPOS (*it);
8590 int saw_smaller_pos = prev_pos < to_charpos;
8592 /* Don't produce glyphs in produce_glyphs. */
8593 saved_glyph_row = it->glyph_row;
8594 it->glyph_row = NULL;
8596 /* Use wrap_it to save a copy of IT wherever a word wrap could
8597 occur. Use atpos_it to save a copy of IT at the desired buffer
8598 position, if found, so that we can scan ahead and check if the
8599 word later overshoots the window edge. Use atx_it similarly, for
8600 pixel positions. */
8601 wrap_it.sp = -1;
8602 atpos_it.sp = -1;
8603 atx_it.sp = -1;
8605 /* Use ppos_it under bidi reordering to save a copy of IT for the
8606 initial position. We restore that position in IT when we have
8607 scanned the entire display line without finding a match for
8608 TO_CHARPOS and all the character positions are greater than
8609 TO_CHARPOS. We then restart the scan from the initial position,
8610 and stop at CLOSEST_POS, which is a position > TO_CHARPOS that is
8611 the closest to TO_CHARPOS. */
8612 if (it->bidi_p)
8614 if ((op & MOVE_TO_POS) && IT_CHARPOS (*it) >= to_charpos)
8616 SAVE_IT (ppos_it, *it, ppos_data);
8617 closest_pos = IT_CHARPOS (*it);
8619 else
8620 closest_pos = ZV;
8623 #define BUFFER_POS_REACHED_P() \
8624 ((op & MOVE_TO_POS) != 0 \
8625 && BUFFERP (it->object) \
8626 && (IT_CHARPOS (*it) == to_charpos \
8627 || ((!it->bidi_p \
8628 || BIDI_AT_BASE_LEVEL (it->bidi_it)) \
8629 && IT_CHARPOS (*it) > to_charpos) \
8630 || (it->what == IT_COMPOSITION \
8631 && ((IT_CHARPOS (*it) > to_charpos \
8632 && to_charpos >= it->cmp_it.charpos) \
8633 || (IT_CHARPOS (*it) < to_charpos \
8634 && to_charpos <= it->cmp_it.charpos)))) \
8635 && (it->method == GET_FROM_BUFFER \
8636 || (it->method == GET_FROM_DISPLAY_VECTOR \
8637 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
8639 /* If there's a line-/wrap-prefix, handle it. */
8640 if (it->hpos == 0 && it->method == GET_FROM_BUFFER
8641 && it->current_y < it->last_visible_y)
8642 handle_line_prefix (it);
8644 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8645 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8647 while (1)
8649 int x, i, ascent = 0, descent = 0;
8651 /* Utility macro to reset an iterator with x, ascent, and descent. */
8652 #define IT_RESET_X_ASCENT_DESCENT(IT) \
8653 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
8654 (IT)->max_descent = descent)
8656 /* Stop if we move beyond TO_CHARPOS (after an image or a
8657 display string or stretch glyph). */
8658 if ((op & MOVE_TO_POS) != 0
8659 && BUFFERP (it->object)
8660 && it->method == GET_FROM_BUFFER
8661 && (((!it->bidi_p
8662 /* When the iterator is at base embedding level, we
8663 are guaranteed that characters are delivered for
8664 display in strictly increasing order of their
8665 buffer positions. */
8666 || BIDI_AT_BASE_LEVEL (it->bidi_it))
8667 && IT_CHARPOS (*it) > to_charpos)
8668 || (it->bidi_p
8669 && (prev_method == GET_FROM_IMAGE
8670 || prev_method == GET_FROM_STRETCH
8671 || prev_method == GET_FROM_STRING)
8672 /* Passed TO_CHARPOS from left to right. */
8673 && ((prev_pos < to_charpos
8674 && IT_CHARPOS (*it) > to_charpos)
8675 /* Passed TO_CHARPOS from right to left. */
8676 || (prev_pos > to_charpos
8677 && IT_CHARPOS (*it) < to_charpos)))))
8679 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8681 result = MOVE_POS_MATCH_OR_ZV;
8682 break;
8684 else if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8685 /* If wrap_it is valid, the current position might be in a
8686 word that is wrapped. So, save the iterator in
8687 atpos_it and continue to see if wrapping happens. */
8688 SAVE_IT (atpos_it, *it, atpos_data);
8691 /* Stop when ZV reached.
8692 We used to stop here when TO_CHARPOS reached as well, but that is
8693 too soon if this glyph does not fit on this line. So we handle it
8694 explicitly below. */
8695 if (!get_next_display_element (it))
8697 result = MOVE_POS_MATCH_OR_ZV;
8698 break;
8701 if (it->line_wrap == TRUNCATE)
8703 if (BUFFER_POS_REACHED_P ())
8705 result = MOVE_POS_MATCH_OR_ZV;
8706 break;
8709 else
8711 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
8713 if (IT_DISPLAYING_WHITESPACE (it))
8714 may_wrap = 1;
8715 else if (may_wrap)
8717 /* We have reached a glyph that follows one or more
8718 whitespace characters. If the position is
8719 already found, we are done. */
8720 if (atpos_it.sp >= 0)
8722 RESTORE_IT (it, &atpos_it, atpos_data);
8723 result = MOVE_POS_MATCH_OR_ZV;
8724 goto done;
8726 if (atx_it.sp >= 0)
8728 RESTORE_IT (it, &atx_it, atx_data);
8729 result = MOVE_X_REACHED;
8730 goto done;
8732 /* Otherwise, we can wrap here. */
8733 SAVE_IT (wrap_it, *it, wrap_data);
8734 may_wrap = 0;
8739 /* Remember the line height for the current line, in case
8740 the next element doesn't fit on the line. */
8741 ascent = it->max_ascent;
8742 descent = it->max_descent;
8744 /* The call to produce_glyphs will get the metrics of the
8745 display element IT is loaded with. Record the x-position
8746 before this display element, in case it doesn't fit on the
8747 line. */
8748 x = it->current_x;
8750 PRODUCE_GLYPHS (it);
8752 if (it->area != TEXT_AREA)
8754 prev_method = it->method;
8755 if (it->method == GET_FROM_BUFFER)
8756 prev_pos = IT_CHARPOS (*it);
8757 set_iterator_to_next (it, 1);
8758 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8759 SET_TEXT_POS (this_line_min_pos,
8760 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8761 if (it->bidi_p
8762 && (op & MOVE_TO_POS)
8763 && IT_CHARPOS (*it) > to_charpos
8764 && IT_CHARPOS (*it) < closest_pos)
8765 closest_pos = IT_CHARPOS (*it);
8766 continue;
8769 /* The number of glyphs we get back in IT->nglyphs will normally
8770 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
8771 character on a terminal frame, or (iii) a line end. For the
8772 second case, IT->nglyphs - 1 padding glyphs will be present.
8773 (On X frames, there is only one glyph produced for a
8774 composite character.)
8776 The behavior implemented below means, for continuation lines,
8777 that as many spaces of a TAB as fit on the current line are
8778 displayed there. For terminal frames, as many glyphs of a
8779 multi-glyph character are displayed in the current line, too.
8780 This is what the old redisplay code did, and we keep it that
8781 way. Under X, the whole shape of a complex character must
8782 fit on the line or it will be completely displayed in the
8783 next line.
8785 Note that both for tabs and padding glyphs, all glyphs have
8786 the same width. */
8787 if (it->nglyphs)
8789 /* More than one glyph or glyph doesn't fit on line. All
8790 glyphs have the same width. */
8791 int single_glyph_width = it->pixel_width / it->nglyphs;
8792 int new_x;
8793 int x_before_this_char = x;
8794 int hpos_before_this_char = it->hpos;
8796 for (i = 0; i < it->nglyphs; ++i, x = new_x)
8798 new_x = x + single_glyph_width;
8800 /* We want to leave anything reaching TO_X to the caller. */
8801 if ((op & MOVE_TO_X) && new_x > to_x)
8803 if (BUFFER_POS_REACHED_P ())
8805 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8806 goto buffer_pos_reached;
8807 if (atpos_it.sp < 0)
8809 SAVE_IT (atpos_it, *it, atpos_data);
8810 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8813 else
8815 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8817 it->current_x = x;
8818 result = MOVE_X_REACHED;
8819 break;
8821 if (atx_it.sp < 0)
8823 SAVE_IT (atx_it, *it, atx_data);
8824 IT_RESET_X_ASCENT_DESCENT (&atx_it);
8829 if (/* Lines are continued. */
8830 it->line_wrap != TRUNCATE
8831 && (/* And glyph doesn't fit on the line. */
8832 new_x > it->last_visible_x
8833 /* Or it fits exactly and we're on a window
8834 system frame. */
8835 || (new_x == it->last_visible_x
8836 && FRAME_WINDOW_P (it->f)
8837 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
8838 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8839 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
8841 if (/* IT->hpos == 0 means the very first glyph
8842 doesn't fit on the line, e.g. a wide image. */
8843 it->hpos == 0
8844 || (new_x == it->last_visible_x
8845 && FRAME_WINDOW_P (it->f)))
8847 ++it->hpos;
8848 it->current_x = new_x;
8850 /* The character's last glyph just barely fits
8851 in this row. */
8852 if (i == it->nglyphs - 1)
8854 /* If this is the destination position,
8855 return a position *before* it in this row,
8856 now that we know it fits in this row. */
8857 if (BUFFER_POS_REACHED_P ())
8859 if (it->line_wrap != WORD_WRAP
8860 || wrap_it.sp < 0)
8862 it->hpos = hpos_before_this_char;
8863 it->current_x = x_before_this_char;
8864 result = MOVE_POS_MATCH_OR_ZV;
8865 break;
8867 if (it->line_wrap == WORD_WRAP
8868 && atpos_it.sp < 0)
8870 SAVE_IT (atpos_it, *it, atpos_data);
8871 atpos_it.current_x = x_before_this_char;
8872 atpos_it.hpos = hpos_before_this_char;
8876 prev_method = it->method;
8877 if (it->method == GET_FROM_BUFFER)
8878 prev_pos = IT_CHARPOS (*it);
8879 set_iterator_to_next (it, 1);
8880 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8881 SET_TEXT_POS (this_line_min_pos,
8882 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8883 /* On graphical terminals, newlines may
8884 "overflow" into the fringe if
8885 overflow-newline-into-fringe is non-nil.
8886 On text terminals, and on graphical
8887 terminals with no right margin, newlines
8888 may overflow into the last glyph on the
8889 display line.*/
8890 if (!FRAME_WINDOW_P (it->f)
8891 || ((it->bidi_p
8892 && it->bidi_it.paragraph_dir == R2L)
8893 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8894 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
8895 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8897 if (!get_next_display_element (it))
8899 result = MOVE_POS_MATCH_OR_ZV;
8900 break;
8902 if (BUFFER_POS_REACHED_P ())
8904 if (ITERATOR_AT_END_OF_LINE_P (it))
8905 result = MOVE_POS_MATCH_OR_ZV;
8906 else
8907 result = MOVE_LINE_CONTINUED;
8908 break;
8910 if (ITERATOR_AT_END_OF_LINE_P (it)
8911 && (it->line_wrap != WORD_WRAP
8912 || wrap_it.sp < 0
8913 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)))
8915 result = MOVE_NEWLINE_OR_CR;
8916 break;
8921 else
8922 IT_RESET_X_ASCENT_DESCENT (it);
8924 if (wrap_it.sp >= 0)
8926 RESTORE_IT (it, &wrap_it, wrap_data);
8927 atpos_it.sp = -1;
8928 atx_it.sp = -1;
8931 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
8932 IT_CHARPOS (*it)));
8933 result = MOVE_LINE_CONTINUED;
8934 break;
8937 if (BUFFER_POS_REACHED_P ())
8939 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8940 goto buffer_pos_reached;
8941 if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8943 SAVE_IT (atpos_it, *it, atpos_data);
8944 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8948 if (new_x > it->first_visible_x)
8950 /* Glyph is visible. Increment number of glyphs that
8951 would be displayed. */
8952 ++it->hpos;
8956 if (result != MOVE_UNDEFINED)
8957 break;
8959 else if (BUFFER_POS_REACHED_P ())
8961 buffer_pos_reached:
8962 IT_RESET_X_ASCENT_DESCENT (it);
8963 result = MOVE_POS_MATCH_OR_ZV;
8964 break;
8966 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
8968 /* Stop when TO_X specified and reached. This check is
8969 necessary here because of lines consisting of a line end,
8970 only. The line end will not produce any glyphs and we
8971 would never get MOVE_X_REACHED. */
8972 eassert (it->nglyphs == 0);
8973 result = MOVE_X_REACHED;
8974 break;
8977 /* Is this a line end? If yes, we're done. */
8978 if (ITERATOR_AT_END_OF_LINE_P (it))
8980 /* If we are past TO_CHARPOS, but never saw any character
8981 positions smaller than TO_CHARPOS, return
8982 MOVE_POS_MATCH_OR_ZV, like the unidirectional display
8983 did. */
8984 if (it->bidi_p && (op & MOVE_TO_POS) != 0)
8986 if (!saw_smaller_pos && IT_CHARPOS (*it) > to_charpos)
8988 if (closest_pos < ZV)
8990 RESTORE_IT (it, &ppos_it, ppos_data);
8991 /* Don't recurse if closest_pos is equal to
8992 to_charpos, since we have just tried that. */
8993 if (closest_pos != to_charpos)
8994 move_it_in_display_line_to (it, closest_pos, -1,
8995 MOVE_TO_POS);
8996 result = MOVE_POS_MATCH_OR_ZV;
8998 else
8999 goto buffer_pos_reached;
9001 else if (it->line_wrap == WORD_WRAP && atpos_it.sp >= 0
9002 && IT_CHARPOS (*it) > to_charpos)
9003 goto buffer_pos_reached;
9004 else
9005 result = MOVE_NEWLINE_OR_CR;
9007 else
9008 result = MOVE_NEWLINE_OR_CR;
9009 break;
9012 prev_method = it->method;
9013 if (it->method == GET_FROM_BUFFER)
9014 prev_pos = IT_CHARPOS (*it);
9015 /* The current display element has been consumed. Advance
9016 to the next. */
9017 set_iterator_to_next (it, 1);
9018 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
9019 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
9020 if (IT_CHARPOS (*it) < to_charpos)
9021 saw_smaller_pos = 1;
9022 if (it->bidi_p
9023 && (op & MOVE_TO_POS)
9024 && IT_CHARPOS (*it) >= to_charpos
9025 && IT_CHARPOS (*it) < closest_pos)
9026 closest_pos = IT_CHARPOS (*it);
9028 /* Stop if lines are truncated and IT's current x-position is
9029 past the right edge of the window now. */
9030 if (it->line_wrap == TRUNCATE
9031 && it->current_x >= it->last_visible_x)
9033 if (!FRAME_WINDOW_P (it->f)
9034 || ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
9035 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
9036 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
9037 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
9039 int at_eob_p = 0;
9041 if ((at_eob_p = !get_next_display_element (it))
9042 || BUFFER_POS_REACHED_P ()
9043 /* If we are past TO_CHARPOS, but never saw any
9044 character positions smaller than TO_CHARPOS,
9045 return MOVE_POS_MATCH_OR_ZV, like the
9046 unidirectional display did. */
9047 || (it->bidi_p && (op & MOVE_TO_POS) != 0
9048 && !saw_smaller_pos
9049 && IT_CHARPOS (*it) > to_charpos))
9051 if (it->bidi_p
9052 && !BUFFER_POS_REACHED_P ()
9053 && !at_eob_p && closest_pos < ZV)
9055 RESTORE_IT (it, &ppos_it, ppos_data);
9056 if (closest_pos != to_charpos)
9057 move_it_in_display_line_to (it, closest_pos, -1,
9058 MOVE_TO_POS);
9060 result = MOVE_POS_MATCH_OR_ZV;
9061 break;
9063 if (ITERATOR_AT_END_OF_LINE_P (it))
9065 result = MOVE_NEWLINE_OR_CR;
9066 break;
9069 else if (it->bidi_p && (op & MOVE_TO_POS) != 0
9070 && !saw_smaller_pos
9071 && IT_CHARPOS (*it) > to_charpos)
9073 if (closest_pos < ZV)
9075 RESTORE_IT (it, &ppos_it, ppos_data);
9076 if (closest_pos != to_charpos)
9077 move_it_in_display_line_to (it, closest_pos, -1,
9078 MOVE_TO_POS);
9080 result = MOVE_POS_MATCH_OR_ZV;
9081 break;
9083 result = MOVE_LINE_TRUNCATED;
9084 break;
9086 #undef IT_RESET_X_ASCENT_DESCENT
9089 #undef BUFFER_POS_REACHED_P
9091 /* If we scanned beyond to_pos and didn't find a point to wrap at,
9092 restore the saved iterator. */
9093 if (atpos_it.sp >= 0)
9094 RESTORE_IT (it, &atpos_it, atpos_data);
9095 else if (atx_it.sp >= 0)
9096 RESTORE_IT (it, &atx_it, atx_data);
9098 done:
9100 if (atpos_data)
9101 bidi_unshelve_cache (atpos_data, 1);
9102 if (atx_data)
9103 bidi_unshelve_cache (atx_data, 1);
9104 if (wrap_data)
9105 bidi_unshelve_cache (wrap_data, 1);
9106 if (ppos_data)
9107 bidi_unshelve_cache (ppos_data, 1);
9109 /* Restore the iterator settings altered at the beginning of this
9110 function. */
9111 it->glyph_row = saved_glyph_row;
9112 return result;
9115 /* For external use. */
9116 void
9117 move_it_in_display_line (struct it *it,
9118 ptrdiff_t to_charpos, int to_x,
9119 enum move_operation_enum op)
9121 if (it->line_wrap == WORD_WRAP
9122 && (op & MOVE_TO_X))
9124 struct it save_it;
9125 void *save_data = NULL;
9126 int skip;
9128 SAVE_IT (save_it, *it, save_data);
9129 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
9130 /* When word-wrap is on, TO_X may lie past the end
9131 of a wrapped line. Then it->current is the
9132 character on the next line, so backtrack to the
9133 space before the wrap point. */
9134 if (skip == MOVE_LINE_CONTINUED)
9136 int prev_x = max (it->current_x - 1, 0);
9137 RESTORE_IT (it, &save_it, save_data);
9138 move_it_in_display_line_to
9139 (it, -1, prev_x, MOVE_TO_X);
9141 else
9142 bidi_unshelve_cache (save_data, 1);
9144 else
9145 move_it_in_display_line_to (it, to_charpos, to_x, op);
9149 /* Move IT forward until it satisfies one or more of the criteria in
9150 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
9152 OP is a bit-mask that specifies where to stop, and in particular,
9153 which of those four position arguments makes a difference. See the
9154 description of enum move_operation_enum.
9156 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
9157 screen line, this function will set IT to the next position that is
9158 displayed to the right of TO_CHARPOS on the screen.
9160 Return the maximum pixel length of any line scanned but never more
9161 than it.last_visible_x. */
9164 move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos, int op)
9166 enum move_it_result skip, skip2 = MOVE_X_REACHED;
9167 int line_height, line_start_x = 0, reached = 0;
9168 int max_current_x = 0;
9169 void *backup_data = NULL;
9171 for (;;)
9173 if (op & MOVE_TO_VPOS)
9175 /* If no TO_CHARPOS and no TO_X specified, stop at the
9176 start of the line TO_VPOS. */
9177 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
9179 if (it->vpos == to_vpos)
9181 reached = 1;
9182 break;
9184 else
9185 skip = move_it_in_display_line_to (it, -1, -1, 0);
9187 else
9189 /* TO_VPOS >= 0 means stop at TO_X in the line at
9190 TO_VPOS, or at TO_POS, whichever comes first. */
9191 if (it->vpos == to_vpos)
9193 reached = 2;
9194 break;
9197 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
9199 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
9201 reached = 3;
9202 break;
9204 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
9206 /* We have reached TO_X but not in the line we want. */
9207 skip = move_it_in_display_line_to (it, to_charpos,
9208 -1, MOVE_TO_POS);
9209 if (skip == MOVE_POS_MATCH_OR_ZV)
9211 reached = 4;
9212 break;
9217 else if (op & MOVE_TO_Y)
9219 struct it it_backup;
9221 if (it->line_wrap == WORD_WRAP)
9222 SAVE_IT (it_backup, *it, backup_data);
9224 /* TO_Y specified means stop at TO_X in the line containing
9225 TO_Y---or at TO_CHARPOS if this is reached first. The
9226 problem is that we can't really tell whether the line
9227 contains TO_Y before we have completely scanned it, and
9228 this may skip past TO_X. What we do is to first scan to
9229 TO_X.
9231 If TO_X is not specified, use a TO_X of zero. The reason
9232 is to make the outcome of this function more predictable.
9233 If we didn't use TO_X == 0, we would stop at the end of
9234 the line which is probably not what a caller would expect
9235 to happen. */
9236 skip = move_it_in_display_line_to
9237 (it, to_charpos, ((op & MOVE_TO_X) ? to_x : 0),
9238 (MOVE_TO_X | (op & MOVE_TO_POS)));
9240 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
9241 if (skip == MOVE_POS_MATCH_OR_ZV)
9242 reached = 5;
9243 else if (skip == MOVE_X_REACHED)
9245 /* If TO_X was reached, we want to know whether TO_Y is
9246 in the line. We know this is the case if the already
9247 scanned glyphs make the line tall enough. Otherwise,
9248 we must check by scanning the rest of the line. */
9249 line_height = it->max_ascent + it->max_descent;
9250 if (to_y >= it->current_y
9251 && to_y < it->current_y + line_height)
9253 reached = 6;
9254 break;
9256 SAVE_IT (it_backup, *it, backup_data);
9257 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
9258 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
9259 op & MOVE_TO_POS);
9260 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
9261 line_height = it->max_ascent + it->max_descent;
9262 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
9264 if (to_y >= it->current_y
9265 && to_y < it->current_y + line_height)
9267 /* If TO_Y is in this line and TO_X was reached
9268 above, we scanned too far. We have to restore
9269 IT's settings to the ones before skipping. But
9270 keep the more accurate values of max_ascent and
9271 max_descent we've found while skipping the rest
9272 of the line, for the sake of callers, such as
9273 pos_visible_p, that need to know the line
9274 height. */
9275 int max_ascent = it->max_ascent;
9276 int max_descent = it->max_descent;
9278 RESTORE_IT (it, &it_backup, backup_data);
9279 it->max_ascent = max_ascent;
9280 it->max_descent = max_descent;
9281 reached = 6;
9283 else
9285 skip = skip2;
9286 if (skip == MOVE_POS_MATCH_OR_ZV)
9287 reached = 7;
9290 else
9292 /* Check whether TO_Y is in this line. */
9293 line_height = it->max_ascent + it->max_descent;
9294 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
9296 if (to_y >= it->current_y
9297 && to_y < it->current_y + line_height)
9299 if (to_y > it->current_y)
9300 max_current_x = max (it->current_x, max_current_x);
9302 /* When word-wrap is on, TO_X may lie past the end
9303 of a wrapped line. Then it->current is the
9304 character on the next line, so backtrack to the
9305 space before the wrap point. */
9306 if (skip == MOVE_LINE_CONTINUED
9307 && it->line_wrap == WORD_WRAP)
9309 int prev_x = max (it->current_x - 1, 0);
9310 RESTORE_IT (it, &it_backup, backup_data);
9311 skip = move_it_in_display_line_to
9312 (it, -1, prev_x, MOVE_TO_X);
9315 reached = 6;
9319 if (reached)
9321 max_current_x = max (it->current_x, max_current_x);
9322 break;
9325 else if (BUFFERP (it->object)
9326 && (it->method == GET_FROM_BUFFER
9327 || it->method == GET_FROM_STRETCH)
9328 && IT_CHARPOS (*it) >= to_charpos
9329 /* Under bidi iteration, a call to set_iterator_to_next
9330 can scan far beyond to_charpos if the initial
9331 portion of the next line needs to be reordered. In
9332 that case, give move_it_in_display_line_to another
9333 chance below. */
9334 && !(it->bidi_p
9335 && it->bidi_it.scan_dir == -1))
9336 skip = MOVE_POS_MATCH_OR_ZV;
9337 else
9338 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
9340 switch (skip)
9342 case MOVE_POS_MATCH_OR_ZV:
9343 max_current_x = max (it->current_x, max_current_x);
9344 reached = 8;
9345 goto out;
9347 case MOVE_NEWLINE_OR_CR:
9348 max_current_x = max (it->current_x, max_current_x);
9349 set_iterator_to_next (it, 1);
9350 it->continuation_lines_width = 0;
9351 break;
9353 case MOVE_LINE_TRUNCATED:
9354 max_current_x = it->last_visible_x;
9355 it->continuation_lines_width = 0;
9356 reseat_at_next_visible_line_start (it, 0);
9357 if ((op & MOVE_TO_POS) != 0
9358 && IT_CHARPOS (*it) > to_charpos)
9360 reached = 9;
9361 goto out;
9363 break;
9365 case MOVE_LINE_CONTINUED:
9366 max_current_x = it->last_visible_x;
9367 /* For continued lines ending in a tab, some of the glyphs
9368 associated with the tab are displayed on the current
9369 line. Since it->current_x does not include these glyphs,
9370 we use it->last_visible_x instead. */
9371 if (it->c == '\t')
9373 it->continuation_lines_width += it->last_visible_x;
9374 /* When moving by vpos, ensure that the iterator really
9375 advances to the next line (bug#847, bug#969). Fixme:
9376 do we need to do this in other circumstances? */
9377 if (it->current_x != it->last_visible_x
9378 && (op & MOVE_TO_VPOS)
9379 && !(op & (MOVE_TO_X | MOVE_TO_POS)))
9381 line_start_x = it->current_x + it->pixel_width
9382 - it->last_visible_x;
9383 if (FRAME_WINDOW_P (it->f))
9385 struct face *face = FACE_FROM_ID (it->f, it->face_id);
9386 struct font *face_font = face->font;
9388 /* When display_line produces a continued line
9389 that ends in a TAB, it skips a tab stop that
9390 is closer than the font's space character
9391 width (see x_produce_glyphs where it produces
9392 the stretch glyph which represents a TAB).
9393 We need to reproduce the same logic here. */
9394 eassert (face_font);
9395 if (face_font)
9397 if (line_start_x < face_font->space_width)
9398 line_start_x
9399 += it->tab_width * face_font->space_width;
9402 set_iterator_to_next (it, 0);
9405 else
9406 it->continuation_lines_width += it->current_x;
9407 break;
9409 default:
9410 emacs_abort ();
9413 /* Reset/increment for the next run. */
9414 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
9415 it->current_x = line_start_x;
9416 line_start_x = 0;
9417 it->hpos = 0;
9418 it->current_y += it->max_ascent + it->max_descent;
9419 ++it->vpos;
9420 last_height = it->max_ascent + it->max_descent;
9421 it->max_ascent = it->max_descent = 0;
9424 out:
9426 /* On text terminals, we may stop at the end of a line in the middle
9427 of a multi-character glyph. If the glyph itself is continued,
9428 i.e. it is actually displayed on the next line, don't treat this
9429 stopping point as valid; move to the next line instead (unless
9430 that brings us offscreen). */
9431 if (!FRAME_WINDOW_P (it->f)
9432 && op & MOVE_TO_POS
9433 && IT_CHARPOS (*it) == to_charpos
9434 && it->what == IT_CHARACTER
9435 && it->nglyphs > 1
9436 && it->line_wrap == WINDOW_WRAP
9437 && it->current_x == it->last_visible_x - 1
9438 && it->c != '\n'
9439 && it->c != '\t'
9440 && it->vpos < it->w->window_end_vpos)
9442 it->continuation_lines_width += it->current_x;
9443 it->current_x = it->hpos = it->max_ascent = it->max_descent = 0;
9444 it->current_y += it->max_ascent + it->max_descent;
9445 ++it->vpos;
9446 last_height = it->max_ascent + it->max_descent;
9449 if (backup_data)
9450 bidi_unshelve_cache (backup_data, 1);
9452 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
9454 return max_current_x;
9458 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
9460 If DY > 0, move IT backward at least that many pixels. DY = 0
9461 means move IT backward to the preceding line start or BEGV. This
9462 function may move over more than DY pixels if IT->current_y - DY
9463 ends up in the middle of a line; in this case IT->current_y will be
9464 set to the top of the line moved to. */
9466 void
9467 move_it_vertically_backward (struct it *it, int dy)
9469 int nlines, h;
9470 struct it it2, it3;
9471 void *it2data = NULL, *it3data = NULL;
9472 ptrdiff_t start_pos;
9473 int nchars_per_row
9474 = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
9475 ptrdiff_t pos_limit;
9477 move_further_back:
9478 eassert (dy >= 0);
9480 start_pos = IT_CHARPOS (*it);
9482 /* Estimate how many newlines we must move back. */
9483 nlines = max (1, dy / default_line_pixel_height (it->w));
9484 if (it->line_wrap == TRUNCATE || nchars_per_row == 0)
9485 pos_limit = BEGV;
9486 else
9487 pos_limit = max (start_pos - nlines * nchars_per_row, BEGV);
9489 /* Set the iterator's position that many lines back. But don't go
9490 back more than NLINES full screen lines -- this wins a day with
9491 buffers which have very long lines. */
9492 while (nlines-- && IT_CHARPOS (*it) > pos_limit)
9493 back_to_previous_visible_line_start (it);
9495 /* Reseat the iterator here. When moving backward, we don't want
9496 reseat to skip forward over invisible text, set up the iterator
9497 to deliver from overlay strings at the new position etc. So,
9498 use reseat_1 here. */
9499 reseat_1 (it, it->current.pos, 1);
9501 /* We are now surely at a line start. */
9502 it->current_x = it->hpos = 0; /* FIXME: this is incorrect when bidi
9503 reordering is in effect. */
9504 it->continuation_lines_width = 0;
9506 /* Move forward and see what y-distance we moved. First move to the
9507 start of the next line so that we get its height. We need this
9508 height to be able to tell whether we reached the specified
9509 y-distance. */
9510 SAVE_IT (it2, *it, it2data);
9511 it2.max_ascent = it2.max_descent = 0;
9514 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
9515 MOVE_TO_POS | MOVE_TO_VPOS);
9517 while (!(IT_POS_VALID_AFTER_MOVE_P (&it2)
9518 /* If we are in a display string which starts at START_POS,
9519 and that display string includes a newline, and we are
9520 right after that newline (i.e. at the beginning of a
9521 display line), exit the loop, because otherwise we will
9522 infloop, since move_it_to will see that it is already at
9523 START_POS and will not move. */
9524 || (it2.method == GET_FROM_STRING
9525 && IT_CHARPOS (it2) == start_pos
9526 && SREF (it2.string, IT_STRING_BYTEPOS (it2) - 1) == '\n')));
9527 eassert (IT_CHARPOS (*it) >= BEGV);
9528 SAVE_IT (it3, it2, it3data);
9530 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
9531 eassert (IT_CHARPOS (*it) >= BEGV);
9532 /* H is the actual vertical distance from the position in *IT
9533 and the starting position. */
9534 h = it2.current_y - it->current_y;
9535 /* NLINES is the distance in number of lines. */
9536 nlines = it2.vpos - it->vpos;
9538 /* Correct IT's y and vpos position
9539 so that they are relative to the starting point. */
9540 it->vpos -= nlines;
9541 it->current_y -= h;
9543 if (dy == 0)
9545 /* DY == 0 means move to the start of the screen line. The
9546 value of nlines is > 0 if continuation lines were involved,
9547 or if the original IT position was at start of a line. */
9548 RESTORE_IT (it, it, it2data);
9549 if (nlines > 0)
9550 move_it_by_lines (it, nlines);
9551 /* The above code moves us to some position NLINES down,
9552 usually to its first glyph (leftmost in an L2R line), but
9553 that's not necessarily the start of the line, under bidi
9554 reordering. We want to get to the character position
9555 that is immediately after the newline of the previous
9556 line. */
9557 if (it->bidi_p
9558 && !it->continuation_lines_width
9559 && !STRINGP (it->string)
9560 && IT_CHARPOS (*it) > BEGV
9561 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9563 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
9565 DEC_BOTH (cp, bp);
9566 cp = find_newline_no_quit (cp, bp, -1, NULL);
9567 move_it_to (it, cp, -1, -1, -1, MOVE_TO_POS);
9569 bidi_unshelve_cache (it3data, 1);
9571 else
9573 /* The y-position we try to reach, relative to *IT.
9574 Note that H has been subtracted in front of the if-statement. */
9575 int target_y = it->current_y + h - dy;
9576 int y0 = it3.current_y;
9577 int y1;
9578 int line_height;
9580 RESTORE_IT (&it3, &it3, it3data);
9581 y1 = line_bottom_y (&it3);
9582 line_height = y1 - y0;
9583 RESTORE_IT (it, it, it2data);
9584 /* If we did not reach target_y, try to move further backward if
9585 we can. If we moved too far backward, try to move forward. */
9586 if (target_y < it->current_y
9587 /* This is heuristic. In a window that's 3 lines high, with
9588 a line height of 13 pixels each, recentering with point
9589 on the bottom line will try to move -39/2 = 19 pixels
9590 backward. Try to avoid moving into the first line. */
9591 && (it->current_y - target_y
9592 > min (window_box_height (it->w), line_height * 2 / 3))
9593 && IT_CHARPOS (*it) > BEGV)
9595 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
9596 target_y - it->current_y));
9597 dy = it->current_y - target_y;
9598 goto move_further_back;
9600 else if (target_y >= it->current_y + line_height
9601 && IT_CHARPOS (*it) < ZV)
9603 /* Should move forward by at least one line, maybe more.
9605 Note: Calling move_it_by_lines can be expensive on
9606 terminal frames, where compute_motion is used (via
9607 vmotion) to do the job, when there are very long lines
9608 and truncate-lines is nil. That's the reason for
9609 treating terminal frames specially here. */
9611 if (!FRAME_WINDOW_P (it->f))
9612 move_it_vertically (it, target_y - (it->current_y + line_height));
9613 else
9617 move_it_by_lines (it, 1);
9619 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
9626 /* Move IT by a specified amount of pixel lines DY. DY negative means
9627 move backwards. DY = 0 means move to start of screen line. At the
9628 end, IT will be on the start of a screen line. */
9630 void
9631 move_it_vertically (struct it *it, int dy)
9633 if (dy <= 0)
9634 move_it_vertically_backward (it, -dy);
9635 else
9637 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
9638 move_it_to (it, ZV, -1, it->current_y + dy, -1,
9639 MOVE_TO_POS | MOVE_TO_Y);
9640 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
9642 /* If buffer ends in ZV without a newline, move to the start of
9643 the line to satisfy the post-condition. */
9644 if (IT_CHARPOS (*it) == ZV
9645 && ZV > BEGV
9646 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9647 move_it_by_lines (it, 0);
9652 /* Move iterator IT past the end of the text line it is in. */
9654 void
9655 move_it_past_eol (struct it *it)
9657 enum move_it_result rc;
9659 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
9660 if (rc == MOVE_NEWLINE_OR_CR)
9661 set_iterator_to_next (it, 0);
9665 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
9666 negative means move up. DVPOS == 0 means move to the start of the
9667 screen line.
9669 Optimization idea: If we would know that IT->f doesn't use
9670 a face with proportional font, we could be faster for
9671 truncate-lines nil. */
9673 void
9674 move_it_by_lines (struct it *it, ptrdiff_t dvpos)
9677 /* The commented-out optimization uses vmotion on terminals. This
9678 gives bad results, because elements like it->what, on which
9679 callers such as pos_visible_p rely, aren't updated. */
9680 /* struct position pos;
9681 if (!FRAME_WINDOW_P (it->f))
9683 struct text_pos textpos;
9685 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
9686 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
9687 reseat (it, textpos, 1);
9688 it->vpos += pos.vpos;
9689 it->current_y += pos.vpos;
9691 else */
9693 if (dvpos == 0)
9695 /* DVPOS == 0 means move to the start of the screen line. */
9696 move_it_vertically_backward (it, 0);
9697 /* Let next call to line_bottom_y calculate real line height. */
9698 last_height = 0;
9700 else if (dvpos > 0)
9702 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
9703 if (!IT_POS_VALID_AFTER_MOVE_P (it))
9705 /* Only move to the next buffer position if we ended up in a
9706 string from display property, not in an overlay string
9707 (before-string or after-string). That is because the
9708 latter don't conceal the underlying buffer position, so
9709 we can ask to move the iterator to the exact position we
9710 are interested in. Note that, even if we are already at
9711 IT_CHARPOS (*it), the call below is not a no-op, as it
9712 will detect that we are at the end of the string, pop the
9713 iterator, and compute it->current_x and it->hpos
9714 correctly. */
9715 move_it_to (it, IT_CHARPOS (*it) + it->string_from_display_prop_p,
9716 -1, -1, -1, MOVE_TO_POS);
9719 else
9721 struct it it2;
9722 void *it2data = NULL;
9723 ptrdiff_t start_charpos, i;
9724 int nchars_per_row
9725 = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
9726 bool hit_pos_limit = false;
9727 ptrdiff_t pos_limit;
9729 /* Start at the beginning of the screen line containing IT's
9730 position. This may actually move vertically backwards,
9731 in case of overlays, so adjust dvpos accordingly. */
9732 dvpos += it->vpos;
9733 move_it_vertically_backward (it, 0);
9734 dvpos -= it->vpos;
9736 /* Go back -DVPOS buffer lines, but no farther than -DVPOS full
9737 screen lines, and reseat the iterator there. */
9738 start_charpos = IT_CHARPOS (*it);
9739 if (it->line_wrap == TRUNCATE || nchars_per_row == 0)
9740 pos_limit = BEGV;
9741 else
9742 pos_limit = max (start_charpos + dvpos * nchars_per_row, BEGV);
9744 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > pos_limit; --i)
9745 back_to_previous_visible_line_start (it);
9746 if (i > 0 && IT_CHARPOS (*it) <= pos_limit)
9747 hit_pos_limit = true;
9748 reseat (it, it->current.pos, 1);
9750 /* Move further back if we end up in a string or an image. */
9751 while (!IT_POS_VALID_AFTER_MOVE_P (it))
9753 /* First try to move to start of display line. */
9754 dvpos += it->vpos;
9755 move_it_vertically_backward (it, 0);
9756 dvpos -= it->vpos;
9757 if (IT_POS_VALID_AFTER_MOVE_P (it))
9758 break;
9759 /* If start of line is still in string or image,
9760 move further back. */
9761 back_to_previous_visible_line_start (it);
9762 reseat (it, it->current.pos, 1);
9763 dvpos--;
9766 it->current_x = it->hpos = 0;
9768 /* Above call may have moved too far if continuation lines
9769 are involved. Scan forward and see if it did. */
9770 SAVE_IT (it2, *it, it2data);
9771 it2.vpos = it2.current_y = 0;
9772 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
9773 it->vpos -= it2.vpos;
9774 it->current_y -= it2.current_y;
9775 it->current_x = it->hpos = 0;
9777 /* If we moved too far back, move IT some lines forward. */
9778 if (it2.vpos > -dvpos)
9780 int delta = it2.vpos + dvpos;
9782 RESTORE_IT (&it2, &it2, it2data);
9783 SAVE_IT (it2, *it, it2data);
9784 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
9785 /* Move back again if we got too far ahead. */
9786 if (IT_CHARPOS (*it) >= start_charpos)
9787 RESTORE_IT (it, &it2, it2data);
9788 else
9789 bidi_unshelve_cache (it2data, 1);
9791 else if (hit_pos_limit && pos_limit > BEGV
9792 && dvpos < 0 && it2.vpos < -dvpos)
9794 /* If we hit the limit, but still didn't make it far enough
9795 back, that means there's a display string with a newline
9796 covering a large chunk of text, and that caused
9797 back_to_previous_visible_line_start try to go too far.
9798 Punish those who commit such atrocities by going back
9799 until we've reached DVPOS, after lifting the limit, which
9800 could make it slow for very long lines. "If it hurts,
9801 don't do that!" */
9802 dvpos += it2.vpos;
9803 RESTORE_IT (it, it, it2data);
9804 for (i = -dvpos; i > 0; --i)
9806 back_to_previous_visible_line_start (it);
9807 it->vpos--;
9809 reseat_1 (it, it->current.pos, 1);
9811 else
9812 RESTORE_IT (it, it, it2data);
9816 /* Return true if IT points into the middle of a display vector. */
9818 bool
9819 in_display_vector_p (struct it *it)
9821 return (it->method == GET_FROM_DISPLAY_VECTOR
9822 && it->current.dpvec_index > 0
9823 && it->dpvec + it->current.dpvec_index != it->dpend);
9826 DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_size, 0, 6, 0,
9827 doc: /* Return the size of the text of WINDOW's buffer in pixels.
9828 WINDOW must be a live window and defaults to the selected one. The
9829 return value is a cons of the maximum pixel-width of any text line and
9830 the maximum pixel-height of all text lines.
9832 The optional argument FROM, if non-nil, specifies the first text
9833 position and defaults to the minimum accessible position of the buffer.
9834 If FROM is t, use the minimum accessible position that is not a newline
9835 character. TO, if non-nil, specifies the last text position and
9836 defaults to the maximum accessible position of the buffer. If TO is t,
9837 use the maximum accessible position that is not a newline character.
9839 The optional argument X-LIMIT, if non-nil, specifies the maximum text
9840 width that can be returned. X-LIMIT nil or omitted, means to use the
9841 pixel-width of WINDOW's body; use this if you do not intend to change
9842 the width of WINDOW. Use the maximum width WINDOW may assume if you
9843 intend to change WINDOW's width. In any case, text whose x-coordinate
9844 is beyond X-LIMIT is ignored. Since calculating the width of long lines
9845 can take some time, it's always a good idea to make this argument as
9846 small as possible; in particular, if the buffer contains long lines that
9847 shall be truncated anyway.
9849 The optional argument Y-LIMIT, if non-nil, specifies the maximum text
9850 height that can be returned. Text lines whose y-coordinate is beyond
9851 Y-LIMIT are ignored. Since calculating the text height of a large
9852 buffer can take some time, it makes sense to specify this argument if
9853 the size of the buffer is unknown.
9855 Optional argument MODE-AND-HEADER-LINE nil or omitted means do not
9856 include the height of the mode- or header-line of WINDOW in the return
9857 value. If it is either the symbol `mode-line' or `header-line', include
9858 only the height of that line, if present, in the return value. If t,
9859 include the height of both, if present, in the return value. */)
9860 (Lisp_Object window, Lisp_Object from, Lisp_Object to, Lisp_Object x_limit, Lisp_Object y_limit,
9861 Lisp_Object mode_and_header_line)
9863 struct window *w = decode_live_window (window);
9864 Lisp_Object buf;
9865 struct buffer *b;
9866 struct it it;
9867 struct buffer *old_buffer = NULL;
9868 ptrdiff_t start, end, pos;
9869 struct text_pos startp;
9870 void *itdata = NULL;
9871 int c, max_y = -1, x = 0, y = 0;
9873 buf = w->contents;
9874 CHECK_BUFFER (buf);
9875 b = XBUFFER (buf);
9877 if (b != current_buffer)
9879 old_buffer = current_buffer;
9880 set_buffer_internal (b);
9883 if (NILP (from))
9884 start = BEGV;
9885 else if (EQ (from, Qt))
9887 start = pos = BEGV;
9888 while ((pos++ < ZV) && (c = FETCH_CHAR (pos))
9889 && (c == ' ' || c == '\t' || c == '\n' || c == '\r'))
9890 start = pos;
9891 while ((pos-- > BEGV) && (c = FETCH_CHAR (pos)) && (c == ' ' || c == '\t'))
9892 start = pos;
9894 else
9896 CHECK_NUMBER_COERCE_MARKER (from);
9897 start = min (max (XINT (from), BEGV), ZV);
9900 if (NILP (to))
9901 end = ZV;
9902 else if (EQ (to, Qt))
9904 end = pos = ZV;
9905 while ((pos-- > BEGV) && (c = FETCH_CHAR (pos))
9906 && (c == ' ' || c == '\t' || c == '\n' || c == '\r'))
9907 end = pos;
9908 while ((pos++ < ZV) && (c = FETCH_CHAR (pos)) && (c == ' ' || c == '\t'))
9909 end = pos;
9911 else
9913 CHECK_NUMBER_COERCE_MARKER (to);
9914 end = max (start, min (XINT (to), ZV));
9917 if (!NILP (y_limit))
9919 CHECK_NUMBER (y_limit);
9920 max_y = min (XINT (y_limit), INT_MAX);
9923 itdata = bidi_shelve_cache ();
9924 SET_TEXT_POS (startp, start, CHAR_TO_BYTE (start));
9925 start_display (&it, w, startp);
9927 if (NILP (x_limit))
9928 x = move_it_to (&it, end, -1, max_y, -1, MOVE_TO_POS | MOVE_TO_Y);
9929 else
9931 CHECK_NUMBER (x_limit);
9932 it.last_visible_x = min (XINT (x_limit), INFINITY);
9933 /* Actually, we never want move_it_to stop at to_x. But to make
9934 sure that move_it_in_display_line_to always moves far enough,
9935 we set it to INT_MAX and specify MOVE_TO_X. */
9936 x = move_it_to (&it, end, INT_MAX, max_y, -1,
9937 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
9940 y = it.current_y + it.max_ascent + it.max_descent;
9942 if (!EQ (mode_and_header_line, Qheader_line)
9943 && !EQ (mode_and_header_line, Qt))
9944 /* Do not count the header-line which was counted automatically by
9945 start_display. */
9946 y = y - WINDOW_HEADER_LINE_HEIGHT (w);
9948 if (EQ (mode_and_header_line, Qmode_line)
9949 || EQ (mode_and_header_line, Qt))
9950 /* Do count the mode-line which is not included automatically by
9951 start_display. */
9952 y = y + WINDOW_MODE_LINE_HEIGHT (w);
9954 bidi_unshelve_cache (itdata, 0);
9956 if (old_buffer)
9957 set_buffer_internal (old_buffer);
9959 return Fcons (make_number (x), make_number (y));
9962 /***********************************************************************
9963 Messages
9964 ***********************************************************************/
9967 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
9968 to *Messages*. */
9970 void
9971 add_to_log (const char *format, Lisp_Object arg1, Lisp_Object arg2)
9973 Lisp_Object args[3];
9974 Lisp_Object msg, fmt;
9975 char *buffer;
9976 ptrdiff_t len;
9977 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
9978 USE_SAFE_ALLOCA;
9980 fmt = msg = Qnil;
9981 GCPRO4 (fmt, msg, arg1, arg2);
9983 args[0] = fmt = build_string (format);
9984 args[1] = arg1;
9985 args[2] = arg2;
9986 msg = Fformat (3, args);
9988 len = SBYTES (msg) + 1;
9989 buffer = SAFE_ALLOCA (len);
9990 memcpy (buffer, SDATA (msg), len);
9992 message_dolog (buffer, len - 1, 1, 0);
9993 SAFE_FREE ();
9995 UNGCPRO;
9999 /* Output a newline in the *Messages* buffer if "needs" one. */
10001 void
10002 message_log_maybe_newline (void)
10004 if (message_log_need_newline)
10005 message_dolog ("", 0, 1, 0);
10009 /* Add a string M of length NBYTES to the message log, optionally
10010 terminated with a newline when NLFLAG is true. MULTIBYTE, if
10011 true, means interpret the contents of M as multibyte. This
10012 function calls low-level routines in order to bypass text property
10013 hooks, etc. which might not be safe to run.
10015 This may GC (insert may run before/after change hooks),
10016 so the buffer M must NOT point to a Lisp string. */
10018 void
10019 message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte)
10021 const unsigned char *msg = (const unsigned char *) m;
10023 if (!NILP (Vmemory_full))
10024 return;
10026 if (!NILP (Vmessage_log_max))
10028 struct buffer *oldbuf;
10029 Lisp_Object oldpoint, oldbegv, oldzv;
10030 int old_windows_or_buffers_changed = windows_or_buffers_changed;
10031 ptrdiff_t point_at_end = 0;
10032 ptrdiff_t zv_at_end = 0;
10033 Lisp_Object old_deactivate_mark;
10034 struct gcpro gcpro1;
10036 old_deactivate_mark = Vdeactivate_mark;
10037 oldbuf = current_buffer;
10039 /* Ensure the Messages buffer exists, and switch to it.
10040 If we created it, set the major-mode. */
10042 int newbuffer = 0;
10043 if (NILP (Fget_buffer (Vmessages_buffer_name))) newbuffer = 1;
10045 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
10047 if (newbuffer
10048 && !NILP (Ffboundp (intern ("messages-buffer-mode"))))
10049 call0 (intern ("messages-buffer-mode"));
10052 bset_undo_list (current_buffer, Qt);
10053 bset_cache_long_scans (current_buffer, Qnil);
10055 oldpoint = message_dolog_marker1;
10056 set_marker_restricted_both (oldpoint, Qnil, PT, PT_BYTE);
10057 oldbegv = message_dolog_marker2;
10058 set_marker_restricted_both (oldbegv, Qnil, BEGV, BEGV_BYTE);
10059 oldzv = message_dolog_marker3;
10060 set_marker_restricted_both (oldzv, Qnil, ZV, ZV_BYTE);
10061 GCPRO1 (old_deactivate_mark);
10063 if (PT == Z)
10064 point_at_end = 1;
10065 if (ZV == Z)
10066 zv_at_end = 1;
10068 BEGV = BEG;
10069 BEGV_BYTE = BEG_BYTE;
10070 ZV = Z;
10071 ZV_BYTE = Z_BYTE;
10072 TEMP_SET_PT_BOTH (Z, Z_BYTE);
10074 /* Insert the string--maybe converting multibyte to single byte
10075 or vice versa, so that all the text fits the buffer. */
10076 if (multibyte
10077 && NILP (BVAR (current_buffer, enable_multibyte_characters)))
10079 ptrdiff_t i;
10080 int c, char_bytes;
10081 char work[1];
10083 /* Convert a multibyte string to single-byte
10084 for the *Message* buffer. */
10085 for (i = 0; i < nbytes; i += char_bytes)
10087 c = string_char_and_length (msg + i, &char_bytes);
10088 work[0] = CHAR_TO_BYTE8 (c);
10089 insert_1_both (work, 1, 1, 1, 0, 0);
10092 else if (! multibyte
10093 && ! NILP (BVAR (current_buffer, enable_multibyte_characters)))
10095 ptrdiff_t i;
10096 int c, char_bytes;
10097 unsigned char str[MAX_MULTIBYTE_LENGTH];
10098 /* Convert a single-byte string to multibyte
10099 for the *Message* buffer. */
10100 for (i = 0; i < nbytes; i++)
10102 c = msg[i];
10103 MAKE_CHAR_MULTIBYTE (c);
10104 char_bytes = CHAR_STRING (c, str);
10105 insert_1_both ((char *) str, 1, char_bytes, 1, 0, 0);
10108 else if (nbytes)
10109 insert_1_both (m, chars_in_text (msg, nbytes), nbytes, 1, 0, 0);
10111 if (nlflag)
10113 ptrdiff_t this_bol, this_bol_byte, prev_bol, prev_bol_byte;
10114 printmax_t dups;
10116 insert_1_both ("\n", 1, 1, 1, 0, 0);
10118 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
10119 this_bol = PT;
10120 this_bol_byte = PT_BYTE;
10122 /* See if this line duplicates the previous one.
10123 If so, combine duplicates. */
10124 if (this_bol > BEG)
10126 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
10127 prev_bol = PT;
10128 prev_bol_byte = PT_BYTE;
10130 dups = message_log_check_duplicate (prev_bol_byte,
10131 this_bol_byte);
10132 if (dups)
10134 del_range_both (prev_bol, prev_bol_byte,
10135 this_bol, this_bol_byte, 0);
10136 if (dups > 1)
10138 char dupstr[sizeof " [ times]"
10139 + INT_STRLEN_BOUND (printmax_t)];
10141 /* If you change this format, don't forget to also
10142 change message_log_check_duplicate. */
10143 int duplen = sprintf (dupstr, " [%"pMd" times]", dups);
10144 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
10145 insert_1_both (dupstr, duplen, duplen, 1, 0, 1);
10150 /* If we have more than the desired maximum number of lines
10151 in the *Messages* buffer now, delete the oldest ones.
10152 This is safe because we don't have undo in this buffer. */
10154 if (NATNUMP (Vmessage_log_max))
10156 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
10157 -XFASTINT (Vmessage_log_max) - 1, 0);
10158 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
10161 BEGV = marker_position (oldbegv);
10162 BEGV_BYTE = marker_byte_position (oldbegv);
10164 if (zv_at_end)
10166 ZV = Z;
10167 ZV_BYTE = Z_BYTE;
10169 else
10171 ZV = marker_position (oldzv);
10172 ZV_BYTE = marker_byte_position (oldzv);
10175 if (point_at_end)
10176 TEMP_SET_PT_BOTH (Z, Z_BYTE);
10177 else
10178 /* We can't do Fgoto_char (oldpoint) because it will run some
10179 Lisp code. */
10180 TEMP_SET_PT_BOTH (marker_position (oldpoint),
10181 marker_byte_position (oldpoint));
10183 UNGCPRO;
10184 unchain_marker (XMARKER (oldpoint));
10185 unchain_marker (XMARKER (oldbegv));
10186 unchain_marker (XMARKER (oldzv));
10188 /* We called insert_1_both above with its 5th argument (PREPARE)
10189 zero, which prevents insert_1_both from calling
10190 prepare_to_modify_buffer, which in turns prevents us from
10191 incrementing windows_or_buffers_changed even if *Messages* is
10192 shown in some window. So we must manually set
10193 windows_or_buffers_changed here to make up for that. */
10194 windows_or_buffers_changed = old_windows_or_buffers_changed;
10195 bset_redisplay (current_buffer);
10197 set_buffer_internal (oldbuf);
10199 message_log_need_newline = !nlflag;
10200 Vdeactivate_mark = old_deactivate_mark;
10205 /* We are at the end of the buffer after just having inserted a newline.
10206 (Note: We depend on the fact we won't be crossing the gap.)
10207 Check to see if the most recent message looks a lot like the previous one.
10208 Return 0 if different, 1 if the new one should just replace it, or a
10209 value N > 1 if we should also append " [N times]". */
10211 static intmax_t
10212 message_log_check_duplicate (ptrdiff_t prev_bol_byte, ptrdiff_t this_bol_byte)
10214 ptrdiff_t i;
10215 ptrdiff_t len = Z_BYTE - 1 - this_bol_byte;
10216 int seen_dots = 0;
10217 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
10218 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
10220 for (i = 0; i < len; i++)
10222 if (i >= 3 && p1[i - 3] == '.' && p1[i - 2] == '.' && p1[i - 1] == '.')
10223 seen_dots = 1;
10224 if (p1[i] != p2[i])
10225 return seen_dots;
10227 p1 += len;
10228 if (*p1 == '\n')
10229 return 2;
10230 if (*p1++ == ' ' && *p1++ == '[')
10232 char *pend;
10233 intmax_t n = strtoimax ((char *) p1, &pend, 10);
10234 if (0 < n && n < INTMAX_MAX && strncmp (pend, " times]\n", 8) == 0)
10235 return n + 1;
10237 return 0;
10241 /* Display an echo area message M with a specified length of NBYTES
10242 bytes. The string may include null characters. If M is not a
10243 string, clear out any existing message, and let the mini-buffer
10244 text show through.
10246 This function cancels echoing. */
10248 void
10249 message3 (Lisp_Object m)
10251 struct gcpro gcpro1;
10253 GCPRO1 (m);
10254 clear_message (true, true);
10255 cancel_echoing ();
10257 /* First flush out any partial line written with print. */
10258 message_log_maybe_newline ();
10259 if (STRINGP (m))
10261 ptrdiff_t nbytes = SBYTES (m);
10262 bool multibyte = STRING_MULTIBYTE (m);
10263 char *buffer;
10264 USE_SAFE_ALLOCA;
10265 SAFE_ALLOCA_STRING (buffer, m);
10266 message_dolog (buffer, nbytes, 1, multibyte);
10267 SAFE_FREE ();
10269 message3_nolog (m);
10271 UNGCPRO;
10275 /* The non-logging version of message3.
10276 This does not cancel echoing, because it is used for echoing.
10277 Perhaps we need to make a separate function for echoing
10278 and make this cancel echoing. */
10280 void
10281 message3_nolog (Lisp_Object m)
10283 struct frame *sf = SELECTED_FRAME ();
10285 if (FRAME_INITIAL_P (sf))
10287 if (noninteractive_need_newline)
10288 putc ('\n', stderr);
10289 noninteractive_need_newline = 0;
10290 if (STRINGP (m))
10292 Lisp_Object s = ENCODE_SYSTEM (m);
10294 fwrite (SDATA (s), SBYTES (s), 1, stderr);
10296 if (cursor_in_echo_area == 0)
10297 fprintf (stderr, "\n");
10298 fflush (stderr);
10300 /* Error messages get reported properly by cmd_error, so this must be just an
10301 informative message; if the frame hasn't really been initialized yet, just
10302 toss it. */
10303 else if (INTERACTIVE && sf->glyphs_initialized_p)
10305 /* Get the frame containing the mini-buffer
10306 that the selected frame is using. */
10307 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
10308 Lisp_Object frame = XWINDOW (mini_window)->frame;
10309 struct frame *f = XFRAME (frame);
10311 if (FRAME_VISIBLE_P (sf) && !FRAME_VISIBLE_P (f))
10312 Fmake_frame_visible (frame);
10314 if (STRINGP (m) && SCHARS (m) > 0)
10316 set_message (m);
10317 if (minibuffer_auto_raise)
10318 Fraise_frame (frame);
10319 /* Assume we are not echoing.
10320 (If we are, echo_now will override this.) */
10321 echo_message_buffer = Qnil;
10323 else
10324 clear_message (true, true);
10326 do_pending_window_change (false);
10327 echo_area_display (true);
10328 do_pending_window_change (false);
10329 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
10330 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
10335 /* Display a null-terminated echo area message M. If M is 0, clear
10336 out any existing message, and let the mini-buffer text show through.
10338 The buffer M must continue to exist until after the echo area gets
10339 cleared or some other message gets displayed there. Do not pass
10340 text that is stored in a Lisp string. Do not pass text in a buffer
10341 that was alloca'd. */
10343 void
10344 message1 (const char *m)
10346 message3 (m ? build_unibyte_string (m) : Qnil);
10350 /* The non-logging counterpart of message1. */
10352 void
10353 message1_nolog (const char *m)
10355 message3_nolog (m ? build_unibyte_string (m) : Qnil);
10358 /* Display a message M which contains a single %s
10359 which gets replaced with STRING. */
10361 void
10362 message_with_string (const char *m, Lisp_Object string, int log)
10364 CHECK_STRING (string);
10366 if (noninteractive)
10368 if (m)
10370 /* ENCODE_SYSTEM below can GC and/or relocate the
10371 Lisp data, so make sure we don't use it here. */
10372 eassert (relocatable_string_data_p (m) != 1);
10374 if (noninteractive_need_newline)
10375 putc ('\n', stderr);
10376 noninteractive_need_newline = 0;
10377 fprintf (stderr, m, SDATA (ENCODE_SYSTEM (string)));
10378 if (!cursor_in_echo_area)
10379 fprintf (stderr, "\n");
10380 fflush (stderr);
10383 else if (INTERACTIVE)
10385 /* The frame whose minibuffer we're going to display the message on.
10386 It may be larger than the selected frame, so we need
10387 to use its buffer, not the selected frame's buffer. */
10388 Lisp_Object mini_window;
10389 struct frame *f, *sf = SELECTED_FRAME ();
10391 /* Get the frame containing the minibuffer
10392 that the selected frame is using. */
10393 mini_window = FRAME_MINIBUF_WINDOW (sf);
10394 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10396 /* Error messages get reported properly by cmd_error, so this must be
10397 just an informative message; if the frame hasn't really been
10398 initialized yet, just toss it. */
10399 if (f->glyphs_initialized_p)
10401 Lisp_Object args[2], msg;
10402 struct gcpro gcpro1, gcpro2;
10404 args[0] = build_string (m);
10405 args[1] = msg = string;
10406 GCPRO2 (args[0], msg);
10407 gcpro1.nvars = 2;
10409 msg = Fformat (2, args);
10411 if (log)
10412 message3 (msg);
10413 else
10414 message3_nolog (msg);
10416 UNGCPRO;
10418 /* Print should start at the beginning of the message
10419 buffer next time. */
10420 message_buf_print = 0;
10426 /* Dump an informative message to the minibuf. If M is 0, clear out
10427 any existing message, and let the mini-buffer text show through. */
10429 static void
10430 vmessage (const char *m, va_list ap)
10432 if (noninteractive)
10434 if (m)
10436 if (noninteractive_need_newline)
10437 putc ('\n', stderr);
10438 noninteractive_need_newline = 0;
10439 vfprintf (stderr, m, ap);
10440 if (cursor_in_echo_area == 0)
10441 fprintf (stderr, "\n");
10442 fflush (stderr);
10445 else if (INTERACTIVE)
10447 /* The frame whose mini-buffer we're going to display the message
10448 on. It may be larger than the selected frame, so we need to
10449 use its buffer, not the selected frame's buffer. */
10450 Lisp_Object mini_window;
10451 struct frame *f, *sf = SELECTED_FRAME ();
10453 /* Get the frame containing the mini-buffer
10454 that the selected frame is using. */
10455 mini_window = FRAME_MINIBUF_WINDOW (sf);
10456 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10458 /* Error messages get reported properly by cmd_error, so this must be
10459 just an informative message; if the frame hasn't really been
10460 initialized yet, just toss it. */
10461 if (f->glyphs_initialized_p)
10463 if (m)
10465 ptrdiff_t len;
10466 ptrdiff_t maxsize = FRAME_MESSAGE_BUF_SIZE (f);
10467 USE_SAFE_ALLOCA;
10468 char *message_buf = SAFE_ALLOCA (maxsize + 1);
10470 len = doprnt (message_buf, maxsize, m, 0, ap);
10472 message3 (make_string (message_buf, len));
10473 SAFE_FREE ();
10475 else
10476 message1 (0);
10478 /* Print should start at the beginning of the message
10479 buffer next time. */
10480 message_buf_print = 0;
10485 void
10486 message (const char *m, ...)
10488 va_list ap;
10489 va_start (ap, m);
10490 vmessage (m, ap);
10491 va_end (ap);
10495 #if 0
10496 /* The non-logging version of message. */
10498 void
10499 message_nolog (const char *m, ...)
10501 Lisp_Object old_log_max;
10502 va_list ap;
10503 va_start (ap, m);
10504 old_log_max = Vmessage_log_max;
10505 Vmessage_log_max = Qnil;
10506 vmessage (m, ap);
10507 Vmessage_log_max = old_log_max;
10508 va_end (ap);
10510 #endif
10513 /* Display the current message in the current mini-buffer. This is
10514 only called from error handlers in process.c, and is not time
10515 critical. */
10517 void
10518 update_echo_area (void)
10520 if (!NILP (echo_area_buffer[0]))
10522 Lisp_Object string;
10523 string = Fcurrent_message ();
10524 message3 (string);
10529 /* Make sure echo area buffers in `echo_buffers' are live.
10530 If they aren't, make new ones. */
10532 static void
10533 ensure_echo_area_buffers (void)
10535 int i;
10537 for (i = 0; i < 2; ++i)
10538 if (!BUFFERP (echo_buffer[i])
10539 || !BUFFER_LIVE_P (XBUFFER (echo_buffer[i])))
10541 char name[30];
10542 Lisp_Object old_buffer;
10543 int j;
10545 old_buffer = echo_buffer[i];
10546 echo_buffer[i] = Fget_buffer_create
10547 (make_formatted_string (name, " *Echo Area %d*", i));
10548 bset_truncate_lines (XBUFFER (echo_buffer[i]), Qnil);
10549 /* to force word wrap in echo area -
10550 it was decided to postpone this*/
10551 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
10553 for (j = 0; j < 2; ++j)
10554 if (EQ (old_buffer, echo_area_buffer[j]))
10555 echo_area_buffer[j] = echo_buffer[i];
10560 /* Call FN with args A1..A2 with either the current or last displayed
10561 echo_area_buffer as current buffer.
10563 WHICH zero means use the current message buffer
10564 echo_area_buffer[0]. If that is nil, choose a suitable buffer
10565 from echo_buffer[] and clear it.
10567 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
10568 suitable buffer from echo_buffer[] and clear it.
10570 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
10571 that the current message becomes the last displayed one, make
10572 choose a suitable buffer for echo_area_buffer[0], and clear it.
10574 Value is what FN returns. */
10576 static int
10577 with_echo_area_buffer (struct window *w, int which,
10578 int (*fn) (ptrdiff_t, Lisp_Object),
10579 ptrdiff_t a1, Lisp_Object a2)
10581 Lisp_Object buffer;
10582 int this_one, the_other, clear_buffer_p, rc;
10583 ptrdiff_t count = SPECPDL_INDEX ();
10585 /* If buffers aren't live, make new ones. */
10586 ensure_echo_area_buffers ();
10588 clear_buffer_p = 0;
10590 if (which == 0)
10591 this_one = 0, the_other = 1;
10592 else if (which > 0)
10593 this_one = 1, the_other = 0;
10594 else
10596 this_one = 0, the_other = 1;
10597 clear_buffer_p = true;
10599 /* We need a fresh one in case the current echo buffer equals
10600 the one containing the last displayed echo area message. */
10601 if (!NILP (echo_area_buffer[this_one])
10602 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
10603 echo_area_buffer[this_one] = Qnil;
10606 /* Choose a suitable buffer from echo_buffer[] is we don't
10607 have one. */
10608 if (NILP (echo_area_buffer[this_one]))
10610 echo_area_buffer[this_one]
10611 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
10612 ? echo_buffer[the_other]
10613 : echo_buffer[this_one]);
10614 clear_buffer_p = true;
10617 buffer = echo_area_buffer[this_one];
10619 /* Don't get confused by reusing the buffer used for echoing
10620 for a different purpose. */
10621 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
10622 cancel_echoing ();
10624 record_unwind_protect (unwind_with_echo_area_buffer,
10625 with_echo_area_buffer_unwind_data (w));
10627 /* Make the echo area buffer current. Note that for display
10628 purposes, it is not necessary that the displayed window's buffer
10629 == current_buffer, except for text property lookup. So, let's
10630 only set that buffer temporarily here without doing a full
10631 Fset_window_buffer. We must also change w->pointm, though,
10632 because otherwise an assertions in unshow_buffer fails, and Emacs
10633 aborts. */
10634 set_buffer_internal_1 (XBUFFER (buffer));
10635 if (w)
10637 wset_buffer (w, buffer);
10638 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
10639 set_marker_both (w->old_pointm, buffer, BEG, BEG_BYTE);
10642 bset_undo_list (current_buffer, Qt);
10643 bset_read_only (current_buffer, Qnil);
10644 specbind (Qinhibit_read_only, Qt);
10645 specbind (Qinhibit_modification_hooks, Qt);
10647 if (clear_buffer_p && Z > BEG)
10648 del_range (BEG, Z);
10650 eassert (BEGV >= BEG);
10651 eassert (ZV <= Z && ZV >= BEGV);
10653 rc = fn (a1, a2);
10655 eassert (BEGV >= BEG);
10656 eassert (ZV <= Z && ZV >= BEGV);
10658 unbind_to (count, Qnil);
10659 return rc;
10663 /* Save state that should be preserved around the call to the function
10664 FN called in with_echo_area_buffer. */
10666 static Lisp_Object
10667 with_echo_area_buffer_unwind_data (struct window *w)
10669 int i = 0;
10670 Lisp_Object vector, tmp;
10672 /* Reduce consing by keeping one vector in
10673 Vwith_echo_area_save_vector. */
10674 vector = Vwith_echo_area_save_vector;
10675 Vwith_echo_area_save_vector = Qnil;
10677 if (NILP (vector))
10678 vector = Fmake_vector (make_number (11), Qnil);
10680 XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
10681 ASET (vector, i, Vdeactivate_mark); ++i;
10682 ASET (vector, i, make_number (windows_or_buffers_changed)); ++i;
10684 if (w)
10686 XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i;
10687 ASET (vector, i, w->contents); ++i;
10688 ASET (vector, i, make_number (marker_position (w->pointm))); ++i;
10689 ASET (vector, i, make_number (marker_byte_position (w->pointm))); ++i;
10690 ASET (vector, i, make_number (marker_position (w->old_pointm))); ++i;
10691 ASET (vector, i, make_number (marker_byte_position (w->old_pointm))); ++i;
10692 ASET (vector, i, make_number (marker_position (w->start))); ++i;
10693 ASET (vector, i, make_number (marker_byte_position (w->start))); ++i;
10695 else
10697 int end = i + 8;
10698 for (; i < end; ++i)
10699 ASET (vector, i, Qnil);
10702 eassert (i == ASIZE (vector));
10703 return vector;
10707 /* Restore global state from VECTOR which was created by
10708 with_echo_area_buffer_unwind_data. */
10710 static void
10711 unwind_with_echo_area_buffer (Lisp_Object vector)
10713 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
10714 Vdeactivate_mark = AREF (vector, 1);
10715 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
10717 if (WINDOWP (AREF (vector, 3)))
10719 struct window *w;
10720 Lisp_Object buffer;
10722 w = XWINDOW (AREF (vector, 3));
10723 buffer = AREF (vector, 4);
10725 wset_buffer (w, buffer);
10726 set_marker_both (w->pointm, buffer,
10727 XFASTINT (AREF (vector, 5)),
10728 XFASTINT (AREF (vector, 6)));
10729 set_marker_both (w->old_pointm, buffer,
10730 XFASTINT (AREF (vector, 7)),
10731 XFASTINT (AREF (vector, 8)));
10732 set_marker_both (w->start, buffer,
10733 XFASTINT (AREF (vector, 9)),
10734 XFASTINT (AREF (vector, 10)));
10737 Vwith_echo_area_save_vector = vector;
10741 /* Set up the echo area for use by print functions. MULTIBYTE_P
10742 non-zero means we will print multibyte. */
10744 void
10745 setup_echo_area_for_printing (int multibyte_p)
10747 /* If we can't find an echo area any more, exit. */
10748 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
10749 Fkill_emacs (Qnil);
10751 ensure_echo_area_buffers ();
10753 if (!message_buf_print)
10755 /* A message has been output since the last time we printed.
10756 Choose a fresh echo area buffer. */
10757 if (EQ (echo_area_buffer[1], echo_buffer[0]))
10758 echo_area_buffer[0] = echo_buffer[1];
10759 else
10760 echo_area_buffer[0] = echo_buffer[0];
10762 /* Switch to that buffer and clear it. */
10763 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
10764 bset_truncate_lines (current_buffer, Qnil);
10766 if (Z > BEG)
10768 ptrdiff_t count = SPECPDL_INDEX ();
10769 specbind (Qinhibit_read_only, Qt);
10770 /* Note that undo recording is always disabled. */
10771 del_range (BEG, Z);
10772 unbind_to (count, Qnil);
10774 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
10776 /* Set up the buffer for the multibyteness we need. */
10777 if (multibyte_p
10778 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
10779 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
10781 /* Raise the frame containing the echo area. */
10782 if (minibuffer_auto_raise)
10784 struct frame *sf = SELECTED_FRAME ();
10785 Lisp_Object mini_window;
10786 mini_window = FRAME_MINIBUF_WINDOW (sf);
10787 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
10790 message_log_maybe_newline ();
10791 message_buf_print = 1;
10793 else
10795 if (NILP (echo_area_buffer[0]))
10797 if (EQ (echo_area_buffer[1], echo_buffer[0]))
10798 echo_area_buffer[0] = echo_buffer[1];
10799 else
10800 echo_area_buffer[0] = echo_buffer[0];
10803 if (current_buffer != XBUFFER (echo_area_buffer[0]))
10805 /* Someone switched buffers between print requests. */
10806 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
10807 bset_truncate_lines (current_buffer, Qnil);
10813 /* Display an echo area message in window W. Value is non-zero if W's
10814 height is changed. If display_last_displayed_message_p is
10815 non-zero, display the message that was last displayed, otherwise
10816 display the current message. */
10818 static int
10819 display_echo_area (struct window *w)
10821 int i, no_message_p, window_height_changed_p;
10823 /* Temporarily disable garbage collections while displaying the echo
10824 area. This is done because a GC can print a message itself.
10825 That message would modify the echo area buffer's contents while a
10826 redisplay of the buffer is going on, and seriously confuse
10827 redisplay. */
10828 ptrdiff_t count = inhibit_garbage_collection ();
10830 /* If there is no message, we must call display_echo_area_1
10831 nevertheless because it resizes the window. But we will have to
10832 reset the echo_area_buffer in question to nil at the end because
10833 with_echo_area_buffer will sets it to an empty buffer. */
10834 i = display_last_displayed_message_p ? 1 : 0;
10835 no_message_p = NILP (echo_area_buffer[i]);
10837 window_height_changed_p
10838 = with_echo_area_buffer (w, display_last_displayed_message_p,
10839 display_echo_area_1,
10840 (intptr_t) w, Qnil);
10842 if (no_message_p)
10843 echo_area_buffer[i] = Qnil;
10845 unbind_to (count, Qnil);
10846 return window_height_changed_p;
10850 /* Helper for display_echo_area. Display the current buffer which
10851 contains the current echo area message in window W, a mini-window,
10852 a pointer to which is passed in A1. A2..A4 are currently not used.
10853 Change the height of W so that all of the message is displayed.
10854 Value is non-zero if height of W was changed. */
10856 static int
10857 display_echo_area_1 (ptrdiff_t a1, Lisp_Object a2)
10859 intptr_t i1 = a1;
10860 struct window *w = (struct window *) i1;
10861 Lisp_Object window;
10862 struct text_pos start;
10863 int window_height_changed_p = 0;
10865 /* Do this before displaying, so that we have a large enough glyph
10866 matrix for the display. If we can't get enough space for the
10867 whole text, display the last N lines. That works by setting w->start. */
10868 window_height_changed_p = resize_mini_window (w, 0);
10870 /* Use the starting position chosen by resize_mini_window. */
10871 SET_TEXT_POS_FROM_MARKER (start, w->start);
10873 /* Display. */
10874 clear_glyph_matrix (w->desired_matrix);
10875 XSETWINDOW (window, w);
10876 try_window (window, start, 0);
10878 return window_height_changed_p;
10882 /* Resize the echo area window to exactly the size needed for the
10883 currently displayed message, if there is one. If a mini-buffer
10884 is active, don't shrink it. */
10886 void
10887 resize_echo_area_exactly (void)
10889 if (BUFFERP (echo_area_buffer[0])
10890 && WINDOWP (echo_area_window))
10892 struct window *w = XWINDOW (echo_area_window);
10893 Lisp_Object resize_exactly = (minibuf_level == 0 ? Qt : Qnil);
10894 int resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
10895 (intptr_t) w, resize_exactly);
10896 if (resized_p)
10898 windows_or_buffers_changed = 42;
10899 update_mode_lines = 30;
10900 redisplay_internal ();
10906 /* Callback function for with_echo_area_buffer, when used from
10907 resize_echo_area_exactly. A1 contains a pointer to the window to
10908 resize, EXACTLY non-nil means resize the mini-window exactly to the
10909 size of the text displayed. A3 and A4 are not used. Value is what
10910 resize_mini_window returns. */
10912 static int
10913 resize_mini_window_1 (ptrdiff_t a1, Lisp_Object exactly)
10915 intptr_t i1 = a1;
10916 return resize_mini_window ((struct window *) i1, !NILP (exactly));
10920 /* Resize mini-window W to fit the size of its contents. EXACT_P
10921 means size the window exactly to the size needed. Otherwise, it's
10922 only enlarged until W's buffer is empty.
10924 Set W->start to the right place to begin display. If the whole
10925 contents fit, start at the beginning. Otherwise, start so as
10926 to make the end of the contents appear. This is particularly
10927 important for y-or-n-p, but seems desirable generally.
10929 Value is non-zero if the window height has been changed. */
10932 resize_mini_window (struct window *w, int exact_p)
10934 struct frame *f = XFRAME (w->frame);
10935 int window_height_changed_p = 0;
10937 eassert (MINI_WINDOW_P (w));
10939 /* By default, start display at the beginning. */
10940 set_marker_both (w->start, w->contents,
10941 BUF_BEGV (XBUFFER (w->contents)),
10942 BUF_BEGV_BYTE (XBUFFER (w->contents)));
10944 /* Don't resize windows while redisplaying a window; it would
10945 confuse redisplay functions when the size of the window they are
10946 displaying changes from under them. Such a resizing can happen,
10947 for instance, when which-func prints a long message while
10948 we are running fontification-functions. We're running these
10949 functions with safe_call which binds inhibit-redisplay to t. */
10950 if (!NILP (Vinhibit_redisplay))
10951 return 0;
10953 /* Nil means don't try to resize. */
10954 if (NILP (Vresize_mini_windows)
10955 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
10956 return 0;
10958 if (!FRAME_MINIBUF_ONLY_P (f))
10960 struct it it;
10961 int total_height = (WINDOW_PIXEL_HEIGHT (XWINDOW (FRAME_ROOT_WINDOW (f)))
10962 + WINDOW_PIXEL_HEIGHT (w));
10963 int unit = FRAME_LINE_HEIGHT (f);
10964 int height, max_height;
10965 struct text_pos start;
10966 struct buffer *old_current_buffer = NULL;
10968 if (current_buffer != XBUFFER (w->contents))
10970 old_current_buffer = current_buffer;
10971 set_buffer_internal (XBUFFER (w->contents));
10974 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
10976 /* Compute the max. number of lines specified by the user. */
10977 if (FLOATP (Vmax_mini_window_height))
10978 max_height = XFLOATINT (Vmax_mini_window_height) * total_height;
10979 else if (INTEGERP (Vmax_mini_window_height))
10980 max_height = XINT (Vmax_mini_window_height) * unit;
10981 else
10982 max_height = total_height / 4;
10984 /* Correct that max. height if it's bogus. */
10985 max_height = clip_to_bounds (unit, max_height, total_height);
10987 /* Find out the height of the text in the window. */
10988 if (it.line_wrap == TRUNCATE)
10989 height = unit;
10990 else
10992 last_height = 0;
10993 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
10994 if (it.max_ascent == 0 && it.max_descent == 0)
10995 height = it.current_y + last_height;
10996 else
10997 height = it.current_y + it.max_ascent + it.max_descent;
10998 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
11001 /* Compute a suitable window start. */
11002 if (height > max_height)
11004 height = (max_height / unit) * unit;
11005 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
11006 move_it_vertically_backward (&it, height - unit);
11007 start = it.current.pos;
11009 else
11010 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
11011 SET_MARKER_FROM_TEXT_POS (w->start, start);
11013 if (EQ (Vresize_mini_windows, Qgrow_only))
11015 /* Let it grow only, until we display an empty message, in which
11016 case the window shrinks again. */
11017 if (height > WINDOW_PIXEL_HEIGHT (w))
11019 int old_height = WINDOW_PIXEL_HEIGHT (w);
11021 FRAME_WINDOWS_FROZEN (f) = 1;
11022 grow_mini_window (w, height - WINDOW_PIXEL_HEIGHT (w), 1);
11023 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
11025 else if (height < WINDOW_PIXEL_HEIGHT (w)
11026 && (exact_p || BEGV == ZV))
11028 int old_height = WINDOW_PIXEL_HEIGHT (w);
11030 FRAME_WINDOWS_FROZEN (f) = 0;
11031 shrink_mini_window (w, 1);
11032 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
11035 else
11037 /* Always resize to exact size needed. */
11038 if (height > WINDOW_PIXEL_HEIGHT (w))
11040 int old_height = WINDOW_PIXEL_HEIGHT (w);
11042 FRAME_WINDOWS_FROZEN (f) = 1;
11043 grow_mini_window (w, height - WINDOW_PIXEL_HEIGHT (w), 1);
11044 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
11046 else if (height < WINDOW_PIXEL_HEIGHT (w))
11048 int old_height = WINDOW_PIXEL_HEIGHT (w);
11050 FRAME_WINDOWS_FROZEN (f) = 0;
11051 shrink_mini_window (w, 1);
11053 if (height)
11055 FRAME_WINDOWS_FROZEN (f) = 1;
11056 grow_mini_window (w, height - WINDOW_PIXEL_HEIGHT (w), 1);
11059 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
11063 if (old_current_buffer)
11064 set_buffer_internal (old_current_buffer);
11067 return window_height_changed_p;
11071 /* Value is the current message, a string, or nil if there is no
11072 current message. */
11074 Lisp_Object
11075 current_message (void)
11077 Lisp_Object msg;
11079 if (!BUFFERP (echo_area_buffer[0]))
11080 msg = Qnil;
11081 else
11083 with_echo_area_buffer (0, 0, current_message_1,
11084 (intptr_t) &msg, Qnil);
11085 if (NILP (msg))
11086 echo_area_buffer[0] = Qnil;
11089 return msg;
11093 static int
11094 current_message_1 (ptrdiff_t a1, Lisp_Object a2)
11096 intptr_t i1 = a1;
11097 Lisp_Object *msg = (Lisp_Object *) i1;
11099 if (Z > BEG)
11100 *msg = make_buffer_string (BEG, Z, 1);
11101 else
11102 *msg = Qnil;
11103 return 0;
11107 /* Push the current message on Vmessage_stack for later restoration
11108 by restore_message. Value is non-zero if the current message isn't
11109 empty. This is a relatively infrequent operation, so it's not
11110 worth optimizing. */
11112 bool
11113 push_message (void)
11115 Lisp_Object msg = current_message ();
11116 Vmessage_stack = Fcons (msg, Vmessage_stack);
11117 return STRINGP (msg);
11121 /* Restore message display from the top of Vmessage_stack. */
11123 void
11124 restore_message (void)
11126 eassert (CONSP (Vmessage_stack));
11127 message3_nolog (XCAR (Vmessage_stack));
11131 /* Handler for unwind-protect calling pop_message. */
11133 void
11134 pop_message_unwind (void)
11136 /* Pop the top-most entry off Vmessage_stack. */
11137 eassert (CONSP (Vmessage_stack));
11138 Vmessage_stack = XCDR (Vmessage_stack);
11142 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
11143 exits. If the stack is not empty, we have a missing pop_message
11144 somewhere. */
11146 void
11147 check_message_stack (void)
11149 if (!NILP (Vmessage_stack))
11150 emacs_abort ();
11154 /* Truncate to NCHARS what will be displayed in the echo area the next
11155 time we display it---but don't redisplay it now. */
11157 void
11158 truncate_echo_area (ptrdiff_t nchars)
11160 if (nchars == 0)
11161 echo_area_buffer[0] = Qnil;
11162 else if (!noninteractive
11163 && INTERACTIVE
11164 && !NILP (echo_area_buffer[0]))
11166 struct frame *sf = SELECTED_FRAME ();
11167 /* Error messages get reported properly by cmd_error, so this must be
11168 just an informative message; if the frame hasn't really been
11169 initialized yet, just toss it. */
11170 if (sf->glyphs_initialized_p)
11171 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil);
11176 /* Helper function for truncate_echo_area. Truncate the current
11177 message to at most NCHARS characters. */
11179 static int
11180 truncate_message_1 (ptrdiff_t nchars, Lisp_Object a2)
11182 if (BEG + nchars < Z)
11183 del_range (BEG + nchars, Z);
11184 if (Z == BEG)
11185 echo_area_buffer[0] = Qnil;
11186 return 0;
11189 /* Set the current message to STRING. */
11191 static void
11192 set_message (Lisp_Object string)
11194 eassert (STRINGP (string));
11196 message_enable_multibyte = STRING_MULTIBYTE (string);
11198 with_echo_area_buffer (0, -1, set_message_1, 0, string);
11199 message_buf_print = 0;
11200 help_echo_showing_p = 0;
11202 if (STRINGP (Vdebug_on_message)
11203 && STRINGP (string)
11204 && fast_string_match (Vdebug_on_message, string) >= 0)
11205 call_debugger (list2 (Qerror, string));
11209 /* Helper function for set_message. First argument is ignored and second
11210 argument has the same meaning as for set_message.
11211 This function is called with the echo area buffer being current. */
11213 static int
11214 set_message_1 (ptrdiff_t a1, Lisp_Object string)
11216 eassert (STRINGP (string));
11218 /* Change multibyteness of the echo buffer appropriately. */
11219 if (message_enable_multibyte
11220 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
11221 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
11223 bset_truncate_lines (current_buffer, message_truncate_lines ? Qt : Qnil);
11224 if (!NILP (BVAR (current_buffer, bidi_display_reordering)))
11225 bset_bidi_paragraph_direction (current_buffer, Qleft_to_right);
11227 /* Insert new message at BEG. */
11228 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
11230 /* This function takes care of single/multibyte conversion.
11231 We just have to ensure that the echo area buffer has the right
11232 setting of enable_multibyte_characters. */
11233 insert_from_string (string, 0, 0, SCHARS (string), SBYTES (string), 1);
11235 return 0;
11239 /* Clear messages. CURRENT_P non-zero means clear the current
11240 message. LAST_DISPLAYED_P non-zero means clear the message
11241 last displayed. */
11243 void
11244 clear_message (bool current_p, bool last_displayed_p)
11246 if (current_p)
11248 echo_area_buffer[0] = Qnil;
11249 message_cleared_p = true;
11252 if (last_displayed_p)
11253 echo_area_buffer[1] = Qnil;
11255 message_buf_print = 0;
11258 /* Clear garbaged frames.
11260 This function is used where the old redisplay called
11261 redraw_garbaged_frames which in turn called redraw_frame which in
11262 turn called clear_frame. The call to clear_frame was a source of
11263 flickering. I believe a clear_frame is not necessary. It should
11264 suffice in the new redisplay to invalidate all current matrices,
11265 and ensure a complete redisplay of all windows. */
11267 static void
11268 clear_garbaged_frames (void)
11270 if (frame_garbaged)
11272 Lisp_Object tail, frame;
11274 FOR_EACH_FRAME (tail, frame)
11276 struct frame *f = XFRAME (frame);
11278 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
11280 if (f->resized_p)
11281 redraw_frame (f);
11282 else
11283 clear_current_matrices (f);
11284 fset_redisplay (f);
11285 f->garbaged = false;
11286 f->resized_p = false;
11290 frame_garbaged = false;
11295 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
11296 is non-zero update selected_frame. Value is non-zero if the
11297 mini-windows height has been changed. */
11299 static bool
11300 echo_area_display (bool update_frame_p)
11302 Lisp_Object mini_window;
11303 struct window *w;
11304 struct frame *f;
11305 bool window_height_changed_p = false;
11306 struct frame *sf = SELECTED_FRAME ();
11308 mini_window = FRAME_MINIBUF_WINDOW (sf);
11309 w = XWINDOW (mini_window);
11310 f = XFRAME (WINDOW_FRAME (w));
11312 /* Don't display if frame is invisible or not yet initialized. */
11313 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
11314 return 0;
11316 #ifdef HAVE_WINDOW_SYSTEM
11317 /* When Emacs starts, selected_frame may be the initial terminal
11318 frame. If we let this through, a message would be displayed on
11319 the terminal. */
11320 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
11321 return 0;
11322 #endif /* HAVE_WINDOW_SYSTEM */
11324 /* Redraw garbaged frames. */
11325 clear_garbaged_frames ();
11327 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
11329 echo_area_window = mini_window;
11330 window_height_changed_p = display_echo_area (w);
11331 w->must_be_updated_p = true;
11333 /* Update the display, unless called from redisplay_internal.
11334 Also don't update the screen during redisplay itself. The
11335 update will happen at the end of redisplay, and an update
11336 here could cause confusion. */
11337 if (update_frame_p && !redisplaying_p)
11339 int n = 0;
11341 /* If the display update has been interrupted by pending
11342 input, update mode lines in the frame. Due to the
11343 pending input, it might have been that redisplay hasn't
11344 been called, so that mode lines above the echo area are
11345 garbaged. This looks odd, so we prevent it here. */
11346 if (!display_completed)
11347 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), false);
11349 if (window_height_changed_p
11350 /* Don't do this if Emacs is shutting down. Redisplay
11351 needs to run hooks. */
11352 && !NILP (Vrun_hooks))
11354 /* Must update other windows. Likewise as in other
11355 cases, don't let this update be interrupted by
11356 pending input. */
11357 ptrdiff_t count = SPECPDL_INDEX ();
11358 specbind (Qredisplay_dont_pause, Qt);
11359 windows_or_buffers_changed = 44;
11360 redisplay_internal ();
11361 unbind_to (count, Qnil);
11363 else if (FRAME_WINDOW_P (f) && n == 0)
11365 /* Window configuration is the same as before.
11366 Can do with a display update of the echo area,
11367 unless we displayed some mode lines. */
11368 update_single_window (w);
11369 flush_frame (f);
11371 else
11372 update_frame (f, true, true);
11374 /* If cursor is in the echo area, make sure that the next
11375 redisplay displays the minibuffer, so that the cursor will
11376 be replaced with what the minibuffer wants. */
11377 if (cursor_in_echo_area)
11378 wset_redisplay (XWINDOW (mini_window));
11381 else if (!EQ (mini_window, selected_window))
11382 wset_redisplay (XWINDOW (mini_window));
11384 /* Last displayed message is now the current message. */
11385 echo_area_buffer[1] = echo_area_buffer[0];
11386 /* Inform read_char that we're not echoing. */
11387 echo_message_buffer = Qnil;
11389 /* Prevent redisplay optimization in redisplay_internal by resetting
11390 this_line_start_pos. This is done because the mini-buffer now
11391 displays the message instead of its buffer text. */
11392 if (EQ (mini_window, selected_window))
11393 CHARPOS (this_line_start_pos) = 0;
11395 return window_height_changed_p;
11398 /* Nonzero if W's buffer was changed but not saved. */
11400 static int
11401 window_buffer_changed (struct window *w)
11403 struct buffer *b = XBUFFER (w->contents);
11405 eassert (BUFFER_LIVE_P (b));
11407 return (((BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) != w->last_had_star));
11410 /* Nonzero if W has %c in its mode line and mode line should be updated. */
11412 static int
11413 mode_line_update_needed (struct window *w)
11415 return (w->column_number_displayed != -1
11416 && !(PT == w->last_point && !window_outdated (w))
11417 && (w->column_number_displayed != current_column ()));
11420 /* Nonzero if window start of W is frozen and may not be changed during
11421 redisplay. */
11423 static bool
11424 window_frozen_p (struct window *w)
11426 if (FRAME_WINDOWS_FROZEN (XFRAME (WINDOW_FRAME (w))))
11428 Lisp_Object window;
11430 XSETWINDOW (window, w);
11431 if (MINI_WINDOW_P (w))
11432 return 0;
11433 else if (EQ (window, selected_window))
11434 return 0;
11435 else if (MINI_WINDOW_P (XWINDOW (selected_window))
11436 && EQ (window, Vminibuf_scroll_window))
11437 /* This special window can't be frozen too. */
11438 return 0;
11439 else
11440 return 1;
11442 return 0;
11445 /***********************************************************************
11446 Mode Lines and Frame Titles
11447 ***********************************************************************/
11449 /* A buffer for constructing non-propertized mode-line strings and
11450 frame titles in it; allocated from the heap in init_xdisp and
11451 resized as needed in store_mode_line_noprop_char. */
11453 static char *mode_line_noprop_buf;
11455 /* The buffer's end, and a current output position in it. */
11457 static char *mode_line_noprop_buf_end;
11458 static char *mode_line_noprop_ptr;
11460 #define MODE_LINE_NOPROP_LEN(start) \
11461 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
11463 static enum {
11464 MODE_LINE_DISPLAY = 0,
11465 MODE_LINE_TITLE,
11466 MODE_LINE_NOPROP,
11467 MODE_LINE_STRING
11468 } mode_line_target;
11470 /* Alist that caches the results of :propertize.
11471 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
11472 static Lisp_Object mode_line_proptrans_alist;
11474 /* List of strings making up the mode-line. */
11475 static Lisp_Object mode_line_string_list;
11477 /* Base face property when building propertized mode line string. */
11478 static Lisp_Object mode_line_string_face;
11479 static Lisp_Object mode_line_string_face_prop;
11482 /* Unwind data for mode line strings */
11484 static Lisp_Object Vmode_line_unwind_vector;
11486 static Lisp_Object
11487 format_mode_line_unwind_data (struct frame *target_frame,
11488 struct buffer *obuf,
11489 Lisp_Object owin,
11490 int save_proptrans)
11492 Lisp_Object vector, tmp;
11494 /* Reduce consing by keeping one vector in
11495 Vwith_echo_area_save_vector. */
11496 vector = Vmode_line_unwind_vector;
11497 Vmode_line_unwind_vector = Qnil;
11499 if (NILP (vector))
11500 vector = Fmake_vector (make_number (10), Qnil);
11502 ASET (vector, 0, make_number (mode_line_target));
11503 ASET (vector, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
11504 ASET (vector, 2, mode_line_string_list);
11505 ASET (vector, 3, save_proptrans ? mode_line_proptrans_alist : Qt);
11506 ASET (vector, 4, mode_line_string_face);
11507 ASET (vector, 5, mode_line_string_face_prop);
11509 if (obuf)
11510 XSETBUFFER (tmp, obuf);
11511 else
11512 tmp = Qnil;
11513 ASET (vector, 6, tmp);
11514 ASET (vector, 7, owin);
11515 if (target_frame)
11517 /* Similarly to `with-selected-window', if the operation selects
11518 a window on another frame, we must restore that frame's
11519 selected window, and (for a tty) the top-frame. */
11520 ASET (vector, 8, target_frame->selected_window);
11521 if (FRAME_TERMCAP_P (target_frame))
11522 ASET (vector, 9, FRAME_TTY (target_frame)->top_frame);
11525 return vector;
11528 static void
11529 unwind_format_mode_line (Lisp_Object vector)
11531 Lisp_Object old_window = AREF (vector, 7);
11532 Lisp_Object target_frame_window = AREF (vector, 8);
11533 Lisp_Object old_top_frame = AREF (vector, 9);
11535 mode_line_target = XINT (AREF (vector, 0));
11536 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
11537 mode_line_string_list = AREF (vector, 2);
11538 if (! EQ (AREF (vector, 3), Qt))
11539 mode_line_proptrans_alist = AREF (vector, 3);
11540 mode_line_string_face = AREF (vector, 4);
11541 mode_line_string_face_prop = AREF (vector, 5);
11543 /* Select window before buffer, since it may change the buffer. */
11544 if (!NILP (old_window))
11546 /* If the operation that we are unwinding had selected a window
11547 on a different frame, reset its frame-selected-window. For a
11548 text terminal, reset its top-frame if necessary. */
11549 if (!NILP (target_frame_window))
11551 Lisp_Object frame
11552 = WINDOW_FRAME (XWINDOW (target_frame_window));
11554 if (!EQ (frame, WINDOW_FRAME (XWINDOW (old_window))))
11555 Fselect_window (target_frame_window, Qt);
11557 if (!NILP (old_top_frame) && !EQ (old_top_frame, frame))
11558 Fselect_frame (old_top_frame, Qt);
11561 Fselect_window (old_window, Qt);
11564 if (!NILP (AREF (vector, 6)))
11566 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
11567 ASET (vector, 6, Qnil);
11570 Vmode_line_unwind_vector = vector;
11574 /* Store a single character C for the frame title in mode_line_noprop_buf.
11575 Re-allocate mode_line_noprop_buf if necessary. */
11577 static void
11578 store_mode_line_noprop_char (char c)
11580 /* If output position has reached the end of the allocated buffer,
11581 increase the buffer's size. */
11582 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
11584 ptrdiff_t len = MODE_LINE_NOPROP_LEN (0);
11585 ptrdiff_t size = len;
11586 mode_line_noprop_buf =
11587 xpalloc (mode_line_noprop_buf, &size, 1, STRING_BYTES_BOUND, 1);
11588 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
11589 mode_line_noprop_ptr = mode_line_noprop_buf + len;
11592 *mode_line_noprop_ptr++ = c;
11596 /* Store part of a frame title in mode_line_noprop_buf, beginning at
11597 mode_line_noprop_ptr. STRING is the string to store. Do not copy
11598 characters that yield more columns than PRECISION; PRECISION <= 0
11599 means copy the whole string. Pad with spaces until FIELD_WIDTH
11600 number of characters have been copied; FIELD_WIDTH <= 0 means don't
11601 pad. Called from display_mode_element when it is used to build a
11602 frame title. */
11604 static int
11605 store_mode_line_noprop (const char *string, int field_width, int precision)
11607 const unsigned char *str = (const unsigned char *) string;
11608 int n = 0;
11609 ptrdiff_t dummy, nbytes;
11611 /* Copy at most PRECISION chars from STR. */
11612 nbytes = strlen (string);
11613 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
11614 while (nbytes--)
11615 store_mode_line_noprop_char (*str++);
11617 /* Fill up with spaces until FIELD_WIDTH reached. */
11618 while (field_width > 0
11619 && n < field_width)
11621 store_mode_line_noprop_char (' ');
11622 ++n;
11625 return n;
11628 /***********************************************************************
11629 Frame Titles
11630 ***********************************************************************/
11632 #ifdef HAVE_WINDOW_SYSTEM
11634 /* Set the title of FRAME, if it has changed. The title format is
11635 Vicon_title_format if FRAME is iconified, otherwise it is
11636 frame_title_format. */
11638 static void
11639 x_consider_frame_title (Lisp_Object frame)
11641 struct frame *f = XFRAME (frame);
11643 if (FRAME_WINDOW_P (f)
11644 || FRAME_MINIBUF_ONLY_P (f)
11645 || f->explicit_name)
11647 /* Do we have more than one visible frame on this X display? */
11648 Lisp_Object tail, other_frame, fmt;
11649 ptrdiff_t title_start;
11650 char *title;
11651 ptrdiff_t len;
11652 struct it it;
11653 ptrdiff_t count = SPECPDL_INDEX ();
11655 FOR_EACH_FRAME (tail, other_frame)
11657 struct frame *tf = XFRAME (other_frame);
11659 if (tf != f
11660 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
11661 && !FRAME_MINIBUF_ONLY_P (tf)
11662 && !EQ (other_frame, tip_frame)
11663 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
11664 break;
11667 /* Set global variable indicating that multiple frames exist. */
11668 multiple_frames = CONSP (tail);
11670 /* Switch to the buffer of selected window of the frame. Set up
11671 mode_line_target so that display_mode_element will output into
11672 mode_line_noprop_buf; then display the title. */
11673 record_unwind_protect (unwind_format_mode_line,
11674 format_mode_line_unwind_data
11675 (f, current_buffer, selected_window, 0));
11677 Fselect_window (f->selected_window, Qt);
11678 set_buffer_internal_1
11679 (XBUFFER (XWINDOW (f->selected_window)->contents));
11680 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
11682 mode_line_target = MODE_LINE_TITLE;
11683 title_start = MODE_LINE_NOPROP_LEN (0);
11684 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
11685 NULL, DEFAULT_FACE_ID);
11686 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
11687 len = MODE_LINE_NOPROP_LEN (title_start);
11688 title = mode_line_noprop_buf + title_start;
11689 unbind_to (count, Qnil);
11691 /* Set the title only if it's changed. This avoids consing in
11692 the common case where it hasn't. (If it turns out that we've
11693 already wasted too much time by walking through the list with
11694 display_mode_element, then we might need to optimize at a
11695 higher level than this.) */
11696 if (! STRINGP (f->name)
11697 || SBYTES (f->name) != len
11698 || memcmp (title, SDATA (f->name), len) != 0)
11699 x_implicitly_set_name (f, make_string (title, len), Qnil);
11703 #endif /* not HAVE_WINDOW_SYSTEM */
11706 /***********************************************************************
11707 Menu Bars
11708 ***********************************************************************/
11710 /* Non-zero if we will not redisplay all visible windows. */
11711 #define REDISPLAY_SOME_P() \
11712 ((windows_or_buffers_changed == 0 \
11713 || windows_or_buffers_changed == REDISPLAY_SOME) \
11714 && (update_mode_lines == 0 \
11715 || update_mode_lines == REDISPLAY_SOME))
11717 /* Prepare for redisplay by updating menu-bar item lists when
11718 appropriate. This can call eval. */
11720 static void
11721 prepare_menu_bars (void)
11723 bool all_windows = windows_or_buffers_changed || update_mode_lines;
11724 bool some_windows = REDISPLAY_SOME_P ();
11725 struct gcpro gcpro1, gcpro2;
11726 Lisp_Object tooltip_frame;
11728 #ifdef HAVE_WINDOW_SYSTEM
11729 tooltip_frame = tip_frame;
11730 #else
11731 tooltip_frame = Qnil;
11732 #endif
11734 if (FUNCTIONP (Vpre_redisplay_function))
11736 Lisp_Object windows = all_windows ? Qt : Qnil;
11737 if (all_windows && some_windows)
11739 Lisp_Object ws = window_list ();
11740 for (windows = Qnil; CONSP (ws); ws = XCDR (ws))
11742 Lisp_Object this = XCAR (ws);
11743 struct window *w = XWINDOW (this);
11744 if (w->redisplay
11745 || XFRAME (w->frame)->redisplay
11746 || XBUFFER (w->contents)->text->redisplay)
11748 windows = Fcons (this, windows);
11752 safe__call1 (true, Vpre_redisplay_function, windows);
11755 /* Update all frame titles based on their buffer names, etc. We do
11756 this before the menu bars so that the buffer-menu will show the
11757 up-to-date frame titles. */
11758 #ifdef HAVE_WINDOW_SYSTEM
11759 if (all_windows)
11761 Lisp_Object tail, frame;
11763 FOR_EACH_FRAME (tail, frame)
11765 struct frame *f = XFRAME (frame);
11766 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
11767 if (some_windows
11768 && !f->redisplay
11769 && !w->redisplay
11770 && !XBUFFER (w->contents)->text->redisplay)
11771 continue;
11773 if (!EQ (frame, tooltip_frame)
11774 && (FRAME_ICONIFIED_P (f)
11775 || FRAME_VISIBLE_P (f) == 1
11776 /* Exclude TTY frames that are obscured because they
11777 are not the top frame on their console. This is
11778 because x_consider_frame_title actually switches
11779 to the frame, which for TTY frames means it is
11780 marked as garbaged, and will be completely
11781 redrawn on the next redisplay cycle. This causes
11782 TTY frames to be completely redrawn, when there
11783 are more than one of them, even though nothing
11784 should be changed on display. */
11785 || (FRAME_VISIBLE_P (f) == 2 && FRAME_WINDOW_P (f))))
11786 x_consider_frame_title (frame);
11789 #endif /* HAVE_WINDOW_SYSTEM */
11791 /* Update the menu bar item lists, if appropriate. This has to be
11792 done before any actual redisplay or generation of display lines. */
11794 if (all_windows)
11796 Lisp_Object tail, frame;
11797 ptrdiff_t count = SPECPDL_INDEX ();
11798 /* 1 means that update_menu_bar has run its hooks
11799 so any further calls to update_menu_bar shouldn't do so again. */
11800 int menu_bar_hooks_run = 0;
11802 record_unwind_save_match_data ();
11804 FOR_EACH_FRAME (tail, frame)
11806 struct frame *f = XFRAME (frame);
11807 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
11809 /* Ignore tooltip frame. */
11810 if (EQ (frame, tooltip_frame))
11811 continue;
11813 if (some_windows
11814 && !f->redisplay
11815 && !w->redisplay
11816 && !XBUFFER (w->contents)->text->redisplay)
11817 continue;
11819 /* If a window on this frame changed size, report that to
11820 the user and clear the size-change flag. */
11821 if (FRAME_WINDOW_SIZES_CHANGED (f))
11823 Lisp_Object functions;
11825 /* Clear flag first in case we get an error below. */
11826 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
11827 functions = Vwindow_size_change_functions;
11828 GCPRO2 (tail, functions);
11830 while (CONSP (functions))
11832 if (!EQ (XCAR (functions), Qt))
11833 call1 (XCAR (functions), frame);
11834 functions = XCDR (functions);
11836 UNGCPRO;
11839 GCPRO1 (tail);
11840 menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
11841 #ifdef HAVE_WINDOW_SYSTEM
11842 update_tool_bar (f, 0);
11843 #endif
11844 UNGCPRO;
11847 unbind_to (count, Qnil);
11849 else
11851 struct frame *sf = SELECTED_FRAME ();
11852 update_menu_bar (sf, 1, 0);
11853 #ifdef HAVE_WINDOW_SYSTEM
11854 update_tool_bar (sf, 1);
11855 #endif
11860 /* Update the menu bar item list for frame F. This has to be done
11861 before we start to fill in any display lines, because it can call
11862 eval.
11864 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
11866 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
11867 already ran the menu bar hooks for this redisplay, so there
11868 is no need to run them again. The return value is the
11869 updated value of this flag, to pass to the next call. */
11871 static int
11872 update_menu_bar (struct frame *f, int save_match_data, int hooks_run)
11874 Lisp_Object window;
11875 register struct window *w;
11877 /* If called recursively during a menu update, do nothing. This can
11878 happen when, for instance, an activate-menubar-hook causes a
11879 redisplay. */
11880 if (inhibit_menubar_update)
11881 return hooks_run;
11883 window = FRAME_SELECTED_WINDOW (f);
11884 w = XWINDOW (window);
11886 if (FRAME_WINDOW_P (f)
11888 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11889 || defined (HAVE_NS) || defined (USE_GTK)
11890 FRAME_EXTERNAL_MENU_BAR (f)
11891 #else
11892 FRAME_MENU_BAR_LINES (f) > 0
11893 #endif
11894 : FRAME_MENU_BAR_LINES (f) > 0)
11896 /* If the user has switched buffers or windows, we need to
11897 recompute to reflect the new bindings. But we'll
11898 recompute when update_mode_lines is set too; that means
11899 that people can use force-mode-line-update to request
11900 that the menu bar be recomputed. The adverse effect on
11901 the rest of the redisplay algorithm is about the same as
11902 windows_or_buffers_changed anyway. */
11903 if (windows_or_buffers_changed
11904 /* This used to test w->update_mode_line, but we believe
11905 there is no need to recompute the menu in that case. */
11906 || update_mode_lines
11907 || window_buffer_changed (w))
11909 struct buffer *prev = current_buffer;
11910 ptrdiff_t count = SPECPDL_INDEX ();
11912 specbind (Qinhibit_menubar_update, Qt);
11914 set_buffer_internal_1 (XBUFFER (w->contents));
11915 if (save_match_data)
11916 record_unwind_save_match_data ();
11917 if (NILP (Voverriding_local_map_menu_flag))
11919 specbind (Qoverriding_terminal_local_map, Qnil);
11920 specbind (Qoverriding_local_map, Qnil);
11923 if (!hooks_run)
11925 /* Run the Lucid hook. */
11926 safe_run_hooks (Qactivate_menubar_hook);
11928 /* If it has changed current-menubar from previous value,
11929 really recompute the menu-bar from the value. */
11930 if (! NILP (Vlucid_menu_bar_dirty_flag))
11931 call0 (Qrecompute_lucid_menubar);
11933 safe_run_hooks (Qmenu_bar_update_hook);
11935 hooks_run = 1;
11938 XSETFRAME (Vmenu_updating_frame, f);
11939 fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f)));
11941 /* Redisplay the menu bar in case we changed it. */
11942 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11943 || defined (HAVE_NS) || defined (USE_GTK)
11944 if (FRAME_WINDOW_P (f))
11946 #if defined (HAVE_NS)
11947 /* All frames on Mac OS share the same menubar. So only
11948 the selected frame should be allowed to set it. */
11949 if (f == SELECTED_FRAME ())
11950 #endif
11951 set_frame_menubar (f, 0, 0);
11953 else
11954 /* On a terminal screen, the menu bar is an ordinary screen
11955 line, and this makes it get updated. */
11956 w->update_mode_line = 1;
11957 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11958 /* In the non-toolkit version, the menu bar is an ordinary screen
11959 line, and this makes it get updated. */
11960 w->update_mode_line = 1;
11961 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11963 unbind_to (count, Qnil);
11964 set_buffer_internal_1 (prev);
11968 return hooks_run;
11971 /***********************************************************************
11972 Tool-bars
11973 ***********************************************************************/
11975 #ifdef HAVE_WINDOW_SYSTEM
11977 /* Select `frame' temporarily without running all the code in
11978 do_switch_frame.
11979 FIXME: Maybe do_switch_frame should be trimmed down similarly
11980 when `norecord' is set. */
11981 static void
11982 fast_set_selected_frame (Lisp_Object frame)
11984 if (!EQ (selected_frame, frame))
11986 selected_frame = frame;
11987 selected_window = XFRAME (frame)->selected_window;
11991 /* Update the tool-bar item list for frame F. This has to be done
11992 before we start to fill in any display lines. Called from
11993 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
11994 and restore it here. */
11996 static void
11997 update_tool_bar (struct frame *f, int save_match_data)
11999 #if defined (USE_GTK) || defined (HAVE_NS)
12000 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
12001 #else
12002 int do_update = (WINDOWP (f->tool_bar_window)
12003 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0);
12004 #endif
12006 if (do_update)
12008 Lisp_Object window;
12009 struct window *w;
12011 window = FRAME_SELECTED_WINDOW (f);
12012 w = XWINDOW (window);
12014 /* If the user has switched buffers or windows, we need to
12015 recompute to reflect the new bindings. But we'll
12016 recompute when update_mode_lines is set too; that means
12017 that people can use force-mode-line-update to request
12018 that the menu bar be recomputed. The adverse effect on
12019 the rest of the redisplay algorithm is about the same as
12020 windows_or_buffers_changed anyway. */
12021 if (windows_or_buffers_changed
12022 || w->update_mode_line
12023 || update_mode_lines
12024 || window_buffer_changed (w))
12026 struct buffer *prev = current_buffer;
12027 ptrdiff_t count = SPECPDL_INDEX ();
12028 Lisp_Object frame, new_tool_bar;
12029 int new_n_tool_bar;
12030 struct gcpro gcpro1;
12032 /* Set current_buffer to the buffer of the selected
12033 window of the frame, so that we get the right local
12034 keymaps. */
12035 set_buffer_internal_1 (XBUFFER (w->contents));
12037 /* Save match data, if we must. */
12038 if (save_match_data)
12039 record_unwind_save_match_data ();
12041 /* Make sure that we don't accidentally use bogus keymaps. */
12042 if (NILP (Voverriding_local_map_menu_flag))
12044 specbind (Qoverriding_terminal_local_map, Qnil);
12045 specbind (Qoverriding_local_map, Qnil);
12048 GCPRO1 (new_tool_bar);
12050 /* We must temporarily set the selected frame to this frame
12051 before calling tool_bar_items, because the calculation of
12052 the tool-bar keymap uses the selected frame (see
12053 `tool-bar-make-keymap' in tool-bar.el). */
12054 eassert (EQ (selected_window,
12055 /* Since we only explicitly preserve selected_frame,
12056 check that selected_window would be redundant. */
12057 XFRAME (selected_frame)->selected_window));
12058 record_unwind_protect (fast_set_selected_frame, selected_frame);
12059 XSETFRAME (frame, f);
12060 fast_set_selected_frame (frame);
12062 /* Build desired tool-bar items from keymaps. */
12063 new_tool_bar
12064 = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
12065 &new_n_tool_bar);
12067 /* Redisplay the tool-bar if we changed it. */
12068 if (new_n_tool_bar != f->n_tool_bar_items
12069 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
12071 /* Redisplay that happens asynchronously due to an expose event
12072 may access f->tool_bar_items. Make sure we update both
12073 variables within BLOCK_INPUT so no such event interrupts. */
12074 block_input ();
12075 fset_tool_bar_items (f, new_tool_bar);
12076 f->n_tool_bar_items = new_n_tool_bar;
12077 w->update_mode_line = 1;
12078 unblock_input ();
12081 UNGCPRO;
12083 unbind_to (count, Qnil);
12084 set_buffer_internal_1 (prev);
12089 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
12091 /* Set F->desired_tool_bar_string to a Lisp string representing frame
12092 F's desired tool-bar contents. F->tool_bar_items must have
12093 been set up previously by calling prepare_menu_bars. */
12095 static void
12096 build_desired_tool_bar_string (struct frame *f)
12098 int i, size, size_needed;
12099 struct gcpro gcpro1, gcpro2;
12100 Lisp_Object image, plist;
12102 image = plist = Qnil;
12103 GCPRO2 (image, plist);
12105 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
12106 Otherwise, make a new string. */
12108 /* The size of the string we might be able to reuse. */
12109 size = (STRINGP (f->desired_tool_bar_string)
12110 ? SCHARS (f->desired_tool_bar_string)
12111 : 0);
12113 /* We need one space in the string for each image. */
12114 size_needed = f->n_tool_bar_items;
12116 /* Reuse f->desired_tool_bar_string, if possible. */
12117 if (size < size_needed || NILP (f->desired_tool_bar_string))
12118 fset_desired_tool_bar_string
12119 (f, Fmake_string (make_number (size_needed), make_number (' ')));
12120 else
12122 AUTO_LIST4 (props, Qdisplay, Qnil, Qmenu_item, Qnil);
12123 struct gcpro gcpro1;
12124 GCPRO1 (props);
12125 Fremove_text_properties (make_number (0), make_number (size),
12126 props, f->desired_tool_bar_string);
12127 UNGCPRO;
12130 /* Put a `display' property on the string for the images to display,
12131 put a `menu_item' property on tool-bar items with a value that
12132 is the index of the item in F's tool-bar item vector. */
12133 for (i = 0; i < f->n_tool_bar_items; ++i)
12135 #define PROP(IDX) \
12136 AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
12138 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
12139 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
12140 int hmargin, vmargin, relief, idx, end;
12142 /* If image is a vector, choose the image according to the
12143 button state. */
12144 image = PROP (TOOL_BAR_ITEM_IMAGES);
12145 if (VECTORP (image))
12147 if (enabled_p)
12148 idx = (selected_p
12149 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
12150 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
12151 else
12152 idx = (selected_p
12153 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
12154 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
12156 eassert (ASIZE (image) >= idx);
12157 image = AREF (image, idx);
12159 else
12160 idx = -1;
12162 /* Ignore invalid image specifications. */
12163 if (!valid_image_p (image))
12164 continue;
12166 /* Display the tool-bar button pressed, or depressed. */
12167 plist = Fcopy_sequence (XCDR (image));
12169 /* Compute margin and relief to draw. */
12170 relief = (tool_bar_button_relief >= 0
12171 ? tool_bar_button_relief
12172 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
12173 hmargin = vmargin = relief;
12175 if (RANGED_INTEGERP (1, Vtool_bar_button_margin,
12176 INT_MAX - max (hmargin, vmargin)))
12178 hmargin += XFASTINT (Vtool_bar_button_margin);
12179 vmargin += XFASTINT (Vtool_bar_button_margin);
12181 else if (CONSP (Vtool_bar_button_margin))
12183 if (RANGED_INTEGERP (1, XCAR (Vtool_bar_button_margin),
12184 INT_MAX - hmargin))
12185 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
12187 if (RANGED_INTEGERP (1, XCDR (Vtool_bar_button_margin),
12188 INT_MAX - vmargin))
12189 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
12192 if (auto_raise_tool_bar_buttons_p)
12194 /* Add a `:relief' property to the image spec if the item is
12195 selected. */
12196 if (selected_p)
12198 plist = Fplist_put (plist, QCrelief, make_number (-relief));
12199 hmargin -= relief;
12200 vmargin -= relief;
12203 else
12205 /* If image is selected, display it pressed, i.e. with a
12206 negative relief. If it's not selected, display it with a
12207 raised relief. */
12208 plist = Fplist_put (plist, QCrelief,
12209 (selected_p
12210 ? make_number (-relief)
12211 : make_number (relief)));
12212 hmargin -= relief;
12213 vmargin -= relief;
12216 /* Put a margin around the image. */
12217 if (hmargin || vmargin)
12219 if (hmargin == vmargin)
12220 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
12221 else
12222 plist = Fplist_put (plist, QCmargin,
12223 Fcons (make_number (hmargin),
12224 make_number (vmargin)));
12227 /* If button is not enabled, and we don't have special images
12228 for the disabled state, make the image appear disabled by
12229 applying an appropriate algorithm to it. */
12230 if (!enabled_p && idx < 0)
12231 plist = Fplist_put (plist, QCconversion, Qdisabled);
12233 /* Put a `display' text property on the string for the image to
12234 display. Put a `menu-item' property on the string that gives
12235 the start of this item's properties in the tool-bar items
12236 vector. */
12237 image = Fcons (Qimage, plist);
12238 AUTO_LIST4 (props, Qdisplay, image, Qmenu_item,
12239 make_number (i * TOOL_BAR_ITEM_NSLOTS));
12240 struct gcpro gcpro1;
12241 GCPRO1 (props);
12243 /* Let the last image hide all remaining spaces in the tool bar
12244 string. The string can be longer than needed when we reuse a
12245 previous string. */
12246 if (i + 1 == f->n_tool_bar_items)
12247 end = SCHARS (f->desired_tool_bar_string);
12248 else
12249 end = i + 1;
12250 Fadd_text_properties (make_number (i), make_number (end),
12251 props, f->desired_tool_bar_string);
12252 UNGCPRO;
12253 #undef PROP
12256 UNGCPRO;
12260 /* Display one line of the tool-bar of frame IT->f.
12262 HEIGHT specifies the desired height of the tool-bar line.
12263 If the actual height of the glyph row is less than HEIGHT, the
12264 row's height is increased to HEIGHT, and the icons are centered
12265 vertically in the new height.
12267 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
12268 count a final empty row in case the tool-bar width exactly matches
12269 the window width.
12272 static void
12273 display_tool_bar_line (struct it *it, int height)
12275 struct glyph_row *row = it->glyph_row;
12276 int max_x = it->last_visible_x;
12277 struct glyph *last;
12279 /* Don't extend on a previously drawn tool bar items (Bug#16058). */
12280 clear_glyph_row (row);
12281 row->enabled_p = true;
12282 row->y = it->current_y;
12284 /* Note that this isn't made use of if the face hasn't a box,
12285 so there's no need to check the face here. */
12286 it->start_of_box_run_p = 1;
12288 while (it->current_x < max_x)
12290 int x, n_glyphs_before, i, nglyphs;
12291 struct it it_before;
12293 /* Get the next display element. */
12294 if (!get_next_display_element (it))
12296 /* Don't count empty row if we are counting needed tool-bar lines. */
12297 if (height < 0 && !it->hpos)
12298 return;
12299 break;
12302 /* Produce glyphs. */
12303 n_glyphs_before = row->used[TEXT_AREA];
12304 it_before = *it;
12306 PRODUCE_GLYPHS (it);
12308 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
12309 i = 0;
12310 x = it_before.current_x;
12311 while (i < nglyphs)
12313 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
12315 if (x + glyph->pixel_width > max_x)
12317 /* Glyph doesn't fit on line. Backtrack. */
12318 row->used[TEXT_AREA] = n_glyphs_before;
12319 *it = it_before;
12320 /* If this is the only glyph on this line, it will never fit on the
12321 tool-bar, so skip it. But ensure there is at least one glyph,
12322 so we don't accidentally disable the tool-bar. */
12323 if (n_glyphs_before == 0
12324 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
12325 break;
12326 goto out;
12329 ++it->hpos;
12330 x += glyph->pixel_width;
12331 ++i;
12334 /* Stop at line end. */
12335 if (ITERATOR_AT_END_OF_LINE_P (it))
12336 break;
12338 set_iterator_to_next (it, 1);
12341 out:;
12343 row->displays_text_p = row->used[TEXT_AREA] != 0;
12345 /* Use default face for the border below the tool bar.
12347 FIXME: When auto-resize-tool-bars is grow-only, there is
12348 no additional border below the possibly empty tool-bar lines.
12349 So to make the extra empty lines look "normal", we have to
12350 use the tool-bar face for the border too. */
12351 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
12352 && !EQ (Vauto_resize_tool_bars, Qgrow_only))
12353 it->face_id = DEFAULT_FACE_ID;
12355 extend_face_to_end_of_line (it);
12356 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
12357 last->right_box_line_p = 1;
12358 if (last == row->glyphs[TEXT_AREA])
12359 last->left_box_line_p = 1;
12361 /* Make line the desired height and center it vertically. */
12362 if ((height -= it->max_ascent + it->max_descent) > 0)
12364 /* Don't add more than one line height. */
12365 height %= FRAME_LINE_HEIGHT (it->f);
12366 it->max_ascent += height / 2;
12367 it->max_descent += (height + 1) / 2;
12370 compute_line_metrics (it);
12372 /* If line is empty, make it occupy the rest of the tool-bar. */
12373 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row))
12375 row->height = row->phys_height = it->last_visible_y - row->y;
12376 row->visible_height = row->height;
12377 row->ascent = row->phys_ascent = 0;
12378 row->extra_line_spacing = 0;
12381 row->full_width_p = 1;
12382 row->continued_p = 0;
12383 row->truncated_on_left_p = 0;
12384 row->truncated_on_right_p = 0;
12386 it->current_x = it->hpos = 0;
12387 it->current_y += row->height;
12388 ++it->vpos;
12389 ++it->glyph_row;
12393 /* Value is the number of pixels needed to make all tool-bar items of
12394 frame F visible. The actual number of glyph rows needed is
12395 returned in *N_ROWS if non-NULL. */
12396 static int
12397 tool_bar_height (struct frame *f, int *n_rows, bool pixelwise)
12399 struct window *w = XWINDOW (f->tool_bar_window);
12400 struct it it;
12401 /* tool_bar_height is called from redisplay_tool_bar after building
12402 the desired matrix, so use (unused) mode-line row as temporary row to
12403 avoid destroying the first tool-bar row. */
12404 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
12406 /* Initialize an iterator for iteration over
12407 F->desired_tool_bar_string in the tool-bar window of frame F. */
12408 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
12409 temp_row->reversed_p = false;
12410 it.first_visible_x = 0;
12411 it.last_visible_x = WINDOW_PIXEL_WIDTH (w);
12412 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
12413 it.paragraph_embedding = L2R;
12415 while (!ITERATOR_AT_END_P (&it))
12417 clear_glyph_row (temp_row);
12418 it.glyph_row = temp_row;
12419 display_tool_bar_line (&it, -1);
12421 clear_glyph_row (temp_row);
12423 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
12424 if (n_rows)
12425 *n_rows = it.vpos > 0 ? it.vpos : -1;
12427 if (pixelwise)
12428 return it.current_y;
12429 else
12430 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
12433 #endif /* !USE_GTK && !HAVE_NS */
12435 DEFUN ("tool-bar-height", Ftool_bar_height, Stool_bar_height,
12436 0, 2, 0,
12437 doc: /* Return the number of lines occupied by the tool bar of FRAME.
12438 If FRAME is nil or omitted, use the selected frame. Optional argument
12439 PIXELWISE non-nil means return the height of the tool bar in pixels. */)
12440 (Lisp_Object frame, Lisp_Object pixelwise)
12442 int height = 0;
12444 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
12445 struct frame *f = decode_any_frame (frame);
12447 if (WINDOWP (f->tool_bar_window)
12448 && WINDOW_PIXEL_HEIGHT (XWINDOW (f->tool_bar_window)) > 0)
12450 update_tool_bar (f, 1);
12451 if (f->n_tool_bar_items)
12453 build_desired_tool_bar_string (f);
12454 height = tool_bar_height (f, NULL, NILP (pixelwise) ? 0 : 1);
12457 #endif
12459 return make_number (height);
12463 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
12464 height should be changed. */
12465 static int
12466 redisplay_tool_bar (struct frame *f)
12468 #if defined (USE_GTK) || defined (HAVE_NS)
12470 if (FRAME_EXTERNAL_TOOL_BAR (f))
12471 update_frame_tool_bar (f);
12472 return 0;
12474 #else /* !USE_GTK && !HAVE_NS */
12476 struct window *w;
12477 struct it it;
12478 struct glyph_row *row;
12480 /* If frame hasn't a tool-bar window or if it is zero-height, don't
12481 do anything. This means you must start with tool-bar-lines
12482 non-zero to get the auto-sizing effect. Or in other words, you
12483 can turn off tool-bars by specifying tool-bar-lines zero. */
12484 if (!WINDOWP (f->tool_bar_window)
12485 || (w = XWINDOW (f->tool_bar_window),
12486 WINDOW_TOTAL_LINES (w) == 0))
12487 return 0;
12489 /* Set up an iterator for the tool-bar window. */
12490 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
12491 it.first_visible_x = 0;
12492 it.last_visible_x = WINDOW_PIXEL_WIDTH (w);
12493 row = it.glyph_row;
12494 row->reversed_p = false;
12496 /* Build a string that represents the contents of the tool-bar. */
12497 build_desired_tool_bar_string (f);
12498 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
12499 /* FIXME: This should be controlled by a user option. But it
12500 doesn't make sense to have an R2L tool bar if the menu bar cannot
12501 be drawn also R2L, and making the menu bar R2L is tricky due
12502 toolkit-specific code that implements it. If an R2L tool bar is
12503 ever supported, display_tool_bar_line should also be augmented to
12504 call unproduce_glyphs like display_line and display_string
12505 do. */
12506 it.paragraph_embedding = L2R;
12508 if (f->n_tool_bar_rows == 0)
12510 int new_height = tool_bar_height (f, &f->n_tool_bar_rows, 1);
12512 if (new_height != WINDOW_PIXEL_HEIGHT (w))
12514 x_change_tool_bar_height (f, new_height);
12515 /* Always do that now. */
12516 clear_glyph_matrix (w->desired_matrix);
12517 f->fonts_changed = 1;
12518 return 1;
12522 /* Display as many lines as needed to display all tool-bar items. */
12524 if (f->n_tool_bar_rows > 0)
12526 int border, rows, height, extra;
12528 if (TYPE_RANGED_INTEGERP (int, Vtool_bar_border))
12529 border = XINT (Vtool_bar_border);
12530 else if (EQ (Vtool_bar_border, Qinternal_border_width))
12531 border = FRAME_INTERNAL_BORDER_WIDTH (f);
12532 else if (EQ (Vtool_bar_border, Qborder_width))
12533 border = f->border_width;
12534 else
12535 border = 0;
12536 if (border < 0)
12537 border = 0;
12539 rows = f->n_tool_bar_rows;
12540 height = max (1, (it.last_visible_y - border) / rows);
12541 extra = it.last_visible_y - border - height * rows;
12543 while (it.current_y < it.last_visible_y)
12545 int h = 0;
12546 if (extra > 0 && rows-- > 0)
12548 h = (extra + rows - 1) / rows;
12549 extra -= h;
12551 display_tool_bar_line (&it, height + h);
12554 else
12556 while (it.current_y < it.last_visible_y)
12557 display_tool_bar_line (&it, 0);
12560 /* It doesn't make much sense to try scrolling in the tool-bar
12561 window, so don't do it. */
12562 w->desired_matrix->no_scrolling_p = 1;
12563 w->must_be_updated_p = 1;
12565 if (!NILP (Vauto_resize_tool_bars))
12567 int change_height_p = 0;
12569 /* If we couldn't display everything, change the tool-bar's
12570 height if there is room for more. */
12571 if (IT_STRING_CHARPOS (it) < it.end_charpos)
12572 change_height_p = 1;
12574 /* We subtract 1 because display_tool_bar_line advances the
12575 glyph_row pointer before returning to its caller. We want to
12576 examine the last glyph row produced by
12577 display_tool_bar_line. */
12578 row = it.glyph_row - 1;
12580 /* If there are blank lines at the end, except for a partially
12581 visible blank line at the end that is smaller than
12582 FRAME_LINE_HEIGHT, change the tool-bar's height. */
12583 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
12584 && row->height >= FRAME_LINE_HEIGHT (f))
12585 change_height_p = 1;
12587 /* If row displays tool-bar items, but is partially visible,
12588 change the tool-bar's height. */
12589 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12590 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
12591 change_height_p = 1;
12593 /* Resize windows as needed by changing the `tool-bar-lines'
12594 frame parameter. */
12595 if (change_height_p)
12597 int nrows;
12598 int new_height = tool_bar_height (f, &nrows, 1);
12600 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
12601 && !f->minimize_tool_bar_window_p)
12602 ? (new_height > WINDOW_PIXEL_HEIGHT (w))
12603 : (new_height != WINDOW_PIXEL_HEIGHT (w)));
12604 f->minimize_tool_bar_window_p = 0;
12606 if (change_height_p)
12608 x_change_tool_bar_height (f, new_height);
12609 clear_glyph_matrix (w->desired_matrix);
12610 f->n_tool_bar_rows = nrows;
12611 f->fonts_changed = 1;
12613 return 1;
12618 f->minimize_tool_bar_window_p = 0;
12619 return 0;
12621 #endif /* USE_GTK || HAVE_NS */
12624 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
12626 /* Get information about the tool-bar item which is displayed in GLYPH
12627 on frame F. Return in *PROP_IDX the index where tool-bar item
12628 properties start in F->tool_bar_items. Value is zero if
12629 GLYPH doesn't display a tool-bar item. */
12631 static int
12632 tool_bar_item_info (struct frame *f, struct glyph *glyph, int *prop_idx)
12634 Lisp_Object prop;
12635 int success_p;
12636 int charpos;
12638 /* This function can be called asynchronously, which means we must
12639 exclude any possibility that Fget_text_property signals an
12640 error. */
12641 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
12642 charpos = max (0, charpos);
12644 /* Get the text property `menu-item' at pos. The value of that
12645 property is the start index of this item's properties in
12646 F->tool_bar_items. */
12647 prop = Fget_text_property (make_number (charpos),
12648 Qmenu_item, f->current_tool_bar_string);
12649 if (INTEGERP (prop))
12651 *prop_idx = XINT (prop);
12652 success_p = 1;
12654 else
12655 success_p = 0;
12657 return success_p;
12661 /* Get information about the tool-bar item at position X/Y on frame F.
12662 Return in *GLYPH a pointer to the glyph of the tool-bar item in
12663 the current matrix of the tool-bar window of F, or NULL if not
12664 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
12665 item in F->tool_bar_items. Value is
12667 -1 if X/Y is not on a tool-bar item
12668 0 if X/Y is on the same item that was highlighted before.
12669 1 otherwise. */
12671 static int
12672 get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
12673 int *hpos, int *vpos, int *prop_idx)
12675 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12676 struct window *w = XWINDOW (f->tool_bar_window);
12677 int area;
12679 /* Find the glyph under X/Y. */
12680 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
12681 if (*glyph == NULL)
12682 return -1;
12684 /* Get the start of this tool-bar item's properties in
12685 f->tool_bar_items. */
12686 if (!tool_bar_item_info (f, *glyph, prop_idx))
12687 return -1;
12689 /* Is mouse on the highlighted item? */
12690 if (EQ (f->tool_bar_window, hlinfo->mouse_face_window)
12691 && *vpos >= hlinfo->mouse_face_beg_row
12692 && *vpos <= hlinfo->mouse_face_end_row
12693 && (*vpos > hlinfo->mouse_face_beg_row
12694 || *hpos >= hlinfo->mouse_face_beg_col)
12695 && (*vpos < hlinfo->mouse_face_end_row
12696 || *hpos < hlinfo->mouse_face_end_col
12697 || hlinfo->mouse_face_past_end))
12698 return 0;
12700 return 1;
12704 /* EXPORT:
12705 Handle mouse button event on the tool-bar of frame F, at
12706 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
12707 0 for button release. MODIFIERS is event modifiers for button
12708 release. */
12710 void
12711 handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
12712 int modifiers)
12714 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12715 struct window *w = XWINDOW (f->tool_bar_window);
12716 int hpos, vpos, prop_idx;
12717 struct glyph *glyph;
12718 Lisp_Object enabled_p;
12719 int ts;
12721 /* If not on the highlighted tool-bar item, and mouse-highlight is
12722 non-nil, return. This is so we generate the tool-bar button
12723 click only when the mouse button is released on the same item as
12724 where it was pressed. However, when mouse-highlight is disabled,
12725 generate the click when the button is released regardless of the
12726 highlight, since tool-bar items are not highlighted in that
12727 case. */
12728 frame_to_window_pixel_xy (w, &x, &y);
12729 ts = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
12730 if (ts == -1
12731 || (ts != 0 && !NILP (Vmouse_highlight)))
12732 return;
12734 /* When mouse-highlight is off, generate the click for the item
12735 where the button was pressed, disregarding where it was
12736 released. */
12737 if (NILP (Vmouse_highlight) && !down_p)
12738 prop_idx = f->last_tool_bar_item;
12740 /* If item is disabled, do nothing. */
12741 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
12742 if (NILP (enabled_p))
12743 return;
12745 if (down_p)
12747 /* Show item in pressed state. */
12748 if (!NILP (Vmouse_highlight))
12749 show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN);
12750 f->last_tool_bar_item = prop_idx;
12752 else
12754 Lisp_Object key, frame;
12755 struct input_event event;
12756 EVENT_INIT (event);
12758 /* Show item in released state. */
12759 if (!NILP (Vmouse_highlight))
12760 show_mouse_face (hlinfo, DRAW_IMAGE_RAISED);
12762 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
12764 XSETFRAME (frame, f);
12765 event.kind = TOOL_BAR_EVENT;
12766 event.frame_or_window = frame;
12767 event.arg = frame;
12768 kbd_buffer_store_event (&event);
12770 event.kind = TOOL_BAR_EVENT;
12771 event.frame_or_window = frame;
12772 event.arg = key;
12773 event.modifiers = modifiers;
12774 kbd_buffer_store_event (&event);
12775 f->last_tool_bar_item = -1;
12780 /* Possibly highlight a tool-bar item on frame F when mouse moves to
12781 tool-bar window-relative coordinates X/Y. Called from
12782 note_mouse_highlight. */
12784 static void
12785 note_tool_bar_highlight (struct frame *f, int x, int y)
12787 Lisp_Object window = f->tool_bar_window;
12788 struct window *w = XWINDOW (window);
12789 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
12790 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12791 int hpos, vpos;
12792 struct glyph *glyph;
12793 struct glyph_row *row;
12794 int i;
12795 Lisp_Object enabled_p;
12796 int prop_idx;
12797 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
12798 int mouse_down_p, rc;
12800 /* Function note_mouse_highlight is called with negative X/Y
12801 values when mouse moves outside of the frame. */
12802 if (x <= 0 || y <= 0)
12804 clear_mouse_face (hlinfo);
12805 return;
12808 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
12809 if (rc < 0)
12811 /* Not on tool-bar item. */
12812 clear_mouse_face (hlinfo);
12813 return;
12815 else if (rc == 0)
12816 /* On same tool-bar item as before. */
12817 goto set_help_echo;
12819 clear_mouse_face (hlinfo);
12821 /* Mouse is down, but on different tool-bar item? */
12822 mouse_down_p = (x_mouse_grabbed (dpyinfo)
12823 && f == dpyinfo->last_mouse_frame);
12825 if (mouse_down_p && f->last_tool_bar_item != prop_idx)
12826 return;
12828 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
12830 /* If tool-bar item is not enabled, don't highlight it. */
12831 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
12832 if (!NILP (enabled_p) && !NILP (Vmouse_highlight))
12834 /* Compute the x-position of the glyph. In front and past the
12835 image is a space. We include this in the highlighted area. */
12836 row = MATRIX_ROW (w->current_matrix, vpos);
12837 for (i = x = 0; i < hpos; ++i)
12838 x += row->glyphs[TEXT_AREA][i].pixel_width;
12840 /* Record this as the current active region. */
12841 hlinfo->mouse_face_beg_col = hpos;
12842 hlinfo->mouse_face_beg_row = vpos;
12843 hlinfo->mouse_face_beg_x = x;
12844 hlinfo->mouse_face_past_end = 0;
12846 hlinfo->mouse_face_end_col = hpos + 1;
12847 hlinfo->mouse_face_end_row = vpos;
12848 hlinfo->mouse_face_end_x = x + glyph->pixel_width;
12849 hlinfo->mouse_face_window = window;
12850 hlinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
12852 /* Display it as active. */
12853 show_mouse_face (hlinfo, draw);
12856 set_help_echo:
12858 /* Set help_echo_string to a help string to display for this tool-bar item.
12859 XTread_socket does the rest. */
12860 help_echo_object = help_echo_window = Qnil;
12861 help_echo_pos = -1;
12862 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
12863 if (NILP (help_echo_string))
12864 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
12867 #endif /* !USE_GTK && !HAVE_NS */
12869 #endif /* HAVE_WINDOW_SYSTEM */
12873 /************************************************************************
12874 Horizontal scrolling
12875 ************************************************************************/
12877 static int hscroll_window_tree (Lisp_Object);
12878 static int hscroll_windows (Lisp_Object);
12880 /* For all leaf windows in the window tree rooted at WINDOW, set their
12881 hscroll value so that PT is (i) visible in the window, and (ii) so
12882 that it is not within a certain margin at the window's left and
12883 right border. Value is non-zero if any window's hscroll has been
12884 changed. */
12886 static int
12887 hscroll_window_tree (Lisp_Object window)
12889 int hscrolled_p = 0;
12890 int hscroll_relative_p = FLOATP (Vhscroll_step);
12891 int hscroll_step_abs = 0;
12892 double hscroll_step_rel = 0;
12894 if (hscroll_relative_p)
12896 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
12897 if (hscroll_step_rel < 0)
12899 hscroll_relative_p = 0;
12900 hscroll_step_abs = 0;
12903 else if (TYPE_RANGED_INTEGERP (int, Vhscroll_step))
12905 hscroll_step_abs = XINT (Vhscroll_step);
12906 if (hscroll_step_abs < 0)
12907 hscroll_step_abs = 0;
12909 else
12910 hscroll_step_abs = 0;
12912 while (WINDOWP (window))
12914 struct window *w = XWINDOW (window);
12916 if (WINDOWP (w->contents))
12917 hscrolled_p |= hscroll_window_tree (w->contents);
12918 else if (w->cursor.vpos >= 0)
12920 int h_margin;
12921 int text_area_width;
12922 struct glyph_row *cursor_row;
12923 struct glyph_row *bottom_row;
12924 int row_r2l_p;
12926 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->desired_matrix, w);
12927 if (w->cursor.vpos < bottom_row - w->desired_matrix->rows)
12928 cursor_row = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
12929 else
12930 cursor_row = bottom_row - 1;
12932 if (!cursor_row->enabled_p)
12934 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12935 if (w->cursor.vpos < bottom_row - w->current_matrix->rows)
12936 cursor_row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
12937 else
12938 cursor_row = bottom_row - 1;
12940 row_r2l_p = cursor_row->reversed_p;
12942 text_area_width = window_box_width (w, TEXT_AREA);
12944 /* Scroll when cursor is inside this scroll margin. */
12945 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
12947 /* If the position of this window's point has explicitly
12948 changed, no more suspend auto hscrolling. */
12949 if (NILP (Fequal (Fwindow_point (window), Fwindow_old_point (window))))
12950 w->suspend_auto_hscroll = 0;
12952 /* Remember window point. */
12953 Fset_marker (w->old_pointm,
12954 ((w == XWINDOW (selected_window))
12955 ? make_number (BUF_PT (XBUFFER (w->contents)))
12956 : Fmarker_position (w->pointm)),
12957 w->contents);
12959 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->contents))
12960 && w->suspend_auto_hscroll == 0
12961 /* In some pathological cases, like restoring a window
12962 configuration into a frame that is much smaller than
12963 the one from which the configuration was saved, we
12964 get glyph rows whose start and end have zero buffer
12965 positions, which we cannot handle below. Just skip
12966 such windows. */
12967 && CHARPOS (cursor_row->start.pos) >= BUF_BEG (w->contents)
12968 /* For left-to-right rows, hscroll when cursor is either
12969 (i) inside the right hscroll margin, or (ii) if it is
12970 inside the left margin and the window is already
12971 hscrolled. */
12972 && ((!row_r2l_p
12973 && ((w->hscroll && w->cursor.x <= h_margin)
12974 || (cursor_row->enabled_p
12975 && cursor_row->truncated_on_right_p
12976 && (w->cursor.x >= text_area_width - h_margin))))
12977 /* For right-to-left rows, the logic is similar,
12978 except that rules for scrolling to left and right
12979 are reversed. E.g., if cursor.x <= h_margin, we
12980 need to hscroll "to the right" unconditionally,
12981 and that will scroll the screen to the left so as
12982 to reveal the next portion of the row. */
12983 || (row_r2l_p
12984 && ((cursor_row->enabled_p
12985 /* FIXME: It is confusing to set the
12986 truncated_on_right_p flag when R2L rows
12987 are actually truncated on the left. */
12988 && cursor_row->truncated_on_right_p
12989 && w->cursor.x <= h_margin)
12990 || (w->hscroll
12991 && (w->cursor.x >= text_area_width - h_margin))))))
12993 struct it it;
12994 ptrdiff_t hscroll;
12995 struct buffer *saved_current_buffer;
12996 ptrdiff_t pt;
12997 int wanted_x;
12999 /* Find point in a display of infinite width. */
13000 saved_current_buffer = current_buffer;
13001 current_buffer = XBUFFER (w->contents);
13003 if (w == XWINDOW (selected_window))
13004 pt = PT;
13005 else
13006 pt = clip_to_bounds (BEGV, marker_position (w->pointm), ZV);
13008 /* Move iterator to pt starting at cursor_row->start in
13009 a line with infinite width. */
13010 init_to_row_start (&it, w, cursor_row);
13011 it.last_visible_x = INFINITY;
13012 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
13013 current_buffer = saved_current_buffer;
13015 /* Position cursor in window. */
13016 if (!hscroll_relative_p && hscroll_step_abs == 0)
13017 hscroll = max (0, (it.current_x
13018 - (ITERATOR_AT_END_OF_LINE_P (&it)
13019 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
13020 : (text_area_width / 2))))
13021 / FRAME_COLUMN_WIDTH (it.f);
13022 else if ((!row_r2l_p
13023 && w->cursor.x >= text_area_width - h_margin)
13024 || (row_r2l_p && w->cursor.x <= h_margin))
13026 if (hscroll_relative_p)
13027 wanted_x = text_area_width * (1 - hscroll_step_rel)
13028 - h_margin;
13029 else
13030 wanted_x = text_area_width
13031 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
13032 - h_margin;
13033 hscroll
13034 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
13036 else
13038 if (hscroll_relative_p)
13039 wanted_x = text_area_width * hscroll_step_rel
13040 + h_margin;
13041 else
13042 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
13043 + h_margin;
13044 hscroll
13045 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
13047 hscroll = max (hscroll, w->min_hscroll);
13049 /* Don't prevent redisplay optimizations if hscroll
13050 hasn't changed, as it will unnecessarily slow down
13051 redisplay. */
13052 if (w->hscroll != hscroll)
13054 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
13055 w->hscroll = hscroll;
13056 hscrolled_p = 1;
13061 window = w->next;
13064 /* Value is non-zero if hscroll of any leaf window has been changed. */
13065 return hscrolled_p;
13069 /* Set hscroll so that cursor is visible and not inside horizontal
13070 scroll margins for all windows in the tree rooted at WINDOW. See
13071 also hscroll_window_tree above. Value is non-zero if any window's
13072 hscroll has been changed. If it has, desired matrices on the frame
13073 of WINDOW are cleared. */
13075 static int
13076 hscroll_windows (Lisp_Object window)
13078 int hscrolled_p = hscroll_window_tree (window);
13079 if (hscrolled_p)
13080 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
13081 return hscrolled_p;
13086 /************************************************************************
13087 Redisplay
13088 ************************************************************************/
13090 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
13091 to a non-zero value. This is sometimes handy to have in a debugger
13092 session. */
13094 #ifdef GLYPH_DEBUG
13096 /* First and last unchanged row for try_window_id. */
13098 static int debug_first_unchanged_at_end_vpos;
13099 static int debug_last_unchanged_at_beg_vpos;
13101 /* Delta vpos and y. */
13103 static int debug_dvpos, debug_dy;
13105 /* Delta in characters and bytes for try_window_id. */
13107 static ptrdiff_t debug_delta, debug_delta_bytes;
13109 /* Values of window_end_pos and window_end_vpos at the end of
13110 try_window_id. */
13112 static ptrdiff_t debug_end_vpos;
13114 /* Append a string to W->desired_matrix->method. FMT is a printf
13115 format string. If trace_redisplay_p is true also printf the
13116 resulting string to stderr. */
13118 static void debug_method_add (struct window *, char const *, ...)
13119 ATTRIBUTE_FORMAT_PRINTF (2, 3);
13121 static void
13122 debug_method_add (struct window *w, char const *fmt, ...)
13124 void *ptr = w;
13125 char *method = w->desired_matrix->method;
13126 int len = strlen (method);
13127 int size = sizeof w->desired_matrix->method;
13128 int remaining = size - len - 1;
13129 va_list ap;
13131 if (len && remaining)
13133 method[len] = '|';
13134 --remaining, ++len;
13137 va_start (ap, fmt);
13138 vsnprintf (method + len, remaining + 1, fmt, ap);
13139 va_end (ap);
13141 if (trace_redisplay_p)
13142 fprintf (stderr, "%p (%s): %s\n",
13143 ptr,
13144 ((BUFFERP (w->contents)
13145 && STRINGP (BVAR (XBUFFER (w->contents), name)))
13146 ? SSDATA (BVAR (XBUFFER (w->contents), name))
13147 : "no buffer"),
13148 method + len);
13151 #endif /* GLYPH_DEBUG */
13154 /* Value is non-zero if all changes in window W, which displays
13155 current_buffer, are in the text between START and END. START is a
13156 buffer position, END is given as a distance from Z. Used in
13157 redisplay_internal for display optimization. */
13159 static int
13160 text_outside_line_unchanged_p (struct window *w,
13161 ptrdiff_t start, ptrdiff_t end)
13163 int unchanged_p = 1;
13165 /* If text or overlays have changed, see where. */
13166 if (window_outdated (w))
13168 /* Gap in the line? */
13169 if (GPT < start || Z - GPT < end)
13170 unchanged_p = 0;
13172 /* Changes start in front of the line, or end after it? */
13173 if (unchanged_p
13174 && (BEG_UNCHANGED < start - 1
13175 || END_UNCHANGED < end))
13176 unchanged_p = 0;
13178 /* If selective display, can't optimize if changes start at the
13179 beginning of the line. */
13180 if (unchanged_p
13181 && INTEGERP (BVAR (current_buffer, selective_display))
13182 && XINT (BVAR (current_buffer, selective_display)) > 0
13183 && (BEG_UNCHANGED < start || GPT <= start))
13184 unchanged_p = 0;
13186 /* If there are overlays at the start or end of the line, these
13187 may have overlay strings with newlines in them. A change at
13188 START, for instance, may actually concern the display of such
13189 overlay strings as well, and they are displayed on different
13190 lines. So, quickly rule out this case. (For the future, it
13191 might be desirable to implement something more telling than
13192 just BEG/END_UNCHANGED.) */
13193 if (unchanged_p)
13195 if (BEG + BEG_UNCHANGED == start
13196 && overlay_touches_p (start))
13197 unchanged_p = 0;
13198 if (END_UNCHANGED == end
13199 && overlay_touches_p (Z - end))
13200 unchanged_p = 0;
13203 /* Under bidi reordering, adding or deleting a character in the
13204 beginning of a paragraph, before the first strong directional
13205 character, can change the base direction of the paragraph (unless
13206 the buffer specifies a fixed paragraph direction), which will
13207 require to redisplay the whole paragraph. It might be worthwhile
13208 to find the paragraph limits and widen the range of redisplayed
13209 lines to that, but for now just give up this optimization. */
13210 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
13211 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
13212 unchanged_p = 0;
13215 return unchanged_p;
13219 /* Do a frame update, taking possible shortcuts into account. This is
13220 the main external entry point for redisplay.
13222 If the last redisplay displayed an echo area message and that message
13223 is no longer requested, we clear the echo area or bring back the
13224 mini-buffer if that is in use. */
13226 void
13227 redisplay (void)
13229 redisplay_internal ();
13233 static Lisp_Object
13234 overlay_arrow_string_or_property (Lisp_Object var)
13236 Lisp_Object val;
13238 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
13239 return val;
13241 return Voverlay_arrow_string;
13244 /* Return 1 if there are any overlay-arrows in current_buffer. */
13245 static int
13246 overlay_arrow_in_current_buffer_p (void)
13248 Lisp_Object vlist;
13250 for (vlist = Voverlay_arrow_variable_list;
13251 CONSP (vlist);
13252 vlist = XCDR (vlist))
13254 Lisp_Object var = XCAR (vlist);
13255 Lisp_Object val;
13257 if (!SYMBOLP (var))
13258 continue;
13259 val = find_symbol_value (var);
13260 if (MARKERP (val)
13261 && current_buffer == XMARKER (val)->buffer)
13262 return 1;
13264 return 0;
13268 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
13269 has changed. */
13271 static int
13272 overlay_arrows_changed_p (void)
13274 Lisp_Object vlist;
13276 for (vlist = Voverlay_arrow_variable_list;
13277 CONSP (vlist);
13278 vlist = XCDR (vlist))
13280 Lisp_Object var = XCAR (vlist);
13281 Lisp_Object val, pstr;
13283 if (!SYMBOLP (var))
13284 continue;
13285 val = find_symbol_value (var);
13286 if (!MARKERP (val))
13287 continue;
13288 if (! EQ (COERCE_MARKER (val),
13289 Fget (var, Qlast_arrow_position))
13290 || ! (pstr = overlay_arrow_string_or_property (var),
13291 EQ (pstr, Fget (var, Qlast_arrow_string))))
13292 return 1;
13294 return 0;
13297 /* Mark overlay arrows to be updated on next redisplay. */
13299 static void
13300 update_overlay_arrows (int up_to_date)
13302 Lisp_Object vlist;
13304 for (vlist = Voverlay_arrow_variable_list;
13305 CONSP (vlist);
13306 vlist = XCDR (vlist))
13308 Lisp_Object var = XCAR (vlist);
13310 if (!SYMBOLP (var))
13311 continue;
13313 if (up_to_date > 0)
13315 Lisp_Object val = find_symbol_value (var);
13316 Fput (var, Qlast_arrow_position,
13317 COERCE_MARKER (val));
13318 Fput (var, Qlast_arrow_string,
13319 overlay_arrow_string_or_property (var));
13321 else if (up_to_date < 0
13322 || !NILP (Fget (var, Qlast_arrow_position)))
13324 Fput (var, Qlast_arrow_position, Qt);
13325 Fput (var, Qlast_arrow_string, Qt);
13331 /* Return overlay arrow string to display at row.
13332 Return integer (bitmap number) for arrow bitmap in left fringe.
13333 Return nil if no overlay arrow. */
13335 static Lisp_Object
13336 overlay_arrow_at_row (struct it *it, struct glyph_row *row)
13338 Lisp_Object vlist;
13340 for (vlist = Voverlay_arrow_variable_list;
13341 CONSP (vlist);
13342 vlist = XCDR (vlist))
13344 Lisp_Object var = XCAR (vlist);
13345 Lisp_Object val;
13347 if (!SYMBOLP (var))
13348 continue;
13350 val = find_symbol_value (var);
13352 if (MARKERP (val)
13353 && current_buffer == XMARKER (val)->buffer
13354 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
13356 if (FRAME_WINDOW_P (it->f)
13357 /* FIXME: if ROW->reversed_p is set, this should test
13358 the right fringe, not the left one. */
13359 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
13361 #ifdef HAVE_WINDOW_SYSTEM
13362 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
13364 int fringe_bitmap;
13365 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
13366 return make_number (fringe_bitmap);
13368 #endif
13369 return make_number (-1); /* Use default arrow bitmap. */
13371 return overlay_arrow_string_or_property (var);
13375 return Qnil;
13378 /* Return 1 if point moved out of or into a composition. Otherwise
13379 return 0. PREV_BUF and PREV_PT are the last point buffer and
13380 position. BUF and PT are the current point buffer and position. */
13382 static int
13383 check_point_in_composition (struct buffer *prev_buf, ptrdiff_t prev_pt,
13384 struct buffer *buf, ptrdiff_t pt)
13386 ptrdiff_t start, end;
13387 Lisp_Object prop;
13388 Lisp_Object buffer;
13390 XSETBUFFER (buffer, buf);
13391 /* Check a composition at the last point if point moved within the
13392 same buffer. */
13393 if (prev_buf == buf)
13395 if (prev_pt == pt)
13396 /* Point didn't move. */
13397 return 0;
13399 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
13400 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
13401 && composition_valid_p (start, end, prop)
13402 && start < prev_pt && end > prev_pt)
13403 /* The last point was within the composition. Return 1 iff
13404 point moved out of the composition. */
13405 return (pt <= start || pt >= end);
13408 /* Check a composition at the current point. */
13409 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
13410 && find_composition (pt, -1, &start, &end, &prop, buffer)
13411 && composition_valid_p (start, end, prop)
13412 && start < pt && end > pt);
13415 /* Reconsider the clip changes of buffer which is displayed in W. */
13417 static void
13418 reconsider_clip_changes (struct window *w)
13420 struct buffer *b = XBUFFER (w->contents);
13422 if (b->clip_changed
13423 && w->window_end_valid
13424 && w->current_matrix->buffer == b
13425 && w->current_matrix->zv == BUF_ZV (b)
13426 && w->current_matrix->begv == BUF_BEGV (b))
13427 b->clip_changed = 0;
13429 /* If display wasn't paused, and W is not a tool bar window, see if
13430 point has been moved into or out of a composition. In that case,
13431 we set b->clip_changed to 1 to force updating the screen. If
13432 b->clip_changed has already been set to 1, we can skip this
13433 check. */
13434 if (!b->clip_changed && w->window_end_valid)
13436 ptrdiff_t pt = (w == XWINDOW (selected_window)
13437 ? PT : marker_position (w->pointm));
13439 if ((w->current_matrix->buffer != b || pt != w->last_point)
13440 && check_point_in_composition (w->current_matrix->buffer,
13441 w->last_point, b, pt))
13442 b->clip_changed = 1;
13446 static void
13447 propagate_buffer_redisplay (void)
13448 { /* Resetting b->text->redisplay is problematic!
13449 We can't just reset it in the case that some window that displays
13450 it has not been redisplayed; and such a window can stay
13451 unredisplayed for a long time if it's currently invisible.
13452 But we do want to reset it at the end of redisplay otherwise
13453 its displayed windows will keep being redisplayed over and over
13454 again.
13455 So we copy all b->text->redisplay flags up to their windows here,
13456 such that mark_window_display_accurate can safely reset
13457 b->text->redisplay. */
13458 Lisp_Object ws = window_list ();
13459 for (; CONSP (ws); ws = XCDR (ws))
13461 struct window *thisw = XWINDOW (XCAR (ws));
13462 struct buffer *thisb = XBUFFER (thisw->contents);
13463 if (thisb->text->redisplay)
13464 thisw->redisplay = true;
13468 #define STOP_POLLING \
13469 do { if (! polling_stopped_here) stop_polling (); \
13470 polling_stopped_here = 1; } while (0)
13472 #define RESUME_POLLING \
13473 do { if (polling_stopped_here) start_polling (); \
13474 polling_stopped_here = 0; } while (0)
13477 /* Perhaps in the future avoid recentering windows if it
13478 is not necessary; currently that causes some problems. */
13480 static void
13481 redisplay_internal (void)
13483 struct window *w = XWINDOW (selected_window);
13484 struct window *sw;
13485 struct frame *fr;
13486 bool pending;
13487 bool must_finish = 0, match_p;
13488 struct text_pos tlbufpos, tlendpos;
13489 int number_of_visible_frames;
13490 ptrdiff_t count;
13491 struct frame *sf;
13492 int polling_stopped_here = 0;
13493 Lisp_Object tail, frame;
13495 /* True means redisplay has to consider all windows on all
13496 frames. False, only selected_window is considered. */
13497 bool consider_all_windows_p;
13499 /* True means redisplay has to redisplay the miniwindow. */
13500 bool update_miniwindow_p = false;
13502 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
13504 /* No redisplay if running in batch mode or frame is not yet fully
13505 initialized, or redisplay is explicitly turned off by setting
13506 Vinhibit_redisplay. */
13507 if (FRAME_INITIAL_P (SELECTED_FRAME ())
13508 || !NILP (Vinhibit_redisplay))
13509 return;
13511 /* Don't examine these until after testing Vinhibit_redisplay.
13512 When Emacs is shutting down, perhaps because its connection to
13513 X has dropped, we should not look at them at all. */
13514 fr = XFRAME (w->frame);
13515 sf = SELECTED_FRAME ();
13517 if (!fr->glyphs_initialized_p)
13518 return;
13520 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
13521 if (popup_activated ())
13522 return;
13523 #endif
13525 /* I don't think this happens but let's be paranoid. */
13526 if (redisplaying_p)
13527 return;
13529 /* Record a function that clears redisplaying_p
13530 when we leave this function. */
13531 count = SPECPDL_INDEX ();
13532 record_unwind_protect_void (unwind_redisplay);
13533 redisplaying_p = 1;
13534 specbind (Qinhibit_free_realized_faces, Qnil);
13536 /* Record this function, so it appears on the profiler's backtraces. */
13537 record_in_backtrace (Qredisplay_internal, &Qnil, 0);
13539 FOR_EACH_FRAME (tail, frame)
13540 XFRAME (frame)->already_hscrolled_p = 0;
13542 retry:
13543 /* Remember the currently selected window. */
13544 sw = w;
13546 pending = false;
13547 last_escape_glyph_frame = NULL;
13548 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
13549 last_glyphless_glyph_frame = NULL;
13550 last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
13552 /* If face_change_count is non-zero, init_iterator will free all
13553 realized faces, which includes the faces referenced from current
13554 matrices. So, we can't reuse current matrices in this case. */
13555 if (face_change_count)
13556 windows_or_buffers_changed = 47;
13558 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
13559 && FRAME_TTY (sf)->previous_frame != sf)
13561 /* Since frames on a single ASCII terminal share the same
13562 display area, displaying a different frame means redisplay
13563 the whole thing. */
13564 SET_FRAME_GARBAGED (sf);
13565 #ifndef DOS_NT
13566 set_tty_color_mode (FRAME_TTY (sf), sf);
13567 #endif
13568 FRAME_TTY (sf)->previous_frame = sf;
13571 /* Set the visible flags for all frames. Do this before checking for
13572 resized or garbaged frames; they want to know if their frames are
13573 visible. See the comment in frame.h for FRAME_SAMPLE_VISIBILITY. */
13574 number_of_visible_frames = 0;
13576 FOR_EACH_FRAME (tail, frame)
13578 struct frame *f = XFRAME (frame);
13580 if (FRAME_VISIBLE_P (f))
13582 ++number_of_visible_frames;
13583 /* Adjust matrices for visible frames only. */
13584 if (f->fonts_changed)
13586 adjust_frame_glyphs (f);
13587 f->fonts_changed = 0;
13589 /* If cursor type has been changed on the frame
13590 other than selected, consider all frames. */
13591 if (f != sf && f->cursor_type_changed)
13592 update_mode_lines = 31;
13594 clear_desired_matrices (f);
13597 /* Notice any pending interrupt request to change frame size. */
13598 do_pending_window_change (true);
13600 /* do_pending_window_change could change the selected_window due to
13601 frame resizing which makes the selected window too small. */
13602 if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw)
13603 sw = w;
13605 /* Clear frames marked as garbaged. */
13606 clear_garbaged_frames ();
13608 /* Build menubar and tool-bar items. */
13609 if (NILP (Vmemory_full))
13610 prepare_menu_bars ();
13612 reconsider_clip_changes (w);
13614 /* In most cases selected window displays current buffer. */
13615 match_p = XBUFFER (w->contents) == current_buffer;
13616 if (match_p)
13618 /* Detect case that we need to write or remove a star in the mode line. */
13619 if ((SAVE_MODIFF < MODIFF) != w->last_had_star)
13620 w->update_mode_line = 1;
13622 if (mode_line_update_needed (w))
13623 w->update_mode_line = 1;
13625 /* If reconsider_clip_changes above decided that the narrowing
13626 in the current buffer changed, make sure all other windows
13627 showing that buffer will be redisplayed. */
13628 if (current_buffer->clip_changed)
13629 bset_update_mode_line (current_buffer);
13632 /* Normally the message* functions will have already displayed and
13633 updated the echo area, but the frame may have been trashed, or
13634 the update may have been preempted, so display the echo area
13635 again here. Checking message_cleared_p captures the case that
13636 the echo area should be cleared. */
13637 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
13638 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
13639 || (message_cleared_p
13640 && minibuf_level == 0
13641 /* If the mini-window is currently selected, this means the
13642 echo-area doesn't show through. */
13643 && !MINI_WINDOW_P (XWINDOW (selected_window))))
13645 int window_height_changed_p = echo_area_display (false);
13647 if (message_cleared_p)
13648 update_miniwindow_p = true;
13650 must_finish = 1;
13652 /* If we don't display the current message, don't clear the
13653 message_cleared_p flag, because, if we did, we wouldn't clear
13654 the echo area in the next redisplay which doesn't preserve
13655 the echo area. */
13656 if (!display_last_displayed_message_p)
13657 message_cleared_p = 0;
13659 if (window_height_changed_p)
13661 windows_or_buffers_changed = 50;
13663 /* If window configuration was changed, frames may have been
13664 marked garbaged. Clear them or we will experience
13665 surprises wrt scrolling. */
13666 clear_garbaged_frames ();
13669 else if (EQ (selected_window, minibuf_window)
13670 && (current_buffer->clip_changed || window_outdated (w))
13671 && resize_mini_window (w, 0))
13673 /* Resized active mini-window to fit the size of what it is
13674 showing if its contents might have changed. */
13675 must_finish = 1;
13677 /* If window configuration was changed, frames may have been
13678 marked garbaged. Clear them or we will experience
13679 surprises wrt scrolling. */
13680 clear_garbaged_frames ();
13683 if (windows_or_buffers_changed && !update_mode_lines)
13684 /* Code that sets windows_or_buffers_changed doesn't distinguish whether
13685 only the windows's contents needs to be refreshed, or whether the
13686 mode-lines also need a refresh. */
13687 update_mode_lines = (windows_or_buffers_changed == REDISPLAY_SOME
13688 ? REDISPLAY_SOME : 32);
13690 /* If specs for an arrow have changed, do thorough redisplay
13691 to ensure we remove any arrow that should no longer exist. */
13692 if (overlay_arrows_changed_p ())
13693 /* Apparently, this is the only case where we update other windows,
13694 without updating other mode-lines. */
13695 windows_or_buffers_changed = 49;
13697 consider_all_windows_p = (update_mode_lines
13698 || windows_or_buffers_changed);
13700 #define AINC(a,i) \
13701 if (VECTORP (a) && i >= 0 && i < ASIZE (a) && INTEGERP (AREF (a, i))) \
13702 ASET (a, i, make_number (1 + XINT (AREF (a, i))))
13704 AINC (Vredisplay__all_windows_cause, windows_or_buffers_changed);
13705 AINC (Vredisplay__mode_lines_cause, update_mode_lines);
13707 /* Optimize the case that only the line containing the cursor in the
13708 selected window has changed. Variables starting with this_ are
13709 set in display_line and record information about the line
13710 containing the cursor. */
13711 tlbufpos = this_line_start_pos;
13712 tlendpos = this_line_end_pos;
13713 if (!consider_all_windows_p
13714 && CHARPOS (tlbufpos) > 0
13715 && !w->update_mode_line
13716 && !current_buffer->clip_changed
13717 && !current_buffer->prevent_redisplay_optimizations_p
13718 && FRAME_VISIBLE_P (XFRAME (w->frame))
13719 && !FRAME_OBSCURED_P (XFRAME (w->frame))
13720 && !XFRAME (w->frame)->cursor_type_changed
13721 /* Make sure recorded data applies to current buffer, etc. */
13722 && this_line_buffer == current_buffer
13723 && match_p
13724 && !w->force_start
13725 && !w->optional_new_start
13726 /* Point must be on the line that we have info recorded about. */
13727 && PT >= CHARPOS (tlbufpos)
13728 && PT <= Z - CHARPOS (tlendpos)
13729 /* All text outside that line, including its final newline,
13730 must be unchanged. */
13731 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
13732 CHARPOS (tlendpos)))
13734 if (CHARPOS (tlbufpos) > BEGV
13735 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
13736 && (CHARPOS (tlbufpos) == ZV
13737 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
13738 /* Former continuation line has disappeared by becoming empty. */
13739 goto cancel;
13740 else if (window_outdated (w) || MINI_WINDOW_P (w))
13742 /* We have to handle the case of continuation around a
13743 wide-column character (see the comment in indent.c around
13744 line 1340).
13746 For instance, in the following case:
13748 -------- Insert --------
13749 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
13750 J_I_ ==> J_I_ `^^' are cursors.
13751 ^^ ^^
13752 -------- --------
13754 As we have to redraw the line above, we cannot use this
13755 optimization. */
13757 struct it it;
13758 int line_height_before = this_line_pixel_height;
13760 /* Note that start_display will handle the case that the
13761 line starting at tlbufpos is a continuation line. */
13762 start_display (&it, w, tlbufpos);
13764 /* Implementation note: It this still necessary? */
13765 if (it.current_x != this_line_start_x)
13766 goto cancel;
13768 TRACE ((stderr, "trying display optimization 1\n"));
13769 w->cursor.vpos = -1;
13770 overlay_arrow_seen = 0;
13771 it.vpos = this_line_vpos;
13772 it.current_y = this_line_y;
13773 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
13774 display_line (&it);
13776 /* If line contains point, is not continued,
13777 and ends at same distance from eob as before, we win. */
13778 if (w->cursor.vpos >= 0
13779 /* Line is not continued, otherwise this_line_start_pos
13780 would have been set to 0 in display_line. */
13781 && CHARPOS (this_line_start_pos)
13782 /* Line ends as before. */
13783 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
13784 /* Line has same height as before. Otherwise other lines
13785 would have to be shifted up or down. */
13786 && this_line_pixel_height == line_height_before)
13788 /* If this is not the window's last line, we must adjust
13789 the charstarts of the lines below. */
13790 if (it.current_y < it.last_visible_y)
13792 struct glyph_row *row
13793 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
13794 ptrdiff_t delta, delta_bytes;
13796 /* We used to distinguish between two cases here,
13797 conditioned by Z - CHARPOS (tlendpos) == ZV, for
13798 when the line ends in a newline or the end of the
13799 buffer's accessible portion. But both cases did
13800 the same, so they were collapsed. */
13801 delta = (Z
13802 - CHARPOS (tlendpos)
13803 - MATRIX_ROW_START_CHARPOS (row));
13804 delta_bytes = (Z_BYTE
13805 - BYTEPOS (tlendpos)
13806 - MATRIX_ROW_START_BYTEPOS (row));
13808 increment_matrix_positions (w->current_matrix,
13809 this_line_vpos + 1,
13810 w->current_matrix->nrows,
13811 delta, delta_bytes);
13814 /* If this row displays text now but previously didn't,
13815 or vice versa, w->window_end_vpos may have to be
13816 adjusted. */
13817 if (MATRIX_ROW_DISPLAYS_TEXT_P (it.glyph_row - 1))
13819 if (w->window_end_vpos < this_line_vpos)
13820 w->window_end_vpos = this_line_vpos;
13822 else if (w->window_end_vpos == this_line_vpos
13823 && this_line_vpos > 0)
13824 w->window_end_vpos = this_line_vpos - 1;
13825 w->window_end_valid = 0;
13827 /* Update hint: No need to try to scroll in update_window. */
13828 w->desired_matrix->no_scrolling_p = 1;
13830 #ifdef GLYPH_DEBUG
13831 *w->desired_matrix->method = 0;
13832 debug_method_add (w, "optimization 1");
13833 #endif
13834 #if HAVE_XWIDGETS
13835 //debug optimization movement issue
13836 //w->desired_matrix->no_scrolling_p = 1;
13837 //*w->desired_matrix->method = 0;
13838 //debug_method_add (w, "optimization 1");
13839 #endif
13841 #ifdef HAVE_WINDOW_SYSTEM
13842 update_window_fringes (w, 0);
13843 #endif
13844 goto update;
13846 else
13847 goto cancel;
13849 else if (/* Cursor position hasn't changed. */
13850 PT == w->last_point
13851 /* Make sure the cursor was last displayed
13852 in this window. Otherwise we have to reposition it. */
13854 /* PXW: Must be converted to pixels, probably. */
13855 && 0 <= w->cursor.vpos
13856 && w->cursor.vpos < WINDOW_TOTAL_LINES (w))
13858 if (!must_finish)
13860 do_pending_window_change (true);
13861 /* If selected_window changed, redisplay again. */
13862 if (WINDOWP (selected_window)
13863 && (w = XWINDOW (selected_window)) != sw)
13864 goto retry;
13866 /* We used to always goto end_of_redisplay here, but this
13867 isn't enough if we have a blinking cursor. */
13868 if (w->cursor_off_p == w->last_cursor_off_p)
13869 goto end_of_redisplay;
13871 goto update;
13873 /* If highlighting the region, or if the cursor is in the echo area,
13874 then we can't just move the cursor. */
13875 else if (NILP (Vshow_trailing_whitespace)
13876 && !cursor_in_echo_area)
13878 struct it it;
13879 struct glyph_row *row;
13881 /* Skip from tlbufpos to PT and see where it is. Note that
13882 PT may be in invisible text. If so, we will end at the
13883 next visible position. */
13884 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
13885 NULL, DEFAULT_FACE_ID);
13886 it.current_x = this_line_start_x;
13887 it.current_y = this_line_y;
13888 it.vpos = this_line_vpos;
13890 /* The call to move_it_to stops in front of PT, but
13891 moves over before-strings. */
13892 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
13894 if (it.vpos == this_line_vpos
13895 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
13896 row->enabled_p))
13898 eassert (this_line_vpos == it.vpos);
13899 eassert (this_line_y == it.current_y);
13900 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13901 #ifdef GLYPH_DEBUG
13902 *w->desired_matrix->method = 0;
13903 debug_method_add (w, "optimization 3");
13904 #endif
13905 goto update;
13907 else
13908 goto cancel;
13911 cancel:
13912 /* Text changed drastically or point moved off of line. */
13913 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, false);
13916 CHARPOS (this_line_start_pos) = 0;
13917 ++clear_face_cache_count;
13918 #ifdef HAVE_WINDOW_SYSTEM
13919 ++clear_image_cache_count;
13920 #endif
13922 /* Build desired matrices, and update the display. If
13923 consider_all_windows_p is non-zero, do it for all windows on all
13924 frames. Otherwise do it for selected_window, only. */
13926 if (consider_all_windows_p)
13928 FOR_EACH_FRAME (tail, frame)
13929 XFRAME (frame)->updated_p = 0;
13931 propagate_buffer_redisplay ();
13933 FOR_EACH_FRAME (tail, frame)
13935 struct frame *f = XFRAME (frame);
13937 /* We don't have to do anything for unselected terminal
13938 frames. */
13939 if ((FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
13940 && !EQ (FRAME_TTY (f)->top_frame, frame))
13941 continue;
13943 retry_frame:
13945 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
13947 bool gcscrollbars
13948 /* Only GC scrollbars when we redisplay the whole frame. */
13949 = f->redisplay || !REDISPLAY_SOME_P ();
13950 /* Mark all the scroll bars to be removed; we'll redeem
13951 the ones we want when we redisplay their windows. */
13952 if (gcscrollbars && FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
13953 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
13955 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
13956 redisplay_windows (FRAME_ROOT_WINDOW (f));
13957 /* Remember that the invisible frames need to be redisplayed next
13958 time they're visible. */
13959 else if (!REDISPLAY_SOME_P ())
13960 f->redisplay = true;
13962 /* The X error handler may have deleted that frame. */
13963 if (!FRAME_LIVE_P (f))
13964 continue;
13966 /* Any scroll bars which redisplay_windows should have
13967 nuked should now go away. */
13968 if (gcscrollbars && FRAME_TERMINAL (f)->judge_scroll_bars_hook)
13969 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
13971 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
13973 /* If fonts changed on visible frame, display again. */
13974 if (f->fonts_changed)
13976 adjust_frame_glyphs (f);
13977 f->fonts_changed = false;
13978 goto retry_frame;
13981 /* See if we have to hscroll. */
13982 if (!f->already_hscrolled_p)
13984 f->already_hscrolled_p = true;
13985 if (hscroll_windows (f->root_window))
13986 goto retry_frame;
13989 /* Prevent various kinds of signals during display
13990 update. stdio is not robust about handling
13991 signals, which can cause an apparent I/O error. */
13992 if (interrupt_input)
13993 unrequest_sigio ();
13994 STOP_POLLING;
13996 pending |= update_frame (f, false, false);
13997 f->cursor_type_changed = false;
13998 f->updated_p = true;
14003 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
14005 if (!pending)
14007 /* Do the mark_window_display_accurate after all windows have
14008 been redisplayed because this call resets flags in buffers
14009 which are needed for proper redisplay. */
14010 FOR_EACH_FRAME (tail, frame)
14012 struct frame *f = XFRAME (frame);
14013 if (f->updated_p)
14015 f->redisplay = false;
14016 mark_window_display_accurate (f->root_window, 1);
14017 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
14018 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
14023 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
14025 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
14026 struct frame *mini_frame;
14028 displayed_buffer = XBUFFER (XWINDOW (selected_window)->contents);
14029 /* Use list_of_error, not Qerror, so that
14030 we catch only errors and don't run the debugger. */
14031 internal_condition_case_1 (redisplay_window_1, selected_window,
14032 list_of_error,
14033 redisplay_window_error);
14034 if (update_miniwindow_p)
14035 internal_condition_case_1 (redisplay_window_1, mini_window,
14036 list_of_error,
14037 redisplay_window_error);
14039 /* Compare desired and current matrices, perform output. */
14041 update:
14042 /* If fonts changed, display again. */
14043 if (sf->fonts_changed)
14044 goto retry;
14046 /* Prevent various kinds of signals during display update.
14047 stdio is not robust about handling signals,
14048 which can cause an apparent I/O error. */
14049 if (interrupt_input)
14050 unrequest_sigio ();
14051 STOP_POLLING;
14053 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
14055 if (hscroll_windows (selected_window))
14056 goto retry;
14058 XWINDOW (selected_window)->must_be_updated_p = true;
14059 pending = update_frame (sf, false, false);
14060 sf->cursor_type_changed = false;
14063 /* We may have called echo_area_display at the top of this
14064 function. If the echo area is on another frame, that may
14065 have put text on a frame other than the selected one, so the
14066 above call to update_frame would not have caught it. Catch
14067 it here. */
14068 mini_window = FRAME_MINIBUF_WINDOW (sf);
14069 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
14071 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
14073 XWINDOW (mini_window)->must_be_updated_p = true;
14074 pending |= update_frame (mini_frame, false, false);
14075 mini_frame->cursor_type_changed = false;
14076 if (!pending && hscroll_windows (mini_window))
14077 goto retry;
14081 /* If display was paused because of pending input, make sure we do a
14082 thorough update the next time. */
14083 if (pending)
14085 /* Prevent the optimization at the beginning of
14086 redisplay_internal that tries a single-line update of the
14087 line containing the cursor in the selected window. */
14088 CHARPOS (this_line_start_pos) = 0;
14090 /* Let the overlay arrow be updated the next time. */
14091 update_overlay_arrows (0);
14093 /* If we pause after scrolling, some rows in the current
14094 matrices of some windows are not valid. */
14095 if (!WINDOW_FULL_WIDTH_P (w)
14096 && !FRAME_WINDOW_P (XFRAME (w->frame)))
14097 update_mode_lines = 36;
14099 else
14101 if (!consider_all_windows_p)
14103 /* This has already been done above if
14104 consider_all_windows_p is set. */
14105 if (XBUFFER (w->contents)->text->redisplay
14106 && buffer_window_count (XBUFFER (w->contents)) > 1)
14107 /* This can happen if b->text->redisplay was set during
14108 jit-lock. */
14109 propagate_buffer_redisplay ();
14110 mark_window_display_accurate_1 (w, 1);
14112 /* Say overlay arrows are up to date. */
14113 update_overlay_arrows (1);
14115 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
14116 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
14119 update_mode_lines = 0;
14120 windows_or_buffers_changed = 0;
14123 /* Start SIGIO interrupts coming again. Having them off during the
14124 code above makes it less likely one will discard output, but not
14125 impossible, since there might be stuff in the system buffer here.
14126 But it is much hairier to try to do anything about that. */
14127 if (interrupt_input)
14128 request_sigio ();
14129 RESUME_POLLING;
14131 /* If a frame has become visible which was not before, redisplay
14132 again, so that we display it. Expose events for such a frame
14133 (which it gets when becoming visible) don't call the parts of
14134 redisplay constructing glyphs, so simply exposing a frame won't
14135 display anything in this case. So, we have to display these
14136 frames here explicitly. */
14137 if (!pending)
14139 int new_count = 0;
14141 FOR_EACH_FRAME (tail, frame)
14143 if (XFRAME (frame)->visible)
14144 new_count++;
14147 if (new_count != number_of_visible_frames)
14148 windows_or_buffers_changed = 52;
14151 /* Change frame size now if a change is pending. */
14152 do_pending_window_change (true);
14154 /* If we just did a pending size change, or have additional
14155 visible frames, or selected_window changed, redisplay again. */
14156 if ((windows_or_buffers_changed && !pending)
14157 || (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw))
14158 goto retry;
14160 /* Clear the face and image caches.
14162 We used to do this only if consider_all_windows_p. But the cache
14163 needs to be cleared if a timer creates images in the current
14164 buffer (e.g. the test case in Bug#6230). */
14166 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
14168 clear_face_cache (false);
14169 clear_face_cache_count = 0;
14172 #ifdef HAVE_WINDOW_SYSTEM
14173 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
14175 clear_image_caches (Qnil);
14176 clear_image_cache_count = 0;
14178 #endif /* HAVE_WINDOW_SYSTEM */
14180 end_of_redisplay:
14181 #ifdef HAVE_NS
14182 ns_set_doc_edited ();
14183 #endif
14184 if (interrupt_input && interrupts_deferred)
14185 request_sigio ();
14187 unbind_to (count, Qnil);
14188 RESUME_POLLING;
14192 /* Redisplay, but leave alone any recent echo area message unless
14193 another message has been requested in its place.
14195 This is useful in situations where you need to redisplay but no
14196 user action has occurred, making it inappropriate for the message
14197 area to be cleared. See tracking_off and
14198 wait_reading_process_output for examples of these situations.
14200 FROM_WHERE is an integer saying from where this function was
14201 called. This is useful for debugging. */
14203 void
14204 redisplay_preserve_echo_area (int from_where)
14206 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
14208 if (!NILP (echo_area_buffer[1]))
14210 /* We have a previously displayed message, but no current
14211 message. Redisplay the previous message. */
14212 display_last_displayed_message_p = true;
14213 redisplay_internal ();
14214 display_last_displayed_message_p = false;
14216 else
14217 redisplay_internal ();
14219 flush_frame (SELECTED_FRAME ());
14223 /* Function registered with record_unwind_protect in redisplay_internal. */
14225 static void
14226 unwind_redisplay (void)
14228 redisplaying_p = 0;
14232 /* Mark the display of leaf window W as accurate or inaccurate.
14233 If ACCURATE_P is non-zero mark display of W as accurate. If
14234 ACCURATE_P is zero, arrange for W to be redisplayed the next
14235 time redisplay_internal is called. */
14237 static void
14238 mark_window_display_accurate_1 (struct window *w, int accurate_p)
14240 struct buffer *b = XBUFFER (w->contents);
14242 w->last_modified = accurate_p ? BUF_MODIFF (b) : 0;
14243 w->last_overlay_modified = accurate_p ? BUF_OVERLAY_MODIFF (b) : 0;
14244 w->last_had_star = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b);
14246 if (accurate_p)
14248 b->clip_changed = false;
14249 b->prevent_redisplay_optimizations_p = false;
14250 eassert (buffer_window_count (b) > 0);
14251 /* Resetting b->text->redisplay is problematic!
14252 In order to make it safer to do it here, redisplay_internal must
14253 have copied all b->text->redisplay to their respective windows. */
14254 b->text->redisplay = false;
14256 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
14257 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
14258 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
14259 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
14261 w->current_matrix->buffer = b;
14262 w->current_matrix->begv = BUF_BEGV (b);
14263 w->current_matrix->zv = BUF_ZV (b);
14265 w->last_cursor_vpos = w->cursor.vpos;
14266 w->last_cursor_off_p = w->cursor_off_p;
14268 if (w == XWINDOW (selected_window))
14269 w->last_point = BUF_PT (b);
14270 else
14271 w->last_point = marker_position (w->pointm);
14273 w->window_end_valid = true;
14274 w->update_mode_line = false;
14277 w->redisplay = !accurate_p;
14281 /* Mark the display of windows in the window tree rooted at WINDOW as
14282 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
14283 windows as accurate. If ACCURATE_P is zero, arrange for windows to
14284 be redisplayed the next time redisplay_internal is called. */
14286 void
14287 mark_window_display_accurate (Lisp_Object window, int accurate_p)
14289 struct window *w;
14291 for (; !NILP (window); window = w->next)
14293 w = XWINDOW (window);
14294 if (WINDOWP (w->contents))
14295 mark_window_display_accurate (w->contents, accurate_p);
14296 else
14297 mark_window_display_accurate_1 (w, accurate_p);
14300 if (accurate_p)
14301 update_overlay_arrows (1);
14302 else
14303 /* Force a thorough redisplay the next time by setting
14304 last_arrow_position and last_arrow_string to t, which is
14305 unequal to any useful value of Voverlay_arrow_... */
14306 update_overlay_arrows (-1);
14310 /* Return value in display table DP (Lisp_Char_Table *) for character
14311 C. Since a display table doesn't have any parent, we don't have to
14312 follow parent. Do not call this function directly but use the
14313 macro DISP_CHAR_VECTOR. */
14315 Lisp_Object
14316 disp_char_vector (struct Lisp_Char_Table *dp, int c)
14318 Lisp_Object val;
14320 if (ASCII_CHAR_P (c))
14322 val = dp->ascii;
14323 if (SUB_CHAR_TABLE_P (val))
14324 val = XSUB_CHAR_TABLE (val)->contents[c];
14326 else
14328 Lisp_Object table;
14330 XSETCHAR_TABLE (table, dp);
14331 val = char_table_ref (table, c);
14333 if (NILP (val))
14334 val = dp->defalt;
14335 return val;
14340 /***********************************************************************
14341 Window Redisplay
14342 ***********************************************************************/
14344 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
14346 static void
14347 redisplay_windows (Lisp_Object window)
14349 while (!NILP (window))
14351 struct window *w = XWINDOW (window);
14353 if (WINDOWP (w->contents))
14354 redisplay_windows (w->contents);
14355 else if (BUFFERP (w->contents))
14357 displayed_buffer = XBUFFER (w->contents);
14358 /* Use list_of_error, not Qerror, so that
14359 we catch only errors and don't run the debugger. */
14360 internal_condition_case_1 (redisplay_window_0, window,
14361 list_of_error,
14362 redisplay_window_error);
14365 window = w->next;
14369 static Lisp_Object
14370 redisplay_window_error (Lisp_Object ignore)
14372 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
14373 return Qnil;
14376 static Lisp_Object
14377 redisplay_window_0 (Lisp_Object window)
14379 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
14380 redisplay_window (window, false);
14381 return Qnil;
14384 static Lisp_Object
14385 redisplay_window_1 (Lisp_Object window)
14387 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
14388 redisplay_window (window, true);
14389 return Qnil;
14393 /* Set cursor position of W. PT is assumed to be displayed in ROW.
14394 DELTA and DELTA_BYTES are the numbers of characters and bytes by
14395 which positions recorded in ROW differ from current buffer
14396 positions.
14398 Return 0 if cursor is not on this row, 1 otherwise. */
14400 static int
14401 set_cursor_from_row (struct window *w, struct glyph_row *row,
14402 struct glyph_matrix *matrix,
14403 ptrdiff_t delta, ptrdiff_t delta_bytes,
14404 int dy, int dvpos)
14406 struct glyph *glyph = row->glyphs[TEXT_AREA];
14407 struct glyph *end = glyph + row->used[TEXT_AREA];
14408 struct glyph *cursor = NULL;
14409 /* The last known character position in row. */
14410 ptrdiff_t last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
14411 int x = row->x;
14412 ptrdiff_t pt_old = PT - delta;
14413 ptrdiff_t pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
14414 ptrdiff_t pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
14415 struct glyph *glyph_before = glyph - 1, *glyph_after = end;
14416 /* A glyph beyond the edge of TEXT_AREA which we should never
14417 touch. */
14418 struct glyph *glyphs_end = end;
14419 /* Non-zero means we've found a match for cursor position, but that
14420 glyph has the avoid_cursor_p flag set. */
14421 int match_with_avoid_cursor = 0;
14422 /* Non-zero means we've seen at least one glyph that came from a
14423 display string. */
14424 int string_seen = 0;
14425 /* Largest and smallest buffer positions seen so far during scan of
14426 glyph row. */
14427 ptrdiff_t bpos_max = pos_before;
14428 ptrdiff_t bpos_min = pos_after;
14429 /* Last buffer position covered by an overlay string with an integer
14430 `cursor' property. */
14431 ptrdiff_t bpos_covered = 0;
14432 /* Non-zero means the display string on which to display the cursor
14433 comes from a text property, not from an overlay. */
14434 int string_from_text_prop = 0;
14436 /* Don't even try doing anything if called for a mode-line or
14437 header-line row, since the rest of the code isn't prepared to
14438 deal with such calamities. */
14439 eassert (!row->mode_line_p);
14440 if (row->mode_line_p)
14441 return 0;
14443 /* Skip over glyphs not having an object at the start and the end of
14444 the row. These are special glyphs like truncation marks on
14445 terminal frames. */
14446 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
14448 if (!row->reversed_p)
14450 while (glyph < end
14451 && INTEGERP (glyph->object)
14452 && glyph->charpos < 0)
14454 x += glyph->pixel_width;
14455 ++glyph;
14457 while (end > glyph
14458 && INTEGERP ((end - 1)->object)
14459 /* CHARPOS is zero for blanks and stretch glyphs
14460 inserted by extend_face_to_end_of_line. */
14461 && (end - 1)->charpos <= 0)
14462 --end;
14463 glyph_before = glyph - 1;
14464 glyph_after = end;
14466 else
14468 struct glyph *g;
14470 /* If the glyph row is reversed, we need to process it from back
14471 to front, so swap the edge pointers. */
14472 glyphs_end = end = glyph - 1;
14473 glyph += row->used[TEXT_AREA] - 1;
14475 while (glyph > end + 1
14476 && INTEGERP (glyph->object)
14477 && glyph->charpos < 0)
14479 --glyph;
14480 x -= glyph->pixel_width;
14482 if (INTEGERP (glyph->object) && glyph->charpos < 0)
14483 --glyph;
14484 /* By default, in reversed rows we put the cursor on the
14485 rightmost (first in the reading order) glyph. */
14486 for (g = end + 1; g < glyph; g++)
14487 x += g->pixel_width;
14488 while (end < glyph
14489 && INTEGERP ((end + 1)->object)
14490 && (end + 1)->charpos <= 0)
14491 ++end;
14492 glyph_before = glyph + 1;
14493 glyph_after = end;
14496 else if (row->reversed_p)
14498 /* In R2L rows that don't display text, put the cursor on the
14499 rightmost glyph. Case in point: an empty last line that is
14500 part of an R2L paragraph. */
14501 cursor = end - 1;
14502 /* Avoid placing the cursor on the last glyph of the row, where
14503 on terminal frames we hold the vertical border between
14504 adjacent windows. */
14505 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w))
14506 && !WINDOW_RIGHTMOST_P (w)
14507 && cursor == row->glyphs[LAST_AREA] - 1)
14508 cursor--;
14509 x = -1; /* will be computed below, at label compute_x */
14512 /* Step 1: Try to find the glyph whose character position
14513 corresponds to point. If that's not possible, find 2 glyphs
14514 whose character positions are the closest to point, one before
14515 point, the other after it. */
14516 if (!row->reversed_p)
14517 while (/* not marched to end of glyph row */
14518 glyph < end
14519 /* glyph was not inserted by redisplay for internal purposes */
14520 && !INTEGERP (glyph->object))
14522 if (BUFFERP (glyph->object))
14524 ptrdiff_t dpos = glyph->charpos - pt_old;
14526 if (glyph->charpos > bpos_max)
14527 bpos_max = glyph->charpos;
14528 if (glyph->charpos < bpos_min)
14529 bpos_min = glyph->charpos;
14530 if (!glyph->avoid_cursor_p)
14532 /* If we hit point, we've found the glyph on which to
14533 display the cursor. */
14534 if (dpos == 0)
14536 match_with_avoid_cursor = 0;
14537 break;
14539 /* See if we've found a better approximation to
14540 POS_BEFORE or to POS_AFTER. */
14541 if (0 > dpos && dpos > pos_before - pt_old)
14543 pos_before = glyph->charpos;
14544 glyph_before = glyph;
14546 else if (0 < dpos && dpos < pos_after - pt_old)
14548 pos_after = glyph->charpos;
14549 glyph_after = glyph;
14552 else if (dpos == 0)
14553 match_with_avoid_cursor = 1;
14555 else if (STRINGP (glyph->object))
14557 Lisp_Object chprop;
14558 ptrdiff_t glyph_pos = glyph->charpos;
14560 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
14561 glyph->object);
14562 if (!NILP (chprop))
14564 /* If the string came from a `display' text property,
14565 look up the buffer position of that property and
14566 use that position to update bpos_max, as if we
14567 actually saw such a position in one of the row's
14568 glyphs. This helps with supporting integer values
14569 of `cursor' property on the display string in
14570 situations where most or all of the row's buffer
14571 text is completely covered by display properties,
14572 so that no glyph with valid buffer positions is
14573 ever seen in the row. */
14574 ptrdiff_t prop_pos =
14575 string_buffer_position_lim (glyph->object, pos_before,
14576 pos_after, 0);
14578 if (prop_pos >= pos_before)
14579 bpos_max = prop_pos;
14581 if (INTEGERP (chprop))
14583 bpos_covered = bpos_max + XINT (chprop);
14584 /* If the `cursor' property covers buffer positions up
14585 to and including point, we should display cursor on
14586 this glyph. Note that, if a `cursor' property on one
14587 of the string's characters has an integer value, we
14588 will break out of the loop below _before_ we get to
14589 the position match above. IOW, integer values of
14590 the `cursor' property override the "exact match for
14591 point" strategy of positioning the cursor. */
14592 /* Implementation note: bpos_max == pt_old when, e.g.,
14593 we are in an empty line, where bpos_max is set to
14594 MATRIX_ROW_START_CHARPOS, see above. */
14595 if (bpos_max <= pt_old && bpos_covered >= pt_old)
14597 cursor = glyph;
14598 break;
14602 string_seen = 1;
14604 x += glyph->pixel_width;
14605 ++glyph;
14607 else if (glyph > end) /* row is reversed */
14608 while (!INTEGERP (glyph->object))
14610 if (BUFFERP (glyph->object))
14612 ptrdiff_t dpos = glyph->charpos - pt_old;
14614 if (glyph->charpos > bpos_max)
14615 bpos_max = glyph->charpos;
14616 if (glyph->charpos < bpos_min)
14617 bpos_min = glyph->charpos;
14618 if (!glyph->avoid_cursor_p)
14620 if (dpos == 0)
14622 match_with_avoid_cursor = 0;
14623 break;
14625 if (0 > dpos && dpos > pos_before - pt_old)
14627 pos_before = glyph->charpos;
14628 glyph_before = glyph;
14630 else if (0 < dpos && dpos < pos_after - pt_old)
14632 pos_after = glyph->charpos;
14633 glyph_after = glyph;
14636 else if (dpos == 0)
14637 match_with_avoid_cursor = 1;
14639 else if (STRINGP (glyph->object))
14641 Lisp_Object chprop;
14642 ptrdiff_t glyph_pos = glyph->charpos;
14644 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
14645 glyph->object);
14646 if (!NILP (chprop))
14648 ptrdiff_t prop_pos =
14649 string_buffer_position_lim (glyph->object, pos_before,
14650 pos_after, 0);
14652 if (prop_pos >= pos_before)
14653 bpos_max = prop_pos;
14655 if (INTEGERP (chprop))
14657 bpos_covered = bpos_max + XINT (chprop);
14658 /* If the `cursor' property covers buffer positions up
14659 to and including point, we should display cursor on
14660 this glyph. */
14661 if (bpos_max <= pt_old && bpos_covered >= pt_old)
14663 cursor = glyph;
14664 break;
14667 string_seen = 1;
14669 --glyph;
14670 if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
14672 x--; /* can't use any pixel_width */
14673 break;
14675 x -= glyph->pixel_width;
14678 /* Step 2: If we didn't find an exact match for point, we need to
14679 look for a proper place to put the cursor among glyphs between
14680 GLYPH_BEFORE and GLYPH_AFTER. */
14681 if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
14682 && BUFFERP (glyph->object) && glyph->charpos == pt_old)
14683 && !(bpos_max <= pt_old && pt_old <= bpos_covered))
14685 /* An empty line has a single glyph whose OBJECT is zero and
14686 whose CHARPOS is the position of a newline on that line.
14687 Note that on a TTY, there are more glyphs after that, which
14688 were produced by extend_face_to_end_of_line, but their
14689 CHARPOS is zero or negative. */
14690 int empty_line_p =
14691 (row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
14692 && INTEGERP (glyph->object) && glyph->charpos > 0
14693 /* On a TTY, continued and truncated rows also have a glyph at
14694 their end whose OBJECT is zero and whose CHARPOS is
14695 positive (the continuation and truncation glyphs), but such
14696 rows are obviously not "empty". */
14697 && !(row->continued_p || row->truncated_on_right_p);
14699 if (row->ends_in_ellipsis_p && pos_after == last_pos)
14701 ptrdiff_t ellipsis_pos;
14703 /* Scan back over the ellipsis glyphs. */
14704 if (!row->reversed_p)
14706 ellipsis_pos = (glyph - 1)->charpos;
14707 while (glyph > row->glyphs[TEXT_AREA]
14708 && (glyph - 1)->charpos == ellipsis_pos)
14709 glyph--, x -= glyph->pixel_width;
14710 /* That loop always goes one position too far, including
14711 the glyph before the ellipsis. So scan forward over
14712 that one. */
14713 x += glyph->pixel_width;
14714 glyph++;
14716 else /* row is reversed */
14718 ellipsis_pos = (glyph + 1)->charpos;
14719 while (glyph < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14720 && (glyph + 1)->charpos == ellipsis_pos)
14721 glyph++, x += glyph->pixel_width;
14722 x -= glyph->pixel_width;
14723 glyph--;
14726 else if (match_with_avoid_cursor)
14728 cursor = glyph_after;
14729 x = -1;
14731 else if (string_seen)
14733 int incr = row->reversed_p ? -1 : +1;
14735 /* Need to find the glyph that came out of a string which is
14736 present at point. That glyph is somewhere between
14737 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
14738 positioned between POS_BEFORE and POS_AFTER in the
14739 buffer. */
14740 struct glyph *start, *stop;
14741 ptrdiff_t pos = pos_before;
14743 x = -1;
14745 /* If the row ends in a newline from a display string,
14746 reordering could have moved the glyphs belonging to the
14747 string out of the [GLYPH_BEFORE..GLYPH_AFTER] range. So
14748 in this case we extend the search to the last glyph in
14749 the row that was not inserted by redisplay. */
14750 if (row->ends_in_newline_from_string_p)
14752 glyph_after = end;
14753 pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
14756 /* GLYPH_BEFORE and GLYPH_AFTER are the glyphs that
14757 correspond to POS_BEFORE and POS_AFTER, respectively. We
14758 need START and STOP in the order that corresponds to the
14759 row's direction as given by its reversed_p flag. If the
14760 directionality of characters between POS_BEFORE and
14761 POS_AFTER is the opposite of the row's base direction,
14762 these characters will have been reordered for display,
14763 and we need to reverse START and STOP. */
14764 if (!row->reversed_p)
14766 start = min (glyph_before, glyph_after);
14767 stop = max (glyph_before, glyph_after);
14769 else
14771 start = max (glyph_before, glyph_after);
14772 stop = min (glyph_before, glyph_after);
14774 for (glyph = start + incr;
14775 row->reversed_p ? glyph > stop : glyph < stop; )
14778 /* Any glyphs that come from the buffer are here because
14779 of bidi reordering. Skip them, and only pay
14780 attention to glyphs that came from some string. */
14781 if (STRINGP (glyph->object))
14783 Lisp_Object str;
14784 ptrdiff_t tem;
14785 /* If the display property covers the newline, we
14786 need to search for it one position farther. */
14787 ptrdiff_t lim = pos_after
14788 + (pos_after == MATRIX_ROW_END_CHARPOS (row) + delta);
14790 string_from_text_prop = 0;
14791 str = glyph->object;
14792 tem = string_buffer_position_lim (str, pos, lim, 0);
14793 if (tem == 0 /* from overlay */
14794 || pos <= tem)
14796 /* If the string from which this glyph came is
14797 found in the buffer at point, or at position
14798 that is closer to point than pos_after, then
14799 we've found the glyph we've been looking for.
14800 If it comes from an overlay (tem == 0), and
14801 it has the `cursor' property on one of its
14802 glyphs, record that glyph as a candidate for
14803 displaying the cursor. (As in the
14804 unidirectional version, we will display the
14805 cursor on the last candidate we find.) */
14806 if (tem == 0
14807 || tem == pt_old
14808 || (tem - pt_old > 0 && tem < pos_after))
14810 /* The glyphs from this string could have
14811 been reordered. Find the one with the
14812 smallest string position. Or there could
14813 be a character in the string with the
14814 `cursor' property, which means display
14815 cursor on that character's glyph. */
14816 ptrdiff_t strpos = glyph->charpos;
14818 if (tem)
14820 cursor = glyph;
14821 string_from_text_prop = 1;
14823 for ( ;
14824 (row->reversed_p ? glyph > stop : glyph < stop)
14825 && EQ (glyph->object, str);
14826 glyph += incr)
14828 Lisp_Object cprop;
14829 ptrdiff_t gpos = glyph->charpos;
14831 cprop = Fget_char_property (make_number (gpos),
14832 Qcursor,
14833 glyph->object);
14834 if (!NILP (cprop))
14836 cursor = glyph;
14837 break;
14839 if (tem && glyph->charpos < strpos)
14841 strpos = glyph->charpos;
14842 cursor = glyph;
14846 if (tem == pt_old
14847 || (tem - pt_old > 0 && tem < pos_after))
14848 goto compute_x;
14850 if (tem)
14851 pos = tem + 1; /* don't find previous instances */
14853 /* This string is not what we want; skip all of the
14854 glyphs that came from it. */
14855 while ((row->reversed_p ? glyph > stop : glyph < stop)
14856 && EQ (glyph->object, str))
14857 glyph += incr;
14859 else
14860 glyph += incr;
14863 /* If we reached the end of the line, and END was from a string,
14864 the cursor is not on this line. */
14865 if (cursor == NULL
14866 && (row->reversed_p ? glyph <= end : glyph >= end)
14867 && (row->reversed_p ? end > glyphs_end : end < glyphs_end)
14868 && STRINGP (end->object)
14869 && row->continued_p)
14870 return 0;
14872 /* A truncated row may not include PT among its character positions.
14873 Setting the cursor inside the scroll margin will trigger
14874 recalculation of hscroll in hscroll_window_tree. But if a
14875 display string covers point, defer to the string-handling
14876 code below to figure this out. */
14877 else if (row->truncated_on_left_p && pt_old < bpos_min)
14879 cursor = glyph_before;
14880 x = -1;
14882 else if ((row->truncated_on_right_p && pt_old > bpos_max)
14883 /* Zero-width characters produce no glyphs. */
14884 || (!empty_line_p
14885 && (row->reversed_p
14886 ? glyph_after > glyphs_end
14887 : glyph_after < glyphs_end)))
14889 cursor = glyph_after;
14890 x = -1;
14894 compute_x:
14895 if (cursor != NULL)
14896 glyph = cursor;
14897 else if (glyph == glyphs_end
14898 && pos_before == pos_after
14899 && STRINGP ((row->reversed_p
14900 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14901 : row->glyphs[TEXT_AREA])->object))
14903 /* If all the glyphs of this row came from strings, put the
14904 cursor on the first glyph of the row. This avoids having the
14905 cursor outside of the text area in this very rare and hard
14906 use case. */
14907 glyph =
14908 row->reversed_p
14909 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14910 : row->glyphs[TEXT_AREA];
14912 if (x < 0)
14914 struct glyph *g;
14916 /* Need to compute x that corresponds to GLYPH. */
14917 for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++)
14919 if (g >= row->glyphs[TEXT_AREA] + row->used[TEXT_AREA])
14920 emacs_abort ();
14921 x += g->pixel_width;
14925 /* ROW could be part of a continued line, which, under bidi
14926 reordering, might have other rows whose start and end charpos
14927 occlude point. Only set w->cursor if we found a better
14928 approximation to the cursor position than we have from previously
14929 examined candidate rows belonging to the same continued line. */
14930 if (/* We already have a candidate row. */
14931 w->cursor.vpos >= 0
14932 /* That candidate is not the row we are processing. */
14933 && MATRIX_ROW (matrix, w->cursor.vpos) != row
14934 /* Make sure cursor.vpos specifies a row whose start and end
14935 charpos occlude point, and it is valid candidate for being a
14936 cursor-row. This is because some callers of this function
14937 leave cursor.vpos at the row where the cursor was displayed
14938 during the last redisplay cycle. */
14939 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old
14940 && pt_old <= MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14941 && cursor_row_p (MATRIX_ROW (matrix, w->cursor.vpos)))
14943 struct glyph *g1
14944 = MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
14946 /* Don't consider glyphs that are outside TEXT_AREA. */
14947 if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
14948 return 0;
14949 /* Keep the candidate whose buffer position is the closest to
14950 point or has the `cursor' property. */
14951 if (/* Previous candidate is a glyph in TEXT_AREA of that row. */
14952 w->cursor.hpos >= 0
14953 && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
14954 && ((BUFFERP (g1->object)
14955 && (g1->charpos == pt_old /* An exact match always wins. */
14956 || (BUFFERP (glyph->object)
14957 && eabs (g1->charpos - pt_old)
14958 < eabs (glyph->charpos - pt_old))))
14959 /* Previous candidate is a glyph from a string that has
14960 a non-nil `cursor' property. */
14961 || (STRINGP (g1->object)
14962 && (!NILP (Fget_char_property (make_number (g1->charpos),
14963 Qcursor, g1->object))
14964 /* Previous candidate is from the same display
14965 string as this one, and the display string
14966 came from a text property. */
14967 || (EQ (g1->object, glyph->object)
14968 && string_from_text_prop)
14969 /* this candidate is from newline and its
14970 position is not an exact match */
14971 || (INTEGERP (glyph->object)
14972 && glyph->charpos != pt_old)))))
14973 return 0;
14974 /* If this candidate gives an exact match, use that. */
14975 if (!((BUFFERP (glyph->object) && glyph->charpos == pt_old)
14976 /* If this candidate is a glyph created for the
14977 terminating newline of a line, and point is on that
14978 newline, it wins because it's an exact match. */
14979 || (!row->continued_p
14980 && INTEGERP (glyph->object)
14981 && glyph->charpos == 0
14982 && pt_old == MATRIX_ROW_END_CHARPOS (row) - 1))
14983 /* Otherwise, keep the candidate that comes from a row
14984 spanning less buffer positions. This may win when one or
14985 both candidate positions are on glyphs that came from
14986 display strings, for which we cannot compare buffer
14987 positions. */
14988 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14989 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14990 < MATRIX_ROW_END_CHARPOS (row) - MATRIX_ROW_START_CHARPOS (row))
14991 return 0;
14993 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
14994 w->cursor.x = x;
14995 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
14996 w->cursor.y = row->y + dy;
14998 if (w == XWINDOW (selected_window))
15000 if (!row->continued_p
15001 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
15002 && row->x == 0)
15004 this_line_buffer = XBUFFER (w->contents);
15006 CHARPOS (this_line_start_pos)
15007 = MATRIX_ROW_START_CHARPOS (row) + delta;
15008 BYTEPOS (this_line_start_pos)
15009 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
15011 CHARPOS (this_line_end_pos)
15012 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
15013 BYTEPOS (this_line_end_pos)
15014 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
15016 this_line_y = w->cursor.y;
15017 this_line_pixel_height = row->height;
15018 this_line_vpos = w->cursor.vpos;
15019 this_line_start_x = row->x;
15021 else
15022 CHARPOS (this_line_start_pos) = 0;
15025 return 1;
15029 /* Run window scroll functions, if any, for WINDOW with new window
15030 start STARTP. Sets the window start of WINDOW to that position.
15032 We assume that the window's buffer is really current. */
15034 static struct text_pos
15035 run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
15037 struct window *w = XWINDOW (window);
15038 SET_MARKER_FROM_TEXT_POS (w->start, startp);
15040 eassert (current_buffer == XBUFFER (w->contents));
15042 if (!NILP (Vwindow_scroll_functions))
15044 run_hook_with_args_2 (Qwindow_scroll_functions, window,
15045 make_number (CHARPOS (startp)));
15046 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15047 /* In case the hook functions switch buffers. */
15048 set_buffer_internal (XBUFFER (w->contents));
15051 return startp;
15055 /* Make sure the line containing the cursor is fully visible.
15056 A value of 1 means there is nothing to be done.
15057 (Either the line is fully visible, or it cannot be made so,
15058 or we cannot tell.)
15060 If FORCE_P is non-zero, return 0 even if partial visible cursor row
15061 is higher than window.
15063 If CURRENT_MATRIX_P is non-zero, use the information from the
15064 window's current glyph matrix; otherwise use the desired glyph
15065 matrix.
15067 A value of 0 means the caller should do scrolling
15068 as if point had gone off the screen. */
15070 static int
15071 cursor_row_fully_visible_p (struct window *w, int force_p, int current_matrix_p)
15073 struct glyph_matrix *matrix;
15074 struct glyph_row *row;
15075 int window_height;
15077 if (!make_cursor_line_fully_visible_p)
15078 return 1;
15080 /* It's not always possible to find the cursor, e.g, when a window
15081 is full of overlay strings. Don't do anything in that case. */
15082 if (w->cursor.vpos < 0)
15083 return 1;
15085 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
15086 row = MATRIX_ROW (matrix, w->cursor.vpos);
15088 /* If the cursor row is not partially visible, there's nothing to do. */
15089 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
15090 return 1;
15092 /* If the row the cursor is in is taller than the window's height,
15093 it's not clear what to do, so do nothing. */
15094 window_height = window_box_height (w);
15095 if (row->height >= window_height)
15097 if (!force_p || MINI_WINDOW_P (w)
15098 || w->vscroll || w->cursor.vpos == 0)
15099 return 1;
15101 return 0;
15105 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
15106 non-zero means only WINDOW is redisplayed in redisplay_internal.
15107 TEMP_SCROLL_STEP has the same meaning as emacs_scroll_step, and is used
15108 in redisplay_window to bring a partially visible line into view in
15109 the case that only the cursor has moved.
15111 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
15112 last screen line's vertical height extends past the end of the screen.
15114 Value is
15116 1 if scrolling succeeded
15118 0 if scrolling didn't find point.
15120 -1 if new fonts have been loaded so that we must interrupt
15121 redisplay, adjust glyph matrices, and try again. */
15123 enum
15125 SCROLLING_SUCCESS,
15126 SCROLLING_FAILED,
15127 SCROLLING_NEED_LARGER_MATRICES
15130 /* If scroll-conservatively is more than this, never recenter.
15132 If you change this, don't forget to update the doc string of
15133 `scroll-conservatively' and the Emacs manual. */
15134 #define SCROLL_LIMIT 100
15136 static int
15137 try_scrolling (Lisp_Object window, int just_this_one_p,
15138 ptrdiff_t arg_scroll_conservatively, ptrdiff_t scroll_step,
15139 int temp_scroll_step, int last_line_misfit)
15141 struct window *w = XWINDOW (window);
15142 struct frame *f = XFRAME (w->frame);
15143 struct text_pos pos, startp;
15144 struct it it;
15145 int this_scroll_margin, scroll_max, rc, height;
15146 int dy = 0, amount_to_scroll = 0, scroll_down_p = 0;
15147 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
15148 Lisp_Object aggressive;
15149 /* We will never try scrolling more than this number of lines. */
15150 int scroll_limit = SCROLL_LIMIT;
15151 int frame_line_height = default_line_pixel_height (w);
15152 int window_total_lines
15153 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
15155 #ifdef GLYPH_DEBUG
15156 debug_method_add (w, "try_scrolling");
15157 #endif
15159 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15161 /* Compute scroll margin height in pixels. We scroll when point is
15162 within this distance from the top or bottom of the window. */
15163 if (scroll_margin > 0)
15164 this_scroll_margin = min (scroll_margin, window_total_lines / 4)
15165 * frame_line_height;
15166 else
15167 this_scroll_margin = 0;
15169 /* Force arg_scroll_conservatively to have a reasonable value, to
15170 avoid scrolling too far away with slow move_it_* functions. Note
15171 that the user can supply scroll-conservatively equal to
15172 `most-positive-fixnum', which can be larger than INT_MAX. */
15173 if (arg_scroll_conservatively > scroll_limit)
15175 arg_scroll_conservatively = scroll_limit + 1;
15176 scroll_max = scroll_limit * frame_line_height;
15178 else if (scroll_step || arg_scroll_conservatively || temp_scroll_step)
15179 /* Compute how much we should try to scroll maximally to bring
15180 point into view. */
15181 scroll_max = (max (scroll_step,
15182 max (arg_scroll_conservatively, temp_scroll_step))
15183 * frame_line_height);
15184 else if (NUMBERP (BVAR (current_buffer, scroll_down_aggressively))
15185 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively)))
15186 /* We're trying to scroll because of aggressive scrolling but no
15187 scroll_step is set. Choose an arbitrary one. */
15188 scroll_max = 10 * frame_line_height;
15189 else
15190 scroll_max = 0;
15192 too_near_end:
15194 /* Decide whether to scroll down. */
15195 if (PT > CHARPOS (startp))
15197 int scroll_margin_y;
15199 /* Compute the pixel ypos of the scroll margin, then move IT to
15200 either that ypos or PT, whichever comes first. */
15201 start_display (&it, w, startp);
15202 scroll_margin_y = it.last_visible_y - this_scroll_margin
15203 - frame_line_height * extra_scroll_margin_lines;
15204 move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
15205 (MOVE_TO_POS | MOVE_TO_Y));
15207 if (PT > CHARPOS (it.current.pos))
15209 int y0 = line_bottom_y (&it);
15210 /* Compute how many pixels below window bottom to stop searching
15211 for PT. This avoids costly search for PT that is far away if
15212 the user limited scrolling by a small number of lines, but
15213 always finds PT if scroll_conservatively is set to a large
15214 number, such as most-positive-fixnum. */
15215 int slack = max (scroll_max, 10 * frame_line_height);
15216 int y_to_move = it.last_visible_y + slack;
15218 /* Compute the distance from the scroll margin to PT or to
15219 the scroll limit, whichever comes first. This should
15220 include the height of the cursor line, to make that line
15221 fully visible. */
15222 move_it_to (&it, PT, -1, y_to_move,
15223 -1, MOVE_TO_POS | MOVE_TO_Y);
15224 dy = line_bottom_y (&it) - y0;
15226 if (dy > scroll_max)
15227 return SCROLLING_FAILED;
15229 if (dy > 0)
15230 scroll_down_p = 1;
15234 if (scroll_down_p)
15236 /* Point is in or below the bottom scroll margin, so move the
15237 window start down. If scrolling conservatively, move it just
15238 enough down to make point visible. If scroll_step is set,
15239 move it down by scroll_step. */
15240 if (arg_scroll_conservatively)
15241 amount_to_scroll
15242 = min (max (dy, frame_line_height),
15243 frame_line_height * arg_scroll_conservatively);
15244 else if (scroll_step || temp_scroll_step)
15245 amount_to_scroll = scroll_max;
15246 else
15248 aggressive = BVAR (current_buffer, scroll_up_aggressively);
15249 height = WINDOW_BOX_TEXT_HEIGHT (w);
15250 if (NUMBERP (aggressive))
15252 double float_amount = XFLOATINT (aggressive) * height;
15253 int aggressive_scroll = float_amount;
15254 if (aggressive_scroll == 0 && float_amount > 0)
15255 aggressive_scroll = 1;
15256 /* Don't let point enter the scroll margin near top of
15257 the window. This could happen if the value of
15258 scroll_up_aggressively is too large and there are
15259 non-zero margins, because scroll_up_aggressively
15260 means put point that fraction of window height
15261 _from_the_bottom_margin_. */
15262 if (aggressive_scroll + 2 * this_scroll_margin > height)
15263 aggressive_scroll = height - 2 * this_scroll_margin;
15264 amount_to_scroll = dy + aggressive_scroll;
15268 if (amount_to_scroll <= 0)
15269 return SCROLLING_FAILED;
15271 start_display (&it, w, startp);
15272 if (arg_scroll_conservatively <= scroll_limit)
15273 move_it_vertically (&it, amount_to_scroll);
15274 else
15276 /* Extra precision for users who set scroll-conservatively
15277 to a large number: make sure the amount we scroll
15278 the window start is never less than amount_to_scroll,
15279 which was computed as distance from window bottom to
15280 point. This matters when lines at window top and lines
15281 below window bottom have different height. */
15282 struct it it1;
15283 void *it1data = NULL;
15284 /* We use a temporary it1 because line_bottom_y can modify
15285 its argument, if it moves one line down; see there. */
15286 int start_y;
15288 SAVE_IT (it1, it, it1data);
15289 start_y = line_bottom_y (&it1);
15290 do {
15291 RESTORE_IT (&it, &it, it1data);
15292 move_it_by_lines (&it, 1);
15293 SAVE_IT (it1, it, it1data);
15294 } while (line_bottom_y (&it1) - start_y < amount_to_scroll);
15297 /* If STARTP is unchanged, move it down another screen line. */
15298 if (CHARPOS (it.current.pos) == CHARPOS (startp))
15299 move_it_by_lines (&it, 1);
15300 startp = it.current.pos;
15302 else
15304 struct text_pos scroll_margin_pos = startp;
15305 int y_offset = 0;
15307 /* See if point is inside the scroll margin at the top of the
15308 window. */
15309 if (this_scroll_margin)
15311 int y_start;
15313 start_display (&it, w, startp);
15314 y_start = it.current_y;
15315 move_it_vertically (&it, this_scroll_margin);
15316 scroll_margin_pos = it.current.pos;
15317 /* If we didn't move enough before hitting ZV, request
15318 additional amount of scroll, to move point out of the
15319 scroll margin. */
15320 if (IT_CHARPOS (it) == ZV
15321 && it.current_y - y_start < this_scroll_margin)
15322 y_offset = this_scroll_margin - (it.current_y - y_start);
15325 if (PT < CHARPOS (scroll_margin_pos))
15327 /* Point is in the scroll margin at the top of the window or
15328 above what is displayed in the window. */
15329 int y0, y_to_move;
15331 /* Compute the vertical distance from PT to the scroll
15332 margin position. Move as far as scroll_max allows, or
15333 one screenful, or 10 screen lines, whichever is largest.
15334 Give up if distance is greater than scroll_max or if we
15335 didn't reach the scroll margin position. */
15336 SET_TEXT_POS (pos, PT, PT_BYTE);
15337 start_display (&it, w, pos);
15338 y0 = it.current_y;
15339 y_to_move = max (it.last_visible_y,
15340 max (scroll_max, 10 * frame_line_height));
15341 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
15342 y_to_move, -1,
15343 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
15344 dy = it.current_y - y0;
15345 if (dy > scroll_max
15346 || IT_CHARPOS (it) < CHARPOS (scroll_margin_pos))
15347 return SCROLLING_FAILED;
15349 /* Additional scroll for when ZV was too close to point. */
15350 dy += y_offset;
15352 /* Compute new window start. */
15353 start_display (&it, w, startp);
15355 if (arg_scroll_conservatively)
15356 amount_to_scroll = max (dy, frame_line_height
15357 * max (scroll_step, temp_scroll_step));
15358 else if (scroll_step || temp_scroll_step)
15359 amount_to_scroll = scroll_max;
15360 else
15362 aggressive = BVAR (current_buffer, scroll_down_aggressively);
15363 height = WINDOW_BOX_TEXT_HEIGHT (w);
15364 if (NUMBERP (aggressive))
15366 double float_amount = XFLOATINT (aggressive) * height;
15367 int aggressive_scroll = float_amount;
15368 if (aggressive_scroll == 0 && float_amount > 0)
15369 aggressive_scroll = 1;
15370 /* Don't let point enter the scroll margin near
15371 bottom of the window, if the value of
15372 scroll_down_aggressively happens to be too
15373 large. */
15374 if (aggressive_scroll + 2 * this_scroll_margin > height)
15375 aggressive_scroll = height - 2 * this_scroll_margin;
15376 amount_to_scroll = dy + aggressive_scroll;
15380 if (amount_to_scroll <= 0)
15381 return SCROLLING_FAILED;
15383 move_it_vertically_backward (&it, amount_to_scroll);
15384 startp = it.current.pos;
15388 /* Run window scroll functions. */
15389 startp = run_window_scroll_functions (window, startp);
15391 /* Display the window. Give up if new fonts are loaded, or if point
15392 doesn't appear. */
15393 if (!try_window (window, startp, 0))
15394 rc = SCROLLING_NEED_LARGER_MATRICES;
15395 else if (w->cursor.vpos < 0)
15397 clear_glyph_matrix (w->desired_matrix);
15398 rc = SCROLLING_FAILED;
15400 else
15402 /* Maybe forget recorded base line for line number display. */
15403 if (!just_this_one_p
15404 || current_buffer->clip_changed
15405 || BEG_UNCHANGED < CHARPOS (startp))
15406 w->base_line_number = 0;
15408 /* If cursor ends up on a partially visible line,
15409 treat that as being off the bottom of the screen. */
15410 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0)
15411 /* It's possible that the cursor is on the first line of the
15412 buffer, which is partially obscured due to a vscroll
15413 (Bug#7537). In that case, avoid looping forever. */
15414 && extra_scroll_margin_lines < w->desired_matrix->nrows - 1)
15416 clear_glyph_matrix (w->desired_matrix);
15417 ++extra_scroll_margin_lines;
15418 goto too_near_end;
15420 rc = SCROLLING_SUCCESS;
15423 return rc;
15427 /* Compute a suitable window start for window W if display of W starts
15428 on a continuation line. Value is non-zero if a new window start
15429 was computed.
15431 The new window start will be computed, based on W's width, starting
15432 from the start of the continued line. It is the start of the
15433 screen line with the minimum distance from the old start W->start. */
15435 static int
15436 compute_window_start_on_continuation_line (struct window *w)
15438 struct text_pos pos, start_pos;
15439 int window_start_changed_p = 0;
15441 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
15443 /* If window start is on a continuation line... Window start may be
15444 < BEGV in case there's invisible text at the start of the
15445 buffer (M-x rmail, for example). */
15446 if (CHARPOS (start_pos) > BEGV
15447 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
15449 struct it it;
15450 struct glyph_row *row;
15452 /* Handle the case that the window start is out of range. */
15453 if (CHARPOS (start_pos) < BEGV)
15454 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
15455 else if (CHARPOS (start_pos) > ZV)
15456 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
15458 /* Find the start of the continued line. This should be fast
15459 because find_newline is fast (newline cache). */
15460 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
15461 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
15462 row, DEFAULT_FACE_ID);
15463 reseat_at_previous_visible_line_start (&it);
15465 /* If the line start is "too far" away from the window start,
15466 say it takes too much time to compute a new window start. */
15467 if (CHARPOS (start_pos) - IT_CHARPOS (it)
15468 /* PXW: Do we need upper bounds here? */
15469 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
15471 int min_distance, distance;
15473 /* Move forward by display lines to find the new window
15474 start. If window width was enlarged, the new start can
15475 be expected to be > the old start. If window width was
15476 decreased, the new window start will be < the old start.
15477 So, we're looking for the display line start with the
15478 minimum distance from the old window start. */
15479 pos = it.current.pos;
15480 min_distance = INFINITY;
15481 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
15482 distance < min_distance)
15484 min_distance = distance;
15485 pos = it.current.pos;
15486 if (it.line_wrap == WORD_WRAP)
15488 /* Under WORD_WRAP, move_it_by_lines is likely to
15489 overshoot and stop not at the first, but the
15490 second character from the left margin. So in
15491 that case, we need a more tight control on the X
15492 coordinate of the iterator than move_it_by_lines
15493 promises in its contract. The method is to first
15494 go to the last (rightmost) visible character of a
15495 line, then move to the leftmost character on the
15496 next line in a separate call. */
15497 move_it_to (&it, ZV, it.last_visible_x, it.current_y, -1,
15498 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
15499 move_it_to (&it, ZV, 0,
15500 it.current_y + it.max_ascent + it.max_descent, -1,
15501 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
15503 else
15504 move_it_by_lines (&it, 1);
15507 /* Set the window start there. */
15508 SET_MARKER_FROM_TEXT_POS (w->start, pos);
15509 window_start_changed_p = 1;
15513 return window_start_changed_p;
15517 /* Try cursor movement in case text has not changed in window WINDOW,
15518 with window start STARTP. Value is
15520 CURSOR_MOVEMENT_SUCCESS if successful
15522 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
15524 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
15525 display. *SCROLL_STEP is set to 1, under certain circumstances, if
15526 we want to scroll as if scroll-step were set to 1. See the code.
15528 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
15529 which case we have to abort this redisplay, and adjust matrices
15530 first. */
15532 enum
15534 CURSOR_MOVEMENT_SUCCESS,
15535 CURSOR_MOVEMENT_CANNOT_BE_USED,
15536 CURSOR_MOVEMENT_MUST_SCROLL,
15537 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
15540 static int
15541 try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_step)
15543 struct window *w = XWINDOW (window);
15544 struct frame *f = XFRAME (w->frame);
15545 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
15547 #ifdef GLYPH_DEBUG
15548 if (inhibit_try_cursor_movement)
15549 return rc;
15550 #endif
15552 /* Previously, there was a check for Lisp integer in the
15553 if-statement below. Now, this field is converted to
15554 ptrdiff_t, thus zero means invalid position in a buffer. */
15555 eassert (w->last_point > 0);
15556 /* Likewise there was a check whether window_end_vpos is nil or larger
15557 than the window. Now window_end_vpos is int and so never nil, but
15558 let's leave eassert to check whether it fits in the window. */
15559 eassert (w->window_end_vpos < w->current_matrix->nrows);
15561 /* Handle case where text has not changed, only point, and it has
15562 not moved off the frame. */
15563 if (/* Point may be in this window. */
15564 PT >= CHARPOS (startp)
15565 /* Selective display hasn't changed. */
15566 && !current_buffer->clip_changed
15567 /* Function force-mode-line-update is used to force a thorough
15568 redisplay. It sets either windows_or_buffers_changed or
15569 update_mode_lines. So don't take a shortcut here for these
15570 cases. */
15571 && !update_mode_lines
15572 && !windows_or_buffers_changed
15573 && !f->cursor_type_changed
15574 && NILP (Vshow_trailing_whitespace)
15575 /* This code is not used for mini-buffer for the sake of the case
15576 of redisplaying to replace an echo area message; since in
15577 that case the mini-buffer contents per se are usually
15578 unchanged. This code is of no real use in the mini-buffer
15579 since the handling of this_line_start_pos, etc., in redisplay
15580 handles the same cases. */
15581 && !EQ (window, minibuf_window)
15582 && (FRAME_WINDOW_P (f)
15583 || !overlay_arrow_in_current_buffer_p ()))
15585 int this_scroll_margin, top_scroll_margin;
15586 struct glyph_row *row = NULL;
15587 int frame_line_height = default_line_pixel_height (w);
15588 int window_total_lines
15589 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
15591 #ifdef GLYPH_DEBUG
15592 debug_method_add (w, "cursor movement");
15593 #endif
15595 /* Scroll if point within this distance from the top or bottom
15596 of the window. This is a pixel value. */
15597 if (scroll_margin > 0)
15599 this_scroll_margin = min (scroll_margin, window_total_lines / 4);
15600 this_scroll_margin *= frame_line_height;
15602 else
15603 this_scroll_margin = 0;
15605 top_scroll_margin = this_scroll_margin;
15606 if (WINDOW_WANTS_HEADER_LINE_P (w))
15607 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
15609 /* Start with the row the cursor was displayed during the last
15610 not paused redisplay. Give up if that row is not valid. */
15611 if (w->last_cursor_vpos < 0
15612 || w->last_cursor_vpos >= w->current_matrix->nrows)
15613 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15614 else
15616 row = MATRIX_ROW (w->current_matrix, w->last_cursor_vpos);
15617 if (row->mode_line_p)
15618 ++row;
15619 if (!row->enabled_p)
15620 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15623 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
15625 int scroll_p = 0, must_scroll = 0;
15626 int last_y = window_text_bottom_y (w) - this_scroll_margin;
15628 if (PT > w->last_point)
15630 /* Point has moved forward. */
15631 while (MATRIX_ROW_END_CHARPOS (row) < PT
15632 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
15634 eassert (row->enabled_p);
15635 ++row;
15638 /* If the end position of a row equals the start
15639 position of the next row, and PT is at that position,
15640 we would rather display cursor in the next line. */
15641 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15642 && MATRIX_ROW_END_CHARPOS (row) == PT
15643 && row < MATRIX_MODE_LINE_ROW (w->current_matrix)
15644 && MATRIX_ROW_START_CHARPOS (row+1) == PT
15645 && !cursor_row_p (row))
15646 ++row;
15648 /* If within the scroll margin, scroll. Note that
15649 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
15650 the next line would be drawn, and that
15651 this_scroll_margin can be zero. */
15652 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
15653 || PT > MATRIX_ROW_END_CHARPOS (row)
15654 /* Line is completely visible last line in window
15655 and PT is to be set in the next line. */
15656 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
15657 && PT == MATRIX_ROW_END_CHARPOS (row)
15658 && !row->ends_at_zv_p
15659 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
15660 scroll_p = 1;
15662 else if (PT < w->last_point)
15664 /* Cursor has to be moved backward. Note that PT >=
15665 CHARPOS (startp) because of the outer if-statement. */
15666 while (!row->mode_line_p
15667 && (MATRIX_ROW_START_CHARPOS (row) > PT
15668 || (MATRIX_ROW_START_CHARPOS (row) == PT
15669 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
15670 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
15671 row > w->current_matrix->rows
15672 && (row-1)->ends_in_newline_from_string_p))))
15673 && (row->y > top_scroll_margin
15674 || CHARPOS (startp) == BEGV))
15676 eassert (row->enabled_p);
15677 --row;
15680 /* Consider the following case: Window starts at BEGV,
15681 there is invisible, intangible text at BEGV, so that
15682 display starts at some point START > BEGV. It can
15683 happen that we are called with PT somewhere between
15684 BEGV and START. Try to handle that case. */
15685 if (row < w->current_matrix->rows
15686 || row->mode_line_p)
15688 row = w->current_matrix->rows;
15689 if (row->mode_line_p)
15690 ++row;
15693 /* Due to newlines in overlay strings, we may have to
15694 skip forward over overlay strings. */
15695 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15696 && MATRIX_ROW_END_CHARPOS (row) == PT
15697 && !cursor_row_p (row))
15698 ++row;
15700 /* If within the scroll margin, scroll. */
15701 if (row->y < top_scroll_margin
15702 && CHARPOS (startp) != BEGV)
15703 scroll_p = 1;
15705 else
15707 /* Cursor did not move. So don't scroll even if cursor line
15708 is partially visible, as it was so before. */
15709 rc = CURSOR_MOVEMENT_SUCCESS;
15712 if (PT < MATRIX_ROW_START_CHARPOS (row)
15713 || PT > MATRIX_ROW_END_CHARPOS (row))
15715 /* if PT is not in the glyph row, give up. */
15716 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15717 must_scroll = 1;
15719 else if (rc != CURSOR_MOVEMENT_SUCCESS
15720 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
15722 struct glyph_row *row1;
15724 /* If rows are bidi-reordered and point moved, back up
15725 until we find a row that does not belong to a
15726 continuation line. This is because we must consider
15727 all rows of a continued line as candidates for the
15728 new cursor positioning, since row start and end
15729 positions change non-linearly with vertical position
15730 in such rows. */
15731 /* FIXME: Revisit this when glyph ``spilling'' in
15732 continuation lines' rows is implemented for
15733 bidi-reordered rows. */
15734 for (row1 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
15735 MATRIX_ROW_CONTINUATION_LINE_P (row);
15736 --row)
15738 /* If we hit the beginning of the displayed portion
15739 without finding the first row of a continued
15740 line, give up. */
15741 if (row <= row1)
15743 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15744 break;
15746 eassert (row->enabled_p);
15749 if (must_scroll)
15751 else if (rc != CURSOR_MOVEMENT_SUCCESS
15752 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
15753 /* Make sure this isn't a header line by any chance, since
15754 then MATRIX_ROW_PARTIALLY_VISIBLE_P might yield non-zero. */
15755 && !row->mode_line_p
15756 && make_cursor_line_fully_visible_p)
15758 if (PT == MATRIX_ROW_END_CHARPOS (row)
15759 && !row->ends_at_zv_p
15760 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
15761 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15762 else if (row->height > window_box_height (w))
15764 /* If we end up in a partially visible line, let's
15765 make it fully visible, except when it's taller
15766 than the window, in which case we can't do much
15767 about it. */
15768 *scroll_step = 1;
15769 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15771 else
15773 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
15774 if (!cursor_row_fully_visible_p (w, 0, 1))
15775 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15776 else
15777 rc = CURSOR_MOVEMENT_SUCCESS;
15780 else if (scroll_p)
15781 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15782 else if (rc != CURSOR_MOVEMENT_SUCCESS
15783 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
15785 /* With bidi-reordered rows, there could be more than
15786 one candidate row whose start and end positions
15787 occlude point. We need to let set_cursor_from_row
15788 find the best candidate. */
15789 /* FIXME: Revisit this when glyph ``spilling'' in
15790 continuation lines' rows is implemented for
15791 bidi-reordered rows. */
15792 int rv = 0;
15796 int at_zv_p = 0, exact_match_p = 0;
15798 if (MATRIX_ROW_START_CHARPOS (row) <= PT
15799 && PT <= MATRIX_ROW_END_CHARPOS (row)
15800 && cursor_row_p (row))
15801 rv |= set_cursor_from_row (w, row, w->current_matrix,
15802 0, 0, 0, 0);
15803 /* As soon as we've found the exact match for point,
15804 or the first suitable row whose ends_at_zv_p flag
15805 is set, we are done. */
15806 if (rv)
15808 at_zv_p = MATRIX_ROW (w->current_matrix,
15809 w->cursor.vpos)->ends_at_zv_p;
15810 if (!at_zv_p
15811 && w->cursor.hpos >= 0
15812 && w->cursor.hpos < MATRIX_ROW_USED (w->current_matrix,
15813 w->cursor.vpos))
15815 struct glyph_row *candidate =
15816 MATRIX_ROW (w->current_matrix, w->cursor.vpos);
15817 struct glyph *g =
15818 candidate->glyphs[TEXT_AREA] + w->cursor.hpos;
15819 ptrdiff_t endpos = MATRIX_ROW_END_CHARPOS (candidate);
15821 exact_match_p =
15822 (BUFFERP (g->object) && g->charpos == PT)
15823 || (INTEGERP (g->object)
15824 && (g->charpos == PT
15825 || (g->charpos == 0 && endpos - 1 == PT)));
15827 if (at_zv_p || exact_match_p)
15829 rc = CURSOR_MOVEMENT_SUCCESS;
15830 break;
15833 if (MATRIX_ROW_BOTTOM_Y (row) == last_y)
15834 break;
15835 ++row;
15837 while (((MATRIX_ROW_CONTINUATION_LINE_P (row)
15838 || row->continued_p)
15839 && MATRIX_ROW_BOTTOM_Y (row) <= last_y)
15840 || (MATRIX_ROW_START_CHARPOS (row) == PT
15841 && MATRIX_ROW_BOTTOM_Y (row) < last_y));
15842 /* If we didn't find any candidate rows, or exited the
15843 loop before all the candidates were examined, signal
15844 to the caller that this method failed. */
15845 if (rc != CURSOR_MOVEMENT_SUCCESS
15846 && !(rv
15847 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
15848 && !row->continued_p))
15849 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15850 else if (rv)
15851 rc = CURSOR_MOVEMENT_SUCCESS;
15853 else
15857 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
15859 rc = CURSOR_MOVEMENT_SUCCESS;
15860 break;
15862 ++row;
15864 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15865 && MATRIX_ROW_START_CHARPOS (row) == PT
15866 && cursor_row_p (row));
15871 return rc;
15875 void
15876 set_vertical_scroll_bar (struct window *w)
15878 ptrdiff_t start, end, whole;
15880 /* Calculate the start and end positions for the current window.
15881 At some point, it would be nice to choose between scrollbars
15882 which reflect the whole buffer size, with special markers
15883 indicating narrowing, and scrollbars which reflect only the
15884 visible region.
15886 Note that mini-buffers sometimes aren't displaying any text. */
15887 if (!MINI_WINDOW_P (w)
15888 || (w == XWINDOW (minibuf_window)
15889 && NILP (echo_area_buffer[0])))
15891 struct buffer *buf = XBUFFER (w->contents);
15892 whole = BUF_ZV (buf) - BUF_BEGV (buf);
15893 start = marker_position (w->start) - BUF_BEGV (buf);
15894 /* I don't think this is guaranteed to be right. For the
15895 moment, we'll pretend it is. */
15896 end = BUF_Z (buf) - w->window_end_pos - BUF_BEGV (buf);
15898 if (end < start)
15899 end = start;
15900 if (whole < (end - start))
15901 whole = end - start;
15903 else
15904 start = end = whole = 0;
15906 /* Indicate what this scroll bar ought to be displaying now. */
15907 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
15908 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
15909 (w, end - start, whole, start);
15913 void
15914 set_horizontal_scroll_bar (struct window *w)
15916 int start, end, whole, portion;
15918 if (!MINI_WINDOW_P (w)
15919 || (w == XWINDOW (minibuf_window)
15920 && NILP (echo_area_buffer[0])))
15922 struct buffer *b = XBUFFER (w->contents);
15923 struct buffer *old_buffer = NULL;
15924 struct it it;
15925 struct text_pos startp;
15927 if (b != current_buffer)
15929 old_buffer = current_buffer;
15930 set_buffer_internal (b);
15933 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15934 start_display (&it, w, startp);
15935 it.last_visible_x = INT_MAX;
15936 whole = move_it_to (&it, -1, INT_MAX, window_box_height (w), -1,
15937 MOVE_TO_X | MOVE_TO_Y);
15938 /* whole = move_it_to (&it, w->window_end_pos, INT_MAX,
15939 window_box_height (w), -1,
15940 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); */
15942 start = w->hscroll * FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w));
15943 end = start + window_box_width (w, TEXT_AREA);
15944 portion = end - start;
15945 /* After enlarging a horizontally scrolled window such that it
15946 gets at least as wide as the text it contains, make sure that
15947 the thumb doesn't fill the entire scroll bar so we can still
15948 drag it back to see the entire text. */
15949 whole = max (whole, end);
15951 if (it.bidi_p)
15953 Lisp_Object pdir;
15955 pdir = Fcurrent_bidi_paragraph_direction (Qnil);
15956 if (EQ (pdir, Qright_to_left))
15958 start = whole - end;
15959 end = start + portion;
15963 if (old_buffer)
15964 set_buffer_internal (old_buffer);
15966 else
15967 start = end = whole = portion = 0;
15969 w->hscroll_whole = whole;
15971 /* Indicate what this scroll bar ought to be displaying now. */
15972 if (FRAME_TERMINAL (XFRAME (w->frame))->set_horizontal_scroll_bar_hook)
15973 (*FRAME_TERMINAL (XFRAME (w->frame))->set_horizontal_scroll_bar_hook)
15974 (w, portion, whole, start);
15978 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
15979 selected_window is redisplayed.
15981 We can return without actually redisplaying the window if fonts has been
15982 changed on window's frame. In that case, redisplay_internal will retry.
15984 As one of the important parts of redisplaying a window, we need to
15985 decide whether the previous window-start position (stored in the
15986 window's w->start marker position) is still valid, and if it isn't,
15987 recompute it. Some details about that:
15989 . The previous window-start could be in a continuation line, in
15990 which case we need to recompute it when the window width
15991 changes. See compute_window_start_on_continuation_line and its
15992 call below.
15994 . The text that changed since last redisplay could include the
15995 previous window-start position. In that case, we try to salvage
15996 what we can from the current glyph matrix by calling
15997 try_scrolling, which see.
15999 . Some Emacs command could force us to use a specific window-start
16000 position by setting the window's force_start flag, or gently
16001 propose doing that by setting the window's optional_new_start
16002 flag. In these cases, we try using the specified start point if
16003 that succeeds (i.e. the window desired matrix is successfully
16004 recomputed, and point location is within the window). In case
16005 of optional_new_start, we first check if the specified start
16006 position is feasible, i.e. if it will allow point to be
16007 displayed in the window. If using the specified start point
16008 fails, e.g., if new fonts are needed to be loaded, we abort the
16009 redisplay cycle and leave it up to the next cycle to figure out
16010 things.
16012 . Note that the window's force_start flag is sometimes set by
16013 redisplay itself, when it decides that the previous window start
16014 point is fine and should be kept. Search for "goto force_start"
16015 below to see the details. Like the values of window-start
16016 specified outside of redisplay, these internally-deduced values
16017 are tested for feasibility, and ignored if found to be
16018 unfeasible.
16020 . Note that the function try_window, used to completely redisplay
16021 a window, accepts the window's start point as its argument.
16022 This is used several times in the redisplay code to control
16023 where the window start will be, according to user options such
16024 as scroll-conservatively, and also to ensure the screen line
16025 showing point will be fully (as opposed to partially) visible on
16026 display. */
16028 static void
16029 redisplay_window (Lisp_Object window, bool just_this_one_p)
16031 struct window *w = XWINDOW (window);
16032 struct frame *f = XFRAME (w->frame);
16033 struct buffer *buffer = XBUFFER (w->contents);
16034 struct buffer *old = current_buffer;
16035 struct text_pos lpoint, opoint, startp;
16036 int update_mode_line;
16037 int tem;
16038 struct it it;
16039 /* Record it now because it's overwritten. */
16040 bool current_matrix_up_to_date_p = false;
16041 bool used_current_matrix_p = false;
16042 /* This is less strict than current_matrix_up_to_date_p.
16043 It indicates that the buffer contents and narrowing are unchanged. */
16044 bool buffer_unchanged_p = false;
16045 int temp_scroll_step = 0;
16046 ptrdiff_t count = SPECPDL_INDEX ();
16047 int rc;
16048 int centering_position = -1;
16049 int last_line_misfit = 0;
16050 ptrdiff_t beg_unchanged, end_unchanged;
16051 int frame_line_height;
16053 SET_TEXT_POS (lpoint, PT, PT_BYTE);
16054 opoint = lpoint;
16056 #ifdef GLYPH_DEBUG
16057 *w->desired_matrix->method = 0;
16058 #endif
16060 if (!just_this_one_p
16061 && REDISPLAY_SOME_P ()
16062 && !w->redisplay
16063 && !f->redisplay
16064 && !buffer->text->redisplay
16065 && BUF_PT (buffer) == w->last_point)
16066 return;
16068 /* Make sure that both W's markers are valid. */
16069 eassert (XMARKER (w->start)->buffer == buffer);
16070 eassert (XMARKER (w->pointm)->buffer == buffer);
16072 /* We come here again if we need to run window-text-change-functions
16073 below. */
16074 restart:
16075 reconsider_clip_changes (w);
16076 frame_line_height = default_line_pixel_height (w);
16078 /* Has the mode line to be updated? */
16079 update_mode_line = (w->update_mode_line
16080 || update_mode_lines
16081 || buffer->clip_changed
16082 || buffer->prevent_redisplay_optimizations_p);
16084 if (!just_this_one_p)
16085 /* If `just_this_one_p' is set, we apparently set must_be_updated_p more
16086 cleverly elsewhere. */
16087 w->must_be_updated_p = true;
16089 if (MINI_WINDOW_P (w))
16091 if (w == XWINDOW (echo_area_window)
16092 && !NILP (echo_area_buffer[0]))
16094 if (update_mode_line)
16095 /* We may have to update a tty frame's menu bar or a
16096 tool-bar. Example `M-x C-h C-h C-g'. */
16097 goto finish_menu_bars;
16098 else
16099 /* We've already displayed the echo area glyphs in this window. */
16100 goto finish_scroll_bars;
16102 else if ((w != XWINDOW (minibuf_window)
16103 || minibuf_level == 0)
16104 /* When buffer is nonempty, redisplay window normally. */
16105 && BUF_Z (XBUFFER (w->contents)) == BUF_BEG (XBUFFER (w->contents))
16106 /* Quail displays non-mini buffers in minibuffer window.
16107 In that case, redisplay the window normally. */
16108 && !NILP (Fmemq (w->contents, Vminibuffer_list)))
16110 /* W is a mini-buffer window, but it's not active, so clear
16111 it. */
16112 int yb = window_text_bottom_y (w);
16113 struct glyph_row *row;
16114 int y;
16116 for (y = 0, row = w->desired_matrix->rows;
16117 y < yb;
16118 y += row->height, ++row)
16119 blank_row (w, row, y);
16120 goto finish_scroll_bars;
16123 clear_glyph_matrix (w->desired_matrix);
16126 /* Otherwise set up data on this window; select its buffer and point
16127 value. */
16128 /* Really select the buffer, for the sake of buffer-local
16129 variables. */
16130 set_buffer_internal_1 (XBUFFER (w->contents));
16132 current_matrix_up_to_date_p
16133 = (w->window_end_valid
16134 && !current_buffer->clip_changed
16135 && !current_buffer->prevent_redisplay_optimizations_p
16136 && !window_outdated (w));
16138 /* Run the window-text-change-functions
16139 if it is possible that the text on the screen has changed
16140 (either due to modification of the text, or any other reason). */
16141 if (!current_matrix_up_to_date_p
16142 && !NILP (Vwindow_text_change_functions))
16144 safe_run_hooks (Qwindow_text_change_functions);
16145 goto restart;
16148 beg_unchanged = BEG_UNCHANGED;
16149 end_unchanged = END_UNCHANGED;
16151 SET_TEXT_POS (opoint, PT, PT_BYTE);
16153 specbind (Qinhibit_point_motion_hooks, Qt);
16155 buffer_unchanged_p
16156 = (w->window_end_valid
16157 && !current_buffer->clip_changed
16158 && !window_outdated (w));
16160 /* When windows_or_buffers_changed is non-zero, we can't rely
16161 on the window end being valid, so set it to zero there. */
16162 if (windows_or_buffers_changed)
16164 /* If window starts on a continuation line, maybe adjust the
16165 window start in case the window's width changed. */
16166 if (XMARKER (w->start)->buffer == current_buffer)
16167 compute_window_start_on_continuation_line (w);
16169 w->window_end_valid = false;
16170 /* If so, we also can't rely on current matrix
16171 and should not fool try_cursor_movement below. */
16172 current_matrix_up_to_date_p = false;
16175 /* Some sanity checks. */
16176 CHECK_WINDOW_END (w);
16177 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
16178 emacs_abort ();
16179 if (BYTEPOS (opoint) < CHARPOS (opoint))
16180 emacs_abort ();
16182 if (mode_line_update_needed (w))
16183 update_mode_line = 1;
16185 /* Point refers normally to the selected window. For any other
16186 window, set up appropriate value. */
16187 if (!EQ (window, selected_window))
16189 ptrdiff_t new_pt = marker_position (w->pointm);
16190 ptrdiff_t new_pt_byte = marker_byte_position (w->pointm);
16192 if (new_pt < BEGV)
16194 new_pt = BEGV;
16195 new_pt_byte = BEGV_BYTE;
16196 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
16198 else if (new_pt > (ZV - 1))
16200 new_pt = ZV;
16201 new_pt_byte = ZV_BYTE;
16202 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
16205 /* We don't use SET_PT so that the point-motion hooks don't run. */
16206 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
16209 /* If any of the character widths specified in the display table
16210 have changed, invalidate the width run cache. It's true that
16211 this may be a bit late to catch such changes, but the rest of
16212 redisplay goes (non-fatally) haywire when the display table is
16213 changed, so why should we worry about doing any better? */
16214 if (current_buffer->width_run_cache
16215 || (current_buffer->base_buffer
16216 && current_buffer->base_buffer->width_run_cache))
16218 struct Lisp_Char_Table *disptab = buffer_display_table ();
16220 if (! disptab_matches_widthtab
16221 (disptab, XVECTOR (BVAR (current_buffer, width_table))))
16223 struct buffer *buf = current_buffer;
16225 if (buf->base_buffer)
16226 buf = buf->base_buffer;
16227 invalidate_region_cache (buf, buf->width_run_cache, BEG, Z);
16228 recompute_width_table (current_buffer, disptab);
16232 /* If window-start is screwed up, choose a new one. */
16233 if (XMARKER (w->start)->buffer != current_buffer)
16234 goto recenter;
16236 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16238 /* If someone specified a new starting point but did not insist,
16239 check whether it can be used. */
16240 if ((w->optional_new_start || window_frozen_p (w))
16241 && CHARPOS (startp) >= BEGV
16242 && CHARPOS (startp) <= ZV)
16244 ptrdiff_t it_charpos;
16246 w->optional_new_start = 0;
16247 start_display (&it, w, startp);
16248 move_it_to (&it, PT, 0, it.last_visible_y, -1,
16249 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
16250 /* Record IT's position now, since line_bottom_y might change
16251 that. */
16252 it_charpos = IT_CHARPOS (it);
16253 /* Make sure we set the force_start flag only if the cursor row
16254 will be fully visible. Otherwise, the code under force_start
16255 label below will try to move point back into view, which is
16256 not what the code which sets optional_new_start wants. */
16257 if ((it.current_y == 0 || line_bottom_y (&it) < it.last_visible_y)
16258 && !w->force_start)
16260 if (it_charpos == PT)
16261 w->force_start = 1;
16262 /* IT may overshoot PT if text at PT is invisible. */
16263 else if (it_charpos > PT && CHARPOS (startp) <= PT)
16264 w->force_start = 1;
16265 #ifdef GLYPH_DEBUG
16266 if (w->force_start)
16268 if (window_frozen_p (w))
16269 debug_method_add (w, "set force_start from frozen window start");
16270 else
16271 debug_method_add (w, "set force_start from optional_new_start");
16273 #endif
16277 force_start:
16279 /* Handle case where place to start displaying has been specified,
16280 unless the specified location is outside the accessible range. */
16281 if (w->force_start)
16283 /* We set this later on if we have to adjust point. */
16284 int new_vpos = -1;
16286 w->force_start = 0;
16287 w->vscroll = 0;
16288 w->window_end_valid = 0;
16290 /* Forget any recorded base line for line number display. */
16291 if (!buffer_unchanged_p)
16292 w->base_line_number = 0;
16294 /* Redisplay the mode line. Select the buffer properly for that.
16295 Also, run the hook window-scroll-functions
16296 because we have scrolled. */
16297 /* Note, we do this after clearing force_start because
16298 if there's an error, it is better to forget about force_start
16299 than to get into an infinite loop calling the hook functions
16300 and having them get more errors. */
16301 if (!update_mode_line
16302 || ! NILP (Vwindow_scroll_functions))
16304 update_mode_line = 1;
16305 w->update_mode_line = 1;
16306 startp = run_window_scroll_functions (window, startp);
16309 if (CHARPOS (startp) < BEGV)
16310 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
16311 else if (CHARPOS (startp) > ZV)
16312 SET_TEXT_POS (startp, ZV, ZV_BYTE);
16314 /* Redisplay, then check if cursor has been set during the
16315 redisplay. Give up if new fonts were loaded. */
16316 /* We used to issue a CHECK_MARGINS argument to try_window here,
16317 but this causes scrolling to fail when point begins inside
16318 the scroll margin (bug#148) -- cyd */
16319 if (!try_window (window, startp, 0))
16321 w->force_start = 1;
16322 clear_glyph_matrix (w->desired_matrix);
16323 goto need_larger_matrices;
16326 if (w->cursor.vpos < 0)
16328 /* If point does not appear, try to move point so it does
16329 appear. The desired matrix has been built above, so we
16330 can use it here. */
16331 new_vpos = window_box_height (w) / 2;
16334 if (!cursor_row_fully_visible_p (w, 0, 0))
16336 /* Point does appear, but on a line partly visible at end of window.
16337 Move it back to a fully-visible line. */
16338 new_vpos = window_box_height (w);
16339 /* But if window_box_height suggests a Y coordinate that is
16340 not less than we already have, that line will clearly not
16341 be fully visible, so give up and scroll the display.
16342 This can happen when the default face uses a font whose
16343 dimensions are different from the frame's default
16344 font. */
16345 if (new_vpos >= w->cursor.y)
16347 w->cursor.vpos = -1;
16348 clear_glyph_matrix (w->desired_matrix);
16349 goto try_to_scroll;
16352 else if (w->cursor.vpos >= 0)
16354 /* Some people insist on not letting point enter the scroll
16355 margin, even though this part handles windows that didn't
16356 scroll at all. */
16357 int window_total_lines
16358 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
16359 int margin = min (scroll_margin, window_total_lines / 4);
16360 int pixel_margin = margin * frame_line_height;
16361 bool header_line = WINDOW_WANTS_HEADER_LINE_P (w);
16363 /* Note: We add an extra FRAME_LINE_HEIGHT, because the loop
16364 below, which finds the row to move point to, advances by
16365 the Y coordinate of the _next_ row, see the definition of
16366 MATRIX_ROW_BOTTOM_Y. */
16367 if (w->cursor.vpos < margin + header_line)
16369 w->cursor.vpos = -1;
16370 clear_glyph_matrix (w->desired_matrix);
16371 goto try_to_scroll;
16373 else
16375 int window_height = window_box_height (w);
16377 if (header_line)
16378 window_height += CURRENT_HEADER_LINE_HEIGHT (w);
16379 if (w->cursor.y >= window_height - pixel_margin)
16381 w->cursor.vpos = -1;
16382 clear_glyph_matrix (w->desired_matrix);
16383 goto try_to_scroll;
16388 /* If we need to move point for either of the above reasons,
16389 now actually do it. */
16390 if (new_vpos >= 0)
16392 struct glyph_row *row;
16394 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
16395 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
16396 ++row;
16398 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
16399 MATRIX_ROW_START_BYTEPOS (row));
16401 if (w != XWINDOW (selected_window))
16402 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
16403 else if (current_buffer == old)
16404 SET_TEXT_POS (lpoint, PT, PT_BYTE);
16406 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
16408 /* Re-run pre-redisplay-function so it can update the region
16409 according to the new position of point. */
16410 /* Other than the cursor, w's redisplay is done so we can set its
16411 redisplay to false. Also the buffer's redisplay can be set to
16412 false, since propagate_buffer_redisplay should have already
16413 propagated its info to `w' anyway. */
16414 w->redisplay = false;
16415 XBUFFER (w->contents)->text->redisplay = false;
16416 safe__call1 (true, Vpre_redisplay_function, Fcons (window, Qnil));
16418 if (w->redisplay || XBUFFER (w->contents)->text->redisplay)
16420 /* pre-redisplay-function made changes (e.g. move the region)
16421 that require another round of redisplay. */
16422 clear_glyph_matrix (w->desired_matrix);
16423 if (!try_window (window, startp, 0))
16424 goto need_larger_matrices;
16427 if (w->cursor.vpos < 0 || !cursor_row_fully_visible_p (w, 0, 0))
16429 clear_glyph_matrix (w->desired_matrix);
16430 goto try_to_scroll;
16433 #ifdef GLYPH_DEBUG
16434 debug_method_add (w, "forced window start");
16435 #endif
16436 goto done;
16439 /* Handle case where text has not changed, only point, and it has
16440 not moved off the frame, and we are not retrying after hscroll.
16441 (current_matrix_up_to_date_p is nonzero when retrying.) */
16442 if (current_matrix_up_to_date_p
16443 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
16444 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
16446 switch (rc)
16448 case CURSOR_MOVEMENT_SUCCESS:
16449 used_current_matrix_p = 1;
16450 goto done;
16452 case CURSOR_MOVEMENT_MUST_SCROLL:
16453 goto try_to_scroll;
16455 default:
16456 emacs_abort ();
16459 /* If current starting point was originally the beginning of a line
16460 but no longer is, find a new starting point. */
16461 else if (w->start_at_line_beg
16462 && !(CHARPOS (startp) <= BEGV
16463 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
16465 #ifdef GLYPH_DEBUG
16466 debug_method_add (w, "recenter 1");
16467 #endif
16468 goto recenter;
16471 /* Try scrolling with try_window_id. Value is > 0 if update has
16472 been done, it is -1 if we know that the same window start will
16473 not work. It is 0 if unsuccessful for some other reason. */
16474 else if ((tem = try_window_id (w)) != 0)
16476 #ifdef GLYPH_DEBUG
16477 debug_method_add (w, "try_window_id %d", tem);
16478 #endif
16480 if (f->fonts_changed)
16481 goto need_larger_matrices;
16482 if (tem > 0)
16483 goto done;
16485 /* Otherwise try_window_id has returned -1 which means that we
16486 don't want the alternative below this comment to execute. */
16488 else if (CHARPOS (startp) >= BEGV
16489 && CHARPOS (startp) <= ZV
16490 && PT >= CHARPOS (startp)
16491 && (CHARPOS (startp) < ZV
16492 /* Avoid starting at end of buffer. */
16493 || CHARPOS (startp) == BEGV
16494 || !window_outdated (w)))
16496 int d1, d2, d5, d6;
16497 int rtop, rbot;
16499 /* If first window line is a continuation line, and window start
16500 is inside the modified region, but the first change is before
16501 current window start, we must select a new window start.
16503 However, if this is the result of a down-mouse event (e.g. by
16504 extending the mouse-drag-overlay), we don't want to select a
16505 new window start, since that would change the position under
16506 the mouse, resulting in an unwanted mouse-movement rather
16507 than a simple mouse-click. */
16508 if (!w->start_at_line_beg
16509 && NILP (do_mouse_tracking)
16510 && CHARPOS (startp) > BEGV
16511 && CHARPOS (startp) > BEG + beg_unchanged
16512 && CHARPOS (startp) <= Z - end_unchanged
16513 /* Even if w->start_at_line_beg is nil, a new window may
16514 start at a line_beg, since that's how set_buffer_window
16515 sets it. So, we need to check the return value of
16516 compute_window_start_on_continuation_line. (See also
16517 bug#197). */
16518 && XMARKER (w->start)->buffer == current_buffer
16519 && compute_window_start_on_continuation_line (w)
16520 /* It doesn't make sense to force the window start like we
16521 do at label force_start if it is already known that point
16522 will not be fully visible in the resulting window, because
16523 doing so will move point from its correct position
16524 instead of scrolling the window to bring point into view.
16525 See bug#9324. */
16526 && pos_visible_p (w, PT, &d1, &d2, &rtop, &rbot, &d5, &d6)
16527 /* A very tall row could need more than the window height,
16528 in which case we accept that it is partially visible. */
16529 && (rtop != 0) == (rbot != 0))
16531 w->force_start = 1;
16532 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16533 #ifdef GLYPH_DEBUG
16534 debug_method_add (w, "recomputed window start in continuation line");
16535 #endif
16536 goto force_start;
16539 #ifdef GLYPH_DEBUG
16540 debug_method_add (w, "same window start");
16541 #endif
16543 /* Try to redisplay starting at same place as before.
16544 If point has not moved off frame, accept the results. */
16545 if (!current_matrix_up_to_date_p
16546 /* Don't use try_window_reusing_current_matrix in this case
16547 because a window scroll function can have changed the
16548 buffer. */
16549 || !NILP (Vwindow_scroll_functions)
16550 || MINI_WINDOW_P (w)
16551 || !(used_current_matrix_p
16552 = try_window_reusing_current_matrix (w)))
16554 IF_DEBUG (debug_method_add (w, "1"));
16555 if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
16556 /* -1 means we need to scroll.
16557 0 means we need new matrices, but fonts_changed
16558 is set in that case, so we will detect it below. */
16559 goto try_to_scroll;
16562 if (f->fonts_changed)
16563 goto need_larger_matrices;
16565 if (w->cursor.vpos >= 0)
16567 if (!just_this_one_p
16568 || current_buffer->clip_changed
16569 || BEG_UNCHANGED < CHARPOS (startp))
16570 /* Forget any recorded base line for line number display. */
16571 w->base_line_number = 0;
16573 if (!cursor_row_fully_visible_p (w, 1, 0))
16575 clear_glyph_matrix (w->desired_matrix);
16576 last_line_misfit = 1;
16578 /* Drop through and scroll. */
16579 else
16580 goto done;
16582 else
16583 clear_glyph_matrix (w->desired_matrix);
16586 try_to_scroll:
16588 /* Redisplay the mode line. Select the buffer properly for that. */
16589 if (!update_mode_line)
16591 update_mode_line = 1;
16592 w->update_mode_line = 1;
16595 /* Try to scroll by specified few lines. */
16596 if ((scroll_conservatively
16597 || emacs_scroll_step
16598 || temp_scroll_step
16599 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively))
16600 || NUMBERP (BVAR (current_buffer, scroll_down_aggressively)))
16601 && CHARPOS (startp) >= BEGV
16602 && CHARPOS (startp) <= ZV)
16604 /* The function returns -1 if new fonts were loaded, 1 if
16605 successful, 0 if not successful. */
16606 int ss = try_scrolling (window, just_this_one_p,
16607 scroll_conservatively,
16608 emacs_scroll_step,
16609 temp_scroll_step, last_line_misfit);
16610 switch (ss)
16612 case SCROLLING_SUCCESS:
16613 goto done;
16615 case SCROLLING_NEED_LARGER_MATRICES:
16616 goto need_larger_matrices;
16618 case SCROLLING_FAILED:
16619 break;
16621 default:
16622 emacs_abort ();
16626 /* Finally, just choose a place to start which positions point
16627 according to user preferences. */
16629 recenter:
16631 #ifdef GLYPH_DEBUG
16632 debug_method_add (w, "recenter");
16633 #endif
16635 /* Forget any previously recorded base line for line number display. */
16636 if (!buffer_unchanged_p)
16637 w->base_line_number = 0;
16639 /* Determine the window start relative to point. */
16640 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
16641 it.current_y = it.last_visible_y;
16642 if (centering_position < 0)
16644 int window_total_lines
16645 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
16646 int margin
16647 = scroll_margin > 0
16648 ? min (scroll_margin, window_total_lines / 4)
16649 : 0;
16650 ptrdiff_t margin_pos = CHARPOS (startp);
16651 Lisp_Object aggressive;
16652 int scrolling_up;
16654 /* If there is a scroll margin at the top of the window, find
16655 its character position. */
16656 if (margin
16657 /* Cannot call start_display if startp is not in the
16658 accessible region of the buffer. This can happen when we
16659 have just switched to a different buffer and/or changed
16660 its restriction. In that case, startp is initialized to
16661 the character position 1 (BEGV) because we did not yet
16662 have chance to display the buffer even once. */
16663 && BEGV <= CHARPOS (startp) && CHARPOS (startp) <= ZV)
16665 struct it it1;
16666 void *it1data = NULL;
16668 SAVE_IT (it1, it, it1data);
16669 start_display (&it1, w, startp);
16670 move_it_vertically (&it1, margin * frame_line_height);
16671 margin_pos = IT_CHARPOS (it1);
16672 RESTORE_IT (&it, &it, it1data);
16674 scrolling_up = PT > margin_pos;
16675 aggressive =
16676 scrolling_up
16677 ? BVAR (current_buffer, scroll_up_aggressively)
16678 : BVAR (current_buffer, scroll_down_aggressively);
16680 if (!MINI_WINDOW_P (w)
16681 && (scroll_conservatively > SCROLL_LIMIT || NUMBERP (aggressive)))
16683 int pt_offset = 0;
16685 /* Setting scroll-conservatively overrides
16686 scroll-*-aggressively. */
16687 if (!scroll_conservatively && NUMBERP (aggressive))
16689 double float_amount = XFLOATINT (aggressive);
16691 pt_offset = float_amount * WINDOW_BOX_TEXT_HEIGHT (w);
16692 if (pt_offset == 0 && float_amount > 0)
16693 pt_offset = 1;
16694 if (pt_offset && margin > 0)
16695 margin -= 1;
16697 /* Compute how much to move the window start backward from
16698 point so that point will be displayed where the user
16699 wants it. */
16700 if (scrolling_up)
16702 centering_position = it.last_visible_y;
16703 if (pt_offset)
16704 centering_position -= pt_offset;
16705 centering_position -=
16706 frame_line_height * (1 + margin + (last_line_misfit != 0))
16707 + WINDOW_HEADER_LINE_HEIGHT (w);
16708 /* Don't let point enter the scroll margin near top of
16709 the window. */
16710 if (centering_position < margin * frame_line_height)
16711 centering_position = margin * frame_line_height;
16713 else
16714 centering_position = margin * frame_line_height + pt_offset;
16716 else
16717 /* Set the window start half the height of the window backward
16718 from point. */
16719 centering_position = window_box_height (w) / 2;
16721 move_it_vertically_backward (&it, centering_position);
16723 eassert (IT_CHARPOS (it) >= BEGV);
16725 /* The function move_it_vertically_backward may move over more
16726 than the specified y-distance. If it->w is small, e.g. a
16727 mini-buffer window, we may end up in front of the window's
16728 display area. Start displaying at the start of the line
16729 containing PT in this case. */
16730 if (it.current_y <= 0)
16732 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
16733 move_it_vertically_backward (&it, 0);
16734 it.current_y = 0;
16737 it.current_x = it.hpos = 0;
16739 /* Set the window start position here explicitly, to avoid an
16740 infinite loop in case the functions in window-scroll-functions
16741 get errors. */
16742 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
16744 /* Run scroll hooks. */
16745 startp = run_window_scroll_functions (window, it.current.pos);
16747 /* Redisplay the window. */
16748 if (!current_matrix_up_to_date_p
16749 || windows_or_buffers_changed
16750 || f->cursor_type_changed
16751 /* Don't use try_window_reusing_current_matrix in this case
16752 because it can have changed the buffer. */
16753 || !NILP (Vwindow_scroll_functions)
16754 || !just_this_one_p
16755 || MINI_WINDOW_P (w)
16756 || !(used_current_matrix_p
16757 = try_window_reusing_current_matrix (w)))
16758 try_window (window, startp, 0);
16760 /* If new fonts have been loaded (due to fontsets), give up. We
16761 have to start a new redisplay since we need to re-adjust glyph
16762 matrices. */
16763 if (f->fonts_changed)
16764 goto need_larger_matrices;
16766 /* If cursor did not appear assume that the middle of the window is
16767 in the first line of the window. Do it again with the next line.
16768 (Imagine a window of height 100, displaying two lines of height
16769 60. Moving back 50 from it->last_visible_y will end in the first
16770 line.) */
16771 if (w->cursor.vpos < 0)
16773 if (w->window_end_valid && PT >= Z - w->window_end_pos)
16775 clear_glyph_matrix (w->desired_matrix);
16776 move_it_by_lines (&it, 1);
16777 try_window (window, it.current.pos, 0);
16779 else if (PT < IT_CHARPOS (it))
16781 clear_glyph_matrix (w->desired_matrix);
16782 move_it_by_lines (&it, -1);
16783 try_window (window, it.current.pos, 0);
16785 else
16787 /* Not much we can do about it. */
16791 /* Consider the following case: Window starts at BEGV, there is
16792 invisible, intangible text at BEGV, so that display starts at
16793 some point START > BEGV. It can happen that we are called with
16794 PT somewhere between BEGV and START. Try to handle that case,
16795 and similar ones. */
16796 if (w->cursor.vpos < 0)
16798 /* First, try locating the proper glyph row for PT. */
16799 struct glyph_row *row =
16800 row_containing_pos (w, PT, w->current_matrix->rows, NULL, 0);
16802 /* Sometimes point is at the beginning of invisible text that is
16803 before the 1st character displayed in the row. In that case,
16804 row_containing_pos fails to find the row, because no glyphs
16805 with appropriate buffer positions are present in the row.
16806 Therefore, we next try to find the row which shows the 1st
16807 position after the invisible text. */
16808 if (!row)
16810 Lisp_Object val =
16811 get_char_property_and_overlay (make_number (PT), Qinvisible,
16812 Qnil, NULL);
16814 if (TEXT_PROP_MEANS_INVISIBLE (val))
16816 ptrdiff_t alt_pos;
16817 Lisp_Object invis_end =
16818 Fnext_single_char_property_change (make_number (PT), Qinvisible,
16819 Qnil, Qnil);
16821 if (NATNUMP (invis_end))
16822 alt_pos = XFASTINT (invis_end);
16823 else
16824 alt_pos = ZV;
16825 row = row_containing_pos (w, alt_pos, w->current_matrix->rows,
16826 NULL, 0);
16829 /* Finally, fall back on the first row of the window after the
16830 header line (if any). This is slightly better than not
16831 displaying the cursor at all. */
16832 if (!row)
16834 row = w->current_matrix->rows;
16835 if (row->mode_line_p)
16836 ++row;
16838 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
16841 if (!cursor_row_fully_visible_p (w, 0, 0))
16843 /* If vscroll is enabled, disable it and try again. */
16844 if (w->vscroll)
16846 w->vscroll = 0;
16847 clear_glyph_matrix (w->desired_matrix);
16848 goto recenter;
16851 /* Users who set scroll-conservatively to a large number want
16852 point just above/below the scroll margin. If we ended up
16853 with point's row partially visible, move the window start to
16854 make that row fully visible and out of the margin. */
16855 if (scroll_conservatively > SCROLL_LIMIT)
16857 int window_total_lines
16858 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) * frame_line_height;
16859 int margin =
16860 scroll_margin > 0
16861 ? min (scroll_margin, window_total_lines / 4)
16862 : 0;
16863 int move_down = w->cursor.vpos >= window_total_lines / 2;
16865 move_it_by_lines (&it, move_down ? margin + 1 : -(margin + 1));
16866 clear_glyph_matrix (w->desired_matrix);
16867 if (1 == try_window (window, it.current.pos,
16868 TRY_WINDOW_CHECK_MARGINS))
16869 goto done;
16872 /* If centering point failed to make the whole line visible,
16873 put point at the top instead. That has to make the whole line
16874 visible, if it can be done. */
16875 if (centering_position == 0)
16876 goto done;
16878 clear_glyph_matrix (w->desired_matrix);
16879 centering_position = 0;
16880 goto recenter;
16883 done:
16885 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16886 w->start_at_line_beg = (CHARPOS (startp) == BEGV
16887 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n');
16889 /* Display the mode line, if we must. */
16890 if ((update_mode_line
16891 /* If window not full width, must redo its mode line
16892 if (a) the window to its side is being redone and
16893 (b) we do a frame-based redisplay. This is a consequence
16894 of how inverted lines are drawn in frame-based redisplay. */
16895 || (!just_this_one_p
16896 && !FRAME_WINDOW_P (f)
16897 && !WINDOW_FULL_WIDTH_P (w))
16898 /* Line number to display. */
16899 || w->base_line_pos > 0
16900 /* Column number is displayed and different from the one displayed. */
16901 || (w->column_number_displayed != -1
16902 && (w->column_number_displayed != current_column ())))
16903 /* This means that the window has a mode line. */
16904 && (WINDOW_WANTS_MODELINE_P (w)
16905 || WINDOW_WANTS_HEADER_LINE_P (w)))
16908 display_mode_lines (w);
16910 /* If mode line height has changed, arrange for a thorough
16911 immediate redisplay using the correct mode line height. */
16912 if (WINDOW_WANTS_MODELINE_P (w)
16913 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
16915 f->fonts_changed = 1;
16916 w->mode_line_height = -1;
16917 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
16918 = DESIRED_MODE_LINE_HEIGHT (w);
16921 /* If header line height has changed, arrange for a thorough
16922 immediate redisplay using the correct header line height. */
16923 if (WINDOW_WANTS_HEADER_LINE_P (w)
16924 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
16926 f->fonts_changed = 1;
16927 w->header_line_height = -1;
16928 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
16929 = DESIRED_HEADER_LINE_HEIGHT (w);
16932 if (f->fonts_changed)
16933 goto need_larger_matrices;
16936 if (!line_number_displayed && w->base_line_pos != -1)
16938 w->base_line_pos = 0;
16939 w->base_line_number = 0;
16942 finish_menu_bars:
16944 /* When we reach a frame's selected window, redo the frame's menu bar. */
16945 if (update_mode_line
16946 && EQ (FRAME_SELECTED_WINDOW (f), window))
16948 int redisplay_menu_p = 0;
16950 if (FRAME_WINDOW_P (f))
16952 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
16953 || defined (HAVE_NS) || defined (USE_GTK)
16954 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
16955 #else
16956 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
16957 #endif
16959 else
16960 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
16962 if (redisplay_menu_p)
16963 display_menu_bar (w);
16965 #ifdef HAVE_WINDOW_SYSTEM
16966 if (FRAME_WINDOW_P (f))
16968 #if defined (USE_GTK) || defined (HAVE_NS)
16969 if (FRAME_EXTERNAL_TOOL_BAR (f))
16970 redisplay_tool_bar (f);
16971 #else
16972 if (WINDOWP (f->tool_bar_window)
16973 && (FRAME_TOOL_BAR_LINES (f) > 0
16974 || !NILP (Vauto_resize_tool_bars))
16975 && redisplay_tool_bar (f))
16976 ignore_mouse_drag_p = 1;
16977 #endif
16979 #endif
16982 #ifdef HAVE_WINDOW_SYSTEM
16983 if (FRAME_WINDOW_P (f)
16984 && update_window_fringes (w, (just_this_one_p
16985 || (!used_current_matrix_p && !overlay_arrow_seen)
16986 || w->pseudo_window_p)))
16988 update_begin (f);
16989 block_input ();
16990 if (draw_window_fringes (w, 1))
16992 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
16993 x_draw_right_divider (w);
16994 else
16995 x_draw_vertical_border (w);
16997 unblock_input ();
16998 update_end (f);
17001 if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
17002 x_draw_bottom_divider (w);
17003 #endif /* HAVE_WINDOW_SYSTEM */
17005 /* We go to this label, with fonts_changed set, if it is
17006 necessary to try again using larger glyph matrices.
17007 We have to redeem the scroll bar even in this case,
17008 because the loop in redisplay_internal expects that. */
17009 need_larger_matrices:
17011 finish_scroll_bars:
17013 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w) || WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w))
17015 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
17016 /* Set the thumb's position and size. */
17017 set_vertical_scroll_bar (w);
17019 if (WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w))
17020 /* Set the thumb's position and size. */
17021 set_horizontal_scroll_bar (w);
17023 /* Note that we actually used the scroll bar attached to this
17024 window, so it shouldn't be deleted at the end of redisplay. */
17025 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
17026 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
17029 /* Restore current_buffer and value of point in it. The window
17030 update may have changed the buffer, so first make sure `opoint'
17031 is still valid (Bug#6177). */
17032 if (CHARPOS (opoint) < BEGV)
17033 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
17034 else if (CHARPOS (opoint) > ZV)
17035 TEMP_SET_PT_BOTH (Z, Z_BYTE);
17036 else
17037 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
17039 set_buffer_internal_1 (old);
17040 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
17041 shorter. This can be caused by log truncation in *Messages*. */
17042 if (CHARPOS (lpoint) <= ZV)
17043 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
17045 unbind_to (count, Qnil);
17049 /* Build the complete desired matrix of WINDOW with a window start
17050 buffer position POS.
17052 Value is 1 if successful. It is zero if fonts were loaded during
17053 redisplay which makes re-adjusting glyph matrices necessary, and -1
17054 if point would appear in the scroll margins.
17055 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
17056 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
17057 set in FLAGS.) */
17060 try_window (Lisp_Object window, struct text_pos pos, int flags)
17062 struct window *w = XWINDOW (window);
17063 struct it it;
17064 struct glyph_row *last_text_row = NULL;
17065 struct frame *f = XFRAME (w->frame);
17066 int frame_line_height = default_line_pixel_height (w);
17068 /* Make POS the new window start. */
17069 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
17071 /* Mark cursor position as unknown. No overlay arrow seen. */
17072 w->cursor.vpos = -1;
17073 overlay_arrow_seen = 0;
17075 /* Initialize iterator and info to start at POS. */
17076 start_display (&it, w, pos);
17077 it.glyph_row->reversed_p = false;
17079 /* Display all lines of W. */
17080 while (it.current_y < it.last_visible_y)
17082 if (display_line (&it))
17083 last_text_row = it.glyph_row - 1;
17084 if (f->fonts_changed && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
17085 return 0;
17087 #ifdef HAVE_XWIDGETS_xxx
17088 //currently this is needed to detect xwidget movement reliably. or probably not.
17089 printf("try_window\n");
17090 return 0;
17091 #endif
17093 /* Don't let the cursor end in the scroll margins. */
17094 if ((flags & TRY_WINDOW_CHECK_MARGINS)
17095 && !MINI_WINDOW_P (w))
17097 int this_scroll_margin;
17098 int window_total_lines
17099 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
17101 if (scroll_margin > 0)
17103 this_scroll_margin = min (scroll_margin, window_total_lines / 4);
17104 this_scroll_margin *= frame_line_height;
17106 else
17107 this_scroll_margin = 0;
17109 if ((w->cursor.y >= 0 /* not vscrolled */
17110 && w->cursor.y < this_scroll_margin
17111 && CHARPOS (pos) > BEGV
17112 && IT_CHARPOS (it) < ZV)
17113 /* rms: considering make_cursor_line_fully_visible_p here
17114 seems to give wrong results. We don't want to recenter
17115 when the last line is partly visible, we want to allow
17116 that case to be handled in the usual way. */
17117 || w->cursor.y > it.last_visible_y - this_scroll_margin - 1)
17119 w->cursor.vpos = -1;
17120 clear_glyph_matrix (w->desired_matrix);
17121 return -1;
17125 /* If bottom moved off end of frame, change mode line percentage. */
17126 if (w->window_end_pos <= 0 && Z != IT_CHARPOS (it))
17127 w->update_mode_line = 1;
17129 /* Set window_end_pos to the offset of the last character displayed
17130 on the window from the end of current_buffer. Set
17131 window_end_vpos to its row number. */
17132 if (last_text_row)
17134 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
17135 adjust_window_ends (w, last_text_row, 0);
17136 eassert
17137 (MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->desired_matrix,
17138 w->window_end_vpos)));
17140 else
17142 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
17143 w->window_end_pos = Z - ZV;
17144 w->window_end_vpos = 0;
17147 /* But that is not valid info until redisplay finishes. */
17148 w->window_end_valid = 0;
17149 return 1;
17154 /************************************************************************
17155 Window redisplay reusing current matrix when buffer has not changed
17156 ************************************************************************/
17158 /* Try redisplay of window W showing an unchanged buffer with a
17159 different window start than the last time it was displayed by
17160 reusing its current matrix. Value is non-zero if successful.
17161 W->start is the new window start. */
17163 static int
17164 try_window_reusing_current_matrix (struct window *w)
17166 struct frame *f = XFRAME (w->frame);
17167 struct glyph_row *bottom_row;
17168 struct it it;
17169 struct run run;
17170 struct text_pos start, new_start;
17171 int nrows_scrolled, i;
17172 struct glyph_row *last_text_row;
17173 struct glyph_row *last_reused_text_row;
17174 struct glyph_row *start_row;
17175 int start_vpos, min_y, max_y;
17177 #ifdef GLYPH_DEBUG
17178 if (inhibit_try_window_reusing)
17179 return 0;
17180 #endif
17182 #ifdef HAVE_XWIDGETS_xxx
17183 //currently this is needed to detect xwidget movement reliably. or probably not.
17184 printf("try_window_reusing_current_matrix\n");
17185 return 0;
17186 #endif
17189 if (/* This function doesn't handle terminal frames. */
17190 !FRAME_WINDOW_P (f)
17191 /* Don't try to reuse the display if windows have been split
17192 or such. */
17193 || windows_or_buffers_changed
17194 || f->cursor_type_changed)
17195 return 0;
17197 /* Can't do this if showing trailing whitespace. */
17198 if (!NILP (Vshow_trailing_whitespace))
17199 return 0;
17201 /* If top-line visibility has changed, give up. */
17202 if (WINDOW_WANTS_HEADER_LINE_P (w)
17203 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
17204 return 0;
17206 /* Give up if old or new display is scrolled vertically. We could
17207 make this function handle this, but right now it doesn't. */
17208 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
17209 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
17210 return 0;
17212 /* The variable new_start now holds the new window start. The old
17213 start `start' can be determined from the current matrix. */
17214 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
17215 start = start_row->minpos;
17216 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
17218 /* Clear the desired matrix for the display below. */
17219 clear_glyph_matrix (w->desired_matrix);
17221 if (CHARPOS (new_start) <= CHARPOS (start))
17223 /* Don't use this method if the display starts with an ellipsis
17224 displayed for invisible text. It's not easy to handle that case
17225 below, and it's certainly not worth the effort since this is
17226 not a frequent case. */
17227 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
17228 return 0;
17230 IF_DEBUG (debug_method_add (w, "twu1"));
17232 /* Display up to a row that can be reused. The variable
17233 last_text_row is set to the last row displayed that displays
17234 text. Note that it.vpos == 0 if or if not there is a
17235 header-line; it's not the same as the MATRIX_ROW_VPOS! */
17236 start_display (&it, w, new_start);
17237 w->cursor.vpos = -1;
17238 last_text_row = last_reused_text_row = NULL;
17240 while (it.current_y < it.last_visible_y && !f->fonts_changed)
17242 /* If we have reached into the characters in the START row,
17243 that means the line boundaries have changed. So we
17244 can't start copying with the row START. Maybe it will
17245 work to start copying with the following row. */
17246 while (IT_CHARPOS (it) > CHARPOS (start))
17248 /* Advance to the next row as the "start". */
17249 start_row++;
17250 start = start_row->minpos;
17251 /* If there are no more rows to try, or just one, give up. */
17252 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
17253 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
17254 || CHARPOS (start) == ZV)
17256 clear_glyph_matrix (w->desired_matrix);
17257 return 0;
17260 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
17262 /* If we have reached alignment, we can copy the rest of the
17263 rows. */
17264 if (IT_CHARPOS (it) == CHARPOS (start)
17265 /* Don't accept "alignment" inside a display vector,
17266 since start_row could have started in the middle of
17267 that same display vector (thus their character
17268 positions match), and we have no way of telling if
17269 that is the case. */
17270 && it.current.dpvec_index < 0)
17271 break;
17273 it.glyph_row->reversed_p = false;
17274 if (display_line (&it))
17275 last_text_row = it.glyph_row - 1;
17279 /* A value of current_y < last_visible_y means that we stopped
17280 at the previous window start, which in turn means that we
17281 have at least one reusable row. */
17282 if (it.current_y < it.last_visible_y)
17284 struct glyph_row *row;
17286 /* IT.vpos always starts from 0; it counts text lines. */
17287 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
17289 /* Find PT if not already found in the lines displayed. */
17290 if (w->cursor.vpos < 0)
17292 int dy = it.current_y - start_row->y;
17294 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
17295 row = row_containing_pos (w, PT, row, NULL, dy);
17296 if (row)
17297 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
17298 dy, nrows_scrolled);
17299 else
17301 clear_glyph_matrix (w->desired_matrix);
17302 return 0;
17306 /* Scroll the display. Do it before the current matrix is
17307 changed. The problem here is that update has not yet
17308 run, i.e. part of the current matrix is not up to date.
17309 scroll_run_hook will clear the cursor, and use the
17310 current matrix to get the height of the row the cursor is
17311 in. */
17312 run.current_y = start_row->y;
17313 run.desired_y = it.current_y;
17314 run.height = it.last_visible_y - it.current_y;
17316 if (run.height > 0 && run.current_y != run.desired_y)
17318 update_begin (f);
17319 FRAME_RIF (f)->update_window_begin_hook (w);
17320 FRAME_RIF (f)->clear_window_mouse_face (w);
17321 FRAME_RIF (f)->scroll_run_hook (w, &run);
17322 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
17323 update_end (f);
17326 /* Shift current matrix down by nrows_scrolled lines. */
17327 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
17328 rotate_matrix (w->current_matrix,
17329 start_vpos,
17330 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
17331 nrows_scrolled);
17333 /* Disable lines that must be updated. */
17334 for (i = 0; i < nrows_scrolled; ++i)
17335 (start_row + i)->enabled_p = false;
17337 /* Re-compute Y positions. */
17338 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
17339 max_y = it.last_visible_y;
17340 for (row = start_row + nrows_scrolled;
17341 row < bottom_row;
17342 ++row)
17344 row->y = it.current_y;
17345 row->visible_height = row->height;
17347 if (row->y < min_y)
17348 row->visible_height -= min_y - row->y;
17349 if (row->y + row->height > max_y)
17350 row->visible_height -= row->y + row->height - max_y;
17351 if (row->fringe_bitmap_periodic_p)
17352 row->redraw_fringe_bitmaps_p = 1;
17354 it.current_y += row->height;
17356 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
17357 last_reused_text_row = row;
17358 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
17359 break;
17362 /* Disable lines in the current matrix which are now
17363 below the window. */
17364 for (++row; row < bottom_row; ++row)
17365 row->enabled_p = row->mode_line_p = 0;
17368 /* Update window_end_pos etc.; last_reused_text_row is the last
17369 reused row from the current matrix containing text, if any.
17370 The value of last_text_row is the last displayed line
17371 containing text. */
17372 if (last_reused_text_row)
17373 adjust_window_ends (w, last_reused_text_row, 1);
17374 else if (last_text_row)
17375 adjust_window_ends (w, last_text_row, 0);
17376 else
17378 /* This window must be completely empty. */
17379 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
17380 w->window_end_pos = Z - ZV;
17381 w->window_end_vpos = 0;
17383 w->window_end_valid = 0;
17385 /* Update hint: don't try scrolling again in update_window. */
17386 w->desired_matrix->no_scrolling_p = 1;
17388 #ifdef GLYPH_DEBUG
17389 debug_method_add (w, "try_window_reusing_current_matrix 1");
17390 #endif
17391 return 1;
17393 else if (CHARPOS (new_start) > CHARPOS (start))
17395 struct glyph_row *pt_row, *row;
17396 struct glyph_row *first_reusable_row;
17397 struct glyph_row *first_row_to_display;
17398 int dy;
17399 int yb = window_text_bottom_y (w);
17401 /* Find the row starting at new_start, if there is one. Don't
17402 reuse a partially visible line at the end. */
17403 first_reusable_row = start_row;
17404 while (first_reusable_row->enabled_p
17405 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
17406 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
17407 < CHARPOS (new_start)))
17408 ++first_reusable_row;
17410 /* Give up if there is no row to reuse. */
17411 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
17412 || !first_reusable_row->enabled_p
17413 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
17414 != CHARPOS (new_start)))
17415 return 0;
17417 /* We can reuse fully visible rows beginning with
17418 first_reusable_row to the end of the window. Set
17419 first_row_to_display to the first row that cannot be reused.
17420 Set pt_row to the row containing point, if there is any. */
17421 pt_row = NULL;
17422 for (first_row_to_display = first_reusable_row;
17423 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
17424 ++first_row_to_display)
17426 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
17427 && (PT < MATRIX_ROW_END_CHARPOS (first_row_to_display)
17428 || (PT == MATRIX_ROW_END_CHARPOS (first_row_to_display)
17429 && first_row_to_display->ends_at_zv_p
17430 && pt_row == NULL)))
17431 pt_row = first_row_to_display;
17434 /* Start displaying at the start of first_row_to_display. */
17435 eassert (first_row_to_display->y < yb);
17436 init_to_row_start (&it, w, first_row_to_display);
17438 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
17439 - start_vpos);
17440 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
17441 - nrows_scrolled);
17442 it.current_y = (first_row_to_display->y - first_reusable_row->y
17443 + WINDOW_HEADER_LINE_HEIGHT (w));
17445 /* Display lines beginning with first_row_to_display in the
17446 desired matrix. Set last_text_row to the last row displayed
17447 that displays text. */
17448 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
17449 if (pt_row == NULL)
17450 w->cursor.vpos = -1;
17451 last_text_row = NULL;
17452 while (it.current_y < it.last_visible_y && !f->fonts_changed)
17453 if (display_line (&it))
17454 last_text_row = it.glyph_row - 1;
17456 /* If point is in a reused row, adjust y and vpos of the cursor
17457 position. */
17458 if (pt_row)
17460 w->cursor.vpos -= nrows_scrolled;
17461 w->cursor.y -= first_reusable_row->y - start_row->y;
17464 /* Give up if point isn't in a row displayed or reused. (This
17465 also handles the case where w->cursor.vpos < nrows_scrolled
17466 after the calls to display_line, which can happen with scroll
17467 margins. See bug#1295.) */
17468 if (w->cursor.vpos < 0)
17470 clear_glyph_matrix (w->desired_matrix);
17471 return 0;
17474 /* Scroll the display. */
17475 run.current_y = first_reusable_row->y;
17476 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
17477 run.height = it.last_visible_y - run.current_y;
17478 dy = run.current_y - run.desired_y;
17480 if (run.height)
17482 update_begin (f);
17483 FRAME_RIF (f)->update_window_begin_hook (w);
17484 FRAME_RIF (f)->clear_window_mouse_face (w);
17485 FRAME_RIF (f)->scroll_run_hook (w, &run);
17486 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
17487 update_end (f);
17490 /* Adjust Y positions of reused rows. */
17491 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
17492 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
17493 max_y = it.last_visible_y;
17494 for (row = first_reusable_row; row < first_row_to_display; ++row)
17496 row->y -= dy;
17497 row->visible_height = row->height;
17498 if (row->y < min_y)
17499 row->visible_height -= min_y - row->y;
17500 if (row->y + row->height > max_y)
17501 row->visible_height -= row->y + row->height - max_y;
17502 if (row->fringe_bitmap_periodic_p)
17503 row->redraw_fringe_bitmaps_p = 1;
17506 /* Scroll the current matrix. */
17507 eassert (nrows_scrolled > 0);
17508 rotate_matrix (w->current_matrix,
17509 start_vpos,
17510 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
17511 -nrows_scrolled);
17513 /* Disable rows not reused. */
17514 for (row -= nrows_scrolled; row < bottom_row; ++row)
17515 row->enabled_p = false;
17517 /* Point may have moved to a different line, so we cannot assume that
17518 the previous cursor position is valid; locate the correct row. */
17519 if (pt_row)
17521 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
17522 row < bottom_row
17523 && PT >= MATRIX_ROW_END_CHARPOS (row)
17524 && !row->ends_at_zv_p;
17525 row++)
17527 w->cursor.vpos++;
17528 w->cursor.y = row->y;
17530 if (row < bottom_row)
17532 /* Can't simply scan the row for point with
17533 bidi-reordered glyph rows. Let set_cursor_from_row
17534 figure out where to put the cursor, and if it fails,
17535 give up. */
17536 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
17538 if (!set_cursor_from_row (w, row, w->current_matrix,
17539 0, 0, 0, 0))
17541 clear_glyph_matrix (w->desired_matrix);
17542 return 0;
17545 else
17547 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
17548 struct glyph *end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
17550 for (; glyph < end
17551 && (!BUFFERP (glyph->object)
17552 || glyph->charpos < PT);
17553 glyph++)
17555 w->cursor.hpos++;
17556 w->cursor.x += glyph->pixel_width;
17562 /* Adjust window end. A null value of last_text_row means that
17563 the window end is in reused rows which in turn means that
17564 only its vpos can have changed. */
17565 if (last_text_row)
17566 adjust_window_ends (w, last_text_row, 0);
17567 else
17568 w->window_end_vpos -= nrows_scrolled;
17570 w->window_end_valid = 0;
17571 w->desired_matrix->no_scrolling_p = 1;
17573 #ifdef GLYPH_DEBUG
17574 debug_method_add (w, "try_window_reusing_current_matrix 2");
17575 #endif
17576 return 1;
17579 return 0;
17584 /************************************************************************
17585 Window redisplay reusing current matrix when buffer has changed
17586 ************************************************************************/
17588 static struct glyph_row *find_last_unchanged_at_beg_row (struct window *);
17589 static struct glyph_row *find_first_unchanged_at_end_row (struct window *,
17590 ptrdiff_t *, ptrdiff_t *);
17591 static struct glyph_row *
17592 find_last_row_displaying_text (struct glyph_matrix *, struct it *,
17593 struct glyph_row *);
17596 /* Return the last row in MATRIX displaying text. If row START is
17597 non-null, start searching with that row. IT gives the dimensions
17598 of the display. Value is null if matrix is empty; otherwise it is
17599 a pointer to the row found. */
17601 static struct glyph_row *
17602 find_last_row_displaying_text (struct glyph_matrix *matrix, struct it *it,
17603 struct glyph_row *start)
17605 struct glyph_row *row, *row_found;
17607 /* Set row_found to the last row in IT->w's current matrix
17608 displaying text. The loop looks funny but think of partially
17609 visible lines. */
17610 row_found = NULL;
17611 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
17612 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
17614 eassert (row->enabled_p);
17615 row_found = row;
17616 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
17617 break;
17618 ++row;
17621 return row_found;
17625 /* Return the last row in the current matrix of W that is not affected
17626 by changes at the start of current_buffer that occurred since W's
17627 current matrix was built. Value is null if no such row exists.
17629 BEG_UNCHANGED us the number of characters unchanged at the start of
17630 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
17631 first changed character in current_buffer. Characters at positions <
17632 BEG + BEG_UNCHANGED are at the same buffer positions as they were
17633 when the current matrix was built. */
17635 static struct glyph_row *
17636 find_last_unchanged_at_beg_row (struct window *w)
17638 ptrdiff_t first_changed_pos = BEG + BEG_UNCHANGED;
17639 struct glyph_row *row;
17640 struct glyph_row *row_found = NULL;
17641 int yb = window_text_bottom_y (w);
17643 /* Find the last row displaying unchanged text. */
17644 for (row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
17645 MATRIX_ROW_DISPLAYS_TEXT_P (row)
17646 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos;
17647 ++row)
17649 if (/* If row ends before first_changed_pos, it is unchanged,
17650 except in some case. */
17651 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
17652 /* When row ends in ZV and we write at ZV it is not
17653 unchanged. */
17654 && !row->ends_at_zv_p
17655 /* When first_changed_pos is the end of a continued line,
17656 row is not unchanged because it may be no longer
17657 continued. */
17658 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
17659 && (row->continued_p
17660 || row->exact_window_width_line_p))
17661 /* If ROW->end is beyond ZV, then ROW->end is outdated and
17662 needs to be recomputed, so don't consider this row as
17663 unchanged. This happens when the last line was
17664 bidi-reordered and was killed immediately before this
17665 redisplay cycle. In that case, ROW->end stores the
17666 buffer position of the first visual-order character of
17667 the killed text, which is now beyond ZV. */
17668 && CHARPOS (row->end.pos) <= ZV)
17669 row_found = row;
17671 /* Stop if last visible row. */
17672 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
17673 break;
17676 return row_found;
17680 /* Find the first glyph row in the current matrix of W that is not
17681 affected by changes at the end of current_buffer since the
17682 time W's current matrix was built.
17684 Return in *DELTA the number of chars by which buffer positions in
17685 unchanged text at the end of current_buffer must be adjusted.
17687 Return in *DELTA_BYTES the corresponding number of bytes.
17689 Value is null if no such row exists, i.e. all rows are affected by
17690 changes. */
17692 static struct glyph_row *
17693 find_first_unchanged_at_end_row (struct window *w,
17694 ptrdiff_t *delta, ptrdiff_t *delta_bytes)
17696 struct glyph_row *row;
17697 struct glyph_row *row_found = NULL;
17699 *delta = *delta_bytes = 0;
17701 /* Display must not have been paused, otherwise the current matrix
17702 is not up to date. */
17703 eassert (w->window_end_valid);
17705 /* A value of window_end_pos >= END_UNCHANGED means that the window
17706 end is in the range of changed text. If so, there is no
17707 unchanged row at the end of W's current matrix. */
17708 if (w->window_end_pos >= END_UNCHANGED)
17709 return NULL;
17711 /* Set row to the last row in W's current matrix displaying text. */
17712 row = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
17714 /* If matrix is entirely empty, no unchanged row exists. */
17715 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
17717 /* The value of row is the last glyph row in the matrix having a
17718 meaningful buffer position in it. The end position of row
17719 corresponds to window_end_pos. This allows us to translate
17720 buffer positions in the current matrix to current buffer
17721 positions for characters not in changed text. */
17722 ptrdiff_t Z_old =
17723 MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos;
17724 ptrdiff_t Z_BYTE_old =
17725 MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
17726 ptrdiff_t last_unchanged_pos, last_unchanged_pos_old;
17727 struct glyph_row *first_text_row
17728 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
17730 *delta = Z - Z_old;
17731 *delta_bytes = Z_BYTE - Z_BYTE_old;
17733 /* Set last_unchanged_pos to the buffer position of the last
17734 character in the buffer that has not been changed. Z is the
17735 index + 1 of the last character in current_buffer, i.e. by
17736 subtracting END_UNCHANGED we get the index of the last
17737 unchanged character, and we have to add BEG to get its buffer
17738 position. */
17739 last_unchanged_pos = Z - END_UNCHANGED + BEG;
17740 last_unchanged_pos_old = last_unchanged_pos - *delta;
17742 /* Search backward from ROW for a row displaying a line that
17743 starts at a minimum position >= last_unchanged_pos_old. */
17744 for (; row > first_text_row; --row)
17746 /* This used to abort, but it can happen.
17747 It is ok to just stop the search instead here. KFS. */
17748 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
17749 break;
17751 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
17752 row_found = row;
17756 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
17758 return row_found;
17762 /* Make sure that glyph rows in the current matrix of window W
17763 reference the same glyph memory as corresponding rows in the
17764 frame's frame matrix. This function is called after scrolling W's
17765 current matrix on a terminal frame in try_window_id and
17766 try_window_reusing_current_matrix. */
17768 static void
17769 sync_frame_with_window_matrix_rows (struct window *w)
17771 struct frame *f = XFRAME (w->frame);
17772 struct glyph_row *window_row, *window_row_end, *frame_row;
17774 /* Preconditions: W must be a leaf window and full-width. Its frame
17775 must have a frame matrix. */
17776 eassert (BUFFERP (w->contents));
17777 eassert (WINDOW_FULL_WIDTH_P (w));
17778 eassert (!FRAME_WINDOW_P (f));
17780 /* If W is a full-width window, glyph pointers in W's current matrix
17781 have, by definition, to be the same as glyph pointers in the
17782 corresponding frame matrix. Note that frame matrices have no
17783 marginal areas (see build_frame_matrix). */
17784 window_row = w->current_matrix->rows;
17785 window_row_end = window_row + w->current_matrix->nrows;
17786 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
17787 while (window_row < window_row_end)
17789 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
17790 struct glyph *end = window_row->glyphs[LAST_AREA];
17792 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
17793 frame_row->glyphs[TEXT_AREA] = start;
17794 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
17795 frame_row->glyphs[LAST_AREA] = end;
17797 /* Disable frame rows whose corresponding window rows have
17798 been disabled in try_window_id. */
17799 if (!window_row->enabled_p)
17800 frame_row->enabled_p = false;
17802 ++window_row, ++frame_row;
17807 /* Find the glyph row in window W containing CHARPOS. Consider all
17808 rows between START and END (not inclusive). END null means search
17809 all rows to the end of the display area of W. Value is the row
17810 containing CHARPOS or null. */
17812 struct glyph_row *
17813 row_containing_pos (struct window *w, ptrdiff_t charpos,
17814 struct glyph_row *start, struct glyph_row *end, int dy)
17816 struct glyph_row *row = start;
17817 struct glyph_row *best_row = NULL;
17818 ptrdiff_t mindif = BUF_ZV (XBUFFER (w->contents)) + 1;
17819 int last_y;
17821 /* If we happen to start on a header-line, skip that. */
17822 if (row->mode_line_p)
17823 ++row;
17825 if ((end && row >= end) || !row->enabled_p)
17826 return NULL;
17828 last_y = window_text_bottom_y (w) - dy;
17830 while (1)
17832 /* Give up if we have gone too far. */
17833 if (end && row >= end)
17834 return NULL;
17835 /* This formerly returned if they were equal.
17836 I think that both quantities are of a "last plus one" type;
17837 if so, when they are equal, the row is within the screen. -- rms. */
17838 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
17839 return NULL;
17841 /* If it is in this row, return this row. */
17842 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
17843 || (MATRIX_ROW_END_CHARPOS (row) == charpos
17844 /* The end position of a row equals the start
17845 position of the next row. If CHARPOS is there, we
17846 would rather consider it displayed in the next
17847 line, except when this line ends in ZV. */
17848 && !row_for_charpos_p (row, charpos)))
17849 && charpos >= MATRIX_ROW_START_CHARPOS (row))
17851 struct glyph *g;
17853 if (NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
17854 || (!best_row && !row->continued_p))
17855 return row;
17856 /* In bidi-reordered rows, there could be several rows whose
17857 edges surround CHARPOS, all of these rows belonging to
17858 the same continued line. We need to find the row which
17859 fits CHARPOS the best. */
17860 for (g = row->glyphs[TEXT_AREA];
17861 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
17862 g++)
17864 if (!STRINGP (g->object))
17866 if (g->charpos > 0 && eabs (g->charpos - charpos) < mindif)
17868 mindif = eabs (g->charpos - charpos);
17869 best_row = row;
17870 /* Exact match always wins. */
17871 if (mindif == 0)
17872 return best_row;
17877 else if (best_row && !row->continued_p)
17878 return best_row;
17879 ++row;
17884 /* Try to redisplay window W by reusing its existing display. W's
17885 current matrix must be up to date when this function is called,
17886 i.e. window_end_valid must be nonzero.
17888 Value is
17890 >= 1 if successful, i.e. display has been updated
17891 specifically:
17892 1 means the changes were in front of a newline that precedes
17893 the window start, and the whole current matrix was reused
17894 2 means the changes were after the last position displayed
17895 in the window, and the whole current matrix was reused
17896 3 means portions of the current matrix were reused, while
17897 some of the screen lines were redrawn
17898 -1 if redisplay with same window start is known not to succeed
17899 0 if otherwise unsuccessful
17901 The following steps are performed:
17903 1. Find the last row in the current matrix of W that is not
17904 affected by changes at the start of current_buffer. If no such row
17905 is found, give up.
17907 2. Find the first row in W's current matrix that is not affected by
17908 changes at the end of current_buffer. Maybe there is no such row.
17910 3. Display lines beginning with the row + 1 found in step 1 to the
17911 row found in step 2 or, if step 2 didn't find a row, to the end of
17912 the window.
17914 4. If cursor is not known to appear on the window, give up.
17916 5. If display stopped at the row found in step 2, scroll the
17917 display and current matrix as needed.
17919 6. Maybe display some lines at the end of W, if we must. This can
17920 happen under various circumstances, like a partially visible line
17921 becoming fully visible, or because newly displayed lines are displayed
17922 in smaller font sizes.
17924 7. Update W's window end information. */
17926 static int
17927 try_window_id (struct window *w)
17929 struct frame *f = XFRAME (w->frame);
17930 struct glyph_matrix *current_matrix = w->current_matrix;
17931 struct glyph_matrix *desired_matrix = w->desired_matrix;
17932 struct glyph_row *last_unchanged_at_beg_row;
17933 struct glyph_row *first_unchanged_at_end_row;
17934 struct glyph_row *row;
17935 struct glyph_row *bottom_row;
17936 int bottom_vpos;
17937 struct it it;
17938 ptrdiff_t delta = 0, delta_bytes = 0, stop_pos;
17939 int dvpos, dy;
17940 struct text_pos start_pos;
17941 struct run run;
17942 int first_unchanged_at_end_vpos = 0;
17943 struct glyph_row *last_text_row, *last_text_row_at_end;
17944 struct text_pos start;
17945 ptrdiff_t first_changed_charpos, last_changed_charpos;
17947 #ifdef GLYPH_DEBUG
17948 if (inhibit_try_window_id)
17949 return 0;
17950 #endif
17952 #ifdef HAVE_XWIDGETS_xxx
17953 //maybe needed for proper xwidget movement
17954 printf("try_window_id\n");
17955 return -1;
17956 #endif
17959 /* This is handy for debugging. */
17960 #if 0
17961 #define GIVE_UP(X) \
17962 do { \
17963 fprintf (stderr, "try_window_id give up %d\n", (X)); \
17964 return 0; \
17965 } while (0)
17966 #else
17967 #define GIVE_UP(X) return 0
17968 #endif
17970 SET_TEXT_POS_FROM_MARKER (start, w->start);
17972 /* Don't use this for mini-windows because these can show
17973 messages and mini-buffers, and we don't handle that here. */
17974 if (MINI_WINDOW_P (w))
17975 GIVE_UP (1);
17977 /* This flag is used to prevent redisplay optimizations. */
17978 if (windows_or_buffers_changed || f->cursor_type_changed)
17979 GIVE_UP (2);
17981 /* This function's optimizations cannot be used if overlays have
17982 changed in the buffer displayed by the window, so give up if they
17983 have. */
17984 if (w->last_overlay_modified != OVERLAY_MODIFF)
17985 GIVE_UP (21);
17987 /* Verify that narrowing has not changed.
17988 Also verify that we were not told to prevent redisplay optimizations.
17989 It would be nice to further
17990 reduce the number of cases where this prevents try_window_id. */
17991 if (current_buffer->clip_changed
17992 || current_buffer->prevent_redisplay_optimizations_p)
17993 GIVE_UP (3);
17995 /* Window must either use window-based redisplay or be full width. */
17996 if (!FRAME_WINDOW_P (f)
17997 && (!FRAME_LINE_INS_DEL_OK (f)
17998 || !WINDOW_FULL_WIDTH_P (w)))
17999 GIVE_UP (4);
18001 /* Give up if point is known NOT to appear in W. */
18002 if (PT < CHARPOS (start))
18003 GIVE_UP (5);
18005 /* Another way to prevent redisplay optimizations. */
18006 if (w->last_modified == 0)
18007 GIVE_UP (6);
18009 /* Verify that window is not hscrolled. */
18010 if (w->hscroll != 0)
18011 GIVE_UP (7);
18013 /* Verify that display wasn't paused. */
18014 if (!w->window_end_valid)
18015 GIVE_UP (8);
18017 /* Likewise if highlighting trailing whitespace. */
18018 if (!NILP (Vshow_trailing_whitespace))
18019 GIVE_UP (11);
18021 /* Can't use this if overlay arrow position and/or string have
18022 changed. */
18023 if (overlay_arrows_changed_p ())
18024 GIVE_UP (12);
18026 /* When word-wrap is on, adding a space to the first word of a
18027 wrapped line can change the wrap position, altering the line
18028 above it. It might be worthwhile to handle this more
18029 intelligently, but for now just redisplay from scratch. */
18030 if (!NILP (BVAR (XBUFFER (w->contents), word_wrap)))
18031 GIVE_UP (21);
18033 /* Under bidi reordering, adding or deleting a character in the
18034 beginning of a paragraph, before the first strong directional
18035 character, can change the base direction of the paragraph (unless
18036 the buffer specifies a fixed paragraph direction), which will
18037 require to redisplay the whole paragraph. It might be worthwhile
18038 to find the paragraph limits and widen the range of redisplayed
18039 lines to that, but for now just give up this optimization and
18040 redisplay from scratch. */
18041 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
18042 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
18043 GIVE_UP (22);
18045 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
18046 only if buffer has really changed. The reason is that the gap is
18047 initially at Z for freshly visited files. The code below would
18048 set end_unchanged to 0 in that case. */
18049 if (MODIFF > SAVE_MODIFF
18050 /* This seems to happen sometimes after saving a buffer. */
18051 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
18053 if (GPT - BEG < BEG_UNCHANGED)
18054 BEG_UNCHANGED = GPT - BEG;
18055 if (Z - GPT < END_UNCHANGED)
18056 END_UNCHANGED = Z - GPT;
18059 /* The position of the first and last character that has been changed. */
18060 first_changed_charpos = BEG + BEG_UNCHANGED;
18061 last_changed_charpos = Z - END_UNCHANGED;
18063 /* If window starts after a line end, and the last change is in
18064 front of that newline, then changes don't affect the display.
18065 This case happens with stealth-fontification. Note that although
18066 the display is unchanged, glyph positions in the matrix have to
18067 be adjusted, of course. */
18068 row = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
18069 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
18070 && ((last_changed_charpos < CHARPOS (start)
18071 && CHARPOS (start) == BEGV)
18072 || (last_changed_charpos < CHARPOS (start) - 1
18073 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
18075 ptrdiff_t Z_old, Z_delta, Z_BYTE_old, Z_delta_bytes;
18076 struct glyph_row *r0;
18078 /* Compute how many chars/bytes have been added to or removed
18079 from the buffer. */
18080 Z_old = MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos;
18081 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
18082 Z_delta = Z - Z_old;
18083 Z_delta_bytes = Z_BYTE - Z_BYTE_old;
18085 /* Give up if PT is not in the window. Note that it already has
18086 been checked at the start of try_window_id that PT is not in
18087 front of the window start. */
18088 if (PT >= MATRIX_ROW_END_CHARPOS (row) + Z_delta)
18089 GIVE_UP (13);
18091 /* If window start is unchanged, we can reuse the whole matrix
18092 as is, after adjusting glyph positions. No need to compute
18093 the window end again, since its offset from Z hasn't changed. */
18094 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
18095 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + Z_delta
18096 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + Z_delta_bytes
18097 /* PT must not be in a partially visible line. */
18098 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + Z_delta
18099 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
18101 /* Adjust positions in the glyph matrix. */
18102 if (Z_delta || Z_delta_bytes)
18104 struct glyph_row *r1
18105 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
18106 increment_matrix_positions (w->current_matrix,
18107 MATRIX_ROW_VPOS (r0, current_matrix),
18108 MATRIX_ROW_VPOS (r1, current_matrix),
18109 Z_delta, Z_delta_bytes);
18112 /* Set the cursor. */
18113 row = row_containing_pos (w, PT, r0, NULL, 0);
18114 if (row)
18115 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
18116 return 1;
18120 /* Handle the case that changes are all below what is displayed in
18121 the window, and that PT is in the window. This shortcut cannot
18122 be taken if ZV is visible in the window, and text has been added
18123 there that is visible in the window. */
18124 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
18125 /* ZV is not visible in the window, or there are no
18126 changes at ZV, actually. */
18127 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
18128 || first_changed_charpos == last_changed_charpos))
18130 struct glyph_row *r0;
18132 /* Give up if PT is not in the window. Note that it already has
18133 been checked at the start of try_window_id that PT is not in
18134 front of the window start. */
18135 if (PT >= MATRIX_ROW_END_CHARPOS (row))
18136 GIVE_UP (14);
18138 /* If window start is unchanged, we can reuse the whole matrix
18139 as is, without changing glyph positions since no text has
18140 been added/removed in front of the window end. */
18141 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
18142 if (TEXT_POS_EQUAL_P (start, r0->minpos)
18143 /* PT must not be in a partially visible line. */
18144 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
18145 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
18147 /* We have to compute the window end anew since text
18148 could have been added/removed after it. */
18149 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
18150 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
18152 /* Set the cursor. */
18153 row = row_containing_pos (w, PT, r0, NULL, 0);
18154 if (row)
18155 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
18156 return 2;
18160 /* Give up if window start is in the changed area.
18162 The condition used to read
18164 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
18166 but why that was tested escapes me at the moment. */
18167 if (CHARPOS (start) >= first_changed_charpos
18168 && CHARPOS (start) <= last_changed_charpos)
18169 GIVE_UP (15);
18171 /* Check that window start agrees with the start of the first glyph
18172 row in its current matrix. Check this after we know the window
18173 start is not in changed text, otherwise positions would not be
18174 comparable. */
18175 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
18176 if (!TEXT_POS_EQUAL_P (start, row->minpos))
18177 GIVE_UP (16);
18179 /* Give up if the window ends in strings. Overlay strings
18180 at the end are difficult to handle, so don't try. */
18181 row = MATRIX_ROW (current_matrix, w->window_end_vpos);
18182 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
18183 GIVE_UP (20);
18185 /* Compute the position at which we have to start displaying new
18186 lines. Some of the lines at the top of the window might be
18187 reusable because they are not displaying changed text. Find the
18188 last row in W's current matrix not affected by changes at the
18189 start of current_buffer. Value is null if changes start in the
18190 first line of window. */
18191 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
18192 if (last_unchanged_at_beg_row)
18194 /* Avoid starting to display in the middle of a character, a TAB
18195 for instance. This is easier than to set up the iterator
18196 exactly, and it's not a frequent case, so the additional
18197 effort wouldn't really pay off. */
18198 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
18199 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
18200 && last_unchanged_at_beg_row > w->current_matrix->rows)
18201 --last_unchanged_at_beg_row;
18203 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
18204 GIVE_UP (17);
18206 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
18207 GIVE_UP (18);
18208 start_pos = it.current.pos;
18210 /* Start displaying new lines in the desired matrix at the same
18211 vpos we would use in the current matrix, i.e. below
18212 last_unchanged_at_beg_row. */
18213 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
18214 current_matrix);
18215 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
18216 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
18218 eassert (it.hpos == 0 && it.current_x == 0);
18220 else
18222 /* There are no reusable lines at the start of the window.
18223 Start displaying in the first text line. */
18224 start_display (&it, w, start);
18225 it.vpos = it.first_vpos;
18226 start_pos = it.current.pos;
18229 /* Find the first row that is not affected by changes at the end of
18230 the buffer. Value will be null if there is no unchanged row, in
18231 which case we must redisplay to the end of the window. delta
18232 will be set to the value by which buffer positions beginning with
18233 first_unchanged_at_end_row have to be adjusted due to text
18234 changes. */
18235 first_unchanged_at_end_row
18236 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
18237 IF_DEBUG (debug_delta = delta);
18238 IF_DEBUG (debug_delta_bytes = delta_bytes);
18240 /* Set stop_pos to the buffer position up to which we will have to
18241 display new lines. If first_unchanged_at_end_row != NULL, this
18242 is the buffer position of the start of the line displayed in that
18243 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
18244 that we don't stop at a buffer position. */
18245 stop_pos = 0;
18246 if (first_unchanged_at_end_row)
18248 eassert (last_unchanged_at_beg_row == NULL
18249 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
18251 /* If this is a continuation line, move forward to the next one
18252 that isn't. Changes in lines above affect this line.
18253 Caution: this may move first_unchanged_at_end_row to a row
18254 not displaying text. */
18255 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
18256 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
18257 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
18258 < it.last_visible_y))
18259 ++first_unchanged_at_end_row;
18261 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
18262 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
18263 >= it.last_visible_y))
18264 first_unchanged_at_end_row = NULL;
18265 else
18267 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
18268 + delta);
18269 first_unchanged_at_end_vpos
18270 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
18271 eassert (stop_pos >= Z - END_UNCHANGED);
18274 else if (last_unchanged_at_beg_row == NULL)
18275 GIVE_UP (19);
18278 #ifdef GLYPH_DEBUG
18280 /* Either there is no unchanged row at the end, or the one we have
18281 now displays text. This is a necessary condition for the window
18282 end pos calculation at the end of this function. */
18283 eassert (first_unchanged_at_end_row == NULL
18284 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
18286 debug_last_unchanged_at_beg_vpos
18287 = (last_unchanged_at_beg_row
18288 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
18289 : -1);
18290 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
18292 #endif /* GLYPH_DEBUG */
18295 /* Display new lines. Set last_text_row to the last new line
18296 displayed which has text on it, i.e. might end up as being the
18297 line where the window_end_vpos is. */
18298 w->cursor.vpos = -1;
18299 last_text_row = NULL;
18300 overlay_arrow_seen = 0;
18301 if (it.current_y < it.last_visible_y
18302 && !f->fonts_changed
18303 && (first_unchanged_at_end_row == NULL
18304 || IT_CHARPOS (it) < stop_pos))
18305 it.glyph_row->reversed_p = false;
18306 while (it.current_y < it.last_visible_y
18307 && !f->fonts_changed
18308 && (first_unchanged_at_end_row == NULL
18309 || IT_CHARPOS (it) < stop_pos))
18311 if (display_line (&it))
18312 last_text_row = it.glyph_row - 1;
18315 if (f->fonts_changed)
18316 return -1;
18319 /* Compute differences in buffer positions, y-positions etc. for
18320 lines reused at the bottom of the window. Compute what we can
18321 scroll. */
18322 if (first_unchanged_at_end_row
18323 /* No lines reused because we displayed everything up to the
18324 bottom of the window. */
18325 && it.current_y < it.last_visible_y)
18327 dvpos = (it.vpos
18328 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
18329 current_matrix));
18330 dy = it.current_y - first_unchanged_at_end_row->y;
18331 run.current_y = first_unchanged_at_end_row->y;
18332 run.desired_y = run.current_y + dy;
18333 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
18335 else
18337 delta = delta_bytes = dvpos = dy
18338 = run.current_y = run.desired_y = run.height = 0;
18339 first_unchanged_at_end_row = NULL;
18341 IF_DEBUG ((debug_dvpos = dvpos, debug_dy = dy));
18344 /* Find the cursor if not already found. We have to decide whether
18345 PT will appear on this window (it sometimes doesn't, but this is
18346 not a very frequent case.) This decision has to be made before
18347 the current matrix is altered. A value of cursor.vpos < 0 means
18348 that PT is either in one of the lines beginning at
18349 first_unchanged_at_end_row or below the window. Don't care for
18350 lines that might be displayed later at the window end; as
18351 mentioned, this is not a frequent case. */
18352 if (w->cursor.vpos < 0)
18354 /* Cursor in unchanged rows at the top? */
18355 if (PT < CHARPOS (start_pos)
18356 && last_unchanged_at_beg_row)
18358 row = row_containing_pos (w, PT,
18359 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
18360 last_unchanged_at_beg_row + 1, 0);
18361 if (row)
18362 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
18365 /* Start from first_unchanged_at_end_row looking for PT. */
18366 else if (first_unchanged_at_end_row)
18368 row = row_containing_pos (w, PT - delta,
18369 first_unchanged_at_end_row, NULL, 0);
18370 if (row)
18371 set_cursor_from_row (w, row, w->current_matrix, delta,
18372 delta_bytes, dy, dvpos);
18375 /* Give up if cursor was not found. */
18376 if (w->cursor.vpos < 0)
18378 clear_glyph_matrix (w->desired_matrix);
18379 return -1;
18383 /* Don't let the cursor end in the scroll margins. */
18385 int this_scroll_margin, cursor_height;
18386 int frame_line_height = default_line_pixel_height (w);
18387 int window_total_lines
18388 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (it.f) / frame_line_height;
18390 this_scroll_margin =
18391 max (0, min (scroll_margin, window_total_lines / 4));
18392 this_scroll_margin *= frame_line_height;
18393 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
18395 if ((w->cursor.y < this_scroll_margin
18396 && CHARPOS (start) > BEGV)
18397 /* Old redisplay didn't take scroll margin into account at the bottom,
18398 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
18399 || (w->cursor.y + (make_cursor_line_fully_visible_p
18400 ? cursor_height + this_scroll_margin
18401 : 1)) > it.last_visible_y)
18403 w->cursor.vpos = -1;
18404 clear_glyph_matrix (w->desired_matrix);
18405 return -1;
18409 /* Scroll the display. Do it before changing the current matrix so
18410 that xterm.c doesn't get confused about where the cursor glyph is
18411 found. */
18412 if (dy && run.height)
18414 update_begin (f);
18416 if (FRAME_WINDOW_P (f))
18418 FRAME_RIF (f)->update_window_begin_hook (w);
18419 FRAME_RIF (f)->clear_window_mouse_face (w);
18420 FRAME_RIF (f)->scroll_run_hook (w, &run);
18421 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
18423 else
18425 /* Terminal frame. In this case, dvpos gives the number of
18426 lines to scroll by; dvpos < 0 means scroll up. */
18427 int from_vpos
18428 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
18429 int from = WINDOW_TOP_EDGE_LINE (w) + from_vpos;
18430 int end = (WINDOW_TOP_EDGE_LINE (w)
18431 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
18432 + window_internal_height (w));
18434 #if defined (HAVE_GPM) || defined (MSDOS)
18435 x_clear_window_mouse_face (w);
18436 #endif
18437 /* Perform the operation on the screen. */
18438 if (dvpos > 0)
18440 /* Scroll last_unchanged_at_beg_row to the end of the
18441 window down dvpos lines. */
18442 set_terminal_window (f, end);
18444 /* On dumb terminals delete dvpos lines at the end
18445 before inserting dvpos empty lines. */
18446 if (!FRAME_SCROLL_REGION_OK (f))
18447 ins_del_lines (f, end - dvpos, -dvpos);
18449 /* Insert dvpos empty lines in front of
18450 last_unchanged_at_beg_row. */
18451 ins_del_lines (f, from, dvpos);
18453 else if (dvpos < 0)
18455 /* Scroll up last_unchanged_at_beg_vpos to the end of
18456 the window to last_unchanged_at_beg_vpos - |dvpos|. */
18457 set_terminal_window (f, end);
18459 /* Delete dvpos lines in front of
18460 last_unchanged_at_beg_vpos. ins_del_lines will set
18461 the cursor to the given vpos and emit |dvpos| delete
18462 line sequences. */
18463 ins_del_lines (f, from + dvpos, dvpos);
18465 /* On a dumb terminal insert dvpos empty lines at the
18466 end. */
18467 if (!FRAME_SCROLL_REGION_OK (f))
18468 ins_del_lines (f, end + dvpos, -dvpos);
18471 set_terminal_window (f, 0);
18474 update_end (f);
18477 /* Shift reused rows of the current matrix to the right position.
18478 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
18479 text. */
18480 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
18481 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
18482 if (dvpos < 0)
18484 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
18485 bottom_vpos, dvpos);
18486 clear_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
18487 bottom_vpos);
18489 else if (dvpos > 0)
18491 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
18492 bottom_vpos, dvpos);
18493 clear_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
18494 first_unchanged_at_end_vpos + dvpos);
18497 /* For frame-based redisplay, make sure that current frame and window
18498 matrix are in sync with respect to glyph memory. */
18499 if (!FRAME_WINDOW_P (f))
18500 sync_frame_with_window_matrix_rows (w);
18502 /* Adjust buffer positions in reused rows. */
18503 if (delta || delta_bytes)
18504 increment_matrix_positions (current_matrix,
18505 first_unchanged_at_end_vpos + dvpos,
18506 bottom_vpos, delta, delta_bytes);
18508 /* Adjust Y positions. */
18509 if (dy)
18510 shift_glyph_matrix (w, current_matrix,
18511 first_unchanged_at_end_vpos + dvpos,
18512 bottom_vpos, dy);
18514 if (first_unchanged_at_end_row)
18516 first_unchanged_at_end_row += dvpos;
18517 if (first_unchanged_at_end_row->y >= it.last_visible_y
18518 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
18519 first_unchanged_at_end_row = NULL;
18522 /* If scrolling up, there may be some lines to display at the end of
18523 the window. */
18524 last_text_row_at_end = NULL;
18525 if (dy < 0)
18527 /* Scrolling up can leave for example a partially visible line
18528 at the end of the window to be redisplayed. */
18529 /* Set last_row to the glyph row in the current matrix where the
18530 window end line is found. It has been moved up or down in
18531 the matrix by dvpos. */
18532 int last_vpos = w->window_end_vpos + dvpos;
18533 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
18535 /* If last_row is the window end line, it should display text. */
18536 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_row));
18538 /* If window end line was partially visible before, begin
18539 displaying at that line. Otherwise begin displaying with the
18540 line following it. */
18541 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
18543 init_to_row_start (&it, w, last_row);
18544 it.vpos = last_vpos;
18545 it.current_y = last_row->y;
18547 else
18549 init_to_row_end (&it, w, last_row);
18550 it.vpos = 1 + last_vpos;
18551 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
18552 ++last_row;
18555 /* We may start in a continuation line. If so, we have to
18556 get the right continuation_lines_width and current_x. */
18557 it.continuation_lines_width = last_row->continuation_lines_width;
18558 it.hpos = it.current_x = 0;
18560 /* Display the rest of the lines at the window end. */
18561 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
18562 while (it.current_y < it.last_visible_y && !f->fonts_changed)
18564 /* Is it always sure that the display agrees with lines in
18565 the current matrix? I don't think so, so we mark rows
18566 displayed invalid in the current matrix by setting their
18567 enabled_p flag to zero. */
18568 SET_MATRIX_ROW_ENABLED_P (w->current_matrix, it.vpos, false);
18569 if (display_line (&it))
18570 last_text_row_at_end = it.glyph_row - 1;
18574 /* Update window_end_pos and window_end_vpos. */
18575 if (first_unchanged_at_end_row && !last_text_row_at_end)
18577 /* Window end line if one of the preserved rows from the current
18578 matrix. Set row to the last row displaying text in current
18579 matrix starting at first_unchanged_at_end_row, after
18580 scrolling. */
18581 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
18582 row = find_last_row_displaying_text (w->current_matrix, &it,
18583 first_unchanged_at_end_row);
18584 eassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
18585 adjust_window_ends (w, row, 1);
18586 eassert (w->window_end_bytepos >= 0);
18587 IF_DEBUG (debug_method_add (w, "A"));
18589 else if (last_text_row_at_end)
18591 adjust_window_ends (w, last_text_row_at_end, 0);
18592 eassert (w->window_end_bytepos >= 0);
18593 IF_DEBUG (debug_method_add (w, "B"));
18595 else if (last_text_row)
18597 /* We have displayed either to the end of the window or at the
18598 end of the window, i.e. the last row with text is to be found
18599 in the desired matrix. */
18600 adjust_window_ends (w, last_text_row, 0);
18601 eassert (w->window_end_bytepos >= 0);
18603 else if (first_unchanged_at_end_row == NULL
18604 && last_text_row == NULL
18605 && last_text_row_at_end == NULL)
18607 /* Displayed to end of window, but no line containing text was
18608 displayed. Lines were deleted at the end of the window. */
18609 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
18610 int vpos = w->window_end_vpos;
18611 struct glyph_row *current_row = current_matrix->rows + vpos;
18612 struct glyph_row *desired_row = desired_matrix->rows + vpos;
18614 for (row = NULL;
18615 row == NULL && vpos >= first_vpos;
18616 --vpos, --current_row, --desired_row)
18618 if (desired_row->enabled_p)
18620 if (MATRIX_ROW_DISPLAYS_TEXT_P (desired_row))
18621 row = desired_row;
18623 else if (MATRIX_ROW_DISPLAYS_TEXT_P (current_row))
18624 row = current_row;
18627 eassert (row != NULL);
18628 w->window_end_vpos = vpos + 1;
18629 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
18630 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
18631 eassert (w->window_end_bytepos >= 0);
18632 IF_DEBUG (debug_method_add (w, "C"));
18634 else
18635 emacs_abort ();
18637 IF_DEBUG ((debug_end_pos = w->window_end_pos,
18638 debug_end_vpos = w->window_end_vpos));
18640 /* Record that display has not been completed. */
18641 w->window_end_valid = 0;
18642 w->desired_matrix->no_scrolling_p = 1;
18643 return 3;
18645 #undef GIVE_UP
18650 /***********************************************************************
18651 More debugging support
18652 ***********************************************************************/
18654 #ifdef GLYPH_DEBUG
18656 void dump_glyph_row (struct glyph_row *, int, int) EXTERNALLY_VISIBLE;
18657 void dump_glyph_matrix (struct glyph_matrix *, int) EXTERNALLY_VISIBLE;
18658 void dump_glyph (struct glyph_row *, struct glyph *, int) EXTERNALLY_VISIBLE;
18661 /* Dump the contents of glyph matrix MATRIX on stderr.
18663 GLYPHS 0 means don't show glyph contents.
18664 GLYPHS 1 means show glyphs in short form
18665 GLYPHS > 1 means show glyphs in long form. */
18667 void
18668 dump_glyph_matrix (struct glyph_matrix *matrix, int glyphs)
18670 int i;
18671 for (i = 0; i < matrix->nrows; ++i)
18672 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
18676 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
18677 the glyph row and area where the glyph comes from. */
18679 void
18680 dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
18682 if (glyph->type == CHAR_GLYPH
18683 || glyph->type == GLYPHLESS_GLYPH)
18685 fprintf (stderr,
18686 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
18687 glyph - row->glyphs[TEXT_AREA],
18688 (glyph->type == CHAR_GLYPH
18689 ? 'C'
18690 : 'G'),
18691 glyph->charpos,
18692 (BUFFERP (glyph->object)
18693 ? 'B'
18694 : (STRINGP (glyph->object)
18695 ? 'S'
18696 : (INTEGERP (glyph->object)
18697 ? '0'
18698 : '-'))),
18699 glyph->pixel_width,
18700 glyph->u.ch,
18701 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
18702 ? glyph->u.ch
18703 : '.'),
18704 glyph->face_id,
18705 glyph->left_box_line_p,
18706 glyph->right_box_line_p);
18708 else if (glyph->type == STRETCH_GLYPH)
18710 fprintf (stderr,
18711 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
18712 glyph - row->glyphs[TEXT_AREA],
18713 'S',
18714 glyph->charpos,
18715 (BUFFERP (glyph->object)
18716 ? 'B'
18717 : (STRINGP (glyph->object)
18718 ? 'S'
18719 : (INTEGERP (glyph->object)
18720 ? '0'
18721 : '-'))),
18722 glyph->pixel_width,
18724 ' ',
18725 glyph->face_id,
18726 glyph->left_box_line_p,
18727 glyph->right_box_line_p);
18729 else if (glyph->type == IMAGE_GLYPH)
18731 fprintf (stderr,
18732 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
18733 glyph - row->glyphs[TEXT_AREA],
18734 'I',
18735 glyph->charpos,
18736 (BUFFERP (glyph->object)
18737 ? 'B'
18738 : (STRINGP (glyph->object)
18739 ? 'S'
18740 : (INTEGERP (glyph->object)
18741 ? '0'
18742 : '-'))),
18743 glyph->pixel_width,
18744 glyph->u.img_id,
18745 '.',
18746 glyph->face_id,
18747 glyph->left_box_line_p,
18748 glyph->right_box_line_p);
18750 else if (glyph->type == COMPOSITE_GLYPH)
18752 fprintf (stderr,
18753 " %5"pD"d %c %9"pI"d %c %3d 0x%06x",
18754 glyph - row->glyphs[TEXT_AREA],
18755 '+',
18756 glyph->charpos,
18757 (BUFFERP (glyph->object)
18758 ? 'B'
18759 : (STRINGP (glyph->object)
18760 ? 'S'
18761 : (INTEGERP (glyph->object)
18762 ? '0'
18763 : '-'))),
18764 glyph->pixel_width,
18765 glyph->u.cmp.id);
18766 if (glyph->u.cmp.automatic)
18767 fprintf (stderr,
18768 "[%d-%d]",
18769 glyph->slice.cmp.from, glyph->slice.cmp.to);
18770 fprintf (stderr, " . %4d %1.1d%1.1d\n",
18771 glyph->face_id,
18772 glyph->left_box_line_p,
18773 glyph->right_box_line_p);
18775 #ifdef HAVE_XWIDGETS
18776 else if (glyph->type == XWIDGET_GLYPH)
18778 fprintf (stderr,
18779 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
18780 glyph - row->glyphs[TEXT_AREA],
18781 'X',
18782 glyph->charpos,
18783 (BUFFERP (glyph->object)
18784 ? 'B'
18785 : (STRINGP (glyph->object)
18786 ? 'S'
18787 : '-')),
18788 glyph->pixel_width,
18789 glyph->u.xwidget,
18790 '.',
18791 glyph->face_id,
18792 glyph->left_box_line_p,
18793 glyph->right_box_line_p);
18795 // printf("dump xwidget glyph\n");
18797 #endif
18801 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
18802 GLYPHS 0 means don't show glyph contents.
18803 GLYPHS 1 means show glyphs in short form
18804 GLYPHS > 1 means show glyphs in long form. */
18806 void
18807 dump_glyph_row (struct glyph_row *row, int vpos, int glyphs)
18809 if (glyphs != 1)
18811 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
18812 fprintf (stderr, "==============================================================================\n");
18814 fprintf (stderr, "%3d %9"pI"d %9"pI"d %4d %1.1d%1.1d%1.1d%1.1d\
18815 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
18816 vpos,
18817 MATRIX_ROW_START_CHARPOS (row),
18818 MATRIX_ROW_END_CHARPOS (row),
18819 row->used[TEXT_AREA],
18820 row->contains_overlapping_glyphs_p,
18821 row->enabled_p,
18822 row->truncated_on_left_p,
18823 row->truncated_on_right_p,
18824 row->continued_p,
18825 MATRIX_ROW_CONTINUATION_LINE_P (row),
18826 MATRIX_ROW_DISPLAYS_TEXT_P (row),
18827 row->ends_at_zv_p,
18828 row->fill_line_p,
18829 row->ends_in_middle_of_char_p,
18830 row->starts_in_middle_of_char_p,
18831 row->mouse_face_p,
18832 row->x,
18833 row->y,
18834 row->pixel_width,
18835 row->height,
18836 row->visible_height,
18837 row->ascent,
18838 row->phys_ascent);
18839 /* The next 3 lines should align to "Start" in the header. */
18840 fprintf (stderr, " %9"pD"d %9"pD"d\t%5d\n", row->start.overlay_string_index,
18841 row->end.overlay_string_index,
18842 row->continuation_lines_width);
18843 fprintf (stderr, " %9"pI"d %9"pI"d\n",
18844 CHARPOS (row->start.string_pos),
18845 CHARPOS (row->end.string_pos));
18846 fprintf (stderr, " %9d %9d\n", row->start.dpvec_index,
18847 row->end.dpvec_index);
18850 if (glyphs > 1)
18852 int area;
18854 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18856 struct glyph *glyph = row->glyphs[area];
18857 struct glyph *glyph_end = glyph + row->used[area];
18859 /* Glyph for a line end in text. */
18860 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
18861 ++glyph_end;
18863 if (glyph < glyph_end)
18864 fprintf (stderr, " Glyph# Type Pos O W Code C Face LR\n");
18866 for (; glyph < glyph_end; ++glyph)
18867 dump_glyph (row, glyph, area);
18870 else if (glyphs == 1)
18872 int area;
18873 char s[SHRT_MAX + 4];
18875 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18877 int i;
18879 for (i = 0; i < row->used[area]; ++i)
18881 struct glyph *glyph = row->glyphs[area] + i;
18882 if (i == row->used[area] - 1
18883 && area == TEXT_AREA
18884 && INTEGERP (glyph->object)
18885 && glyph->type == CHAR_GLYPH
18886 && glyph->u.ch == ' ')
18888 strcpy (&s[i], "[\\n]");
18889 i += 4;
18891 else if (glyph->type == CHAR_GLYPH
18892 && glyph->u.ch < 0x80
18893 && glyph->u.ch >= ' ')
18894 s[i] = glyph->u.ch;
18895 else
18896 s[i] = '.';
18899 s[i] = '\0';
18900 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
18906 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
18907 Sdump_glyph_matrix, 0, 1, "p",
18908 doc: /* Dump the current matrix of the selected window to stderr.
18909 Shows contents of glyph row structures. With non-nil
18910 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
18911 glyphs in short form, otherwise show glyphs in long form.
18913 Interactively, no argument means show glyphs in short form;
18914 with numeric argument, its value is passed as the GLYPHS flag. */)
18915 (Lisp_Object glyphs)
18917 struct window *w = XWINDOW (selected_window);
18918 struct buffer *buffer = XBUFFER (w->contents);
18920 fprintf (stderr, "PT = %"pI"d, BEGV = %"pI"d. ZV = %"pI"d\n",
18921 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
18922 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
18923 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
18924 fprintf (stderr, "=============================================\n");
18925 dump_glyph_matrix (w->current_matrix,
18926 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 0);
18927 return Qnil;
18931 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
18932 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* Dump the current glyph matrix of the selected frame to stderr.
18933 Only text-mode frames have frame glyph matrices. */)
18934 (void)
18936 struct frame *f = XFRAME (selected_frame);
18938 if (f->current_matrix)
18939 dump_glyph_matrix (f->current_matrix, 1);
18940 else
18941 fprintf (stderr, "*** This frame doesn't have a frame glyph matrix ***\n");
18942 return Qnil;
18946 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
18947 doc: /* Dump glyph row ROW to stderr.
18948 GLYPH 0 means don't dump glyphs.
18949 GLYPH 1 means dump glyphs in short form.
18950 GLYPH > 1 or omitted means dump glyphs in long form. */)
18951 (Lisp_Object row, Lisp_Object glyphs)
18953 struct glyph_matrix *matrix;
18954 EMACS_INT vpos;
18956 CHECK_NUMBER (row);
18957 matrix = XWINDOW (selected_window)->current_matrix;
18958 vpos = XINT (row);
18959 if (vpos >= 0 && vpos < matrix->nrows)
18960 dump_glyph_row (MATRIX_ROW (matrix, vpos),
18961 vpos,
18962 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
18963 return Qnil;
18967 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
18968 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
18969 GLYPH 0 means don't dump glyphs.
18970 GLYPH 1 means dump glyphs in short form.
18971 GLYPH > 1 or omitted means dump glyphs in long form.
18973 If there's no tool-bar, or if the tool-bar is not drawn by Emacs,
18974 do nothing. */)
18975 (Lisp_Object row, Lisp_Object glyphs)
18977 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
18978 struct frame *sf = SELECTED_FRAME ();
18979 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
18980 EMACS_INT vpos;
18982 CHECK_NUMBER (row);
18983 vpos = XINT (row);
18984 if (vpos >= 0 && vpos < m->nrows)
18985 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
18986 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
18987 #endif
18988 return Qnil;
18992 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
18993 doc: /* Toggle tracing of redisplay.
18994 With ARG, turn tracing on if and only if ARG is positive. */)
18995 (Lisp_Object arg)
18997 if (NILP (arg))
18998 trace_redisplay_p = !trace_redisplay_p;
18999 else
19001 arg = Fprefix_numeric_value (arg);
19002 trace_redisplay_p = XINT (arg) > 0;
19005 return Qnil;
19009 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
19010 doc: /* Like `format', but print result to stderr.
19011 usage: (trace-to-stderr STRING &rest OBJECTS) */)
19012 (ptrdiff_t nargs, Lisp_Object *args)
19014 Lisp_Object s = Fformat (nargs, args);
19015 fprintf (stderr, "%s", SDATA (s));
19016 return Qnil;
19019 #endif /* GLYPH_DEBUG */
19023 /***********************************************************************
19024 Building Desired Matrix Rows
19025 ***********************************************************************/
19027 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
19028 Used for non-window-redisplay windows, and for windows w/o left fringe. */
19030 static struct glyph_row *
19031 get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
19033 struct frame *f = XFRAME (WINDOW_FRAME (w));
19034 struct buffer *buffer = XBUFFER (w->contents);
19035 struct buffer *old = current_buffer;
19036 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
19037 ptrdiff_t arrow_len = SCHARS (overlay_arrow_string);
19038 const unsigned char *arrow_end = arrow_string + arrow_len;
19039 const unsigned char *p;
19040 struct it it;
19041 bool multibyte_p;
19042 int n_glyphs_before;
19044 set_buffer_temp (buffer);
19045 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
19046 scratch_glyph_row.reversed_p = false;
19047 it.glyph_row->used[TEXT_AREA] = 0;
19048 SET_TEXT_POS (it.position, 0, 0);
19050 multibyte_p = !NILP (BVAR (buffer, enable_multibyte_characters));
19051 p = arrow_string;
19052 while (p < arrow_end)
19054 Lisp_Object face, ilisp;
19056 /* Get the next character. */
19057 if (multibyte_p)
19058 it.c = it.char_to_display = string_char_and_length (p, &it.len);
19059 else
19061 it.c = it.char_to_display = *p, it.len = 1;
19062 if (! ASCII_CHAR_P (it.c))
19063 it.char_to_display = BYTE8_TO_CHAR (it.c);
19065 p += it.len;
19067 /* Get its face. */
19068 ilisp = make_number (p - arrow_string);
19069 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
19070 it.face_id = compute_char_face (f, it.char_to_display, face);
19072 /* Compute its width, get its glyphs. */
19073 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
19074 SET_TEXT_POS (it.position, -1, -1);
19075 PRODUCE_GLYPHS (&it);
19077 /* If this character doesn't fit any more in the line, we have
19078 to remove some glyphs. */
19079 if (it.current_x > it.last_visible_x)
19081 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
19082 break;
19086 set_buffer_temp (old);
19087 return it.glyph_row;
19091 /* Insert truncation glyphs at the start of IT->glyph_row. Which
19092 glyphs to insert is determined by produce_special_glyphs. */
19094 static void
19095 insert_left_trunc_glyphs (struct it *it)
19097 struct it truncate_it;
19098 struct glyph *from, *end, *to, *toend;
19100 eassert (!FRAME_WINDOW_P (it->f)
19101 || (!it->glyph_row->reversed_p
19102 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)
19103 || (it->glyph_row->reversed_p
19104 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0));
19106 /* Get the truncation glyphs. */
19107 truncate_it = *it;
19108 truncate_it.current_x = 0;
19109 truncate_it.face_id = DEFAULT_FACE_ID;
19110 truncate_it.glyph_row = &scratch_glyph_row;
19111 truncate_it.area = TEXT_AREA;
19112 truncate_it.glyph_row->used[TEXT_AREA] = 0;
19113 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
19114 truncate_it.object = make_number (0);
19115 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
19117 /* Overwrite glyphs from IT with truncation glyphs. */
19118 if (!it->glyph_row->reversed_p)
19120 short tused = truncate_it.glyph_row->used[TEXT_AREA];
19122 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
19123 end = from + tused;
19124 to = it->glyph_row->glyphs[TEXT_AREA];
19125 toend = to + it->glyph_row->used[TEXT_AREA];
19126 if (FRAME_WINDOW_P (it->f))
19128 /* On GUI frames, when variable-size fonts are displayed,
19129 the truncation glyphs may need more pixels than the row's
19130 glyphs they overwrite. We overwrite more glyphs to free
19131 enough screen real estate, and enlarge the stretch glyph
19132 on the right (see display_line), if there is one, to
19133 preserve the screen position of the truncation glyphs on
19134 the right. */
19135 int w = 0;
19136 struct glyph *g = to;
19137 short used;
19139 /* The first glyph could be partially visible, in which case
19140 it->glyph_row->x will be negative. But we want the left
19141 truncation glyphs to be aligned at the left margin of the
19142 window, so we override the x coordinate at which the row
19143 will begin. */
19144 it->glyph_row->x = 0;
19145 while (g < toend && w < it->truncation_pixel_width)
19147 w += g->pixel_width;
19148 ++g;
19150 if (g - to - tused > 0)
19152 memmove (to + tused, g, (toend - g) * sizeof(*g));
19153 it->glyph_row->used[TEXT_AREA] -= g - to - tused;
19155 used = it->glyph_row->used[TEXT_AREA];
19156 if (it->glyph_row->truncated_on_right_p
19157 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
19158 && it->glyph_row->glyphs[TEXT_AREA][used - 2].type
19159 == STRETCH_GLYPH)
19161 int extra = w - it->truncation_pixel_width;
19163 it->glyph_row->glyphs[TEXT_AREA][used - 2].pixel_width += extra;
19167 while (from < end)
19168 *to++ = *from++;
19170 /* There may be padding glyphs left over. Overwrite them too. */
19171 if (!FRAME_WINDOW_P (it->f))
19173 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
19175 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
19176 while (from < end)
19177 *to++ = *from++;
19181 if (to > toend)
19182 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
19184 else
19186 short tused = truncate_it.glyph_row->used[TEXT_AREA];
19188 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
19189 that back to front. */
19190 end = truncate_it.glyph_row->glyphs[TEXT_AREA];
19191 from = end + truncate_it.glyph_row->used[TEXT_AREA] - 1;
19192 toend = it->glyph_row->glyphs[TEXT_AREA];
19193 to = toend + it->glyph_row->used[TEXT_AREA] - 1;
19194 if (FRAME_WINDOW_P (it->f))
19196 int w = 0;
19197 struct glyph *g = to;
19199 while (g >= toend && w < it->truncation_pixel_width)
19201 w += g->pixel_width;
19202 --g;
19204 if (to - g - tused > 0)
19205 to = g + tused;
19206 if (it->glyph_row->truncated_on_right_p
19207 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0
19208 && it->glyph_row->glyphs[TEXT_AREA][1].type == STRETCH_GLYPH)
19210 int extra = w - it->truncation_pixel_width;
19212 it->glyph_row->glyphs[TEXT_AREA][1].pixel_width += extra;
19216 while (from >= end && to >= toend)
19217 *to-- = *from--;
19218 if (!FRAME_WINDOW_P (it->f))
19220 while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
19222 from =
19223 truncate_it.glyph_row->glyphs[TEXT_AREA]
19224 + truncate_it.glyph_row->used[TEXT_AREA] - 1;
19225 while (from >= end && to >= toend)
19226 *to-- = *from--;
19229 if (from >= end)
19231 /* Need to free some room before prepending additional
19232 glyphs. */
19233 int move_by = from - end + 1;
19234 struct glyph *g0 = it->glyph_row->glyphs[TEXT_AREA];
19235 struct glyph *g = g0 + it->glyph_row->used[TEXT_AREA] - 1;
19237 for ( ; g >= g0; g--)
19238 g[move_by] = *g;
19239 while (from >= end)
19240 *to-- = *from--;
19241 it->glyph_row->used[TEXT_AREA] += move_by;
19246 /* Compute the hash code for ROW. */
19247 unsigned
19248 row_hash (struct glyph_row *row)
19250 int area, k;
19251 unsigned hashval = 0;
19253 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
19254 for (k = 0; k < row->used[area]; ++k)
19255 hashval = ((((hashval << 4) + (hashval >> 24)) & 0x0fffffff)
19256 + row->glyphs[area][k].u.val
19257 + row->glyphs[area][k].face_id
19258 + row->glyphs[area][k].padding_p
19259 + (row->glyphs[area][k].type << 2));
19261 return hashval;
19264 /* Compute the pixel height and width of IT->glyph_row.
19266 Most of the time, ascent and height of a display line will be equal
19267 to the max_ascent and max_height values of the display iterator
19268 structure. This is not the case if
19270 1. We hit ZV without displaying anything. In this case, max_ascent
19271 and max_height will be zero.
19273 2. We have some glyphs that don't contribute to the line height.
19274 (The glyph row flag contributes_to_line_height_p is for future
19275 pixmap extensions).
19277 The first case is easily covered by using default values because in
19278 these cases, the line height does not really matter, except that it
19279 must not be zero. */
19281 static void
19282 compute_line_metrics (struct it *it)
19284 struct glyph_row *row = it->glyph_row;
19286 if (FRAME_WINDOW_P (it->f))
19288 int i, min_y, max_y;
19290 /* The line may consist of one space only, that was added to
19291 place the cursor on it. If so, the row's height hasn't been
19292 computed yet. */
19293 if (row->height == 0)
19295 if (it->max_ascent + it->max_descent == 0)
19296 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
19297 row->ascent = it->max_ascent;
19298 row->height = it->max_ascent + it->max_descent;
19299 row->phys_ascent = it->max_phys_ascent;
19300 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
19301 row->extra_line_spacing = it->max_extra_line_spacing;
19304 /* Compute the width of this line. */
19305 row->pixel_width = row->x;
19306 for (i = 0; i < row->used[TEXT_AREA]; ++i)
19307 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
19309 eassert (row->pixel_width >= 0);
19310 eassert (row->ascent >= 0 && row->height > 0);
19312 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
19313 || MATRIX_ROW_OVERLAPS_PRED_P (row));
19315 /* If first line's physical ascent is larger than its logical
19316 ascent, use the physical ascent, and make the row taller.
19317 This makes accented characters fully visible. */
19318 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
19319 && row->phys_ascent > row->ascent)
19321 row->height += row->phys_ascent - row->ascent;
19322 row->ascent = row->phys_ascent;
19325 /* Compute how much of the line is visible. */
19326 row->visible_height = row->height;
19328 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
19329 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
19331 if (row->y < min_y)
19332 row->visible_height -= min_y - row->y;
19333 if (row->y + row->height > max_y)
19334 row->visible_height -= row->y + row->height - max_y;
19336 else
19338 row->pixel_width = row->used[TEXT_AREA];
19339 if (row->continued_p)
19340 row->pixel_width -= it->continuation_pixel_width;
19341 else if (row->truncated_on_right_p)
19342 row->pixel_width -= it->truncation_pixel_width;
19343 row->ascent = row->phys_ascent = 0;
19344 row->height = row->phys_height = row->visible_height = 1;
19345 row->extra_line_spacing = 0;
19348 /* Compute a hash code for this row. */
19349 row->hash = row_hash (row);
19351 it->max_ascent = it->max_descent = 0;
19352 it->max_phys_ascent = it->max_phys_descent = 0;
19356 /* Append one space to the glyph row of iterator IT if doing a
19357 window-based redisplay. The space has the same face as
19358 IT->face_id. Value is non-zero if a space was added.
19360 This function is called to make sure that there is always one glyph
19361 at the end of a glyph row that the cursor can be set on under
19362 window-systems. (If there weren't such a glyph we would not know
19363 how wide and tall a box cursor should be displayed).
19365 At the same time this space let's a nicely handle clearing to the
19366 end of the line if the row ends in italic text. */
19368 static int
19369 append_space_for_newline (struct it *it, int default_face_p)
19371 if (FRAME_WINDOW_P (it->f))
19373 int n = it->glyph_row->used[TEXT_AREA];
19375 if (it->glyph_row->glyphs[TEXT_AREA] + n
19376 < it->glyph_row->glyphs[1 + TEXT_AREA])
19378 /* Save some values that must not be changed.
19379 Must save IT->c and IT->len because otherwise
19380 ITERATOR_AT_END_P wouldn't work anymore after
19381 append_space_for_newline has been called. */
19382 enum display_element_type saved_what = it->what;
19383 int saved_c = it->c, saved_len = it->len;
19384 int saved_char_to_display = it->char_to_display;
19385 int saved_x = it->current_x;
19386 int saved_face_id = it->face_id;
19387 int saved_box_end = it->end_of_box_run_p;
19388 struct text_pos saved_pos;
19389 Lisp_Object saved_object;
19390 struct face *face;
19392 saved_object = it->object;
19393 saved_pos = it->position;
19395 it->what = IT_CHARACTER;
19396 memset (&it->position, 0, sizeof it->position);
19397 it->object = make_number (0);
19398 it->c = it->char_to_display = ' ';
19399 it->len = 1;
19401 /* If the default face was remapped, be sure to use the
19402 remapped face for the appended newline. */
19403 if (default_face_p)
19404 it->face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
19405 else if (it->face_before_selective_p)
19406 it->face_id = it->saved_face_id;
19407 face = FACE_FROM_ID (it->f, it->face_id);
19408 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
19409 /* In R2L rows, we will prepend a stretch glyph that will
19410 have the end_of_box_run_p flag set for it, so there's no
19411 need for the appended newline glyph to have that flag
19412 set. */
19413 if (it->glyph_row->reversed_p
19414 /* But if the appended newline glyph goes all the way to
19415 the end of the row, there will be no stretch glyph,
19416 so leave the box flag set. */
19417 && saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x)
19418 it->end_of_box_run_p = 0;
19420 PRODUCE_GLYPHS (it);
19422 it->override_ascent = -1;
19423 it->constrain_row_ascent_descent_p = 0;
19424 it->current_x = saved_x;
19425 it->object = saved_object;
19426 it->position = saved_pos;
19427 it->what = saved_what;
19428 it->face_id = saved_face_id;
19429 it->len = saved_len;
19430 it->c = saved_c;
19431 it->char_to_display = saved_char_to_display;
19432 it->end_of_box_run_p = saved_box_end;
19433 return 1;
19437 return 0;
19441 /* Extend the face of the last glyph in the text area of IT->glyph_row
19442 to the end of the display line. Called from display_line. If the
19443 glyph row is empty, add a space glyph to it so that we know the
19444 face to draw. Set the glyph row flag fill_line_p. If the glyph
19445 row is R2L, prepend a stretch glyph to cover the empty space to the
19446 left of the leftmost glyph. */
19448 static void
19449 extend_face_to_end_of_line (struct it *it)
19451 struct face *face, *default_face;
19452 struct frame *f = it->f;
19454 /* If line is already filled, do nothing. Non window-system frames
19455 get a grace of one more ``pixel'' because their characters are
19456 1-``pixel'' wide, so they hit the equality too early. This grace
19457 is needed only for R2L rows that are not continued, to produce
19458 one extra blank where we could display the cursor. */
19459 if ((it->current_x >= it->last_visible_x
19460 + (!FRAME_WINDOW_P (f)
19461 && it->glyph_row->reversed_p
19462 && !it->glyph_row->continued_p))
19463 /* If the window has display margins, we will need to extend
19464 their face even if the text area is filled. */
19465 && !(WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
19466 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0))
19467 return;
19469 /* The default face, possibly remapped. */
19470 default_face = FACE_FROM_ID (f, lookup_basic_face (f, DEFAULT_FACE_ID));
19472 /* Face extension extends the background and box of IT->face_id
19473 to the end of the line. If the background equals the background
19474 of the frame, we don't have to do anything. */
19475 if (it->face_before_selective_p)
19476 face = FACE_FROM_ID (f, it->saved_face_id);
19477 else
19478 face = FACE_FROM_ID (f, it->face_id);
19480 if (FRAME_WINDOW_P (f)
19481 && MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row)
19482 && face->box == FACE_NO_BOX
19483 && face->background == FRAME_BACKGROUND_PIXEL (f)
19484 #ifdef HAVE_WINDOW_SYSTEM
19485 && !face->stipple
19486 #endif
19487 && !it->glyph_row->reversed_p)
19488 return;
19490 /* Set the glyph row flag indicating that the face of the last glyph
19491 in the text area has to be drawn to the end of the text area. */
19492 it->glyph_row->fill_line_p = 1;
19494 /* If current character of IT is not ASCII, make sure we have the
19495 ASCII face. This will be automatically undone the next time
19496 get_next_display_element returns a multibyte character. Note
19497 that the character will always be single byte in unibyte
19498 text. */
19499 if (!ASCII_CHAR_P (it->c))
19501 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
19504 if (FRAME_WINDOW_P (f))
19506 /* If the row is empty, add a space with the current face of IT,
19507 so that we know which face to draw. */
19508 if (it->glyph_row->used[TEXT_AREA] == 0)
19510 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
19511 it->glyph_row->glyphs[TEXT_AREA][0].face_id = face->id;
19512 it->glyph_row->used[TEXT_AREA] = 1;
19514 /* Mode line and the header line don't have margins, and
19515 likewise the frame's tool-bar window, if there is any. */
19516 if (!(it->glyph_row->mode_line_p
19517 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
19518 || (WINDOWP (f->tool_bar_window)
19519 && it->w == XWINDOW (f->tool_bar_window))
19520 #endif
19523 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
19524 && it->glyph_row->used[LEFT_MARGIN_AREA] == 0)
19526 it->glyph_row->glyphs[LEFT_MARGIN_AREA][0] = space_glyph;
19527 it->glyph_row->glyphs[LEFT_MARGIN_AREA][0].face_id =
19528 default_face->id;
19529 it->glyph_row->used[LEFT_MARGIN_AREA] = 1;
19531 if (WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0
19532 && it->glyph_row->used[RIGHT_MARGIN_AREA] == 0)
19534 it->glyph_row->glyphs[RIGHT_MARGIN_AREA][0] = space_glyph;
19535 it->glyph_row->glyphs[RIGHT_MARGIN_AREA][0].face_id =
19536 default_face->id;
19537 it->glyph_row->used[RIGHT_MARGIN_AREA] = 1;
19540 #ifdef HAVE_WINDOW_SYSTEM
19541 if (it->glyph_row->reversed_p)
19543 /* Prepend a stretch glyph to the row, such that the
19544 rightmost glyph will be drawn flushed all the way to the
19545 right margin of the window. The stretch glyph that will
19546 occupy the empty space, if any, to the left of the
19547 glyphs. */
19548 struct font *font = face->font ? face->font : FRAME_FONT (f);
19549 struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA];
19550 struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA];
19551 struct glyph *g;
19552 int row_width, stretch_ascent, stretch_width;
19553 struct text_pos saved_pos;
19554 int saved_face_id, saved_avoid_cursor, saved_box_start;
19556 for (row_width = 0, g = row_start; g < row_end; g++)
19557 row_width += g->pixel_width;
19559 /* FIXME: There are various minor display glitches in R2L
19560 rows when only one of the fringes is missing. The
19561 strange condition below produces the least bad effect. */
19562 if ((WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)
19563 == (WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0)
19564 || WINDOW_RIGHT_FRINGE_WIDTH (it->w) != 0)
19565 stretch_width = window_box_width (it->w, TEXT_AREA);
19566 else
19567 stretch_width = it->last_visible_x - it->first_visible_x;
19568 stretch_width -= row_width;
19570 if (stretch_width > 0)
19572 stretch_ascent =
19573 (((it->ascent + it->descent)
19574 * FONT_BASE (font)) / FONT_HEIGHT (font));
19575 saved_pos = it->position;
19576 memset (&it->position, 0, sizeof it->position);
19577 saved_avoid_cursor = it->avoid_cursor_p;
19578 it->avoid_cursor_p = 1;
19579 saved_face_id = it->face_id;
19580 saved_box_start = it->start_of_box_run_p;
19581 /* The last row's stretch glyph should get the default
19582 face, to avoid painting the rest of the window with
19583 the region face, if the region ends at ZV. */
19584 if (it->glyph_row->ends_at_zv_p)
19585 it->face_id = default_face->id;
19586 else
19587 it->face_id = face->id;
19588 it->start_of_box_run_p = 0;
19589 append_stretch_glyph (it, make_number (0), stretch_width,
19590 it->ascent + it->descent, stretch_ascent);
19591 it->position = saved_pos;
19592 it->avoid_cursor_p = saved_avoid_cursor;
19593 it->face_id = saved_face_id;
19594 it->start_of_box_run_p = saved_box_start;
19596 /* If stretch_width comes out negative, it means that the
19597 last glyph is only partially visible. In R2L rows, we
19598 want the leftmost glyph to be partially visible, so we
19599 need to give the row the corresponding left offset. */
19600 if (stretch_width < 0)
19601 it->glyph_row->x = stretch_width;
19603 #endif /* HAVE_WINDOW_SYSTEM */
19605 else
19607 /* Save some values that must not be changed. */
19608 int saved_x = it->current_x;
19609 struct text_pos saved_pos;
19610 Lisp_Object saved_object;
19611 enum display_element_type saved_what = it->what;
19612 int saved_face_id = it->face_id;
19614 saved_object = it->object;
19615 saved_pos = it->position;
19617 it->what = IT_CHARACTER;
19618 memset (&it->position, 0, sizeof it->position);
19619 it->object = make_number (0);
19620 it->c = it->char_to_display = ' ';
19621 it->len = 1;
19623 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
19624 && (it->glyph_row->used[LEFT_MARGIN_AREA]
19625 < WINDOW_LEFT_MARGIN_WIDTH (it->w))
19626 && !it->glyph_row->mode_line_p
19627 && default_face->background != FRAME_BACKGROUND_PIXEL (f))
19629 struct glyph *g = it->glyph_row->glyphs[LEFT_MARGIN_AREA];
19630 struct glyph *e = g + it->glyph_row->used[LEFT_MARGIN_AREA];
19632 for (it->current_x = 0; g < e; g++)
19633 it->current_x += g->pixel_width;
19635 it->area = LEFT_MARGIN_AREA;
19636 it->face_id = default_face->id;
19637 while (it->glyph_row->used[LEFT_MARGIN_AREA]
19638 < WINDOW_LEFT_MARGIN_WIDTH (it->w))
19640 PRODUCE_GLYPHS (it);
19641 /* term.c:produce_glyphs advances it->current_x only for
19642 TEXT_AREA. */
19643 it->current_x += it->pixel_width;
19646 it->current_x = saved_x;
19647 it->area = TEXT_AREA;
19650 /* The last row's blank glyphs should get the default face, to
19651 avoid painting the rest of the window with the region face,
19652 if the region ends at ZV. */
19653 if (it->glyph_row->ends_at_zv_p)
19654 it->face_id = default_face->id;
19655 else
19656 it->face_id = face->id;
19657 PRODUCE_GLYPHS (it);
19659 while (it->current_x <= it->last_visible_x)
19660 PRODUCE_GLYPHS (it);
19662 if (WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0
19663 && (it->glyph_row->used[RIGHT_MARGIN_AREA]
19664 < WINDOW_RIGHT_MARGIN_WIDTH (it->w))
19665 && !it->glyph_row->mode_line_p
19666 && default_face->background != FRAME_BACKGROUND_PIXEL (f))
19668 struct glyph *g = it->glyph_row->glyphs[RIGHT_MARGIN_AREA];
19669 struct glyph *e = g + it->glyph_row->used[RIGHT_MARGIN_AREA];
19671 for ( ; g < e; g++)
19672 it->current_x += g->pixel_width;
19674 it->area = RIGHT_MARGIN_AREA;
19675 it->face_id = default_face->id;
19676 while (it->glyph_row->used[RIGHT_MARGIN_AREA]
19677 < WINDOW_RIGHT_MARGIN_WIDTH (it->w))
19679 PRODUCE_GLYPHS (it);
19680 it->current_x += it->pixel_width;
19683 it->area = TEXT_AREA;
19686 /* Don't count these blanks really. It would let us insert a left
19687 truncation glyph below and make us set the cursor on them, maybe. */
19688 it->current_x = saved_x;
19689 it->object = saved_object;
19690 it->position = saved_pos;
19691 it->what = saved_what;
19692 it->face_id = saved_face_id;
19697 /* Value is non-zero if text starting at CHARPOS in current_buffer is
19698 trailing whitespace. */
19700 static int
19701 trailing_whitespace_p (ptrdiff_t charpos)
19703 ptrdiff_t bytepos = CHAR_TO_BYTE (charpos);
19704 int c = 0;
19706 while (bytepos < ZV_BYTE
19707 && (c = FETCH_CHAR (bytepos),
19708 c == ' ' || c == '\t'))
19709 ++bytepos;
19711 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
19713 if (bytepos != PT_BYTE)
19714 return 1;
19716 return 0;
19720 /* Highlight trailing whitespace, if any, in ROW. */
19722 static void
19723 highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
19725 int used = row->used[TEXT_AREA];
19727 if (used)
19729 struct glyph *start = row->glyphs[TEXT_AREA];
19730 struct glyph *glyph = start + used - 1;
19732 if (row->reversed_p)
19734 /* Right-to-left rows need to be processed in the opposite
19735 direction, so swap the edge pointers. */
19736 glyph = start;
19737 start = row->glyphs[TEXT_AREA] + used - 1;
19740 /* Skip over glyphs inserted to display the cursor at the
19741 end of a line, for extending the face of the last glyph
19742 to the end of the line on terminals, and for truncation
19743 and continuation glyphs. */
19744 if (!row->reversed_p)
19746 while (glyph >= start
19747 && glyph->type == CHAR_GLYPH
19748 && INTEGERP (glyph->object))
19749 --glyph;
19751 else
19753 while (glyph <= start
19754 && glyph->type == CHAR_GLYPH
19755 && INTEGERP (glyph->object))
19756 ++glyph;
19759 /* If last glyph is a space or stretch, and it's trailing
19760 whitespace, set the face of all trailing whitespace glyphs in
19761 IT->glyph_row to `trailing-whitespace'. */
19762 if ((row->reversed_p ? glyph <= start : glyph >= start)
19763 && BUFFERP (glyph->object)
19764 && (glyph->type == STRETCH_GLYPH
19765 || (glyph->type == CHAR_GLYPH
19766 && glyph->u.ch == ' '))
19767 && trailing_whitespace_p (glyph->charpos))
19769 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
19770 if (face_id < 0)
19771 return;
19773 if (!row->reversed_p)
19775 while (glyph >= start
19776 && BUFFERP (glyph->object)
19777 && (glyph->type == STRETCH_GLYPH
19778 || (glyph->type == CHAR_GLYPH
19779 && glyph->u.ch == ' ')))
19780 (glyph--)->face_id = face_id;
19782 else
19784 while (glyph <= start
19785 && BUFFERP (glyph->object)
19786 && (glyph->type == STRETCH_GLYPH
19787 || (glyph->type == CHAR_GLYPH
19788 && glyph->u.ch == ' ')))
19789 (glyph++)->face_id = face_id;
19796 /* Value is non-zero if glyph row ROW should be
19797 considered to hold the buffer position CHARPOS. */
19799 static int
19800 row_for_charpos_p (struct glyph_row *row, ptrdiff_t charpos)
19802 int result = 1;
19804 if (charpos == CHARPOS (row->end.pos)
19805 || charpos == MATRIX_ROW_END_CHARPOS (row))
19807 /* Suppose the row ends on a string.
19808 Unless the row is continued, that means it ends on a newline
19809 in the string. If it's anything other than a display string
19810 (e.g., a before-string from an overlay), we don't want the
19811 cursor there. (This heuristic seems to give the optimal
19812 behavior for the various types of multi-line strings.)
19813 One exception: if the string has `cursor' property on one of
19814 its characters, we _do_ want the cursor there. */
19815 if (CHARPOS (row->end.string_pos) >= 0)
19817 if (row->continued_p)
19818 result = 1;
19819 else
19821 /* Check for `display' property. */
19822 struct glyph *beg = row->glyphs[TEXT_AREA];
19823 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
19824 struct glyph *glyph;
19826 result = 0;
19827 for (glyph = end; glyph >= beg; --glyph)
19828 if (STRINGP (glyph->object))
19830 Lisp_Object prop
19831 = Fget_char_property (make_number (charpos),
19832 Qdisplay, Qnil);
19833 result =
19834 (!NILP (prop)
19835 && display_prop_string_p (prop, glyph->object));
19836 /* If there's a `cursor' property on one of the
19837 string's characters, this row is a cursor row,
19838 even though this is not a display string. */
19839 if (!result)
19841 Lisp_Object s = glyph->object;
19843 for ( ; glyph >= beg && EQ (glyph->object, s); --glyph)
19845 ptrdiff_t gpos = glyph->charpos;
19847 if (!NILP (Fget_char_property (make_number (gpos),
19848 Qcursor, s)))
19850 result = 1;
19851 break;
19855 break;
19859 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
19861 /* If the row ends in middle of a real character,
19862 and the line is continued, we want the cursor here.
19863 That's because CHARPOS (ROW->end.pos) would equal
19864 PT if PT is before the character. */
19865 if (!row->ends_in_ellipsis_p)
19866 result = row->continued_p;
19867 else
19868 /* If the row ends in an ellipsis, then
19869 CHARPOS (ROW->end.pos) will equal point after the
19870 invisible text. We want that position to be displayed
19871 after the ellipsis. */
19872 result = 0;
19874 /* If the row ends at ZV, display the cursor at the end of that
19875 row instead of at the start of the row below. */
19876 else if (row->ends_at_zv_p)
19877 result = 1;
19878 else
19879 result = 0;
19882 return result;
19885 /* Value is non-zero if glyph row ROW should be
19886 used to hold the cursor. */
19888 static int
19889 cursor_row_p (struct glyph_row *row)
19891 return row_for_charpos_p (row, PT);
19896 /* Push the property PROP so that it will be rendered at the current
19897 position in IT. Return 1 if PROP was successfully pushed, 0
19898 otherwise. Called from handle_line_prefix to handle the
19899 `line-prefix' and `wrap-prefix' properties. */
19901 static int
19902 push_prefix_prop (struct it *it, Lisp_Object prop)
19904 struct text_pos pos =
19905 STRINGP (it->string) ? it->current.string_pos : it->current.pos;
19907 eassert (it->method == GET_FROM_BUFFER
19908 || it->method == GET_FROM_DISPLAY_VECTOR
19909 || it->method == GET_FROM_STRING);
19911 /* We need to save the current buffer/string position, so it will be
19912 restored by pop_it, because iterate_out_of_display_property
19913 depends on that being set correctly, but some situations leave
19914 it->position not yet set when this function is called. */
19915 push_it (it, &pos);
19917 if (STRINGP (prop))
19919 if (SCHARS (prop) == 0)
19921 pop_it (it);
19922 return 0;
19925 it->string = prop;
19926 it->string_from_prefix_prop_p = 1;
19927 it->multibyte_p = STRING_MULTIBYTE (it->string);
19928 it->current.overlay_string_index = -1;
19929 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
19930 it->end_charpos = it->string_nchars = SCHARS (it->string);
19931 it->method = GET_FROM_STRING;
19932 it->stop_charpos = 0;
19933 it->prev_stop = 0;
19934 it->base_level_stop = 0;
19936 /* Force paragraph direction to be that of the parent
19937 buffer/string. */
19938 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
19939 it->paragraph_embedding = it->bidi_it.paragraph_dir;
19940 else
19941 it->paragraph_embedding = L2R;
19943 /* Set up the bidi iterator for this display string. */
19944 if (it->bidi_p)
19946 it->bidi_it.string.lstring = it->string;
19947 it->bidi_it.string.s = NULL;
19948 it->bidi_it.string.schars = it->end_charpos;
19949 it->bidi_it.string.bufpos = IT_CHARPOS (*it);
19950 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
19951 it->bidi_it.string.unibyte = !it->multibyte_p;
19952 it->bidi_it.w = it->w;
19953 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
19956 else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
19958 it->method = GET_FROM_STRETCH;
19959 it->object = prop;
19961 #ifdef HAVE_WINDOW_SYSTEM
19962 else if (IMAGEP (prop))
19964 it->what = IT_IMAGE;
19965 it->image_id = lookup_image (it->f, prop);
19966 it->method = GET_FROM_IMAGE;
19968 #endif /* HAVE_WINDOW_SYSTEM */
19969 else
19971 pop_it (it); /* bogus display property, give up */
19972 return 0;
19975 return 1;
19978 /* Return the character-property PROP at the current position in IT. */
19980 static Lisp_Object
19981 get_it_property (struct it *it, Lisp_Object prop)
19983 Lisp_Object position, object = it->object;
19985 if (STRINGP (object))
19986 position = make_number (IT_STRING_CHARPOS (*it));
19987 else if (BUFFERP (object))
19989 position = make_number (IT_CHARPOS (*it));
19990 object = it->window;
19992 else
19993 return Qnil;
19995 return Fget_char_property (position, prop, object);
19998 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
20000 static void
20001 handle_line_prefix (struct it *it)
20003 Lisp_Object prefix;
20005 if (it->continuation_lines_width > 0)
20007 prefix = get_it_property (it, Qwrap_prefix);
20008 if (NILP (prefix))
20009 prefix = Vwrap_prefix;
20011 else
20013 prefix = get_it_property (it, Qline_prefix);
20014 if (NILP (prefix))
20015 prefix = Vline_prefix;
20017 if (! NILP (prefix) && push_prefix_prop (it, prefix))
20019 /* If the prefix is wider than the window, and we try to wrap
20020 it, it would acquire its own wrap prefix, and so on till the
20021 iterator stack overflows. So, don't wrap the prefix. */
20022 it->line_wrap = TRUNCATE;
20023 it->avoid_cursor_p = 1;
20029 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
20030 only for R2L lines from display_line and display_string, when they
20031 decide that too many glyphs were produced by PRODUCE_GLYPHS, and
20032 the line/string needs to be continued on the next glyph row. */
20033 static void
20034 unproduce_glyphs (struct it *it, int n)
20036 struct glyph *glyph, *end;
20038 eassert (it->glyph_row);
20039 eassert (it->glyph_row->reversed_p);
20040 eassert (it->area == TEXT_AREA);
20041 eassert (n <= it->glyph_row->used[TEXT_AREA]);
20043 if (n > it->glyph_row->used[TEXT_AREA])
20044 n = it->glyph_row->used[TEXT_AREA];
20045 glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
20046 end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
20047 for ( ; glyph < end; glyph++)
20048 glyph[-n] = *glyph;
20051 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
20052 and ROW->maxpos. */
20053 static void
20054 find_row_edges (struct it *it, struct glyph_row *row,
20055 ptrdiff_t min_pos, ptrdiff_t min_bpos,
20056 ptrdiff_t max_pos, ptrdiff_t max_bpos)
20058 /* FIXME: Revisit this when glyph ``spilling'' in continuation
20059 lines' rows is implemented for bidi-reordered rows. */
20061 /* ROW->minpos is the value of min_pos, the minimal buffer position
20062 we have in ROW, or ROW->start.pos if that is smaller. */
20063 if (min_pos <= ZV && min_pos < row->start.pos.charpos)
20064 SET_TEXT_POS (row->minpos, min_pos, min_bpos);
20065 else
20066 /* We didn't find buffer positions smaller than ROW->start, or
20067 didn't find _any_ valid buffer positions in any of the glyphs,
20068 so we must trust the iterator's computed positions. */
20069 row->minpos = row->start.pos;
20070 if (max_pos <= 0)
20072 max_pos = CHARPOS (it->current.pos);
20073 max_bpos = BYTEPOS (it->current.pos);
20076 /* Here are the various use-cases for ending the row, and the
20077 corresponding values for ROW->maxpos:
20079 Line ends in a newline from buffer eol_pos + 1
20080 Line is continued from buffer max_pos + 1
20081 Line is truncated on right it->current.pos
20082 Line ends in a newline from string max_pos + 1(*)
20083 (*) + 1 only when line ends in a forward scan
20084 Line is continued from string max_pos
20085 Line is continued from display vector max_pos
20086 Line is entirely from a string min_pos == max_pos
20087 Line is entirely from a display vector min_pos == max_pos
20088 Line that ends at ZV ZV
20090 If you discover other use-cases, please add them here as
20091 appropriate. */
20092 if (row->ends_at_zv_p)
20093 row->maxpos = it->current.pos;
20094 else if (row->used[TEXT_AREA])
20096 int seen_this_string = 0;
20097 struct glyph_row *r1 = row - 1;
20099 /* Did we see the same display string on the previous row? */
20100 if (STRINGP (it->object)
20101 /* this is not the first row */
20102 && row > it->w->desired_matrix->rows
20103 /* previous row is not the header line */
20104 && !r1->mode_line_p
20105 /* previous row also ends in a newline from a string */
20106 && r1->ends_in_newline_from_string_p)
20108 struct glyph *start, *end;
20110 /* Search for the last glyph of the previous row that came
20111 from buffer or string. Depending on whether the row is
20112 L2R or R2L, we need to process it front to back or the
20113 other way round. */
20114 if (!r1->reversed_p)
20116 start = r1->glyphs[TEXT_AREA];
20117 end = start + r1->used[TEXT_AREA];
20118 /* Glyphs inserted by redisplay have an integer (zero)
20119 as their object. */
20120 while (end > start
20121 && INTEGERP ((end - 1)->object)
20122 && (end - 1)->charpos <= 0)
20123 --end;
20124 if (end > start)
20126 if (EQ ((end - 1)->object, it->object))
20127 seen_this_string = 1;
20129 else
20130 /* If all the glyphs of the previous row were inserted
20131 by redisplay, it means the previous row was
20132 produced from a single newline, which is only
20133 possible if that newline came from the same string
20134 as the one which produced this ROW. */
20135 seen_this_string = 1;
20137 else
20139 end = r1->glyphs[TEXT_AREA] - 1;
20140 start = end + r1->used[TEXT_AREA];
20141 while (end < start
20142 && INTEGERP ((end + 1)->object)
20143 && (end + 1)->charpos <= 0)
20144 ++end;
20145 if (end < start)
20147 if (EQ ((end + 1)->object, it->object))
20148 seen_this_string = 1;
20150 else
20151 seen_this_string = 1;
20154 /* Take note of each display string that covers a newline only
20155 once, the first time we see it. This is for when a display
20156 string includes more than one newline in it. */
20157 if (row->ends_in_newline_from_string_p && !seen_this_string)
20159 /* If we were scanning the buffer forward when we displayed
20160 the string, we want to account for at least one buffer
20161 position that belongs to this row (position covered by
20162 the display string), so that cursor positioning will
20163 consider this row as a candidate when point is at the end
20164 of the visual line represented by this row. This is not
20165 required when scanning back, because max_pos will already
20166 have a much larger value. */
20167 if (CHARPOS (row->end.pos) > max_pos)
20168 INC_BOTH (max_pos, max_bpos);
20169 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
20171 else if (CHARPOS (it->eol_pos) > 0)
20172 SET_TEXT_POS (row->maxpos,
20173 CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
20174 else if (row->continued_p)
20176 /* If max_pos is different from IT's current position, it
20177 means IT->method does not belong to the display element
20178 at max_pos. However, it also means that the display
20179 element at max_pos was displayed in its entirety on this
20180 line, which is equivalent to saying that the next line
20181 starts at the next buffer position. */
20182 if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
20183 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
20184 else
20186 INC_BOTH (max_pos, max_bpos);
20187 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
20190 else if (row->truncated_on_right_p)
20191 /* display_line already called reseat_at_next_visible_line_start,
20192 which puts the iterator at the beginning of the next line, in
20193 the logical order. */
20194 row->maxpos = it->current.pos;
20195 else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
20196 /* A line that is entirely from a string/image/stretch... */
20197 row->maxpos = row->minpos;
20198 else
20199 emacs_abort ();
20201 else
20202 row->maxpos = it->current.pos;
20205 /* Construct the glyph row IT->glyph_row in the desired matrix of
20206 IT->w from text at the current position of IT. See dispextern.h
20207 for an overview of struct it. Value is non-zero if
20208 IT->glyph_row displays text, as opposed to a line displaying ZV
20209 only. */
20211 static int
20212 display_line (struct it *it)
20214 struct glyph_row *row = it->glyph_row;
20215 Lisp_Object overlay_arrow_string;
20216 struct it wrap_it;
20217 void *wrap_data = NULL;
20218 int may_wrap = 0, wrap_x IF_LINT (= 0);
20219 int wrap_row_used = -1;
20220 int wrap_row_ascent IF_LINT (= 0), wrap_row_height IF_LINT (= 0);
20221 int wrap_row_phys_ascent IF_LINT (= 0), wrap_row_phys_height IF_LINT (= 0);
20222 int wrap_row_extra_line_spacing IF_LINT (= 0);
20223 ptrdiff_t wrap_row_min_pos IF_LINT (= 0), wrap_row_min_bpos IF_LINT (= 0);
20224 ptrdiff_t wrap_row_max_pos IF_LINT (= 0), wrap_row_max_bpos IF_LINT (= 0);
20225 int cvpos;
20226 ptrdiff_t min_pos = ZV + 1, max_pos = 0;
20227 ptrdiff_t min_bpos IF_LINT (= 0), max_bpos IF_LINT (= 0);
20228 bool pending_handle_line_prefix = false;
20230 /* We always start displaying at hpos zero even if hscrolled. */
20231 eassert (it->hpos == 0 && it->current_x == 0);
20233 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
20234 >= it->w->desired_matrix->nrows)
20236 it->w->nrows_scale_factor++;
20237 it->f->fonts_changed = 1;
20238 return 0;
20241 /* Clear the result glyph row and enable it. */
20242 prepare_desired_row (it->w, row, false);
20244 row->y = it->current_y;
20245 row->start = it->start;
20246 row->continuation_lines_width = it->continuation_lines_width;
20247 row->displays_text_p = 1;
20248 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
20249 it->starts_in_middle_of_char_p = 0;
20251 /* Arrange the overlays nicely for our purposes. Usually, we call
20252 display_line on only one line at a time, in which case this
20253 can't really hurt too much, or we call it on lines which appear
20254 one after another in the buffer, in which case all calls to
20255 recenter_overlay_lists but the first will be pretty cheap. */
20256 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
20258 /* Move over display elements that are not visible because we are
20259 hscrolled. This may stop at an x-position < IT->first_visible_x
20260 if the first glyph is partially visible or if we hit a line end. */
20261 if (it->current_x < it->first_visible_x)
20263 enum move_it_result move_result;
20265 this_line_min_pos = row->start.pos;
20266 move_result = move_it_in_display_line_to (it, ZV, it->first_visible_x,
20267 MOVE_TO_POS | MOVE_TO_X);
20268 /* If we are under a large hscroll, move_it_in_display_line_to
20269 could hit the end of the line without reaching
20270 it->first_visible_x. Pretend that we did reach it. This is
20271 especially important on a TTY, where we will call
20272 extend_face_to_end_of_line, which needs to know how many
20273 blank glyphs to produce. */
20274 if (it->current_x < it->first_visible_x
20275 && (move_result == MOVE_NEWLINE_OR_CR
20276 || move_result == MOVE_POS_MATCH_OR_ZV))
20277 it->current_x = it->first_visible_x;
20279 /* Record the smallest positions seen while we moved over
20280 display elements that are not visible. This is needed by
20281 redisplay_internal for optimizing the case where the cursor
20282 stays inside the same line. The rest of this function only
20283 considers positions that are actually displayed, so
20284 RECORD_MAX_MIN_POS will not otherwise record positions that
20285 are hscrolled to the left of the left edge of the window. */
20286 min_pos = CHARPOS (this_line_min_pos);
20287 min_bpos = BYTEPOS (this_line_min_pos);
20289 else if (it->area == TEXT_AREA)
20291 /* We only do this when not calling move_it_in_display_line_to
20292 above, because that function calls itself handle_line_prefix. */
20293 handle_line_prefix (it);
20295 else
20297 /* Line-prefix and wrap-prefix are always displayed in the text
20298 area. But if this is the first call to display_line after
20299 init_iterator, the iterator might have been set up to write
20300 into a marginal area, e.g. if the line begins with some
20301 display property that writes to the margins. So we need to
20302 wait with the call to handle_line_prefix until whatever
20303 writes to the margin has done its job. */
20304 pending_handle_line_prefix = true;
20307 /* Get the initial row height. This is either the height of the
20308 text hscrolled, if there is any, or zero. */
20309 row->ascent = it->max_ascent;
20310 row->height = it->max_ascent + it->max_descent;
20311 row->phys_ascent = it->max_phys_ascent;
20312 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
20313 row->extra_line_spacing = it->max_extra_line_spacing;
20315 /* Utility macro to record max and min buffer positions seen until now. */
20316 #define RECORD_MAX_MIN_POS(IT) \
20317 do \
20319 int composition_p = !STRINGP ((IT)->string) \
20320 && ((IT)->what == IT_COMPOSITION); \
20321 ptrdiff_t current_pos = \
20322 composition_p ? (IT)->cmp_it.charpos \
20323 : IT_CHARPOS (*(IT)); \
20324 ptrdiff_t current_bpos = \
20325 composition_p ? CHAR_TO_BYTE (current_pos) \
20326 : IT_BYTEPOS (*(IT)); \
20327 if (current_pos < min_pos) \
20329 min_pos = current_pos; \
20330 min_bpos = current_bpos; \
20332 if (IT_CHARPOS (*it) > max_pos) \
20334 max_pos = IT_CHARPOS (*it); \
20335 max_bpos = IT_BYTEPOS (*it); \
20338 while (0)
20340 /* Loop generating characters. The loop is left with IT on the next
20341 character to display. */
20342 while (1)
20344 int n_glyphs_before, hpos_before, x_before;
20345 int x, nglyphs;
20346 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
20348 /* Retrieve the next thing to display. Value is zero if end of
20349 buffer reached. */
20350 if (!get_next_display_element (it))
20352 /* Maybe add a space at the end of this line that is used to
20353 display the cursor there under X. Set the charpos of the
20354 first glyph of blank lines not corresponding to any text
20355 to -1. */
20356 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
20357 row->exact_window_width_line_p = 1;
20358 else if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
20359 || row->used[TEXT_AREA] == 0)
20361 row->glyphs[TEXT_AREA]->charpos = -1;
20362 row->displays_text_p = 0;
20364 if (!NILP (BVAR (XBUFFER (it->w->contents), indicate_empty_lines))
20365 && (!MINI_WINDOW_P (it->w)
20366 || (minibuf_level && EQ (it->window, minibuf_window))))
20367 row->indicate_empty_line_p = 1;
20370 it->continuation_lines_width = 0;
20371 row->ends_at_zv_p = 1;
20372 /* A row that displays right-to-left text must always have
20373 its last face extended all the way to the end of line,
20374 even if this row ends in ZV, because we still write to
20375 the screen left to right. We also need to extend the
20376 last face if the default face is remapped to some
20377 different face, otherwise the functions that clear
20378 portions of the screen will clear with the default face's
20379 background color. */
20380 if (row->reversed_p
20381 || lookup_basic_face (it->f, DEFAULT_FACE_ID) != DEFAULT_FACE_ID)
20382 extend_face_to_end_of_line (it);
20383 break;
20386 /* Now, get the metrics of what we want to display. This also
20387 generates glyphs in `row' (which is IT->glyph_row). */
20388 n_glyphs_before = row->used[TEXT_AREA];
20389 x = it->current_x;
20391 /* Remember the line height so far in case the next element doesn't
20392 fit on the line. */
20393 if (it->line_wrap != TRUNCATE)
20395 ascent = it->max_ascent;
20396 descent = it->max_descent;
20397 phys_ascent = it->max_phys_ascent;
20398 phys_descent = it->max_phys_descent;
20400 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
20402 if (IT_DISPLAYING_WHITESPACE (it))
20403 may_wrap = 1;
20404 else if (may_wrap)
20406 SAVE_IT (wrap_it, *it, wrap_data);
20407 wrap_x = x;
20408 wrap_row_used = row->used[TEXT_AREA];
20409 wrap_row_ascent = row->ascent;
20410 wrap_row_height = row->height;
20411 wrap_row_phys_ascent = row->phys_ascent;
20412 wrap_row_phys_height = row->phys_height;
20413 wrap_row_extra_line_spacing = row->extra_line_spacing;
20414 wrap_row_min_pos = min_pos;
20415 wrap_row_min_bpos = min_bpos;
20416 wrap_row_max_pos = max_pos;
20417 wrap_row_max_bpos = max_bpos;
20418 may_wrap = 0;
20423 PRODUCE_GLYPHS (it);
20425 /* If this display element was in marginal areas, continue with
20426 the next one. */
20427 if (it->area != TEXT_AREA)
20429 row->ascent = max (row->ascent, it->max_ascent);
20430 row->height = max (row->height, it->max_ascent + it->max_descent);
20431 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
20432 row->phys_height = max (row->phys_height,
20433 it->max_phys_ascent + it->max_phys_descent);
20434 row->extra_line_spacing = max (row->extra_line_spacing,
20435 it->max_extra_line_spacing);
20436 set_iterator_to_next (it, 1);
20437 /* If we didn't handle the line/wrap prefix above, and the
20438 call to set_iterator_to_next just switched to TEXT_AREA,
20439 process the prefix now. */
20440 if (it->area == TEXT_AREA && pending_handle_line_prefix)
20442 pending_handle_line_prefix = false;
20443 handle_line_prefix (it);
20445 continue;
20448 /* Does the display element fit on the line? If we truncate
20449 lines, we should draw past the right edge of the window. If
20450 we don't truncate, we want to stop so that we can display the
20451 continuation glyph before the right margin. If lines are
20452 continued, there are two possible strategies for characters
20453 resulting in more than 1 glyph (e.g. tabs): Display as many
20454 glyphs as possible in this line and leave the rest for the
20455 continuation line, or display the whole element in the next
20456 line. Original redisplay did the former, so we do it also. */
20457 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
20458 hpos_before = it->hpos;
20459 x_before = x;
20461 if (/* Not a newline. */
20462 nglyphs > 0
20463 /* Glyphs produced fit entirely in the line. */
20464 && it->current_x < it->last_visible_x)
20466 it->hpos += nglyphs;
20467 row->ascent = max (row->ascent, it->max_ascent);
20468 row->height = max (row->height, it->max_ascent + it->max_descent);
20469 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
20470 row->phys_height = max (row->phys_height,
20471 it->max_phys_ascent + it->max_phys_descent);
20472 row->extra_line_spacing = max (row->extra_line_spacing,
20473 it->max_extra_line_spacing);
20474 if (it->current_x - it->pixel_width < it->first_visible_x
20475 /* In R2L rows, we arrange in extend_face_to_end_of_line
20476 to add a right offset to the line, by a suitable
20477 change to the stretch glyph that is the leftmost
20478 glyph of the line. */
20479 && !row->reversed_p)
20480 row->x = x - it->first_visible_x;
20481 /* Record the maximum and minimum buffer positions seen so
20482 far in glyphs that will be displayed by this row. */
20483 if (it->bidi_p)
20484 RECORD_MAX_MIN_POS (it);
20486 else
20488 int i, new_x;
20489 struct glyph *glyph;
20491 for (i = 0; i < nglyphs; ++i, x = new_x)
20493 /* Identify the glyphs added by the last call to
20494 PRODUCE_GLYPHS. In R2L rows, they are prepended to
20495 the previous glyphs. */
20496 if (!row->reversed_p)
20497 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
20498 else
20499 glyph = row->glyphs[TEXT_AREA] + nglyphs - 1 - i;
20500 new_x = x + glyph->pixel_width;
20502 if (/* Lines are continued. */
20503 it->line_wrap != TRUNCATE
20504 && (/* Glyph doesn't fit on the line. */
20505 new_x > it->last_visible_x
20506 /* Or it fits exactly on a window system frame. */
20507 || (new_x == it->last_visible_x
20508 && FRAME_WINDOW_P (it->f)
20509 && (row->reversed_p
20510 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
20511 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
20513 /* End of a continued line. */
20515 if (it->hpos == 0
20516 || (new_x == it->last_visible_x
20517 && FRAME_WINDOW_P (it->f)
20518 && (row->reversed_p
20519 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
20520 : WINDOW_RIGHT_FRINGE_WIDTH (it->w))))
20522 /* Current glyph is the only one on the line or
20523 fits exactly on the line. We must continue
20524 the line because we can't draw the cursor
20525 after the glyph. */
20526 row->continued_p = 1;
20527 it->current_x = new_x;
20528 it->continuation_lines_width += new_x;
20529 ++it->hpos;
20530 if (i == nglyphs - 1)
20532 /* If line-wrap is on, check if a previous
20533 wrap point was found. */
20534 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)
20535 && wrap_row_used > 0
20536 /* Even if there is a previous wrap
20537 point, continue the line here as
20538 usual, if (i) the previous character
20539 was a space or tab AND (ii) the
20540 current character is not. */
20541 && (!may_wrap
20542 || IT_DISPLAYING_WHITESPACE (it)))
20543 goto back_to_wrap;
20545 /* Record the maximum and minimum buffer
20546 positions seen so far in glyphs that will be
20547 displayed by this row. */
20548 if (it->bidi_p)
20549 RECORD_MAX_MIN_POS (it);
20550 set_iterator_to_next (it, 1);
20551 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
20553 if (!get_next_display_element (it))
20555 row->exact_window_width_line_p = 1;
20556 it->continuation_lines_width = 0;
20557 row->continued_p = 0;
20558 row->ends_at_zv_p = 1;
20560 else if (ITERATOR_AT_END_OF_LINE_P (it))
20562 row->continued_p = 0;
20563 row->exact_window_width_line_p = 1;
20565 /* If line-wrap is on, check if a
20566 previous wrap point was found. */
20567 else if (wrap_row_used > 0
20568 /* Even if there is a previous wrap
20569 point, continue the line here as
20570 usual, if (i) the previous character
20571 was a space or tab AND (ii) the
20572 current character is not. */
20573 && (!may_wrap
20574 || IT_DISPLAYING_WHITESPACE (it)))
20575 goto back_to_wrap;
20579 else if (it->bidi_p)
20580 RECORD_MAX_MIN_POS (it);
20581 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
20582 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)
20583 extend_face_to_end_of_line (it);
20585 else if (CHAR_GLYPH_PADDING_P (*glyph)
20586 && !FRAME_WINDOW_P (it->f))
20588 /* A padding glyph that doesn't fit on this line.
20589 This means the whole character doesn't fit
20590 on the line. */
20591 if (row->reversed_p)
20592 unproduce_glyphs (it, row->used[TEXT_AREA]
20593 - n_glyphs_before);
20594 row->used[TEXT_AREA] = n_glyphs_before;
20596 /* Fill the rest of the row with continuation
20597 glyphs like in 20.x. */
20598 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
20599 < row->glyphs[1 + TEXT_AREA])
20600 produce_special_glyphs (it, IT_CONTINUATION);
20602 row->continued_p = 1;
20603 it->current_x = x_before;
20604 it->continuation_lines_width += x_before;
20606 /* Restore the height to what it was before the
20607 element not fitting on the line. */
20608 it->max_ascent = ascent;
20609 it->max_descent = descent;
20610 it->max_phys_ascent = phys_ascent;
20611 it->max_phys_descent = phys_descent;
20612 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
20613 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)
20614 extend_face_to_end_of_line (it);
20616 else if (wrap_row_used > 0)
20618 back_to_wrap:
20619 if (row->reversed_p)
20620 unproduce_glyphs (it,
20621 row->used[TEXT_AREA] - wrap_row_used);
20622 RESTORE_IT (it, &wrap_it, wrap_data);
20623 it->continuation_lines_width += wrap_x;
20624 row->used[TEXT_AREA] = wrap_row_used;
20625 row->ascent = wrap_row_ascent;
20626 row->height = wrap_row_height;
20627 row->phys_ascent = wrap_row_phys_ascent;
20628 row->phys_height = wrap_row_phys_height;
20629 row->extra_line_spacing = wrap_row_extra_line_spacing;
20630 min_pos = wrap_row_min_pos;
20631 min_bpos = wrap_row_min_bpos;
20632 max_pos = wrap_row_max_pos;
20633 max_bpos = wrap_row_max_bpos;
20634 row->continued_p = 1;
20635 row->ends_at_zv_p = 0;
20636 row->exact_window_width_line_p = 0;
20637 it->continuation_lines_width += x;
20639 /* Make sure that a non-default face is extended
20640 up to the right margin of the window. */
20641 extend_face_to_end_of_line (it);
20643 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
20645 /* A TAB that extends past the right edge of the
20646 window. This produces a single glyph on
20647 window system frames. We leave the glyph in
20648 this row and let it fill the row, but don't
20649 consume the TAB. */
20650 if ((row->reversed_p
20651 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
20652 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
20653 produce_special_glyphs (it, IT_CONTINUATION);
20654 it->continuation_lines_width += it->last_visible_x;
20655 row->ends_in_middle_of_char_p = 1;
20656 row->continued_p = 1;
20657 glyph->pixel_width = it->last_visible_x - x;
20658 it->starts_in_middle_of_char_p = 1;
20659 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
20660 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)
20661 extend_face_to_end_of_line (it);
20663 else
20665 /* Something other than a TAB that draws past
20666 the right edge of the window. Restore
20667 positions to values before the element. */
20668 if (row->reversed_p)
20669 unproduce_glyphs (it, row->used[TEXT_AREA]
20670 - (n_glyphs_before + i));
20671 row->used[TEXT_AREA] = n_glyphs_before + i;
20673 /* Display continuation glyphs. */
20674 it->current_x = x_before;
20675 it->continuation_lines_width += x;
20676 if (!FRAME_WINDOW_P (it->f)
20677 || (row->reversed_p
20678 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
20679 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
20680 produce_special_glyphs (it, IT_CONTINUATION);
20681 row->continued_p = 1;
20683 extend_face_to_end_of_line (it);
20685 if (nglyphs > 1 && i > 0)
20687 row->ends_in_middle_of_char_p = 1;
20688 it->starts_in_middle_of_char_p = 1;
20691 /* Restore the height to what it was before the
20692 element not fitting on the line. */
20693 it->max_ascent = ascent;
20694 it->max_descent = descent;
20695 it->max_phys_ascent = phys_ascent;
20696 it->max_phys_descent = phys_descent;
20699 break;
20701 else if (new_x > it->first_visible_x)
20703 /* Increment number of glyphs actually displayed. */
20704 ++it->hpos;
20706 /* Record the maximum and minimum buffer positions
20707 seen so far in glyphs that will be displayed by
20708 this row. */
20709 if (it->bidi_p)
20710 RECORD_MAX_MIN_POS (it);
20712 if (x < it->first_visible_x && !row->reversed_p)
20713 /* Glyph is partially visible, i.e. row starts at
20714 negative X position. Don't do that in R2L
20715 rows, where we arrange to add a right offset to
20716 the line in extend_face_to_end_of_line, by a
20717 suitable change to the stretch glyph that is
20718 the leftmost glyph of the line. */
20719 row->x = x - it->first_visible_x;
20720 /* When the last glyph of an R2L row only fits
20721 partially on the line, we need to set row->x to a
20722 negative offset, so that the leftmost glyph is
20723 the one that is partially visible. But if we are
20724 going to produce the truncation glyph, this will
20725 be taken care of in produce_special_glyphs. */
20726 if (row->reversed_p
20727 && new_x > it->last_visible_x
20728 && !(it->line_wrap == TRUNCATE
20729 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0))
20731 eassert (FRAME_WINDOW_P (it->f));
20732 row->x = it->last_visible_x - new_x;
20735 else
20737 /* Glyph is completely off the left margin of the
20738 window. This should not happen because of the
20739 move_it_in_display_line at the start of this
20740 function, unless the text display area of the
20741 window is empty. */
20742 eassert (it->first_visible_x <= it->last_visible_x);
20745 /* Even if this display element produced no glyphs at all,
20746 we want to record its position. */
20747 if (it->bidi_p && nglyphs == 0)
20748 RECORD_MAX_MIN_POS (it);
20750 row->ascent = max (row->ascent, it->max_ascent);
20751 row->height = max (row->height, it->max_ascent + it->max_descent);
20752 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
20753 row->phys_height = max (row->phys_height,
20754 it->max_phys_ascent + it->max_phys_descent);
20755 row->extra_line_spacing = max (row->extra_line_spacing,
20756 it->max_extra_line_spacing);
20758 /* End of this display line if row is continued. */
20759 if (row->continued_p || row->ends_at_zv_p)
20760 break;
20763 at_end_of_line:
20764 /* Is this a line end? If yes, we're also done, after making
20765 sure that a non-default face is extended up to the right
20766 margin of the window. */
20767 if (ITERATOR_AT_END_OF_LINE_P (it))
20769 int used_before = row->used[TEXT_AREA];
20771 row->ends_in_newline_from_string_p = STRINGP (it->object);
20773 /* Add a space at the end of the line that is used to
20774 display the cursor there. */
20775 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
20776 append_space_for_newline (it, 0);
20778 /* Extend the face to the end of the line. */
20779 extend_face_to_end_of_line (it);
20781 /* Make sure we have the position. */
20782 if (used_before == 0)
20783 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
20785 /* Record the position of the newline, for use in
20786 find_row_edges. */
20787 it->eol_pos = it->current.pos;
20789 /* Consume the line end. This skips over invisible lines. */
20790 set_iterator_to_next (it, 1);
20791 it->continuation_lines_width = 0;
20792 break;
20795 /* Proceed with next display element. Note that this skips
20796 over lines invisible because of selective display. */
20797 set_iterator_to_next (it, 1);
20799 /* If we truncate lines, we are done when the last displayed
20800 glyphs reach past the right margin of the window. */
20801 if (it->line_wrap == TRUNCATE
20802 && ((FRAME_WINDOW_P (it->f)
20803 /* Images are preprocessed in produce_image_glyph such
20804 that they are cropped at the right edge of the
20805 window, so an image glyph will always end exactly at
20806 last_visible_x, even if there's no right fringe. */
20807 && ((row->reversed_p
20808 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
20809 : WINDOW_RIGHT_FRINGE_WIDTH (it->w))
20810 || it->what == IT_IMAGE))
20811 ? (it->current_x >= it->last_visible_x)
20812 : (it->current_x > it->last_visible_x)))
20814 /* Maybe add truncation glyphs. */
20815 if (!FRAME_WINDOW_P (it->f)
20816 || (row->reversed_p
20817 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
20818 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
20820 int i, n;
20822 if (!row->reversed_p)
20824 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
20825 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
20826 break;
20828 else
20830 for (i = 0; i < row->used[TEXT_AREA]; i++)
20831 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
20832 break;
20833 /* Remove any padding glyphs at the front of ROW, to
20834 make room for the truncation glyphs we will be
20835 adding below. The loop below always inserts at
20836 least one truncation glyph, so also remove the
20837 last glyph added to ROW. */
20838 unproduce_glyphs (it, i + 1);
20839 /* Adjust i for the loop below. */
20840 i = row->used[TEXT_AREA] - (i + 1);
20843 /* produce_special_glyphs overwrites the last glyph, so
20844 we don't want that if we want to keep that last
20845 glyph, which means it's an image. */
20846 if (it->current_x > it->last_visible_x)
20848 it->current_x = x_before;
20849 if (!FRAME_WINDOW_P (it->f))
20851 for (n = row->used[TEXT_AREA]; i < n; ++i)
20853 row->used[TEXT_AREA] = i;
20854 produce_special_glyphs (it, IT_TRUNCATION);
20857 else
20859 row->used[TEXT_AREA] = i;
20860 produce_special_glyphs (it, IT_TRUNCATION);
20862 it->hpos = hpos_before;
20865 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
20867 /* Don't truncate if we can overflow newline into fringe. */
20868 if (!get_next_display_element (it))
20870 it->continuation_lines_width = 0;
20871 row->ends_at_zv_p = 1;
20872 row->exact_window_width_line_p = 1;
20873 break;
20875 if (ITERATOR_AT_END_OF_LINE_P (it))
20877 row->exact_window_width_line_p = 1;
20878 goto at_end_of_line;
20880 it->current_x = x_before;
20881 it->hpos = hpos_before;
20884 row->truncated_on_right_p = 1;
20885 it->continuation_lines_width = 0;
20886 reseat_at_next_visible_line_start (it, 0);
20887 /* We insist below that IT's position be at ZV because in
20888 bidi-reordered lines the character at visible line start
20889 might not be the character that follows the newline in
20890 the logical order. */
20891 if (IT_BYTEPOS (*it) > BEG_BYTE)
20892 row->ends_at_zv_p =
20893 IT_BYTEPOS (*it) >= ZV_BYTE && FETCH_BYTE (ZV_BYTE - 1) != '\n';
20894 else
20895 row->ends_at_zv_p = false;
20896 break;
20900 if (wrap_data)
20901 bidi_unshelve_cache (wrap_data, 1);
20903 /* If line is not empty and hscrolled, maybe insert truncation glyphs
20904 at the left window margin. */
20905 if (it->first_visible_x
20906 && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
20908 if (!FRAME_WINDOW_P (it->f)
20909 || (((row->reversed_p
20910 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
20911 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
20912 /* Don't let insert_left_trunc_glyphs overwrite the
20913 first glyph of the row if it is an image. */
20914 && row->glyphs[TEXT_AREA]->type != IMAGE_GLYPH))
20915 insert_left_trunc_glyphs (it);
20916 row->truncated_on_left_p = 1;
20919 /* Remember the position at which this line ends.
20921 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
20922 cannot be before the call to find_row_edges below, since that is
20923 where these positions are determined. */
20924 row->end = it->current;
20925 if (!it->bidi_p)
20927 row->minpos = row->start.pos;
20928 row->maxpos = row->end.pos;
20930 else
20932 /* ROW->minpos and ROW->maxpos must be the smallest and
20933 `1 + the largest' buffer positions in ROW. But if ROW was
20934 bidi-reordered, these two positions can be anywhere in the
20935 row, so we must determine them now. */
20936 find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
20939 /* If the start of this line is the overlay arrow-position, then
20940 mark this glyph row as the one containing the overlay arrow.
20941 This is clearly a mess with variable size fonts. It would be
20942 better to let it be displayed like cursors under X. */
20943 if ((MATRIX_ROW_DISPLAYS_TEXT_P (row) || !overlay_arrow_seen)
20944 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
20945 !NILP (overlay_arrow_string)))
20947 /* Overlay arrow in window redisplay is a fringe bitmap. */
20948 if (STRINGP (overlay_arrow_string))
20950 struct glyph_row *arrow_row
20951 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
20952 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
20953 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
20954 struct glyph *p = row->glyphs[TEXT_AREA];
20955 struct glyph *p2, *end;
20957 /* Copy the arrow glyphs. */
20958 while (glyph < arrow_end)
20959 *p++ = *glyph++;
20961 /* Throw away padding glyphs. */
20962 p2 = p;
20963 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
20964 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
20965 ++p2;
20966 if (p2 > p)
20968 while (p2 < end)
20969 *p++ = *p2++;
20970 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
20973 else
20975 eassert (INTEGERP (overlay_arrow_string));
20976 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
20978 overlay_arrow_seen = 1;
20981 /* Highlight trailing whitespace. */
20982 if (!NILP (Vshow_trailing_whitespace))
20983 highlight_trailing_whitespace (it->f, it->glyph_row);
20985 /* Compute pixel dimensions of this line. */
20986 compute_line_metrics (it);
20988 /* Implementation note: No changes in the glyphs of ROW or in their
20989 faces can be done past this point, because compute_line_metrics
20990 computes ROW's hash value and stores it within the glyph_row
20991 structure. */
20993 /* Record whether this row ends inside an ellipsis. */
20994 row->ends_in_ellipsis_p
20995 = (it->method == GET_FROM_DISPLAY_VECTOR
20996 && it->ellipsis_p);
20998 /* Save fringe bitmaps in this row. */
20999 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
21000 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
21001 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
21002 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
21004 it->left_user_fringe_bitmap = 0;
21005 it->left_user_fringe_face_id = 0;
21006 it->right_user_fringe_bitmap = 0;
21007 it->right_user_fringe_face_id = 0;
21009 /* Maybe set the cursor. */
21010 cvpos = it->w->cursor.vpos;
21011 if ((cvpos < 0
21012 /* In bidi-reordered rows, keep checking for proper cursor
21013 position even if one has been found already, because buffer
21014 positions in such rows change non-linearly with ROW->VPOS,
21015 when a line is continued. One exception: when we are at ZV,
21016 display cursor on the first suitable glyph row, since all
21017 the empty rows after that also have their position set to ZV. */
21018 /* FIXME: Revisit this when glyph ``spilling'' in continuation
21019 lines' rows is implemented for bidi-reordered rows. */
21020 || (it->bidi_p
21021 && !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
21022 && PT >= MATRIX_ROW_START_CHARPOS (row)
21023 && PT <= MATRIX_ROW_END_CHARPOS (row)
21024 && cursor_row_p (row))
21025 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
21027 /* Prepare for the next line. This line starts horizontally at (X
21028 HPOS) = (0 0). Vertical positions are incremented. As a
21029 convenience for the caller, IT->glyph_row is set to the next
21030 row to be used. */
21031 it->current_x = it->hpos = 0;
21032 it->current_y += row->height;
21033 SET_TEXT_POS (it->eol_pos, 0, 0);
21034 ++it->vpos;
21035 ++it->glyph_row;
21036 /* The next row should by default use the same value of the
21037 reversed_p flag as this one. set_iterator_to_next decides when
21038 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
21039 the flag accordingly. */
21040 if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
21041 it->glyph_row->reversed_p = row->reversed_p;
21042 it->start = row->end;
21043 return MATRIX_ROW_DISPLAYS_TEXT_P (row);
21045 #undef RECORD_MAX_MIN_POS
21048 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,
21049 Scurrent_bidi_paragraph_direction, 0, 1, 0,
21050 doc: /* Return paragraph direction at point in BUFFER.
21051 Value is either `left-to-right' or `right-to-left'.
21052 If BUFFER is omitted or nil, it defaults to the current buffer.
21054 Paragraph direction determines how the text in the paragraph is displayed.
21055 In left-to-right paragraphs, text begins at the left margin of the window
21056 and the reading direction is generally left to right. In right-to-left
21057 paragraphs, text begins at the right margin and is read from right to left.
21059 See also `bidi-paragraph-direction'. */)
21060 (Lisp_Object buffer)
21062 struct buffer *buf = current_buffer;
21063 struct buffer *old = buf;
21065 if (! NILP (buffer))
21067 CHECK_BUFFER (buffer);
21068 buf = XBUFFER (buffer);
21071 if (NILP (BVAR (buf, bidi_display_reordering))
21072 || NILP (BVAR (buf, enable_multibyte_characters))
21073 /* When we are loading loadup.el, the character property tables
21074 needed for bidi iteration are not yet available. */
21075 || !NILP (Vpurify_flag))
21076 return Qleft_to_right;
21077 else if (!NILP (BVAR (buf, bidi_paragraph_direction)))
21078 return BVAR (buf, bidi_paragraph_direction);
21079 else
21081 /* Determine the direction from buffer text. We could try to
21082 use current_matrix if it is up to date, but this seems fast
21083 enough as it is. */
21084 struct bidi_it itb;
21085 ptrdiff_t pos = BUF_PT (buf);
21086 ptrdiff_t bytepos = BUF_PT_BYTE (buf);
21087 int c;
21088 void *itb_data = bidi_shelve_cache ();
21090 set_buffer_temp (buf);
21091 /* bidi_paragraph_init finds the base direction of the paragraph
21092 by searching forward from paragraph start. We need the base
21093 direction of the current or _previous_ paragraph, so we need
21094 to make sure we are within that paragraph. To that end, find
21095 the previous non-empty line. */
21096 if (pos >= ZV && pos > BEGV)
21097 DEC_BOTH (pos, bytepos);
21098 AUTO_STRING (trailing_white_space, "[\f\t ]*\n");
21099 if (fast_looking_at (trailing_white_space,
21100 pos, bytepos, ZV, ZV_BYTE, Qnil) > 0)
21102 while ((c = FETCH_BYTE (bytepos)) == '\n'
21103 || c == ' ' || c == '\t' || c == '\f')
21105 if (bytepos <= BEGV_BYTE)
21106 break;
21107 bytepos--;
21108 pos--;
21110 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos)))
21111 bytepos--;
21113 bidi_init_it (pos, bytepos, FRAME_WINDOW_P (SELECTED_FRAME ()), &itb);
21114 itb.paragraph_dir = NEUTRAL_DIR;
21115 itb.string.s = NULL;
21116 itb.string.lstring = Qnil;
21117 itb.string.bufpos = 0;
21118 itb.string.from_disp_str = 0;
21119 itb.string.unibyte = 0;
21120 /* We have no window to use here for ignoring window-specific
21121 overlays. Using NULL for window pointer will cause
21122 compute_display_string_pos to use the current buffer. */
21123 itb.w = NULL;
21124 bidi_paragraph_init (NEUTRAL_DIR, &itb, 1);
21125 bidi_unshelve_cache (itb_data, 0);
21126 set_buffer_temp (old);
21127 switch (itb.paragraph_dir)
21129 case L2R:
21130 return Qleft_to_right;
21131 break;
21132 case R2L:
21133 return Qright_to_left;
21134 break;
21135 default:
21136 emacs_abort ();
21141 DEFUN ("bidi-find-overridden-directionality",
21142 Fbidi_find_overridden_directionality,
21143 Sbidi_find_overridden_directionality, 2, 3, 0,
21144 doc: /* Return position between FROM and TO where directionality was overridden.
21146 This function returns the first character position in the specified
21147 region of OBJECT where there is a character whose `bidi-class' property
21148 is `L', but which was forced to display as `R' by a directional
21149 override, and likewise with characters whose `bidi-class' is `R'
21150 or `AL' that were forced to display as `L'.
21152 If no such character is found, the function returns nil.
21154 OBJECT is a Lisp string or buffer to search for overridden
21155 directionality, and defaults to the current buffer if nil or omitted.
21156 OBJECT can also be a window, in which case the function will search
21157 the buffer displayed in that window. Passing the window instead of
21158 a buffer is preferable when the buffer is displayed in some window,
21159 because this function will then be able to correctly account for
21160 window-specific overlays, which can affect the results.
21162 Strong directional characters `L', `R', and `AL' can have their
21163 intrinsic directionality overridden by directional override
21164 control characters RLO \(u+202e) and LRO \(u+202d). See the
21165 function `get-char-code-property' for a way to inquire about
21166 the `bidi-class' property of a character. */)
21167 (Lisp_Object from, Lisp_Object to, Lisp_Object object)
21169 struct buffer *buf = current_buffer;
21170 struct buffer *old = buf;
21171 struct window *w = NULL;
21172 bool frame_window_p = FRAME_WINDOW_P (SELECTED_FRAME ());
21173 struct bidi_it itb;
21174 ptrdiff_t from_pos, to_pos, from_bpos;
21175 void *itb_data;
21177 if (!NILP (object))
21179 if (BUFFERP (object))
21180 buf = XBUFFER (object);
21181 else if (WINDOWP (object))
21183 w = decode_live_window (object);
21184 buf = XBUFFER (w->contents);
21185 frame_window_p = FRAME_WINDOW_P (XFRAME (w->frame));
21187 else
21188 CHECK_STRING (object);
21191 if (STRINGP (object))
21193 /* Characters in unibyte strings are always treated by bidi.c as
21194 strong LTR. */
21195 if (!STRING_MULTIBYTE (object)
21196 /* When we are loading loadup.el, the character property
21197 tables needed for bidi iteration are not yet
21198 available. */
21199 || !NILP (Vpurify_flag))
21200 return Qnil;
21202 validate_subarray (object, from, to, SCHARS (object), &from_pos, &to_pos);
21203 if (from_pos >= SCHARS (object))
21204 return Qnil;
21206 /* Set up the bidi iterator. */
21207 itb_data = bidi_shelve_cache ();
21208 itb.paragraph_dir = NEUTRAL_DIR;
21209 itb.string.lstring = object;
21210 itb.string.s = NULL;
21211 itb.string.schars = SCHARS (object);
21212 itb.string.bufpos = 0;
21213 itb.string.from_disp_str = 0;
21214 itb.string.unibyte = 0;
21215 itb.w = w;
21216 bidi_init_it (0, 0, frame_window_p, &itb);
21218 else
21220 /* Nothing this fancy can happen in unibyte buffers, or in a
21221 buffer that disabled reordering, or if FROM is at EOB. */
21222 if (NILP (BVAR (buf, bidi_display_reordering))
21223 || NILP (BVAR (buf, enable_multibyte_characters))
21224 /* When we are loading loadup.el, the character property
21225 tables needed for bidi iteration are not yet
21226 available. */
21227 || !NILP (Vpurify_flag))
21228 return Qnil;
21230 set_buffer_temp (buf);
21231 validate_region (&from, &to);
21232 from_pos = XINT (from);
21233 to_pos = XINT (to);
21234 if (from_pos >= ZV)
21235 return Qnil;
21237 /* Set up the bidi iterator. */
21238 itb_data = bidi_shelve_cache ();
21239 from_bpos = CHAR_TO_BYTE (from_pos);
21240 if (from_pos == BEGV)
21242 itb.charpos = BEGV;
21243 itb.bytepos = BEGV_BYTE;
21245 else if (FETCH_CHAR (from_bpos - 1) == '\n')
21247 itb.charpos = from_pos;
21248 itb.bytepos = from_bpos;
21250 else
21251 itb.charpos = find_newline_no_quit (from_pos, CHAR_TO_BYTE (from_pos),
21252 -1, &itb.bytepos);
21253 itb.paragraph_dir = NEUTRAL_DIR;
21254 itb.string.s = NULL;
21255 itb.string.lstring = Qnil;
21256 itb.string.bufpos = 0;
21257 itb.string.from_disp_str = 0;
21258 itb.string.unibyte = 0;
21259 itb.w = w;
21260 bidi_init_it (itb.charpos, itb.bytepos, frame_window_p, &itb);
21263 ptrdiff_t found;
21264 do {
21265 /* For the purposes of this function, the actual base direction of
21266 the paragraph doesn't matter, so just set it to L2R. */
21267 bidi_paragraph_init (L2R, &itb, 0);
21268 while ((found = bidi_find_first_overridden (&itb)) < from_pos)
21270 } while (found == ZV && itb.ch == '\n' && itb.charpos < to_pos);
21272 bidi_unshelve_cache (itb_data, 0);
21273 set_buffer_temp (old);
21275 return (from_pos <= found && found < to_pos) ? make_number (found) : Qnil;
21278 DEFUN ("move-point-visually", Fmove_point_visually,
21279 Smove_point_visually, 1, 1, 0,
21280 doc: /* Move point in the visual order in the specified DIRECTION.
21281 DIRECTION can be 1, meaning move to the right, or -1, which moves to the
21282 left.
21284 Value is the new character position of point. */)
21285 (Lisp_Object direction)
21287 struct window *w = XWINDOW (selected_window);
21288 struct buffer *b = XBUFFER (w->contents);
21289 struct glyph_row *row;
21290 int dir;
21291 Lisp_Object paragraph_dir;
21293 #define ROW_GLYPH_NEWLINE_P(ROW,GLYPH) \
21294 (!(ROW)->continued_p \
21295 && INTEGERP ((GLYPH)->object) \
21296 && (GLYPH)->type == CHAR_GLYPH \
21297 && (GLYPH)->u.ch == ' ' \
21298 && (GLYPH)->charpos >= 0 \
21299 && !(GLYPH)->avoid_cursor_p)
21301 CHECK_NUMBER (direction);
21302 dir = XINT (direction);
21303 if (dir > 0)
21304 dir = 1;
21305 else
21306 dir = -1;
21308 /* If current matrix is up-to-date, we can use the information
21309 recorded in the glyphs, at least as long as the goal is on the
21310 screen. */
21311 if (w->window_end_valid
21312 && !windows_or_buffers_changed
21313 && b
21314 && !b->clip_changed
21315 && !b->prevent_redisplay_optimizations_p
21316 && !window_outdated (w)
21317 /* We rely below on the cursor coordinates to be up to date, but
21318 we cannot trust them if some command moved point since the
21319 last complete redisplay. */
21320 && w->last_point == BUF_PT (b)
21321 && w->cursor.vpos >= 0
21322 && w->cursor.vpos < w->current_matrix->nrows
21323 && (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos))->enabled_p)
21325 struct glyph *g = row->glyphs[TEXT_AREA];
21326 struct glyph *e = dir > 0 ? g + row->used[TEXT_AREA] : g - 1;
21327 struct glyph *gpt = g + w->cursor.hpos;
21329 for (g = gpt + dir; (dir > 0 ? g < e : g > e); g += dir)
21331 if (BUFFERP (g->object) && g->charpos != PT)
21333 SET_PT (g->charpos);
21334 w->cursor.vpos = -1;
21335 return make_number (PT);
21337 else if (!INTEGERP (g->object) && !EQ (g->object, gpt->object))
21339 ptrdiff_t new_pos;
21341 if (BUFFERP (gpt->object))
21343 new_pos = PT;
21344 if ((gpt->resolved_level - row->reversed_p) % 2 == 0)
21345 new_pos += (row->reversed_p ? -dir : dir);
21346 else
21347 new_pos -= (row->reversed_p ? -dir : dir);
21349 else if (BUFFERP (g->object))
21350 new_pos = g->charpos;
21351 else
21352 break;
21353 SET_PT (new_pos);
21354 w->cursor.vpos = -1;
21355 return make_number (PT);
21357 else if (ROW_GLYPH_NEWLINE_P (row, g))
21359 /* Glyphs inserted at the end of a non-empty line for
21360 positioning the cursor have zero charpos, so we must
21361 deduce the value of point by other means. */
21362 if (g->charpos > 0)
21363 SET_PT (g->charpos);
21364 else if (row->ends_at_zv_p && PT != ZV)
21365 SET_PT (ZV);
21366 else if (PT != MATRIX_ROW_END_CHARPOS (row) - 1)
21367 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
21368 else
21369 break;
21370 w->cursor.vpos = -1;
21371 return make_number (PT);
21374 if (g == e || INTEGERP (g->object))
21376 if (row->truncated_on_left_p || row->truncated_on_right_p)
21377 goto simulate_display;
21378 if (!row->reversed_p)
21379 row += dir;
21380 else
21381 row -= dir;
21382 if (row < MATRIX_FIRST_TEXT_ROW (w->current_matrix)
21383 || row > MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
21384 goto simulate_display;
21386 if (dir > 0)
21388 if (row->reversed_p && !row->continued_p)
21390 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
21391 w->cursor.vpos = -1;
21392 return make_number (PT);
21394 g = row->glyphs[TEXT_AREA];
21395 e = g + row->used[TEXT_AREA];
21396 for ( ; g < e; g++)
21398 if (BUFFERP (g->object)
21399 /* Empty lines have only one glyph, which stands
21400 for the newline, and whose charpos is the
21401 buffer position of the newline. */
21402 || ROW_GLYPH_NEWLINE_P (row, g)
21403 /* When the buffer ends in a newline, the line at
21404 EOB also has one glyph, but its charpos is -1. */
21405 || (row->ends_at_zv_p
21406 && !row->reversed_p
21407 && INTEGERP (g->object)
21408 && g->type == CHAR_GLYPH
21409 && g->u.ch == ' '))
21411 if (g->charpos > 0)
21412 SET_PT (g->charpos);
21413 else if (!row->reversed_p
21414 && row->ends_at_zv_p
21415 && PT != ZV)
21416 SET_PT (ZV);
21417 else
21418 continue;
21419 w->cursor.vpos = -1;
21420 return make_number (PT);
21424 else
21426 if (!row->reversed_p && !row->continued_p)
21428 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
21429 w->cursor.vpos = -1;
21430 return make_number (PT);
21432 e = row->glyphs[TEXT_AREA];
21433 g = e + row->used[TEXT_AREA] - 1;
21434 for ( ; g >= e; g--)
21436 if (BUFFERP (g->object)
21437 || (ROW_GLYPH_NEWLINE_P (row, g)
21438 && g->charpos > 0)
21439 /* Empty R2L lines on GUI frames have the buffer
21440 position of the newline stored in the stretch
21441 glyph. */
21442 || g->type == STRETCH_GLYPH
21443 || (row->ends_at_zv_p
21444 && row->reversed_p
21445 && INTEGERP (g->object)
21446 && g->type == CHAR_GLYPH
21447 && g->u.ch == ' '))
21449 if (g->charpos > 0)
21450 SET_PT (g->charpos);
21451 else if (row->reversed_p
21452 && row->ends_at_zv_p
21453 && PT != ZV)
21454 SET_PT (ZV);
21455 else
21456 continue;
21457 w->cursor.vpos = -1;
21458 return make_number (PT);
21465 simulate_display:
21467 /* If we wind up here, we failed to move by using the glyphs, so we
21468 need to simulate display instead. */
21470 if (b)
21471 paragraph_dir = Fcurrent_bidi_paragraph_direction (w->contents);
21472 else
21473 paragraph_dir = Qleft_to_right;
21474 if (EQ (paragraph_dir, Qright_to_left))
21475 dir = -dir;
21476 if (PT <= BEGV && dir < 0)
21477 xsignal0 (Qbeginning_of_buffer);
21478 else if (PT >= ZV && dir > 0)
21479 xsignal0 (Qend_of_buffer);
21480 else
21482 struct text_pos pt;
21483 struct it it;
21484 int pt_x, target_x, pixel_width, pt_vpos;
21485 bool at_eol_p;
21486 bool overshoot_expected = false;
21487 bool target_is_eol_p = false;
21489 /* Setup the arena. */
21490 SET_TEXT_POS (pt, PT, PT_BYTE);
21491 start_display (&it, w, pt);
21493 if (it.cmp_it.id < 0
21494 && it.method == GET_FROM_STRING
21495 && it.area == TEXT_AREA
21496 && it.string_from_display_prop_p
21497 && (it.sp > 0 && it.stack[it.sp - 1].method == GET_FROM_BUFFER))
21498 overshoot_expected = true;
21500 /* Find the X coordinate of point. We start from the beginning
21501 of this or previous line to make sure we are before point in
21502 the logical order (since the move_it_* functions can only
21503 move forward). */
21504 reseat:
21505 reseat_at_previous_visible_line_start (&it);
21506 it.current_x = it.hpos = it.current_y = it.vpos = 0;
21507 if (IT_CHARPOS (it) != PT)
21509 move_it_to (&it, overshoot_expected ? PT - 1 : PT,
21510 -1, -1, -1, MOVE_TO_POS);
21511 /* If we missed point because the character there is
21512 displayed out of a display vector that has more than one
21513 glyph, retry expecting overshoot. */
21514 if (it.method == GET_FROM_DISPLAY_VECTOR
21515 && it.current.dpvec_index > 0
21516 && !overshoot_expected)
21518 overshoot_expected = true;
21519 goto reseat;
21521 else if (IT_CHARPOS (it) != PT && !overshoot_expected)
21522 move_it_in_display_line (&it, PT, -1, MOVE_TO_POS);
21524 pt_x = it.current_x;
21525 pt_vpos = it.vpos;
21526 if (dir > 0 || overshoot_expected)
21528 struct glyph_row *row = it.glyph_row;
21530 /* When point is at beginning of line, we don't have
21531 information about the glyph there loaded into struct
21532 it. Calling get_next_display_element fixes that. */
21533 if (pt_x == 0)
21534 get_next_display_element (&it);
21535 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
21536 it.glyph_row = NULL;
21537 PRODUCE_GLYPHS (&it); /* compute it.pixel_width */
21538 it.glyph_row = row;
21539 /* PRODUCE_GLYPHS advances it.current_x, so we must restore
21540 it, lest it will become out of sync with it's buffer
21541 position. */
21542 it.current_x = pt_x;
21544 else
21545 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
21546 pixel_width = it.pixel_width;
21547 if (overshoot_expected && at_eol_p)
21548 pixel_width = 0;
21549 else if (pixel_width <= 0)
21550 pixel_width = 1;
21552 /* If there's a display string (or something similar) at point,
21553 we are actually at the glyph to the left of point, so we need
21554 to correct the X coordinate. */
21555 if (overshoot_expected)
21557 if (it.bidi_p)
21558 pt_x += pixel_width * it.bidi_it.scan_dir;
21559 else
21560 pt_x += pixel_width;
21563 /* Compute target X coordinate, either to the left or to the
21564 right of point. On TTY frames, all characters have the same
21565 pixel width of 1, so we can use that. On GUI frames we don't
21566 have an easy way of getting at the pixel width of the
21567 character to the left of point, so we use a different method
21568 of getting to that place. */
21569 if (dir > 0)
21570 target_x = pt_x + pixel_width;
21571 else
21572 target_x = pt_x - (!FRAME_WINDOW_P (it.f)) * pixel_width;
21574 /* Target X coordinate could be one line above or below the line
21575 of point, in which case we need to adjust the target X
21576 coordinate. Also, if moving to the left, we need to begin at
21577 the left edge of the point's screen line. */
21578 if (dir < 0)
21580 if (pt_x > 0)
21582 start_display (&it, w, pt);
21583 reseat_at_previous_visible_line_start (&it);
21584 it.current_x = it.current_y = it.hpos = 0;
21585 if (pt_vpos != 0)
21586 move_it_by_lines (&it, pt_vpos);
21588 else
21590 move_it_by_lines (&it, -1);
21591 target_x = it.last_visible_x - !FRAME_WINDOW_P (it.f);
21592 target_is_eol_p = true;
21593 /* Under word-wrap, we don't know the x coordinate of
21594 the last character displayed on the previous line,
21595 which immediately precedes the wrap point. To find
21596 out its x coordinate, we try moving to the right
21597 margin of the window, which will stop at the wrap
21598 point, and then reset target_x to point at the
21599 character that precedes the wrap point. This is not
21600 needed on GUI frames, because (see below) there we
21601 move from the left margin one grapheme cluster at a
21602 time, and stop when we hit the wrap point. */
21603 if (!FRAME_WINDOW_P (it.f) && it.line_wrap == WORD_WRAP)
21605 void *it_data = NULL;
21606 struct it it2;
21608 SAVE_IT (it2, it, it_data);
21609 move_it_in_display_line_to (&it, ZV, target_x,
21610 MOVE_TO_POS | MOVE_TO_X);
21611 /* If we arrived at target_x, that _is_ the last
21612 character on the previous line. */
21613 if (it.current_x != target_x)
21614 target_x = it.current_x - 1;
21615 RESTORE_IT (&it, &it2, it_data);
21619 else
21621 if (at_eol_p
21622 || (target_x >= it.last_visible_x
21623 && it.line_wrap != TRUNCATE))
21625 if (pt_x > 0)
21626 move_it_by_lines (&it, 0);
21627 move_it_by_lines (&it, 1);
21628 target_x = 0;
21632 /* Move to the target X coordinate. */
21633 #ifdef HAVE_WINDOW_SYSTEM
21634 /* On GUI frames, as we don't know the X coordinate of the
21635 character to the left of point, moving point to the left
21636 requires walking, one grapheme cluster at a time, until we
21637 find ourself at a place immediately to the left of the
21638 character at point. */
21639 if (FRAME_WINDOW_P (it.f) && dir < 0)
21641 struct text_pos new_pos;
21642 enum move_it_result rc = MOVE_X_REACHED;
21644 if (it.current_x == 0)
21645 get_next_display_element (&it);
21646 if (it.what == IT_COMPOSITION)
21648 new_pos.charpos = it.cmp_it.charpos;
21649 new_pos.bytepos = -1;
21651 else
21652 new_pos = it.current.pos;
21654 while (it.current_x + it.pixel_width <= target_x
21655 && (rc == MOVE_X_REACHED
21656 /* Under word-wrap, move_it_in_display_line_to
21657 stops at correct coordinates, but sometimes
21658 returns MOVE_POS_MATCH_OR_ZV. */
21659 || (it.line_wrap == WORD_WRAP
21660 && rc == MOVE_POS_MATCH_OR_ZV)))
21662 int new_x = it.current_x + it.pixel_width;
21664 /* For composed characters, we want the position of the
21665 first character in the grapheme cluster (usually, the
21666 composition's base character), whereas it.current
21667 might give us the position of the _last_ one, e.g. if
21668 the composition is rendered in reverse due to bidi
21669 reordering. */
21670 if (it.what == IT_COMPOSITION)
21672 new_pos.charpos = it.cmp_it.charpos;
21673 new_pos.bytepos = -1;
21675 else
21676 new_pos = it.current.pos;
21677 if (new_x == it.current_x)
21678 new_x++;
21679 rc = move_it_in_display_line_to (&it, ZV, new_x,
21680 MOVE_TO_POS | MOVE_TO_X);
21681 if (ITERATOR_AT_END_OF_LINE_P (&it) && !target_is_eol_p)
21682 break;
21684 /* The previous position we saw in the loop is the one we
21685 want. */
21686 if (new_pos.bytepos == -1)
21687 new_pos.bytepos = CHAR_TO_BYTE (new_pos.charpos);
21688 it.current.pos = new_pos;
21690 else
21691 #endif
21692 if (it.current_x != target_x)
21693 move_it_in_display_line_to (&it, ZV, target_x, MOVE_TO_POS | MOVE_TO_X);
21695 /* When lines are truncated, the above loop will stop at the
21696 window edge. But we want to get to the end of line, even if
21697 it is beyond the window edge; automatic hscroll will then
21698 scroll the window to show point as appropriate. */
21699 if (target_is_eol_p && it.line_wrap == TRUNCATE
21700 && get_next_display_element (&it))
21702 struct text_pos new_pos = it.current.pos;
21704 while (!ITERATOR_AT_END_OF_LINE_P (&it))
21706 set_iterator_to_next (&it, 0);
21707 if (it.method == GET_FROM_BUFFER)
21708 new_pos = it.current.pos;
21709 if (!get_next_display_element (&it))
21710 break;
21713 it.current.pos = new_pos;
21716 /* If we ended up in a display string that covers point, move to
21717 buffer position to the right in the visual order. */
21718 if (dir > 0)
21720 while (IT_CHARPOS (it) == PT)
21722 set_iterator_to_next (&it, 0);
21723 if (!get_next_display_element (&it))
21724 break;
21728 /* Move point to that position. */
21729 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
21732 return make_number (PT);
21734 #undef ROW_GLYPH_NEWLINE_P
21737 DEFUN ("bidi-resolved-levels", Fbidi_resolved_levels,
21738 Sbidi_resolved_levels, 0, 1, 0,
21739 doc: /* Return the resolved bidirectional levels of characters at VPOS.
21741 The resolved levels are produced by the Emacs bidi reordering engine
21742 that implements the UBA, the Unicode Bidirectional Algorithm. Please
21743 read the Unicode Standard Annex 9 (UAX#9) for background information
21744 about these levels.
21746 VPOS is the zero-based number of the current window's screen line
21747 for which to produce the resolved levels. If VPOS is nil or omitted,
21748 it defaults to the screen line of point. If the window displays a
21749 header line, VPOS of zero will report on the header line, and first
21750 line of text in the window will have VPOS of 1.
21752 Value is an array of resolved levels, indexed by glyph number.
21753 Glyphs are numbered from zero starting from the beginning of the
21754 screen line, i.e. the left edge of the window for left-to-right lines
21755 and from the right edge for right-to-left lines. The resolved levels
21756 are produced only for the window's text area; text in display margins
21757 is not included.
21759 If the selected window's display is not up-to-date, or if the specified
21760 screen line does not display text, this function returns nil. It is
21761 highly recommended to bind this function to some simple key, like F8,
21762 in order to avoid these problems.
21764 This function exists mainly for testing the correctness of the
21765 Emacs UBA implementation, in particular with the test suite. */)
21766 (Lisp_Object vpos)
21768 struct window *w = XWINDOW (selected_window);
21769 struct buffer *b = XBUFFER (w->contents);
21770 int nrow;
21771 struct glyph_row *row;
21773 if (NILP (vpos))
21775 int d1, d2, d3, d4, d5;
21777 pos_visible_p (w, PT, &d1, &d2, &d3, &d4, &d5, &nrow);
21779 else
21781 CHECK_NUMBER_COERCE_MARKER (vpos);
21782 nrow = XINT (vpos);
21785 /* We require up-to-date glyph matrix for this window. */
21786 if (w->window_end_valid
21787 && !windows_or_buffers_changed
21788 && b
21789 && !b->clip_changed
21790 && !b->prevent_redisplay_optimizations_p
21791 && !window_outdated (w)
21792 && nrow >= 0
21793 && nrow < w->current_matrix->nrows
21794 && (row = MATRIX_ROW (w->current_matrix, nrow))->enabled_p
21795 && MATRIX_ROW_DISPLAYS_TEXT_P (row))
21797 struct glyph *g, *e, *g1;
21798 int nglyphs, i;
21799 Lisp_Object levels;
21801 if (!row->reversed_p) /* Left-to-right glyph row. */
21803 g = g1 = row->glyphs[TEXT_AREA];
21804 e = g + row->used[TEXT_AREA];
21806 /* Skip over glyphs at the start of the row that was
21807 generated by redisplay for its own needs. */
21808 while (g < e
21809 && INTEGERP (g->object)
21810 && g->charpos < 0)
21811 g++;
21812 g1 = g;
21814 /* Count the "interesting" glyphs in this row. */
21815 for (nglyphs = 0; g < e && !INTEGERP (g->object); g++)
21816 nglyphs++;
21818 /* Create and fill the array. */
21819 levels = make_uninit_vector (nglyphs);
21820 for (i = 0; g1 < g; i++, g1++)
21821 ASET (levels, i, make_number (g1->resolved_level));
21823 else /* Right-to-left glyph row. */
21825 g = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
21826 e = row->glyphs[TEXT_AREA] - 1;
21827 while (g > e
21828 && INTEGERP (g->object)
21829 && g->charpos < 0)
21830 g--;
21831 g1 = g;
21832 for (nglyphs = 0; g > e && !INTEGERP (g->object); g--)
21833 nglyphs++;
21834 levels = make_uninit_vector (nglyphs);
21835 for (i = 0; g1 > g; i++, g1--)
21836 ASET (levels, i, make_number (g1->resolved_level));
21838 return levels;
21840 else
21841 return Qnil;
21846 /***********************************************************************
21847 Menu Bar
21848 ***********************************************************************/
21850 /* Redisplay the menu bar in the frame for window W.
21852 The menu bar of X frames that don't have X toolkit support is
21853 displayed in a special window W->frame->menu_bar_window.
21855 The menu bar of terminal frames is treated specially as far as
21856 glyph matrices are concerned. Menu bar lines are not part of
21857 windows, so the update is done directly on the frame matrix rows
21858 for the menu bar. */
21860 static void
21861 display_menu_bar (struct window *w)
21863 struct frame *f = XFRAME (WINDOW_FRAME (w));
21864 struct it it;
21865 Lisp_Object items;
21866 int i;
21868 /* Don't do all this for graphical frames. */
21869 #ifdef HAVE_NTGUI
21870 if (FRAME_W32_P (f))
21871 return;
21872 #endif
21873 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
21874 if (FRAME_X_P (f))
21875 return;
21876 #endif
21878 #ifdef HAVE_NS
21879 if (FRAME_NS_P (f))
21880 return;
21881 #endif /* HAVE_NS */
21883 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
21884 eassert (!FRAME_WINDOW_P (f));
21885 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
21886 it.first_visible_x = 0;
21887 it.last_visible_x = FRAME_PIXEL_WIDTH (f);
21888 #elif defined (HAVE_X_WINDOWS) /* X without toolkit. */
21889 if (FRAME_WINDOW_P (f))
21891 /* Menu bar lines are displayed in the desired matrix of the
21892 dummy window menu_bar_window. */
21893 struct window *menu_w;
21894 menu_w = XWINDOW (f->menu_bar_window);
21895 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
21896 MENU_FACE_ID);
21897 it.first_visible_x = 0;
21898 it.last_visible_x = FRAME_PIXEL_WIDTH (f);
21900 else
21901 #endif /* not USE_X_TOOLKIT and not USE_GTK */
21903 /* This is a TTY frame, i.e. character hpos/vpos are used as
21904 pixel x/y. */
21905 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
21906 MENU_FACE_ID);
21907 it.first_visible_x = 0;
21908 it.last_visible_x = FRAME_COLS (f);
21911 /* FIXME: This should be controlled by a user option. See the
21912 comments in redisplay_tool_bar and display_mode_line about
21913 this. */
21914 it.paragraph_embedding = L2R;
21916 /* Clear all rows of the menu bar. */
21917 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
21919 struct glyph_row *row = it.glyph_row + i;
21920 clear_glyph_row (row);
21921 row->enabled_p = true;
21922 row->full_width_p = 1;
21923 row->reversed_p = false;
21926 /* Display all items of the menu bar. */
21927 items = FRAME_MENU_BAR_ITEMS (it.f);
21928 for (i = 0; i < ASIZE (items); i += 4)
21930 Lisp_Object string;
21932 /* Stop at nil string. */
21933 string = AREF (items, i + 1);
21934 if (NILP (string))
21935 break;
21937 /* Remember where item was displayed. */
21938 ASET (items, i + 3, make_number (it.hpos));
21940 /* Display the item, pad with one space. */
21941 if (it.current_x < it.last_visible_x)
21942 display_string (NULL, string, Qnil, 0, 0, &it,
21943 SCHARS (string) + 1, 0, 0, -1);
21946 /* Fill out the line with spaces. */
21947 if (it.current_x < it.last_visible_x)
21948 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
21950 /* Compute the total height of the lines. */
21951 compute_line_metrics (&it);
21954 /* Deep copy of a glyph row, including the glyphs. */
21955 static void
21956 deep_copy_glyph_row (struct glyph_row *to, struct glyph_row *from)
21958 struct glyph *pointers[1 + LAST_AREA];
21959 int to_used = to->used[TEXT_AREA];
21961 /* Save glyph pointers of TO. */
21962 memcpy (pointers, to->glyphs, sizeof to->glyphs);
21964 /* Do a structure assignment. */
21965 *to = *from;
21967 /* Restore original glyph pointers of TO. */
21968 memcpy (to->glyphs, pointers, sizeof to->glyphs);
21970 /* Copy the glyphs. */
21971 memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA],
21972 min (from->used[TEXT_AREA], to_used) * sizeof (struct glyph));
21974 /* If we filled only part of the TO row, fill the rest with
21975 space_glyph (which will display as empty space). */
21976 if (to_used > from->used[TEXT_AREA])
21977 fill_up_frame_row_with_spaces (to, to_used);
21980 /* Display one menu item on a TTY, by overwriting the glyphs in the
21981 frame F's desired glyph matrix with glyphs produced from the menu
21982 item text. Called from term.c to display TTY drop-down menus one
21983 item at a time.
21985 ITEM_TEXT is the menu item text as a C string.
21987 FACE_ID is the face ID to be used for this menu item. FACE_ID
21988 could specify one of 3 faces: a face for an enabled item, a face
21989 for a disabled item, or a face for a selected item.
21991 X and Y are coordinates of the first glyph in the frame's desired
21992 matrix to be overwritten by the menu item. Since this is a TTY, Y
21993 is the zero-based number of the glyph row and X is the zero-based
21994 glyph number in the row, starting from left, where to start
21995 displaying the item.
21997 SUBMENU non-zero means this menu item drops down a submenu, which
21998 should be indicated by displaying a proper visual cue after the
21999 item text. */
22001 void
22002 display_tty_menu_item (const char *item_text, int width, int face_id,
22003 int x, int y, int submenu)
22005 struct it it;
22006 struct frame *f = SELECTED_FRAME ();
22007 struct window *w = XWINDOW (f->selected_window);
22008 int saved_used, saved_truncated, saved_width, saved_reversed;
22009 struct glyph_row *row;
22010 size_t item_len = strlen (item_text);
22012 eassert (FRAME_TERMCAP_P (f));
22014 /* Don't write beyond the matrix's last row. This can happen for
22015 TTY screens that are not high enough to show the entire menu.
22016 (This is actually a bit of defensive programming, as
22017 tty_menu_display already limits the number of menu items to one
22018 less than the number of screen lines.) */
22019 if (y >= f->desired_matrix->nrows)
22020 return;
22022 init_iterator (&it, w, -1, -1, f->desired_matrix->rows + y, MENU_FACE_ID);
22023 it.first_visible_x = 0;
22024 it.last_visible_x = FRAME_COLS (f) - 1;
22025 row = it.glyph_row;
22026 /* Start with the row contents from the current matrix. */
22027 deep_copy_glyph_row (row, f->current_matrix->rows + y);
22028 saved_width = row->full_width_p;
22029 row->full_width_p = 1;
22030 saved_reversed = row->reversed_p;
22031 row->reversed_p = 0;
22032 row->enabled_p = true;
22034 /* Arrange for the menu item glyphs to start at (X,Y) and have the
22035 desired face. */
22036 eassert (x < f->desired_matrix->matrix_w);
22037 it.current_x = it.hpos = x;
22038 it.current_y = it.vpos = y;
22039 saved_used = row->used[TEXT_AREA];
22040 saved_truncated = row->truncated_on_right_p;
22041 row->used[TEXT_AREA] = x;
22042 it.face_id = face_id;
22043 it.line_wrap = TRUNCATE;
22045 /* FIXME: This should be controlled by a user option. See the
22046 comments in redisplay_tool_bar and display_mode_line about this.
22047 Also, if paragraph_embedding could ever be R2L, changes will be
22048 needed to avoid shifting to the right the row characters in
22049 term.c:append_glyph. */
22050 it.paragraph_embedding = L2R;
22052 /* Pad with a space on the left. */
22053 display_string (" ", Qnil, Qnil, 0, 0, &it, 1, 0, FRAME_COLS (f) - 1, -1);
22054 width--;
22055 /* Display the menu item, pad with spaces to WIDTH. */
22056 if (submenu)
22058 display_string (item_text, Qnil, Qnil, 0, 0, &it,
22059 item_len, 0, FRAME_COLS (f) - 1, -1);
22060 width -= item_len;
22061 /* Indicate with " >" that there's a submenu. */
22062 display_string (" >", Qnil, Qnil, 0, 0, &it, width, 0,
22063 FRAME_COLS (f) - 1, -1);
22065 else
22066 display_string (item_text, Qnil, Qnil, 0, 0, &it,
22067 width, 0, FRAME_COLS (f) - 1, -1);
22069 row->used[TEXT_AREA] = max (saved_used, row->used[TEXT_AREA]);
22070 row->truncated_on_right_p = saved_truncated;
22071 row->hash = row_hash (row);
22072 row->full_width_p = saved_width;
22073 row->reversed_p = saved_reversed;
22076 /***********************************************************************
22077 Mode Line
22078 ***********************************************************************/
22080 /* Redisplay mode lines in the window tree whose root is WINDOW. If
22081 FORCE is non-zero, redisplay mode lines unconditionally.
22082 Otherwise, redisplay only mode lines that are garbaged. Value is
22083 the number of windows whose mode lines were redisplayed. */
22085 static int
22086 redisplay_mode_lines (Lisp_Object window, bool force)
22088 int nwindows = 0;
22090 while (!NILP (window))
22092 struct window *w = XWINDOW (window);
22094 if (WINDOWP (w->contents))
22095 nwindows += redisplay_mode_lines (w->contents, force);
22096 else if (force
22097 || FRAME_GARBAGED_P (XFRAME (w->frame))
22098 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
22100 struct text_pos lpoint;
22101 struct buffer *old = current_buffer;
22103 /* Set the window's buffer for the mode line display. */
22104 SET_TEXT_POS (lpoint, PT, PT_BYTE);
22105 set_buffer_internal_1 (XBUFFER (w->contents));
22107 /* Point refers normally to the selected window. For any
22108 other window, set up appropriate value. */
22109 if (!EQ (window, selected_window))
22111 struct text_pos pt;
22113 CLIP_TEXT_POS_FROM_MARKER (pt, w->pointm);
22114 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
22117 /* Display mode lines. */
22118 clear_glyph_matrix (w->desired_matrix);
22119 if (display_mode_lines (w))
22120 ++nwindows;
22122 /* Restore old settings. */
22123 set_buffer_internal_1 (old);
22124 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
22127 window = w->next;
22130 return nwindows;
22134 /* Display the mode and/or header line of window W. Value is the
22135 sum number of mode lines and header lines displayed. */
22137 static int
22138 display_mode_lines (struct window *w)
22140 Lisp_Object old_selected_window = selected_window;
22141 Lisp_Object old_selected_frame = selected_frame;
22142 Lisp_Object new_frame = w->frame;
22143 Lisp_Object old_frame_selected_window = XFRAME (new_frame)->selected_window;
22144 int n = 0;
22146 selected_frame = new_frame;
22147 /* FIXME: If we were to allow the mode-line's computation changing the buffer
22148 or window's point, then we'd need select_window_1 here as well. */
22149 XSETWINDOW (selected_window, w);
22150 XFRAME (new_frame)->selected_window = selected_window;
22152 /* These will be set while the mode line specs are processed. */
22153 line_number_displayed = 0;
22154 w->column_number_displayed = -1;
22156 if (WINDOW_WANTS_MODELINE_P (w))
22158 struct window *sel_w = XWINDOW (old_selected_window);
22160 /* Select mode line face based on the real selected window. */
22161 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
22162 BVAR (current_buffer, mode_line_format));
22163 ++n;
22166 if (WINDOW_WANTS_HEADER_LINE_P (w))
22168 display_mode_line (w, HEADER_LINE_FACE_ID,
22169 BVAR (current_buffer, header_line_format));
22170 ++n;
22173 XFRAME (new_frame)->selected_window = old_frame_selected_window;
22174 selected_frame = old_selected_frame;
22175 selected_window = old_selected_window;
22176 if (n > 0)
22177 w->must_be_updated_p = true;
22178 return n;
22182 /* Display mode or header line of window W. FACE_ID specifies which
22183 line to display; it is either MODE_LINE_FACE_ID or
22184 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
22185 display. Value is the pixel height of the mode/header line
22186 displayed. */
22188 static int
22189 display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
22191 struct it it;
22192 struct face *face;
22193 ptrdiff_t count = SPECPDL_INDEX ();
22195 init_iterator (&it, w, -1, -1, NULL, face_id);
22196 /* Don't extend on a previously drawn mode-line.
22197 This may happen if called from pos_visible_p. */
22198 it.glyph_row->enabled_p = false;
22199 prepare_desired_row (w, it.glyph_row, true);
22201 it.glyph_row->mode_line_p = 1;
22203 /* FIXME: This should be controlled by a user option. But
22204 supporting such an option is not trivial, since the mode line is
22205 made up of many separate strings. */
22206 it.paragraph_embedding = L2R;
22208 record_unwind_protect (unwind_format_mode_line,
22209 format_mode_line_unwind_data (NULL, NULL, Qnil, 0));
22211 mode_line_target = MODE_LINE_DISPLAY;
22213 /* Temporarily make frame's keyboard the current kboard so that
22214 kboard-local variables in the mode_line_format will get the right
22215 values. */
22216 push_kboard (FRAME_KBOARD (it.f));
22217 record_unwind_save_match_data ();
22218 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
22219 pop_kboard ();
22221 unbind_to (count, Qnil);
22223 /* Fill up with spaces. */
22224 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
22226 compute_line_metrics (&it);
22227 it.glyph_row->full_width_p = 1;
22228 it.glyph_row->continued_p = 0;
22229 it.glyph_row->truncated_on_left_p = 0;
22230 it.glyph_row->truncated_on_right_p = 0;
22232 /* Make a 3D mode-line have a shadow at its right end. */
22233 face = FACE_FROM_ID (it.f, face_id);
22234 extend_face_to_end_of_line (&it);
22235 if (face->box != FACE_NO_BOX)
22237 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
22238 + it.glyph_row->used[TEXT_AREA] - 1);
22239 last->right_box_line_p = 1;
22242 return it.glyph_row->height;
22245 /* Move element ELT in LIST to the front of LIST.
22246 Return the updated list. */
22248 static Lisp_Object
22249 move_elt_to_front (Lisp_Object elt, Lisp_Object list)
22251 register Lisp_Object tail, prev;
22252 register Lisp_Object tem;
22254 tail = list;
22255 prev = Qnil;
22256 while (CONSP (tail))
22258 tem = XCAR (tail);
22260 if (EQ (elt, tem))
22262 /* Splice out the link TAIL. */
22263 if (NILP (prev))
22264 list = XCDR (tail);
22265 else
22266 Fsetcdr (prev, XCDR (tail));
22268 /* Now make it the first. */
22269 Fsetcdr (tail, list);
22270 return tail;
22272 else
22273 prev = tail;
22274 tail = XCDR (tail);
22275 QUIT;
22278 /* Not found--return unchanged LIST. */
22279 return list;
22282 /* Contribute ELT to the mode line for window IT->w. How it
22283 translates into text depends on its data type.
22285 IT describes the display environment in which we display, as usual.
22287 DEPTH is the depth in recursion. It is used to prevent
22288 infinite recursion here.
22290 FIELD_WIDTH is the number of characters the display of ELT should
22291 occupy in the mode line, and PRECISION is the maximum number of
22292 characters to display from ELT's representation. See
22293 display_string for details.
22295 Returns the hpos of the end of the text generated by ELT.
22297 PROPS is a property list to add to any string we encounter.
22299 If RISKY is nonzero, remove (disregard) any properties in any string
22300 we encounter, and ignore :eval and :propertize.
22302 The global variable `mode_line_target' determines whether the
22303 output is passed to `store_mode_line_noprop',
22304 `store_mode_line_string', or `display_string'. */
22306 static int
22307 display_mode_element (struct it *it, int depth, int field_width, int precision,
22308 Lisp_Object elt, Lisp_Object props, int risky)
22310 int n = 0, field, prec;
22311 int literal = 0;
22313 tail_recurse:
22314 if (depth > 100)
22315 elt = build_string ("*too-deep*");
22317 depth++;
22319 switch (XTYPE (elt))
22321 case Lisp_String:
22323 /* A string: output it and check for %-constructs within it. */
22324 unsigned char c;
22325 ptrdiff_t offset = 0;
22327 if (SCHARS (elt) > 0
22328 && (!NILP (props) || risky))
22330 Lisp_Object oprops, aelt;
22331 oprops = Ftext_properties_at (make_number (0), elt);
22333 /* If the starting string's properties are not what
22334 we want, translate the string. Also, if the string
22335 is risky, do that anyway. */
22337 if (NILP (Fequal (props, oprops)) || risky)
22339 /* If the starting string has properties,
22340 merge the specified ones onto the existing ones. */
22341 if (! NILP (oprops) && !risky)
22343 Lisp_Object tem;
22345 oprops = Fcopy_sequence (oprops);
22346 tem = props;
22347 while (CONSP (tem))
22349 oprops = Fplist_put (oprops, XCAR (tem),
22350 XCAR (XCDR (tem)));
22351 tem = XCDR (XCDR (tem));
22353 props = oprops;
22356 aelt = Fassoc (elt, mode_line_proptrans_alist);
22357 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
22359 /* AELT is what we want. Move it to the front
22360 without consing. */
22361 elt = XCAR (aelt);
22362 mode_line_proptrans_alist
22363 = move_elt_to_front (aelt, mode_line_proptrans_alist);
22365 else
22367 Lisp_Object tem;
22369 /* If AELT has the wrong props, it is useless.
22370 so get rid of it. */
22371 if (! NILP (aelt))
22372 mode_line_proptrans_alist
22373 = Fdelq (aelt, mode_line_proptrans_alist);
22375 elt = Fcopy_sequence (elt);
22376 Fset_text_properties (make_number (0), Flength (elt),
22377 props, elt);
22378 /* Add this item to mode_line_proptrans_alist. */
22379 mode_line_proptrans_alist
22380 = Fcons (Fcons (elt, props),
22381 mode_line_proptrans_alist);
22382 /* Truncate mode_line_proptrans_alist
22383 to at most 50 elements. */
22384 tem = Fnthcdr (make_number (50),
22385 mode_line_proptrans_alist);
22386 if (! NILP (tem))
22387 XSETCDR (tem, Qnil);
22392 offset = 0;
22394 if (literal)
22396 prec = precision - n;
22397 switch (mode_line_target)
22399 case MODE_LINE_NOPROP:
22400 case MODE_LINE_TITLE:
22401 n += store_mode_line_noprop (SSDATA (elt), -1, prec);
22402 break;
22403 case MODE_LINE_STRING:
22404 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
22405 break;
22406 case MODE_LINE_DISPLAY:
22407 n += display_string (NULL, elt, Qnil, 0, 0, it,
22408 0, prec, 0, STRING_MULTIBYTE (elt));
22409 break;
22412 break;
22415 /* Handle the non-literal case. */
22417 while ((precision <= 0 || n < precision)
22418 && SREF (elt, offset) != 0
22419 && (mode_line_target != MODE_LINE_DISPLAY
22420 || it->current_x < it->last_visible_x))
22422 ptrdiff_t last_offset = offset;
22424 /* Advance to end of string or next format specifier. */
22425 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
22428 if (offset - 1 != last_offset)
22430 ptrdiff_t nchars, nbytes;
22432 /* Output to end of string or up to '%'. Field width
22433 is length of string. Don't output more than
22434 PRECISION allows us. */
22435 offset--;
22437 prec = c_string_width (SDATA (elt) + last_offset,
22438 offset - last_offset, precision - n,
22439 &nchars, &nbytes);
22441 switch (mode_line_target)
22443 case MODE_LINE_NOPROP:
22444 case MODE_LINE_TITLE:
22445 n += store_mode_line_noprop (SSDATA (elt) + last_offset, 0, prec);
22446 break;
22447 case MODE_LINE_STRING:
22449 ptrdiff_t bytepos = last_offset;
22450 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
22451 ptrdiff_t endpos = (precision <= 0
22452 ? string_byte_to_char (elt, offset)
22453 : charpos + nchars);
22455 n += store_mode_line_string (NULL,
22456 Fsubstring (elt, make_number (charpos),
22457 make_number (endpos)),
22458 0, 0, 0, Qnil);
22460 break;
22461 case MODE_LINE_DISPLAY:
22463 ptrdiff_t bytepos = last_offset;
22464 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
22466 if (precision <= 0)
22467 nchars = string_byte_to_char (elt, offset) - charpos;
22468 n += display_string (NULL, elt, Qnil, 0, charpos,
22469 it, 0, nchars, 0,
22470 STRING_MULTIBYTE (elt));
22472 break;
22475 else /* c == '%' */
22477 ptrdiff_t percent_position = offset;
22479 /* Get the specified minimum width. Zero means
22480 don't pad. */
22481 field = 0;
22482 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
22483 field = field * 10 + c - '0';
22485 /* Don't pad beyond the total padding allowed. */
22486 if (field_width - n > 0 && field > field_width - n)
22487 field = field_width - n;
22489 /* Note that either PRECISION <= 0 or N < PRECISION. */
22490 prec = precision - n;
22492 if (c == 'M')
22493 n += display_mode_element (it, depth, field, prec,
22494 Vglobal_mode_string, props,
22495 risky);
22496 else if (c != 0)
22498 bool multibyte;
22499 ptrdiff_t bytepos, charpos;
22500 const char *spec;
22501 Lisp_Object string;
22503 bytepos = percent_position;
22504 charpos = (STRING_MULTIBYTE (elt)
22505 ? string_byte_to_char (elt, bytepos)
22506 : bytepos);
22507 spec = decode_mode_spec (it->w, c, field, &string);
22508 multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
22510 switch (mode_line_target)
22512 case MODE_LINE_NOPROP:
22513 case MODE_LINE_TITLE:
22514 n += store_mode_line_noprop (spec, field, prec);
22515 break;
22516 case MODE_LINE_STRING:
22518 Lisp_Object tem = build_string (spec);
22519 props = Ftext_properties_at (make_number (charpos), elt);
22520 /* Should only keep face property in props */
22521 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
22523 break;
22524 case MODE_LINE_DISPLAY:
22526 int nglyphs_before, nwritten;
22528 nglyphs_before = it->glyph_row->used[TEXT_AREA];
22529 nwritten = display_string (spec, string, elt,
22530 charpos, 0, it,
22531 field, prec, 0,
22532 multibyte);
22534 /* Assign to the glyphs written above the
22535 string where the `%x' came from, position
22536 of the `%'. */
22537 if (nwritten > 0)
22539 struct glyph *glyph
22540 = (it->glyph_row->glyphs[TEXT_AREA]
22541 + nglyphs_before);
22542 int i;
22544 for (i = 0; i < nwritten; ++i)
22546 glyph[i].object = elt;
22547 glyph[i].charpos = charpos;
22550 n += nwritten;
22553 break;
22556 else /* c == 0 */
22557 break;
22561 break;
22563 case Lisp_Symbol:
22564 /* A symbol: process the value of the symbol recursively
22565 as if it appeared here directly. Avoid error if symbol void.
22566 Special case: if value of symbol is a string, output the string
22567 literally. */
22569 register Lisp_Object tem;
22571 /* If the variable is not marked as risky to set
22572 then its contents are risky to use. */
22573 if (NILP (Fget (elt, Qrisky_local_variable)))
22574 risky = 1;
22576 tem = Fboundp (elt);
22577 if (!NILP (tem))
22579 tem = Fsymbol_value (elt);
22580 /* If value is a string, output that string literally:
22581 don't check for % within it. */
22582 if (STRINGP (tem))
22583 literal = 1;
22585 if (!EQ (tem, elt))
22587 /* Give up right away for nil or t. */
22588 elt = tem;
22589 goto tail_recurse;
22593 break;
22595 case Lisp_Cons:
22597 register Lisp_Object car, tem;
22599 /* A cons cell: five distinct cases.
22600 If first element is :eval or :propertize, do something special.
22601 If first element is a string or a cons, process all the elements
22602 and effectively concatenate them.
22603 If first element is a negative number, truncate displaying cdr to
22604 at most that many characters. If positive, pad (with spaces)
22605 to at least that many characters.
22606 If first element is a symbol, process the cadr or caddr recursively
22607 according to whether the symbol's value is non-nil or nil. */
22608 car = XCAR (elt);
22609 if (EQ (car, QCeval))
22611 /* An element of the form (:eval FORM) means evaluate FORM
22612 and use the result as mode line elements. */
22614 if (risky)
22615 break;
22617 if (CONSP (XCDR (elt)))
22619 Lisp_Object spec;
22620 spec = safe__eval (true, XCAR (XCDR (elt)));
22621 n += display_mode_element (it, depth, field_width - n,
22622 precision - n, spec, props,
22623 risky);
22626 else if (EQ (car, QCpropertize))
22628 /* An element of the form (:propertize ELT PROPS...)
22629 means display ELT but applying properties PROPS. */
22631 if (risky)
22632 break;
22634 if (CONSP (XCDR (elt)))
22635 n += display_mode_element (it, depth, field_width - n,
22636 precision - n, XCAR (XCDR (elt)),
22637 XCDR (XCDR (elt)), risky);
22639 else if (SYMBOLP (car))
22641 tem = Fboundp (car);
22642 elt = XCDR (elt);
22643 if (!CONSP (elt))
22644 goto invalid;
22645 /* elt is now the cdr, and we know it is a cons cell.
22646 Use its car if CAR has a non-nil value. */
22647 if (!NILP (tem))
22649 tem = Fsymbol_value (car);
22650 if (!NILP (tem))
22652 elt = XCAR (elt);
22653 goto tail_recurse;
22656 /* Symbol's value is nil (or symbol is unbound)
22657 Get the cddr of the original list
22658 and if possible find the caddr and use that. */
22659 elt = XCDR (elt);
22660 if (NILP (elt))
22661 break;
22662 else if (!CONSP (elt))
22663 goto invalid;
22664 elt = XCAR (elt);
22665 goto tail_recurse;
22667 else if (INTEGERP (car))
22669 register int lim = XINT (car);
22670 elt = XCDR (elt);
22671 if (lim < 0)
22673 /* Negative int means reduce maximum width. */
22674 if (precision <= 0)
22675 precision = -lim;
22676 else
22677 precision = min (precision, -lim);
22679 else if (lim > 0)
22681 /* Padding specified. Don't let it be more than
22682 current maximum. */
22683 if (precision > 0)
22684 lim = min (precision, lim);
22686 /* If that's more padding than already wanted, queue it.
22687 But don't reduce padding already specified even if
22688 that is beyond the current truncation point. */
22689 field_width = max (lim, field_width);
22691 goto tail_recurse;
22693 else if (STRINGP (car) || CONSP (car))
22695 Lisp_Object halftail = elt;
22696 int len = 0;
22698 while (CONSP (elt)
22699 && (precision <= 0 || n < precision))
22701 n += display_mode_element (it, depth,
22702 /* Do padding only after the last
22703 element in the list. */
22704 (! CONSP (XCDR (elt))
22705 ? field_width - n
22706 : 0),
22707 precision - n, XCAR (elt),
22708 props, risky);
22709 elt = XCDR (elt);
22710 len++;
22711 if ((len & 1) == 0)
22712 halftail = XCDR (halftail);
22713 /* Check for cycle. */
22714 if (EQ (halftail, elt))
22715 break;
22719 break;
22721 default:
22722 invalid:
22723 elt = build_string ("*invalid*");
22724 goto tail_recurse;
22727 /* Pad to FIELD_WIDTH. */
22728 if (field_width > 0 && n < field_width)
22730 switch (mode_line_target)
22732 case MODE_LINE_NOPROP:
22733 case MODE_LINE_TITLE:
22734 n += store_mode_line_noprop ("", field_width - n, 0);
22735 break;
22736 case MODE_LINE_STRING:
22737 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
22738 break;
22739 case MODE_LINE_DISPLAY:
22740 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
22741 0, 0, 0);
22742 break;
22746 return n;
22749 /* Store a mode-line string element in mode_line_string_list.
22751 If STRING is non-null, display that C string. Otherwise, the Lisp
22752 string LISP_STRING is displayed.
22754 FIELD_WIDTH is the minimum number of output glyphs to produce.
22755 If STRING has fewer characters than FIELD_WIDTH, pad to the right
22756 with spaces. FIELD_WIDTH <= 0 means don't pad.
22758 PRECISION is the maximum number of characters to output from
22759 STRING. PRECISION <= 0 means don't truncate the string.
22761 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
22762 properties to the string.
22764 PROPS are the properties to add to the string.
22765 The mode_line_string_face face property is always added to the string.
22768 static int
22769 store_mode_line_string (const char *string, Lisp_Object lisp_string, int copy_string,
22770 int field_width, int precision, Lisp_Object props)
22772 ptrdiff_t len;
22773 int n = 0;
22775 if (string != NULL)
22777 len = strlen (string);
22778 if (precision > 0 && len > precision)
22779 len = precision;
22780 lisp_string = make_string (string, len);
22781 if (NILP (props))
22782 props = mode_line_string_face_prop;
22783 else if (!NILP (mode_line_string_face))
22785 Lisp_Object face = Fplist_get (props, Qface);
22786 props = Fcopy_sequence (props);
22787 if (NILP (face))
22788 face = mode_line_string_face;
22789 else
22790 face = list2 (face, mode_line_string_face);
22791 props = Fplist_put (props, Qface, face);
22793 Fadd_text_properties (make_number (0), make_number (len),
22794 props, lisp_string);
22796 else
22798 len = XFASTINT (Flength (lisp_string));
22799 if (precision > 0 && len > precision)
22801 len = precision;
22802 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
22803 precision = -1;
22805 if (!NILP (mode_line_string_face))
22807 Lisp_Object face;
22808 if (NILP (props))
22809 props = Ftext_properties_at (make_number (0), lisp_string);
22810 face = Fplist_get (props, Qface);
22811 if (NILP (face))
22812 face = mode_line_string_face;
22813 else
22814 face = list2 (face, mode_line_string_face);
22815 props = list2 (Qface, face);
22816 if (copy_string)
22817 lisp_string = Fcopy_sequence (lisp_string);
22819 if (!NILP (props))
22820 Fadd_text_properties (make_number (0), make_number (len),
22821 props, lisp_string);
22824 if (len > 0)
22826 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
22827 n += len;
22830 if (field_width > len)
22832 field_width -= len;
22833 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
22834 if (!NILP (props))
22835 Fadd_text_properties (make_number (0), make_number (field_width),
22836 props, lisp_string);
22837 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
22838 n += field_width;
22841 return n;
22845 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
22846 1, 4, 0,
22847 doc: /* Format a string out of a mode line format specification.
22848 First arg FORMAT specifies the mode line format (see `mode-line-format'
22849 for details) to use.
22851 By default, the format is evaluated for the currently selected window.
22853 Optional second arg FACE specifies the face property to put on all
22854 characters for which no face is specified. The value nil means the
22855 default face. The value t means whatever face the window's mode line
22856 currently uses (either `mode-line' or `mode-line-inactive',
22857 depending on whether the window is the selected window or not).
22858 An integer value means the value string has no text
22859 properties.
22861 Optional third and fourth args WINDOW and BUFFER specify the window
22862 and buffer to use as the context for the formatting (defaults
22863 are the selected window and the WINDOW's buffer). */)
22864 (Lisp_Object format, Lisp_Object face,
22865 Lisp_Object window, Lisp_Object buffer)
22867 struct it it;
22868 int len;
22869 struct window *w;
22870 struct buffer *old_buffer = NULL;
22871 int face_id;
22872 int no_props = INTEGERP (face);
22873 ptrdiff_t count = SPECPDL_INDEX ();
22874 Lisp_Object str;
22875 int string_start = 0;
22877 w = decode_any_window (window);
22878 XSETWINDOW (window, w);
22880 if (NILP (buffer))
22881 buffer = w->contents;
22882 CHECK_BUFFER (buffer);
22884 /* Make formatting the modeline a non-op when noninteractive, otherwise
22885 there will be problems later caused by a partially initialized frame. */
22886 if (NILP (format) || noninteractive)
22887 return empty_unibyte_string;
22889 if (no_props)
22890 face = Qnil;
22892 face_id = (NILP (face) || EQ (face, Qdefault)) ? DEFAULT_FACE_ID
22893 : EQ (face, Qt) ? (EQ (window, selected_window)
22894 ? MODE_LINE_FACE_ID : MODE_LINE_INACTIVE_FACE_ID)
22895 : EQ (face, Qmode_line) ? MODE_LINE_FACE_ID
22896 : EQ (face, Qmode_line_inactive) ? MODE_LINE_INACTIVE_FACE_ID
22897 : EQ (face, Qheader_line) ? HEADER_LINE_FACE_ID
22898 : EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID
22899 : DEFAULT_FACE_ID;
22901 old_buffer = current_buffer;
22903 /* Save things including mode_line_proptrans_alist,
22904 and set that to nil so that we don't alter the outer value. */
22905 record_unwind_protect (unwind_format_mode_line,
22906 format_mode_line_unwind_data
22907 (XFRAME (WINDOW_FRAME (w)),
22908 old_buffer, selected_window, 1));
22909 mode_line_proptrans_alist = Qnil;
22911 Fselect_window (window, Qt);
22912 set_buffer_internal_1 (XBUFFER (buffer));
22914 init_iterator (&it, w, -1, -1, NULL, face_id);
22916 if (no_props)
22918 mode_line_target = MODE_LINE_NOPROP;
22919 mode_line_string_face_prop = Qnil;
22920 mode_line_string_list = Qnil;
22921 string_start = MODE_LINE_NOPROP_LEN (0);
22923 else
22925 mode_line_target = MODE_LINE_STRING;
22926 mode_line_string_list = Qnil;
22927 mode_line_string_face = face;
22928 mode_line_string_face_prop
22929 = NILP (face) ? Qnil : list2 (Qface, face);
22932 push_kboard (FRAME_KBOARD (it.f));
22933 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
22934 pop_kboard ();
22936 if (no_props)
22938 len = MODE_LINE_NOPROP_LEN (string_start);
22939 str = make_string (mode_line_noprop_buf + string_start, len);
22941 else
22943 mode_line_string_list = Fnreverse (mode_line_string_list);
22944 str = Fmapconcat (intern ("identity"), mode_line_string_list,
22945 empty_unibyte_string);
22948 unbind_to (count, Qnil);
22949 return str;
22952 /* Write a null-terminated, right justified decimal representation of
22953 the positive integer D to BUF using a minimal field width WIDTH. */
22955 static void
22956 pint2str (register char *buf, register int width, register ptrdiff_t d)
22958 register char *p = buf;
22960 if (d <= 0)
22961 *p++ = '0';
22962 else
22964 while (d > 0)
22966 *p++ = d % 10 + '0';
22967 d /= 10;
22971 for (width -= (int) (p - buf); width > 0; --width)
22972 *p++ = ' ';
22973 *p-- = '\0';
22974 while (p > buf)
22976 d = *buf;
22977 *buf++ = *p;
22978 *p-- = d;
22982 /* Write a null-terminated, right justified decimal and "human
22983 readable" representation of the nonnegative integer D to BUF using
22984 a minimal field width WIDTH. D should be smaller than 999.5e24. */
22986 static const char power_letter[] =
22988 0, /* no letter */
22989 'k', /* kilo */
22990 'M', /* mega */
22991 'G', /* giga */
22992 'T', /* tera */
22993 'P', /* peta */
22994 'E', /* exa */
22995 'Z', /* zetta */
22996 'Y' /* yotta */
22999 static void
23000 pint2hrstr (char *buf, int width, ptrdiff_t d)
23002 /* We aim to represent the nonnegative integer D as
23003 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
23004 ptrdiff_t quotient = d;
23005 int remainder = 0;
23006 /* -1 means: do not use TENTHS. */
23007 int tenths = -1;
23008 int exponent = 0;
23010 /* Length of QUOTIENT.TENTHS as a string. */
23011 int length;
23013 char * psuffix;
23014 char * p;
23016 if (quotient >= 1000)
23018 /* Scale to the appropriate EXPONENT. */
23021 remainder = quotient % 1000;
23022 quotient /= 1000;
23023 exponent++;
23025 while (quotient >= 1000);
23027 /* Round to nearest and decide whether to use TENTHS or not. */
23028 if (quotient <= 9)
23030 tenths = remainder / 100;
23031 if (remainder % 100 >= 50)
23033 if (tenths < 9)
23034 tenths++;
23035 else
23037 quotient++;
23038 if (quotient == 10)
23039 tenths = -1;
23040 else
23041 tenths = 0;
23045 else
23046 if (remainder >= 500)
23048 if (quotient < 999)
23049 quotient++;
23050 else
23052 quotient = 1;
23053 exponent++;
23054 tenths = 0;
23059 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
23060 if (tenths == -1 && quotient <= 99)
23061 if (quotient <= 9)
23062 length = 1;
23063 else
23064 length = 2;
23065 else
23066 length = 3;
23067 p = psuffix = buf + max (width, length);
23069 /* Print EXPONENT. */
23070 *psuffix++ = power_letter[exponent];
23071 *psuffix = '\0';
23073 /* Print TENTHS. */
23074 if (tenths >= 0)
23076 *--p = '0' + tenths;
23077 *--p = '.';
23080 /* Print QUOTIENT. */
23083 int digit = quotient % 10;
23084 *--p = '0' + digit;
23086 while ((quotient /= 10) != 0);
23088 /* Print leading spaces. */
23089 while (buf < p)
23090 *--p = ' ';
23093 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
23094 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
23095 type of CODING_SYSTEM. Return updated pointer into BUF. */
23097 static unsigned char invalid_eol_type[] = "(*invalid*)";
23099 static char *
23100 decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_flag)
23102 Lisp_Object val;
23103 bool multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
23104 const unsigned char *eol_str;
23105 int eol_str_len;
23106 /* The EOL conversion we are using. */
23107 Lisp_Object eoltype;
23109 val = CODING_SYSTEM_SPEC (coding_system);
23110 eoltype = Qnil;
23112 if (!VECTORP (val)) /* Not yet decided. */
23114 *buf++ = multibyte ? '-' : ' ';
23115 if (eol_flag)
23116 eoltype = eol_mnemonic_undecided;
23117 /* Don't mention EOL conversion if it isn't decided. */
23119 else
23121 Lisp_Object attrs;
23122 Lisp_Object eolvalue;
23124 attrs = AREF (val, 0);
23125 eolvalue = AREF (val, 2);
23127 *buf++ = multibyte
23128 ? XFASTINT (CODING_ATTR_MNEMONIC (attrs))
23129 : ' ';
23131 if (eol_flag)
23133 /* The EOL conversion that is normal on this system. */
23135 if (NILP (eolvalue)) /* Not yet decided. */
23136 eoltype = eol_mnemonic_undecided;
23137 else if (VECTORP (eolvalue)) /* Not yet decided. */
23138 eoltype = eol_mnemonic_undecided;
23139 else /* eolvalue is Qunix, Qdos, or Qmac. */
23140 eoltype = (EQ (eolvalue, Qunix)
23141 ? eol_mnemonic_unix
23142 : (EQ (eolvalue, Qdos) == 1
23143 ? eol_mnemonic_dos : eol_mnemonic_mac));
23147 if (eol_flag)
23149 /* Mention the EOL conversion if it is not the usual one. */
23150 if (STRINGP (eoltype))
23152 eol_str = SDATA (eoltype);
23153 eol_str_len = SBYTES (eoltype);
23155 else if (CHARACTERP (eoltype))
23157 int c = XFASTINT (eoltype);
23158 return buf + CHAR_STRING (c, (unsigned char *) buf);
23160 else
23162 eol_str = invalid_eol_type;
23163 eol_str_len = sizeof (invalid_eol_type) - 1;
23165 memcpy (buf, eol_str, eol_str_len);
23166 buf += eol_str_len;
23169 return buf;
23172 /* Return a string for the output of a mode line %-spec for window W,
23173 generated by character C. FIELD_WIDTH > 0 means pad the string
23174 returned with spaces to that value. Return a Lisp string in
23175 *STRING if the resulting string is taken from that Lisp string.
23177 Note we operate on the current buffer for most purposes. */
23179 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
23181 static const char *
23182 decode_mode_spec (struct window *w, register int c, int field_width,
23183 Lisp_Object *string)
23185 Lisp_Object obj;
23186 struct frame *f = XFRAME (WINDOW_FRAME (w));
23187 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
23188 /* We are going to use f->decode_mode_spec_buffer as the buffer to
23189 produce strings from numerical values, so limit preposterously
23190 large values of FIELD_WIDTH to avoid overrunning the buffer's
23191 end. The size of the buffer is enough for FRAME_MESSAGE_BUF_SIZE
23192 bytes plus the terminating null. */
23193 int width = min (field_width, FRAME_MESSAGE_BUF_SIZE (f));
23194 struct buffer *b = current_buffer;
23196 obj = Qnil;
23197 *string = Qnil;
23199 switch (c)
23201 case '*':
23202 if (!NILP (BVAR (b, read_only)))
23203 return "%";
23204 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
23205 return "*";
23206 return "-";
23208 case '+':
23209 /* This differs from %* only for a modified read-only buffer. */
23210 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
23211 return "*";
23212 if (!NILP (BVAR (b, read_only)))
23213 return "%";
23214 return "-";
23216 case '&':
23217 /* This differs from %* in ignoring read-only-ness. */
23218 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
23219 return "*";
23220 return "-";
23222 case '%':
23223 return "%";
23225 case '[':
23227 int i;
23228 char *p;
23230 if (command_loop_level > 5)
23231 return "[[[... ";
23232 p = decode_mode_spec_buf;
23233 for (i = 0; i < command_loop_level; i++)
23234 *p++ = '[';
23235 *p = 0;
23236 return decode_mode_spec_buf;
23239 case ']':
23241 int i;
23242 char *p;
23244 if (command_loop_level > 5)
23245 return " ...]]]";
23246 p = decode_mode_spec_buf;
23247 for (i = 0; i < command_loop_level; i++)
23248 *p++ = ']';
23249 *p = 0;
23250 return decode_mode_spec_buf;
23253 case '-':
23255 register int i;
23257 /* Let lots_of_dashes be a string of infinite length. */
23258 if (mode_line_target == MODE_LINE_NOPROP
23259 || mode_line_target == MODE_LINE_STRING)
23260 return "--";
23261 if (field_width <= 0
23262 || field_width > sizeof (lots_of_dashes))
23264 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
23265 decode_mode_spec_buf[i] = '-';
23266 decode_mode_spec_buf[i] = '\0';
23267 return decode_mode_spec_buf;
23269 else
23270 return lots_of_dashes;
23273 case 'b':
23274 obj = BVAR (b, name);
23275 break;
23277 case 'c':
23278 /* %c and %l are ignored in `frame-title-format'.
23279 (In redisplay_internal, the frame title is drawn _before_ the
23280 windows are updated, so the stuff which depends on actual
23281 window contents (such as %l) may fail to render properly, or
23282 even crash emacs.) */
23283 if (mode_line_target == MODE_LINE_TITLE)
23284 return "";
23285 else
23287 ptrdiff_t col = current_column ();
23288 w->column_number_displayed = col;
23289 pint2str (decode_mode_spec_buf, width, col);
23290 return decode_mode_spec_buf;
23293 case 'e':
23294 #if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
23296 if (NILP (Vmemory_full))
23297 return "";
23298 else
23299 return "!MEM FULL! ";
23301 #else
23302 return "";
23303 #endif
23305 case 'F':
23306 /* %F displays the frame name. */
23307 if (!NILP (f->title))
23308 return SSDATA (f->title);
23309 if (f->explicit_name || ! FRAME_WINDOW_P (f))
23310 return SSDATA (f->name);
23311 return "Emacs";
23313 case 'f':
23314 obj = BVAR (b, filename);
23315 break;
23317 case 'i':
23319 ptrdiff_t size = ZV - BEGV;
23320 pint2str (decode_mode_spec_buf, width, size);
23321 return decode_mode_spec_buf;
23324 case 'I':
23326 ptrdiff_t size = ZV - BEGV;
23327 pint2hrstr (decode_mode_spec_buf, width, size);
23328 return decode_mode_spec_buf;
23331 case 'l':
23333 ptrdiff_t startpos, startpos_byte, line, linepos, linepos_byte;
23334 ptrdiff_t topline, nlines, height;
23335 ptrdiff_t junk;
23337 /* %c and %l are ignored in `frame-title-format'. */
23338 if (mode_line_target == MODE_LINE_TITLE)
23339 return "";
23341 startpos = marker_position (w->start);
23342 startpos_byte = marker_byte_position (w->start);
23343 height = WINDOW_TOTAL_LINES (w);
23345 /* If we decided that this buffer isn't suitable for line numbers,
23346 don't forget that too fast. */
23347 if (w->base_line_pos == -1)
23348 goto no_value;
23350 /* If the buffer is very big, don't waste time. */
23351 if (INTEGERP (Vline_number_display_limit)
23352 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
23354 w->base_line_pos = 0;
23355 w->base_line_number = 0;
23356 goto no_value;
23359 if (w->base_line_number > 0
23360 && w->base_line_pos > 0
23361 && w->base_line_pos <= startpos)
23363 line = w->base_line_number;
23364 linepos = w->base_line_pos;
23365 linepos_byte = buf_charpos_to_bytepos (b, linepos);
23367 else
23369 line = 1;
23370 linepos = BUF_BEGV (b);
23371 linepos_byte = BUF_BEGV_BYTE (b);
23374 /* Count lines from base line to window start position. */
23375 nlines = display_count_lines (linepos_byte,
23376 startpos_byte,
23377 startpos, &junk);
23379 topline = nlines + line;
23381 /* Determine a new base line, if the old one is too close
23382 or too far away, or if we did not have one.
23383 "Too close" means it's plausible a scroll-down would
23384 go back past it. */
23385 if (startpos == BUF_BEGV (b))
23387 w->base_line_number = topline;
23388 w->base_line_pos = BUF_BEGV (b);
23390 else if (nlines < height + 25 || nlines > height * 3 + 50
23391 || linepos == BUF_BEGV (b))
23393 ptrdiff_t limit = BUF_BEGV (b);
23394 ptrdiff_t limit_byte = BUF_BEGV_BYTE (b);
23395 ptrdiff_t position;
23396 ptrdiff_t distance =
23397 (height * 2 + 30) * line_number_display_limit_width;
23399 if (startpos - distance > limit)
23401 limit = startpos - distance;
23402 limit_byte = CHAR_TO_BYTE (limit);
23405 nlines = display_count_lines (startpos_byte,
23406 limit_byte,
23407 - (height * 2 + 30),
23408 &position);
23409 /* If we couldn't find the lines we wanted within
23410 line_number_display_limit_width chars per line,
23411 give up on line numbers for this window. */
23412 if (position == limit_byte && limit == startpos - distance)
23414 w->base_line_pos = -1;
23415 w->base_line_number = 0;
23416 goto no_value;
23419 w->base_line_number = topline - nlines;
23420 w->base_line_pos = BYTE_TO_CHAR (position);
23423 /* Now count lines from the start pos to point. */
23424 nlines = display_count_lines (startpos_byte,
23425 PT_BYTE, PT, &junk);
23427 /* Record that we did display the line number. */
23428 line_number_displayed = 1;
23430 /* Make the string to show. */
23431 pint2str (decode_mode_spec_buf, width, topline + nlines);
23432 return decode_mode_spec_buf;
23433 no_value:
23435 char *p = decode_mode_spec_buf;
23436 int pad = width - 2;
23437 while (pad-- > 0)
23438 *p++ = ' ';
23439 *p++ = '?';
23440 *p++ = '?';
23441 *p = '\0';
23442 return decode_mode_spec_buf;
23445 break;
23447 case 'm':
23448 obj = BVAR (b, mode_name);
23449 break;
23451 case 'n':
23452 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
23453 return " Narrow";
23454 break;
23456 case 'p':
23458 ptrdiff_t pos = marker_position (w->start);
23459 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
23461 if (w->window_end_pos <= BUF_Z (b) - BUF_ZV (b))
23463 if (pos <= BUF_BEGV (b))
23464 return "All";
23465 else
23466 return "Bottom";
23468 else if (pos <= BUF_BEGV (b))
23469 return "Top";
23470 else
23472 if (total > 1000000)
23473 /* Do it differently for a large value, to avoid overflow. */
23474 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
23475 else
23476 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
23477 /* We can't normally display a 3-digit number,
23478 so get us a 2-digit number that is close. */
23479 if (total == 100)
23480 total = 99;
23481 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
23482 return decode_mode_spec_buf;
23486 /* Display percentage of size above the bottom of the screen. */
23487 case 'P':
23489 ptrdiff_t toppos = marker_position (w->start);
23490 ptrdiff_t botpos = BUF_Z (b) - w->window_end_pos;
23491 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
23493 if (botpos >= BUF_ZV (b))
23495 if (toppos <= BUF_BEGV (b))
23496 return "All";
23497 else
23498 return "Bottom";
23500 else
23502 if (total > 1000000)
23503 /* Do it differently for a large value, to avoid overflow. */
23504 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
23505 else
23506 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
23507 /* We can't normally display a 3-digit number,
23508 so get us a 2-digit number that is close. */
23509 if (total == 100)
23510 total = 99;
23511 if (toppos <= BUF_BEGV (b))
23512 sprintf (decode_mode_spec_buf, "Top%2"pD"d%%", total);
23513 else
23514 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
23515 return decode_mode_spec_buf;
23519 case 's':
23520 /* status of process */
23521 obj = Fget_buffer_process (Fcurrent_buffer ());
23522 if (NILP (obj))
23523 return "no process";
23524 #ifndef MSDOS
23525 obj = Fsymbol_name (Fprocess_status (obj));
23526 #endif
23527 break;
23529 case '@':
23531 ptrdiff_t count = inhibit_garbage_collection ();
23532 Lisp_Object curdir = BVAR (current_buffer, directory);
23533 Lisp_Object val = Qnil;
23535 if (STRINGP (curdir))
23536 val = call1 (intern ("file-remote-p"), curdir);
23538 unbind_to (count, Qnil);
23540 if (NILP (val))
23541 return "-";
23542 else
23543 return "@";
23546 case 'z':
23547 /* coding-system (not including end-of-line format) */
23548 case 'Z':
23549 /* coding-system (including end-of-line type) */
23551 int eol_flag = (c == 'Z');
23552 char *p = decode_mode_spec_buf;
23554 if (! FRAME_WINDOW_P (f))
23556 /* No need to mention EOL here--the terminal never needs
23557 to do EOL conversion. */
23558 p = decode_mode_spec_coding (CODING_ID_NAME
23559 (FRAME_KEYBOARD_CODING (f)->id),
23560 p, 0);
23561 p = decode_mode_spec_coding (CODING_ID_NAME
23562 (FRAME_TERMINAL_CODING (f)->id),
23563 p, 0);
23565 p = decode_mode_spec_coding (BVAR (b, buffer_file_coding_system),
23566 p, eol_flag);
23568 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
23569 #ifdef subprocesses
23570 obj = Fget_buffer_process (Fcurrent_buffer ());
23571 if (PROCESSP (obj))
23573 p = decode_mode_spec_coding
23574 (XPROCESS (obj)->decode_coding_system, p, eol_flag);
23575 p = decode_mode_spec_coding
23576 (XPROCESS (obj)->encode_coding_system, p, eol_flag);
23578 #endif /* subprocesses */
23579 #endif /* 0 */
23580 *p = 0;
23581 return decode_mode_spec_buf;
23585 if (STRINGP (obj))
23587 *string = obj;
23588 return SSDATA (obj);
23590 else
23591 return "";
23595 /* Count up to COUNT lines starting from START_BYTE. COUNT negative
23596 means count lines back from START_BYTE. But don't go beyond
23597 LIMIT_BYTE. Return the number of lines thus found (always
23598 nonnegative).
23600 Set *BYTE_POS_PTR to the byte position where we stopped. This is
23601 either the position COUNT lines after/before START_BYTE, if we
23602 found COUNT lines, or LIMIT_BYTE if we hit the limit before finding
23603 COUNT lines. */
23605 static ptrdiff_t
23606 display_count_lines (ptrdiff_t start_byte,
23607 ptrdiff_t limit_byte, ptrdiff_t count,
23608 ptrdiff_t *byte_pos_ptr)
23610 register unsigned char *cursor;
23611 unsigned char *base;
23613 register ptrdiff_t ceiling;
23614 register unsigned char *ceiling_addr;
23615 ptrdiff_t orig_count = count;
23617 /* If we are not in selective display mode,
23618 check only for newlines. */
23619 int selective_display = (!NILP (BVAR (current_buffer, selective_display))
23620 && !INTEGERP (BVAR (current_buffer, selective_display)));
23622 if (count > 0)
23624 while (start_byte < limit_byte)
23626 ceiling = BUFFER_CEILING_OF (start_byte);
23627 ceiling = min (limit_byte - 1, ceiling);
23628 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
23629 base = (cursor = BYTE_POS_ADDR (start_byte));
23633 if (selective_display)
23635 while (*cursor != '\n' && *cursor != 015
23636 && ++cursor != ceiling_addr)
23637 continue;
23638 if (cursor == ceiling_addr)
23639 break;
23641 else
23643 cursor = memchr (cursor, '\n', ceiling_addr - cursor);
23644 if (! cursor)
23645 break;
23648 cursor++;
23650 if (--count == 0)
23652 start_byte += cursor - base;
23653 *byte_pos_ptr = start_byte;
23654 return orig_count;
23657 while (cursor < ceiling_addr);
23659 start_byte += ceiling_addr - base;
23662 else
23664 while (start_byte > limit_byte)
23666 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
23667 ceiling = max (limit_byte, ceiling);
23668 ceiling_addr = BYTE_POS_ADDR (ceiling);
23669 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
23670 while (1)
23672 if (selective_display)
23674 while (--cursor >= ceiling_addr
23675 && *cursor != '\n' && *cursor != 015)
23676 continue;
23677 if (cursor < ceiling_addr)
23678 break;
23680 else
23682 cursor = memrchr (ceiling_addr, '\n', cursor - ceiling_addr);
23683 if (! cursor)
23684 break;
23687 if (++count == 0)
23689 start_byte += cursor - base + 1;
23690 *byte_pos_ptr = start_byte;
23691 /* When scanning backwards, we should
23692 not count the newline posterior to which we stop. */
23693 return - orig_count - 1;
23696 start_byte += ceiling_addr - base;
23700 *byte_pos_ptr = limit_byte;
23702 if (count < 0)
23703 return - orig_count + count;
23704 return orig_count - count;
23710 /***********************************************************************
23711 Displaying strings
23712 ***********************************************************************/
23714 /* Display a NUL-terminated string, starting with index START.
23716 If STRING is non-null, display that C string. Otherwise, the Lisp
23717 string LISP_STRING is displayed. There's a case that STRING is
23718 non-null and LISP_STRING is not nil. It means STRING is a string
23719 data of LISP_STRING. In that case, we display LISP_STRING while
23720 ignoring its text properties.
23722 If FACE_STRING is not nil, FACE_STRING_POS is a position in
23723 FACE_STRING. Display STRING or LISP_STRING with the face at
23724 FACE_STRING_POS in FACE_STRING:
23726 Display the string in the environment given by IT, but use the
23727 standard display table, temporarily.
23729 FIELD_WIDTH is the minimum number of output glyphs to produce.
23730 If STRING has fewer characters than FIELD_WIDTH, pad to the right
23731 with spaces. If STRING has more characters, more than FIELD_WIDTH
23732 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
23734 PRECISION is the maximum number of characters to output from
23735 STRING. PRECISION < 0 means don't truncate the string.
23737 This is roughly equivalent to printf format specifiers:
23739 FIELD_WIDTH PRECISION PRINTF
23740 ----------------------------------------
23741 -1 -1 %s
23742 -1 10 %.10s
23743 10 -1 %10s
23744 20 10 %20.10s
23746 MULTIBYTE zero means do not display multibyte chars, > 0 means do
23747 display them, and < 0 means obey the current buffer's value of
23748 enable_multibyte_characters.
23750 Value is the number of columns displayed. */
23752 static int
23753 display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_string,
23754 ptrdiff_t face_string_pos, ptrdiff_t start, struct it *it,
23755 int field_width, int precision, int max_x, int multibyte)
23757 int hpos_at_start = it->hpos;
23758 int saved_face_id = it->face_id;
23759 struct glyph_row *row = it->glyph_row;
23760 ptrdiff_t it_charpos;
23762 /* Initialize the iterator IT for iteration over STRING beginning
23763 with index START. */
23764 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
23765 precision, field_width, multibyte);
23766 if (string && STRINGP (lisp_string))
23767 /* LISP_STRING is the one returned by decode_mode_spec. We should
23768 ignore its text properties. */
23769 it->stop_charpos = it->end_charpos;
23771 /* If displaying STRING, set up the face of the iterator from
23772 FACE_STRING, if that's given. */
23773 if (STRINGP (face_string))
23775 ptrdiff_t endptr;
23776 struct face *face;
23778 it->face_id
23779 = face_at_string_position (it->w, face_string, face_string_pos,
23780 0, &endptr, it->base_face_id, 0);
23781 face = FACE_FROM_ID (it->f, it->face_id);
23782 it->face_box_p = face->box != FACE_NO_BOX;
23785 /* Set max_x to the maximum allowed X position. Don't let it go
23786 beyond the right edge of the window. */
23787 if (max_x <= 0)
23788 max_x = it->last_visible_x;
23789 else
23790 max_x = min (max_x, it->last_visible_x);
23792 /* Skip over display elements that are not visible. because IT->w is
23793 hscrolled. */
23794 if (it->current_x < it->first_visible_x)
23795 move_it_in_display_line_to (it, 100000, it->first_visible_x,
23796 MOVE_TO_POS | MOVE_TO_X);
23798 row->ascent = it->max_ascent;
23799 row->height = it->max_ascent + it->max_descent;
23800 row->phys_ascent = it->max_phys_ascent;
23801 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
23802 row->extra_line_spacing = it->max_extra_line_spacing;
23804 if (STRINGP (it->string))
23805 it_charpos = IT_STRING_CHARPOS (*it);
23806 else
23807 it_charpos = IT_CHARPOS (*it);
23809 /* This condition is for the case that we are called with current_x
23810 past last_visible_x. */
23811 while (it->current_x < max_x)
23813 int x_before, x, n_glyphs_before, i, nglyphs;
23815 /* Get the next display element. */
23816 if (!get_next_display_element (it))
23817 break;
23819 /* Produce glyphs. */
23820 x_before = it->current_x;
23821 n_glyphs_before = row->used[TEXT_AREA];
23822 PRODUCE_GLYPHS (it);
23824 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
23825 i = 0;
23826 x = x_before;
23827 while (i < nglyphs)
23829 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
23831 if (it->line_wrap != TRUNCATE
23832 && x + glyph->pixel_width > max_x)
23834 /* End of continued line or max_x reached. */
23835 if (CHAR_GLYPH_PADDING_P (*glyph))
23837 /* A wide character is unbreakable. */
23838 if (row->reversed_p)
23839 unproduce_glyphs (it, row->used[TEXT_AREA]
23840 - n_glyphs_before);
23841 row->used[TEXT_AREA] = n_glyphs_before;
23842 it->current_x = x_before;
23844 else
23846 if (row->reversed_p)
23847 unproduce_glyphs (it, row->used[TEXT_AREA]
23848 - (n_glyphs_before + i));
23849 row->used[TEXT_AREA] = n_glyphs_before + i;
23850 it->current_x = x;
23852 break;
23854 else if (x + glyph->pixel_width >= it->first_visible_x)
23856 /* Glyph is at least partially visible. */
23857 ++it->hpos;
23858 if (x < it->first_visible_x)
23859 row->x = x - it->first_visible_x;
23861 else
23863 /* Glyph is off the left margin of the display area.
23864 Should not happen. */
23865 emacs_abort ();
23868 row->ascent = max (row->ascent, it->max_ascent);
23869 row->height = max (row->height, it->max_ascent + it->max_descent);
23870 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
23871 row->phys_height = max (row->phys_height,
23872 it->max_phys_ascent + it->max_phys_descent);
23873 row->extra_line_spacing = max (row->extra_line_spacing,
23874 it->max_extra_line_spacing);
23875 x += glyph->pixel_width;
23876 ++i;
23879 /* Stop if max_x reached. */
23880 if (i < nglyphs)
23881 break;
23883 /* Stop at line ends. */
23884 if (ITERATOR_AT_END_OF_LINE_P (it))
23886 it->continuation_lines_width = 0;
23887 break;
23890 set_iterator_to_next (it, 1);
23891 if (STRINGP (it->string))
23892 it_charpos = IT_STRING_CHARPOS (*it);
23893 else
23894 it_charpos = IT_CHARPOS (*it);
23896 /* Stop if truncating at the right edge. */
23897 if (it->line_wrap == TRUNCATE
23898 && it->current_x >= it->last_visible_x)
23900 /* Add truncation mark, but don't do it if the line is
23901 truncated at a padding space. */
23902 if (it_charpos < it->string_nchars)
23904 if (!FRAME_WINDOW_P (it->f))
23906 int ii, n;
23908 if (it->current_x > it->last_visible_x)
23910 if (!row->reversed_p)
23912 for (ii = row->used[TEXT_AREA] - 1; ii > 0; --ii)
23913 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
23914 break;
23916 else
23918 for (ii = 0; ii < row->used[TEXT_AREA]; ii++)
23919 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
23920 break;
23921 unproduce_glyphs (it, ii + 1);
23922 ii = row->used[TEXT_AREA] - (ii + 1);
23924 for (n = row->used[TEXT_AREA]; ii < n; ++ii)
23926 row->used[TEXT_AREA] = ii;
23927 produce_special_glyphs (it, IT_TRUNCATION);
23930 produce_special_glyphs (it, IT_TRUNCATION);
23932 row->truncated_on_right_p = 1;
23934 break;
23938 /* Maybe insert a truncation at the left. */
23939 if (it->first_visible_x
23940 && it_charpos > 0)
23942 if (!FRAME_WINDOW_P (it->f)
23943 || (row->reversed_p
23944 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
23945 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
23946 insert_left_trunc_glyphs (it);
23947 row->truncated_on_left_p = 1;
23950 it->face_id = saved_face_id;
23952 /* Value is number of columns displayed. */
23953 return it->hpos - hpos_at_start;
23958 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
23959 appears as an element of LIST or as the car of an element of LIST.
23960 If PROPVAL is a list, compare each element against LIST in that
23961 way, and return 1/2 if any element of PROPVAL is found in LIST.
23962 Otherwise return 0. This function cannot quit.
23963 The return value is 2 if the text is invisible but with an ellipsis
23964 and 1 if it's invisible and without an ellipsis. */
23967 invisible_p (register Lisp_Object propval, Lisp_Object list)
23969 register Lisp_Object tail, proptail;
23971 for (tail = list; CONSP (tail); tail = XCDR (tail))
23973 register Lisp_Object tem;
23974 tem = XCAR (tail);
23975 if (EQ (propval, tem))
23976 return 1;
23977 if (CONSP (tem) && EQ (propval, XCAR (tem)))
23978 return NILP (XCDR (tem)) ? 1 : 2;
23981 if (CONSP (propval))
23983 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
23985 Lisp_Object propelt;
23986 propelt = XCAR (proptail);
23987 for (tail = list; CONSP (tail); tail = XCDR (tail))
23989 register Lisp_Object tem;
23990 tem = XCAR (tail);
23991 if (EQ (propelt, tem))
23992 return 1;
23993 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
23994 return NILP (XCDR (tem)) ? 1 : 2;
23999 return 0;
24002 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
24003 doc: /* Non-nil if the property makes the text invisible.
24004 POS-OR-PROP can be a marker or number, in which case it is taken to be
24005 a position in the current buffer and the value of the `invisible' property
24006 is checked; or it can be some other value, which is then presumed to be the
24007 value of the `invisible' property of the text of interest.
24008 The non-nil value returned can be t for truly invisible text or something
24009 else if the text is replaced by an ellipsis. */)
24010 (Lisp_Object pos_or_prop)
24012 Lisp_Object prop
24013 = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
24014 ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
24015 : pos_or_prop);
24016 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
24017 return (invis == 0 ? Qnil
24018 : invis == 1 ? Qt
24019 : make_number (invis));
24022 /* Calculate a width or height in pixels from a specification using
24023 the following elements:
24025 SPEC ::=
24026 NUM - a (fractional) multiple of the default font width/height
24027 (NUM) - specifies exactly NUM pixels
24028 UNIT - a fixed number of pixels, see below.
24029 ELEMENT - size of a display element in pixels, see below.
24030 (NUM . SPEC) - equals NUM * SPEC
24031 (+ SPEC SPEC ...) - add pixel values
24032 (- SPEC SPEC ...) - subtract pixel values
24033 (- SPEC) - negate pixel value
24035 NUM ::=
24036 INT or FLOAT - a number constant
24037 SYMBOL - use symbol's (buffer local) variable binding.
24039 UNIT ::=
24040 in - pixels per inch *)
24041 mm - pixels per 1/1000 meter *)
24042 cm - pixels per 1/100 meter *)
24043 width - width of current font in pixels.
24044 height - height of current font in pixels.
24046 *) using the ratio(s) defined in display-pixels-per-inch.
24048 ELEMENT ::=
24050 left-fringe - left fringe width in pixels
24051 right-fringe - right fringe width in pixels
24053 left-margin - left margin width in pixels
24054 right-margin - right margin width in pixels
24056 scroll-bar - scroll-bar area width in pixels
24058 Examples:
24060 Pixels corresponding to 5 inches:
24061 (5 . in)
24063 Total width of non-text areas on left side of window (if scroll-bar is on left):
24064 '(space :width (+ left-fringe left-margin scroll-bar))
24066 Align to first text column (in header line):
24067 '(space :align-to 0)
24069 Align to middle of text area minus half the width of variable `my-image'
24070 containing a loaded image:
24071 '(space :align-to (0.5 . (- text my-image)))
24073 Width of left margin minus width of 1 character in the default font:
24074 '(space :width (- left-margin 1))
24076 Width of left margin minus width of 2 characters in the current font:
24077 '(space :width (- left-margin (2 . width)))
24079 Center 1 character over left-margin (in header line):
24080 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
24082 Different ways to express width of left fringe plus left margin minus one pixel:
24083 '(space :width (- (+ left-fringe left-margin) (1)))
24084 '(space :width (+ left-fringe left-margin (- (1))))
24085 '(space :width (+ left-fringe left-margin (-1)))
24089 static int
24090 calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
24091 struct font *font, int width_p, int *align_to)
24093 double pixels;
24095 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
24096 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
24098 if (NILP (prop))
24099 return OK_PIXELS (0);
24101 eassert (FRAME_LIVE_P (it->f));
24103 if (SYMBOLP (prop))
24105 if (SCHARS (SYMBOL_NAME (prop)) == 2)
24107 char *unit = SSDATA (SYMBOL_NAME (prop));
24109 if (unit[0] == 'i' && unit[1] == 'n')
24110 pixels = 1.0;
24111 else if (unit[0] == 'm' && unit[1] == 'm')
24112 pixels = 25.4;
24113 else if (unit[0] == 'c' && unit[1] == 'm')
24114 pixels = 2.54;
24115 else
24116 pixels = 0;
24117 if (pixels > 0)
24119 double ppi = (width_p ? FRAME_RES_X (it->f)
24120 : FRAME_RES_Y (it->f));
24122 if (ppi > 0)
24123 return OK_PIXELS (ppi / pixels);
24124 return 0;
24128 #ifdef HAVE_WINDOW_SYSTEM
24129 if (EQ (prop, Qheight))
24130 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
24131 if (EQ (prop, Qwidth))
24132 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
24133 #else
24134 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
24135 return OK_PIXELS (1);
24136 #endif
24138 if (EQ (prop, Qtext))
24139 return OK_PIXELS (width_p
24140 ? window_box_width (it->w, TEXT_AREA)
24141 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
24143 if (align_to && *align_to < 0)
24145 *res = 0;
24146 if (EQ (prop, Qleft))
24147 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
24148 if (EQ (prop, Qright))
24149 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
24150 if (EQ (prop, Qcenter))
24151 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
24152 + window_box_width (it->w, TEXT_AREA) / 2);
24153 if (EQ (prop, Qleft_fringe))
24154 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
24155 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
24156 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
24157 if (EQ (prop, Qright_fringe))
24158 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
24159 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
24160 : window_box_right_offset (it->w, TEXT_AREA));
24161 if (EQ (prop, Qleft_margin))
24162 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
24163 if (EQ (prop, Qright_margin))
24164 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
24165 if (EQ (prop, Qscroll_bar))
24166 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
24168 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
24169 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
24170 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
24171 : 0)));
24173 else
24175 if (EQ (prop, Qleft_fringe))
24176 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
24177 if (EQ (prop, Qright_fringe))
24178 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
24179 if (EQ (prop, Qleft_margin))
24180 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
24181 if (EQ (prop, Qright_margin))
24182 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
24183 if (EQ (prop, Qscroll_bar))
24184 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
24187 prop = buffer_local_value (prop, it->w->contents);
24188 if (EQ (prop, Qunbound))
24189 prop = Qnil;
24192 if (INTEGERP (prop) || FLOATP (prop))
24194 int base_unit = (width_p
24195 ? FRAME_COLUMN_WIDTH (it->f)
24196 : FRAME_LINE_HEIGHT (it->f));
24197 return OK_PIXELS (XFLOATINT (prop) * base_unit);
24200 if (CONSP (prop))
24202 Lisp_Object car = XCAR (prop);
24203 Lisp_Object cdr = XCDR (prop);
24205 if (SYMBOLP (car))
24207 #ifdef HAVE_WINDOW_SYSTEM
24208 if (FRAME_WINDOW_P (it->f)
24209 && valid_image_p (prop))
24211 ptrdiff_t id = lookup_image (it->f, prop);
24212 struct image *img = IMAGE_FROM_ID (it->f, id);
24214 return OK_PIXELS (width_p ? img->width : img->height);
24216 #ifdef HAVE_XWIDGETS
24217 if (FRAME_WINDOW_P (it->f) && valid_xwidget_spec_p (prop))
24219 printf("calc_pixel_width_or_height: return dummy size FIXME\n");
24220 return OK_PIXELS (width_p ? 100 : 100);
24222 #endif
24223 #endif
24224 if (EQ (car, Qplus) || EQ (car, Qminus))
24226 int first = 1;
24227 double px;
24229 pixels = 0;
24230 while (CONSP (cdr))
24232 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
24233 font, width_p, align_to))
24234 return 0;
24235 if (first)
24236 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
24237 else
24238 pixels += px;
24239 cdr = XCDR (cdr);
24241 if (EQ (car, Qminus))
24242 pixels = -pixels;
24243 return OK_PIXELS (pixels);
24246 car = buffer_local_value (car, it->w->contents);
24247 if (EQ (car, Qunbound))
24248 car = Qnil;
24251 if (INTEGERP (car) || FLOATP (car))
24253 double fact;
24254 pixels = XFLOATINT (car);
24255 if (NILP (cdr))
24256 return OK_PIXELS (pixels);
24257 if (calc_pixel_width_or_height (&fact, it, cdr,
24258 font, width_p, align_to))
24259 return OK_PIXELS (pixels * fact);
24260 return 0;
24263 return 0;
24266 return 0;
24270 /***********************************************************************
24271 Glyph Display
24272 ***********************************************************************/
24274 #ifdef HAVE_WINDOW_SYSTEM
24276 #ifdef GLYPH_DEBUG
24278 void
24279 dump_glyph_string (struct glyph_string *s)
24281 fprintf (stderr, "glyph string\n");
24282 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
24283 s->x, s->y, s->width, s->height);
24284 fprintf (stderr, " ybase = %d\n", s->ybase);
24285 fprintf (stderr, " hl = %d\n", s->hl);
24286 fprintf (stderr, " left overhang = %d, right = %d\n",
24287 s->left_overhang, s->right_overhang);
24288 fprintf (stderr, " nchars = %d\n", s->nchars);
24289 fprintf (stderr, " extends to end of line = %d\n",
24290 s->extends_to_end_of_line_p);
24291 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
24292 fprintf (stderr, " bg width = %d\n", s->background_width);
24295 #endif /* GLYPH_DEBUG */
24297 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
24298 of XChar2b structures for S; it can't be allocated in
24299 init_glyph_string because it must be allocated via `alloca'. W
24300 is the window on which S is drawn. ROW and AREA are the glyph row
24301 and area within the row from which S is constructed. START is the
24302 index of the first glyph structure covered by S. HL is a
24303 face-override for drawing S. */
24305 #ifdef HAVE_NTGUI
24306 #define OPTIONAL_HDC(hdc) HDC hdc,
24307 #define DECLARE_HDC(hdc) HDC hdc;
24308 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
24309 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
24310 #endif
24312 #ifndef OPTIONAL_HDC
24313 #define OPTIONAL_HDC(hdc)
24314 #define DECLARE_HDC(hdc)
24315 #define ALLOCATE_HDC(hdc, f)
24316 #define RELEASE_HDC(hdc, f)
24317 #endif
24319 static void
24320 init_glyph_string (struct glyph_string *s,
24321 OPTIONAL_HDC (hdc)
24322 XChar2b *char2b, struct window *w, struct glyph_row *row,
24323 enum glyph_row_area area, int start, enum draw_glyphs_face hl)
24325 memset (s, 0, sizeof *s);
24326 s->w = w;
24327 s->f = XFRAME (w->frame);
24328 #ifdef HAVE_NTGUI
24329 s->hdc = hdc;
24330 #endif
24331 s->display = FRAME_X_DISPLAY (s->f);
24332 s->window = FRAME_X_WINDOW (s->f);
24333 s->char2b = char2b;
24334 s->hl = hl;
24335 s->row = row;
24336 s->area = area;
24337 s->first_glyph = row->glyphs[area] + start;
24338 s->height = row->height;
24339 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
24340 s->ybase = s->y + row->ascent;
24344 /* Append the list of glyph strings with head H and tail T to the list
24345 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
24347 static void
24348 append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
24349 struct glyph_string *h, struct glyph_string *t)
24351 if (h)
24353 if (*head)
24354 (*tail)->next = h;
24355 else
24356 *head = h;
24357 h->prev = *tail;
24358 *tail = t;
24363 /* Prepend the list of glyph strings with head H and tail T to the
24364 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
24365 result. */
24367 static void
24368 prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
24369 struct glyph_string *h, struct glyph_string *t)
24371 if (h)
24373 if (*head)
24374 (*head)->prev = t;
24375 else
24376 *tail = t;
24377 t->next = *head;
24378 *head = h;
24383 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
24384 Set *HEAD and *TAIL to the resulting list. */
24386 static void
24387 append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
24388 struct glyph_string *s)
24390 s->next = s->prev = NULL;
24391 append_glyph_string_lists (head, tail, s, s);
24395 /* Get face and two-byte form of character C in face FACE_ID on frame F.
24396 The encoding of C is returned in *CHAR2B. DISPLAY_P non-zero means
24397 make sure that X resources for the face returned are allocated.
24398 Value is a pointer to a realized face that is ready for display if
24399 DISPLAY_P is non-zero. */
24401 static struct face *
24402 get_char_face_and_encoding (struct frame *f, int c, int face_id,
24403 XChar2b *char2b, int display_p)
24405 struct face *face = FACE_FROM_ID (f, face_id);
24406 unsigned code = 0;
24408 if (face->font)
24410 code = face->font->driver->encode_char (face->font, c);
24412 if (code == FONT_INVALID_CODE)
24413 code = 0;
24415 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
24417 /* Make sure X resources of the face are allocated. */
24418 #ifdef HAVE_X_WINDOWS
24419 if (display_p)
24420 #endif
24422 eassert (face != NULL);
24423 prepare_face_for_display (f, face);
24426 return face;
24430 /* Get face and two-byte form of character glyph GLYPH on frame F.
24431 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
24432 a pointer to a realized face that is ready for display. */
24434 static struct face *
24435 get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
24436 XChar2b *char2b, int *two_byte_p)
24438 struct face *face;
24439 unsigned code = 0;
24441 eassert (glyph->type == CHAR_GLYPH);
24442 face = FACE_FROM_ID (f, glyph->face_id);
24444 /* Make sure X resources of the face are allocated. */
24445 eassert (face != NULL);
24446 prepare_face_for_display (f, face);
24448 if (two_byte_p)
24449 *two_byte_p = 0;
24451 if (face->font)
24453 if (CHAR_BYTE8_P (glyph->u.ch))
24454 code = CHAR_TO_BYTE8 (glyph->u.ch);
24455 else
24456 code = face->font->driver->encode_char (face->font, glyph->u.ch);
24458 if (code == FONT_INVALID_CODE)
24459 code = 0;
24462 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
24463 return face;
24467 /* Get glyph code of character C in FONT in the two-byte form CHAR2B.
24468 Return 1 if FONT has a glyph for C, otherwise return 0. */
24470 static int
24471 get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
24473 unsigned code;
24475 if (CHAR_BYTE8_P (c))
24476 code = CHAR_TO_BYTE8 (c);
24477 else
24478 code = font->driver->encode_char (font, c);
24480 if (code == FONT_INVALID_CODE)
24481 return 0;
24482 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
24483 return 1;
24487 /* Fill glyph string S with composition components specified by S->cmp.
24489 BASE_FACE is the base face of the composition.
24490 S->cmp_from is the index of the first component for S.
24492 OVERLAPS non-zero means S should draw the foreground only, and use
24493 its physical height for clipping. See also draw_glyphs.
24495 Value is the index of a component not in S. */
24497 static int
24498 fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
24499 int overlaps)
24501 int i;
24502 /* For all glyphs of this composition, starting at the offset
24503 S->cmp_from, until we reach the end of the definition or encounter a
24504 glyph that requires the different face, add it to S. */
24505 struct face *face;
24507 eassert (s);
24509 s->for_overlaps = overlaps;
24510 s->face = NULL;
24511 s->font = NULL;
24512 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
24514 int c = COMPOSITION_GLYPH (s->cmp, i);
24516 /* TAB in a composition means display glyphs with padding space
24517 on the left or right. */
24518 if (c != '\t')
24520 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
24521 -1, Qnil);
24523 face = get_char_face_and_encoding (s->f, c, face_id,
24524 s->char2b + i, 1);
24525 if (face)
24527 if (! s->face)
24529 s->face = face;
24530 s->font = s->face->font;
24532 else if (s->face != face)
24533 break;
24536 ++s->nchars;
24538 s->cmp_to = i;
24540 if (s->face == NULL)
24542 s->face = base_face->ascii_face;
24543 s->font = s->face->font;
24546 /* All glyph strings for the same composition has the same width,
24547 i.e. the width set for the first component of the composition. */
24548 s->width = s->first_glyph->pixel_width;
24550 /* If the specified font could not be loaded, use the frame's
24551 default font, but record the fact that we couldn't load it in
24552 the glyph string so that we can draw rectangles for the
24553 characters of the glyph string. */
24554 if (s->font == NULL)
24556 s->font_not_found_p = 1;
24557 s->font = FRAME_FONT (s->f);
24560 /* Adjust base line for subscript/superscript text. */
24561 s->ybase += s->first_glyph->voffset;
24563 /* This glyph string must always be drawn with 16-bit functions. */
24564 s->two_byte_p = 1;
24566 return s->cmp_to;
24569 static int
24570 fill_gstring_glyph_string (struct glyph_string *s, int face_id,
24571 int start, int end, int overlaps)
24573 struct glyph *glyph, *last;
24574 Lisp_Object lgstring;
24575 int i;
24577 s->for_overlaps = overlaps;
24578 glyph = s->row->glyphs[s->area] + start;
24579 last = s->row->glyphs[s->area] + end;
24580 s->cmp_id = glyph->u.cmp.id;
24581 s->cmp_from = glyph->slice.cmp.from;
24582 s->cmp_to = glyph->slice.cmp.to + 1;
24583 s->face = FACE_FROM_ID (s->f, face_id);
24584 lgstring = composition_gstring_from_id (s->cmp_id);
24585 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
24586 glyph++;
24587 while (glyph < last
24588 && glyph->u.cmp.automatic
24589 && glyph->u.cmp.id == s->cmp_id
24590 && s->cmp_to == glyph->slice.cmp.from)
24591 s->cmp_to = (glyph++)->slice.cmp.to + 1;
24593 for (i = s->cmp_from; i < s->cmp_to; i++)
24595 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
24596 unsigned code = LGLYPH_CODE (lglyph);
24598 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
24600 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
24601 return glyph - s->row->glyphs[s->area];
24605 /* Fill glyph string S from a sequence glyphs for glyphless characters.
24606 See the comment of fill_glyph_string for arguments.
24607 Value is the index of the first glyph not in S. */
24610 static int
24611 fill_glyphless_glyph_string (struct glyph_string *s, int face_id,
24612 int start, int end, int overlaps)
24614 struct glyph *glyph, *last;
24615 int voffset;
24617 eassert (s->first_glyph->type == GLYPHLESS_GLYPH);
24618 s->for_overlaps = overlaps;
24619 glyph = s->row->glyphs[s->area] + start;
24620 last = s->row->glyphs[s->area] + end;
24621 voffset = glyph->voffset;
24622 s->face = FACE_FROM_ID (s->f, face_id);
24623 s->font = s->face->font ? s->face->font : FRAME_FONT (s->f);
24624 s->nchars = 1;
24625 s->width = glyph->pixel_width;
24626 glyph++;
24627 while (glyph < last
24628 && glyph->type == GLYPHLESS_GLYPH
24629 && glyph->voffset == voffset
24630 && glyph->face_id == face_id)
24632 s->nchars++;
24633 s->width += glyph->pixel_width;
24634 glyph++;
24636 s->ybase += voffset;
24637 return glyph - s->row->glyphs[s->area];
24641 /* Fill glyph string S from a sequence of character glyphs.
24643 FACE_ID is the face id of the string. START is the index of the
24644 first glyph to consider, END is the index of the last + 1.
24645 OVERLAPS non-zero means S should draw the foreground only, and use
24646 its physical height for clipping. See also draw_glyphs.
24648 Value is the index of the first glyph not in S. */
24650 static int
24651 fill_glyph_string (struct glyph_string *s, int face_id,
24652 int start, int end, int overlaps)
24654 struct glyph *glyph, *last;
24655 int voffset;
24656 int glyph_not_available_p;
24658 eassert (s->f == XFRAME (s->w->frame));
24659 eassert (s->nchars == 0);
24660 eassert (start >= 0 && end > start);
24662 s->for_overlaps = overlaps;
24663 glyph = s->row->glyphs[s->area] + start;
24664 last = s->row->glyphs[s->area] + end;
24665 voffset = glyph->voffset;
24666 s->padding_p = glyph->padding_p;
24667 glyph_not_available_p = glyph->glyph_not_available_p;
24669 while (glyph < last
24670 && glyph->type == CHAR_GLYPH
24671 && glyph->voffset == voffset
24672 /* Same face id implies same font, nowadays. */
24673 && glyph->face_id == face_id
24674 && glyph->glyph_not_available_p == glyph_not_available_p)
24676 int two_byte_p;
24678 s->face = get_glyph_face_and_encoding (s->f, glyph,
24679 s->char2b + s->nchars,
24680 &two_byte_p);
24681 s->two_byte_p = two_byte_p;
24682 ++s->nchars;
24683 eassert (s->nchars <= end - start);
24684 s->width += glyph->pixel_width;
24685 if (glyph++->padding_p != s->padding_p)
24686 break;
24689 s->font = s->face->font;
24691 /* If the specified font could not be loaded, use the frame's font,
24692 but record the fact that we couldn't load it in
24693 S->font_not_found_p so that we can draw rectangles for the
24694 characters of the glyph string. */
24695 if (s->font == NULL || glyph_not_available_p)
24697 s->font_not_found_p = 1;
24698 s->font = FRAME_FONT (s->f);
24701 /* Adjust base line for subscript/superscript text. */
24702 s->ybase += voffset;
24704 eassert (s->face && s->face->gc);
24705 return glyph - s->row->glyphs[s->area];
24709 /* Fill glyph string S from image glyph S->first_glyph. */
24711 static void
24712 fill_image_glyph_string (struct glyph_string *s)
24714 eassert (s->first_glyph->type == IMAGE_GLYPH);
24715 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
24716 eassert (s->img);
24717 s->slice = s->first_glyph->slice.img;
24718 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
24719 s->font = s->face->font;
24720 s->width = s->first_glyph->pixel_width;
24722 /* Adjust base line for subscript/superscript text. */
24723 s->ybase += s->first_glyph->voffset;
24727 #ifdef HAVE_XWIDGETS
24728 static void
24729 fill_xwidget_glyph_string (struct glyph_string *s)
24731 eassert (s->first_glyph->type == XWIDGET_GLYPH);
24732 printf("fill_xwidget_glyph_string: width:%d \n",s->first_glyph->pixel_width);
24733 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
24734 s->font = s->face->font;
24735 s->width = s->first_glyph->pixel_width;
24736 s->ybase += s->first_glyph->voffset;
24737 s->xwidget = s->first_glyph->u.xwidget;
24738 //assert_valid_xwidget_id ( s->xwidget, "fill_xwidget_glyph_string");
24740 #endif
24741 /* Fill glyph string S from a sequence of stretch glyphs.
24743 START is the index of the first glyph to consider,
24744 END is the index of the last + 1.
24746 Value is the index of the first glyph not in S. */
24748 static int
24749 fill_stretch_glyph_string (struct glyph_string *s, int start, int end)
24751 struct glyph *glyph, *last;
24752 int voffset, face_id;
24754 eassert (s->first_glyph->type == STRETCH_GLYPH);
24756 glyph = s->row->glyphs[s->area] + start;
24757 last = s->row->glyphs[s->area] + end;
24758 face_id = glyph->face_id;
24759 s->face = FACE_FROM_ID (s->f, face_id);
24760 s->font = s->face->font;
24761 s->width = glyph->pixel_width;
24762 s->nchars = 1;
24763 voffset = glyph->voffset;
24765 for (++glyph;
24766 (glyph < last
24767 && glyph->type == STRETCH_GLYPH
24768 && glyph->voffset == voffset
24769 && glyph->face_id == face_id);
24770 ++glyph)
24771 s->width += glyph->pixel_width;
24773 /* Adjust base line for subscript/superscript text. */
24774 s->ybase += voffset;
24776 /* The case that face->gc == 0 is handled when drawing the glyph
24777 string by calling prepare_face_for_display. */
24778 eassert (s->face);
24779 return glyph - s->row->glyphs[s->area];
24782 static struct font_metrics *
24783 get_per_char_metric (struct font *font, XChar2b *char2b)
24785 static struct font_metrics metrics;
24786 unsigned code;
24788 if (! font)
24789 return NULL;
24790 code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
24791 if (code == FONT_INVALID_CODE)
24792 return NULL;
24793 font->driver->text_extents (font, &code, 1, &metrics);
24794 return &metrics;
24797 /* EXPORT for RIF:
24798 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
24799 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
24800 assumed to be zero. */
24802 void
24803 x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *right)
24805 *left = *right = 0;
24807 if (glyph->type == CHAR_GLYPH)
24809 struct face *face;
24810 XChar2b char2b;
24811 struct font_metrics *pcm;
24813 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
24814 if (face->font && (pcm = get_per_char_metric (face->font, &char2b)))
24816 if (pcm->rbearing > pcm->width)
24817 *right = pcm->rbearing - pcm->width;
24818 if (pcm->lbearing < 0)
24819 *left = -pcm->lbearing;
24822 else if (glyph->type == COMPOSITE_GLYPH)
24824 if (! glyph->u.cmp.automatic)
24826 struct composition *cmp = composition_table[glyph->u.cmp.id];
24828 if (cmp->rbearing > cmp->pixel_width)
24829 *right = cmp->rbearing - cmp->pixel_width;
24830 if (cmp->lbearing < 0)
24831 *left = - cmp->lbearing;
24833 else
24835 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
24836 struct font_metrics metrics;
24838 composition_gstring_width (gstring, glyph->slice.cmp.from,
24839 glyph->slice.cmp.to + 1, &metrics);
24840 if (metrics.rbearing > metrics.width)
24841 *right = metrics.rbearing - metrics.width;
24842 if (metrics.lbearing < 0)
24843 *left = - metrics.lbearing;
24849 /* Return the index of the first glyph preceding glyph string S that
24850 is overwritten by S because of S's left overhang. Value is -1
24851 if no glyphs are overwritten. */
24853 static int
24854 left_overwritten (struct glyph_string *s)
24856 int k;
24858 if (s->left_overhang)
24860 int x = 0, i;
24861 struct glyph *glyphs = s->row->glyphs[s->area];
24862 int first = s->first_glyph - glyphs;
24864 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
24865 x -= glyphs[i].pixel_width;
24867 k = i + 1;
24869 else
24870 k = -1;
24872 return k;
24876 /* Return the index of the first glyph preceding glyph string S that
24877 is overwriting S because of its right overhang. Value is -1 if no
24878 glyph in front of S overwrites S. */
24880 static int
24881 left_overwriting (struct glyph_string *s)
24883 int i, k, x;
24884 struct glyph *glyphs = s->row->glyphs[s->area];
24885 int first = s->first_glyph - glyphs;
24887 k = -1;
24888 x = 0;
24889 for (i = first - 1; i >= 0; --i)
24891 int left, right;
24892 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
24893 if (x + right > 0)
24894 k = i;
24895 x -= glyphs[i].pixel_width;
24898 return k;
24902 /* Return the index of the last glyph following glyph string S that is
24903 overwritten by S because of S's right overhang. Value is -1 if
24904 no such glyph is found. */
24906 static int
24907 right_overwritten (struct glyph_string *s)
24909 int k = -1;
24911 if (s->right_overhang)
24913 int x = 0, i;
24914 struct glyph *glyphs = s->row->glyphs[s->area];
24915 int first = (s->first_glyph - glyphs
24916 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
24917 int end = s->row->used[s->area];
24919 for (i = first; i < end && s->right_overhang > x; ++i)
24920 x += glyphs[i].pixel_width;
24922 k = i;
24925 return k;
24929 /* Return the index of the last glyph following glyph string S that
24930 overwrites S because of its left overhang. Value is negative
24931 if no such glyph is found. */
24933 static int
24934 right_overwriting (struct glyph_string *s)
24936 int i, k, x;
24937 int end = s->row->used[s->area];
24938 struct glyph *glyphs = s->row->glyphs[s->area];
24939 int first = (s->first_glyph - glyphs
24940 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
24942 k = -1;
24943 x = 0;
24944 for (i = first; i < end; ++i)
24946 int left, right;
24947 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
24948 if (x - left < 0)
24949 k = i;
24950 x += glyphs[i].pixel_width;
24953 return k;
24957 /* Set background width of glyph string S. START is the index of the
24958 first glyph following S. LAST_X is the right-most x-position + 1
24959 in the drawing area. */
24961 static void
24962 set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
24964 /* If the face of this glyph string has to be drawn to the end of
24965 the drawing area, set S->extends_to_end_of_line_p. */
24967 if (start == s->row->used[s->area]
24968 && ((s->row->fill_line_p
24969 && (s->hl == DRAW_NORMAL_TEXT
24970 || s->hl == DRAW_IMAGE_RAISED
24971 || s->hl == DRAW_IMAGE_SUNKEN))
24972 || s->hl == DRAW_MOUSE_FACE))
24973 s->extends_to_end_of_line_p = 1;
24975 /* If S extends its face to the end of the line, set its
24976 background_width to the distance to the right edge of the drawing
24977 area. */
24978 if (s->extends_to_end_of_line_p)
24979 s->background_width = last_x - s->x + 1;
24980 else
24981 s->background_width = s->width;
24985 /* Compute overhangs and x-positions for glyph string S and its
24986 predecessors, or successors. X is the starting x-position for S.
24987 BACKWARD_P non-zero means process predecessors. */
24989 static void
24990 compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
24992 if (backward_p)
24994 while (s)
24996 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
24997 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
24998 x -= s->width;
24999 s->x = x;
25000 s = s->prev;
25003 else
25005 while (s)
25007 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
25008 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
25009 s->x = x;
25010 x += s->width;
25011 s = s->next;
25018 /* The following macros are only called from draw_glyphs below.
25019 They reference the following parameters of that function directly:
25020 `w', `row', `area', and `overlap_p'
25021 as well as the following local variables:
25022 `s', `f', and `hdc' (in W32) */
25024 #ifdef HAVE_NTGUI
25025 /* On W32, silently add local `hdc' variable to argument list of
25026 init_glyph_string. */
25027 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
25028 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
25029 #else
25030 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
25031 init_glyph_string (s, char2b, w, row, area, start, hl)
25032 #endif
25034 /* Add a glyph string for a stretch glyph to the list of strings
25035 between HEAD and TAIL. START is the index of the stretch glyph in
25036 row area AREA of glyph row ROW. END is the index of the last glyph
25037 in that glyph row area. X is the current output position assigned
25038 to the new glyph string constructed. HL overrides that face of the
25039 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
25040 is the right-most x-position of the drawing area. */
25042 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
25043 and below -- keep them on one line. */
25044 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
25045 do \
25047 s = alloca (sizeof *s); \
25048 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
25049 START = fill_stretch_glyph_string (s, START, END); \
25050 append_glyph_string (&HEAD, &TAIL, s); \
25051 s->x = (X); \
25053 while (0)
25056 /* Add a glyph string for an image glyph to the list of strings
25057 between HEAD and TAIL. START is the index of the image glyph in
25058 row area AREA of glyph row ROW. END is the index of the last glyph
25059 in that glyph row area. X is the current output position assigned
25060 to the new glyph string constructed. HL overrides that face of the
25061 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
25062 is the right-most x-position of the drawing area. */
25064 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
25065 do \
25067 s = alloca (sizeof *s); \
25068 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
25069 fill_image_glyph_string (s); \
25070 append_glyph_string (&HEAD, &TAIL, s); \
25071 ++START; \
25072 s->x = (X); \
25074 while (0)
25076 #ifdef HAVE_XWIDGETS
25077 #define BUILD_XWIDGET_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
25078 do \
25080 printf("BUILD_XWIDGET_GLYPH_STRING\n"); \
25081 s = (struct glyph_string *) alloca (sizeof *s); \
25082 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
25083 fill_xwidget_glyph_string (s); \
25084 append_glyph_string (&HEAD, &TAIL, s); \
25085 ++START; \
25086 s->x = (X); \
25088 while (0)
25089 #endif
25092 /* Add a glyph string for a sequence of character glyphs to the list
25093 of strings between HEAD and TAIL. START is the index of the first
25094 glyph in row area AREA of glyph row ROW that is part of the new
25095 glyph string. END is the index of the last glyph in that glyph row
25096 area. X is the current output position assigned to the new glyph
25097 string constructed. HL overrides that face of the glyph; e.g. it
25098 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
25099 right-most x-position of the drawing area. */
25101 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
25102 do \
25104 int face_id; \
25105 XChar2b *char2b; \
25107 face_id = (row)->glyphs[area][START].face_id; \
25109 s = alloca (sizeof *s); \
25110 SAFE_NALLOCA (char2b, 1, (END) - (START)); \
25111 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
25112 append_glyph_string (&HEAD, &TAIL, s); \
25113 s->x = (X); \
25114 START = fill_glyph_string (s, face_id, START, END, overlaps); \
25116 while (0)
25119 /* Add a glyph string for a composite sequence to the list of strings
25120 between HEAD and TAIL. START is the index of the first glyph in
25121 row area AREA of glyph row ROW that is part of the new glyph
25122 string. END is the index of the last glyph in that glyph row area.
25123 X is the current output position assigned to the new glyph string
25124 constructed. HL overrides that face of the glyph; e.g. it is
25125 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
25126 x-position of the drawing area. */
25128 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
25129 do { \
25130 int face_id = (row)->glyphs[area][START].face_id; \
25131 struct face *base_face = FACE_FROM_ID (f, face_id); \
25132 ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \
25133 struct composition *cmp = composition_table[cmp_id]; \
25134 XChar2b *char2b; \
25135 struct glyph_string *first_s = NULL; \
25136 int n; \
25138 SAFE_NALLOCA (char2b, 1, cmp->glyph_len); \
25140 /* Make glyph_strings for each glyph sequence that is drawable by \
25141 the same face, and append them to HEAD/TAIL. */ \
25142 for (n = 0; n < cmp->glyph_len;) \
25144 s = alloca (sizeof *s); \
25145 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
25146 append_glyph_string (&(HEAD), &(TAIL), s); \
25147 s->cmp = cmp; \
25148 s->cmp_from = n; \
25149 s->x = (X); \
25150 if (n == 0) \
25151 first_s = s; \
25152 n = fill_composite_glyph_string (s, base_face, overlaps); \
25155 ++START; \
25156 s = first_s; \
25157 } while (0)
25160 /* Add a glyph string for a glyph-string sequence to the list of strings
25161 between HEAD and TAIL. */
25163 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
25164 do { \
25165 int face_id; \
25166 XChar2b *char2b; \
25167 Lisp_Object gstring; \
25169 face_id = (row)->glyphs[area][START].face_id; \
25170 gstring = (composition_gstring_from_id \
25171 ((row)->glyphs[area][START].u.cmp.id)); \
25172 s = alloca (sizeof *s); \
25173 SAFE_NALLOCA (char2b, 1, LGSTRING_GLYPH_LEN (gstring)); \
25174 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
25175 append_glyph_string (&(HEAD), &(TAIL), s); \
25176 s->x = (X); \
25177 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
25178 } while (0)
25181 /* Add a glyph string for a sequence of glyphless character's glyphs
25182 to the list of strings between HEAD and TAIL. The meanings of
25183 arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */
25185 #define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
25186 do \
25188 int face_id; \
25190 face_id = (row)->glyphs[area][START].face_id; \
25192 s = alloca (sizeof *s); \
25193 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
25194 append_glyph_string (&HEAD, &TAIL, s); \
25195 s->x = (X); \
25196 START = fill_glyphless_glyph_string (s, face_id, START, END, \
25197 overlaps); \
25199 while (0)
25202 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
25203 of AREA of glyph row ROW on window W between indices START and END.
25204 HL overrides the face for drawing glyph strings, e.g. it is
25205 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
25206 x-positions of the drawing area.
25208 This is an ugly monster macro construct because we must use alloca
25209 to allocate glyph strings (because draw_glyphs can be called
25210 asynchronously). */
25212 #define BUILD_GLYPH_STRINGS_1(START, END, HEAD, TAIL, HL, X, LAST_X) \
25213 do \
25215 HEAD = TAIL = NULL; \
25216 while (START < END) \
25218 struct glyph *first_glyph = (row)->glyphs[area] + START; \
25219 switch (first_glyph->type) \
25221 case CHAR_GLYPH: \
25222 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
25223 HL, X, LAST_X); \
25224 break; \
25226 case COMPOSITE_GLYPH: \
25227 if (first_glyph->u.cmp.automatic) \
25228 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
25229 HL, X, LAST_X); \
25230 else \
25231 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
25232 HL, X, LAST_X); \
25233 break; \
25235 case STRETCH_GLYPH: \
25236 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
25237 HL, X, LAST_X); \
25238 break; \
25240 case IMAGE_GLYPH: \
25241 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
25242 HL, X, LAST_X); \
25243 break;
25245 #define BUILD_GLYPH_STRINGS_XW(START, END, HEAD, TAIL, HL, X, LAST_X) \
25246 case XWIDGET_GLYPH: \
25247 BUILD_XWIDGET_GLYPH_STRING (START, END, HEAD, TAIL, \
25248 HL, X, LAST_X); \
25249 break;
25251 #define BUILD_GLYPH_STRINGS_2(START, END, HEAD, TAIL, HL, X, LAST_X) \
25252 case GLYPHLESS_GLYPH: \
25253 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
25254 HL, X, LAST_X); \
25255 break; \
25257 default: \
25258 emacs_abort (); \
25261 if (s) \
25263 set_glyph_string_background_width (s, START, LAST_X); \
25264 (X) += s->width; \
25267 } while (0)
25270 #ifdef HAVE_XWIDGETS
25271 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
25272 BUILD_GLYPH_STRINGS_1(START, END, HEAD, TAIL, HL, X, LAST_X) \
25273 BUILD_GLYPH_STRINGS_XW(START, END, HEAD, TAIL, HL, X, LAST_X) \
25274 BUILD_GLYPH_STRINGS_2(START, END, HEAD, TAIL, HL, X, LAST_X)
25275 #else
25276 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
25277 BUILD_GLYPH_STRINGS_1(START, END, HEAD, TAIL, HL, X, LAST_X) \
25278 BUILD_GLYPH_STRINGS_2(START, END, HEAD, TAIL, HL, X, LAST_X)
25279 #endif
25282 /* Draw glyphs between START and END in AREA of ROW on window W,
25283 starting at x-position X. X is relative to AREA in W. HL is a
25284 face-override with the following meaning:
25286 DRAW_NORMAL_TEXT draw normally
25287 DRAW_CURSOR draw in cursor face
25288 DRAW_MOUSE_FACE draw in mouse face.
25289 DRAW_INVERSE_VIDEO draw in mode line face
25290 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
25291 DRAW_IMAGE_RAISED draw an image with a raised relief around it
25293 If OVERLAPS is non-zero, draw only the foreground of characters and
25294 clip to the physical height of ROW. Non-zero value also defines
25295 the overlapping part to be drawn:
25297 OVERLAPS_PRED overlap with preceding rows
25298 OVERLAPS_SUCC overlap with succeeding rows
25299 OVERLAPS_BOTH overlap with both preceding/succeeding rows
25300 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
25302 Value is the x-position reached, relative to AREA of W. */
25304 static int
25305 draw_glyphs (struct window *w, int x, struct glyph_row *row,
25306 enum glyph_row_area area, ptrdiff_t start, ptrdiff_t end,
25307 enum draw_glyphs_face hl, int overlaps)
25309 struct glyph_string *head, *tail;
25310 struct glyph_string *s;
25311 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
25312 int i, j, x_reached, last_x, area_left = 0;
25313 struct frame *f = XFRAME (WINDOW_FRAME (w));
25314 DECLARE_HDC (hdc);
25316 ALLOCATE_HDC (hdc, f);
25318 /* Let's rather be paranoid than getting a SEGV. */
25319 end = min (end, row->used[area]);
25320 start = clip_to_bounds (0, start, end);
25322 /* Translate X to frame coordinates. Set last_x to the right
25323 end of the drawing area. */
25324 if (row->full_width_p)
25326 /* X is relative to the left edge of W, without scroll bars
25327 or fringes. */
25328 area_left = WINDOW_LEFT_EDGE_X (w);
25329 last_x = (WINDOW_LEFT_EDGE_X (w) + WINDOW_PIXEL_WIDTH (w)
25330 - (row->mode_line_p ? WINDOW_RIGHT_DIVIDER_WIDTH (w) : 0));
25332 else
25334 area_left = window_box_left (w, area);
25335 last_x = area_left + window_box_width (w, area);
25337 x += area_left;
25339 /* Build a doubly-linked list of glyph_string structures between
25340 head and tail from what we have to draw. Note that the macro
25341 BUILD_GLYPH_STRINGS will modify its start parameter. That's
25342 the reason we use a separate variable `i'. */
25343 i = start;
25344 USE_SAFE_ALLOCA;
25345 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
25346 if (tail)
25347 x_reached = tail->x + tail->background_width;
25348 else
25349 x_reached = x;
25351 /* If there are any glyphs with lbearing < 0 or rbearing > width in
25352 the row, redraw some glyphs in front or following the glyph
25353 strings built above. */
25354 if (head && !overlaps && row->contains_overlapping_glyphs_p)
25356 struct glyph_string *h, *t;
25357 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
25358 int mouse_beg_col IF_LINT (= 0), mouse_end_col IF_LINT (= 0);
25359 int check_mouse_face = 0;
25360 int dummy_x = 0;
25362 /* If mouse highlighting is on, we may need to draw adjacent
25363 glyphs using mouse-face highlighting. */
25364 if (area == TEXT_AREA && row->mouse_face_p
25365 && hlinfo->mouse_face_beg_row >= 0
25366 && hlinfo->mouse_face_end_row >= 0)
25368 ptrdiff_t row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
25370 if (row_vpos >= hlinfo->mouse_face_beg_row
25371 && row_vpos <= hlinfo->mouse_face_end_row)
25373 check_mouse_face = 1;
25374 mouse_beg_col = (row_vpos == hlinfo->mouse_face_beg_row)
25375 ? hlinfo->mouse_face_beg_col : 0;
25376 mouse_end_col = (row_vpos == hlinfo->mouse_face_end_row)
25377 ? hlinfo->mouse_face_end_col
25378 : row->used[TEXT_AREA];
25382 /* Compute overhangs for all glyph strings. */
25383 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
25384 for (s = head; s; s = s->next)
25385 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
25387 /* Prepend glyph strings for glyphs in front of the first glyph
25388 string that are overwritten because of the first glyph
25389 string's left overhang. The background of all strings
25390 prepended must be drawn because the first glyph string
25391 draws over it. */
25392 i = left_overwritten (head);
25393 if (i >= 0)
25395 enum draw_glyphs_face overlap_hl;
25397 /* If this row contains mouse highlighting, attempt to draw
25398 the overlapped glyphs with the correct highlight. This
25399 code fails if the overlap encompasses more than one glyph
25400 and mouse-highlight spans only some of these glyphs.
25401 However, making it work perfectly involves a lot more
25402 code, and I don't know if the pathological case occurs in
25403 practice, so we'll stick to this for now. --- cyd */
25404 if (check_mouse_face
25405 && mouse_beg_col < start && mouse_end_col > i)
25406 overlap_hl = DRAW_MOUSE_FACE;
25407 else
25408 overlap_hl = DRAW_NORMAL_TEXT;
25410 if (hl != overlap_hl)
25411 clip_head = head;
25412 j = i;
25413 BUILD_GLYPH_STRINGS (j, start, h, t,
25414 overlap_hl, dummy_x, last_x);
25415 start = i;
25416 compute_overhangs_and_x (t, head->x, 1);
25417 prepend_glyph_string_lists (&head, &tail, h, t);
25418 if (clip_head == NULL)
25419 clip_head = head;
25422 /* Prepend glyph strings for glyphs in front of the first glyph
25423 string that overwrite that glyph string because of their
25424 right overhang. For these strings, only the foreground must
25425 be drawn, because it draws over the glyph string at `head'.
25426 The background must not be drawn because this would overwrite
25427 right overhangs of preceding glyphs for which no glyph
25428 strings exist. */
25429 i = left_overwriting (head);
25430 if (i >= 0)
25432 enum draw_glyphs_face overlap_hl;
25434 if (check_mouse_face
25435 && mouse_beg_col < start && mouse_end_col > i)
25436 overlap_hl = DRAW_MOUSE_FACE;
25437 else
25438 overlap_hl = DRAW_NORMAL_TEXT;
25440 if (hl == overlap_hl || clip_head == NULL)
25441 clip_head = head;
25442 BUILD_GLYPH_STRINGS (i, start, h, t,
25443 overlap_hl, dummy_x, last_x);
25444 for (s = h; s; s = s->next)
25445 s->background_filled_p = 1;
25446 compute_overhangs_and_x (t, head->x, 1);
25447 prepend_glyph_string_lists (&head, &tail, h, t);
25450 /* Append glyphs strings for glyphs following the last glyph
25451 string tail that are overwritten by tail. The background of
25452 these strings has to be drawn because tail's foreground draws
25453 over it. */
25454 i = right_overwritten (tail);
25455 if (i >= 0)
25457 enum draw_glyphs_face overlap_hl;
25459 if (check_mouse_face
25460 && mouse_beg_col < i && mouse_end_col > end)
25461 overlap_hl = DRAW_MOUSE_FACE;
25462 else
25463 overlap_hl = DRAW_NORMAL_TEXT;
25465 if (hl != overlap_hl)
25466 clip_tail = tail;
25467 BUILD_GLYPH_STRINGS (end, i, h, t,
25468 overlap_hl, x, last_x);
25469 /* Because BUILD_GLYPH_STRINGS updates the first argument,
25470 we don't have `end = i;' here. */
25471 compute_overhangs_and_x (h, tail->x + tail->width, 0);
25472 append_glyph_string_lists (&head, &tail, h, t);
25473 if (clip_tail == NULL)
25474 clip_tail = tail;
25477 /* Append glyph strings for glyphs following the last glyph
25478 string tail that overwrite tail. The foreground of such
25479 glyphs has to be drawn because it writes into the background
25480 of tail. The background must not be drawn because it could
25481 paint over the foreground of following glyphs. */
25482 i = right_overwriting (tail);
25483 if (i >= 0)
25485 enum draw_glyphs_face overlap_hl;
25486 if (check_mouse_face
25487 && mouse_beg_col < i && mouse_end_col > end)
25488 overlap_hl = DRAW_MOUSE_FACE;
25489 else
25490 overlap_hl = DRAW_NORMAL_TEXT;
25492 if (hl == overlap_hl || clip_tail == NULL)
25493 clip_tail = tail;
25494 i++; /* We must include the Ith glyph. */
25495 BUILD_GLYPH_STRINGS (end, i, h, t,
25496 overlap_hl, x, last_x);
25497 for (s = h; s; s = s->next)
25498 s->background_filled_p = 1;
25499 compute_overhangs_and_x (h, tail->x + tail->width, 0);
25500 append_glyph_string_lists (&head, &tail, h, t);
25502 if (clip_head || clip_tail)
25503 for (s = head; s; s = s->next)
25505 s->clip_head = clip_head;
25506 s->clip_tail = clip_tail;
25510 /* Draw all strings. */
25511 for (s = head; s; s = s->next)
25512 FRAME_RIF (f)->draw_glyph_string (s);
25514 #ifndef HAVE_NS
25515 /* When focus a sole frame and move horizontally, this sets on_p to 0
25516 causing a failure to erase prev cursor position. */
25517 if (area == TEXT_AREA
25518 && !row->full_width_p
25519 /* When drawing overlapping rows, only the glyph strings'
25520 foreground is drawn, which doesn't erase a cursor
25521 completely. */
25522 && !overlaps)
25524 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
25525 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
25526 : (tail ? tail->x + tail->background_width : x));
25527 x0 -= area_left;
25528 x1 -= area_left;
25530 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
25531 row->y, MATRIX_ROW_BOTTOM_Y (row));
25533 #endif
25535 /* Value is the x-position up to which drawn, relative to AREA of W.
25536 This doesn't include parts drawn because of overhangs. */
25537 if (row->full_width_p)
25538 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
25539 else
25540 x_reached -= area_left;
25542 RELEASE_HDC (hdc, f);
25544 SAFE_FREE ();
25545 return x_reached;
25548 /* Expand row matrix if too narrow. Don't expand if area
25549 is not present. */
25551 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
25553 if (!it->f->fonts_changed \
25554 && (it->glyph_row->glyphs[area] \
25555 < it->glyph_row->glyphs[area + 1])) \
25557 it->w->ncols_scale_factor++; \
25558 it->f->fonts_changed = 1; \
25562 /* Store one glyph for IT->char_to_display in IT->glyph_row.
25563 Called from x_produce_glyphs when IT->glyph_row is non-null. */
25565 static void
25566 append_glyph (struct it *it)
25568 struct glyph *glyph;
25569 enum glyph_row_area area = it->area;
25571 eassert (it->glyph_row);
25572 eassert (it->char_to_display != '\n' && it->char_to_display != '\t');
25574 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
25575 if (glyph < it->glyph_row->glyphs[area + 1])
25577 /* If the glyph row is reversed, we need to prepend the glyph
25578 rather than append it. */
25579 if (it->glyph_row->reversed_p && area == TEXT_AREA)
25581 struct glyph *g;
25583 /* Make room for the additional glyph. */
25584 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
25585 g[1] = *g;
25586 glyph = it->glyph_row->glyphs[area];
25588 glyph->charpos = CHARPOS (it->position);
25589 glyph->object = it->object;
25590 if (it->pixel_width > 0)
25592 glyph->pixel_width = it->pixel_width;
25593 glyph->padding_p = 0;
25595 else
25597 /* Assure at least 1-pixel width. Otherwise, cursor can't
25598 be displayed correctly. */
25599 glyph->pixel_width = 1;
25600 glyph->padding_p = 1;
25602 glyph->ascent = it->ascent;
25603 glyph->descent = it->descent;
25604 glyph->voffset = it->voffset;
25605 glyph->type = CHAR_GLYPH;
25606 glyph->avoid_cursor_p = it->avoid_cursor_p;
25607 glyph->multibyte_p = it->multibyte_p;
25608 if (it->glyph_row->reversed_p && area == TEXT_AREA)
25610 /* In R2L rows, the left and the right box edges need to be
25611 drawn in reverse direction. */
25612 glyph->right_box_line_p = it->start_of_box_run_p;
25613 glyph->left_box_line_p = it->end_of_box_run_p;
25615 else
25617 glyph->left_box_line_p = it->start_of_box_run_p;
25618 glyph->right_box_line_p = it->end_of_box_run_p;
25620 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
25621 || it->phys_descent > it->descent);
25622 glyph->glyph_not_available_p = it->glyph_not_available_p;
25623 glyph->face_id = it->face_id;
25624 glyph->u.ch = it->char_to_display;
25625 glyph->slice.img = null_glyph_slice;
25626 glyph->font_type = FONT_TYPE_UNKNOWN;
25627 if (it->bidi_p)
25629 glyph->resolved_level = it->bidi_it.resolved_level;
25630 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
25631 glyph->bidi_type = it->bidi_it.type;
25633 else
25635 glyph->resolved_level = 0;
25636 glyph->bidi_type = UNKNOWN_BT;
25638 ++it->glyph_row->used[area];
25640 else
25641 IT_EXPAND_MATRIX_WIDTH (it, area);
25644 /* Store one glyph for the composition IT->cmp_it.id in
25645 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
25646 non-null. */
25648 static void
25649 append_composite_glyph (struct it *it)
25651 struct glyph *glyph;
25652 enum glyph_row_area area = it->area;
25654 eassert (it->glyph_row);
25656 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
25657 if (glyph < it->glyph_row->glyphs[area + 1])
25659 /* If the glyph row is reversed, we need to prepend the glyph
25660 rather than append it. */
25661 if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
25663 struct glyph *g;
25665 /* Make room for the new glyph. */
25666 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
25667 g[1] = *g;
25668 glyph = it->glyph_row->glyphs[it->area];
25670 glyph->charpos = it->cmp_it.charpos;
25671 glyph->object = it->object;
25672 glyph->pixel_width = it->pixel_width;
25673 glyph->ascent = it->ascent;
25674 glyph->descent = it->descent;
25675 glyph->voffset = it->voffset;
25676 glyph->type = COMPOSITE_GLYPH;
25677 if (it->cmp_it.ch < 0)
25679 glyph->u.cmp.automatic = 0;
25680 glyph->u.cmp.id = it->cmp_it.id;
25681 glyph->slice.cmp.from = glyph->slice.cmp.to = 0;
25683 else
25685 glyph->u.cmp.automatic = 1;
25686 glyph->u.cmp.id = it->cmp_it.id;
25687 glyph->slice.cmp.from = it->cmp_it.from;
25688 glyph->slice.cmp.to = it->cmp_it.to - 1;
25690 glyph->avoid_cursor_p = it->avoid_cursor_p;
25691 glyph->multibyte_p = it->multibyte_p;
25692 if (it->glyph_row->reversed_p && area == TEXT_AREA)
25694 /* In R2L rows, the left and the right box edges need to be
25695 drawn in reverse direction. */
25696 glyph->right_box_line_p = it->start_of_box_run_p;
25697 glyph->left_box_line_p = it->end_of_box_run_p;
25699 else
25701 glyph->left_box_line_p = it->start_of_box_run_p;
25702 glyph->right_box_line_p = it->end_of_box_run_p;
25704 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
25705 || it->phys_descent > it->descent);
25706 glyph->padding_p = 0;
25707 glyph->glyph_not_available_p = 0;
25708 glyph->face_id = it->face_id;
25709 glyph->font_type = FONT_TYPE_UNKNOWN;
25710 if (it->bidi_p)
25712 glyph->resolved_level = it->bidi_it.resolved_level;
25713 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
25714 glyph->bidi_type = it->bidi_it.type;
25716 ++it->glyph_row->used[area];
25718 else
25719 IT_EXPAND_MATRIX_WIDTH (it, area);
25723 /* Change IT->ascent and IT->height according to the setting of
25724 IT->voffset. */
25726 static void
25727 take_vertical_position_into_account (struct it *it)
25729 if (it->voffset)
25731 if (it->voffset < 0)
25732 /* Increase the ascent so that we can display the text higher
25733 in the line. */
25734 it->ascent -= it->voffset;
25735 else
25736 /* Increase the descent so that we can display the text lower
25737 in the line. */
25738 it->descent += it->voffset;
25743 /* Produce glyphs/get display metrics for the image IT is loaded with.
25744 See the description of struct display_iterator in dispextern.h for
25745 an overview of struct display_iterator. */
25747 static void
25748 produce_image_glyph (struct it *it)
25750 struct image *img;
25751 struct face *face;
25752 int glyph_ascent, crop;
25753 struct glyph_slice slice;
25755 eassert (it->what == IT_IMAGE);
25757 face = FACE_FROM_ID (it->f, it->face_id);
25758 eassert (face);
25759 /* Make sure X resources of the face is loaded. */
25760 prepare_face_for_display (it->f, face);
25762 if (it->image_id < 0)
25764 /* Fringe bitmap. */
25765 it->ascent = it->phys_ascent = 0;
25766 it->descent = it->phys_descent = 0;
25767 it->pixel_width = 0;
25768 it->nglyphs = 0;
25769 return;
25772 img = IMAGE_FROM_ID (it->f, it->image_id);
25773 eassert (img);
25774 /* Make sure X resources of the image is loaded. */
25775 prepare_image_for_display (it->f, img);
25777 slice.x = slice.y = 0;
25778 slice.width = img->width;
25779 slice.height = img->height;
25781 if (INTEGERP (it->slice.x))
25782 slice.x = XINT (it->slice.x);
25783 else if (FLOATP (it->slice.x))
25784 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
25786 if (INTEGERP (it->slice.y))
25787 slice.y = XINT (it->slice.y);
25788 else if (FLOATP (it->slice.y))
25789 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
25791 if (INTEGERP (it->slice.width))
25792 slice.width = XINT (it->slice.width);
25793 else if (FLOATP (it->slice.width))
25794 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
25796 if (INTEGERP (it->slice.height))
25797 slice.height = XINT (it->slice.height);
25798 else if (FLOATP (it->slice.height))
25799 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
25801 if (slice.x >= img->width)
25802 slice.x = img->width;
25803 if (slice.y >= img->height)
25804 slice.y = img->height;
25805 if (slice.x + slice.width >= img->width)
25806 slice.width = img->width - slice.x;
25807 if (slice.y + slice.height > img->height)
25808 slice.height = img->height - slice.y;
25810 if (slice.width == 0 || slice.height == 0)
25811 return;
25813 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
25815 it->descent = slice.height - glyph_ascent;
25816 if (slice.y == 0)
25817 it->descent += img->vmargin;
25818 if (slice.y + slice.height == img->height)
25819 it->descent += img->vmargin;
25820 it->phys_descent = it->descent;
25822 it->pixel_width = slice.width;
25823 if (slice.x == 0)
25824 it->pixel_width += img->hmargin;
25825 if (slice.x + slice.width == img->width)
25826 it->pixel_width += img->hmargin;
25828 /* It's quite possible for images to have an ascent greater than
25829 their height, so don't get confused in that case. */
25830 if (it->descent < 0)
25831 it->descent = 0;
25833 it->nglyphs = 1;
25835 if (face->box != FACE_NO_BOX)
25837 if (face->box_line_width > 0)
25839 if (slice.y == 0)
25840 it->ascent += face->box_line_width;
25841 if (slice.y + slice.height == img->height)
25842 it->descent += face->box_line_width;
25845 if (it->start_of_box_run_p && slice.x == 0)
25846 it->pixel_width += eabs (face->box_line_width);
25847 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
25848 it->pixel_width += eabs (face->box_line_width);
25851 take_vertical_position_into_account (it);
25853 /* Automatically crop wide image glyphs at right edge so we can
25854 draw the cursor on same display row. */
25855 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
25856 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
25858 it->pixel_width -= crop;
25859 slice.width -= crop;
25862 if (it->glyph_row)
25864 struct glyph *glyph;
25865 enum glyph_row_area area = it->area;
25867 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
25868 if (glyph < it->glyph_row->glyphs[area + 1])
25870 glyph->charpos = CHARPOS (it->position);
25871 glyph->object = it->object;
25872 glyph->pixel_width = it->pixel_width;
25873 glyph->ascent = glyph_ascent;
25874 glyph->descent = it->descent;
25875 glyph->voffset = it->voffset;
25876 glyph->type = IMAGE_GLYPH;
25877 glyph->avoid_cursor_p = it->avoid_cursor_p;
25878 glyph->multibyte_p = it->multibyte_p;
25879 if (it->glyph_row->reversed_p && area == TEXT_AREA)
25881 /* In R2L rows, the left and the right box edges need to be
25882 drawn in reverse direction. */
25883 glyph->right_box_line_p = it->start_of_box_run_p;
25884 glyph->left_box_line_p = it->end_of_box_run_p;
25886 else
25888 glyph->left_box_line_p = it->start_of_box_run_p;
25889 glyph->right_box_line_p = it->end_of_box_run_p;
25891 glyph->overlaps_vertically_p = 0;
25892 glyph->padding_p = 0;
25893 glyph->glyph_not_available_p = 0;
25894 glyph->face_id = it->face_id;
25895 glyph->u.img_id = img->id;
25896 glyph->slice.img = slice;
25897 glyph->font_type = FONT_TYPE_UNKNOWN;
25898 if (it->bidi_p)
25900 glyph->resolved_level = it->bidi_it.resolved_level;
25901 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
25902 glyph->bidi_type = it->bidi_it.type;
25904 ++it->glyph_row->used[area];
25906 else
25907 IT_EXPAND_MATRIX_WIDTH (it, area);
25911 #ifdef HAVE_XWIDGETS
25912 static void
25913 produce_xwidget_glyph (struct it *it)
25915 struct xwidget* xw;
25916 struct face *face;
25917 int glyph_ascent, crop;
25918 printf("produce_xwidget_glyph:\n");
25919 eassert (it->what == IT_XWIDGET);
25921 face = FACE_FROM_ID (it->f, it->face_id);
25922 eassert (face);
25923 /* Make sure X resources of the face is loaded. */
25924 prepare_face_for_display (it->f, face);
25926 xw = it->xwidget;
25927 it->ascent = it->phys_ascent = glyph_ascent = xw->height/2;
25928 it->descent = xw->height/2;
25929 it->phys_descent = it->descent;
25930 it->pixel_width = xw->width;
25931 /* It's quite possible for images to have an ascent greater than
25932 their height, so don't get confused in that case. */
25933 if (it->descent < 0)
25934 it->descent = 0;
25936 it->nglyphs = 1;
25938 if (face->box != FACE_NO_BOX)
25940 if (face->box_line_width > 0)
25942 it->ascent += face->box_line_width;
25943 it->descent += face->box_line_width;
25946 if (it->start_of_box_run_p)
25947 it->pixel_width += eabs (face->box_line_width);
25948 it->pixel_width += eabs (face->box_line_width);
25951 take_vertical_position_into_account (it);
25953 /* Automatically crop wide image glyphs at right edge so we can
25954 draw the cursor on same display row. */
25955 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
25956 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
25958 it->pixel_width -= crop;
25961 if (it->glyph_row)
25963 struct glyph *glyph;
25964 enum glyph_row_area area = it->area;
25966 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
25967 if (glyph < it->glyph_row->glyphs[area + 1])
25969 glyph->charpos = CHARPOS (it->position);
25970 glyph->object = it->object;
25971 glyph->pixel_width = it->pixel_width;
25972 glyph->ascent = glyph_ascent;
25973 glyph->descent = it->descent;
25974 glyph->voffset = it->voffset;
25975 glyph->type = XWIDGET_GLYPH;
25977 glyph->multibyte_p = it->multibyte_p;
25978 glyph->left_box_line_p = it->start_of_box_run_p;
25979 glyph->right_box_line_p = it->end_of_box_run_p;
25980 glyph->overlaps_vertically_p = 0;
25981 glyph->padding_p = 0;
25982 glyph->glyph_not_available_p = 0;
25983 glyph->face_id = it->face_id;
25984 glyph->u.xwidget = it->xwidget;
25985 //assert_valid_xwidget_id(glyph->u.xwidget_id,"produce_xwidget_glyph");
25986 glyph->font_type = FONT_TYPE_UNKNOWN;
25987 ++it->glyph_row->used[area];
25989 else
25990 IT_EXPAND_MATRIX_WIDTH (it, area);
25993 #endif
25995 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
25996 of the glyph, WIDTH and HEIGHT are the width and height of the
25997 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
25999 static void
26000 append_stretch_glyph (struct it *it, Lisp_Object object,
26001 int width, int height, int ascent)
26003 struct glyph *glyph;
26004 enum glyph_row_area area = it->area;
26006 eassert (ascent >= 0 && ascent <= height);
26008 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
26009 if (glyph < it->glyph_row->glyphs[area + 1])
26011 /* If the glyph row is reversed, we need to prepend the glyph
26012 rather than append it. */
26013 if (it->glyph_row->reversed_p && area == TEXT_AREA)
26015 struct glyph *g;
26017 /* Make room for the additional glyph. */
26018 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
26019 g[1] = *g;
26020 glyph = it->glyph_row->glyphs[area];
26022 /* Decrease the width of the first glyph of the row that
26023 begins before first_visible_x (e.g., due to hscroll).
26024 This is so the overall width of the row becomes smaller
26025 by the scroll amount, and the stretch glyph appended by
26026 extend_face_to_end_of_line will be wider, to shift the
26027 row glyphs to the right. (In L2R rows, the corresponding
26028 left-shift effect is accomplished by setting row->x to a
26029 negative value, which won't work with R2L rows.)
26031 This must leave us with a positive value of WIDTH, since
26032 otherwise the call to move_it_in_display_line_to at the
26033 beginning of display_line would have got past the entire
26034 first glyph, and then it->current_x would have been
26035 greater or equal to it->first_visible_x. */
26036 if (it->current_x < it->first_visible_x)
26037 width -= it->first_visible_x - it->current_x;
26038 eassert (width > 0);
26040 glyph->charpos = CHARPOS (it->position);
26041 glyph->object = object;
26042 glyph->pixel_width = width;
26043 glyph->ascent = ascent;
26044 glyph->descent = height - ascent;
26045 glyph->voffset = it->voffset;
26046 glyph->type = STRETCH_GLYPH;
26047 glyph->avoid_cursor_p = it->avoid_cursor_p;
26048 glyph->multibyte_p = it->multibyte_p;
26049 if (it->glyph_row->reversed_p && area == TEXT_AREA)
26051 /* In R2L rows, the left and the right box edges need to be
26052 drawn in reverse direction. */
26053 glyph->right_box_line_p = it->start_of_box_run_p;
26054 glyph->left_box_line_p = it->end_of_box_run_p;
26056 else
26058 glyph->left_box_line_p = it->start_of_box_run_p;
26059 glyph->right_box_line_p = it->end_of_box_run_p;
26061 glyph->overlaps_vertically_p = 0;
26062 glyph->padding_p = 0;
26063 glyph->glyph_not_available_p = 0;
26064 glyph->face_id = it->face_id;
26065 glyph->u.stretch.ascent = ascent;
26066 glyph->u.stretch.height = height;
26067 glyph->slice.img = null_glyph_slice;
26068 glyph->font_type = FONT_TYPE_UNKNOWN;
26069 if (it->bidi_p)
26071 glyph->resolved_level = it->bidi_it.resolved_level;
26072 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
26073 glyph->bidi_type = it->bidi_it.type;
26075 else
26077 glyph->resolved_level = 0;
26078 glyph->bidi_type = UNKNOWN_BT;
26080 ++it->glyph_row->used[area];
26082 else
26083 IT_EXPAND_MATRIX_WIDTH (it, area);
26086 #endif /* HAVE_WINDOW_SYSTEM */
26088 /* Produce a stretch glyph for iterator IT. IT->object is the value
26089 of the glyph property displayed. The value must be a list
26090 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
26091 being recognized:
26093 1. `:width WIDTH' specifies that the space should be WIDTH *
26094 canonical char width wide. WIDTH may be an integer or floating
26095 point number.
26097 2. `:relative-width FACTOR' specifies that the width of the stretch
26098 should be computed from the width of the first character having the
26099 `glyph' property, and should be FACTOR times that width.
26101 3. `:align-to HPOS' specifies that the space should be wide enough
26102 to reach HPOS, a value in canonical character units.
26104 Exactly one of the above pairs must be present.
26106 4. `:height HEIGHT' specifies that the height of the stretch produced
26107 should be HEIGHT, measured in canonical character units.
26109 5. `:relative-height FACTOR' specifies that the height of the
26110 stretch should be FACTOR times the height of the characters having
26111 the glyph property.
26113 Either none or exactly one of 4 or 5 must be present.
26115 6. `:ascent ASCENT' specifies that ASCENT percent of the height
26116 of the stretch should be used for the ascent of the stretch.
26117 ASCENT must be in the range 0 <= ASCENT <= 100. */
26119 void
26120 produce_stretch_glyph (struct it *it)
26122 /* (space :width WIDTH :height HEIGHT ...) */
26123 Lisp_Object prop, plist;
26124 int width = 0, height = 0, align_to = -1;
26125 int zero_width_ok_p = 0;
26126 double tem;
26127 struct font *font = NULL;
26129 #ifdef HAVE_WINDOW_SYSTEM
26130 int ascent = 0;
26131 int zero_height_ok_p = 0;
26133 if (FRAME_WINDOW_P (it->f))
26135 struct face *face = FACE_FROM_ID (it->f, it->face_id);
26136 font = face->font ? face->font : FRAME_FONT (it->f);
26137 prepare_face_for_display (it->f, face);
26139 #endif
26141 /* List should start with `space'. */
26142 eassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
26143 plist = XCDR (it->object);
26145 /* Compute the width of the stretch. */
26146 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
26147 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
26149 /* Absolute width `:width WIDTH' specified and valid. */
26150 zero_width_ok_p = 1;
26151 width = (int)tem;
26153 #ifdef HAVE_WINDOW_SYSTEM
26154 else if (FRAME_WINDOW_P (it->f)
26155 && (prop = Fplist_get (plist, QCrelative_width), NUMVAL (prop) > 0))
26157 /* Relative width `:relative-width FACTOR' specified and valid.
26158 Compute the width of the characters having the `glyph'
26159 property. */
26160 struct it it2;
26161 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
26163 it2 = *it;
26164 if (it->multibyte_p)
26165 it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
26166 else
26168 it2.c = it2.char_to_display = *p, it2.len = 1;
26169 if (! ASCII_CHAR_P (it2.c))
26170 it2.char_to_display = BYTE8_TO_CHAR (it2.c);
26173 it2.glyph_row = NULL;
26174 it2.what = IT_CHARACTER;
26175 x_produce_glyphs (&it2);
26176 width = NUMVAL (prop) * it2.pixel_width;
26178 #endif /* HAVE_WINDOW_SYSTEM */
26179 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
26180 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
26182 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
26183 align_to = (align_to < 0
26185 : align_to - window_box_left_offset (it->w, TEXT_AREA));
26186 else if (align_to < 0)
26187 align_to = window_box_left_offset (it->w, TEXT_AREA);
26188 width = max (0, (int)tem + align_to - it->current_x);
26189 zero_width_ok_p = 1;
26191 else
26192 /* Nothing specified -> width defaults to canonical char width. */
26193 width = FRAME_COLUMN_WIDTH (it->f);
26195 if (width <= 0 && (width < 0 || !zero_width_ok_p))
26196 width = 1;
26198 #ifdef HAVE_WINDOW_SYSTEM
26199 /* Compute height. */
26200 if (FRAME_WINDOW_P (it->f))
26202 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
26203 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
26205 height = (int)tem;
26206 zero_height_ok_p = 1;
26208 else if (prop = Fplist_get (plist, QCrelative_height),
26209 NUMVAL (prop) > 0)
26210 height = FONT_HEIGHT (font) * NUMVAL (prop);
26211 else
26212 height = FONT_HEIGHT (font);
26214 if (height <= 0 && (height < 0 || !zero_height_ok_p))
26215 height = 1;
26217 /* Compute percentage of height used for ascent. If
26218 `:ascent ASCENT' is present and valid, use that. Otherwise,
26219 derive the ascent from the font in use. */
26220 if (prop = Fplist_get (plist, QCascent),
26221 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
26222 ascent = height * NUMVAL (prop) / 100.0;
26223 else if (!NILP (prop)
26224 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
26225 ascent = min (max (0, (int)tem), height);
26226 else
26227 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
26229 else
26230 #endif /* HAVE_WINDOW_SYSTEM */
26231 height = 1;
26233 if (width > 0 && it->line_wrap != TRUNCATE
26234 && it->current_x + width > it->last_visible_x)
26236 width = it->last_visible_x - it->current_x;
26237 #ifdef HAVE_WINDOW_SYSTEM
26238 /* Subtract one more pixel from the stretch width, but only on
26239 GUI frames, since on a TTY each glyph is one "pixel" wide. */
26240 width -= FRAME_WINDOW_P (it->f);
26241 #endif
26244 if (width > 0 && height > 0 && it->glyph_row)
26246 Lisp_Object o_object = it->object;
26247 Lisp_Object object = it->stack[it->sp - 1].string;
26248 int n = width;
26250 if (!STRINGP (object))
26251 object = it->w->contents;
26252 #ifdef HAVE_WINDOW_SYSTEM
26253 if (FRAME_WINDOW_P (it->f))
26254 append_stretch_glyph (it, object, width, height, ascent);
26255 else
26256 #endif
26258 it->object = object;
26259 it->char_to_display = ' ';
26260 it->pixel_width = it->len = 1;
26261 while (n--)
26262 tty_append_glyph (it);
26263 it->object = o_object;
26267 it->pixel_width = width;
26268 #ifdef HAVE_WINDOW_SYSTEM
26269 if (FRAME_WINDOW_P (it->f))
26271 it->ascent = it->phys_ascent = ascent;
26272 it->descent = it->phys_descent = height - it->ascent;
26273 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
26274 take_vertical_position_into_account (it);
26276 else
26277 #endif
26278 it->nglyphs = width;
26281 /* Get information about special display element WHAT in an
26282 environment described by IT. WHAT is one of IT_TRUNCATION or
26283 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
26284 non-null glyph_row member. This function ensures that fields like
26285 face_id, c, len of IT are left untouched. */
26287 static void
26288 produce_special_glyphs (struct it *it, enum display_element_type what)
26290 struct it temp_it;
26291 Lisp_Object gc;
26292 GLYPH glyph;
26294 temp_it = *it;
26295 temp_it.object = make_number (0);
26296 memset (&temp_it.current, 0, sizeof temp_it.current);
26298 if (what == IT_CONTINUATION)
26300 /* Continuation glyph. For R2L lines, we mirror it by hand. */
26301 if (it->bidi_it.paragraph_dir == R2L)
26302 SET_GLYPH_FROM_CHAR (glyph, '/');
26303 else
26304 SET_GLYPH_FROM_CHAR (glyph, '\\');
26305 if (it->dp
26306 && (gc = DISP_CONTINUE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
26308 /* FIXME: Should we mirror GC for R2L lines? */
26309 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
26310 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
26313 else if (what == IT_TRUNCATION)
26315 /* Truncation glyph. */
26316 SET_GLYPH_FROM_CHAR (glyph, '$');
26317 if (it->dp
26318 && (gc = DISP_TRUNC_GLYPH (it->dp), GLYPH_CODE_P (gc)))
26320 /* FIXME: Should we mirror GC for R2L lines? */
26321 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
26322 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
26325 else
26326 emacs_abort ();
26328 #ifdef HAVE_WINDOW_SYSTEM
26329 /* On a GUI frame, when the right fringe (left fringe for R2L rows)
26330 is turned off, we precede the truncation/continuation glyphs by a
26331 stretch glyph whose width is computed such that these special
26332 glyphs are aligned at the window margin, even when very different
26333 fonts are used in different glyph rows. */
26334 if (FRAME_WINDOW_P (temp_it.f)
26335 /* init_iterator calls this with it->glyph_row == NULL, and it
26336 wants only the pixel width of the truncation/continuation
26337 glyphs. */
26338 && temp_it.glyph_row
26339 /* insert_left_trunc_glyphs calls us at the beginning of the
26340 row, and it has its own calculation of the stretch glyph
26341 width. */
26342 && temp_it.glyph_row->used[TEXT_AREA] > 0
26343 && (temp_it.glyph_row->reversed_p
26344 ? WINDOW_LEFT_FRINGE_WIDTH (temp_it.w)
26345 : WINDOW_RIGHT_FRINGE_WIDTH (temp_it.w)) == 0)
26347 int stretch_width = temp_it.last_visible_x - temp_it.current_x;
26349 if (stretch_width > 0)
26351 struct face *face = FACE_FROM_ID (temp_it.f, temp_it.face_id);
26352 struct font *font =
26353 face->font ? face->font : FRAME_FONT (temp_it.f);
26354 int stretch_ascent =
26355 (((temp_it.ascent + temp_it.descent)
26356 * FONT_BASE (font)) / FONT_HEIGHT (font));
26358 append_stretch_glyph (&temp_it, make_number (0), stretch_width,
26359 temp_it.ascent + temp_it.descent,
26360 stretch_ascent);
26363 #endif
26365 temp_it.dp = NULL;
26366 temp_it.what = IT_CHARACTER;
26367 temp_it.c = temp_it.char_to_display = GLYPH_CHAR (glyph);
26368 temp_it.face_id = GLYPH_FACE (glyph);
26369 temp_it.len = CHAR_BYTES (temp_it.c);
26371 PRODUCE_GLYPHS (&temp_it);
26372 it->pixel_width = temp_it.pixel_width;
26373 it->nglyphs = temp_it.nglyphs;
26376 #ifdef HAVE_WINDOW_SYSTEM
26378 /* Calculate line-height and line-spacing properties.
26379 An integer value specifies explicit pixel value.
26380 A float value specifies relative value to current face height.
26381 A cons (float . face-name) specifies relative value to
26382 height of specified face font.
26384 Returns height in pixels, or nil. */
26387 static Lisp_Object
26388 calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
26389 int boff, int override)
26391 Lisp_Object face_name = Qnil;
26392 int ascent, descent, height;
26394 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
26395 return val;
26397 if (CONSP (val))
26399 face_name = XCAR (val);
26400 val = XCDR (val);
26401 if (!NUMBERP (val))
26402 val = make_number (1);
26403 if (NILP (face_name))
26405 height = it->ascent + it->descent;
26406 goto scale;
26410 if (NILP (face_name))
26412 font = FRAME_FONT (it->f);
26413 boff = FRAME_BASELINE_OFFSET (it->f);
26415 else if (EQ (face_name, Qt))
26417 override = 0;
26419 else
26421 int face_id;
26422 struct face *face;
26424 face_id = lookup_named_face (it->f, face_name, 0);
26425 if (face_id < 0)
26426 return make_number (-1);
26428 face = FACE_FROM_ID (it->f, face_id);
26429 font = face->font;
26430 if (font == NULL)
26431 return make_number (-1);
26432 boff = font->baseline_offset;
26433 if (font->vertical_centering)
26434 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
26437 ascent = FONT_BASE (font) + boff;
26438 descent = FONT_DESCENT (font) - boff;
26440 if (override)
26442 it->override_ascent = ascent;
26443 it->override_descent = descent;
26444 it->override_boff = boff;
26447 height = ascent + descent;
26449 scale:
26450 if (FLOATP (val))
26451 height = (int)(XFLOAT_DATA (val) * height);
26452 else if (INTEGERP (val))
26453 height *= XINT (val);
26455 return make_number (height);
26459 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
26460 is a face ID to be used for the glyph. FOR_NO_FONT is nonzero if
26461 and only if this is for a character for which no font was found.
26463 If the display method (it->glyphless_method) is
26464 GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
26465 length of the acronym or the hexadecimal string, UPPER_XOFF and
26466 UPPER_YOFF are pixel offsets for the upper part of the string,
26467 LOWER_XOFF and LOWER_YOFF are for the lower part.
26469 For the other display methods, LEN through LOWER_YOFF are zero. */
26471 static void
26472 append_glyphless_glyph (struct it *it, int face_id, int for_no_font, int len,
26473 short upper_xoff, short upper_yoff,
26474 short lower_xoff, short lower_yoff)
26476 struct glyph *glyph;
26477 enum glyph_row_area area = it->area;
26479 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
26480 if (glyph < it->glyph_row->glyphs[area + 1])
26482 /* If the glyph row is reversed, we need to prepend the glyph
26483 rather than append it. */
26484 if (it->glyph_row->reversed_p && area == TEXT_AREA)
26486 struct glyph *g;
26488 /* Make room for the additional glyph. */
26489 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
26490 g[1] = *g;
26491 glyph = it->glyph_row->glyphs[area];
26493 glyph->charpos = CHARPOS (it->position);
26494 glyph->object = it->object;
26495 glyph->pixel_width = it->pixel_width;
26496 glyph->ascent = it->ascent;
26497 glyph->descent = it->descent;
26498 glyph->voffset = it->voffset;
26499 glyph->type = GLYPHLESS_GLYPH;
26500 glyph->u.glyphless.method = it->glyphless_method;
26501 glyph->u.glyphless.for_no_font = for_no_font;
26502 glyph->u.glyphless.len = len;
26503 glyph->u.glyphless.ch = it->c;
26504 glyph->slice.glyphless.upper_xoff = upper_xoff;
26505 glyph->slice.glyphless.upper_yoff = upper_yoff;
26506 glyph->slice.glyphless.lower_xoff = lower_xoff;
26507 glyph->slice.glyphless.lower_yoff = lower_yoff;
26508 glyph->avoid_cursor_p = it->avoid_cursor_p;
26509 glyph->multibyte_p = it->multibyte_p;
26510 if (it->glyph_row->reversed_p && area == TEXT_AREA)
26512 /* In R2L rows, the left and the right box edges need to be
26513 drawn in reverse direction. */
26514 glyph->right_box_line_p = it->start_of_box_run_p;
26515 glyph->left_box_line_p = it->end_of_box_run_p;
26517 else
26519 glyph->left_box_line_p = it->start_of_box_run_p;
26520 glyph->right_box_line_p = it->end_of_box_run_p;
26522 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
26523 || it->phys_descent > it->descent);
26524 glyph->padding_p = 0;
26525 glyph->glyph_not_available_p = 0;
26526 glyph->face_id = face_id;
26527 glyph->font_type = FONT_TYPE_UNKNOWN;
26528 if (it->bidi_p)
26530 glyph->resolved_level = it->bidi_it.resolved_level;
26531 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
26532 glyph->bidi_type = it->bidi_it.type;
26534 ++it->glyph_row->used[area];
26536 else
26537 IT_EXPAND_MATRIX_WIDTH (it, area);
26541 /* Produce a glyph for a glyphless character for iterator IT.
26542 IT->glyphless_method specifies which method to use for displaying
26543 the character. See the description of enum
26544 glyphless_display_method in dispextern.h for the detail.
26546 FOR_NO_FONT is nonzero if and only if this is for a character for
26547 which no font was found. ACRONYM, if non-nil, is an acronym string
26548 for the character. */
26550 static void
26551 produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
26553 int face_id;
26554 struct face *face;
26555 struct font *font;
26556 int base_width, base_height, width, height;
26557 short upper_xoff, upper_yoff, lower_xoff, lower_yoff;
26558 int len;
26560 /* Get the metrics of the base font. We always refer to the current
26561 ASCII face. */
26562 face = FACE_FROM_ID (it->f, it->face_id)->ascii_face;
26563 font = face->font ? face->font : FRAME_FONT (it->f);
26564 it->ascent = FONT_BASE (font) + font->baseline_offset;
26565 it->descent = FONT_DESCENT (font) - font->baseline_offset;
26566 base_height = it->ascent + it->descent;
26567 base_width = font->average_width;
26569 face_id = merge_glyphless_glyph_face (it);
26571 if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
26573 it->pixel_width = THIN_SPACE_WIDTH;
26574 len = 0;
26575 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
26577 else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX)
26579 width = CHAR_WIDTH (it->c);
26580 if (width == 0)
26581 width = 1;
26582 else if (width > 4)
26583 width = 4;
26584 it->pixel_width = base_width * width;
26585 len = 0;
26586 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
26588 else
26590 char buf[7];
26591 const char *str;
26592 unsigned int code[6];
26593 int upper_len;
26594 int ascent, descent;
26595 struct font_metrics metrics_upper, metrics_lower;
26597 face = FACE_FROM_ID (it->f, face_id);
26598 font = face->font ? face->font : FRAME_FONT (it->f);
26599 prepare_face_for_display (it->f, face);
26601 if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM)
26603 if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
26604 acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
26605 if (CONSP (acronym))
26606 acronym = XCAR (acronym);
26607 str = STRINGP (acronym) ? SSDATA (acronym) : "";
26609 else
26611 eassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
26612 sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c);
26613 str = buf;
26615 for (len = 0; str[len] && ASCII_CHAR_P (str[len]) && len < 6; len++)
26616 code[len] = font->driver->encode_char (font, str[len]);
26617 upper_len = (len + 1) / 2;
26618 font->driver->text_extents (font, code, upper_len,
26619 &metrics_upper);
26620 font->driver->text_extents (font, code + upper_len, len - upper_len,
26621 &metrics_lower);
26625 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
26626 width = max (metrics_upper.width, metrics_lower.width) + 4;
26627 upper_xoff = upper_yoff = 2; /* the typical case */
26628 if (base_width >= width)
26630 /* Align the upper to the left, the lower to the right. */
26631 it->pixel_width = base_width;
26632 lower_xoff = base_width - 2 - metrics_lower.width;
26634 else
26636 /* Center the shorter one. */
26637 it->pixel_width = width;
26638 if (metrics_upper.width >= metrics_lower.width)
26639 lower_xoff = (width - metrics_lower.width) / 2;
26640 else
26642 /* FIXME: This code doesn't look right. It formerly was
26643 missing the "lower_xoff = 0;", which couldn't have
26644 been right since it left lower_xoff uninitialized. */
26645 lower_xoff = 0;
26646 upper_xoff = (width - metrics_upper.width) / 2;
26650 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
26651 top, bottom, and between upper and lower strings. */
26652 height = (metrics_upper.ascent + metrics_upper.descent
26653 + metrics_lower.ascent + metrics_lower.descent) + 5;
26654 /* Center vertically.
26655 H:base_height, D:base_descent
26656 h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent
26658 ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up
26659 descent = D - H/2 + h/2;
26660 lower_yoff = descent - 2 - ld;
26661 upper_yoff = lower_yoff - la - 1 - ud; */
26662 ascent = - (it->descent - (base_height + height + 1) / 2);
26663 descent = it->descent - (base_height - height) / 2;
26664 lower_yoff = descent - 2 - metrics_lower.descent;
26665 upper_yoff = (lower_yoff - metrics_lower.ascent - 1
26666 - metrics_upper.descent);
26667 /* Don't make the height shorter than the base height. */
26668 if (height > base_height)
26670 it->ascent = ascent;
26671 it->descent = descent;
26675 it->phys_ascent = it->ascent;
26676 it->phys_descent = it->descent;
26677 if (it->glyph_row)
26678 append_glyphless_glyph (it, face_id, for_no_font, len,
26679 upper_xoff, upper_yoff,
26680 lower_xoff, lower_yoff);
26681 it->nglyphs = 1;
26682 take_vertical_position_into_account (it);
26686 /* RIF:
26687 Produce glyphs/get display metrics for the display element IT is
26688 loaded with. See the description of struct it in dispextern.h
26689 for an overview of struct it. */
26691 void
26692 x_produce_glyphs (struct it *it)
26694 int extra_line_spacing = it->extra_line_spacing;
26696 it->glyph_not_available_p = 0;
26698 if (it->what == IT_CHARACTER)
26700 XChar2b char2b;
26701 struct face *face = FACE_FROM_ID (it->f, it->face_id);
26702 struct font *font = face->font;
26703 struct font_metrics *pcm = NULL;
26704 int boff; /* Baseline offset. */
26706 if (font == NULL)
26708 /* When no suitable font is found, display this character by
26709 the method specified in the first extra slot of
26710 Vglyphless_char_display. */
26711 Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
26713 eassert (it->what == IT_GLYPHLESS);
26714 produce_glyphless_glyph (it, 1, STRINGP (acronym) ? acronym : Qnil);
26715 goto done;
26718 boff = font->baseline_offset;
26719 if (font->vertical_centering)
26720 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
26722 if (it->char_to_display != '\n' && it->char_to_display != '\t')
26724 int stretched_p;
26726 it->nglyphs = 1;
26728 if (it->override_ascent >= 0)
26730 it->ascent = it->override_ascent;
26731 it->descent = it->override_descent;
26732 boff = it->override_boff;
26734 else
26736 it->ascent = FONT_BASE (font) + boff;
26737 it->descent = FONT_DESCENT (font) - boff;
26740 if (get_char_glyph_code (it->char_to_display, font, &char2b))
26742 pcm = get_per_char_metric (font, &char2b);
26743 if (pcm->width == 0
26744 && pcm->rbearing == 0 && pcm->lbearing == 0)
26745 pcm = NULL;
26748 if (pcm)
26750 it->phys_ascent = pcm->ascent + boff;
26751 it->phys_descent = pcm->descent - boff;
26752 it->pixel_width = pcm->width;
26754 else
26756 it->glyph_not_available_p = 1;
26757 it->phys_ascent = it->ascent;
26758 it->phys_descent = it->descent;
26759 it->pixel_width = font->space_width;
26762 if (it->constrain_row_ascent_descent_p)
26764 if (it->descent > it->max_descent)
26766 it->ascent += it->descent - it->max_descent;
26767 it->descent = it->max_descent;
26769 if (it->ascent > it->max_ascent)
26771 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
26772 it->ascent = it->max_ascent;
26774 it->phys_ascent = min (it->phys_ascent, it->ascent);
26775 it->phys_descent = min (it->phys_descent, it->descent);
26776 extra_line_spacing = 0;
26779 /* If this is a space inside a region of text with
26780 `space-width' property, change its width. */
26781 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
26782 if (stretched_p)
26783 it->pixel_width *= XFLOATINT (it->space_width);
26785 /* If face has a box, add the box thickness to the character
26786 height. If character has a box line to the left and/or
26787 right, add the box line width to the character's width. */
26788 if (face->box != FACE_NO_BOX)
26790 int thick = face->box_line_width;
26792 if (thick > 0)
26794 it->ascent += thick;
26795 it->descent += thick;
26797 else
26798 thick = -thick;
26800 if (it->start_of_box_run_p)
26801 it->pixel_width += thick;
26802 if (it->end_of_box_run_p)
26803 it->pixel_width += thick;
26806 /* If face has an overline, add the height of the overline
26807 (1 pixel) and a 1 pixel margin to the character height. */
26808 if (face->overline_p)
26809 it->ascent += overline_margin;
26811 if (it->constrain_row_ascent_descent_p)
26813 if (it->ascent > it->max_ascent)
26814 it->ascent = it->max_ascent;
26815 if (it->descent > it->max_descent)
26816 it->descent = it->max_descent;
26819 take_vertical_position_into_account (it);
26821 /* If we have to actually produce glyphs, do it. */
26822 if (it->glyph_row)
26824 if (stretched_p)
26826 /* Translate a space with a `space-width' property
26827 into a stretch glyph. */
26828 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
26829 / FONT_HEIGHT (font));
26830 append_stretch_glyph (it, it->object, it->pixel_width,
26831 it->ascent + it->descent, ascent);
26833 else
26834 append_glyph (it);
26836 /* If characters with lbearing or rbearing are displayed
26837 in this line, record that fact in a flag of the
26838 glyph row. This is used to optimize X output code. */
26839 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
26840 it->glyph_row->contains_overlapping_glyphs_p = 1;
26842 if (! stretched_p && it->pixel_width == 0)
26843 /* We assure that all visible glyphs have at least 1-pixel
26844 width. */
26845 it->pixel_width = 1;
26847 else if (it->char_to_display == '\n')
26849 /* A newline has no width, but we need the height of the
26850 line. But if previous part of the line sets a height,
26851 don't increase that height. */
26853 Lisp_Object height;
26854 Lisp_Object total_height = Qnil;
26856 it->override_ascent = -1;
26857 it->pixel_width = 0;
26858 it->nglyphs = 0;
26860 height = get_it_property (it, Qline_height);
26861 /* Split (line-height total-height) list. */
26862 if (CONSP (height)
26863 && CONSP (XCDR (height))
26864 && NILP (XCDR (XCDR (height))))
26866 total_height = XCAR (XCDR (height));
26867 height = XCAR (height);
26869 height = calc_line_height_property (it, height, font, boff, 1);
26871 if (it->override_ascent >= 0)
26873 it->ascent = it->override_ascent;
26874 it->descent = it->override_descent;
26875 boff = it->override_boff;
26877 else
26879 it->ascent = FONT_BASE (font) + boff;
26880 it->descent = FONT_DESCENT (font) - boff;
26883 if (EQ (height, Qt))
26885 if (it->descent > it->max_descent)
26887 it->ascent += it->descent - it->max_descent;
26888 it->descent = it->max_descent;
26890 if (it->ascent > it->max_ascent)
26892 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
26893 it->ascent = it->max_ascent;
26895 it->phys_ascent = min (it->phys_ascent, it->ascent);
26896 it->phys_descent = min (it->phys_descent, it->descent);
26897 it->constrain_row_ascent_descent_p = 1;
26898 extra_line_spacing = 0;
26900 else
26902 Lisp_Object spacing;
26904 it->phys_ascent = it->ascent;
26905 it->phys_descent = it->descent;
26907 if ((it->max_ascent > 0 || it->max_descent > 0)
26908 && face->box != FACE_NO_BOX
26909 && face->box_line_width > 0)
26911 it->ascent += face->box_line_width;
26912 it->descent += face->box_line_width;
26914 if (!NILP (height)
26915 && XINT (height) > it->ascent + it->descent)
26916 it->ascent = XINT (height) - it->descent;
26918 if (!NILP (total_height))
26919 spacing = calc_line_height_property (it, total_height, font, boff, 0);
26920 else
26922 spacing = get_it_property (it, Qline_spacing);
26923 spacing = calc_line_height_property (it, spacing, font, boff, 0);
26925 if (INTEGERP (spacing))
26927 extra_line_spacing = XINT (spacing);
26928 if (!NILP (total_height))
26929 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
26933 else /* i.e. (it->char_to_display == '\t') */
26935 if (font->space_width > 0)
26937 int tab_width = it->tab_width * font->space_width;
26938 int x = it->current_x + it->continuation_lines_width;
26939 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
26941 /* If the distance from the current position to the next tab
26942 stop is less than a space character width, use the
26943 tab stop after that. */
26944 if (next_tab_x - x < font->space_width)
26945 next_tab_x += tab_width;
26947 it->pixel_width = next_tab_x - x;
26948 it->nglyphs = 1;
26949 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
26950 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
26952 if (it->glyph_row)
26954 append_stretch_glyph (it, it->object, it->pixel_width,
26955 it->ascent + it->descent, it->ascent);
26958 else
26960 it->pixel_width = 0;
26961 it->nglyphs = 1;
26965 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
26967 /* A static composition.
26969 Note: A composition is represented as one glyph in the
26970 glyph matrix. There are no padding glyphs.
26972 Important note: pixel_width, ascent, and descent are the
26973 values of what is drawn by draw_glyphs (i.e. the values of
26974 the overall glyphs composed). */
26975 struct face *face = FACE_FROM_ID (it->f, it->face_id);
26976 int boff; /* baseline offset */
26977 struct composition *cmp = composition_table[it->cmp_it.id];
26978 int glyph_len = cmp->glyph_len;
26979 struct font *font = face->font;
26981 it->nglyphs = 1;
26983 /* If we have not yet calculated pixel size data of glyphs of
26984 the composition for the current face font, calculate them
26985 now. Theoretically, we have to check all fonts for the
26986 glyphs, but that requires much time and memory space. So,
26987 here we check only the font of the first glyph. This may
26988 lead to incorrect display, but it's very rare, and C-l
26989 (recenter-top-bottom) can correct the display anyway. */
26990 if (! cmp->font || cmp->font != font)
26992 /* Ascent and descent of the font of the first character
26993 of this composition (adjusted by baseline offset).
26994 Ascent and descent of overall glyphs should not be less
26995 than these, respectively. */
26996 int font_ascent, font_descent, font_height;
26997 /* Bounding box of the overall glyphs. */
26998 int leftmost, rightmost, lowest, highest;
26999 int lbearing, rbearing;
27000 int i, width, ascent, descent;
27001 int left_padded = 0, right_padded = 0;
27002 int c IF_LINT (= 0); /* cmp->glyph_len can't be zero; see Bug#8512 */
27003 XChar2b char2b;
27004 struct font_metrics *pcm;
27005 int font_not_found_p;
27006 ptrdiff_t pos;
27008 for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
27009 if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
27010 break;
27011 if (glyph_len < cmp->glyph_len)
27012 right_padded = 1;
27013 for (i = 0; i < glyph_len; i++)
27015 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
27016 break;
27017 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
27019 if (i > 0)
27020 left_padded = 1;
27022 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
27023 : IT_CHARPOS (*it));
27024 /* If no suitable font is found, use the default font. */
27025 font_not_found_p = font == NULL;
27026 if (font_not_found_p)
27028 face = face->ascii_face;
27029 font = face->font;
27031 boff = font->baseline_offset;
27032 if (font->vertical_centering)
27033 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
27034 font_ascent = FONT_BASE (font) + boff;
27035 font_descent = FONT_DESCENT (font) - boff;
27036 font_height = FONT_HEIGHT (font);
27038 cmp->font = font;
27040 pcm = NULL;
27041 if (! font_not_found_p)
27043 get_char_face_and_encoding (it->f, c, it->face_id,
27044 &char2b, 0);
27045 pcm = get_per_char_metric (font, &char2b);
27048 /* Initialize the bounding box. */
27049 if (pcm)
27051 width = cmp->glyph_len > 0 ? pcm->width : 0;
27052 ascent = pcm->ascent;
27053 descent = pcm->descent;
27054 lbearing = pcm->lbearing;
27055 rbearing = pcm->rbearing;
27057 else
27059 width = cmp->glyph_len > 0 ? font->space_width : 0;
27060 ascent = FONT_BASE (font);
27061 descent = FONT_DESCENT (font);
27062 lbearing = 0;
27063 rbearing = width;
27066 rightmost = width;
27067 leftmost = 0;
27068 lowest = - descent + boff;
27069 highest = ascent + boff;
27071 if (! font_not_found_p
27072 && font->default_ascent
27073 && CHAR_TABLE_P (Vuse_default_ascent)
27074 && !NILP (Faref (Vuse_default_ascent,
27075 make_number (it->char_to_display))))
27076 highest = font->default_ascent + boff;
27078 /* Draw the first glyph at the normal position. It may be
27079 shifted to right later if some other glyphs are drawn
27080 at the left. */
27081 cmp->offsets[i * 2] = 0;
27082 cmp->offsets[i * 2 + 1] = boff;
27083 cmp->lbearing = lbearing;
27084 cmp->rbearing = rbearing;
27086 /* Set cmp->offsets for the remaining glyphs. */
27087 for (i++; i < glyph_len; i++)
27089 int left, right, btm, top;
27090 int ch = COMPOSITION_GLYPH (cmp, i);
27091 int face_id;
27092 struct face *this_face;
27094 if (ch == '\t')
27095 ch = ' ';
27096 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
27097 this_face = FACE_FROM_ID (it->f, face_id);
27098 font = this_face->font;
27100 if (font == NULL)
27101 pcm = NULL;
27102 else
27104 get_char_face_and_encoding (it->f, ch, face_id,
27105 &char2b, 0);
27106 pcm = get_per_char_metric (font, &char2b);
27108 if (! pcm)
27109 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
27110 else
27112 width = pcm->width;
27113 ascent = pcm->ascent;
27114 descent = pcm->descent;
27115 lbearing = pcm->lbearing;
27116 rbearing = pcm->rbearing;
27117 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
27119 /* Relative composition with or without
27120 alternate chars. */
27121 left = (leftmost + rightmost - width) / 2;
27122 btm = - descent + boff;
27123 if (font->relative_compose
27124 && (! CHAR_TABLE_P (Vignore_relative_composition)
27125 || NILP (Faref (Vignore_relative_composition,
27126 make_number (ch)))))
27129 if (- descent >= font->relative_compose)
27130 /* One extra pixel between two glyphs. */
27131 btm = highest + 1;
27132 else if (ascent <= 0)
27133 /* One extra pixel between two glyphs. */
27134 btm = lowest - 1 - ascent - descent;
27137 else
27139 /* A composition rule is specified by an integer
27140 value that encodes global and new reference
27141 points (GREF and NREF). GREF and NREF are
27142 specified by numbers as below:
27144 0---1---2 -- ascent
27148 9--10--11 -- center
27150 ---3---4---5--- baseline
27152 6---7---8 -- descent
27154 int rule = COMPOSITION_RULE (cmp, i);
27155 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
27157 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
27158 grefx = gref % 3, nrefx = nref % 3;
27159 grefy = gref / 3, nrefy = nref / 3;
27160 if (xoff)
27161 xoff = font_height * (xoff - 128) / 256;
27162 if (yoff)
27163 yoff = font_height * (yoff - 128) / 256;
27165 left = (leftmost
27166 + grefx * (rightmost - leftmost) / 2
27167 - nrefx * width / 2
27168 + xoff);
27170 btm = ((grefy == 0 ? highest
27171 : grefy == 1 ? 0
27172 : grefy == 2 ? lowest
27173 : (highest + lowest) / 2)
27174 - (nrefy == 0 ? ascent + descent
27175 : nrefy == 1 ? descent - boff
27176 : nrefy == 2 ? 0
27177 : (ascent + descent) / 2)
27178 + yoff);
27181 cmp->offsets[i * 2] = left;
27182 cmp->offsets[i * 2 + 1] = btm + descent;
27184 /* Update the bounding box of the overall glyphs. */
27185 if (width > 0)
27187 right = left + width;
27188 if (left < leftmost)
27189 leftmost = left;
27190 if (right > rightmost)
27191 rightmost = right;
27193 top = btm + descent + ascent;
27194 if (top > highest)
27195 highest = top;
27196 if (btm < lowest)
27197 lowest = btm;
27199 if (cmp->lbearing > left + lbearing)
27200 cmp->lbearing = left + lbearing;
27201 if (cmp->rbearing < left + rbearing)
27202 cmp->rbearing = left + rbearing;
27206 /* If there are glyphs whose x-offsets are negative,
27207 shift all glyphs to the right and make all x-offsets
27208 non-negative. */
27209 if (leftmost < 0)
27211 for (i = 0; i < cmp->glyph_len; i++)
27212 cmp->offsets[i * 2] -= leftmost;
27213 rightmost -= leftmost;
27214 cmp->lbearing -= leftmost;
27215 cmp->rbearing -= leftmost;
27218 if (left_padded && cmp->lbearing < 0)
27220 for (i = 0; i < cmp->glyph_len; i++)
27221 cmp->offsets[i * 2] -= cmp->lbearing;
27222 rightmost -= cmp->lbearing;
27223 cmp->rbearing -= cmp->lbearing;
27224 cmp->lbearing = 0;
27226 if (right_padded && rightmost < cmp->rbearing)
27228 rightmost = cmp->rbearing;
27231 cmp->pixel_width = rightmost;
27232 cmp->ascent = highest;
27233 cmp->descent = - lowest;
27234 if (cmp->ascent < font_ascent)
27235 cmp->ascent = font_ascent;
27236 if (cmp->descent < font_descent)
27237 cmp->descent = font_descent;
27240 if (it->glyph_row
27241 && (cmp->lbearing < 0
27242 || cmp->rbearing > cmp->pixel_width))
27243 it->glyph_row->contains_overlapping_glyphs_p = 1;
27245 it->pixel_width = cmp->pixel_width;
27246 it->ascent = it->phys_ascent = cmp->ascent;
27247 it->descent = it->phys_descent = cmp->descent;
27248 if (face->box != FACE_NO_BOX)
27250 int thick = face->box_line_width;
27252 if (thick > 0)
27254 it->ascent += thick;
27255 it->descent += thick;
27257 else
27258 thick = - thick;
27260 if (it->start_of_box_run_p)
27261 it->pixel_width += thick;
27262 if (it->end_of_box_run_p)
27263 it->pixel_width += thick;
27266 /* If face has an overline, add the height of the overline
27267 (1 pixel) and a 1 pixel margin to the character height. */
27268 if (face->overline_p)
27269 it->ascent += overline_margin;
27271 take_vertical_position_into_account (it);
27272 if (it->ascent < 0)
27273 it->ascent = 0;
27274 if (it->descent < 0)
27275 it->descent = 0;
27277 if (it->glyph_row && cmp->glyph_len > 0)
27278 append_composite_glyph (it);
27280 else if (it->what == IT_COMPOSITION)
27282 /* A dynamic (automatic) composition. */
27283 struct face *face = FACE_FROM_ID (it->f, it->face_id);
27284 Lisp_Object gstring;
27285 struct font_metrics metrics;
27287 it->nglyphs = 1;
27289 gstring = composition_gstring_from_id (it->cmp_it.id);
27290 it->pixel_width
27291 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
27292 &metrics);
27293 if (it->glyph_row
27294 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
27295 it->glyph_row->contains_overlapping_glyphs_p = 1;
27296 it->ascent = it->phys_ascent = metrics.ascent;
27297 it->descent = it->phys_descent = metrics.descent;
27298 if (face->box != FACE_NO_BOX)
27300 int thick = face->box_line_width;
27302 if (thick > 0)
27304 it->ascent += thick;
27305 it->descent += thick;
27307 else
27308 thick = - thick;
27310 if (it->start_of_box_run_p)
27311 it->pixel_width += thick;
27312 if (it->end_of_box_run_p)
27313 it->pixel_width += thick;
27315 /* If face has an overline, add the height of the overline
27316 (1 pixel) and a 1 pixel margin to the character height. */
27317 if (face->overline_p)
27318 it->ascent += overline_margin;
27319 take_vertical_position_into_account (it);
27320 if (it->ascent < 0)
27321 it->ascent = 0;
27322 if (it->descent < 0)
27323 it->descent = 0;
27325 if (it->glyph_row)
27326 append_composite_glyph (it);
27328 else if (it->what == IT_GLYPHLESS)
27329 produce_glyphless_glyph (it, 0, Qnil);
27330 else if (it->what == IT_IMAGE)
27331 produce_image_glyph (it);
27332 else if (it->what == IT_STRETCH)
27333 produce_stretch_glyph (it);
27334 #ifdef HAVE_XWIDGETS
27335 else if (it->what == IT_XWIDGET)
27336 produce_xwidget_glyph (it);
27337 #endif
27339 done:
27340 /* Accumulate dimensions. Note: can't assume that it->descent > 0
27341 because this isn't true for images with `:ascent 100'. */
27342 eassert (it->ascent >= 0 && it->descent >= 0);
27343 if (it->area == TEXT_AREA)
27344 it->current_x += it->pixel_width;
27346 if (extra_line_spacing > 0)
27348 it->descent += extra_line_spacing;
27349 if (extra_line_spacing > it->max_extra_line_spacing)
27350 it->max_extra_line_spacing = extra_line_spacing;
27353 it->max_ascent = max (it->max_ascent, it->ascent);
27354 it->max_descent = max (it->max_descent, it->descent);
27355 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
27356 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
27359 /* EXPORT for RIF:
27360 Output LEN glyphs starting at START at the nominal cursor position.
27361 Advance the nominal cursor over the text. UPDATED_ROW is the glyph row
27362 being updated, and UPDATED_AREA is the area of that row being updated. */
27364 void
27365 x_write_glyphs (struct window *w, struct glyph_row *updated_row,
27366 struct glyph *start, enum glyph_row_area updated_area, int len)
27368 int x, hpos, chpos = w->phys_cursor.hpos;
27370 eassert (updated_row);
27371 /* When the window is hscrolled, cursor hpos can legitimately be out
27372 of bounds, but we draw the cursor at the corresponding window
27373 margin in that case. */
27374 if (!updated_row->reversed_p && chpos < 0)
27375 chpos = 0;
27376 if (updated_row->reversed_p && chpos >= updated_row->used[TEXT_AREA])
27377 chpos = updated_row->used[TEXT_AREA] - 1;
27379 block_input ();
27381 /* Write glyphs. */
27383 hpos = start - updated_row->glyphs[updated_area];
27384 x = draw_glyphs (w, w->output_cursor.x,
27385 updated_row, updated_area,
27386 hpos, hpos + len,
27387 DRAW_NORMAL_TEXT, 0);
27389 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
27390 if (updated_area == TEXT_AREA
27391 && w->phys_cursor_on_p
27392 && w->phys_cursor.vpos == w->output_cursor.vpos
27393 && chpos >= hpos
27394 && chpos < hpos + len)
27395 w->phys_cursor_on_p = 0;
27397 unblock_input ();
27399 /* Advance the output cursor. */
27400 w->output_cursor.hpos += len;
27401 w->output_cursor.x = x;
27405 /* EXPORT for RIF:
27406 Insert LEN glyphs from START at the nominal cursor position. */
27408 void
27409 x_insert_glyphs (struct window *w, struct glyph_row *updated_row,
27410 struct glyph *start, enum glyph_row_area updated_area, int len)
27412 struct frame *f;
27413 int line_height, shift_by_width, shifted_region_width;
27414 struct glyph_row *row;
27415 struct glyph *glyph;
27416 int frame_x, frame_y;
27417 ptrdiff_t hpos;
27419 eassert (updated_row);
27420 block_input ();
27421 f = XFRAME (WINDOW_FRAME (w));
27423 /* Get the height of the line we are in. */
27424 row = updated_row;
27425 line_height = row->height;
27427 /* Get the width of the glyphs to insert. */
27428 shift_by_width = 0;
27429 for (glyph = start; glyph < start + len; ++glyph)
27430 shift_by_width += glyph->pixel_width;
27432 /* Get the width of the region to shift right. */
27433 shifted_region_width = (window_box_width (w, updated_area)
27434 - w->output_cursor.x
27435 - shift_by_width);
27437 /* Shift right. */
27438 frame_x = window_box_left (w, updated_area) + w->output_cursor.x;
27439 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, w->output_cursor.y);
27441 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
27442 line_height, shift_by_width);
27444 /* Write the glyphs. */
27445 hpos = start - row->glyphs[updated_area];
27446 draw_glyphs (w, w->output_cursor.x, row, updated_area,
27447 hpos, hpos + len,
27448 DRAW_NORMAL_TEXT, 0);
27450 /* Advance the output cursor. */
27451 w->output_cursor.hpos += len;
27452 w->output_cursor.x += shift_by_width;
27453 unblock_input ();
27457 /* EXPORT for RIF:
27458 Erase the current text line from the nominal cursor position
27459 (inclusive) to pixel column TO_X (exclusive). The idea is that
27460 everything from TO_X onward is already erased.
27462 TO_X is a pixel position relative to UPDATED_AREA of currently
27463 updated window W. TO_X == -1 means clear to the end of this area. */
27465 void
27466 x_clear_end_of_line (struct window *w, struct glyph_row *updated_row,
27467 enum glyph_row_area updated_area, int to_x)
27469 struct frame *f;
27470 int max_x, min_y, max_y;
27471 int from_x, from_y, to_y;
27473 eassert (updated_row);
27474 f = XFRAME (w->frame);
27476 if (updated_row->full_width_p)
27477 max_x = (WINDOW_PIXEL_WIDTH (w)
27478 - (updated_row->mode_line_p ? WINDOW_RIGHT_DIVIDER_WIDTH (w) : 0));
27479 else
27480 max_x = window_box_width (w, updated_area);
27481 max_y = window_text_bottom_y (w);
27483 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
27484 of window. For TO_X > 0, truncate to end of drawing area. */
27485 if (to_x == 0)
27486 return;
27487 else if (to_x < 0)
27488 to_x = max_x;
27489 else
27490 to_x = min (to_x, max_x);
27492 to_y = min (max_y, w->output_cursor.y + updated_row->height);
27494 /* Notice if the cursor will be cleared by this operation. */
27495 if (!updated_row->full_width_p)
27496 notice_overwritten_cursor (w, updated_area,
27497 w->output_cursor.x, -1,
27498 updated_row->y,
27499 MATRIX_ROW_BOTTOM_Y (updated_row));
27501 from_x = w->output_cursor.x;
27503 /* Translate to frame coordinates. */
27504 if (updated_row->full_width_p)
27506 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
27507 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
27509 else
27511 int area_left = window_box_left (w, updated_area);
27512 from_x += area_left;
27513 to_x += area_left;
27516 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
27517 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, w->output_cursor.y));
27518 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
27520 /* Prevent inadvertently clearing to end of the X window. */
27521 if (to_x > from_x && to_y > from_y)
27523 block_input ();
27524 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
27525 to_x - from_x, to_y - from_y);
27526 unblock_input ();
27530 #endif /* HAVE_WINDOW_SYSTEM */
27534 /***********************************************************************
27535 Cursor types
27536 ***********************************************************************/
27538 /* Value is the internal representation of the specified cursor type
27539 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
27540 of the bar cursor. */
27542 static enum text_cursor_kinds
27543 get_specified_cursor_type (Lisp_Object arg, int *width)
27545 enum text_cursor_kinds type;
27547 if (NILP (arg))
27548 return NO_CURSOR;
27550 if (EQ (arg, Qbox))
27551 return FILLED_BOX_CURSOR;
27553 if (EQ (arg, Qhollow))
27554 return HOLLOW_BOX_CURSOR;
27556 if (EQ (arg, Qbar))
27558 *width = 2;
27559 return BAR_CURSOR;
27562 if (CONSP (arg)
27563 && EQ (XCAR (arg), Qbar)
27564 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
27566 *width = XINT (XCDR (arg));
27567 return BAR_CURSOR;
27570 if (EQ (arg, Qhbar))
27572 *width = 2;
27573 return HBAR_CURSOR;
27576 if (CONSP (arg)
27577 && EQ (XCAR (arg), Qhbar)
27578 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
27580 *width = XINT (XCDR (arg));
27581 return HBAR_CURSOR;
27584 /* Treat anything unknown as "hollow box cursor".
27585 It was bad to signal an error; people have trouble fixing
27586 .Xdefaults with Emacs, when it has something bad in it. */
27587 type = HOLLOW_BOX_CURSOR;
27589 return type;
27592 /* Set the default cursor types for specified frame. */
27593 void
27594 set_frame_cursor_types (struct frame *f, Lisp_Object arg)
27596 int width = 1;
27597 Lisp_Object tem;
27599 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
27600 FRAME_CURSOR_WIDTH (f) = width;
27602 /* By default, set up the blink-off state depending on the on-state. */
27604 tem = Fassoc (arg, Vblink_cursor_alist);
27605 if (!NILP (tem))
27607 FRAME_BLINK_OFF_CURSOR (f)
27608 = get_specified_cursor_type (XCDR (tem), &width);
27609 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
27611 else
27612 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
27614 /* Make sure the cursor gets redrawn. */
27615 f->cursor_type_changed = 1;
27619 #ifdef HAVE_WINDOW_SYSTEM
27621 /* Return the cursor we want to be displayed in window W. Return
27622 width of bar/hbar cursor through WIDTH arg. Return with
27623 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
27624 (i.e. if the `system caret' should track this cursor).
27626 In a mini-buffer window, we want the cursor only to appear if we
27627 are reading input from this window. For the selected window, we
27628 want the cursor type given by the frame parameter or buffer local
27629 setting of cursor-type. If explicitly marked off, draw no cursor.
27630 In all other cases, we want a hollow box cursor. */
27632 static enum text_cursor_kinds
27633 get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
27634 int *active_cursor)
27636 struct frame *f = XFRAME (w->frame);
27637 struct buffer *b = XBUFFER (w->contents);
27638 int cursor_type = DEFAULT_CURSOR;
27639 Lisp_Object alt_cursor;
27640 int non_selected = 0;
27642 *active_cursor = 1;
27644 /* Echo area */
27645 if (cursor_in_echo_area
27646 && FRAME_HAS_MINIBUF_P (f)
27647 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
27649 if (w == XWINDOW (echo_area_window))
27651 if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
27653 *width = FRAME_CURSOR_WIDTH (f);
27654 return FRAME_DESIRED_CURSOR (f);
27656 else
27657 return get_specified_cursor_type (BVAR (b, cursor_type), width);
27660 *active_cursor = 0;
27661 non_selected = 1;
27664 /* Detect a nonselected window or nonselected frame. */
27665 else if (w != XWINDOW (f->selected_window)
27666 || f != FRAME_DISPLAY_INFO (f)->x_highlight_frame)
27668 *active_cursor = 0;
27670 if (MINI_WINDOW_P (w) && minibuf_level == 0)
27671 return NO_CURSOR;
27673 non_selected = 1;
27676 /* Never display a cursor in a window in which cursor-type is nil. */
27677 if (NILP (BVAR (b, cursor_type)))
27678 return NO_CURSOR;
27680 /* Get the normal cursor type for this window. */
27681 if (EQ (BVAR (b, cursor_type), Qt))
27683 cursor_type = FRAME_DESIRED_CURSOR (f);
27684 *width = FRAME_CURSOR_WIDTH (f);
27686 else
27687 cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
27689 /* Use cursor-in-non-selected-windows instead
27690 for non-selected window or frame. */
27691 if (non_selected)
27693 alt_cursor = BVAR (b, cursor_in_non_selected_windows);
27694 if (!EQ (Qt, alt_cursor))
27695 return get_specified_cursor_type (alt_cursor, width);
27696 /* t means modify the normal cursor type. */
27697 if (cursor_type == FILLED_BOX_CURSOR)
27698 cursor_type = HOLLOW_BOX_CURSOR;
27699 else if (cursor_type == BAR_CURSOR && *width > 1)
27700 --*width;
27701 return cursor_type;
27704 /* Use normal cursor if not blinked off. */
27705 if (!w->cursor_off_p)
27708 #ifdef HAVE_XWIDGETS
27709 if (glyph != NULL && glyph->type == XWIDGET_GLYPH){
27710 //printf("attempt xwidget cursor avoidance in get_window_cursor_type\n");
27711 return NO_CURSOR;
27713 #endif
27714 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
27716 if (cursor_type == FILLED_BOX_CURSOR)
27718 /* Using a block cursor on large images can be very annoying.
27719 So use a hollow cursor for "large" images.
27720 If image is not transparent (no mask), also use hollow cursor. */
27721 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
27722 if (img != NULL && IMAGEP (img->spec))
27724 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
27725 where N = size of default frame font size.
27726 This should cover most of the "tiny" icons people may use. */
27727 if (!img->mask
27728 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
27729 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
27730 cursor_type = HOLLOW_BOX_CURSOR;
27733 else if (cursor_type != NO_CURSOR)
27735 /* Display current only supports BOX and HOLLOW cursors for images.
27736 So for now, unconditionally use a HOLLOW cursor when cursor is
27737 not a solid box cursor. */
27738 cursor_type = HOLLOW_BOX_CURSOR;
27741 return cursor_type;
27744 /* Cursor is blinked off, so determine how to "toggle" it. */
27746 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
27747 if ((alt_cursor = Fassoc (BVAR (b, cursor_type), Vblink_cursor_alist), !NILP (alt_cursor)))
27748 return get_specified_cursor_type (XCDR (alt_cursor), width);
27750 /* Then see if frame has specified a specific blink off cursor type. */
27751 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
27753 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
27754 return FRAME_BLINK_OFF_CURSOR (f);
27757 #if 0
27758 /* Some people liked having a permanently visible blinking cursor,
27759 while others had very strong opinions against it. So it was
27760 decided to remove it. KFS 2003-09-03 */
27762 /* Finally perform built-in cursor blinking:
27763 filled box <-> hollow box
27764 wide [h]bar <-> narrow [h]bar
27765 narrow [h]bar <-> no cursor
27766 other type <-> no cursor */
27768 if (cursor_type == FILLED_BOX_CURSOR)
27769 return HOLLOW_BOX_CURSOR;
27771 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
27773 *width = 1;
27774 return cursor_type;
27776 #endif
27778 return NO_CURSOR;
27782 /* Notice when the text cursor of window W has been completely
27783 overwritten by a drawing operation that outputs glyphs in AREA
27784 starting at X0 and ending at X1 in the line starting at Y0 and
27785 ending at Y1. X coordinates are area-relative. X1 < 0 means all
27786 the rest of the line after X0 has been written. Y coordinates
27787 are window-relative. */
27789 static void
27790 notice_overwritten_cursor (struct window *w, enum glyph_row_area area,
27791 int x0, int x1, int y0, int y1)
27793 int cx0, cx1, cy0, cy1;
27794 struct glyph_row *row;
27796 if (!w->phys_cursor_on_p)
27797 return;
27798 if (area != TEXT_AREA)
27799 return;
27801 if (w->phys_cursor.vpos < 0
27802 || w->phys_cursor.vpos >= w->current_matrix->nrows
27803 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
27804 !(row->enabled_p && MATRIX_ROW_DISPLAYS_TEXT_P (row))))
27805 return;
27807 if (row->cursor_in_fringe_p)
27809 row->cursor_in_fringe_p = 0;
27810 draw_fringe_bitmap (w, row, row->reversed_p);
27811 w->phys_cursor_on_p = 0;
27812 return;
27815 cx0 = w->phys_cursor.x;
27816 cx1 = cx0 + w->phys_cursor_width;
27817 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
27818 return;
27820 /* The cursor image will be completely removed from the
27821 screen if the output area intersects the cursor area in
27822 y-direction. When we draw in [y0 y1[, and some part of
27823 the cursor is at y < y0, that part must have been drawn
27824 before. When scrolling, the cursor is erased before
27825 actually scrolling, so we don't come here. When not
27826 scrolling, the rows above the old cursor row must have
27827 changed, and in this case these rows must have written
27828 over the cursor image.
27830 Likewise if part of the cursor is below y1, with the
27831 exception of the cursor being in the first blank row at
27832 the buffer and window end because update_text_area
27833 doesn't draw that row. (Except when it does, but
27834 that's handled in update_text_area.) */
27836 cy0 = w->phys_cursor.y;
27837 cy1 = cy0 + w->phys_cursor_height;
27838 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
27839 return;
27841 w->phys_cursor_on_p = 0;
27844 #endif /* HAVE_WINDOW_SYSTEM */
27847 /************************************************************************
27848 Mouse Face
27849 ************************************************************************/
27851 #ifdef HAVE_WINDOW_SYSTEM
27853 /* EXPORT for RIF:
27854 Fix the display of area AREA of overlapping row ROW in window W
27855 with respect to the overlapping part OVERLAPS. */
27857 void
27858 x_fix_overlapping_area (struct window *w, struct glyph_row *row,
27859 enum glyph_row_area area, int overlaps)
27861 int i, x;
27863 block_input ();
27865 x = 0;
27866 for (i = 0; i < row->used[area];)
27868 if (row->glyphs[area][i].overlaps_vertically_p)
27870 int start = i, start_x = x;
27874 x += row->glyphs[area][i].pixel_width;
27875 ++i;
27877 while (i < row->used[area]
27878 && row->glyphs[area][i].overlaps_vertically_p);
27880 draw_glyphs (w, start_x, row, area,
27881 start, i,
27882 DRAW_NORMAL_TEXT, overlaps);
27884 else
27886 x += row->glyphs[area][i].pixel_width;
27887 ++i;
27891 unblock_input ();
27895 /* EXPORT:
27896 Draw the cursor glyph of window W in glyph row ROW. See the
27897 comment of draw_glyphs for the meaning of HL. */
27899 void
27900 draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
27901 enum draw_glyphs_face hl)
27903 /* If cursor hpos is out of bounds, don't draw garbage. This can
27904 happen in mini-buffer windows when switching between echo area
27905 glyphs and mini-buffer. */
27906 if ((row->reversed_p
27907 ? (w->phys_cursor.hpos >= 0)
27908 : (w->phys_cursor.hpos < row->used[TEXT_AREA])))
27910 int on_p = w->phys_cursor_on_p;
27911 int x1;
27912 int hpos = w->phys_cursor.hpos;
27914 /* When the window is hscrolled, cursor hpos can legitimately be
27915 out of bounds, but we draw the cursor at the corresponding
27916 window margin in that case. */
27917 if (!row->reversed_p && hpos < 0)
27918 hpos = 0;
27919 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
27920 hpos = row->used[TEXT_AREA] - 1;
27922 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA, hpos, hpos + 1,
27923 hl, 0);
27924 w->phys_cursor_on_p = on_p;
27926 if (hl == DRAW_CURSOR)
27927 w->phys_cursor_width = x1 - w->phys_cursor.x;
27928 /* When we erase the cursor, and ROW is overlapped by other
27929 rows, make sure that these overlapping parts of other rows
27930 are redrawn. */
27931 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
27933 w->phys_cursor_width = x1 - w->phys_cursor.x;
27935 if (row > w->current_matrix->rows
27936 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
27937 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
27938 OVERLAPS_ERASED_CURSOR);
27940 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
27941 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
27942 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
27943 OVERLAPS_ERASED_CURSOR);
27949 /* Erase the image of a cursor of window W from the screen. */
27951 void
27952 erase_phys_cursor (struct window *w)
27954 struct frame *f = XFRAME (w->frame);
27955 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
27956 int hpos = w->phys_cursor.hpos;
27957 int vpos = w->phys_cursor.vpos;
27958 int mouse_face_here_p = 0;
27959 struct glyph_matrix *active_glyphs = w->current_matrix;
27960 struct glyph_row *cursor_row;
27961 struct glyph *cursor_glyph;
27962 enum draw_glyphs_face hl;
27964 /* No cursor displayed or row invalidated => nothing to do on the
27965 screen. */
27966 if (w->phys_cursor_type == NO_CURSOR)
27967 goto mark_cursor_off;
27969 /* VPOS >= active_glyphs->nrows means that window has been resized.
27970 Don't bother to erase the cursor. */
27971 if (vpos >= active_glyphs->nrows)
27972 goto mark_cursor_off;
27974 /* If row containing cursor is marked invalid, there is nothing we
27975 can do. */
27976 cursor_row = MATRIX_ROW (active_glyphs, vpos);
27977 if (!cursor_row->enabled_p)
27978 goto mark_cursor_off;
27980 /* If line spacing is > 0, old cursor may only be partially visible in
27981 window after split-window. So adjust visible height. */
27982 cursor_row->visible_height = min (cursor_row->visible_height,
27983 window_text_bottom_y (w) - cursor_row->y);
27985 /* If row is completely invisible, don't attempt to delete a cursor which
27986 isn't there. This can happen if cursor is at top of a window, and
27987 we switch to a buffer with a header line in that window. */
27988 if (cursor_row->visible_height <= 0)
27989 goto mark_cursor_off;
27991 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
27992 if (cursor_row->cursor_in_fringe_p)
27994 cursor_row->cursor_in_fringe_p = 0;
27995 draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
27996 goto mark_cursor_off;
27999 /* This can happen when the new row is shorter than the old one.
28000 In this case, either draw_glyphs or clear_end_of_line
28001 should have cleared the cursor. Note that we wouldn't be
28002 able to erase the cursor in this case because we don't have a
28003 cursor glyph at hand. */
28004 if ((cursor_row->reversed_p
28005 ? (w->phys_cursor.hpos < 0)
28006 : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
28007 goto mark_cursor_off;
28009 /* When the window is hscrolled, cursor hpos can legitimately be out
28010 of bounds, but we draw the cursor at the corresponding window
28011 margin in that case. */
28012 if (!cursor_row->reversed_p && hpos < 0)
28013 hpos = 0;
28014 if (cursor_row->reversed_p && hpos >= cursor_row->used[TEXT_AREA])
28015 hpos = cursor_row->used[TEXT_AREA] - 1;
28017 /* If the cursor is in the mouse face area, redisplay that when
28018 we clear the cursor. */
28019 if (! NILP (hlinfo->mouse_face_window)
28020 && coords_in_mouse_face_p (w, hpos, vpos)
28021 /* Don't redraw the cursor's spot in mouse face if it is at the
28022 end of a line (on a newline). The cursor appears there, but
28023 mouse highlighting does not. */
28024 && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
28025 mouse_face_here_p = 1;
28027 /* Maybe clear the display under the cursor. */
28028 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
28030 int x, y;
28031 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
28032 int width;
28034 cursor_glyph = get_phys_cursor_glyph (w);
28035 if (cursor_glyph == NULL)
28036 goto mark_cursor_off;
28038 width = cursor_glyph->pixel_width;
28039 x = w->phys_cursor.x;
28040 if (x < 0)
28042 width += x;
28043 x = 0;
28045 width = min (width, window_box_width (w, TEXT_AREA) - x);
28046 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
28047 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
28049 if (width > 0)
28050 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
28053 /* Erase the cursor by redrawing the character underneath it. */
28054 if (mouse_face_here_p)
28055 hl = DRAW_MOUSE_FACE;
28056 else
28057 hl = DRAW_NORMAL_TEXT;
28058 draw_phys_cursor_glyph (w, cursor_row, hl);
28060 mark_cursor_off:
28061 w->phys_cursor_on_p = 0;
28062 w->phys_cursor_type = NO_CURSOR;
28066 /* EXPORT:
28067 Display or clear cursor of window W. If ON is zero, clear the
28068 cursor. If it is non-zero, display the cursor. If ON is nonzero,
28069 where to put the cursor is specified by HPOS, VPOS, X and Y. */
28071 void
28072 display_and_set_cursor (struct window *w, bool on,
28073 int hpos, int vpos, int x, int y)
28075 struct frame *f = XFRAME (w->frame);
28076 int new_cursor_type;
28077 int new_cursor_width;
28078 int active_cursor;
28079 struct glyph_row *glyph_row;
28080 struct glyph *glyph;
28082 /* This is pointless on invisible frames, and dangerous on garbaged
28083 windows and frames; in the latter case, the frame or window may
28084 be in the midst of changing its size, and x and y may be off the
28085 window. */
28086 if (! FRAME_VISIBLE_P (f)
28087 || FRAME_GARBAGED_P (f)
28088 || vpos >= w->current_matrix->nrows
28089 || hpos >= w->current_matrix->matrix_w)
28090 return;
28092 /* If cursor is off and we want it off, return quickly. */
28093 if (!on && !w->phys_cursor_on_p)
28094 return;
28096 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
28097 /* If cursor row is not enabled, we don't really know where to
28098 display the cursor. */
28099 if (!glyph_row->enabled_p)
28101 w->phys_cursor_on_p = 0;
28102 return;
28105 glyph = NULL;
28106 if (!glyph_row->exact_window_width_line_p
28107 || (0 <= hpos && hpos < glyph_row->used[TEXT_AREA]))
28108 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
28110 eassert (input_blocked_p ());
28112 /* Set new_cursor_type to the cursor we want to be displayed. */
28113 new_cursor_type = get_window_cursor_type (w, glyph,
28114 &new_cursor_width, &active_cursor);
28116 /* If cursor is currently being shown and we don't want it to be or
28117 it is in the wrong place, or the cursor type is not what we want,
28118 erase it. */
28119 if (w->phys_cursor_on_p
28120 && (!on
28121 || w->phys_cursor.x != x
28122 || w->phys_cursor.y != y
28123 /* HPOS can be negative in R2L rows whose
28124 exact_window_width_line_p flag is set (i.e. their newline
28125 would "overflow into the fringe"). */
28126 || hpos < 0
28127 || new_cursor_type != w->phys_cursor_type
28128 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
28129 && new_cursor_width != w->phys_cursor_width)))
28130 erase_phys_cursor (w);
28132 /* Don't check phys_cursor_on_p here because that flag is only set
28133 to zero in some cases where we know that the cursor has been
28134 completely erased, to avoid the extra work of erasing the cursor
28135 twice. In other words, phys_cursor_on_p can be 1 and the cursor
28136 still not be visible, or it has only been partly erased. */
28137 if (on)
28139 w->phys_cursor_ascent = glyph_row->ascent;
28140 w->phys_cursor_height = glyph_row->height;
28142 /* Set phys_cursor_.* before x_draw_.* is called because some
28143 of them may need the information. */
28144 w->phys_cursor.x = x;
28145 w->phys_cursor.y = glyph_row->y;
28146 w->phys_cursor.hpos = hpos;
28147 w->phys_cursor.vpos = vpos;
28150 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
28151 new_cursor_type, new_cursor_width,
28152 on, active_cursor);
28156 /* Switch the display of W's cursor on or off, according to the value
28157 of ON. */
28159 static void
28160 update_window_cursor (struct window *w, bool on)
28162 /* Don't update cursor in windows whose frame is in the process
28163 of being deleted. */
28164 if (w->current_matrix)
28166 int hpos = w->phys_cursor.hpos;
28167 int vpos = w->phys_cursor.vpos;
28168 struct glyph_row *row;
28170 if (vpos >= w->current_matrix->nrows
28171 || hpos >= w->current_matrix->matrix_w)
28172 return;
28174 row = MATRIX_ROW (w->current_matrix, vpos);
28176 /* When the window is hscrolled, cursor hpos can legitimately be
28177 out of bounds, but we draw the cursor at the corresponding
28178 window margin in that case. */
28179 if (!row->reversed_p && hpos < 0)
28180 hpos = 0;
28181 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
28182 hpos = row->used[TEXT_AREA] - 1;
28184 block_input ();
28185 display_and_set_cursor (w, on, hpos, vpos,
28186 w->phys_cursor.x, w->phys_cursor.y);
28187 unblock_input ();
28192 /* Call update_window_cursor with parameter ON_P on all leaf windows
28193 in the window tree rooted at W. */
28195 static void
28196 update_cursor_in_window_tree (struct window *w, bool on_p)
28198 while (w)
28200 if (WINDOWP (w->contents))
28201 update_cursor_in_window_tree (XWINDOW (w->contents), on_p);
28202 else
28203 update_window_cursor (w, on_p);
28205 w = NILP (w->next) ? 0 : XWINDOW (w->next);
28210 /* EXPORT:
28211 Display the cursor on window W, or clear it, according to ON_P.
28212 Don't change the cursor's position. */
28214 void
28215 x_update_cursor (struct frame *f, bool on_p)
28217 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
28221 /* EXPORT:
28222 Clear the cursor of window W to background color, and mark the
28223 cursor as not shown. This is used when the text where the cursor
28224 is about to be rewritten. */
28226 void
28227 x_clear_cursor (struct window *w)
28229 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
28230 update_window_cursor (w, 0);
28233 #endif /* HAVE_WINDOW_SYSTEM */
28235 /* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
28236 and MSDOS. */
28237 static void
28238 draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
28239 int start_hpos, int end_hpos,
28240 enum draw_glyphs_face draw)
28242 #ifdef HAVE_WINDOW_SYSTEM
28243 if (FRAME_WINDOW_P (XFRAME (w->frame)))
28245 draw_glyphs (w, start_x, row, TEXT_AREA, start_hpos, end_hpos, draw, 0);
28246 return;
28248 #endif
28249 #if defined (HAVE_GPM) || defined (MSDOS) || defined (WINDOWSNT)
28250 tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
28251 #endif
28254 /* Display the active region described by mouse_face_* according to DRAW. */
28256 static void
28257 show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
28259 struct window *w = XWINDOW (hlinfo->mouse_face_window);
28260 struct frame *f = XFRAME (WINDOW_FRAME (w));
28262 if (/* If window is in the process of being destroyed, don't bother
28263 to do anything. */
28264 w->current_matrix != NULL
28265 /* Don't update mouse highlight if hidden. */
28266 && (draw != DRAW_MOUSE_FACE || !hlinfo->mouse_face_hidden)
28267 /* Recognize when we are called to operate on rows that don't exist
28268 anymore. This can happen when a window is split. */
28269 && hlinfo->mouse_face_end_row < w->current_matrix->nrows)
28271 int phys_cursor_on_p = w->phys_cursor_on_p;
28272 struct glyph_row *row, *first, *last;
28274 first = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
28275 last = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
28277 for (row = first; row <= last && row->enabled_p; ++row)
28279 int start_hpos, end_hpos, start_x;
28281 /* For all but the first row, the highlight starts at column 0. */
28282 if (row == first)
28284 /* R2L rows have BEG and END in reversed order, but the
28285 screen drawing geometry is always left to right. So
28286 we need to mirror the beginning and end of the
28287 highlighted area in R2L rows. */
28288 if (!row->reversed_p)
28290 start_hpos = hlinfo->mouse_face_beg_col;
28291 start_x = hlinfo->mouse_face_beg_x;
28293 else if (row == last)
28295 start_hpos = hlinfo->mouse_face_end_col;
28296 start_x = hlinfo->mouse_face_end_x;
28298 else
28300 start_hpos = 0;
28301 start_x = 0;
28304 else if (row->reversed_p && row == last)
28306 start_hpos = hlinfo->mouse_face_end_col;
28307 start_x = hlinfo->mouse_face_end_x;
28309 else
28311 start_hpos = 0;
28312 start_x = 0;
28315 if (row == last)
28317 if (!row->reversed_p)
28318 end_hpos = hlinfo->mouse_face_end_col;
28319 else if (row == first)
28320 end_hpos = hlinfo->mouse_face_beg_col;
28321 else
28323 end_hpos = row->used[TEXT_AREA];
28324 if (draw == DRAW_NORMAL_TEXT)
28325 row->fill_line_p = 1; /* Clear to end of line */
28328 else if (row->reversed_p && row == first)
28329 end_hpos = hlinfo->mouse_face_beg_col;
28330 else
28332 end_hpos = row->used[TEXT_AREA];
28333 if (draw == DRAW_NORMAL_TEXT)
28334 row->fill_line_p = 1; /* Clear to end of line */
28337 if (end_hpos > start_hpos)
28339 draw_row_with_mouse_face (w, start_x, row,
28340 start_hpos, end_hpos, draw);
28342 row->mouse_face_p
28343 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
28347 #ifdef HAVE_WINDOW_SYSTEM
28348 /* When we've written over the cursor, arrange for it to
28349 be displayed again. */
28350 if (FRAME_WINDOW_P (f)
28351 && phys_cursor_on_p && !w->phys_cursor_on_p)
28353 int hpos = w->phys_cursor.hpos;
28355 /* When the window is hscrolled, cursor hpos can legitimately be
28356 out of bounds, but we draw the cursor at the corresponding
28357 window margin in that case. */
28358 if (!row->reversed_p && hpos < 0)
28359 hpos = 0;
28360 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
28361 hpos = row->used[TEXT_AREA] - 1;
28363 block_input ();
28364 display_and_set_cursor (w, 1, hpos, w->phys_cursor.vpos,
28365 w->phys_cursor.x, w->phys_cursor.y);
28366 unblock_input ();
28368 #endif /* HAVE_WINDOW_SYSTEM */
28371 #ifdef HAVE_WINDOW_SYSTEM
28372 /* Change the mouse cursor. */
28373 if (FRAME_WINDOW_P (f) && NILP (do_mouse_tracking))
28375 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
28376 if (draw == DRAW_NORMAL_TEXT
28377 && !EQ (hlinfo->mouse_face_window, f->tool_bar_window))
28378 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
28379 else
28380 #endif
28381 if (draw == DRAW_MOUSE_FACE)
28382 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
28383 else
28384 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
28386 #endif /* HAVE_WINDOW_SYSTEM */
28389 /* EXPORT:
28390 Clear out the mouse-highlighted active region.
28391 Redraw it un-highlighted first. Value is non-zero if mouse
28392 face was actually drawn unhighlighted. */
28395 clear_mouse_face (Mouse_HLInfo *hlinfo)
28397 int cleared = 0;
28399 if (!hlinfo->mouse_face_hidden && !NILP (hlinfo->mouse_face_window))
28401 show_mouse_face (hlinfo, DRAW_NORMAL_TEXT);
28402 cleared = 1;
28405 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
28406 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
28407 hlinfo->mouse_face_window = Qnil;
28408 hlinfo->mouse_face_overlay = Qnil;
28409 return cleared;
28412 /* Return true if the coordinates HPOS and VPOS on windows W are
28413 within the mouse face on that window. */
28414 static bool
28415 coords_in_mouse_face_p (struct window *w, int hpos, int vpos)
28417 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
28419 /* Quickly resolve the easy cases. */
28420 if (!(WINDOWP (hlinfo->mouse_face_window)
28421 && XWINDOW (hlinfo->mouse_face_window) == w))
28422 return false;
28423 if (vpos < hlinfo->mouse_face_beg_row
28424 || vpos > hlinfo->mouse_face_end_row)
28425 return false;
28426 if (vpos > hlinfo->mouse_face_beg_row
28427 && vpos < hlinfo->mouse_face_end_row)
28428 return true;
28430 if (!MATRIX_ROW (w->current_matrix, vpos)->reversed_p)
28432 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
28434 if (hlinfo->mouse_face_beg_col <= hpos && hpos < hlinfo->mouse_face_end_col)
28435 return true;
28437 else if ((vpos == hlinfo->mouse_face_beg_row
28438 && hpos >= hlinfo->mouse_face_beg_col)
28439 || (vpos == hlinfo->mouse_face_end_row
28440 && hpos < hlinfo->mouse_face_end_col))
28441 return true;
28443 else
28445 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
28447 if (hlinfo->mouse_face_end_col < hpos && hpos <= hlinfo->mouse_face_beg_col)
28448 return true;
28450 else if ((vpos == hlinfo->mouse_face_beg_row
28451 && hpos <= hlinfo->mouse_face_beg_col)
28452 || (vpos == hlinfo->mouse_face_end_row
28453 && hpos > hlinfo->mouse_face_end_col))
28454 return true;
28456 return false;
28460 /* EXPORT:
28461 True if physical cursor of window W is within mouse face. */
28463 bool
28464 cursor_in_mouse_face_p (struct window *w)
28466 int hpos = w->phys_cursor.hpos;
28467 int vpos = w->phys_cursor.vpos;
28468 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
28470 /* When the window is hscrolled, cursor hpos can legitimately be out
28471 of bounds, but we draw the cursor at the corresponding window
28472 margin in that case. */
28473 if (!row->reversed_p && hpos < 0)
28474 hpos = 0;
28475 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
28476 hpos = row->used[TEXT_AREA] - 1;
28478 return coords_in_mouse_face_p (w, hpos, vpos);
28483 /* Find the glyph rows START_ROW and END_ROW of window W that display
28484 characters between buffer positions START_CHARPOS and END_CHARPOS
28485 (excluding END_CHARPOS). DISP_STRING is a display string that
28486 covers these buffer positions. This is similar to
28487 row_containing_pos, but is more accurate when bidi reordering makes
28488 buffer positions change non-linearly with glyph rows. */
28489 static void
28490 rows_from_pos_range (struct window *w,
28491 ptrdiff_t start_charpos, ptrdiff_t end_charpos,
28492 Lisp_Object disp_string,
28493 struct glyph_row **start, struct glyph_row **end)
28495 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
28496 int last_y = window_text_bottom_y (w);
28497 struct glyph_row *row;
28499 *start = NULL;
28500 *end = NULL;
28502 while (!first->enabled_p
28503 && first < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
28504 first++;
28506 /* Find the START row. */
28507 for (row = first;
28508 row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y;
28509 row++)
28511 /* A row can potentially be the START row if the range of the
28512 characters it displays intersects the range
28513 [START_CHARPOS..END_CHARPOS). */
28514 if (! ((start_charpos < MATRIX_ROW_START_CHARPOS (row)
28515 && end_charpos < MATRIX_ROW_START_CHARPOS (row))
28516 /* See the commentary in row_containing_pos, for the
28517 explanation of the complicated way to check whether
28518 some position is beyond the end of the characters
28519 displayed by a row. */
28520 || ((start_charpos > MATRIX_ROW_END_CHARPOS (row)
28521 || (start_charpos == MATRIX_ROW_END_CHARPOS (row)
28522 && !row->ends_at_zv_p
28523 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
28524 && (end_charpos > MATRIX_ROW_END_CHARPOS (row)
28525 || (end_charpos == MATRIX_ROW_END_CHARPOS (row)
28526 && !row->ends_at_zv_p
28527 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))))))
28529 /* Found a candidate row. Now make sure at least one of the
28530 glyphs it displays has a charpos from the range
28531 [START_CHARPOS..END_CHARPOS).
28533 This is not obvious because bidi reordering could make
28534 buffer positions of a row be 1,2,3,102,101,100, and if we
28535 want to highlight characters in [50..60), we don't want
28536 this row, even though [50..60) does intersect [1..103),
28537 the range of character positions given by the row's start
28538 and end positions. */
28539 struct glyph *g = row->glyphs[TEXT_AREA];
28540 struct glyph *e = g + row->used[TEXT_AREA];
28542 while (g < e)
28544 if (((BUFFERP (g->object) || INTEGERP (g->object))
28545 && start_charpos <= g->charpos && g->charpos < end_charpos)
28546 /* A glyph that comes from DISP_STRING is by
28547 definition to be highlighted. */
28548 || EQ (g->object, disp_string))
28549 *start = row;
28550 g++;
28552 if (*start)
28553 break;
28557 /* Find the END row. */
28558 if (!*start
28559 /* If the last row is partially visible, start looking for END
28560 from that row, instead of starting from FIRST. */
28561 && !(row->enabled_p
28562 && row->y < last_y && MATRIX_ROW_BOTTOM_Y (row) > last_y))
28563 row = first;
28564 for ( ; row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y; row++)
28566 struct glyph_row *next = row + 1;
28567 ptrdiff_t next_start = MATRIX_ROW_START_CHARPOS (next);
28569 if (!next->enabled_p
28570 || next >= MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)
28571 /* The first row >= START whose range of displayed characters
28572 does NOT intersect the range [START_CHARPOS..END_CHARPOS]
28573 is the row END + 1. */
28574 || (start_charpos < next_start
28575 && end_charpos < next_start)
28576 || ((start_charpos > MATRIX_ROW_END_CHARPOS (next)
28577 || (start_charpos == MATRIX_ROW_END_CHARPOS (next)
28578 && !next->ends_at_zv_p
28579 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))
28580 && (end_charpos > MATRIX_ROW_END_CHARPOS (next)
28581 || (end_charpos == MATRIX_ROW_END_CHARPOS (next)
28582 && !next->ends_at_zv_p
28583 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))))
28585 *end = row;
28586 break;
28588 else
28590 /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
28591 but none of the characters it displays are in the range, it is
28592 also END + 1. */
28593 struct glyph *g = next->glyphs[TEXT_AREA];
28594 struct glyph *s = g;
28595 struct glyph *e = g + next->used[TEXT_AREA];
28597 while (g < e)
28599 if (((BUFFERP (g->object) || INTEGERP (g->object))
28600 && ((start_charpos <= g->charpos && g->charpos < end_charpos)
28601 /* If the buffer position of the first glyph in
28602 the row is equal to END_CHARPOS, it means
28603 the last character to be highlighted is the
28604 newline of ROW, and we must consider NEXT as
28605 END, not END+1. */
28606 || (((!next->reversed_p && g == s)
28607 || (next->reversed_p && g == e - 1))
28608 && (g->charpos == end_charpos
28609 /* Special case for when NEXT is an
28610 empty line at ZV. */
28611 || (g->charpos == -1
28612 && !row->ends_at_zv_p
28613 && next_start == end_charpos)))))
28614 /* A glyph that comes from DISP_STRING is by
28615 definition to be highlighted. */
28616 || EQ (g->object, disp_string))
28617 break;
28618 g++;
28620 if (g == e)
28622 *end = row;
28623 break;
28625 /* The first row that ends at ZV must be the last to be
28626 highlighted. */
28627 else if (next->ends_at_zv_p)
28629 *end = next;
28630 break;
28636 /* This function sets the mouse_face_* elements of HLINFO, assuming
28637 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
28638 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
28639 for the overlay or run of text properties specifying the mouse
28640 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
28641 before-string and after-string that must also be highlighted.
28642 DISP_STRING, if non-nil, is a display string that may cover some
28643 or all of the highlighted text. */
28645 static void
28646 mouse_face_from_buffer_pos (Lisp_Object window,
28647 Mouse_HLInfo *hlinfo,
28648 ptrdiff_t mouse_charpos,
28649 ptrdiff_t start_charpos,
28650 ptrdiff_t end_charpos,
28651 Lisp_Object before_string,
28652 Lisp_Object after_string,
28653 Lisp_Object disp_string)
28655 struct window *w = XWINDOW (window);
28656 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
28657 struct glyph_row *r1, *r2;
28658 struct glyph *glyph, *end;
28659 ptrdiff_t ignore, pos;
28660 int x;
28662 eassert (NILP (disp_string) || STRINGP (disp_string));
28663 eassert (NILP (before_string) || STRINGP (before_string));
28664 eassert (NILP (after_string) || STRINGP (after_string));
28666 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
28667 rows_from_pos_range (w, start_charpos, end_charpos, disp_string, &r1, &r2);
28668 if (r1 == NULL)
28669 r1 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
28670 /* If the before-string or display-string contains newlines,
28671 rows_from_pos_range skips to its last row. Move back. */
28672 if (!NILP (before_string) || !NILP (disp_string))
28674 struct glyph_row *prev;
28675 while ((prev = r1 - 1, prev >= first)
28676 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
28677 && prev->used[TEXT_AREA] > 0)
28679 struct glyph *beg = prev->glyphs[TEXT_AREA];
28680 glyph = beg + prev->used[TEXT_AREA];
28681 while (--glyph >= beg && INTEGERP (glyph->object));
28682 if (glyph < beg
28683 || !(EQ (glyph->object, before_string)
28684 || EQ (glyph->object, disp_string)))
28685 break;
28686 r1 = prev;
28689 if (r2 == NULL)
28691 r2 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
28692 hlinfo->mouse_face_past_end = 1;
28694 else if (!NILP (after_string))
28696 /* If the after-string has newlines, advance to its last row. */
28697 struct glyph_row *next;
28698 struct glyph_row *last
28699 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
28701 for (next = r2 + 1;
28702 next <= last
28703 && next->used[TEXT_AREA] > 0
28704 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
28705 ++next)
28706 r2 = next;
28708 /* The rest of the display engine assumes that mouse_face_beg_row is
28709 either above mouse_face_end_row or identical to it. But with
28710 bidi-reordered continued lines, the row for START_CHARPOS could
28711 be below the row for END_CHARPOS. If so, swap the rows and store
28712 them in correct order. */
28713 if (r1->y > r2->y)
28715 struct glyph_row *tem = r2;
28717 r2 = r1;
28718 r1 = tem;
28721 hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
28722 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
28724 /* For a bidi-reordered row, the positions of BEFORE_STRING,
28725 AFTER_STRING, DISP_STRING, START_CHARPOS, and END_CHARPOS
28726 could be anywhere in the row and in any order. The strategy
28727 below is to find the leftmost and the rightmost glyph that
28728 belongs to either of these 3 strings, or whose position is
28729 between START_CHARPOS and END_CHARPOS, and highlight all the
28730 glyphs between those two. This may cover more than just the text
28731 between START_CHARPOS and END_CHARPOS if the range of characters
28732 strides the bidi level boundary, e.g. if the beginning is in R2L
28733 text while the end is in L2R text or vice versa. */
28734 if (!r1->reversed_p)
28736 /* This row is in a left to right paragraph. Scan it left to
28737 right. */
28738 glyph = r1->glyphs[TEXT_AREA];
28739 end = glyph + r1->used[TEXT_AREA];
28740 x = r1->x;
28742 /* Skip truncation glyphs at the start of the glyph row. */
28743 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
28744 for (; glyph < end
28745 && INTEGERP (glyph->object)
28746 && glyph->charpos < 0;
28747 ++glyph)
28748 x += glyph->pixel_width;
28750 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
28751 or DISP_STRING, and the first glyph from buffer whose
28752 position is between START_CHARPOS and END_CHARPOS. */
28753 for (; glyph < end
28754 && !INTEGERP (glyph->object)
28755 && !EQ (glyph->object, disp_string)
28756 && !(BUFFERP (glyph->object)
28757 && (glyph->charpos >= start_charpos
28758 && glyph->charpos < end_charpos));
28759 ++glyph)
28761 /* BEFORE_STRING or AFTER_STRING are only relevant if they
28762 are present at buffer positions between START_CHARPOS and
28763 END_CHARPOS, or if they come from an overlay. */
28764 if (EQ (glyph->object, before_string))
28766 pos = string_buffer_position (before_string,
28767 start_charpos);
28768 /* If pos == 0, it means before_string came from an
28769 overlay, not from a buffer position. */
28770 if (!pos || (pos >= start_charpos && pos < end_charpos))
28771 break;
28773 else if (EQ (glyph->object, after_string))
28775 pos = string_buffer_position (after_string, end_charpos);
28776 if (!pos || (pos >= start_charpos && pos < end_charpos))
28777 break;
28779 x += glyph->pixel_width;
28781 hlinfo->mouse_face_beg_x = x;
28782 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
28784 else
28786 /* This row is in a right to left paragraph. Scan it right to
28787 left. */
28788 struct glyph *g;
28790 end = r1->glyphs[TEXT_AREA] - 1;
28791 glyph = end + r1->used[TEXT_AREA];
28793 /* Skip truncation glyphs at the start of the glyph row. */
28794 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
28795 for (; glyph > end
28796 && INTEGERP (glyph->object)
28797 && glyph->charpos < 0;
28798 --glyph)
28801 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
28802 or DISP_STRING, and the first glyph from buffer whose
28803 position is between START_CHARPOS and END_CHARPOS. */
28804 for (; glyph > end
28805 && !INTEGERP (glyph->object)
28806 && !EQ (glyph->object, disp_string)
28807 && !(BUFFERP (glyph->object)
28808 && (glyph->charpos >= start_charpos
28809 && glyph->charpos < end_charpos));
28810 --glyph)
28812 /* BEFORE_STRING or AFTER_STRING are only relevant if they
28813 are present at buffer positions between START_CHARPOS and
28814 END_CHARPOS, or if they come from an overlay. */
28815 if (EQ (glyph->object, before_string))
28817 pos = string_buffer_position (before_string, start_charpos);
28818 /* If pos == 0, it means before_string came from an
28819 overlay, not from a buffer position. */
28820 if (!pos || (pos >= start_charpos && pos < end_charpos))
28821 break;
28823 else if (EQ (glyph->object, after_string))
28825 pos = string_buffer_position (after_string, end_charpos);
28826 if (!pos || (pos >= start_charpos && pos < end_charpos))
28827 break;
28831 glyph++; /* first glyph to the right of the highlighted area */
28832 for (g = r1->glyphs[TEXT_AREA], x = r1->x; g < glyph; g++)
28833 x += g->pixel_width;
28834 hlinfo->mouse_face_beg_x = x;
28835 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
28838 /* If the highlight ends in a different row, compute GLYPH and END
28839 for the end row. Otherwise, reuse the values computed above for
28840 the row where the highlight begins. */
28841 if (r2 != r1)
28843 if (!r2->reversed_p)
28845 glyph = r2->glyphs[TEXT_AREA];
28846 end = glyph + r2->used[TEXT_AREA];
28847 x = r2->x;
28849 else
28851 end = r2->glyphs[TEXT_AREA] - 1;
28852 glyph = end + r2->used[TEXT_AREA];
28856 if (!r2->reversed_p)
28858 /* Skip truncation and continuation glyphs near the end of the
28859 row, and also blanks and stretch glyphs inserted by
28860 extend_face_to_end_of_line. */
28861 while (end > glyph
28862 && INTEGERP ((end - 1)->object))
28863 --end;
28864 /* Scan the rest of the glyph row from the end, looking for the
28865 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
28866 DISP_STRING, or whose position is between START_CHARPOS
28867 and END_CHARPOS */
28868 for (--end;
28869 end > glyph
28870 && !INTEGERP (end->object)
28871 && !EQ (end->object, disp_string)
28872 && !(BUFFERP (end->object)
28873 && (end->charpos >= start_charpos
28874 && end->charpos < end_charpos));
28875 --end)
28877 /* BEFORE_STRING or AFTER_STRING are only relevant if they
28878 are present at buffer positions between START_CHARPOS and
28879 END_CHARPOS, or if they come from an overlay. */
28880 if (EQ (end->object, before_string))
28882 pos = string_buffer_position (before_string, start_charpos);
28883 if (!pos || (pos >= start_charpos && pos < end_charpos))
28884 break;
28886 else if (EQ (end->object, after_string))
28888 pos = string_buffer_position (after_string, end_charpos);
28889 if (!pos || (pos >= start_charpos && pos < end_charpos))
28890 break;
28893 /* Find the X coordinate of the last glyph to be highlighted. */
28894 for (; glyph <= end; ++glyph)
28895 x += glyph->pixel_width;
28897 hlinfo->mouse_face_end_x = x;
28898 hlinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
28900 else
28902 /* Skip truncation and continuation glyphs near the end of the
28903 row, and also blanks and stretch glyphs inserted by
28904 extend_face_to_end_of_line. */
28905 x = r2->x;
28906 end++;
28907 while (end < glyph
28908 && INTEGERP (end->object))
28910 x += end->pixel_width;
28911 ++end;
28913 /* Scan the rest of the glyph row from the end, looking for the
28914 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
28915 DISP_STRING, or whose position is between START_CHARPOS
28916 and END_CHARPOS */
28917 for ( ;
28918 end < glyph
28919 && !INTEGERP (end->object)
28920 && !EQ (end->object, disp_string)
28921 && !(BUFFERP (end->object)
28922 && (end->charpos >= start_charpos
28923 && end->charpos < end_charpos));
28924 ++end)
28926 /* BEFORE_STRING or AFTER_STRING are only relevant if they
28927 are present at buffer positions between START_CHARPOS and
28928 END_CHARPOS, or if they come from an overlay. */
28929 if (EQ (end->object, before_string))
28931 pos = string_buffer_position (before_string, start_charpos);
28932 if (!pos || (pos >= start_charpos && pos < end_charpos))
28933 break;
28935 else if (EQ (end->object, after_string))
28937 pos = string_buffer_position (after_string, end_charpos);
28938 if (!pos || (pos >= start_charpos && pos < end_charpos))
28939 break;
28941 x += end->pixel_width;
28943 /* If we exited the above loop because we arrived at the last
28944 glyph of the row, and its buffer position is still not in
28945 range, it means the last character in range is the preceding
28946 newline. Bump the end column and x values to get past the
28947 last glyph. */
28948 if (end == glyph
28949 && BUFFERP (end->object)
28950 && (end->charpos < start_charpos
28951 || end->charpos >= end_charpos))
28953 x += end->pixel_width;
28954 ++end;
28956 hlinfo->mouse_face_end_x = x;
28957 hlinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
28960 hlinfo->mouse_face_window = window;
28961 hlinfo->mouse_face_face_id
28962 = face_at_buffer_position (w, mouse_charpos, &ignore,
28963 mouse_charpos + 1,
28964 !hlinfo->mouse_face_hidden, -1);
28965 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
28968 /* The following function is not used anymore (replaced with
28969 mouse_face_from_string_pos), but I leave it here for the time
28970 being, in case someone would. */
28972 #if 0 /* not used */
28974 /* Find the position of the glyph for position POS in OBJECT in
28975 window W's current matrix, and return in *X, *Y the pixel
28976 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
28978 RIGHT_P non-zero means return the position of the right edge of the
28979 glyph, RIGHT_P zero means return the left edge position.
28981 If no glyph for POS exists in the matrix, return the position of
28982 the glyph with the next smaller position that is in the matrix, if
28983 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
28984 exists in the matrix, return the position of the glyph with the
28985 next larger position in OBJECT.
28987 Value is non-zero if a glyph was found. */
28989 static int
28990 fast_find_string_pos (struct window *w, ptrdiff_t pos, Lisp_Object object,
28991 int *hpos, int *vpos, int *x, int *y, int right_p)
28993 int yb = window_text_bottom_y (w);
28994 struct glyph_row *r;
28995 struct glyph *best_glyph = NULL;
28996 struct glyph_row *best_row = NULL;
28997 int best_x = 0;
28999 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
29000 r->enabled_p && r->y < yb;
29001 ++r)
29003 struct glyph *g = r->glyphs[TEXT_AREA];
29004 struct glyph *e = g + r->used[TEXT_AREA];
29005 int gx;
29007 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
29008 if (EQ (g->object, object))
29010 if (g->charpos == pos)
29012 best_glyph = g;
29013 best_x = gx;
29014 best_row = r;
29015 goto found;
29017 else if (best_glyph == NULL
29018 || ((eabs (g->charpos - pos)
29019 < eabs (best_glyph->charpos - pos))
29020 && (right_p
29021 ? g->charpos < pos
29022 : g->charpos > pos)))
29024 best_glyph = g;
29025 best_x = gx;
29026 best_row = r;
29031 found:
29033 if (best_glyph)
29035 *x = best_x;
29036 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
29038 if (right_p)
29040 *x += best_glyph->pixel_width;
29041 ++*hpos;
29044 *y = best_row->y;
29045 *vpos = MATRIX_ROW_VPOS (best_row, w->current_matrix);
29048 return best_glyph != NULL;
29050 #endif /* not used */
29052 /* Find the positions of the first and the last glyphs in window W's
29053 current matrix that occlude positions [STARTPOS..ENDPOS) in OBJECT
29054 (assumed to be a string), and return in HLINFO's mouse_face_*
29055 members the pixel and column/row coordinates of those glyphs. */
29057 static void
29058 mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
29059 Lisp_Object object,
29060 ptrdiff_t startpos, ptrdiff_t endpos)
29062 int yb = window_text_bottom_y (w);
29063 struct glyph_row *r;
29064 struct glyph *g, *e;
29065 int gx;
29066 int found = 0;
29068 /* Find the glyph row with at least one position in the range
29069 [STARTPOS..ENDPOS), and the first glyph in that row whose
29070 position belongs to that range. */
29071 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
29072 r->enabled_p && r->y < yb;
29073 ++r)
29075 if (!r->reversed_p)
29077 g = r->glyphs[TEXT_AREA];
29078 e = g + r->used[TEXT_AREA];
29079 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
29080 if (EQ (g->object, object)
29081 && startpos <= g->charpos && g->charpos < endpos)
29083 hlinfo->mouse_face_beg_row
29084 = MATRIX_ROW_VPOS (r, w->current_matrix);
29085 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
29086 hlinfo->mouse_face_beg_x = gx;
29087 found = 1;
29088 break;
29091 else
29093 struct glyph *g1;
29095 e = r->glyphs[TEXT_AREA];
29096 g = e + r->used[TEXT_AREA];
29097 for ( ; g > e; --g)
29098 if (EQ ((g-1)->object, object)
29099 && startpos <= (g-1)->charpos && (g-1)->charpos < endpos)
29101 hlinfo->mouse_face_beg_row
29102 = MATRIX_ROW_VPOS (r, w->current_matrix);
29103 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
29104 for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
29105 gx += g1->pixel_width;
29106 hlinfo->mouse_face_beg_x = gx;
29107 found = 1;
29108 break;
29111 if (found)
29112 break;
29115 if (!found)
29116 return;
29118 /* Starting with the next row, look for the first row which does NOT
29119 include any glyphs whose positions are in the range. */
29120 for (++r; r->enabled_p && r->y < yb; ++r)
29122 g = r->glyphs[TEXT_AREA];
29123 e = g + r->used[TEXT_AREA];
29124 found = 0;
29125 for ( ; g < e; ++g)
29126 if (EQ (g->object, object)
29127 && startpos <= g->charpos && g->charpos < endpos)
29129 found = 1;
29130 break;
29132 if (!found)
29133 break;
29136 /* The highlighted region ends on the previous row. */
29137 r--;
29139 /* Set the end row. */
29140 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r, w->current_matrix);
29142 /* Compute and set the end column and the end column's horizontal
29143 pixel coordinate. */
29144 if (!r->reversed_p)
29146 g = r->glyphs[TEXT_AREA];
29147 e = g + r->used[TEXT_AREA];
29148 for ( ; e > g; --e)
29149 if (EQ ((e-1)->object, object)
29150 && startpos <= (e-1)->charpos && (e-1)->charpos < endpos)
29151 break;
29152 hlinfo->mouse_face_end_col = e - g;
29154 for (gx = r->x; g < e; ++g)
29155 gx += g->pixel_width;
29156 hlinfo->mouse_face_end_x = gx;
29158 else
29160 e = r->glyphs[TEXT_AREA];
29161 g = e + r->used[TEXT_AREA];
29162 for (gx = r->x ; e < g; ++e)
29164 if (EQ (e->object, object)
29165 && startpos <= e->charpos && e->charpos < endpos)
29166 break;
29167 gx += e->pixel_width;
29169 hlinfo->mouse_face_end_col = e - r->glyphs[TEXT_AREA];
29170 hlinfo->mouse_face_end_x = gx;
29174 #ifdef HAVE_WINDOW_SYSTEM
29176 /* See if position X, Y is within a hot-spot of an image. */
29178 static int
29179 on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
29181 if (!CONSP (hot_spot))
29182 return 0;
29184 if (EQ (XCAR (hot_spot), Qrect))
29186 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
29187 Lisp_Object rect = XCDR (hot_spot);
29188 Lisp_Object tem;
29189 if (!CONSP (rect))
29190 return 0;
29191 if (!CONSP (XCAR (rect)))
29192 return 0;
29193 if (!CONSP (XCDR (rect)))
29194 return 0;
29195 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
29196 return 0;
29197 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
29198 return 0;
29199 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
29200 return 0;
29201 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
29202 return 0;
29203 return 1;
29205 else if (EQ (XCAR (hot_spot), Qcircle))
29207 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
29208 Lisp_Object circ = XCDR (hot_spot);
29209 Lisp_Object lr, lx0, ly0;
29210 if (CONSP (circ)
29211 && CONSP (XCAR (circ))
29212 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
29213 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
29214 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
29216 double r = XFLOATINT (lr);
29217 double dx = XINT (lx0) - x;
29218 double dy = XINT (ly0) - y;
29219 return (dx * dx + dy * dy <= r * r);
29222 else if (EQ (XCAR (hot_spot), Qpoly))
29224 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
29225 if (VECTORP (XCDR (hot_spot)))
29227 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
29228 Lisp_Object *poly = v->contents;
29229 ptrdiff_t n = v->header.size;
29230 ptrdiff_t i;
29231 int inside = 0;
29232 Lisp_Object lx, ly;
29233 int x0, y0;
29235 /* Need an even number of coordinates, and at least 3 edges. */
29236 if (n < 6 || n & 1)
29237 return 0;
29239 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
29240 If count is odd, we are inside polygon. Pixels on edges
29241 may or may not be included depending on actual geometry of the
29242 polygon. */
29243 if ((lx = poly[n-2], !INTEGERP (lx))
29244 || (ly = poly[n-1], !INTEGERP (lx)))
29245 return 0;
29246 x0 = XINT (lx), y0 = XINT (ly);
29247 for (i = 0; i < n; i += 2)
29249 int x1 = x0, y1 = y0;
29250 if ((lx = poly[i], !INTEGERP (lx))
29251 || (ly = poly[i+1], !INTEGERP (ly)))
29252 return 0;
29253 x0 = XINT (lx), y0 = XINT (ly);
29255 /* Does this segment cross the X line? */
29256 if (x0 >= x)
29258 if (x1 >= x)
29259 continue;
29261 else if (x1 < x)
29262 continue;
29263 if (y > y0 && y > y1)
29264 continue;
29265 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
29266 inside = !inside;
29268 return inside;
29271 return 0;
29274 Lisp_Object
29275 find_hot_spot (Lisp_Object map, int x, int y)
29277 while (CONSP (map))
29279 if (CONSP (XCAR (map))
29280 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
29281 return XCAR (map);
29282 map = XCDR (map);
29285 return Qnil;
29288 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
29289 3, 3, 0,
29290 doc: /* Lookup in image map MAP coordinates X and Y.
29291 An image map is an alist where each element has the format (AREA ID PLIST).
29292 An AREA is specified as either a rectangle, a circle, or a polygon:
29293 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
29294 pixel coordinates of the upper left and bottom right corners.
29295 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
29296 and the radius of the circle; r may be a float or integer.
29297 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
29298 vector describes one corner in the polygon.
29299 Returns the alist element for the first matching AREA in MAP. */)
29300 (Lisp_Object map, Lisp_Object x, Lisp_Object y)
29302 if (NILP (map))
29303 return Qnil;
29305 CHECK_NUMBER (x);
29306 CHECK_NUMBER (y);
29308 return find_hot_spot (map,
29309 clip_to_bounds (INT_MIN, XINT (x), INT_MAX),
29310 clip_to_bounds (INT_MIN, XINT (y), INT_MAX));
29314 /* Display frame CURSOR, optionally using shape defined by POINTER. */
29315 static void
29316 define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
29318 /* Do not change cursor shape while dragging mouse. */
29319 if (!NILP (do_mouse_tracking))
29320 return;
29322 if (!NILP (pointer))
29324 if (EQ (pointer, Qarrow))
29325 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
29326 else if (EQ (pointer, Qhand))
29327 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
29328 else if (EQ (pointer, Qtext))
29329 cursor = FRAME_X_OUTPUT (f)->text_cursor;
29330 else if (EQ (pointer, intern ("hdrag")))
29331 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
29332 else if (EQ (pointer, intern ("nhdrag")))
29333 cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
29334 #ifdef HAVE_X_WINDOWS
29335 else if (EQ (pointer, intern ("vdrag")))
29336 cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
29337 #endif
29338 else if (EQ (pointer, intern ("hourglass")))
29339 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
29340 else if (EQ (pointer, Qmodeline))
29341 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
29342 else
29343 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
29346 if (cursor != No_Cursor)
29347 FRAME_RIF (f)->define_frame_cursor (f, cursor);
29350 #endif /* HAVE_WINDOW_SYSTEM */
29352 /* Take proper action when mouse has moved to the mode or header line
29353 or marginal area AREA of window W, x-position X and y-position Y.
29354 X is relative to the start of the text display area of W, so the
29355 width of bitmap areas and scroll bars must be subtracted to get a
29356 position relative to the start of the mode line. */
29358 static void
29359 note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
29360 enum window_part area)
29362 struct window *w = XWINDOW (window);
29363 struct frame *f = XFRAME (w->frame);
29364 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
29365 #ifdef HAVE_WINDOW_SYSTEM
29366 Display_Info *dpyinfo;
29367 #endif
29368 Cursor cursor = No_Cursor;
29369 Lisp_Object pointer = Qnil;
29370 int dx, dy, width, height;
29371 ptrdiff_t charpos;
29372 Lisp_Object string, object = Qnil;
29373 Lisp_Object pos IF_LINT (= Qnil), help;
29375 Lisp_Object mouse_face;
29376 int original_x_pixel = x;
29377 struct glyph * glyph = NULL, * row_start_glyph = NULL;
29378 struct glyph_row *row IF_LINT (= 0);
29380 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
29382 int x0;
29383 struct glyph *end;
29385 /* Kludge alert: mode_line_string takes X/Y in pixels, but
29386 returns them in row/column units! */
29387 string = mode_line_string (w, area, &x, &y, &charpos,
29388 &object, &dx, &dy, &width, &height);
29390 row = (area == ON_MODE_LINE
29391 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
29392 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
29394 /* Find the glyph under the mouse pointer. */
29395 if (row->mode_line_p && row->enabled_p)
29397 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
29398 end = glyph + row->used[TEXT_AREA];
29400 for (x0 = original_x_pixel;
29401 glyph < end && x0 >= glyph->pixel_width;
29402 ++glyph)
29403 x0 -= glyph->pixel_width;
29405 if (glyph >= end)
29406 glyph = NULL;
29409 else
29411 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
29412 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
29413 returns them in row/column units! */
29414 string = marginal_area_string (w, area, &x, &y, &charpos,
29415 &object, &dx, &dy, &width, &height);
29418 help = Qnil;
29420 #ifdef HAVE_WINDOW_SYSTEM
29421 if (IMAGEP (object))
29423 Lisp_Object image_map, hotspot;
29424 if ((image_map = Fplist_get (XCDR (object), QCmap),
29425 !NILP (image_map))
29426 && (hotspot = find_hot_spot (image_map, dx, dy),
29427 CONSP (hotspot))
29428 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
29430 Lisp_Object plist;
29432 /* Could check XCAR (hotspot) to see if we enter/leave this hot-spot.
29433 If so, we could look for mouse-enter, mouse-leave
29434 properties in PLIST (and do something...). */
29435 hotspot = XCDR (hotspot);
29436 if (CONSP (hotspot)
29437 && (plist = XCAR (hotspot), CONSP (plist)))
29439 pointer = Fplist_get (plist, Qpointer);
29440 if (NILP (pointer))
29441 pointer = Qhand;
29442 help = Fplist_get (plist, Qhelp_echo);
29443 if (!NILP (help))
29445 help_echo_string = help;
29446 XSETWINDOW (help_echo_window, w);
29447 help_echo_object = w->contents;
29448 help_echo_pos = charpos;
29452 if (NILP (pointer))
29453 pointer = Fplist_get (XCDR (object), QCpointer);
29455 #endif /* HAVE_WINDOW_SYSTEM */
29457 if (STRINGP (string))
29458 pos = make_number (charpos);
29460 /* Set the help text and mouse pointer. If the mouse is on a part
29461 of the mode line without any text (e.g. past the right edge of
29462 the mode line text), use the default help text and pointer. */
29463 if (STRINGP (string) || area == ON_MODE_LINE)
29465 /* Arrange to display the help by setting the global variables
29466 help_echo_string, help_echo_object, and help_echo_pos. */
29467 if (NILP (help))
29469 if (STRINGP (string))
29470 help = Fget_text_property (pos, Qhelp_echo, string);
29472 if (!NILP (help))
29474 help_echo_string = help;
29475 XSETWINDOW (help_echo_window, w);
29476 help_echo_object = string;
29477 help_echo_pos = charpos;
29479 else if (area == ON_MODE_LINE)
29481 Lisp_Object default_help
29482 = buffer_local_value (Qmode_line_default_help_echo,
29483 w->contents);
29485 if (STRINGP (default_help))
29487 help_echo_string = default_help;
29488 XSETWINDOW (help_echo_window, w);
29489 help_echo_object = Qnil;
29490 help_echo_pos = -1;
29495 #ifdef HAVE_WINDOW_SYSTEM
29496 /* Change the mouse pointer according to what is under it. */
29497 if (FRAME_WINDOW_P (f))
29499 bool draggable = (! WINDOW_BOTTOMMOST_P (w)
29500 || minibuf_level
29501 || NILP (Vresize_mini_windows));
29503 dpyinfo = FRAME_DISPLAY_INFO (f);
29504 if (STRINGP (string))
29506 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
29508 if (NILP (pointer))
29509 pointer = Fget_text_property (pos, Qpointer, string);
29511 /* Change the mouse pointer according to what is under X/Y. */
29512 if (NILP (pointer)
29513 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
29515 Lisp_Object map;
29516 map = Fget_text_property (pos, Qlocal_map, string);
29517 if (!KEYMAPP (map))
29518 map = Fget_text_property (pos, Qkeymap, string);
29519 if (!KEYMAPP (map) && draggable)
29520 cursor = dpyinfo->vertical_scroll_bar_cursor;
29523 else if (draggable)
29524 /* Default mode-line pointer. */
29525 cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
29527 #endif
29530 /* Change the mouse face according to what is under X/Y. */
29531 if (STRINGP (string))
29533 mouse_face = Fget_text_property (pos, Qmouse_face, string);
29534 if (!NILP (Vmouse_highlight) && !NILP (mouse_face)
29535 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
29536 && glyph)
29538 Lisp_Object b, e;
29540 struct glyph * tmp_glyph;
29542 int gpos;
29543 int gseq_length;
29544 int total_pixel_width;
29545 ptrdiff_t begpos, endpos, ignore;
29547 int vpos, hpos;
29549 b = Fprevious_single_property_change (make_number (charpos + 1),
29550 Qmouse_face, string, Qnil);
29551 if (NILP (b))
29552 begpos = 0;
29553 else
29554 begpos = XINT (b);
29556 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
29557 if (NILP (e))
29558 endpos = SCHARS (string);
29559 else
29560 endpos = XINT (e);
29562 /* Calculate the glyph position GPOS of GLYPH in the
29563 displayed string, relative to the beginning of the
29564 highlighted part of the string.
29566 Note: GPOS is different from CHARPOS. CHARPOS is the
29567 position of GLYPH in the internal string object. A mode
29568 line string format has structures which are converted to
29569 a flattened string by the Emacs Lisp interpreter. The
29570 internal string is an element of those structures. The
29571 displayed string is the flattened string. */
29572 tmp_glyph = row_start_glyph;
29573 while (tmp_glyph < glyph
29574 && (!(EQ (tmp_glyph->object, glyph->object)
29575 && begpos <= tmp_glyph->charpos
29576 && tmp_glyph->charpos < endpos)))
29577 tmp_glyph++;
29578 gpos = glyph - tmp_glyph;
29580 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
29581 the highlighted part of the displayed string to which
29582 GLYPH belongs. Note: GSEQ_LENGTH is different from
29583 SCHARS (STRING), because the latter returns the length of
29584 the internal string. */
29585 for (tmp_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
29586 tmp_glyph > glyph
29587 && (!(EQ (tmp_glyph->object, glyph->object)
29588 && begpos <= tmp_glyph->charpos
29589 && tmp_glyph->charpos < endpos));
29590 tmp_glyph--)
29592 gseq_length = gpos + (tmp_glyph - glyph) + 1;
29594 /* Calculate the total pixel width of all the glyphs between
29595 the beginning of the highlighted area and GLYPH. */
29596 total_pixel_width = 0;
29597 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
29598 total_pixel_width += tmp_glyph->pixel_width;
29600 /* Pre calculation of re-rendering position. Note: X is in
29601 column units here, after the call to mode_line_string or
29602 marginal_area_string. */
29603 hpos = x - gpos;
29604 vpos = (area == ON_MODE_LINE
29605 ? (w->current_matrix)->nrows - 1
29606 : 0);
29608 /* If GLYPH's position is included in the region that is
29609 already drawn in mouse face, we have nothing to do. */
29610 if ( EQ (window, hlinfo->mouse_face_window)
29611 && (!row->reversed_p
29612 ? (hlinfo->mouse_face_beg_col <= hpos
29613 && hpos < hlinfo->mouse_face_end_col)
29614 /* In R2L rows we swap BEG and END, see below. */
29615 : (hlinfo->mouse_face_end_col <= hpos
29616 && hpos < hlinfo->mouse_face_beg_col))
29617 && hlinfo->mouse_face_beg_row == vpos )
29618 return;
29620 if (clear_mouse_face (hlinfo))
29621 cursor = No_Cursor;
29623 if (!row->reversed_p)
29625 hlinfo->mouse_face_beg_col = hpos;
29626 hlinfo->mouse_face_beg_x = original_x_pixel
29627 - (total_pixel_width + dx);
29628 hlinfo->mouse_face_end_col = hpos + gseq_length;
29629 hlinfo->mouse_face_end_x = 0;
29631 else
29633 /* In R2L rows, show_mouse_face expects BEG and END
29634 coordinates to be swapped. */
29635 hlinfo->mouse_face_end_col = hpos;
29636 hlinfo->mouse_face_end_x = original_x_pixel
29637 - (total_pixel_width + dx);
29638 hlinfo->mouse_face_beg_col = hpos + gseq_length;
29639 hlinfo->mouse_face_beg_x = 0;
29642 hlinfo->mouse_face_beg_row = vpos;
29643 hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row;
29644 hlinfo->mouse_face_past_end = 0;
29645 hlinfo->mouse_face_window = window;
29647 hlinfo->mouse_face_face_id = face_at_string_position (w, string,
29648 charpos,
29649 0, &ignore,
29650 glyph->face_id,
29652 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
29654 if (NILP (pointer))
29655 pointer = Qhand;
29657 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
29658 clear_mouse_face (hlinfo);
29660 #ifdef HAVE_WINDOW_SYSTEM
29661 if (FRAME_WINDOW_P (f))
29662 define_frame_cursor1 (f, cursor, pointer);
29663 #endif
29667 /* EXPORT:
29668 Take proper action when the mouse has moved to position X, Y on
29669 frame F with regards to highlighting portions of display that have
29670 mouse-face properties. Also de-highlight portions of display where
29671 the mouse was before, set the mouse pointer shape as appropriate
29672 for the mouse coordinates, and activate help echo (tooltips).
29673 X and Y can be negative or out of range. */
29675 void
29676 note_mouse_highlight (struct frame *f, int x, int y)
29678 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
29679 enum window_part part = ON_NOTHING;
29680 Lisp_Object window;
29681 struct window *w;
29682 Cursor cursor = No_Cursor;
29683 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
29684 struct buffer *b;
29686 /* When a menu is active, don't highlight because this looks odd. */
29687 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
29688 if (popup_activated ())
29689 return;
29690 #endif
29692 if (!f->glyphs_initialized_p
29693 || f->pointer_invisible)
29694 return;
29696 hlinfo->mouse_face_mouse_x = x;
29697 hlinfo->mouse_face_mouse_y = y;
29698 hlinfo->mouse_face_mouse_frame = f;
29700 if (hlinfo->mouse_face_defer)
29701 return;
29703 /* Which window is that in? */
29704 window = window_from_coordinates (f, x, y, &part, 1);
29706 /* If displaying active text in another window, clear that. */
29707 if (! EQ (window, hlinfo->mouse_face_window)
29708 /* Also clear if we move out of text area in same window. */
29709 || (!NILP (hlinfo->mouse_face_window)
29710 && !NILP (window)
29711 && part != ON_TEXT
29712 && part != ON_MODE_LINE
29713 && part != ON_HEADER_LINE))
29714 clear_mouse_face (hlinfo);
29716 /* Not on a window -> return. */
29717 if (!WINDOWP (window))
29718 return;
29720 /* Reset help_echo_string. It will get recomputed below. */
29721 help_echo_string = Qnil;
29723 /* Convert to window-relative pixel coordinates. */
29724 w = XWINDOW (window);
29725 frame_to_window_pixel_xy (w, &x, &y);
29727 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
29728 /* Handle tool-bar window differently since it doesn't display a
29729 buffer. */
29730 if (EQ (window, f->tool_bar_window))
29732 note_tool_bar_highlight (f, x, y);
29733 return;
29735 #endif
29737 /* Mouse is on the mode, header line or margin? */
29738 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
29739 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
29741 note_mode_line_or_margin_highlight (window, x, y, part);
29743 #ifdef HAVE_WINDOW_SYSTEM
29744 if (part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
29746 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
29747 /* Show non-text cursor (Bug#16647). */
29748 goto set_cursor;
29750 else
29751 #endif
29752 return;
29755 #ifdef HAVE_WINDOW_SYSTEM
29756 if (part == ON_VERTICAL_BORDER)
29758 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
29759 help_echo_string = build_string ("drag-mouse-1: resize");
29761 else if (part == ON_RIGHT_DIVIDER)
29763 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
29764 help_echo_string = build_string ("drag-mouse-1: resize");
29766 else if (part == ON_BOTTOM_DIVIDER)
29767 if (! WINDOW_BOTTOMMOST_P (w)
29768 || minibuf_level
29769 || NILP (Vresize_mini_windows))
29771 cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
29772 help_echo_string = build_string ("drag-mouse-1: resize");
29774 else
29775 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
29776 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
29777 || part == ON_VERTICAL_SCROLL_BAR
29778 || part == ON_HORIZONTAL_SCROLL_BAR)
29779 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
29780 else
29781 cursor = FRAME_X_OUTPUT (f)->text_cursor;
29782 #endif
29784 /* Are we in a window whose display is up to date?
29785 And verify the buffer's text has not changed. */
29786 b = XBUFFER (w->contents);
29787 if (part == ON_TEXT && w->window_end_valid && !window_outdated (w))
29789 int hpos, vpos, dx, dy, area = LAST_AREA;
29790 ptrdiff_t pos;
29791 struct glyph *glyph;
29792 Lisp_Object object;
29793 Lisp_Object mouse_face = Qnil, position;
29794 Lisp_Object *overlay_vec = NULL;
29795 ptrdiff_t i, noverlays;
29796 struct buffer *obuf;
29797 ptrdiff_t obegv, ozv;
29798 int same_region;
29800 /* Find the glyph under X/Y. */
29801 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
29803 #ifdef HAVE_WINDOW_SYSTEM
29804 /* Look for :pointer property on image. */
29805 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
29807 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
29808 if (img != NULL && IMAGEP (img->spec))
29810 Lisp_Object image_map, hotspot;
29811 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
29812 !NILP (image_map))
29813 && (hotspot = find_hot_spot (image_map,
29814 glyph->slice.img.x + dx,
29815 glyph->slice.img.y + dy),
29816 CONSP (hotspot))
29817 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
29819 Lisp_Object plist;
29821 /* Could check XCAR (hotspot) to see if we enter/leave
29822 this hot-spot.
29823 If so, we could look for mouse-enter, mouse-leave
29824 properties in PLIST (and do something...). */
29825 hotspot = XCDR (hotspot);
29826 if (CONSP (hotspot)
29827 && (plist = XCAR (hotspot), CONSP (plist)))
29829 pointer = Fplist_get (plist, Qpointer);
29830 if (NILP (pointer))
29831 pointer = Qhand;
29832 help_echo_string = Fplist_get (plist, Qhelp_echo);
29833 if (!NILP (help_echo_string))
29835 help_echo_window = window;
29836 help_echo_object = glyph->object;
29837 help_echo_pos = glyph->charpos;
29841 if (NILP (pointer))
29842 pointer = Fplist_get (XCDR (img->spec), QCpointer);
29845 #endif /* HAVE_WINDOW_SYSTEM */
29847 /* Clear mouse face if X/Y not over text. */
29848 if (glyph == NULL
29849 || area != TEXT_AREA
29850 || !MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->current_matrix, vpos))
29851 /* Glyph's OBJECT is an integer for glyphs inserted by the
29852 display engine for its internal purposes, like truncation
29853 and continuation glyphs and blanks beyond the end of
29854 line's text on text terminals. If we are over such a
29855 glyph, we are not over any text. */
29856 || INTEGERP (glyph->object)
29857 /* R2L rows have a stretch glyph at their front, which
29858 stands for no text, whereas L2R rows have no glyphs at
29859 all beyond the end of text. Treat such stretch glyphs
29860 like we do with NULL glyphs in L2R rows. */
29861 || (MATRIX_ROW (w->current_matrix, vpos)->reversed_p
29862 && glyph == MATRIX_ROW_GLYPH_START (w->current_matrix, vpos)
29863 && glyph->type == STRETCH_GLYPH
29864 && glyph->avoid_cursor_p))
29866 if (clear_mouse_face (hlinfo))
29867 cursor = No_Cursor;
29868 #ifdef HAVE_WINDOW_SYSTEM
29869 if (FRAME_WINDOW_P (f) && NILP (pointer))
29871 if (area != TEXT_AREA)
29872 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
29873 else
29874 pointer = Vvoid_text_area_pointer;
29876 #endif
29877 goto set_cursor;
29880 pos = glyph->charpos;
29881 object = glyph->object;
29882 if (!STRINGP (object) && !BUFFERP (object))
29883 goto set_cursor;
29885 /* If we get an out-of-range value, return now; avoid an error. */
29886 if (BUFFERP (object) && pos > BUF_Z (b))
29887 goto set_cursor;
29889 /* Make the window's buffer temporarily current for
29890 overlays_at and compute_char_face. */
29891 obuf = current_buffer;
29892 current_buffer = b;
29893 obegv = BEGV;
29894 ozv = ZV;
29895 BEGV = BEG;
29896 ZV = Z;
29898 /* Is this char mouse-active or does it have help-echo? */
29899 position = make_number (pos);
29901 USE_SAFE_ALLOCA;
29903 if (BUFFERP (object))
29905 /* Put all the overlays we want in a vector in overlay_vec. */
29906 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
29907 /* Sort overlays into increasing priority order. */
29908 noverlays = sort_overlays (overlay_vec, noverlays, w);
29910 else
29911 noverlays = 0;
29913 if (NILP (Vmouse_highlight))
29915 clear_mouse_face (hlinfo);
29916 goto check_help_echo;
29919 same_region = coords_in_mouse_face_p (w, hpos, vpos);
29921 if (same_region)
29922 cursor = No_Cursor;
29924 /* Check mouse-face highlighting. */
29925 if (! same_region
29926 /* If there exists an overlay with mouse-face overlapping
29927 the one we are currently highlighting, we have to
29928 check if we enter the overlapping overlay, and then
29929 highlight only that. */
29930 || (OVERLAYP (hlinfo->mouse_face_overlay)
29931 && mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
29933 /* Find the highest priority overlay with a mouse-face. */
29934 Lisp_Object overlay = Qnil;
29935 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
29937 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
29938 if (!NILP (mouse_face))
29939 overlay = overlay_vec[i];
29942 /* If we're highlighting the same overlay as before, there's
29943 no need to do that again. */
29944 if (!NILP (overlay) && EQ (overlay, hlinfo->mouse_face_overlay))
29945 goto check_help_echo;
29946 hlinfo->mouse_face_overlay = overlay;
29948 /* Clear the display of the old active region, if any. */
29949 if (clear_mouse_face (hlinfo))
29950 cursor = No_Cursor;
29952 /* If no overlay applies, get a text property. */
29953 if (NILP (overlay))
29954 mouse_face = Fget_text_property (position, Qmouse_face, object);
29956 /* Next, compute the bounds of the mouse highlighting and
29957 display it. */
29958 if (!NILP (mouse_face) && STRINGP (object))
29960 /* The mouse-highlighting comes from a display string
29961 with a mouse-face. */
29962 Lisp_Object s, e;
29963 ptrdiff_t ignore;
29965 s = Fprevious_single_property_change
29966 (make_number (pos + 1), Qmouse_face, object, Qnil);
29967 e = Fnext_single_property_change
29968 (position, Qmouse_face, object, Qnil);
29969 if (NILP (s))
29970 s = make_number (0);
29971 if (NILP (e))
29972 e = make_number (SCHARS (object));
29973 mouse_face_from_string_pos (w, hlinfo, object,
29974 XINT (s), XINT (e));
29975 hlinfo->mouse_face_past_end = 0;
29976 hlinfo->mouse_face_window = window;
29977 hlinfo->mouse_face_face_id
29978 = face_at_string_position (w, object, pos, 0, &ignore,
29979 glyph->face_id, 1);
29980 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
29981 cursor = No_Cursor;
29983 else
29985 /* The mouse-highlighting, if any, comes from an overlay
29986 or text property in the buffer. */
29987 Lisp_Object buffer IF_LINT (= Qnil);
29988 Lisp_Object disp_string IF_LINT (= Qnil);
29990 if (STRINGP (object))
29992 /* If we are on a display string with no mouse-face,
29993 check if the text under it has one. */
29994 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
29995 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
29996 pos = string_buffer_position (object, start);
29997 if (pos > 0)
29999 mouse_face = get_char_property_and_overlay
30000 (make_number (pos), Qmouse_face, w->contents, &overlay);
30001 buffer = w->contents;
30002 disp_string = object;
30005 else
30007 buffer = object;
30008 disp_string = Qnil;
30011 if (!NILP (mouse_face))
30013 Lisp_Object before, after;
30014 Lisp_Object before_string, after_string;
30015 /* To correctly find the limits of mouse highlight
30016 in a bidi-reordered buffer, we must not use the
30017 optimization of limiting the search in
30018 previous-single-property-change and
30019 next-single-property-change, because
30020 rows_from_pos_range needs the real start and end
30021 positions to DTRT in this case. That's because
30022 the first row visible in a window does not
30023 necessarily display the character whose position
30024 is the smallest. */
30025 Lisp_Object lim1
30026 = NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
30027 ? Fmarker_position (w->start)
30028 : Qnil;
30029 Lisp_Object lim2
30030 = NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
30031 ? make_number (BUF_Z (XBUFFER (buffer))
30032 - w->window_end_pos)
30033 : Qnil;
30035 if (NILP (overlay))
30037 /* Handle the text property case. */
30038 before = Fprevious_single_property_change
30039 (make_number (pos + 1), Qmouse_face, buffer, lim1);
30040 after = Fnext_single_property_change
30041 (make_number (pos), Qmouse_face, buffer, lim2);
30042 before_string = after_string = Qnil;
30044 else
30046 /* Handle the overlay case. */
30047 before = Foverlay_start (overlay);
30048 after = Foverlay_end (overlay);
30049 before_string = Foverlay_get (overlay, Qbefore_string);
30050 after_string = Foverlay_get (overlay, Qafter_string);
30052 if (!STRINGP (before_string)) before_string = Qnil;
30053 if (!STRINGP (after_string)) after_string = Qnil;
30056 mouse_face_from_buffer_pos (window, hlinfo, pos,
30057 NILP (before)
30059 : XFASTINT (before),
30060 NILP (after)
30061 ? BUF_Z (XBUFFER (buffer))
30062 : XFASTINT (after),
30063 before_string, after_string,
30064 disp_string);
30065 cursor = No_Cursor;
30070 check_help_echo:
30072 /* Look for a `help-echo' property. */
30073 if (NILP (help_echo_string)) {
30074 Lisp_Object help, overlay;
30076 /* Check overlays first. */
30077 help = overlay = Qnil;
30078 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
30080 overlay = overlay_vec[i];
30081 help = Foverlay_get (overlay, Qhelp_echo);
30084 if (!NILP (help))
30086 help_echo_string = help;
30087 help_echo_window = window;
30088 help_echo_object = overlay;
30089 help_echo_pos = pos;
30091 else
30093 Lisp_Object obj = glyph->object;
30094 ptrdiff_t charpos = glyph->charpos;
30096 /* Try text properties. */
30097 if (STRINGP (obj)
30098 && charpos >= 0
30099 && charpos < SCHARS (obj))
30101 help = Fget_text_property (make_number (charpos),
30102 Qhelp_echo, obj);
30103 if (NILP (help))
30105 /* If the string itself doesn't specify a help-echo,
30106 see if the buffer text ``under'' it does. */
30107 struct glyph_row *r
30108 = MATRIX_ROW (w->current_matrix, vpos);
30109 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
30110 ptrdiff_t p = string_buffer_position (obj, start);
30111 if (p > 0)
30113 help = Fget_char_property (make_number (p),
30114 Qhelp_echo, w->contents);
30115 if (!NILP (help))
30117 charpos = p;
30118 obj = w->contents;
30123 else if (BUFFERP (obj)
30124 && charpos >= BEGV
30125 && charpos < ZV)
30126 help = Fget_text_property (make_number (charpos), Qhelp_echo,
30127 obj);
30129 if (!NILP (help))
30131 help_echo_string = help;
30132 help_echo_window = window;
30133 help_echo_object = obj;
30134 help_echo_pos = charpos;
30139 #ifdef HAVE_WINDOW_SYSTEM
30140 /* Look for a `pointer' property. */
30141 if (FRAME_WINDOW_P (f) && NILP (pointer))
30143 /* Check overlays first. */
30144 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
30145 pointer = Foverlay_get (overlay_vec[i], Qpointer);
30147 if (NILP (pointer))
30149 Lisp_Object obj = glyph->object;
30150 ptrdiff_t charpos = glyph->charpos;
30152 /* Try text properties. */
30153 if (STRINGP (obj)
30154 && charpos >= 0
30155 && charpos < SCHARS (obj))
30157 pointer = Fget_text_property (make_number (charpos),
30158 Qpointer, obj);
30159 if (NILP (pointer))
30161 /* If the string itself doesn't specify a pointer,
30162 see if the buffer text ``under'' it does. */
30163 struct glyph_row *r
30164 = MATRIX_ROW (w->current_matrix, vpos);
30165 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
30166 ptrdiff_t p = string_buffer_position (obj, start);
30167 if (p > 0)
30168 pointer = Fget_char_property (make_number (p),
30169 Qpointer, w->contents);
30172 else if (BUFFERP (obj)
30173 && charpos >= BEGV
30174 && charpos < ZV)
30175 pointer = Fget_text_property (make_number (charpos),
30176 Qpointer, obj);
30179 #endif /* HAVE_WINDOW_SYSTEM */
30181 BEGV = obegv;
30182 ZV = ozv;
30183 current_buffer = obuf;
30184 SAFE_FREE ();
30187 set_cursor:
30189 #ifdef HAVE_WINDOW_SYSTEM
30190 if (FRAME_WINDOW_P (f))
30191 define_frame_cursor1 (f, cursor, pointer);
30192 #else
30193 /* This is here to prevent a compiler error, about "label at end of
30194 compound statement". */
30195 return;
30196 #endif
30200 /* EXPORT for RIF:
30201 Clear any mouse-face on window W. This function is part of the
30202 redisplay interface, and is called from try_window_id and similar
30203 functions to ensure the mouse-highlight is off. */
30205 void
30206 x_clear_window_mouse_face (struct window *w)
30208 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
30209 Lisp_Object window;
30211 block_input ();
30212 XSETWINDOW (window, w);
30213 if (EQ (window, hlinfo->mouse_face_window))
30214 clear_mouse_face (hlinfo);
30215 unblock_input ();
30219 /* EXPORT:
30220 Just discard the mouse face information for frame F, if any.
30221 This is used when the size of F is changed. */
30223 void
30224 cancel_mouse_face (struct frame *f)
30226 Lisp_Object window;
30227 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
30229 window = hlinfo->mouse_face_window;
30230 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
30231 reset_mouse_highlight (hlinfo);
30236 /***********************************************************************
30237 Exposure Events
30238 ***********************************************************************/
30240 #ifdef HAVE_WINDOW_SYSTEM
30242 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
30243 which intersects rectangle R. R is in window-relative coordinates. */
30245 static void
30246 expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
30247 enum glyph_row_area area)
30249 struct glyph *first = row->glyphs[area];
30250 struct glyph *end = row->glyphs[area] + row->used[area];
30251 struct glyph *last;
30252 int first_x, start_x, x;
30254 if (area == TEXT_AREA && row->fill_line_p)
30255 /* If row extends face to end of line write the whole line. */
30256 draw_glyphs (w, 0, row, area,
30257 0, row->used[area],
30258 DRAW_NORMAL_TEXT, 0);
30259 else
30261 /* Set START_X to the window-relative start position for drawing glyphs of
30262 AREA. The first glyph of the text area can be partially visible.
30263 The first glyphs of other areas cannot. */
30264 start_x = window_box_left_offset (w, area);
30265 x = start_x;
30266 if (area == TEXT_AREA)
30267 x += row->x;
30269 /* Find the first glyph that must be redrawn. */
30270 while (first < end
30271 && x + first->pixel_width < r->x)
30273 x += first->pixel_width;
30274 ++first;
30277 /* Find the last one. */
30278 last = first;
30279 first_x = x;
30280 while (last < end
30281 && x < r->x + r->width)
30283 x += last->pixel_width;
30284 ++last;
30287 /* Repaint. */
30288 if (last > first)
30289 draw_glyphs (w, first_x - start_x, row, area,
30290 first - row->glyphs[area], last - row->glyphs[area],
30291 DRAW_NORMAL_TEXT, 0);
30296 /* Redraw the parts of the glyph row ROW on window W intersecting
30297 rectangle R. R is in window-relative coordinates. Value is
30298 non-zero if mouse-face was overwritten. */
30300 static int
30301 expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
30303 eassert (row->enabled_p);
30305 if (row->mode_line_p || w->pseudo_window_p)
30306 draw_glyphs (w, 0, row, TEXT_AREA,
30307 0, row->used[TEXT_AREA],
30308 DRAW_NORMAL_TEXT, 0);
30309 else
30311 if (row->used[LEFT_MARGIN_AREA])
30312 expose_area (w, row, r, LEFT_MARGIN_AREA);
30313 if (row->used[TEXT_AREA])
30314 expose_area (w, row, r, TEXT_AREA);
30315 if (row->used[RIGHT_MARGIN_AREA])
30316 expose_area (w, row, r, RIGHT_MARGIN_AREA);
30317 draw_row_fringe_bitmaps (w, row);
30320 return row->mouse_face_p;
30324 /* Redraw those parts of glyphs rows during expose event handling that
30325 overlap other rows. Redrawing of an exposed line writes over parts
30326 of lines overlapping that exposed line; this function fixes that.
30328 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
30329 row in W's current matrix that is exposed and overlaps other rows.
30330 LAST_OVERLAPPING_ROW is the last such row. */
30332 static void
30333 expose_overlaps (struct window *w,
30334 struct glyph_row *first_overlapping_row,
30335 struct glyph_row *last_overlapping_row,
30336 XRectangle *r)
30338 struct glyph_row *row;
30340 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
30341 if (row->overlapping_p)
30343 eassert (row->enabled_p && !row->mode_line_p);
30345 row->clip = r;
30346 if (row->used[LEFT_MARGIN_AREA])
30347 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
30349 if (row->used[TEXT_AREA])
30350 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
30352 if (row->used[RIGHT_MARGIN_AREA])
30353 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
30354 row->clip = NULL;
30359 /* Return non-zero if W's cursor intersects rectangle R. */
30361 static int
30362 phys_cursor_in_rect_p (struct window *w, XRectangle *r)
30364 XRectangle cr, result;
30365 struct glyph *cursor_glyph;
30366 struct glyph_row *row;
30368 if (w->phys_cursor.vpos >= 0
30369 && w->phys_cursor.vpos < w->current_matrix->nrows
30370 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
30371 row->enabled_p)
30372 && row->cursor_in_fringe_p)
30374 /* Cursor is in the fringe. */
30375 cr.x = window_box_right_offset (w,
30376 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
30377 ? RIGHT_MARGIN_AREA
30378 : TEXT_AREA));
30379 cr.y = row->y;
30380 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
30381 cr.height = row->height;
30382 return x_intersect_rectangles (&cr, r, &result);
30385 cursor_glyph = get_phys_cursor_glyph (w);
30386 if (cursor_glyph)
30388 /* r is relative to W's box, but w->phys_cursor.x is relative
30389 to left edge of W's TEXT area. Adjust it. */
30390 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
30391 cr.y = w->phys_cursor.y;
30392 cr.width = cursor_glyph->pixel_width;
30393 cr.height = w->phys_cursor_height;
30394 /* ++KFS: W32 version used W32-specific IntersectRect here, but
30395 I assume the effect is the same -- and this is portable. */
30396 return x_intersect_rectangles (&cr, r, &result);
30398 /* If we don't understand the format, pretend we're not in the hot-spot. */
30399 return 0;
30403 /* EXPORT:
30404 Draw a vertical window border to the right of window W if W doesn't
30405 have vertical scroll bars. */
30407 void
30408 x_draw_vertical_border (struct window *w)
30410 struct frame *f = XFRAME (WINDOW_FRAME (w));
30412 /* We could do better, if we knew what type of scroll-bar the adjacent
30413 windows (on either side) have... But we don't :-(
30414 However, I think this works ok. ++KFS 2003-04-25 */
30416 /* Redraw borders between horizontally adjacent windows. Don't
30417 do it for frames with vertical scroll bars because either the
30418 right scroll bar of a window, or the left scroll bar of its
30419 neighbor will suffice as a border. */
30420 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f) || FRAME_RIGHT_DIVIDER_WIDTH (f))
30421 return;
30423 /* Note: It is necessary to redraw both the left and the right
30424 borders, for when only this single window W is being
30425 redisplayed. */
30426 if (!WINDOW_RIGHTMOST_P (w)
30427 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
30429 int x0, x1, y0, y1;
30431 window_box_edges (w, &x0, &y0, &x1, &y1);
30432 y1 -= 1;
30434 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
30435 x1 -= 1;
30437 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
30440 if (!WINDOW_LEFTMOST_P (w)
30441 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
30443 int x0, x1, y0, y1;
30445 window_box_edges (w, &x0, &y0, &x1, &y1);
30446 y1 -= 1;
30448 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
30449 x0 -= 1;
30451 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
30456 /* Draw window dividers for window W. */
30458 void
30459 x_draw_right_divider (struct window *w)
30461 struct frame *f = WINDOW_XFRAME (w);
30463 if (w->mini || w->pseudo_window_p)
30464 return;
30465 else if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
30467 int x0 = WINDOW_RIGHT_EDGE_X (w) - WINDOW_RIGHT_DIVIDER_WIDTH (w);
30468 int x1 = WINDOW_RIGHT_EDGE_X (w);
30469 int y0 = WINDOW_TOP_EDGE_Y (w);
30470 /* The bottom divider prevails. */
30471 int y1 = WINDOW_BOTTOM_EDGE_Y (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
30473 FRAME_RIF (f)->draw_window_divider (w, x0, x1, y0, y1);
30477 static void
30478 x_draw_bottom_divider (struct window *w)
30480 struct frame *f = XFRAME (WINDOW_FRAME (w));
30482 if (w->mini || w->pseudo_window_p)
30483 return;
30484 else if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
30486 int x0 = WINDOW_LEFT_EDGE_X (w);
30487 int x1 = WINDOW_RIGHT_EDGE_X (w);
30488 int y0 = WINDOW_BOTTOM_EDGE_Y (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
30489 int y1 = WINDOW_BOTTOM_EDGE_Y (w);
30491 FRAME_RIF (f)->draw_window_divider (w, x0, x1, y0, y1);
30495 /* Redraw the part of window W intersection rectangle FR. Pixel
30496 coordinates in FR are frame-relative. Call this function with
30497 input blocked. Value is non-zero if the exposure overwrites
30498 mouse-face. */
30500 static int
30501 expose_window (struct window *w, XRectangle *fr)
30503 struct frame *f = XFRAME (w->frame);
30504 XRectangle wr, r;
30505 int mouse_face_overwritten_p = 0;
30507 /* If window is not yet fully initialized, do nothing. This can
30508 happen when toolkit scroll bars are used and a window is split.
30509 Reconfiguring the scroll bar will generate an expose for a newly
30510 created window. */
30511 if (w->current_matrix == NULL)
30512 return 0;
30514 /* When we're currently updating the window, display and current
30515 matrix usually don't agree. Arrange for a thorough display
30516 later. */
30517 if (w->must_be_updated_p)
30519 SET_FRAME_GARBAGED (f);
30520 return 0;
30523 /* Frame-relative pixel rectangle of W. */
30524 wr.x = WINDOW_LEFT_EDGE_X (w);
30525 wr.y = WINDOW_TOP_EDGE_Y (w);
30526 wr.width = WINDOW_PIXEL_WIDTH (w);
30527 wr.height = WINDOW_PIXEL_HEIGHT (w);
30529 if (x_intersect_rectangles (fr, &wr, &r))
30531 int yb = window_text_bottom_y (w);
30532 struct glyph_row *row;
30533 int cursor_cleared_p, phys_cursor_on_p;
30534 struct glyph_row *first_overlapping_row, *last_overlapping_row;
30536 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
30537 r.x, r.y, r.width, r.height));
30539 /* Convert to window coordinates. */
30540 r.x -= WINDOW_LEFT_EDGE_X (w);
30541 r.y -= WINDOW_TOP_EDGE_Y (w);
30543 /* Turn off the cursor. */
30544 if (!w->pseudo_window_p
30545 && phys_cursor_in_rect_p (w, &r))
30547 x_clear_cursor (w);
30548 cursor_cleared_p = 1;
30550 else
30551 cursor_cleared_p = 0;
30553 /* If the row containing the cursor extends face to end of line,
30554 then expose_area might overwrite the cursor outside the
30555 rectangle and thus notice_overwritten_cursor might clear
30556 w->phys_cursor_on_p. We remember the original value and
30557 check later if it is changed. */
30558 phys_cursor_on_p = w->phys_cursor_on_p;
30560 /* Update lines intersecting rectangle R. */
30561 first_overlapping_row = last_overlapping_row = NULL;
30562 for (row = w->current_matrix->rows;
30563 row->enabled_p;
30564 ++row)
30566 int y0 = row->y;
30567 int y1 = MATRIX_ROW_BOTTOM_Y (row);
30569 if ((y0 >= r.y && y0 < r.y + r.height)
30570 || (y1 > r.y && y1 < r.y + r.height)
30571 || (r.y >= y0 && r.y < y1)
30572 || (r.y + r.height > y0 && r.y + r.height < y1))
30574 /* A header line may be overlapping, but there is no need
30575 to fix overlapping areas for them. KFS 2005-02-12 */
30576 if (row->overlapping_p && !row->mode_line_p)
30578 if (first_overlapping_row == NULL)
30579 first_overlapping_row = row;
30580 last_overlapping_row = row;
30583 row->clip = fr;
30584 if (expose_line (w, row, &r))
30585 mouse_face_overwritten_p = 1;
30586 row->clip = NULL;
30588 else if (row->overlapping_p)
30590 /* We must redraw a row overlapping the exposed area. */
30591 if (y0 < r.y
30592 ? y0 + row->phys_height > r.y
30593 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
30595 if (first_overlapping_row == NULL)
30596 first_overlapping_row = row;
30597 last_overlapping_row = row;
30601 if (y1 >= yb)
30602 break;
30605 /* Display the mode line if there is one. */
30606 if (WINDOW_WANTS_MODELINE_P (w)
30607 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
30608 row->enabled_p)
30609 && row->y < r.y + r.height)
30611 if (expose_line (w, row, &r))
30612 mouse_face_overwritten_p = 1;
30615 if (!w->pseudo_window_p)
30617 /* Fix the display of overlapping rows. */
30618 if (first_overlapping_row)
30619 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
30620 fr);
30622 /* Draw border between windows. */
30623 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
30624 x_draw_right_divider (w);
30625 else
30626 x_draw_vertical_border (w);
30628 if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
30629 x_draw_bottom_divider (w);
30631 /* Turn the cursor on again. */
30632 if (cursor_cleared_p
30633 || (phys_cursor_on_p && !w->phys_cursor_on_p))
30634 update_window_cursor (w, 1);
30638 return mouse_face_overwritten_p;
30643 /* Redraw (parts) of all windows in the window tree rooted at W that
30644 intersect R. R contains frame pixel coordinates. Value is
30645 non-zero if the exposure overwrites mouse-face. */
30647 static int
30648 expose_window_tree (struct window *w, XRectangle *r)
30650 struct frame *f = XFRAME (w->frame);
30651 int mouse_face_overwritten_p = 0;
30653 while (w && !FRAME_GARBAGED_P (f))
30655 if (WINDOWP (w->contents))
30656 mouse_face_overwritten_p
30657 |= expose_window_tree (XWINDOW (w->contents), r);
30658 else
30659 mouse_face_overwritten_p |= expose_window (w, r);
30661 w = NILP (w->next) ? NULL : XWINDOW (w->next);
30664 return mouse_face_overwritten_p;
30668 /* EXPORT:
30669 Redisplay an exposed area of frame F. X and Y are the upper-left
30670 corner of the exposed rectangle. W and H are width and height of
30671 the exposed area. All are pixel values. W or H zero means redraw
30672 the entire frame. */
30674 void
30675 expose_frame (struct frame *f, int x, int y, int w, int h)
30677 XRectangle r;
30678 int mouse_face_overwritten_p = 0;
30680 TRACE ((stderr, "expose_frame "));
30682 /* No need to redraw if frame will be redrawn soon. */
30683 if (FRAME_GARBAGED_P (f))
30685 TRACE ((stderr, " garbaged\n"));
30686 return;
30689 /* If basic faces haven't been realized yet, there is no point in
30690 trying to redraw anything. This can happen when we get an expose
30691 event while Emacs is starting, e.g. by moving another window. */
30692 if (FRAME_FACE_CACHE (f) == NULL
30693 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
30695 TRACE ((stderr, " no faces\n"));
30696 return;
30699 if (w == 0 || h == 0)
30701 r.x = r.y = 0;
30702 r.width = FRAME_TEXT_WIDTH (f);
30703 r.height = FRAME_TEXT_HEIGHT (f);
30705 else
30707 r.x = x;
30708 r.y = y;
30709 r.width = w;
30710 r.height = h;
30713 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
30714 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
30716 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
30717 if (WINDOWP (f->tool_bar_window))
30718 mouse_face_overwritten_p
30719 |= expose_window (XWINDOW (f->tool_bar_window), &r);
30720 #endif
30722 #ifdef HAVE_X_WINDOWS
30723 #ifndef MSDOS
30724 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
30725 if (WINDOWP (f->menu_bar_window))
30726 mouse_face_overwritten_p
30727 |= expose_window (XWINDOW (f->menu_bar_window), &r);
30728 #endif /* not USE_X_TOOLKIT and not USE_GTK */
30729 #endif
30730 #endif
30732 /* Some window managers support a focus-follows-mouse style with
30733 delayed raising of frames. Imagine a partially obscured frame,
30734 and moving the mouse into partially obscured mouse-face on that
30735 frame. The visible part of the mouse-face will be highlighted,
30736 then the WM raises the obscured frame. With at least one WM, KDE
30737 2.1, Emacs is not getting any event for the raising of the frame
30738 (even tried with SubstructureRedirectMask), only Expose events.
30739 These expose events will draw text normally, i.e. not
30740 highlighted. Which means we must redo the highlight here.
30741 Subsume it under ``we love X''. --gerd 2001-08-15 */
30742 /* Included in Windows version because Windows most likely does not
30743 do the right thing if any third party tool offers
30744 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
30745 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
30747 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
30748 if (f == hlinfo->mouse_face_mouse_frame)
30750 int mouse_x = hlinfo->mouse_face_mouse_x;
30751 int mouse_y = hlinfo->mouse_face_mouse_y;
30752 clear_mouse_face (hlinfo);
30753 note_mouse_highlight (f, mouse_x, mouse_y);
30759 /* EXPORT:
30760 Determine the intersection of two rectangles R1 and R2. Return
30761 the intersection in *RESULT. Value is non-zero if RESULT is not
30762 empty. */
30765 x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
30767 XRectangle *left, *right;
30768 XRectangle *upper, *lower;
30769 int intersection_p = 0;
30771 /* Rearrange so that R1 is the left-most rectangle. */
30772 if (r1->x < r2->x)
30773 left = r1, right = r2;
30774 else
30775 left = r2, right = r1;
30777 /* X0 of the intersection is right.x0, if this is inside R1,
30778 otherwise there is no intersection. */
30779 if (right->x <= left->x + left->width)
30781 result->x = right->x;
30783 /* The right end of the intersection is the minimum of
30784 the right ends of left and right. */
30785 result->width = (min (left->x + left->width, right->x + right->width)
30786 - result->x);
30788 /* Same game for Y. */
30789 if (r1->y < r2->y)
30790 upper = r1, lower = r2;
30791 else
30792 upper = r2, lower = r1;
30794 /* The upper end of the intersection is lower.y0, if this is inside
30795 of upper. Otherwise, there is no intersection. */
30796 if (lower->y <= upper->y + upper->height)
30798 result->y = lower->y;
30800 /* The lower end of the intersection is the minimum of the lower
30801 ends of upper and lower. */
30802 result->height = (min (lower->y + lower->height,
30803 upper->y + upper->height)
30804 - result->y);
30805 intersection_p = 1;
30809 return intersection_p;
30812 #endif /* HAVE_WINDOW_SYSTEM */
30815 /***********************************************************************
30816 Initialization
30817 ***********************************************************************/
30819 void
30820 syms_of_xdisp (void)
30822 Vwith_echo_area_save_vector = Qnil;
30823 staticpro (&Vwith_echo_area_save_vector);
30825 Vmessage_stack = Qnil;
30826 staticpro (&Vmessage_stack);
30828 DEFSYM (Qinhibit_redisplay, "inhibit-redisplay");
30829 DEFSYM (Qredisplay_internal, "redisplay_internal (C function)");
30831 message_dolog_marker1 = Fmake_marker ();
30832 staticpro (&message_dolog_marker1);
30833 message_dolog_marker2 = Fmake_marker ();
30834 staticpro (&message_dolog_marker2);
30835 message_dolog_marker3 = Fmake_marker ();
30836 staticpro (&message_dolog_marker3);
30838 #ifdef GLYPH_DEBUG
30839 defsubr (&Sdump_frame_glyph_matrix);
30840 defsubr (&Sdump_glyph_matrix);
30841 defsubr (&Sdump_glyph_row);
30842 defsubr (&Sdump_tool_bar_row);
30843 defsubr (&Strace_redisplay);
30844 defsubr (&Strace_to_stderr);
30845 #endif
30846 #ifdef HAVE_WINDOW_SYSTEM
30847 defsubr (&Stool_bar_height);
30848 defsubr (&Slookup_image_map);
30849 #endif
30850 defsubr (&Sline_pixel_height);
30851 defsubr (&Sformat_mode_line);
30852 defsubr (&Sinvisible_p);
30853 defsubr (&Scurrent_bidi_paragraph_direction);
30854 defsubr (&Swindow_text_pixel_size);
30855 defsubr (&Smove_point_visually);
30856 defsubr (&Sbidi_find_overridden_directionality);
30858 DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook");
30859 DEFSYM (Qoverriding_terminal_local_map, "overriding-terminal-local-map");
30860 DEFSYM (Qoverriding_local_map, "overriding-local-map");
30861 DEFSYM (Qwindow_scroll_functions, "window-scroll-functions");
30862 DEFSYM (Qwindow_text_change_functions, "window-text-change-functions");
30863 DEFSYM (Qredisplay_end_trigger_functions, "redisplay-end-trigger-functions");
30864 DEFSYM (Qinhibit_point_motion_hooks, "inhibit-point-motion-hooks");
30865 DEFSYM (Qeval, "eval");
30866 DEFSYM (QCdata, ":data");
30867 DEFSYM (Qdisplay, "display");
30868 DEFSYM (Qspace_width, "space-width");
30869 DEFSYM (Qraise, "raise");
30870 DEFSYM (Qslice, "slice");
30871 DEFSYM (Qspace, "space");
30872 DEFSYM (Qmargin, "margin");
30873 DEFSYM (Qpointer, "pointer");
30874 DEFSYM (Qleft_margin, "left-margin");
30875 DEFSYM (Qright_margin, "right-margin");
30876 DEFSYM (Qcenter, "center");
30877 DEFSYM (Qline_height, "line-height");
30878 DEFSYM (QCalign_to, ":align-to");
30879 DEFSYM (QCrelative_width, ":relative-width");
30880 DEFSYM (QCrelative_height, ":relative-height");
30881 DEFSYM (QCeval, ":eval");
30882 DEFSYM (QCpropertize, ":propertize");
30883 DEFSYM (QCfile, ":file");
30884 DEFSYM (Qfontified, "fontified");
30885 DEFSYM (Qfontification_functions, "fontification-functions");
30886 DEFSYM (Qtrailing_whitespace, "trailing-whitespace");
30887 DEFSYM (Qescape_glyph, "escape-glyph");
30888 DEFSYM (Qnobreak_space, "nobreak-space");
30889 DEFSYM (Qimage, "image");
30890 DEFSYM (Qtext, "text");
30891 DEFSYM (Qboth, "both");
30892 DEFSYM (Qboth_horiz, "both-horiz");
30893 DEFSYM (Qtext_image_horiz, "text-image-horiz");
30894 DEFSYM (QCmap, ":map");
30895 DEFSYM (QCpointer, ":pointer");
30896 DEFSYM (Qrect, "rect");
30897 DEFSYM (Qcircle, "circle");
30898 DEFSYM (Qpoly, "poly");
30899 DEFSYM (Qmessage_truncate_lines, "message-truncate-lines");
30900 DEFSYM (Qgrow_only, "grow-only");
30901 DEFSYM (Qinhibit_menubar_update, "inhibit-menubar-update");
30902 DEFSYM (Qinhibit_eval_during_redisplay, "inhibit-eval-during-redisplay");
30903 DEFSYM (Qposition, "position");
30904 DEFSYM (Qbuffer_position, "buffer-position");
30905 DEFSYM (Qobject, "object");
30906 DEFSYM (Qbar, "bar");
30907 DEFSYM (Qhbar, "hbar");
30908 DEFSYM (Qbox, "box");
30909 DEFSYM (Qhollow, "hollow");
30910 DEFSYM (Qhand, "hand");
30911 DEFSYM (Qarrow, "arrow");
30912 DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces");
30914 list_of_error = list1 (list2 (intern_c_string ("error"),
30915 intern_c_string ("void-variable")));
30916 staticpro (&list_of_error);
30918 DEFSYM (Qlast_arrow_position, "last-arrow-position");
30919 DEFSYM (Qlast_arrow_string, "last-arrow-string");
30920 DEFSYM (Qoverlay_arrow_string, "overlay-arrow-string");
30921 DEFSYM (Qoverlay_arrow_bitmap, "overlay-arrow-bitmap");
30923 echo_buffer[0] = echo_buffer[1] = Qnil;
30924 staticpro (&echo_buffer[0]);
30925 staticpro (&echo_buffer[1]);
30927 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
30928 staticpro (&echo_area_buffer[0]);
30929 staticpro (&echo_area_buffer[1]);
30931 Vmessages_buffer_name = build_pure_c_string ("*Messages*");
30932 staticpro (&Vmessages_buffer_name);
30934 mode_line_proptrans_alist = Qnil;
30935 staticpro (&mode_line_proptrans_alist);
30936 mode_line_string_list = Qnil;
30937 staticpro (&mode_line_string_list);
30938 mode_line_string_face = Qnil;
30939 staticpro (&mode_line_string_face);
30940 mode_line_string_face_prop = Qnil;
30941 staticpro (&mode_line_string_face_prop);
30942 Vmode_line_unwind_vector = Qnil;
30943 staticpro (&Vmode_line_unwind_vector);
30945 DEFSYM (Qmode_line_default_help_echo, "mode-line-default-help-echo");
30947 help_echo_string = Qnil;
30948 staticpro (&help_echo_string);
30949 help_echo_object = Qnil;
30950 staticpro (&help_echo_object);
30951 help_echo_window = Qnil;
30952 staticpro (&help_echo_window);
30953 previous_help_echo_string = Qnil;
30954 staticpro (&previous_help_echo_string);
30955 help_echo_pos = -1;
30957 DEFSYM (Qright_to_left, "right-to-left");
30958 DEFSYM (Qleft_to_right, "left-to-right");
30959 defsubr (&Sbidi_resolved_levels);
30961 #ifdef HAVE_WINDOW_SYSTEM
30962 DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p,
30963 doc: /* Non-nil means draw block cursor as wide as the glyph under it.
30964 For example, if a block cursor is over a tab, it will be drawn as
30965 wide as that tab on the display. */);
30966 x_stretch_cursor_p = 0;
30967 #endif
30969 DEFVAR_LISP ("show-trailing-whitespace", Vshow_trailing_whitespace,
30970 doc: /* Non-nil means highlight trailing whitespace.
30971 The face used for trailing whitespace is `trailing-whitespace'. */);
30972 Vshow_trailing_whitespace = Qnil;
30974 DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display,
30975 doc: /* Control highlighting of non-ASCII space and hyphen chars.
30976 If the value is t, Emacs highlights non-ASCII chars which have the
30977 same appearance as an ASCII space or hyphen, using the `nobreak-space'
30978 or `escape-glyph' face respectively.
30980 U+00A0 (no-break space), U+00AD (soft hyphen), U+2010 (hyphen), and
30981 U+2011 (non-breaking hyphen) are affected.
30983 Any other non-nil value means to display these characters as a escape
30984 glyph followed by an ordinary space or hyphen.
30986 A value of nil means no special handling of these characters. */);
30987 Vnobreak_char_display = Qt;
30989 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer,
30990 doc: /* The pointer shape to show in void text areas.
30991 A value of nil means to show the text pointer. Other options are
30992 `arrow', `text', `hand', `vdrag', `hdrag', `nhdrag', `modeline', and
30993 `hourglass'. */);
30994 Vvoid_text_area_pointer = Qarrow;
30996 DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay,
30997 doc: /* Non-nil means don't actually do any redisplay.
30998 This is used for internal purposes. */);
30999 Vinhibit_redisplay = Qnil;
31001 DEFVAR_LISP ("global-mode-string", Vglobal_mode_string,
31002 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
31003 Vglobal_mode_string = Qnil;
31005 DEFVAR_LISP ("overlay-arrow-position", Voverlay_arrow_position,
31006 doc: /* Marker for where to display an arrow on top of the buffer text.
31007 This must be the beginning of a line in order to work.
31008 See also `overlay-arrow-string'. */);
31009 Voverlay_arrow_position = Qnil;
31011 DEFVAR_LISP ("overlay-arrow-string", Voverlay_arrow_string,
31012 doc: /* String to display as an arrow in non-window frames.
31013 See also `overlay-arrow-position'. */);
31014 Voverlay_arrow_string = build_pure_c_string ("=>");
31016 DEFVAR_LISP ("overlay-arrow-variable-list", Voverlay_arrow_variable_list,
31017 doc: /* List of variables (symbols) which hold markers for overlay arrows.
31018 The symbols on this list are examined during redisplay to determine
31019 where to display overlay arrows. */);
31020 Voverlay_arrow_variable_list
31021 = list1 (intern_c_string ("overlay-arrow-position"));
31023 DEFVAR_INT ("scroll-step", emacs_scroll_step,
31024 doc: /* The number of lines to try scrolling a window by when point moves out.
31025 If that fails to bring point back on frame, point is centered instead.
31026 If this is zero, point is always centered after it moves off frame.
31027 If you want scrolling to always be a line at a time, you should set
31028 `scroll-conservatively' to a large value rather than set this to 1. */);
31030 DEFVAR_INT ("scroll-conservatively", scroll_conservatively,
31031 doc: /* Scroll up to this many lines, to bring point back on screen.
31032 If point moves off-screen, redisplay will scroll by up to
31033 `scroll-conservatively' lines in order to bring point just barely
31034 onto the screen again. If that cannot be done, then redisplay
31035 recenters point as usual.
31037 If the value is greater than 100, redisplay will never recenter point,
31038 but will always scroll just enough text to bring point into view, even
31039 if you move far away.
31041 A value of zero means always recenter point if it moves off screen. */);
31042 scroll_conservatively = 0;
31044 DEFVAR_INT ("scroll-margin", scroll_margin,
31045 doc: /* Number of lines of margin at the top and bottom of a window.
31046 Recenter the window whenever point gets within this many lines
31047 of the top or bottom of the window. */);
31048 scroll_margin = 0;
31050 DEFVAR_LISP ("display-pixels-per-inch", Vdisplay_pixels_per_inch,
31051 doc: /* Pixels per inch value for non-window system displays.
31052 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
31053 Vdisplay_pixels_per_inch = make_float (72.0);
31055 #ifdef GLYPH_DEBUG
31056 DEFVAR_INT ("debug-end-pos", debug_end_pos, doc: /* Don't ask. */);
31057 #endif
31059 DEFVAR_LISP ("truncate-partial-width-windows",
31060 Vtruncate_partial_width_windows,
31061 doc: /* Non-nil means truncate lines in windows narrower than the frame.
31062 For an integer value, truncate lines in each window narrower than the
31063 full frame width, provided the window width is less than that integer;
31064 otherwise, respect the value of `truncate-lines'.
31066 For any other non-nil value, truncate lines in all windows that do
31067 not span the full frame width.
31069 A value of nil means to respect the value of `truncate-lines'.
31071 If `word-wrap' is enabled, you might want to reduce this. */);
31072 Vtruncate_partial_width_windows = make_number (50);
31074 DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit,
31075 doc: /* Maximum buffer size for which line number should be displayed.
31076 If the buffer is bigger than this, the line number does not appear
31077 in the mode line. A value of nil means no limit. */);
31078 Vline_number_display_limit = Qnil;
31080 DEFVAR_INT ("line-number-display-limit-width",
31081 line_number_display_limit_width,
31082 doc: /* Maximum line width (in characters) for line number display.
31083 If the average length of the lines near point is bigger than this, then the
31084 line number may be omitted from the mode line. */);
31085 line_number_display_limit_width = 200;
31087 DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows,
31088 doc: /* Non-nil means highlight region even in nonselected windows. */);
31089 highlight_nonselected_windows = 0;
31091 DEFVAR_BOOL ("multiple-frames", multiple_frames,
31092 doc: /* Non-nil if more than one frame is visible on this display.
31093 Minibuffer-only frames don't count, but iconified frames do.
31094 This variable is not guaranteed to be accurate except while processing
31095 `frame-title-format' and `icon-title-format'. */);
31097 DEFVAR_LISP ("frame-title-format", Vframe_title_format,
31098 doc: /* Template for displaying the title bar of visible frames.
31099 \(Assuming the window manager supports this feature.)
31101 This variable has the same structure as `mode-line-format', except that
31102 the %c and %l constructs are ignored. It is used only on frames for
31103 which no explicit name has been set \(see `modify-frame-parameters'). */);
31105 DEFVAR_LISP ("icon-title-format", Vicon_title_format,
31106 doc: /* Template for displaying the title bar of an iconified frame.
31107 \(Assuming the window manager supports this feature.)
31108 This variable has the same structure as `mode-line-format' (which see),
31109 and is used only on frames for which no explicit name has been set
31110 \(see `modify-frame-parameters'). */);
31111 Vicon_title_format
31112 = Vframe_title_format
31113 = listn (CONSTYPE_PURE, 3,
31114 intern_c_string ("multiple-frames"),
31115 build_pure_c_string ("%b"),
31116 listn (CONSTYPE_PURE, 4,
31117 empty_unibyte_string,
31118 intern_c_string ("invocation-name"),
31119 build_pure_c_string ("@"),
31120 intern_c_string ("system-name")));
31122 DEFVAR_LISP ("message-log-max", Vmessage_log_max,
31123 doc: /* Maximum number of lines to keep in the message log buffer.
31124 If nil, disable message logging. If t, log messages but don't truncate
31125 the buffer when it becomes large. */);
31126 Vmessage_log_max = make_number (1000);
31128 DEFVAR_LISP ("window-size-change-functions", Vwindow_size_change_functions,
31129 doc: /* Functions called before redisplay, if window sizes have changed.
31130 The value should be a list of functions that take one argument.
31131 Just before redisplay, for each frame, if any of its windows have changed
31132 size since the last redisplay, or have been split or deleted,
31133 all the functions in the list are called, with the frame as argument. */);
31134 Vwindow_size_change_functions = Qnil;
31136 DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions,
31137 doc: /* List of functions to call before redisplaying a window with scrolling.
31138 Each function is called with two arguments, the window and its new
31139 display-start position.
31140 These functions are called whenever the `window-start' marker is modified,
31141 either to point into another buffer (e.g. via `set-window-buffer') or another
31142 place in the same buffer.
31143 Note that the value of `window-end' is not valid when these functions are
31144 called.
31146 Warning: Do not use this feature to alter the way the window
31147 is scrolled. It is not designed for that, and such use probably won't
31148 work. */);
31149 Vwindow_scroll_functions = Qnil;
31151 DEFVAR_LISP ("window-text-change-functions",
31152 Vwindow_text_change_functions,
31153 doc: /* Functions to call in redisplay when text in the window might change. */);
31154 Vwindow_text_change_functions = Qnil;
31156 DEFVAR_LISP ("redisplay-end-trigger-functions", Vredisplay_end_trigger_functions,
31157 doc: /* Functions called when redisplay of a window reaches the end trigger.
31158 Each function is called with two arguments, the window and the end trigger value.
31159 See `set-window-redisplay-end-trigger'. */);
31160 Vredisplay_end_trigger_functions = Qnil;
31162 DEFVAR_LISP ("mouse-autoselect-window", Vmouse_autoselect_window,
31163 doc: /* Non-nil means autoselect window with mouse pointer.
31164 If nil, do not autoselect windows.
31165 A positive number means delay autoselection by that many seconds: a
31166 window is autoselected only after the mouse has remained in that
31167 window for the duration of the delay.
31168 A negative number has a similar effect, but causes windows to be
31169 autoselected only after the mouse has stopped moving. \(Because of
31170 the way Emacs compares mouse events, you will occasionally wait twice
31171 that time before the window gets selected.\)
31172 Any other value means to autoselect window instantaneously when the
31173 mouse pointer enters it.
31175 Autoselection selects the minibuffer only if it is active, and never
31176 unselects the minibuffer if it is active.
31178 When customizing this variable make sure that the actual value of
31179 `focus-follows-mouse' matches the behavior of your window manager. */);
31180 Vmouse_autoselect_window = Qnil;
31182 DEFVAR_LISP ("auto-resize-tool-bars", Vauto_resize_tool_bars,
31183 doc: /* Non-nil means automatically resize tool-bars.
31184 This dynamically changes the tool-bar's height to the minimum height
31185 that is needed to make all tool-bar items visible.
31186 If value is `grow-only', the tool-bar's height is only increased
31187 automatically; to decrease the tool-bar height, use \\[recenter]. */);
31188 Vauto_resize_tool_bars = Qt;
31190 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p,
31191 doc: /* Non-nil means raise tool-bar buttons when the mouse moves over them. */);
31192 auto_raise_tool_bar_buttons_p = 1;
31194 DEFVAR_BOOL ("make-cursor-line-fully-visible", make_cursor_line_fully_visible_p,
31195 doc: /* Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
31196 make_cursor_line_fully_visible_p = 1;
31198 DEFVAR_LISP ("tool-bar-border", Vtool_bar_border,
31199 doc: /* Border below tool-bar in pixels.
31200 If an integer, use it as the height of the border.
31201 If it is one of `internal-border-width' or `border-width', use the
31202 value of the corresponding frame parameter.
31203 Otherwise, no border is added below the tool-bar. */);
31204 Vtool_bar_border = Qinternal_border_width;
31206 DEFVAR_LISP ("tool-bar-button-margin", Vtool_bar_button_margin,
31207 doc: /* Margin around tool-bar buttons in pixels.
31208 If an integer, use that for both horizontal and vertical margins.
31209 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
31210 HORZ specifying the horizontal margin, and VERT specifying the
31211 vertical margin. */);
31212 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
31214 DEFVAR_INT ("tool-bar-button-relief", tool_bar_button_relief,
31215 doc: /* Relief thickness of tool-bar buttons. */);
31216 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
31218 DEFVAR_LISP ("tool-bar-style", Vtool_bar_style,
31219 doc: /* Tool bar style to use.
31220 It can be one of
31221 image - show images only
31222 text - show text only
31223 both - show both, text below image
31224 both-horiz - show text to the right of the image
31225 text-image-horiz - show text to the left of the image
31226 any other - use system default or image if no system default.
31228 This variable only affects the GTK+ toolkit version of Emacs. */);
31229 Vtool_bar_style = Qnil;
31231 DEFVAR_INT ("tool-bar-max-label-size", tool_bar_max_label_size,
31232 doc: /* Maximum number of characters a label can have to be shown.
31233 The tool bar style must also show labels for this to have any effect, see
31234 `tool-bar-style'. */);
31235 tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
31237 DEFVAR_LISP ("fontification-functions", Vfontification_functions,
31238 doc: /* List of functions to call to fontify regions of text.
31239 Each function is called with one argument POS. Functions must
31240 fontify a region starting at POS in the current buffer, and give
31241 fontified regions the property `fontified'. */);
31242 Vfontification_functions = Qnil;
31243 Fmake_variable_buffer_local (Qfontification_functions);
31245 DEFVAR_BOOL ("unibyte-display-via-language-environment",
31246 unibyte_display_via_language_environment,
31247 doc: /* Non-nil means display unibyte text according to language environment.
31248 Specifically, this means that raw bytes in the range 160-255 decimal
31249 are displayed by converting them to the equivalent multibyte characters
31250 according to the current language environment. As a result, they are
31251 displayed according to the current fontset.
31253 Note that this variable affects only how these bytes are displayed,
31254 but does not change the fact they are interpreted as raw bytes. */);
31255 unibyte_display_via_language_environment = 0;
31257 DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height,
31258 doc: /* Maximum height for resizing mini-windows (the minibuffer and the echo area).
31259 If a float, it specifies a fraction of the mini-window frame's height.
31260 If an integer, it specifies a number of lines. */);
31261 Vmax_mini_window_height = make_float (0.25);
31263 DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows,
31264 doc: /* How to resize mini-windows (the minibuffer and the echo area).
31265 A value of nil means don't automatically resize mini-windows.
31266 A value of t means resize them to fit the text displayed in them.
31267 A value of `grow-only', the default, means let mini-windows grow only;
31268 they return to their normal size when the minibuffer is closed, or the
31269 echo area becomes empty. */);
31270 Vresize_mini_windows = Qgrow_only;
31272 DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist,
31273 doc: /* Alist specifying how to blink the cursor off.
31274 Each element has the form (ON-STATE . OFF-STATE). Whenever the
31275 `cursor-type' frame-parameter or variable equals ON-STATE,
31276 comparing using `equal', Emacs uses OFF-STATE to specify
31277 how to blink it off. ON-STATE and OFF-STATE are values for
31278 the `cursor-type' frame parameter.
31280 If a frame's ON-STATE has no entry in this list,
31281 the frame's other specifications determine how to blink the cursor off. */);
31282 Vblink_cursor_alist = Qnil;
31284 DEFVAR_BOOL ("auto-hscroll-mode", automatic_hscrolling_p,
31285 doc: /* Allow or disallow automatic horizontal scrolling of windows.
31286 If non-nil, windows are automatically scrolled horizontally to make
31287 point visible. */);
31288 automatic_hscrolling_p = 1;
31289 DEFSYM (Qauto_hscroll_mode, "auto-hscroll-mode");
31291 DEFVAR_INT ("hscroll-margin", hscroll_margin,
31292 doc: /* How many columns away from the window edge point is allowed to get
31293 before automatic hscrolling will horizontally scroll the window. */);
31294 hscroll_margin = 5;
31296 DEFVAR_LISP ("hscroll-step", Vhscroll_step,
31297 doc: /* How many columns to scroll the window when point gets too close to the edge.
31298 When point is less than `hscroll-margin' columns from the window
31299 edge, automatic hscrolling will scroll the window by the amount of columns
31300 determined by this variable. If its value is a positive integer, scroll that
31301 many columns. If it's a positive floating-point number, it specifies the
31302 fraction of the window's width to scroll. If it's nil or zero, point will be
31303 centered horizontally after the scroll. Any other value, including negative
31304 numbers, are treated as if the value were zero.
31306 Automatic hscrolling always moves point outside the scroll margin, so if
31307 point was more than scroll step columns inside the margin, the window will
31308 scroll more than the value given by the scroll step.
31310 Note that the lower bound for automatic hscrolling specified by `scroll-left'
31311 and `scroll-right' overrides this variable's effect. */);
31312 Vhscroll_step = make_number (0);
31314 DEFVAR_BOOL ("message-truncate-lines", message_truncate_lines,
31315 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
31316 Bind this around calls to `message' to let it take effect. */);
31317 message_truncate_lines = 0;
31319 DEFVAR_LISP ("menu-bar-update-hook", Vmenu_bar_update_hook,
31320 doc: /* Normal hook run to update the menu bar definitions.
31321 Redisplay runs this hook before it redisplays the menu bar.
31322 This is used to update menus such as Buffers, whose contents depend on
31323 various data. */);
31324 Vmenu_bar_update_hook = Qnil;
31326 DEFVAR_LISP ("menu-updating-frame", Vmenu_updating_frame,
31327 doc: /* Frame for which we are updating a menu.
31328 The enable predicate for a menu binding should check this variable. */);
31329 Vmenu_updating_frame = Qnil;
31331 DEFVAR_BOOL ("inhibit-menubar-update", inhibit_menubar_update,
31332 doc: /* Non-nil means don't update menu bars. Internal use only. */);
31333 inhibit_menubar_update = 0;
31335 DEFVAR_LISP ("wrap-prefix", Vwrap_prefix,
31336 doc: /* Prefix prepended to all continuation lines at display time.
31337 The value may be a string, an image, or a stretch-glyph; it is
31338 interpreted in the same way as the value of a `display' text property.
31340 This variable is overridden by any `wrap-prefix' text or overlay
31341 property.
31343 To add a prefix to non-continuation lines, use `line-prefix'. */);
31344 Vwrap_prefix = Qnil;
31345 DEFSYM (Qwrap_prefix, "wrap-prefix");
31346 Fmake_variable_buffer_local (Qwrap_prefix);
31348 DEFVAR_LISP ("line-prefix", Vline_prefix,
31349 doc: /* Prefix prepended to all non-continuation lines at display time.
31350 The value may be a string, an image, or a stretch-glyph; it is
31351 interpreted in the same way as the value of a `display' text property.
31353 This variable is overridden by any `line-prefix' text or overlay
31354 property.
31356 To add a prefix to continuation lines, use `wrap-prefix'. */);
31357 Vline_prefix = Qnil;
31358 DEFSYM (Qline_prefix, "line-prefix");
31359 Fmake_variable_buffer_local (Qline_prefix);
31361 DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay,
31362 doc: /* Non-nil means don't eval Lisp during redisplay. */);
31363 inhibit_eval_during_redisplay = 0;
31365 DEFVAR_BOOL ("inhibit-free-realized-faces", inhibit_free_realized_faces,
31366 doc: /* Non-nil means don't free realized faces. Internal use only. */);
31367 inhibit_free_realized_faces = 0;
31369 DEFVAR_BOOL ("inhibit-bidi-mirroring", inhibit_bidi_mirroring,
31370 doc: /* Non-nil means don't mirror characters even when bidi context requires that.
31371 Intended for use during debugging and for testing bidi display;
31372 see biditest.el in the test suite. */);
31373 inhibit_bidi_mirroring = 0;
31375 #ifdef GLYPH_DEBUG
31376 DEFVAR_BOOL ("inhibit-try-window-id", inhibit_try_window_id,
31377 doc: /* Inhibit try_window_id display optimization. */);
31378 inhibit_try_window_id = 0;
31380 DEFVAR_BOOL ("inhibit-try-window-reusing", inhibit_try_window_reusing,
31381 doc: /* Inhibit try_window_reusing display optimization. */);
31382 inhibit_try_window_reusing = 0;
31384 DEFVAR_BOOL ("inhibit-try-cursor-movement", inhibit_try_cursor_movement,
31385 doc: /* Inhibit try_cursor_movement display optimization. */);
31386 inhibit_try_cursor_movement = 0;
31387 #endif /* GLYPH_DEBUG */
31389 DEFVAR_INT ("overline-margin", overline_margin,
31390 doc: /* Space between overline and text, in pixels.
31391 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
31392 margin to the character height. */);
31393 overline_margin = 2;
31395 DEFVAR_INT ("underline-minimum-offset",
31396 underline_minimum_offset,
31397 doc: /* Minimum distance between baseline and underline.
31398 This can improve legibility of underlined text at small font sizes,
31399 particularly when using variable `x-use-underline-position-properties'
31400 with fonts that specify an UNDERLINE_POSITION relatively close to the
31401 baseline. The default value is 1. */);
31402 underline_minimum_offset = 1;
31404 DEFVAR_BOOL ("display-hourglass", display_hourglass_p,
31405 doc: /* Non-nil means show an hourglass pointer, when Emacs is busy.
31406 This feature only works when on a window system that can change
31407 cursor shapes. */);
31408 display_hourglass_p = 1;
31410 DEFVAR_LISP ("hourglass-delay", Vhourglass_delay,
31411 doc: /* Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
31412 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
31414 #ifdef HAVE_WINDOW_SYSTEM
31415 hourglass_atimer = NULL;
31416 hourglass_shown_p = 0;
31417 #endif /* HAVE_WINDOW_SYSTEM */
31419 DEFSYM (Qglyphless_char, "glyphless-char");
31420 DEFSYM (Qhex_code, "hex-code");
31421 DEFSYM (Qempty_box, "empty-box");
31422 DEFSYM (Qthin_space, "thin-space");
31423 DEFSYM (Qzero_width, "zero-width");
31425 DEFVAR_LISP ("pre-redisplay-function", Vpre_redisplay_function,
31426 doc: /* Function run just before redisplay.
31427 It is called with one argument, which is the set of windows that are to
31428 be redisplayed. This set can be nil (meaning, only the selected window),
31429 or t (meaning all windows). */);
31430 Vpre_redisplay_function = intern ("ignore");
31432 DEFSYM (Qglyphless_char_display, "glyphless-char-display");
31433 Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
31435 DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display,
31436 doc: /* Char-table defining glyphless characters.
31437 Each element, if non-nil, should be one of the following:
31438 an ASCII acronym string: display this string in a box
31439 `hex-code': display the hexadecimal code of a character in a box
31440 `empty-box': display as an empty box
31441 `thin-space': display as 1-pixel width space
31442 `zero-width': don't display
31443 An element may also be a cons cell (GRAPHICAL . TEXT), which specifies the
31444 display method for graphical terminals and text terminals respectively.
31445 GRAPHICAL and TEXT should each have one of the values listed above.
31447 The char-table has one extra slot to control the display of a character for
31448 which no font is found. This slot only takes effect on graphical terminals.
31449 Its value should be an ASCII acronym string, `hex-code', `empty-box', or
31450 `thin-space'. The default is `empty-box'.
31452 If a character has a non-nil entry in an active display table, the
31453 display table takes effect; in this case, Emacs does not consult
31454 `glyphless-char-display' at all. */);
31455 Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
31456 Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
31457 Qempty_box);
31459 DEFVAR_LISP ("debug-on-message", Vdebug_on_message,
31460 doc: /* If non-nil, debug if a message matching this regexp is displayed. */);
31461 Vdebug_on_message = Qnil;
31463 DEFVAR_LISP ("redisplay--all-windows-cause", Vredisplay__all_windows_cause,
31464 doc: /* */);
31465 Vredisplay__all_windows_cause
31466 = Fmake_vector (make_number (100), make_number (0));
31468 DEFVAR_LISP ("redisplay--mode-lines-cause", Vredisplay__mode_lines_cause,
31469 doc: /* */);
31470 Vredisplay__mode_lines_cause
31471 = Fmake_vector (make_number (100), make_number (0));
31475 /* Initialize this module when Emacs starts. */
31477 void
31478 init_xdisp (void)
31480 CHARPOS (this_line_start_pos) = 0;
31482 if (!noninteractive)
31484 struct window *m = XWINDOW (minibuf_window);
31485 Lisp_Object frame = m->frame;
31486 struct frame *f = XFRAME (frame);
31487 Lisp_Object root = FRAME_ROOT_WINDOW (f);
31488 struct window *r = XWINDOW (root);
31489 int i;
31491 echo_area_window = minibuf_window;
31493 r->top_line = FRAME_TOP_MARGIN (f);
31494 r->pixel_top = r->top_line * FRAME_LINE_HEIGHT (f);
31495 r->total_cols = FRAME_COLS (f);
31496 r->pixel_width = r->total_cols * FRAME_COLUMN_WIDTH (f);
31497 r->total_lines = FRAME_TOTAL_LINES (f) - 1 - FRAME_TOP_MARGIN (f);
31498 r->pixel_height = r->total_lines * FRAME_LINE_HEIGHT (f);
31500 m->top_line = FRAME_TOTAL_LINES (f) - 1;
31501 m->pixel_top = m->top_line * FRAME_LINE_HEIGHT (f);
31502 m->total_cols = FRAME_COLS (f);
31503 m->pixel_width = m->total_cols * FRAME_COLUMN_WIDTH (f);
31504 m->total_lines = 1;
31505 m->pixel_height = m->total_lines * FRAME_LINE_HEIGHT (f);
31507 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
31508 scratch_glyph_row.glyphs[TEXT_AREA + 1]
31509 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
31511 /* The default ellipsis glyphs `...'. */
31512 for (i = 0; i < 3; ++i)
31513 default_invis_vector[i] = make_number ('.');
31517 /* Allocate the buffer for frame titles.
31518 Also used for `format-mode-line'. */
31519 int size = 100;
31520 mode_line_noprop_buf = xmalloc (size);
31521 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
31522 mode_line_noprop_ptr = mode_line_noprop_buf;
31523 mode_line_target = MODE_LINE_DISPLAY;
31526 help_echo_showing_p = 0;
31529 #ifdef HAVE_WINDOW_SYSTEM
31531 /* Platform-independent portion of hourglass implementation. */
31533 /* Timer function of hourglass_atimer. */
31535 static void
31536 show_hourglass (struct atimer *timer)
31538 /* The timer implementation will cancel this timer automatically
31539 after this function has run. Set hourglass_atimer to null
31540 so that we know the timer doesn't have to be canceled. */
31541 hourglass_atimer = NULL;
31543 if (!hourglass_shown_p)
31545 Lisp_Object tail, frame;
31547 block_input ();
31549 FOR_EACH_FRAME (tail, frame)
31551 struct frame *f = XFRAME (frame);
31553 if (FRAME_LIVE_P (f) && FRAME_WINDOW_P (f)
31554 && FRAME_RIF (f)->show_hourglass)
31555 FRAME_RIF (f)->show_hourglass (f);
31558 hourglass_shown_p = 1;
31559 unblock_input ();
31563 /* Cancel a currently active hourglass timer, and start a new one. */
31565 void
31566 start_hourglass (void)
31568 struct timespec delay;
31570 cancel_hourglass ();
31572 if (INTEGERP (Vhourglass_delay)
31573 && XINT (Vhourglass_delay) > 0)
31574 delay = make_timespec (min (XINT (Vhourglass_delay),
31575 TYPE_MAXIMUM (time_t)),
31577 else if (FLOATP (Vhourglass_delay)
31578 && XFLOAT_DATA (Vhourglass_delay) > 0)
31579 delay = dtotimespec (XFLOAT_DATA (Vhourglass_delay));
31580 else
31581 delay = make_timespec (DEFAULT_HOURGLASS_DELAY, 0);
31583 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
31584 show_hourglass, NULL);
31587 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
31588 shown. */
31590 void
31591 cancel_hourglass (void)
31593 if (hourglass_atimer)
31595 cancel_atimer (hourglass_atimer);
31596 hourglass_atimer = NULL;
31599 if (hourglass_shown_p)
31601 Lisp_Object tail, frame;
31603 block_input ();
31605 FOR_EACH_FRAME (tail, frame)
31607 struct frame *f = XFRAME (frame);
31609 if (FRAME_LIVE_P (f) && FRAME_WINDOW_P (f)
31610 && FRAME_RIF (f)->hide_hourglass)
31611 FRAME_RIF (f)->hide_hourglass (f);
31612 #ifdef HAVE_NTGUI
31613 /* No cursors on non GUI frames - restore to stock arrow cursor. */
31614 else if (!FRAME_W32_P (f))
31615 w32_arrow_cursor ();
31616 #endif
31619 hourglass_shown_p = 0;
31620 unblock_input ();
31624 #endif /* HAVE_WINDOW_SYSTEM */