1 /* Display generation from window structure and buffer text.
3 Copyright (C) 1985-1988, 1993-1995, 1997-2013 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20 /* New redisplay written by Gerd Moellmann <gerd@gnu.org>.
24 Emacs separates the task of updating the display from code
25 modifying global state, e.g. buffer text. This way functions
26 operating on buffers don't also have to be concerned with updating
29 Updating the display is triggered by the Lisp interpreter when it
30 decides it's time to do it. This is done either automatically for
31 you as part of the interpreter's command loop or as the result of
32 calling Lisp functions like `sit-for'. The C function `redisplay'
33 in xdisp.c is the only entry into the inner redisplay code.
35 The following diagram shows how redisplay code is invoked. As you
36 can see, Lisp calls redisplay and vice versa. Under window systems
37 like X, some portions of the redisplay code are also called
38 asynchronously during mouse movement or expose events. It is very
39 important that these code parts do NOT use the C library (malloc,
40 free) because many C libraries under Unix are not reentrant. They
41 may also NOT call functions of the Lisp interpreter which could
42 change the interpreter's state. If you don't follow these rules,
43 you will encounter bugs which are very hard to explain.
45 +--------------+ redisplay +----------------+
46 | Lisp machine |---------------->| Redisplay code |<--+
47 +--------------+ (xdisp.c) +----------------+ |
49 +----------------------------------+ |
50 Don't use this path when called |
53 expose_window (asynchronous) |
55 X expose events -----+
57 What does redisplay do? Obviously, it has to figure out somehow what
58 has been changed since the last time the display has been updated,
59 and to make these changes visible. Preferably it would do that in
60 a moderately intelligent way, i.e. fast.
62 Changes in buffer text can be deduced from window and buffer
63 structures, and from some global variables like `beg_unchanged' and
64 `end_unchanged'. The contents of the display are additionally
65 recorded in a `glyph matrix', a two-dimensional matrix of glyph
66 structures. Each row in such a matrix corresponds to a line on the
67 display, and each glyph in a row corresponds to a column displaying
68 a character, an image, or what else. This matrix is called the
69 `current glyph matrix' or `current matrix' in redisplay
72 For buffer parts that have been changed since the last update, a
73 second glyph matrix is constructed, the so called `desired glyph
74 matrix' or short `desired matrix'. Current and desired matrix are
75 then compared to find a cheap way to update the display, e.g. by
76 reusing part of the display by scrolling lines.
78 You will find a lot of redisplay optimizations when you start
79 looking at the innards of redisplay. The overall goal of all these
80 optimizations is to make redisplay fast because it is done
81 frequently. Some of these optimizations are implemented by the
86 This function tries to update the display if the text in the
87 window did not change and did not scroll, only point moved, and
88 it did not move off the displayed portion of the text.
90 . try_window_reusing_current_matrix
92 This function reuses the current matrix of a window when text
93 has not changed, but the window start changed (e.g., due to
98 This function attempts to redisplay a window by reusing parts of
99 its existing display. It finds and reuses the part that was not
100 changed, and redraws the rest.
104 This function performs the full redisplay of a single window
105 assuming that its fonts were not changed and that the cursor
106 will not end up in the scroll margins. (Loading fonts requires
107 re-adjustment of dimensions of glyph matrices, which makes this
108 method impossible to use.)
110 These optimizations are tried in sequence (some can be skipped if
111 it is known that they are not applicable). If none of the
112 optimizations were successful, redisplay calls redisplay_windows,
113 which performs a full redisplay of all windows.
117 Desired matrices are always built per Emacs window. The function
118 `display_line' is the central function to look at if you are
119 interested. It constructs one row in a desired matrix given an
120 iterator structure containing both a buffer position and a
121 description of the environment in which the text is to be
122 displayed. But this is too early, read on.
124 Characters and pixmaps displayed for a range of buffer text depend
125 on various settings of buffers and windows, on overlays and text
126 properties, on display tables, on selective display. The good news
127 is that all this hairy stuff is hidden behind a small set of
128 interface functions taking an iterator structure (struct it)
131 Iteration over things to be displayed is then simple. It is
132 started by initializing an iterator with a call to init_iterator,
133 passing it the buffer position where to start iteration. For
134 iteration over strings, pass -1 as the position to init_iterator,
135 and call reseat_to_string when the string is ready, to initialize
136 the iterator for that string. Thereafter, calls to
137 get_next_display_element fill the iterator structure with relevant
138 information about the next thing to display. Calls to
139 set_iterator_to_next move the iterator to the next thing.
141 Besides this, an iterator also contains information about the
142 display environment in which glyphs for display elements are to be
143 produced. It has fields for the width and height of the display,
144 the information whether long lines are truncated or continued, a
145 current X and Y position, and lots of other stuff you can better
148 Glyphs in a desired matrix are normally constructed in a loop
149 calling get_next_display_element and then PRODUCE_GLYPHS. The call
150 to PRODUCE_GLYPHS will fill the iterator structure with pixel
151 information about the element being displayed and at the same time
152 produce glyphs for it. If the display element fits on the line
153 being displayed, set_iterator_to_next is called next, otherwise the
154 glyphs produced are discarded. The function display_line is the
155 workhorse of filling glyph rows in the desired matrix with glyphs.
156 In addition to producing glyphs, it also handles line truncation
157 and continuation, word wrap, and cursor positioning (for the
158 latter, see also set_cursor_from_row).
162 That just couldn't be all, could it? What about terminal types not
163 supporting operations on sub-windows of the screen? To update the
164 display on such a terminal, window-based glyph matrices are not
165 well suited. To be able to reuse part of the display (scrolling
166 lines up and down), we must instead have a view of the whole
167 screen. This is what `frame matrices' are for. They are a trick.
169 Frames on terminals like above have a glyph pool. Windows on such
170 a frame sub-allocate their glyph memory from their frame's glyph
171 pool. The frame itself is given its own glyph matrices. By
172 coincidence---or maybe something else---rows in window glyph
173 matrices are slices of corresponding rows in frame matrices. Thus
174 writing to window matrices implicitly updates a frame matrix which
175 provides us with the view of the whole screen that we originally
176 wanted to have without having to move many bytes around. To be
177 honest, there is a little bit more done, but not much more. If you
178 plan to extend that code, take a look at dispnew.c. The function
179 build_frame_matrix is a good starting point.
181 Bidirectional display.
183 Bidirectional display adds quite some hair to this already complex
184 design. The good news are that a large portion of that hairy stuff
185 is hidden in bidi.c behind only 3 interfaces. bidi.c implements a
186 reordering engine which is called by set_iterator_to_next and
187 returns the next character to display in the visual order. See
188 commentary on bidi.c for more details. As far as redisplay is
189 concerned, the effect of calling bidi_move_to_visually_next, the
190 main interface of the reordering engine, is that the iterator gets
191 magically placed on the buffer or string position that is to be
192 displayed next. In other words, a linear iteration through the
193 buffer/string is replaced with a non-linear one. All the rest of
194 the redisplay is oblivious to the bidi reordering.
196 Well, almost oblivious---there are still complications, most of
197 them due to the fact that buffer and string positions no longer
198 change monotonously with glyph indices in a glyph row. Moreover,
199 for continued lines, the buffer positions may not even be
200 monotonously changing with vertical positions. Also, accounting
201 for face changes, overlays, etc. becomes more complex because
202 non-linear iteration could potentially skip many positions with
203 changes, and then cross them again on the way back...
205 One other prominent effect of bidirectional display is that some
206 paragraphs of text need to be displayed starting at the right
207 margin of the window---the so-called right-to-left, or R2L
208 paragraphs. R2L paragraphs are displayed with R2L glyph rows,
209 which have their reversed_p flag set. The bidi reordering engine
210 produces characters in such rows starting from the character which
211 should be the rightmost on display. PRODUCE_GLYPHS then reverses
212 the order, when it fills up the glyph row whose reversed_p flag is
213 set, by prepending each new glyph to what is already there, instead
214 of appending it. When the glyph row is complete, the function
215 extend_face_to_end_of_line fills the empty space to the left of the
216 leftmost character with special glyphs, which will display as,
217 well, empty. On text terminals, these special glyphs are simply
218 blank characters. On graphics terminals, there's a single stretch
219 glyph of a suitably computed width. Both the blanks and the
220 stretch glyph are given the face of the background of the line.
221 This way, the terminal-specific back-end can still draw the glyphs
222 left to right, even for R2L lines.
224 Bidirectional display and character compositions
226 Some scripts cannot be displayed by drawing each character
227 individually, because adjacent characters change each other's shape
228 on display. For example, Arabic and Indic scripts belong to this
231 Emacs display supports this by providing "character compositions",
232 most of which is implemented in composite.c. During the buffer
233 scan that delivers characters to PRODUCE_GLYPHS, if the next
234 character to be delivered is a composed character, the iteration
235 calls composition_reseat_it and next_element_from_composition. If
236 they succeed to compose the character with one or more of the
237 following characters, the whole sequence of characters that where
238 composed is recorded in the `struct composition_it' object that is
239 part of the buffer iterator. The composed sequence could produce
240 one or more font glyphs (called "grapheme clusters") on the screen.
241 Each of these grapheme clusters is then delivered to PRODUCE_GLYPHS
242 in the direction corresponding to the current bidi scan direction
243 (recorded in the scan_dir member of the `struct bidi_it' object
244 that is part of the buffer iterator). In particular, if the bidi
245 iterator currently scans the buffer backwards, the grapheme
246 clusters are delivered back to front. This reorders the grapheme
247 clusters as appropriate for the current bidi context. Note that
248 this means that the grapheme clusters are always stored in the
249 LGSTRING object (see composite.c) in the logical order.
251 Moving an iterator in bidirectional text
252 without producing glyphs
254 Note one important detail mentioned above: that the bidi reordering
255 engine, driven by the iterator, produces characters in R2L rows
256 starting at the character that will be the rightmost on display.
257 As far as the iterator is concerned, the geometry of such rows is
258 still left to right, i.e. the iterator "thinks" the first character
259 is at the leftmost pixel position. The iterator does not know that
260 PRODUCE_GLYPHS reverses the order of the glyphs that the iterator
261 delivers. This is important when functions from the move_it_*
262 family are used to get to certain screen position or to match
263 screen coordinates with buffer coordinates: these functions use the
264 iterator geometry, which is left to right even in R2L paragraphs.
265 This works well with most callers of move_it_*, because they need
266 to get to a specific column, and columns are still numbered in the
267 reading order, i.e. the rightmost character in a R2L paragraph is
268 still column zero. But some callers do not get well with this; a
269 notable example is mouse clicks that need to find the character
270 that corresponds to certain pixel coordinates. See
271 buffer_posn_from_coords in dispnew.c for how this is handled. */
279 #include "keyboard.h"
282 #include "termchar.h"
283 #include "dispextern.h"
284 #include "character.h"
288 #include "commands.h"
292 #include "termhooks.h"
293 #include "termopts.h"
294 #include "intervals.h"
297 #include "region-cache.h"
300 #include "blockinput.h"
301 #ifdef HAVE_WINDOW_SYSTEM
303 #endif /* HAVE_WINDOW_SYSTEM */
305 #ifndef FRAME_X_OUTPUT
306 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
309 #define INFINITY 10000000
311 Lisp_Object Qoverriding_local_map
, Qoverriding_terminal_local_map
;
312 Lisp_Object Qwindow_scroll_functions
;
313 static Lisp_Object Qwindow_text_change_functions
;
314 static Lisp_Object Qredisplay_end_trigger_functions
;
315 Lisp_Object Qinhibit_point_motion_hooks
;
316 static Lisp_Object QCeval
, QCpropertize
;
317 Lisp_Object QCfile
, QCdata
;
318 static Lisp_Object Qfontified
;
319 static Lisp_Object Qgrow_only
;
320 static Lisp_Object Qinhibit_eval_during_redisplay
;
321 static Lisp_Object Qbuffer_position
, Qposition
, Qobject
;
322 static Lisp_Object Qright_to_left
, Qleft_to_right
;
325 Lisp_Object Qbar
, Qhbar
, Qbox
, Qhollow
;
327 /* Pointer shapes. */
328 static Lisp_Object Qarrow
, Qhand
;
331 /* Holds the list (error). */
332 static Lisp_Object list_of_error
;
334 static Lisp_Object Qfontification_functions
;
336 static Lisp_Object Qwrap_prefix
;
337 static Lisp_Object Qline_prefix
;
338 static Lisp_Object Qredisplay_internal
;
340 /* Non-nil means don't actually do any redisplay. */
342 Lisp_Object Qinhibit_redisplay
;
344 /* Names of text properties relevant for redisplay. */
346 Lisp_Object Qdisplay
;
348 Lisp_Object Qspace
, QCalign_to
;
349 static Lisp_Object QCrelative_width
, QCrelative_height
;
350 Lisp_Object Qleft_margin
, Qright_margin
;
351 static Lisp_Object Qspace_width
, Qraise
;
352 static Lisp_Object Qslice
;
354 static Lisp_Object Qmargin
, Qpointer
;
355 static Lisp_Object Qline_height
;
357 #ifdef HAVE_WINDOW_SYSTEM
359 /* Test if overflow newline into fringe. Called with iterator IT
360 at or past right window margin, and with IT->current_x set. */
362 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(IT) \
363 (!NILP (Voverflow_newline_into_fringe) \
364 && FRAME_WINDOW_P ((IT)->f) \
365 && ((IT)->bidi_it.paragraph_dir == R2L \
366 ? (WINDOW_LEFT_FRINGE_WIDTH ((IT)->w) > 0) \
367 : (WINDOW_RIGHT_FRINGE_WIDTH ((IT)->w) > 0)) \
368 && (IT)->current_x == (IT)->last_visible_x)
370 #else /* !HAVE_WINDOW_SYSTEM */
371 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) 0
372 #endif /* HAVE_WINDOW_SYSTEM */
374 /* Test if the display element loaded in IT, or the underlying buffer
375 or string character, is a space or a TAB character. This is used
376 to determine where word wrapping can occur. */
378 #define IT_DISPLAYING_WHITESPACE(it) \
379 ((it->what == IT_CHARACTER && (it->c == ' ' || it->c == '\t')) \
380 || ((STRINGP (it->string) \
381 && (SREF (it->string, IT_STRING_BYTEPOS (*it)) == ' ' \
382 || SREF (it->string, IT_STRING_BYTEPOS (*it)) == '\t')) \
384 && (it->s[IT_BYTEPOS (*it)] == ' ' \
385 || it->s[IT_BYTEPOS (*it)] == '\t')) \
386 || (IT_BYTEPOS (*it) < ZV_BYTE \
387 && (*BYTE_POS_ADDR (IT_BYTEPOS (*it)) == ' ' \
388 || *BYTE_POS_ADDR (IT_BYTEPOS (*it)) == '\t')))) \
390 /* Name of the face used to highlight trailing whitespace. */
392 static Lisp_Object Qtrailing_whitespace
;
394 /* Name and number of the face used to highlight escape glyphs. */
396 static Lisp_Object Qescape_glyph
;
398 /* Name and number of the face used to highlight non-breaking spaces. */
400 static Lisp_Object Qnobreak_space
;
402 /* The symbol `image' which is the car of the lists used to represent
403 images in Lisp. Also a tool bar style. */
407 /* The image map types. */
409 static Lisp_Object QCpointer
;
410 static Lisp_Object Qrect
, Qcircle
, Qpoly
;
412 /* Tool bar styles */
413 Lisp_Object Qboth
, Qboth_horiz
, Qtext_image_horiz
;
415 /* Non-zero means print newline to stdout before next mini-buffer
418 bool noninteractive_need_newline
;
420 /* Non-zero means print newline to message log before next message. */
422 static bool message_log_need_newline
;
424 /* Three markers that message_dolog uses.
425 It could allocate them itself, but that causes trouble
426 in handling memory-full errors. */
427 static Lisp_Object message_dolog_marker1
;
428 static Lisp_Object message_dolog_marker2
;
429 static Lisp_Object message_dolog_marker3
;
431 /* The buffer position of the first character appearing entirely or
432 partially on the line of the selected window which contains the
433 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
434 redisplay optimization in redisplay_internal. */
436 static struct text_pos this_line_start_pos
;
438 /* Number of characters past the end of the line above, including the
439 terminating newline. */
441 static struct text_pos this_line_end_pos
;
443 /* The vertical positions and the height of this line. */
445 static int this_line_vpos
;
446 static int this_line_y
;
447 static int this_line_pixel_height
;
449 /* X position at which this display line starts. Usually zero;
450 negative if first character is partially visible. */
452 static int this_line_start_x
;
454 /* The smallest character position seen by move_it_* functions as they
455 move across display lines. Used to set MATRIX_ROW_START_CHARPOS of
456 hscrolled lines, see display_line. */
458 static struct text_pos this_line_min_pos
;
460 /* Buffer that this_line_.* variables are referring to. */
462 static struct buffer
*this_line_buffer
;
465 /* Values of those variables at last redisplay are stored as
466 properties on `overlay-arrow-position' symbol. However, if
467 Voverlay_arrow_position is a marker, last-arrow-position is its
468 numerical position. */
470 static Lisp_Object Qlast_arrow_position
, Qlast_arrow_string
;
472 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
473 properties on a symbol in overlay-arrow-variable-list. */
475 static Lisp_Object Qoverlay_arrow_string
, Qoverlay_arrow_bitmap
;
477 Lisp_Object Qmenu_bar_update_hook
;
479 /* Nonzero if an overlay arrow has been displayed in this window. */
481 static bool overlay_arrow_seen
;
483 /* Vector containing glyphs for an ellipsis `...'. */
485 static Lisp_Object default_invis_vector
[3];
487 /* This is the window where the echo area message was displayed. It
488 is always a mini-buffer window, but it may not be the same window
489 currently active as a mini-buffer. */
491 Lisp_Object echo_area_window
;
493 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
494 pushes the current message and the value of
495 message_enable_multibyte on the stack, the function restore_message
496 pops the stack and displays MESSAGE again. */
498 static Lisp_Object Vmessage_stack
;
500 /* Nonzero means multibyte characters were enabled when the echo area
501 message was specified. */
503 static bool message_enable_multibyte
;
505 /* Nonzero if we should redraw the mode lines on the next redisplay.
506 If it has value REDISPLAY_SOME, then only redisplay the mode lines where
507 the `redisplay' bit has been set. Otherwise, redisplay all mode lines
508 (the number used is then only used to track down the cause for this
511 int update_mode_lines
;
513 /* Nonzero if window sizes or contents other than selected-window have changed
514 since last redisplay that finished.
515 If it has value REDISPLAY_SOME, then only redisplay the windows where
516 the `redisplay' bit has been set. Otherwise, redisplay all windows
517 (the number used is then only used to track down the cause for this
520 int windows_or_buffers_changed
;
522 /* Nonzero after display_mode_line if %l was used and it displayed a
525 static bool line_number_displayed
;
527 /* The name of the *Messages* buffer, a string. */
529 static Lisp_Object Vmessages_buffer_name
;
531 /* Current, index 0, and last displayed echo area message. Either
532 buffers from echo_buffers, or nil to indicate no message. */
534 Lisp_Object echo_area_buffer
[2];
536 /* The buffers referenced from echo_area_buffer. */
538 static Lisp_Object echo_buffer
[2];
540 /* A vector saved used in with_area_buffer to reduce consing. */
542 static Lisp_Object Vwith_echo_area_save_vector
;
544 /* Non-zero means display_echo_area should display the last echo area
545 message again. Set by redisplay_preserve_echo_area. */
547 static bool display_last_displayed_message_p
;
549 /* Nonzero if echo area is being used by print; zero if being used by
552 static bool message_buf_print
;
554 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
556 static Lisp_Object Qinhibit_menubar_update
;
557 static Lisp_Object Qmessage_truncate_lines
;
559 /* Set to 1 in clear_message to make redisplay_internal aware
560 of an emptied echo area. */
562 static bool message_cleared_p
;
564 /* A scratch glyph row with contents used for generating truncation
565 glyphs. Also used in direct_output_for_insert. */
567 #define MAX_SCRATCH_GLYPHS 100
568 static struct glyph_row scratch_glyph_row
;
569 static struct glyph scratch_glyphs
[MAX_SCRATCH_GLYPHS
];
571 /* Ascent and height of the last line processed by move_it_to. */
573 static int last_height
;
575 /* Non-zero if there's a help-echo in the echo area. */
577 bool help_echo_showing_p
;
579 /* The maximum distance to look ahead for text properties. Values
580 that are too small let us call compute_char_face and similar
581 functions too often which is expensive. Values that are too large
582 let us call compute_char_face and alike too often because we
583 might not be interested in text properties that far away. */
585 #define TEXT_PROP_DISTANCE_LIMIT 100
587 /* SAVE_IT and RESTORE_IT are called when we save a snapshot of the
588 iterator state and later restore it. This is needed because the
589 bidi iterator on bidi.c keeps a stacked cache of its states, which
590 is really a singleton. When we use scratch iterator objects to
591 move around the buffer, we can cause the bidi cache to be pushed or
592 popped, and therefore we need to restore the cache state when we
593 return to the original iterator. */
594 #define SAVE_IT(ITCOPY,ITORIG,CACHE) \
597 bidi_unshelve_cache (CACHE, 1); \
599 CACHE = bidi_shelve_cache (); \
602 #define RESTORE_IT(pITORIG,pITCOPY,CACHE) \
604 if (pITORIG != pITCOPY) \
605 *(pITORIG) = *(pITCOPY); \
606 bidi_unshelve_cache (CACHE, 0); \
610 /* Functions to mark elements as needing redisplay. */
611 enum { REDISPLAY_SOME
= 2}; /* Arbitrary choice. */
613 void redisplay_other_windows (void)
615 if (!windows_or_buffers_changed
)
616 windows_or_buffers_changed
= REDISPLAY_SOME
;
619 void wset_redisplay (struct window
*w
)
621 redisplay_other_windows ();
625 void fset_redisplay (struct frame
*f
)
627 redisplay_other_windows ();
631 void bset_redisplay (struct buffer
*b
)
633 int count
= buffer_window_count (b
);
636 /* ... it's visible in other window than selected, */
637 if (count
> 1 || b
!= XBUFFER (XWINDOW (selected_window
)->contents
))
638 redisplay_other_windows ();
639 /* Even if we don't set windows_or_buffers_changed, do set `redisplay'
640 so that if we later set windows_or_buffers_changed, this buffer will
642 b
->text
->redisplay
= true;
646 extern void bset_update_mode_line (struct buffer
*b
)
648 if (!update_mode_lines
)
649 update_mode_lines
= REDISPLAY_SOME
;
650 b
->text
->redisplay
= true;
655 /* Non-zero means print traces of redisplay if compiled with
656 GLYPH_DEBUG defined. */
658 int trace_redisplay_p
;
660 #endif /* GLYPH_DEBUG */
662 #ifdef DEBUG_TRACE_MOVE
663 /* Non-zero means trace with TRACE_MOVE to stderr. */
666 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
668 #define TRACE_MOVE(x) (void) 0
671 static Lisp_Object Qauto_hscroll_mode
;
673 /* Buffer being redisplayed -- for redisplay_window_error. */
675 static struct buffer
*displayed_buffer
;
677 /* Value returned from text property handlers (see below). */
682 HANDLED_RECOMPUTE_PROPS
,
683 HANDLED_OVERLAY_STRING_CONSUMED
,
687 /* A description of text properties that redisplay is interested
692 /* The name of the property. */
695 /* A unique index for the property. */
698 /* A handler function called to set up iterator IT from the property
699 at IT's current position. Value is used to steer handle_stop. */
700 enum prop_handled (*handler
) (struct it
*it
);
703 static enum prop_handled
handle_face_prop (struct it
*);
704 static enum prop_handled
handle_invisible_prop (struct it
*);
705 static enum prop_handled
handle_display_prop (struct it
*);
706 static enum prop_handled
handle_composition_prop (struct it
*);
707 static enum prop_handled
handle_overlay_change (struct it
*);
708 static enum prop_handled
handle_fontified_prop (struct it
*);
710 /* Properties handled by iterators. */
712 static struct props it_props
[] =
714 {&Qfontified
, FONTIFIED_PROP_IDX
, handle_fontified_prop
},
715 /* Handle `face' before `display' because some sub-properties of
716 `display' need to know the face. */
717 {&Qface
, FACE_PROP_IDX
, handle_face_prop
},
718 {&Qdisplay
, DISPLAY_PROP_IDX
, handle_display_prop
},
719 {&Qinvisible
, INVISIBLE_PROP_IDX
, handle_invisible_prop
},
720 {&Qcomposition
, COMPOSITION_PROP_IDX
, handle_composition_prop
},
724 /* Value is the position described by X. If X is a marker, value is
725 the marker_position of X. Otherwise, value is X. */
727 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
729 /* Enumeration returned by some move_it_.* functions internally. */
733 /* Not used. Undefined value. */
736 /* Move ended at the requested buffer position or ZV. */
737 MOVE_POS_MATCH_OR_ZV
,
739 /* Move ended at the requested X pixel position. */
742 /* Move within a line ended at the end of a line that must be
746 /* Move within a line ended at the end of a line that would
747 be displayed truncated. */
750 /* Move within a line ended at a line end. */
754 /* This counter is used to clear the face cache every once in a while
755 in redisplay_internal. It is incremented for each redisplay.
756 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
759 #define CLEAR_FACE_CACHE_COUNT 500
760 static int clear_face_cache_count
;
762 /* Similarly for the image cache. */
764 #ifdef HAVE_WINDOW_SYSTEM
765 #define CLEAR_IMAGE_CACHE_COUNT 101
766 static int clear_image_cache_count
;
768 /* Null glyph slice */
769 static struct glyph_slice null_glyph_slice
= { 0, 0, 0, 0 };
772 /* True while redisplay_internal is in progress. */
776 static Lisp_Object Qinhibit_free_realized_faces
;
777 static Lisp_Object Qmode_line_default_help_echo
;
779 /* If a string, XTread_socket generates an event to display that string.
780 (The display is done in read_char.) */
782 Lisp_Object help_echo_string
;
783 Lisp_Object help_echo_window
;
784 Lisp_Object help_echo_object
;
785 ptrdiff_t help_echo_pos
;
787 /* Temporary variable for XTread_socket. */
789 Lisp_Object previous_help_echo_string
;
791 /* Platform-independent portion of hourglass implementation. */
793 #ifdef HAVE_WINDOW_SYSTEM
795 /* Non-zero means an hourglass cursor is currently shown. */
796 bool hourglass_shown_p
;
798 /* If non-null, an asynchronous timer that, when it expires, displays
799 an hourglass cursor on all frames. */
800 struct atimer
*hourglass_atimer
;
802 #endif /* HAVE_WINDOW_SYSTEM */
804 /* Name of the face used to display glyphless characters. */
805 static Lisp_Object Qglyphless_char
;
807 /* Symbol for the purpose of Vglyphless_char_display. */
808 static Lisp_Object Qglyphless_char_display
;
810 /* Method symbols for Vglyphless_char_display. */
811 static Lisp_Object Qhex_code
, Qempty_box
, Qthin_space
, Qzero_width
;
813 /* Default number of seconds to wait before displaying an hourglass
815 #define DEFAULT_HOURGLASS_DELAY 1
817 #ifdef HAVE_WINDOW_SYSTEM
819 /* Default pixel width of `thin-space' display method. */
820 #define THIN_SPACE_WIDTH 1
822 #endif /* HAVE_WINDOW_SYSTEM */
824 /* Function prototypes. */
826 static void setup_for_ellipsis (struct it
*, int);
827 static void set_iterator_to_next (struct it
*, int);
828 static void mark_window_display_accurate_1 (struct window
*, int);
829 static int single_display_spec_string_p (Lisp_Object
, Lisp_Object
);
830 static int display_prop_string_p (Lisp_Object
, Lisp_Object
);
831 static int row_for_charpos_p (struct glyph_row
*, ptrdiff_t);
832 static int cursor_row_p (struct glyph_row
*);
833 static int redisplay_mode_lines (Lisp_Object
, int);
834 static char *decode_mode_spec_coding (Lisp_Object
, char *, int);
836 static Lisp_Object
get_it_property (struct it
*it
, Lisp_Object prop
);
838 static void handle_line_prefix (struct it
*);
840 static void pint2str (char *, int, ptrdiff_t);
841 static void pint2hrstr (char *, int, ptrdiff_t);
842 static struct text_pos
run_window_scroll_functions (Lisp_Object
,
844 static int text_outside_line_unchanged_p (struct window
*,
845 ptrdiff_t, ptrdiff_t);
846 static void store_mode_line_noprop_char (char);
847 static int store_mode_line_noprop (const char *, int, int);
848 static void handle_stop (struct it
*);
849 static void handle_stop_backwards (struct it
*, ptrdiff_t);
850 static void vmessage (const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (1, 0);
851 static void ensure_echo_area_buffers (void);
852 static void unwind_with_echo_area_buffer (Lisp_Object
);
853 static Lisp_Object
with_echo_area_buffer_unwind_data (struct window
*);
854 static int with_echo_area_buffer (struct window
*, int,
855 int (*) (ptrdiff_t, Lisp_Object
),
856 ptrdiff_t, Lisp_Object
);
857 static void clear_garbaged_frames (void);
858 static int current_message_1 (ptrdiff_t, Lisp_Object
);
859 static int truncate_message_1 (ptrdiff_t, Lisp_Object
);
860 static void set_message (Lisp_Object
);
861 static int set_message_1 (ptrdiff_t, Lisp_Object
);
862 static int display_echo_area (struct window
*);
863 static int display_echo_area_1 (ptrdiff_t, Lisp_Object
);
864 static int resize_mini_window_1 (ptrdiff_t, Lisp_Object
);
865 static void unwind_redisplay (void);
866 static int string_char_and_length (const unsigned char *, int *);
867 static struct text_pos
display_prop_end (struct it
*, Lisp_Object
,
869 static int compute_window_start_on_continuation_line (struct window
*);
870 static void insert_left_trunc_glyphs (struct it
*);
871 static struct glyph_row
*get_overlay_arrow_glyph_row (struct window
*,
873 static void extend_face_to_end_of_line (struct it
*);
874 static int append_space_for_newline (struct it
*, int);
875 static int cursor_row_fully_visible_p (struct window
*, int, int);
876 static int try_scrolling (Lisp_Object
, int, ptrdiff_t, ptrdiff_t, int, int);
877 static int try_cursor_movement (Lisp_Object
, struct text_pos
, int *);
878 static int trailing_whitespace_p (ptrdiff_t);
879 static intmax_t message_log_check_duplicate (ptrdiff_t, ptrdiff_t);
880 static void push_it (struct it
*, struct text_pos
*);
881 static void iterate_out_of_display_property (struct it
*);
882 static void pop_it (struct it
*);
883 static void sync_frame_with_window_matrix_rows (struct window
*);
884 static void redisplay_internal (void);
885 static int echo_area_display (int);
886 static void redisplay_windows (Lisp_Object
);
887 static void redisplay_window (Lisp_Object
, int);
888 static Lisp_Object
redisplay_window_error (Lisp_Object
);
889 static Lisp_Object
redisplay_window_0 (Lisp_Object
);
890 static Lisp_Object
redisplay_window_1 (Lisp_Object
);
891 static int set_cursor_from_row (struct window
*, struct glyph_row
*,
892 struct glyph_matrix
*, ptrdiff_t, ptrdiff_t,
894 static int update_menu_bar (struct frame
*, int, int);
895 static int try_window_reusing_current_matrix (struct window
*);
896 static int try_window_id (struct window
*);
897 static int display_line (struct it
*);
898 static int display_mode_lines (struct window
*);
899 static int display_mode_line (struct window
*, enum face_id
, Lisp_Object
);
900 static int display_mode_element (struct it
*, int, int, int, Lisp_Object
, Lisp_Object
, int);
901 static int store_mode_line_string (const char *, Lisp_Object
, int, int, int, Lisp_Object
);
902 static const char *decode_mode_spec (struct window
*, int, int, Lisp_Object
*);
903 static void display_menu_bar (struct window
*);
904 static ptrdiff_t display_count_lines (ptrdiff_t, ptrdiff_t, ptrdiff_t,
906 static int display_string (const char *, Lisp_Object
, Lisp_Object
,
907 ptrdiff_t, ptrdiff_t, struct it
*, int, int, int, int);
908 static void compute_line_metrics (struct it
*);
909 static void run_redisplay_end_trigger_hook (struct it
*);
910 static int get_overlay_strings (struct it
*, ptrdiff_t);
911 static int get_overlay_strings_1 (struct it
*, ptrdiff_t, int);
912 static void next_overlay_string (struct it
*);
913 static void reseat (struct it
*, struct text_pos
, int);
914 static void reseat_1 (struct it
*, struct text_pos
, int);
915 static void back_to_previous_visible_line_start (struct it
*);
916 static void reseat_at_next_visible_line_start (struct it
*, int);
917 static int next_element_from_ellipsis (struct it
*);
918 static int next_element_from_display_vector (struct it
*);
919 static int next_element_from_string (struct it
*);
920 static int next_element_from_c_string (struct it
*);
921 static int next_element_from_buffer (struct it
*);
922 static int next_element_from_composition (struct it
*);
923 static int next_element_from_image (struct it
*);
924 static int next_element_from_stretch (struct it
*);
925 static void load_overlay_strings (struct it
*, ptrdiff_t);
926 static int init_from_display_pos (struct it
*, struct window
*,
927 struct display_pos
*);
928 static void reseat_to_string (struct it
*, const char *,
929 Lisp_Object
, ptrdiff_t, ptrdiff_t, int, int);
930 static int get_next_display_element (struct it
*);
931 static enum move_it_result
932 move_it_in_display_line_to (struct it
*, ptrdiff_t, int,
933 enum move_operation_enum
);
934 static void get_visually_first_element (struct it
*);
935 static void init_to_row_start (struct it
*, struct window
*,
937 static int init_to_row_end (struct it
*, struct window
*,
939 static void back_to_previous_line_start (struct it
*);
940 static int forward_to_next_line_start (struct it
*, int *, struct bidi_it
*);
941 static struct text_pos
string_pos_nchars_ahead (struct text_pos
,
942 Lisp_Object
, ptrdiff_t);
943 static struct text_pos
string_pos (ptrdiff_t, Lisp_Object
);
944 static struct text_pos
c_string_pos (ptrdiff_t, const char *, bool);
945 static ptrdiff_t number_of_chars (const char *, bool);
946 static void compute_stop_pos (struct it
*);
947 static void compute_string_pos (struct text_pos
*, struct text_pos
,
949 static int face_before_or_after_it_pos (struct it
*, int);
950 static ptrdiff_t next_overlay_change (ptrdiff_t);
951 static int handle_display_spec (struct it
*, Lisp_Object
, Lisp_Object
,
952 Lisp_Object
, struct text_pos
*, ptrdiff_t, int);
953 static int handle_single_display_spec (struct it
*, Lisp_Object
,
954 Lisp_Object
, Lisp_Object
,
955 struct text_pos
*, ptrdiff_t, int, int);
956 static int underlying_face_id (struct it
*);
957 static int in_ellipses_for_invisible_text_p (struct display_pos
*,
960 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
961 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
963 #ifdef HAVE_WINDOW_SYSTEM
965 static void x_consider_frame_title (Lisp_Object
);
966 static void update_tool_bar (struct frame
*, int);
967 static int redisplay_tool_bar (struct frame
*);
968 static void notice_overwritten_cursor (struct window
*,
971 static void append_stretch_glyph (struct it
*, Lisp_Object
,
975 #endif /* HAVE_WINDOW_SYSTEM */
977 static void produce_special_glyphs (struct it
*, enum display_element_type
);
978 static void show_mouse_face (Mouse_HLInfo
*, enum draw_glyphs_face
);
979 static int coords_in_mouse_face_p (struct window
*, int, int);
983 /***********************************************************************
984 Window display dimensions
985 ***********************************************************************/
987 /* Return the bottom boundary y-position for text lines in window W.
988 This is the first y position at which a line cannot start.
989 It is relative to the top of the window.
991 This is the height of W minus the height of a mode line, if any. */
994 window_text_bottom_y (struct window
*w
)
996 int height
= WINDOW_TOTAL_HEIGHT (w
);
998 if (WINDOW_WANTS_MODELINE_P (w
))
999 height
-= CURRENT_MODE_LINE_HEIGHT (w
);
1003 /* Return the pixel width of display area AREA of window W.
1004 ANY_AREA means return the total width of W, not including
1005 fringes to the left and right of the window. */
1008 window_box_width (struct window
*w
, enum glyph_row_area area
)
1010 int cols
= w
->total_cols
;
1013 if (!w
->pseudo_window_p
)
1015 cols
-= WINDOW_SCROLL_BAR_COLS (w
);
1017 if (area
== TEXT_AREA
)
1019 cols
-= max (0, w
->left_margin_cols
);
1020 cols
-= max (0, w
->right_margin_cols
);
1021 pixels
= -WINDOW_TOTAL_FRINGE_WIDTH (w
);
1023 else if (area
== LEFT_MARGIN_AREA
)
1025 cols
= max (0, w
->left_margin_cols
);
1028 else if (area
== RIGHT_MARGIN_AREA
)
1030 cols
= max (0, w
->right_margin_cols
);
1035 return cols
* WINDOW_FRAME_COLUMN_WIDTH (w
) + pixels
;
1039 /* Return the pixel height of the display area of window W, not
1040 including mode lines of W, if any. */
1043 window_box_height (struct window
*w
)
1045 struct frame
*f
= XFRAME (w
->frame
);
1046 int height
= WINDOW_TOTAL_HEIGHT (w
);
1048 eassert (height
>= 0);
1050 /* Note: the code below that determines the mode-line/header-line
1051 height is essentially the same as that contained in the macro
1052 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1053 the appropriate glyph row has its `mode_line_p' flag set,
1054 and if it doesn't, uses estimate_mode_line_height instead. */
1056 if (WINDOW_WANTS_MODELINE_P (w
))
1058 struct glyph_row
*ml_row
1059 = (w
->current_matrix
&& w
->current_matrix
->rows
1060 ? MATRIX_MODE_LINE_ROW (w
->current_matrix
)
1062 if (ml_row
&& ml_row
->mode_line_p
)
1063 height
-= ml_row
->height
;
1065 height
-= estimate_mode_line_height (f
, CURRENT_MODE_LINE_FACE_ID (w
));
1068 if (WINDOW_WANTS_HEADER_LINE_P (w
))
1070 struct glyph_row
*hl_row
1071 = (w
->current_matrix
&& w
->current_matrix
->rows
1072 ? MATRIX_HEADER_LINE_ROW (w
->current_matrix
)
1074 if (hl_row
&& hl_row
->mode_line_p
)
1075 height
-= hl_row
->height
;
1077 height
-= estimate_mode_line_height (f
, HEADER_LINE_FACE_ID
);
1080 /* With a very small font and a mode-line that's taller than
1081 default, we might end up with a negative height. */
1082 return max (0, height
);
1085 /* Return the window-relative coordinate of the left edge of display
1086 area AREA of window W. ANY_AREA means return the left edge of the
1087 whole window, to the right of the left fringe of W. */
1090 window_box_left_offset (struct window
*w
, enum glyph_row_area area
)
1094 if (w
->pseudo_window_p
)
1097 x
= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w
);
1099 if (area
== TEXT_AREA
)
1100 x
+= (WINDOW_LEFT_FRINGE_WIDTH (w
)
1101 + window_box_width (w
, LEFT_MARGIN_AREA
));
1102 else if (area
== RIGHT_MARGIN_AREA
)
1103 x
+= (WINDOW_LEFT_FRINGE_WIDTH (w
)
1104 + window_box_width (w
, LEFT_MARGIN_AREA
)
1105 + window_box_width (w
, TEXT_AREA
)
1106 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
1108 : WINDOW_RIGHT_FRINGE_WIDTH (w
)));
1109 else if (area
== LEFT_MARGIN_AREA
1110 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
))
1111 x
+= WINDOW_LEFT_FRINGE_WIDTH (w
);
1117 /* Return the window-relative coordinate of the right edge of display
1118 area AREA of window W. ANY_AREA means return the right edge of the
1119 whole window, to the left of the right fringe of W. */
1122 window_box_right_offset (struct window
*w
, enum glyph_row_area area
)
1124 return window_box_left_offset (w
, area
) + window_box_width (w
, area
);
1127 /* Return the frame-relative coordinate of the left edge of display
1128 area AREA of window W. ANY_AREA means return the left edge of the
1129 whole window, to the right of the left fringe of W. */
1132 window_box_left (struct window
*w
, enum glyph_row_area area
)
1134 struct frame
*f
= XFRAME (w
->frame
);
1137 if (w
->pseudo_window_p
)
1138 return FRAME_INTERNAL_BORDER_WIDTH (f
);
1140 x
= (WINDOW_LEFT_EDGE_X (w
)
1141 + window_box_left_offset (w
, area
));
1147 /* Return the frame-relative coordinate of the right edge of display
1148 area AREA of window W. ANY_AREA means return the right edge of the
1149 whole window, to the left of the right fringe of W. */
1152 window_box_right (struct window
*w
, enum glyph_row_area area
)
1154 return window_box_left (w
, area
) + window_box_width (w
, area
);
1157 /* Get the bounding box of the display area AREA of window W, without
1158 mode lines, in frame-relative coordinates. ANY_AREA means the
1159 whole window, not including the left and right fringes of
1160 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1161 coordinates of the upper-left corner of the box. Return in
1162 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1165 window_box (struct window
*w
, enum glyph_row_area area
, int *box_x
,
1166 int *box_y
, int *box_width
, int *box_height
)
1169 *box_width
= window_box_width (w
, area
);
1171 *box_height
= window_box_height (w
);
1173 *box_x
= window_box_left (w
, area
);
1176 *box_y
= WINDOW_TOP_EDGE_Y (w
);
1177 if (WINDOW_WANTS_HEADER_LINE_P (w
))
1178 *box_y
+= CURRENT_HEADER_LINE_HEIGHT (w
);
1182 #ifdef HAVE_WINDOW_SYSTEM
1184 /* Get the bounding box of the display area AREA of window W, without
1185 mode lines and both fringes of the window. Return in *TOP_LEFT_X
1186 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1187 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1188 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1192 window_box_edges (struct window
*w
, int *top_left_x
, int *top_left_y
,
1193 int *bottom_right_x
, int *bottom_right_y
)
1195 window_box (w
, ANY_AREA
, top_left_x
, top_left_y
,
1196 bottom_right_x
, bottom_right_y
);
1197 *bottom_right_x
+= *top_left_x
;
1198 *bottom_right_y
+= *top_left_y
;
1201 #endif /* HAVE_WINDOW_SYSTEM */
1203 /***********************************************************************
1205 ***********************************************************************/
1207 /* Return the bottom y-position of the line the iterator IT is in.
1208 This can modify IT's settings. */
1211 line_bottom_y (struct it
*it
)
1213 int line_height
= it
->max_ascent
+ it
->max_descent
;
1214 int line_top_y
= it
->current_y
;
1216 if (line_height
== 0)
1219 line_height
= last_height
;
1220 else if (IT_CHARPOS (*it
) < ZV
)
1222 move_it_by_lines (it
, 1);
1223 line_height
= (it
->max_ascent
|| it
->max_descent
1224 ? it
->max_ascent
+ it
->max_descent
1229 struct glyph_row
*row
= it
->glyph_row
;
1231 /* Use the default character height. */
1232 it
->glyph_row
= NULL
;
1233 it
->what
= IT_CHARACTER
;
1236 PRODUCE_GLYPHS (it
);
1237 line_height
= it
->ascent
+ it
->descent
;
1238 it
->glyph_row
= row
;
1242 return line_top_y
+ line_height
;
1245 DEFUN ("line-pixel-height", Fline_pixel_height
,
1246 Sline_pixel_height
, 0, 0, 0,
1247 doc
: /* Return height in pixels of text line in the selected window.
1249 Value is the height in pixels of the line at point. */)
1254 struct window
*w
= XWINDOW (selected_window
);
1256 SET_TEXT_POS (pt
, PT
, PT_BYTE
);
1257 start_display (&it
, w
, pt
);
1258 it
.vpos
= it
.current_y
= 0;
1260 return make_number (line_bottom_y (&it
));
1263 /* Return the default pixel height of text lines in window W. The
1264 value is the canonical height of the W frame's default font, plus
1265 any extra space required by the line-spacing variable or frame
1268 Implementation note: this ignores any line-spacing text properties
1269 put on the newline characters. This is because those properties
1270 only affect the _screen_ line ending in the newline (i.e., in a
1271 continued line, only the last screen line will be affected), which
1272 means only a small number of lines in a buffer can ever use this
1273 feature. Since this function is used to compute the default pixel
1274 equivalent of text lines in a window, we can safely ignore those
1275 few lines. For the same reasons, we ignore the line-height
1278 default_line_pixel_height (struct window
*w
)
1280 struct frame
*f
= WINDOW_XFRAME (w
);
1281 int height
= FRAME_LINE_HEIGHT (f
);
1283 if (!FRAME_INITIAL_P (f
) && BUFFERP (w
->contents
))
1285 struct buffer
*b
= XBUFFER (w
->contents
);
1286 Lisp_Object val
= BVAR (b
, extra_line_spacing
);
1289 val
= BVAR (&buffer_defaults
, extra_line_spacing
);
1292 if (RANGED_INTEGERP (0, val
, INT_MAX
))
1293 height
+= XFASTINT (val
);
1294 else if (FLOATP (val
))
1296 int addon
= XFLOAT_DATA (val
) * height
+ 0.5;
1303 height
+= f
->extra_line_spacing
;
1309 /* Subroutine of pos_visible_p below. Extracts a display string, if
1310 any, from the display spec given as its argument. */
1312 string_from_display_spec (Lisp_Object spec
)
1316 while (CONSP (spec
))
1318 if (STRINGP (XCAR (spec
)))
1323 else if (VECTORP (spec
))
1327 for (i
= 0; i
< ASIZE (spec
); i
++)
1329 if (STRINGP (AREF (spec
, i
)))
1330 return AREF (spec
, i
);
1339 /* Limit insanely large values of W->hscroll on frame F to the largest
1340 value that will still prevent first_visible_x and last_visible_x of
1341 'struct it' from overflowing an int. */
1343 window_hscroll_limited (struct window
*w
, struct frame
*f
)
1345 ptrdiff_t window_hscroll
= w
->hscroll
;
1346 int window_text_width
= window_box_width (w
, TEXT_AREA
);
1347 int colwidth
= FRAME_COLUMN_WIDTH (f
);
1349 if (window_hscroll
> (INT_MAX
- window_text_width
) / colwidth
- 1)
1350 window_hscroll
= (INT_MAX
- window_text_width
) / colwidth
- 1;
1352 return window_hscroll
;
1355 /* Return 1 if position CHARPOS is visible in window W.
1356 CHARPOS < 0 means return info about WINDOW_END position.
1357 If visible, set *X and *Y to pixel coordinates of top left corner.
1358 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1359 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1362 pos_visible_p (struct window
*w
, ptrdiff_t charpos
, int *x
, int *y
,
1363 int *rtop
, int *rbot
, int *rowh
, int *vpos
)
1366 void *itdata
= bidi_shelve_cache ();
1367 struct text_pos top
;
1369 struct buffer
*old_buffer
= NULL
;
1371 if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w
))))
1374 if (XBUFFER (w
->contents
) != current_buffer
)
1376 old_buffer
= current_buffer
;
1377 set_buffer_internal_1 (XBUFFER (w
->contents
));
1380 SET_TEXT_POS_FROM_MARKER (top
, w
->start
);
1381 /* Scrolling a minibuffer window via scroll bar when the echo area
1382 shows long text sometimes resets the minibuffer contents behind
1384 if (CHARPOS (top
) > ZV
)
1385 SET_TEXT_POS (top
, BEGV
, BEGV_BYTE
);
1387 /* Compute exact mode line heights. */
1388 if (WINDOW_WANTS_MODELINE_P (w
))
1390 = display_mode_line (w
, CURRENT_MODE_LINE_FACE_ID (w
),
1391 BVAR (current_buffer
, mode_line_format
));
1393 if (WINDOW_WANTS_HEADER_LINE_P (w
))
1394 w
->header_line_height
1395 = display_mode_line (w
, HEADER_LINE_FACE_ID
,
1396 BVAR (current_buffer
, header_line_format
));
1398 start_display (&it
, w
, top
);
1399 move_it_to (&it
, charpos
, -1, it
.last_visible_y
- 1, -1,
1400 (charpos
>= 0 ? MOVE_TO_POS
: 0) | MOVE_TO_Y
);
1403 && (((!it
.bidi_p
|| it
.bidi_it
.scan_dir
== 1)
1404 && IT_CHARPOS (it
) >= charpos
)
1405 /* When scanning backwards under bidi iteration, move_it_to
1406 stops at or _before_ CHARPOS, because it stops at or to
1407 the _right_ of the character at CHARPOS. */
1408 || (it
.bidi_p
&& it
.bidi_it
.scan_dir
== -1
1409 && IT_CHARPOS (it
) <= charpos
)))
1411 /* We have reached CHARPOS, or passed it. How the call to
1412 move_it_to can overshoot: (i) If CHARPOS is on invisible text
1413 or covered by a display property, move_it_to stops at the end
1414 of the invisible text, to the right of CHARPOS. (ii) If
1415 CHARPOS is in a display vector, move_it_to stops on its last
1417 int top_x
= it
.current_x
;
1418 int top_y
= it
.current_y
;
1419 /* Calling line_bottom_y may change it.method, it.position, etc. */
1420 enum it_method it_method
= it
.method
;
1421 int bottom_y
= (last_height
= 0, line_bottom_y (&it
));
1422 int window_top_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
1424 if (top_y
< window_top_y
)
1425 visible_p
= bottom_y
> window_top_y
;
1426 else if (top_y
< it
.last_visible_y
)
1428 if (bottom_y
>= it
.last_visible_y
1429 && it
.bidi_p
&& it
.bidi_it
.scan_dir
== -1
1430 && IT_CHARPOS (it
) < charpos
)
1432 /* When the last line of the window is scanned backwards
1433 under bidi iteration, we could be duped into thinking
1434 that we have passed CHARPOS, when in fact move_it_to
1435 simply stopped short of CHARPOS because it reached
1436 last_visible_y. To see if that's what happened, we call
1437 move_it_to again with a slightly larger vertical limit,
1438 and see if it actually moved vertically; if it did, we
1439 didn't really reach CHARPOS, which is beyond window end. */
1440 struct it save_it
= it
;
1441 /* Why 10? because we don't know how many canonical lines
1442 will the height of the next line(s) be. So we guess. */
1443 int ten_more_lines
= 10 * default_line_pixel_height (w
);
1445 move_it_to (&it
, charpos
, -1, bottom_y
+ ten_more_lines
, -1,
1446 MOVE_TO_POS
| MOVE_TO_Y
);
1447 if (it
.current_y
> top_y
)
1454 if (it_method
== GET_FROM_DISPLAY_VECTOR
)
1456 /* We stopped on the last glyph of a display vector.
1457 Try and recompute. Hack alert! */
1458 if (charpos
< 2 || top
.charpos
>= charpos
)
1459 top_x
= it
.glyph_row
->x
;
1462 struct it it2
, it2_prev
;
1463 /* The idea is to get to the previous buffer
1464 position, consume the character there, and use
1465 the pixel coordinates we get after that. But if
1466 the previous buffer position is also displayed
1467 from a display vector, we need to consume all of
1468 the glyphs from that display vector. */
1469 start_display (&it2
, w
, top
);
1470 move_it_to (&it2
, charpos
- 1, -1, -1, -1, MOVE_TO_POS
);
1471 /* If we didn't get to CHARPOS - 1, there's some
1472 replacing display property at that position, and
1473 we stopped after it. That is exactly the place
1474 whose coordinates we want. */
1475 if (IT_CHARPOS (it2
) != charpos
- 1)
1479 /* Iterate until we get out of the display
1480 vector that displays the character at
1483 get_next_display_element (&it2
);
1484 PRODUCE_GLYPHS (&it2
);
1486 set_iterator_to_next (&it2
, 1);
1487 } while (it2
.method
== GET_FROM_DISPLAY_VECTOR
1488 && IT_CHARPOS (it2
) < charpos
);
1490 if (ITERATOR_AT_END_OF_LINE_P (&it2_prev
)
1491 || it2_prev
.current_x
> it2_prev
.last_visible_x
)
1492 top_x
= it
.glyph_row
->x
;
1495 top_x
= it2_prev
.current_x
;
1496 top_y
= it2_prev
.current_y
;
1500 else if (IT_CHARPOS (it
) != charpos
)
1502 Lisp_Object cpos
= make_number (charpos
);
1503 Lisp_Object spec
= Fget_char_property (cpos
, Qdisplay
, Qnil
);
1504 Lisp_Object string
= string_from_display_spec (spec
);
1505 struct text_pos tpos
;
1506 int replacing_spec_p
;
1507 bool newline_in_string
1509 && memchr (SDATA (string
), '\n', SBYTES (string
)));
1511 SET_TEXT_POS (tpos
, charpos
, CHAR_TO_BYTE (charpos
));
1514 && handle_display_spec (NULL
, spec
, Qnil
, Qnil
, &tpos
,
1515 charpos
, FRAME_WINDOW_P (it
.f
)));
1516 /* The tricky code below is needed because there's a
1517 discrepancy between move_it_to and how we set cursor
1518 when PT is at the beginning of a portion of text
1519 covered by a display property or an overlay with a
1520 display property, or the display line ends in a
1521 newline from a display string. move_it_to will stop
1522 _after_ such display strings, whereas
1523 set_cursor_from_row conspires with cursor_row_p to
1524 place the cursor on the first glyph produced from the
1527 /* We have overshoot PT because it is covered by a
1528 display property that replaces the text it covers.
1529 If the string includes embedded newlines, we are also
1530 in the wrong display line. Backtrack to the correct
1531 line, where the display property begins. */
1532 if (replacing_spec_p
)
1534 Lisp_Object startpos
, endpos
;
1535 EMACS_INT start
, end
;
1539 /* Find the first and the last buffer positions
1540 covered by the display string. */
1542 Fnext_single_char_property_change (cpos
, Qdisplay
,
1545 Fprevious_single_char_property_change (endpos
, Qdisplay
,
1547 start
= XFASTINT (startpos
);
1548 end
= XFASTINT (endpos
);
1549 /* Move to the last buffer position before the
1550 display property. */
1551 start_display (&it3
, w
, top
);
1552 move_it_to (&it3
, start
- 1, -1, -1, -1, MOVE_TO_POS
);
1553 /* Move forward one more line if the position before
1554 the display string is a newline or if it is the
1555 rightmost character on a line that is
1556 continued or word-wrapped. */
1557 if (it3
.method
== GET_FROM_BUFFER
1559 || FETCH_BYTE (IT_BYTEPOS (it3
)) == '\n'))
1560 move_it_by_lines (&it3
, 1);
1561 else if (move_it_in_display_line_to (&it3
, -1,
1565 == MOVE_LINE_CONTINUED
)
1567 move_it_by_lines (&it3
, 1);
1568 /* When we are under word-wrap, the #$@%!
1569 move_it_by_lines moves 2 lines, so we need to
1571 if (it3
.line_wrap
== WORD_WRAP
)
1572 move_it_by_lines (&it3
, -1);
1575 /* Record the vertical coordinate of the display
1576 line where we wound up. */
1577 top_y
= it3
.current_y
;
1580 /* When characters are reordered for display,
1581 the character displayed to the left of the
1582 display string could be _after_ the display
1583 property in the logical order. Use the
1584 smallest vertical position of these two. */
1585 start_display (&it3
, w
, top
);
1586 move_it_to (&it3
, end
+ 1, -1, -1, -1, MOVE_TO_POS
);
1587 if (it3
.current_y
< top_y
)
1588 top_y
= it3
.current_y
;
1590 /* Move from the top of the window to the beginning
1591 of the display line where the display string
1593 start_display (&it3
, w
, top
);
1594 move_it_to (&it3
, -1, 0, top_y
, -1, MOVE_TO_X
| MOVE_TO_Y
);
1595 /* If it3_moved stays zero after the 'while' loop
1596 below, that means we already were at a newline
1597 before the loop (e.g., the display string begins
1598 with a newline), so we don't need to (and cannot)
1599 inspect the glyphs of it3.glyph_row, because
1600 PRODUCE_GLYPHS will not produce anything for a
1601 newline, and thus it3.glyph_row stays at its
1602 stale content it got at top of the window. */
1604 /* Finally, advance the iterator until we hit the
1605 first display element whose character position is
1606 CHARPOS, or until the first newline from the
1607 display string, which signals the end of the
1609 while (get_next_display_element (&it3
))
1611 PRODUCE_GLYPHS (&it3
);
1612 if (IT_CHARPOS (it3
) == charpos
1613 || ITERATOR_AT_END_OF_LINE_P (&it3
))
1616 set_iterator_to_next (&it3
, 0);
1618 top_x
= it3
.current_x
- it3
.pixel_width
;
1619 /* Normally, we would exit the above loop because we
1620 found the display element whose character
1621 position is CHARPOS. For the contingency that we
1622 didn't, and stopped at the first newline from the
1623 display string, move back over the glyphs
1624 produced from the string, until we find the
1625 rightmost glyph not from the string. */
1627 && newline_in_string
1628 && IT_CHARPOS (it3
) != charpos
&& EQ (it3
.object
, string
))
1630 struct glyph
*g
= it3
.glyph_row
->glyphs
[TEXT_AREA
]
1631 + it3
.glyph_row
->used
[TEXT_AREA
];
1633 while (EQ ((g
- 1)->object
, string
))
1636 top_x
-= g
->pixel_width
;
1638 eassert (g
< it3
.glyph_row
->glyphs
[TEXT_AREA
]
1639 + it3
.glyph_row
->used
[TEXT_AREA
]);
1645 *y
= max (top_y
+ max (0, it
.max_ascent
- it
.ascent
), window_top_y
);
1646 *rtop
= max (0, window_top_y
- top_y
);
1647 *rbot
= max (0, bottom_y
- it
.last_visible_y
);
1648 *rowh
= max (0, (min (bottom_y
, it
.last_visible_y
)
1649 - max (top_y
, window_top_y
)));
1655 /* We were asked to provide info about WINDOW_END. */
1657 void *it2data
= NULL
;
1659 SAVE_IT (it2
, it
, it2data
);
1660 if (IT_CHARPOS (it
) < ZV
&& FETCH_BYTE (IT_BYTEPOS (it
)) != '\n')
1661 move_it_by_lines (&it
, 1);
1662 if (charpos
< IT_CHARPOS (it
)
1663 || (it
.what
== IT_EOB
&& charpos
== IT_CHARPOS (it
)))
1666 RESTORE_IT (&it2
, &it2
, it2data
);
1667 move_it_to (&it2
, charpos
, -1, -1, -1, MOVE_TO_POS
);
1669 *y
= it2
.current_y
+ it2
.max_ascent
- it2
.ascent
;
1670 *rtop
= max (0, -it2
.current_y
);
1671 *rbot
= max (0, ((it2
.current_y
+ it2
.max_ascent
+ it2
.max_descent
)
1672 - it
.last_visible_y
));
1673 *rowh
= max (0, (min (it2
.current_y
+ it2
.max_ascent
+ it2
.max_descent
,
1675 - max (it2
.current_y
,
1676 WINDOW_HEADER_LINE_HEIGHT (w
))));
1680 bidi_unshelve_cache (it2data
, 1);
1682 bidi_unshelve_cache (itdata
, 0);
1685 set_buffer_internal_1 (old_buffer
);
1687 if (visible_p
&& w
->hscroll
> 0)
1689 window_hscroll_limited (w
, WINDOW_XFRAME (w
))
1690 * WINDOW_FRAME_COLUMN_WIDTH (w
);
1693 /* Debugging code. */
1695 fprintf (stderr
, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1696 charpos
, w
->vscroll
, *x
, *y
, *rtop
, *rbot
, *rowh
, *vpos
);
1698 fprintf (stderr
, "-pv pt=%d vs=%d\n", charpos
, w
->vscroll
);
1705 /* Return the next character from STR. Return in *LEN the length of
1706 the character. This is like STRING_CHAR_AND_LENGTH but never
1707 returns an invalid character. If we find one, we return a `?', but
1708 with the length of the invalid character. */
1711 string_char_and_length (const unsigned char *str
, int *len
)
1715 c
= STRING_CHAR_AND_LENGTH (str
, *len
);
1716 if (!CHAR_VALID_P (c
))
1717 /* We may not change the length here because other places in Emacs
1718 don't use this function, i.e. they silently accept invalid
1727 /* Given a position POS containing a valid character and byte position
1728 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1730 static struct text_pos
1731 string_pos_nchars_ahead (struct text_pos pos
, Lisp_Object string
, ptrdiff_t nchars
)
1733 eassert (STRINGP (string
) && nchars
>= 0);
1735 if (STRING_MULTIBYTE (string
))
1737 const unsigned char *p
= SDATA (string
) + BYTEPOS (pos
);
1742 string_char_and_length (p
, &len
);
1745 BYTEPOS (pos
) += len
;
1749 SET_TEXT_POS (pos
, CHARPOS (pos
) + nchars
, BYTEPOS (pos
) + nchars
);
1755 /* Value is the text position, i.e. character and byte position,
1756 for character position CHARPOS in STRING. */
1758 static struct text_pos
1759 string_pos (ptrdiff_t charpos
, Lisp_Object string
)
1761 struct text_pos pos
;
1762 eassert (STRINGP (string
));
1763 eassert (charpos
>= 0);
1764 SET_TEXT_POS (pos
, charpos
, string_char_to_byte (string
, charpos
));
1769 /* Value is a text position, i.e. character and byte position, for
1770 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1771 means recognize multibyte characters. */
1773 static struct text_pos
1774 c_string_pos (ptrdiff_t charpos
, const char *s
, bool multibyte_p
)
1776 struct text_pos pos
;
1778 eassert (s
!= NULL
);
1779 eassert (charpos
>= 0);
1785 SET_TEXT_POS (pos
, 0, 0);
1788 string_char_and_length ((const unsigned char *) s
, &len
);
1791 BYTEPOS (pos
) += len
;
1795 SET_TEXT_POS (pos
, charpos
, charpos
);
1801 /* Value is the number of characters in C string S. MULTIBYTE_P
1802 non-zero means recognize multibyte characters. */
1805 number_of_chars (const char *s
, bool multibyte_p
)
1811 ptrdiff_t rest
= strlen (s
);
1813 const unsigned char *p
= (const unsigned char *) s
;
1815 for (nchars
= 0; rest
> 0; ++nchars
)
1817 string_char_and_length (p
, &len
);
1818 rest
-= len
, p
+= len
;
1822 nchars
= strlen (s
);
1828 /* Compute byte position NEWPOS->bytepos corresponding to
1829 NEWPOS->charpos. POS is a known position in string STRING.
1830 NEWPOS->charpos must be >= POS.charpos. */
1833 compute_string_pos (struct text_pos
*newpos
, struct text_pos pos
, Lisp_Object string
)
1835 eassert (STRINGP (string
));
1836 eassert (CHARPOS (*newpos
) >= CHARPOS (pos
));
1838 if (STRING_MULTIBYTE (string
))
1839 *newpos
= string_pos_nchars_ahead (pos
, string
,
1840 CHARPOS (*newpos
) - CHARPOS (pos
));
1842 BYTEPOS (*newpos
) = CHARPOS (*newpos
);
1846 Return an estimation of the pixel height of mode or header lines on
1847 frame F. FACE_ID specifies what line's height to estimate. */
1850 estimate_mode_line_height (struct frame
*f
, enum face_id face_id
)
1852 #ifdef HAVE_WINDOW_SYSTEM
1853 if (FRAME_WINDOW_P (f
))
1855 int height
= FONT_HEIGHT (FRAME_FONT (f
));
1857 /* This function is called so early when Emacs starts that the face
1858 cache and mode line face are not yet initialized. */
1859 if (FRAME_FACE_CACHE (f
))
1861 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1865 height
= FONT_HEIGHT (face
->font
);
1866 if (face
->box_line_width
> 0)
1867 height
+= 2 * face
->box_line_width
;
1878 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1879 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1880 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1881 not force the value into range. */
1884 pixel_to_glyph_coords (struct frame
*f
, register int pix_x
, register int pix_y
,
1885 int *x
, int *y
, NativeRectangle
*bounds
, int noclip
)
1888 #ifdef HAVE_WINDOW_SYSTEM
1889 if (FRAME_WINDOW_P (f
))
1891 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1892 even for negative values. */
1894 pix_x
-= FRAME_COLUMN_WIDTH (f
) - 1;
1896 pix_y
-= FRAME_LINE_HEIGHT (f
) - 1;
1898 pix_x
= FRAME_PIXEL_X_TO_COL (f
, pix_x
);
1899 pix_y
= FRAME_PIXEL_Y_TO_LINE (f
, pix_y
);
1902 STORE_NATIVE_RECT (*bounds
,
1903 FRAME_COL_TO_PIXEL_X (f
, pix_x
),
1904 FRAME_LINE_TO_PIXEL_Y (f
, pix_y
),
1905 FRAME_COLUMN_WIDTH (f
) - 1,
1906 FRAME_LINE_HEIGHT (f
) - 1);
1912 else if (pix_x
> FRAME_TOTAL_COLS (f
))
1913 pix_x
= FRAME_TOTAL_COLS (f
);
1917 else if (pix_y
> FRAME_LINES (f
))
1918 pix_y
= FRAME_LINES (f
);
1928 /* Find the glyph under window-relative coordinates X/Y in window W.
1929 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1930 strings. Return in *HPOS and *VPOS the row and column number of
1931 the glyph found. Return in *AREA the glyph area containing X.
1932 Value is a pointer to the glyph found or null if X/Y is not on
1933 text, or we can't tell because W's current matrix is not up to
1936 static struct glyph
*
1937 x_y_to_hpos_vpos (struct window
*w
, int x
, int y
, int *hpos
, int *vpos
,
1938 int *dx
, int *dy
, int *area
)
1940 struct glyph
*glyph
, *end
;
1941 struct glyph_row
*row
= NULL
;
1944 /* Find row containing Y. Give up if some row is not enabled. */
1945 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
1947 row
= MATRIX_ROW (w
->current_matrix
, i
);
1948 if (!row
->enabled_p
)
1950 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
1957 /* Give up if Y is not in the window. */
1958 if (i
== w
->current_matrix
->nrows
)
1961 /* Get the glyph area containing X. */
1962 if (w
->pseudo_window_p
)
1969 if (x
< window_box_left_offset (w
, TEXT_AREA
))
1971 *area
= LEFT_MARGIN_AREA
;
1972 x0
= window_box_left_offset (w
, LEFT_MARGIN_AREA
);
1974 else if (x
< window_box_right_offset (w
, TEXT_AREA
))
1977 x0
= window_box_left_offset (w
, TEXT_AREA
) + min (row
->x
, 0);
1981 *area
= RIGHT_MARGIN_AREA
;
1982 x0
= window_box_left_offset (w
, RIGHT_MARGIN_AREA
);
1986 /* Find glyph containing X. */
1987 glyph
= row
->glyphs
[*area
];
1988 end
= glyph
+ row
->used
[*area
];
1990 while (glyph
< end
&& x
>= glyph
->pixel_width
)
1992 x
-= glyph
->pixel_width
;
2002 *dy
= y
- (row
->y
+ row
->ascent
- glyph
->ascent
);
2005 *hpos
= glyph
- row
->glyphs
[*area
];
2009 /* Convert frame-relative x/y to coordinates relative to window W.
2010 Takes pseudo-windows into account. */
2013 frame_to_window_pixel_xy (struct window
*w
, int *x
, int *y
)
2015 if (w
->pseudo_window_p
)
2017 /* A pseudo-window is always full-width, and starts at the
2018 left edge of the frame, plus a frame border. */
2019 struct frame
*f
= XFRAME (w
->frame
);
2020 *x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
2021 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
2025 *x
-= WINDOW_LEFT_EDGE_X (w
);
2026 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
2030 #ifdef HAVE_WINDOW_SYSTEM
2033 Return in RECTS[] at most N clipping rectangles for glyph string S.
2034 Return the number of stored rectangles. */
2037 get_glyph_string_clip_rects (struct glyph_string
*s
, NativeRectangle
*rects
, int n
)
2044 if (s
->row
->full_width_p
)
2046 /* Draw full-width. X coordinates are relative to S->w->left_col. */
2047 r
.x
= WINDOW_LEFT_EDGE_X (s
->w
);
2048 r
.width
= WINDOW_TOTAL_WIDTH (s
->w
);
2050 /* Unless displaying a mode or menu bar line, which are always
2051 fully visible, clip to the visible part of the row. */
2052 if (s
->w
->pseudo_window_p
)
2053 r
.height
= s
->row
->visible_height
;
2055 r
.height
= s
->height
;
2059 /* This is a text line that may be partially visible. */
2060 r
.x
= window_box_left (s
->w
, s
->area
);
2061 r
.width
= window_box_width (s
->w
, s
->area
);
2062 r
.height
= s
->row
->visible_height
;
2066 if (r
.x
< s
->clip_head
->x
)
2068 if (r
.width
>= s
->clip_head
->x
- r
.x
)
2069 r
.width
-= s
->clip_head
->x
- r
.x
;
2072 r
.x
= s
->clip_head
->x
;
2075 if (r
.x
+ r
.width
> s
->clip_tail
->x
+ s
->clip_tail
->background_width
)
2077 if (s
->clip_tail
->x
+ s
->clip_tail
->background_width
>= r
.x
)
2078 r
.width
= s
->clip_tail
->x
+ s
->clip_tail
->background_width
- r
.x
;
2083 /* If S draws overlapping rows, it's sufficient to use the top and
2084 bottom of the window for clipping because this glyph string
2085 intentionally draws over other lines. */
2086 if (s
->for_overlaps
)
2088 r
.y
= WINDOW_HEADER_LINE_HEIGHT (s
->w
);
2089 r
.height
= window_text_bottom_y (s
->w
) - r
.y
;
2091 /* Alas, the above simple strategy does not work for the
2092 environments with anti-aliased text: if the same text is
2093 drawn onto the same place multiple times, it gets thicker.
2094 If the overlap we are processing is for the erased cursor, we
2095 take the intersection with the rectangle of the cursor. */
2096 if (s
->for_overlaps
& OVERLAPS_ERASED_CURSOR
)
2098 XRectangle rc
, r_save
= r
;
2100 rc
.x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (s
->w
, s
->w
->phys_cursor
.x
);
2101 rc
.y
= s
->w
->phys_cursor
.y
;
2102 rc
.width
= s
->w
->phys_cursor_width
;
2103 rc
.height
= s
->w
->phys_cursor_height
;
2105 x_intersect_rectangles (&r_save
, &rc
, &r
);
2110 /* Don't use S->y for clipping because it doesn't take partially
2111 visible lines into account. For example, it can be negative for
2112 partially visible lines at the top of a window. */
2113 if (!s
->row
->full_width_p
2114 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
2115 r
.y
= WINDOW_HEADER_LINE_HEIGHT (s
->w
);
2117 r
.y
= max (0, s
->row
->y
);
2120 r
.y
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
.y
);
2122 /* If drawing the cursor, don't let glyph draw outside its
2123 advertised boundaries. Cleartype does this under some circumstances. */
2124 if (s
->hl
== DRAW_CURSOR
)
2126 struct glyph
*glyph
= s
->first_glyph
;
2131 r
.width
-= s
->x
- r
.x
;
2134 r
.width
= min (r
.width
, glyph
->pixel_width
);
2136 /* If r.y is below window bottom, ensure that we still see a cursor. */
2137 height
= min (glyph
->ascent
+ glyph
->descent
,
2138 min (FRAME_LINE_HEIGHT (s
->f
), s
->row
->visible_height
));
2139 max_y
= window_text_bottom_y (s
->w
) - height
;
2140 max_y
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, max_y
);
2141 if (s
->ybase
- glyph
->ascent
> max_y
)
2148 /* Don't draw cursor glyph taller than our actual glyph. */
2149 height
= max (FRAME_LINE_HEIGHT (s
->f
), glyph
->ascent
+ glyph
->descent
);
2150 if (height
< r
.height
)
2152 max_y
= r
.y
+ r
.height
;
2153 r
.y
= min (max_y
, max (r
.y
, s
->ybase
+ glyph
->descent
- height
));
2154 r
.height
= min (max_y
- r
.y
, height
);
2161 XRectangle r_save
= r
;
2163 if (! x_intersect_rectangles (&r_save
, s
->row
->clip
, &r
))
2167 if ((s
->for_overlaps
& OVERLAPS_BOTH
) == 0
2168 || ((s
->for_overlaps
& OVERLAPS_BOTH
) == OVERLAPS_BOTH
&& n
== 1))
2170 #ifdef CONVERT_FROM_XRECT
2171 CONVERT_FROM_XRECT (r
, *rects
);
2179 /* If we are processing overlapping and allowed to return
2180 multiple clipping rectangles, we exclude the row of the glyph
2181 string from the clipping rectangle. This is to avoid drawing
2182 the same text on the environment with anti-aliasing. */
2183 #ifdef CONVERT_FROM_XRECT
2186 XRectangle
*rs
= rects
;
2188 int i
= 0, row_y
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, s
->row
->y
);
2190 if (s
->for_overlaps
& OVERLAPS_PRED
)
2193 if (r
.y
+ r
.height
> row_y
)
2196 rs
[i
].height
= row_y
- r
.y
;
2202 if (s
->for_overlaps
& OVERLAPS_SUCC
)
2205 if (r
.y
< row_y
+ s
->row
->visible_height
)
2207 if (r
.y
+ r
.height
> row_y
+ s
->row
->visible_height
)
2209 rs
[i
].y
= row_y
+ s
->row
->visible_height
;
2210 rs
[i
].height
= r
.y
+ r
.height
- rs
[i
].y
;
2219 #ifdef CONVERT_FROM_XRECT
2220 for (i
= 0; i
< n
; i
++)
2221 CONVERT_FROM_XRECT (rs
[i
], rects
[i
]);
2228 Return in *NR the clipping rectangle for glyph string S. */
2231 get_glyph_string_clip_rect (struct glyph_string
*s
, NativeRectangle
*nr
)
2233 get_glyph_string_clip_rects (s
, nr
, 1);
2238 Return the position and height of the phys cursor in window W.
2239 Set w->phys_cursor_width to width of phys cursor.
2243 get_phys_cursor_geometry (struct window
*w
, struct glyph_row
*row
,
2244 struct glyph
*glyph
, int *xp
, int *yp
, int *heightp
)
2246 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
2247 int x
, y
, wd
, h
, h0
, y0
;
2249 /* Compute the width of the rectangle to draw. If on a stretch
2250 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2251 rectangle as wide as the glyph, but use a canonical character
2253 wd
= glyph
->pixel_width
- 1;
2254 #if defined (HAVE_NTGUI) || defined (HAVE_NS)
2258 x
= w
->phys_cursor
.x
;
2265 if (glyph
->type
== STRETCH_GLYPH
2266 && !x_stretch_cursor_p
)
2267 wd
= min (FRAME_COLUMN_WIDTH (f
), wd
);
2268 w
->phys_cursor_width
= wd
;
2270 y
= w
->phys_cursor
.y
+ row
->ascent
- glyph
->ascent
;
2272 /* If y is below window bottom, ensure that we still see a cursor. */
2273 h0
= min (FRAME_LINE_HEIGHT (f
), row
->visible_height
);
2275 h
= max (h0
, glyph
->ascent
+ glyph
->descent
);
2276 h0
= min (h0
, glyph
->ascent
+ glyph
->descent
);
2278 y0
= WINDOW_HEADER_LINE_HEIGHT (w
);
2281 h
= max (h
- (y0
- y
) + 1, h0
);
2286 y0
= window_text_bottom_y (w
) - h0
;
2294 *xp
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, x
);
2295 *yp
= WINDOW_TO_FRAME_PIXEL_Y (w
, y
);
2300 * Remember which glyph the mouse is over.
2304 remember_mouse_glyph (struct frame
*f
, int gx
, int gy
, NativeRectangle
*rect
)
2308 struct glyph_row
*r
, *gr
, *end_row
;
2309 enum window_part part
;
2310 enum glyph_row_area area
;
2311 int x
, y
, width
, height
;
2313 /* Try to determine frame pixel position and size of the glyph under
2314 frame pixel coordinates X/Y on frame F. */
2316 if (!f
->glyphs_initialized_p
2317 || (window
= window_from_coordinates (f
, gx
, gy
, &part
, 0),
2320 width
= FRAME_SMALLEST_CHAR_WIDTH (f
);
2321 height
= FRAME_SMALLEST_FONT_HEIGHT (f
);
2325 w
= XWINDOW (window
);
2326 width
= WINDOW_FRAME_COLUMN_WIDTH (w
);
2327 height
= WINDOW_FRAME_LINE_HEIGHT (w
);
2329 x
= window_relative_x_coord (w
, part
, gx
);
2330 y
= gy
- WINDOW_TOP_EDGE_Y (w
);
2332 r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
2333 end_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
2335 if (w
->pseudo_window_p
)
2338 part
= ON_MODE_LINE
; /* Don't adjust margin. */
2344 case ON_LEFT_MARGIN
:
2345 area
= LEFT_MARGIN_AREA
;
2348 case ON_RIGHT_MARGIN
:
2349 area
= RIGHT_MARGIN_AREA
;
2352 case ON_HEADER_LINE
:
2354 gr
= (part
== ON_HEADER_LINE
2355 ? MATRIX_HEADER_LINE_ROW (w
->current_matrix
)
2356 : MATRIX_MODE_LINE_ROW (w
->current_matrix
));
2359 goto text_glyph_row_found
;
2366 for (; r
<= end_row
&& r
->enabled_p
; ++r
)
2367 if (r
->y
+ r
->height
> y
)
2373 text_glyph_row_found
:
2376 struct glyph
*g
= gr
->glyphs
[area
];
2377 struct glyph
*end
= g
+ gr
->used
[area
];
2379 height
= gr
->height
;
2380 for (gx
= gr
->x
; g
< end
; gx
+= g
->pixel_width
, ++g
)
2381 if (gx
+ g
->pixel_width
> x
)
2386 if (g
->type
== IMAGE_GLYPH
)
2388 /* Don't remember when mouse is over image, as
2389 image may have hot-spots. */
2390 STORE_NATIVE_RECT (*rect
, 0, 0, 0, 0);
2393 width
= g
->pixel_width
;
2397 /* Use nominal char spacing at end of line. */
2399 gx
+= (x
/ width
) * width
;
2402 if (part
!= ON_MODE_LINE
&& part
!= ON_HEADER_LINE
)
2403 gx
+= window_box_left_offset (w
, area
);
2407 /* Use nominal line height at end of window. */
2408 gx
= (x
/ width
) * width
;
2410 gy
+= (y
/ height
) * height
;
2414 case ON_LEFT_FRINGE
:
2415 gx
= (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
2416 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w
)
2417 : window_box_right_offset (w
, LEFT_MARGIN_AREA
));
2418 width
= WINDOW_LEFT_FRINGE_WIDTH (w
);
2421 case ON_RIGHT_FRINGE
:
2422 gx
= (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
2423 ? window_box_right_offset (w
, RIGHT_MARGIN_AREA
)
2424 : window_box_right_offset (w
, TEXT_AREA
));
2425 width
= WINDOW_RIGHT_FRINGE_WIDTH (w
);
2429 gx
= (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w
)
2431 : (window_box_right_offset (w
, RIGHT_MARGIN_AREA
)
2432 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
2433 ? WINDOW_RIGHT_FRINGE_WIDTH (w
)
2435 width
= WINDOW_SCROLL_BAR_AREA_WIDTH (w
);
2439 for (; r
<= end_row
&& r
->enabled_p
; ++r
)
2440 if (r
->y
+ r
->height
> y
)
2447 height
= gr
->height
;
2450 /* Use nominal line height at end of window. */
2452 gy
+= (y
/ height
) * height
;
2459 /* If there is no glyph under the mouse, then we divide the screen
2460 into a grid of the smallest glyph in the frame, and use that
2463 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2464 round down even for negative values. */
2470 gx
= (gx
/ width
) * width
;
2471 gy
= (gy
/ height
) * height
;
2476 gx
+= WINDOW_LEFT_EDGE_X (w
);
2477 gy
+= WINDOW_TOP_EDGE_Y (w
);
2480 STORE_NATIVE_RECT (*rect
, gx
, gy
, width
, height
);
2482 /* Visible feedback for debugging. */
2485 XDrawRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2486 f
->output_data
.x
->normal_gc
,
2487 gx
, gy
, width
, height
);
2493 #endif /* HAVE_WINDOW_SYSTEM */
2496 adjust_window_ends (struct window
*w
, struct glyph_row
*row
, bool current
)
2499 w
->window_end_pos
= Z
- MATRIX_ROW_END_CHARPOS (row
);
2500 w
->window_end_bytepos
= Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
2502 = MATRIX_ROW_VPOS (row
, current
? w
->current_matrix
: w
->desired_matrix
);
2505 /***********************************************************************
2506 Lisp form evaluation
2507 ***********************************************************************/
2509 /* Error handler for safe_eval and safe_call. */
2512 safe_eval_handler (Lisp_Object arg
, ptrdiff_t nargs
, Lisp_Object
*args
)
2514 add_to_log ("Error during redisplay: %S signaled %S",
2515 Flist (nargs
, args
), arg
);
2519 /* Call function FUNC with the rest of NARGS - 1 arguments
2520 following. Return the result, or nil if something went
2521 wrong. Prevent redisplay during the evaluation. */
2524 safe_call (ptrdiff_t nargs
, Lisp_Object func
, ...)
2528 if (inhibit_eval_during_redisplay
)
2534 ptrdiff_t count
= SPECPDL_INDEX ();
2535 struct gcpro gcpro1
;
2536 Lisp_Object
*args
= alloca (nargs
* word_size
);
2539 va_start (ap
, func
);
2540 for (i
= 1; i
< nargs
; i
++)
2541 args
[i
] = va_arg (ap
, Lisp_Object
);
2545 gcpro1
.nvars
= nargs
;
2546 specbind (Qinhibit_redisplay
, Qt
);
2547 /* Use Qt to ensure debugger does not run,
2548 so there is no possibility of wanting to redisplay. */
2549 val
= internal_condition_case_n (Ffuncall
, nargs
, args
, Qt
,
2552 val
= unbind_to (count
, val
);
2559 /* Call function FN with one argument ARG.
2560 Return the result, or nil if something went wrong. */
2563 safe_call1 (Lisp_Object fn
, Lisp_Object arg
)
2565 return safe_call (2, fn
, arg
);
2568 static Lisp_Object Qeval
;
2571 safe_eval (Lisp_Object sexpr
)
2573 return safe_call1 (Qeval
, sexpr
);
2576 /* Call function FN with two arguments ARG1 and ARG2.
2577 Return the result, or nil if something went wrong. */
2580 safe_call2 (Lisp_Object fn
, Lisp_Object arg1
, Lisp_Object arg2
)
2582 return safe_call (3, fn
, arg1
, arg2
);
2587 /***********************************************************************
2589 ***********************************************************************/
2593 /* Define CHECK_IT to perform sanity checks on iterators.
2594 This is for debugging. It is too slow to do unconditionally. */
2597 check_it (struct it
*it
)
2599 if (it
->method
== GET_FROM_STRING
)
2601 eassert (STRINGP (it
->string
));
2602 eassert (IT_STRING_CHARPOS (*it
) >= 0);
2606 eassert (IT_STRING_CHARPOS (*it
) < 0);
2607 if (it
->method
== GET_FROM_BUFFER
)
2609 /* Check that character and byte positions agree. */
2610 eassert (IT_CHARPOS (*it
) == BYTE_TO_CHAR (IT_BYTEPOS (*it
)));
2615 eassert (it
->current
.dpvec_index
>= 0);
2617 eassert (it
->current
.dpvec_index
< 0);
2620 #define CHECK_IT(IT) check_it ((IT))
2624 #define CHECK_IT(IT) (void) 0
2629 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2631 /* Check that the window end of window W is what we expect it
2632 to be---the last row in the current matrix displaying text. */
2635 check_window_end (struct window
*w
)
2637 if (!MINI_WINDOW_P (w
) && w
->window_end_valid
)
2639 struct glyph_row
*row
;
2640 eassert ((row
= MATRIX_ROW (w
->current_matrix
, w
->window_end_vpos
),
2642 || MATRIX_ROW_DISPLAYS_TEXT_P (row
)
2643 || MATRIX_ROW_VPOS (row
, w
->current_matrix
) == 0));
2647 #define CHECK_WINDOW_END(W) check_window_end ((W))
2651 #define CHECK_WINDOW_END(W) (void) 0
2653 #endif /* GLYPH_DEBUG and ENABLE_CHECKING */
2655 /***********************************************************************
2656 Iterator initialization
2657 ***********************************************************************/
2659 /* Initialize IT for displaying current_buffer in window W, starting
2660 at character position CHARPOS. CHARPOS < 0 means that no buffer
2661 position is specified which is useful when the iterator is assigned
2662 a position later. BYTEPOS is the byte position corresponding to
2665 If ROW is not null, calls to produce_glyphs with IT as parameter
2666 will produce glyphs in that row.
2668 BASE_FACE_ID is the id of a base face to use. It must be one of
2669 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2670 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2671 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2673 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2674 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2675 will be initialized to use the corresponding mode line glyph row of
2676 the desired matrix of W. */
2679 init_iterator (struct it
*it
, struct window
*w
,
2680 ptrdiff_t charpos
, ptrdiff_t bytepos
,
2681 struct glyph_row
*row
, enum face_id base_face_id
)
2683 enum face_id remapped_base_face_id
= base_face_id
;
2685 /* Some precondition checks. */
2686 eassert (w
!= NULL
&& it
!= NULL
);
2687 eassert (charpos
< 0 || (charpos
>= BUF_BEG (current_buffer
)
2690 /* If face attributes have been changed since the last redisplay,
2691 free realized faces now because they depend on face definitions
2692 that might have changed. Don't free faces while there might be
2693 desired matrices pending which reference these faces. */
2694 if (face_change_count
&& !inhibit_free_realized_faces
)
2696 face_change_count
= 0;
2697 free_all_realized_faces (Qnil
);
2700 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
2701 if (! NILP (Vface_remapping_alist
))
2702 remapped_base_face_id
2703 = lookup_basic_face (XFRAME (w
->frame
), base_face_id
);
2705 /* Use one of the mode line rows of W's desired matrix if
2709 if (base_face_id
== MODE_LINE_FACE_ID
2710 || base_face_id
== MODE_LINE_INACTIVE_FACE_ID
)
2711 row
= MATRIX_MODE_LINE_ROW (w
->desired_matrix
);
2712 else if (base_face_id
== HEADER_LINE_FACE_ID
)
2713 row
= MATRIX_HEADER_LINE_ROW (w
->desired_matrix
);
2717 memset (it
, 0, sizeof *it
);
2718 it
->current
.overlay_string_index
= -1;
2719 it
->current
.dpvec_index
= -1;
2720 it
->base_face_id
= remapped_base_face_id
;
2722 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = -1;
2723 it
->paragraph_embedding
= L2R
;
2724 it
->bidi_it
.string
.lstring
= Qnil
;
2725 it
->bidi_it
.string
.s
= NULL
;
2726 it
->bidi_it
.string
.bufpos
= 0;
2729 /* The window in which we iterate over current_buffer: */
2730 XSETWINDOW (it
->window
, w
);
2732 it
->f
= XFRAME (w
->frame
);
2736 /* Extra space between lines (on window systems only). */
2737 if (base_face_id
== DEFAULT_FACE_ID
2738 && FRAME_WINDOW_P (it
->f
))
2740 if (NATNUMP (BVAR (current_buffer
, extra_line_spacing
)))
2741 it
->extra_line_spacing
= XFASTINT (BVAR (current_buffer
, extra_line_spacing
));
2742 else if (FLOATP (BVAR (current_buffer
, extra_line_spacing
)))
2743 it
->extra_line_spacing
= (XFLOAT_DATA (BVAR (current_buffer
, extra_line_spacing
))
2744 * FRAME_LINE_HEIGHT (it
->f
));
2745 else if (it
->f
->extra_line_spacing
> 0)
2746 it
->extra_line_spacing
= it
->f
->extra_line_spacing
;
2747 it
->max_extra_line_spacing
= 0;
2750 /* If realized faces have been removed, e.g. because of face
2751 attribute changes of named faces, recompute them. When running
2752 in batch mode, the face cache of the initial frame is null. If
2753 we happen to get called, make a dummy face cache. */
2754 if (FRAME_FACE_CACHE (it
->f
) == NULL
)
2755 init_frame_faces (it
->f
);
2756 if (FRAME_FACE_CACHE (it
->f
)->used
== 0)
2757 recompute_basic_faces (it
->f
);
2759 /* Current value of the `slice', `space-width', and 'height' properties. */
2760 it
->slice
.x
= it
->slice
.y
= it
->slice
.width
= it
->slice
.height
= Qnil
;
2761 it
->space_width
= Qnil
;
2762 it
->font_height
= Qnil
;
2763 it
->override_ascent
= -1;
2765 /* Are control characters displayed as `^C'? */
2766 it
->ctl_arrow_p
= !NILP (BVAR (current_buffer
, ctl_arrow
));
2768 /* -1 means everything between a CR and the following line end
2769 is invisible. >0 means lines indented more than this value are
2771 it
->selective
= (INTEGERP (BVAR (current_buffer
, selective_display
))
2773 (-1, XINT (BVAR (current_buffer
, selective_display
)),
2775 : (!NILP (BVAR (current_buffer
, selective_display
))
2777 it
->selective_display_ellipsis_p
2778 = !NILP (BVAR (current_buffer
, selective_display_ellipses
));
2780 /* Display table to use. */
2781 it
->dp
= window_display_table (w
);
2783 /* Are multibyte characters enabled in current_buffer? */
2784 it
->multibyte_p
= !NILP (BVAR (current_buffer
, enable_multibyte_characters
));
2786 /* Get the position at which the redisplay_end_trigger hook should
2787 be run, if it is to be run at all. */
2788 if (MARKERP (w
->redisplay_end_trigger
)
2789 && XMARKER (w
->redisplay_end_trigger
)->buffer
!= 0)
2790 it
->redisplay_end_trigger_charpos
2791 = marker_position (w
->redisplay_end_trigger
);
2792 else if (INTEGERP (w
->redisplay_end_trigger
))
2793 it
->redisplay_end_trigger_charpos
=
2794 clip_to_bounds (PTRDIFF_MIN
, XINT (w
->redisplay_end_trigger
), PTRDIFF_MAX
);
2796 it
->tab_width
= SANE_TAB_WIDTH (current_buffer
);
2798 /* Are lines in the display truncated? */
2799 if (base_face_id
!= DEFAULT_FACE_ID
2801 || (! WINDOW_FULL_WIDTH_P (it
->w
)
2802 && ((!NILP (Vtruncate_partial_width_windows
)
2803 && !INTEGERP (Vtruncate_partial_width_windows
))
2804 || (INTEGERP (Vtruncate_partial_width_windows
)
2805 && (WINDOW_TOTAL_COLS (it
->w
)
2806 < XINT (Vtruncate_partial_width_windows
))))))
2807 it
->line_wrap
= TRUNCATE
;
2808 else if (NILP (BVAR (current_buffer
, truncate_lines
)))
2809 it
->line_wrap
= NILP (BVAR (current_buffer
, word_wrap
))
2810 ? WINDOW_WRAP
: WORD_WRAP
;
2812 it
->line_wrap
= TRUNCATE
;
2814 /* Get dimensions of truncation and continuation glyphs. These are
2815 displayed as fringe bitmaps under X, but we need them for such
2816 frames when the fringes are turned off. But leave the dimensions
2817 zero for tooltip frames, as these glyphs look ugly there and also
2818 sabotage calculations of tooltip dimensions in x-show-tip. */
2819 #ifdef HAVE_WINDOW_SYSTEM
2820 if (!(FRAME_WINDOW_P (it
->f
)
2821 && FRAMEP (tip_frame
)
2822 && it
->f
== XFRAME (tip_frame
)))
2825 if (it
->line_wrap
== TRUNCATE
)
2827 /* We will need the truncation glyph. */
2828 eassert (it
->glyph_row
== NULL
);
2829 produce_special_glyphs (it
, IT_TRUNCATION
);
2830 it
->truncation_pixel_width
= it
->pixel_width
;
2834 /* We will need the continuation glyph. */
2835 eassert (it
->glyph_row
== NULL
);
2836 produce_special_glyphs (it
, IT_CONTINUATION
);
2837 it
->continuation_pixel_width
= it
->pixel_width
;
2841 /* Reset these values to zero because the produce_special_glyphs
2842 above has changed them. */
2843 it
->pixel_width
= it
->ascent
= it
->descent
= 0;
2844 it
->phys_ascent
= it
->phys_descent
= 0;
2846 /* Set this after getting the dimensions of truncation and
2847 continuation glyphs, so that we don't produce glyphs when calling
2848 produce_special_glyphs, above. */
2849 it
->glyph_row
= row
;
2850 it
->area
= TEXT_AREA
;
2852 /* Forget any previous info about this row being reversed. */
2854 it
->glyph_row
->reversed_p
= 0;
2856 /* Get the dimensions of the display area. The display area
2857 consists of the visible window area plus a horizontally scrolled
2858 part to the left of the window. All x-values are relative to the
2859 start of this total display area. */
2860 if (base_face_id
!= DEFAULT_FACE_ID
)
2862 /* Mode lines, menu bar in terminal frames. */
2863 it
->first_visible_x
= 0;
2864 it
->last_visible_x
= WINDOW_TOTAL_WIDTH (w
);
2868 it
->first_visible_x
=
2869 window_hscroll_limited (it
->w
, it
->f
) * FRAME_COLUMN_WIDTH (it
->f
);
2870 it
->last_visible_x
= (it
->first_visible_x
2871 + window_box_width (w
, TEXT_AREA
));
2873 /* If we truncate lines, leave room for the truncation glyph(s) at
2874 the right margin. Otherwise, leave room for the continuation
2875 glyph(s). Done only if the window has no fringes. Since we
2876 don't know at this point whether there will be any R2L lines in
2877 the window, we reserve space for truncation/continuation glyphs
2878 even if only one of the fringes is absent. */
2879 if (WINDOW_RIGHT_FRINGE_WIDTH (it
->w
) == 0
2880 || (it
->bidi_p
&& WINDOW_LEFT_FRINGE_WIDTH (it
->w
) == 0))
2882 if (it
->line_wrap
== TRUNCATE
)
2883 it
->last_visible_x
-= it
->truncation_pixel_width
;
2885 it
->last_visible_x
-= it
->continuation_pixel_width
;
2888 it
->header_line_p
= WINDOW_WANTS_HEADER_LINE_P (w
);
2889 it
->current_y
= WINDOW_HEADER_LINE_HEIGHT (w
) + w
->vscroll
;
2892 /* Leave room for a border glyph. */
2893 if (!FRAME_WINDOW_P (it
->f
)
2894 && !WINDOW_RIGHTMOST_P (it
->w
))
2895 it
->last_visible_x
-= 1;
2897 it
->last_visible_y
= window_text_bottom_y (w
);
2899 /* For mode lines and alike, arrange for the first glyph having a
2900 left box line if the face specifies a box. */
2901 if (base_face_id
!= DEFAULT_FACE_ID
)
2905 it
->face_id
= remapped_base_face_id
;
2907 /* If we have a boxed mode line, make the first character appear
2908 with a left box line. */
2909 face
= FACE_FROM_ID (it
->f
, remapped_base_face_id
);
2910 if (face
->box
!= FACE_NO_BOX
)
2911 it
->start_of_box_run_p
= 1;
2914 /* If a buffer position was specified, set the iterator there,
2915 getting overlays and face properties from that position. */
2916 if (charpos
>= BUF_BEG (current_buffer
))
2918 it
->end_charpos
= ZV
;
2919 eassert (charpos
== BYTE_TO_CHAR (bytepos
));
2920 IT_CHARPOS (*it
) = charpos
;
2921 IT_BYTEPOS (*it
) = bytepos
;
2923 /* We will rely on `reseat' to set this up properly, via
2924 handle_face_prop. */
2925 it
->face_id
= it
->base_face_id
;
2927 it
->start
= it
->current
;
2928 /* Do we need to reorder bidirectional text? Not if this is a
2929 unibyte buffer: by definition, none of the single-byte
2930 characters are strong R2L, so no reordering is needed. And
2931 bidi.c doesn't support unibyte buffers anyway. Also, don't
2932 reorder while we are loading loadup.el, since the tables of
2933 character properties needed for reordering are not yet
2937 && !NILP (BVAR (current_buffer
, bidi_display_reordering
))
2940 /* If we are to reorder bidirectional text, init the bidi
2944 /* Note the paragraph direction that this buffer wants to
2946 if (EQ (BVAR (current_buffer
, bidi_paragraph_direction
),
2948 it
->paragraph_embedding
= L2R
;
2949 else if (EQ (BVAR (current_buffer
, bidi_paragraph_direction
),
2951 it
->paragraph_embedding
= R2L
;
2953 it
->paragraph_embedding
= NEUTRAL_DIR
;
2954 bidi_unshelve_cache (NULL
, 0);
2955 bidi_init_it (charpos
, IT_BYTEPOS (*it
), FRAME_WINDOW_P (it
->f
),
2959 /* Compute faces etc. */
2960 reseat (it
, it
->current
.pos
, 1);
2967 /* Initialize IT for the display of window W with window start POS. */
2970 start_display (struct it
*it
, struct window
*w
, struct text_pos pos
)
2972 struct glyph_row
*row
;
2973 int first_vpos
= WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0;
2975 row
= w
->desired_matrix
->rows
+ first_vpos
;
2976 init_iterator (it
, w
, CHARPOS (pos
), BYTEPOS (pos
), row
, DEFAULT_FACE_ID
);
2977 it
->first_vpos
= first_vpos
;
2979 /* Don't reseat to previous visible line start if current start
2980 position is in a string or image. */
2981 if (it
->method
== GET_FROM_BUFFER
&& it
->line_wrap
!= TRUNCATE
)
2983 int start_at_line_beg_p
;
2984 int first_y
= it
->current_y
;
2986 /* If window start is not at a line start, skip forward to POS to
2987 get the correct continuation lines width. */
2988 start_at_line_beg_p
= (CHARPOS (pos
) == BEGV
2989 || FETCH_BYTE (BYTEPOS (pos
) - 1) == '\n');
2990 if (!start_at_line_beg_p
)
2994 reseat_at_previous_visible_line_start (it
);
2995 move_it_to (it
, CHARPOS (pos
), -1, -1, -1, MOVE_TO_POS
);
2997 new_x
= it
->current_x
+ it
->pixel_width
;
2999 /* If lines are continued, this line may end in the middle
3000 of a multi-glyph character (e.g. a control character
3001 displayed as \003, or in the middle of an overlay
3002 string). In this case move_it_to above will not have
3003 taken us to the start of the continuation line but to the
3004 end of the continued line. */
3005 if (it
->current_x
> 0
3006 && it
->line_wrap
!= TRUNCATE
/* Lines are continued. */
3007 && (/* And glyph doesn't fit on the line. */
3008 new_x
> it
->last_visible_x
3009 /* Or it fits exactly and we're on a window
3011 || (new_x
== it
->last_visible_x
3012 && FRAME_WINDOW_P (it
->f
)
3013 && ((it
->bidi_p
&& it
->bidi_it
.paragraph_dir
== R2L
)
3014 ? WINDOW_LEFT_FRINGE_WIDTH (it
->w
)
3015 : WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)))))
3017 if ((it
->current
.dpvec_index
>= 0
3018 || it
->current
.overlay_string_index
>= 0)
3019 /* If we are on a newline from a display vector or
3020 overlay string, then we are already at the end of
3021 a screen line; no need to go to the next line in
3022 that case, as this line is not really continued.
3023 (If we do go to the next line, C-e will not DTRT.) */
3026 set_iterator_to_next (it
, 1);
3027 move_it_in_display_line_to (it
, -1, -1, 0);
3030 it
->continuation_lines_width
+= it
->current_x
;
3032 /* If the character at POS is displayed via a display
3033 vector, move_it_to above stops at the final glyph of
3034 IT->dpvec. To make the caller redisplay that character
3035 again (a.k.a. start at POS), we need to reset the
3036 dpvec_index to the beginning of IT->dpvec. */
3037 else if (it
->current
.dpvec_index
>= 0)
3038 it
->current
.dpvec_index
= 0;
3040 /* We're starting a new display line, not affected by the
3041 height of the continued line, so clear the appropriate
3042 fields in the iterator structure. */
3043 it
->max_ascent
= it
->max_descent
= 0;
3044 it
->max_phys_ascent
= it
->max_phys_descent
= 0;
3046 it
->current_y
= first_y
;
3048 it
->current_x
= it
->hpos
= 0;
3054 /* Return 1 if POS is a position in ellipses displayed for invisible
3055 text. W is the window we display, for text property lookup. */
3058 in_ellipses_for_invisible_text_p (struct display_pos
*pos
, struct window
*w
)
3060 Lisp_Object prop
, window
;
3062 ptrdiff_t charpos
= CHARPOS (pos
->pos
);
3064 /* If POS specifies a position in a display vector, this might
3065 be for an ellipsis displayed for invisible text. We won't
3066 get the iterator set up for delivering that ellipsis unless
3067 we make sure that it gets aware of the invisible text. */
3068 if (pos
->dpvec_index
>= 0
3069 && pos
->overlay_string_index
< 0
3070 && CHARPOS (pos
->string_pos
) < 0
3072 && (XSETWINDOW (window
, w
),
3073 prop
= Fget_char_property (make_number (charpos
),
3074 Qinvisible
, window
),
3075 !TEXT_PROP_MEANS_INVISIBLE (prop
)))
3077 prop
= Fget_char_property (make_number (charpos
- 1), Qinvisible
,
3079 ellipses_p
= 2 == TEXT_PROP_MEANS_INVISIBLE (prop
);
3086 /* Initialize IT for stepping through current_buffer in window W,
3087 starting at position POS that includes overlay string and display
3088 vector/ control character translation position information. Value
3089 is zero if there are overlay strings with newlines at POS. */
3092 init_from_display_pos (struct it
*it
, struct window
*w
, struct display_pos
*pos
)
3094 ptrdiff_t charpos
= CHARPOS (pos
->pos
), bytepos
= BYTEPOS (pos
->pos
);
3095 int i
, overlay_strings_with_newlines
= 0;
3097 /* If POS specifies a position in a display vector, this might
3098 be for an ellipsis displayed for invisible text. We won't
3099 get the iterator set up for delivering that ellipsis unless
3100 we make sure that it gets aware of the invisible text. */
3101 if (in_ellipses_for_invisible_text_p (pos
, w
))
3107 /* Keep in mind: the call to reseat in init_iterator skips invisible
3108 text, so we might end up at a position different from POS. This
3109 is only a problem when POS is a row start after a newline and an
3110 overlay starts there with an after-string, and the overlay has an
3111 invisible property. Since we don't skip invisible text in
3112 display_line and elsewhere immediately after consuming the
3113 newline before the row start, such a POS will not be in a string,
3114 but the call to init_iterator below will move us to the
3116 init_iterator (it
, w
, charpos
, bytepos
, NULL
, DEFAULT_FACE_ID
);
3118 /* This only scans the current chunk -- it should scan all chunks.
3119 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
3120 to 16 in 22.1 to make this a lesser problem. */
3121 for (i
= 0; i
< it
->n_overlay_strings
&& i
< OVERLAY_STRING_CHUNK_SIZE
; ++i
)
3123 const char *s
= SSDATA (it
->overlay_strings
[i
]);
3124 const char *e
= s
+ SBYTES (it
->overlay_strings
[i
]);
3126 while (s
< e
&& *s
!= '\n')
3131 overlay_strings_with_newlines
= 1;
3136 /* If position is within an overlay string, set up IT to the right
3138 if (pos
->overlay_string_index
>= 0)
3142 /* If the first overlay string happens to have a `display'
3143 property for an image, the iterator will be set up for that
3144 image, and we have to undo that setup first before we can
3145 correct the overlay string index. */
3146 if (it
->method
== GET_FROM_IMAGE
)
3149 /* We already have the first chunk of overlay strings in
3150 IT->overlay_strings. Load more until the one for
3151 pos->overlay_string_index is in IT->overlay_strings. */
3152 if (pos
->overlay_string_index
>= OVERLAY_STRING_CHUNK_SIZE
)
3154 ptrdiff_t n
= pos
->overlay_string_index
/ OVERLAY_STRING_CHUNK_SIZE
;
3155 it
->current
.overlay_string_index
= 0;
3158 load_overlay_strings (it
, 0);
3159 it
->current
.overlay_string_index
+= OVERLAY_STRING_CHUNK_SIZE
;
3163 it
->current
.overlay_string_index
= pos
->overlay_string_index
;
3164 relative_index
= (it
->current
.overlay_string_index
3165 % OVERLAY_STRING_CHUNK_SIZE
);
3166 it
->string
= it
->overlay_strings
[relative_index
];
3167 eassert (STRINGP (it
->string
));
3168 it
->current
.string_pos
= pos
->string_pos
;
3169 it
->method
= GET_FROM_STRING
;
3170 it
->end_charpos
= SCHARS (it
->string
);
3171 /* Set up the bidi iterator for this overlay string. */
3174 it
->bidi_it
.string
.lstring
= it
->string
;
3175 it
->bidi_it
.string
.s
= NULL
;
3176 it
->bidi_it
.string
.schars
= SCHARS (it
->string
);
3177 it
->bidi_it
.string
.bufpos
= it
->overlay_strings_charpos
;
3178 it
->bidi_it
.string
.from_disp_str
= it
->string_from_display_prop_p
;
3179 it
->bidi_it
.string
.unibyte
= !it
->multibyte_p
;
3180 it
->bidi_it
.w
= it
->w
;
3181 bidi_init_it (IT_STRING_CHARPOS (*it
), IT_STRING_BYTEPOS (*it
),
3182 FRAME_WINDOW_P (it
->f
), &it
->bidi_it
);
3184 /* Synchronize the state of the bidi iterator with
3185 pos->string_pos. For any string position other than
3186 zero, this will be done automagically when we resume
3187 iteration over the string and get_visually_first_element
3188 is called. But if string_pos is zero, and the string is
3189 to be reordered for display, we need to resync manually,
3190 since it could be that the iteration state recorded in
3191 pos ended at string_pos of 0 moving backwards in string. */
3192 if (CHARPOS (pos
->string_pos
) == 0)
3194 get_visually_first_element (it
);
3195 if (IT_STRING_CHARPOS (*it
) != 0)
3198 eassert (it
->bidi_it
.charpos
< it
->bidi_it
.string
.schars
);
3199 bidi_move_to_visually_next (&it
->bidi_it
);
3200 } while (it
->bidi_it
.charpos
!= 0);
3202 eassert (IT_STRING_CHARPOS (*it
) == it
->bidi_it
.charpos
3203 && IT_STRING_BYTEPOS (*it
) == it
->bidi_it
.bytepos
);
3207 if (CHARPOS (pos
->string_pos
) >= 0)
3209 /* Recorded position is not in an overlay string, but in another
3210 string. This can only be a string from a `display' property.
3211 IT should already be filled with that string. */
3212 it
->current
.string_pos
= pos
->string_pos
;
3213 eassert (STRINGP (it
->string
));
3215 bidi_init_it (IT_STRING_CHARPOS (*it
), IT_STRING_BYTEPOS (*it
),
3216 FRAME_WINDOW_P (it
->f
), &it
->bidi_it
);
3219 /* Restore position in display vector translations, control
3220 character translations or ellipses. */
3221 if (pos
->dpvec_index
>= 0)
3223 if (it
->dpvec
== NULL
)
3224 get_next_display_element (it
);
3225 eassert (it
->dpvec
&& it
->current
.dpvec_index
== 0);
3226 it
->current
.dpvec_index
= pos
->dpvec_index
;
3230 return !overlay_strings_with_newlines
;
3234 /* Initialize IT for stepping through current_buffer in window W
3235 starting at ROW->start. */
3238 init_to_row_start (struct it
*it
, struct window
*w
, struct glyph_row
*row
)
3240 init_from_display_pos (it
, w
, &row
->start
);
3241 it
->start
= row
->start
;
3242 it
->continuation_lines_width
= row
->continuation_lines_width
;
3247 /* Initialize IT for stepping through current_buffer in window W
3248 starting in the line following ROW, i.e. starting at ROW->end.
3249 Value is zero if there are overlay strings with newlines at ROW's
3253 init_to_row_end (struct it
*it
, struct window
*w
, struct glyph_row
*row
)
3257 if (init_from_display_pos (it
, w
, &row
->end
))
3259 if (row
->continued_p
)
3260 it
->continuation_lines_width
3261 = row
->continuation_lines_width
+ row
->pixel_width
;
3272 /***********************************************************************
3274 ***********************************************************************/
3276 /* Called when IT reaches IT->stop_charpos. Handle text property and
3277 overlay changes. Set IT->stop_charpos to the next position where
3281 handle_stop (struct it
*it
)
3283 enum prop_handled handled
;
3284 int handle_overlay_change_p
;
3288 it
->current
.dpvec_index
= -1;
3289 handle_overlay_change_p
= !it
->ignore_overlay_strings_at_pos_p
;
3290 it
->ignore_overlay_strings_at_pos_p
= 0;
3293 /* Use face of preceding text for ellipsis (if invisible) */
3294 if (it
->selective_display_ellipsis_p
)
3295 it
->saved_face_id
= it
->face_id
;
3299 handled
= HANDLED_NORMALLY
;
3301 /* Call text property handlers. */
3302 for (p
= it_props
; p
->handler
; ++p
)
3304 handled
= p
->handler (it
);
3306 if (handled
== HANDLED_RECOMPUTE_PROPS
)
3308 else if (handled
== HANDLED_RETURN
)
3310 /* We still want to show before and after strings from
3311 overlays even if the actual buffer text is replaced. */
3312 if (!handle_overlay_change_p
3314 /* Don't call get_overlay_strings_1 if we already
3315 have overlay strings loaded, because doing so
3316 will load them again and push the iterator state
3317 onto the stack one more time, which is not
3318 expected by the rest of the code that processes
3320 || (it
->current
.overlay_string_index
< 0
3321 ? !get_overlay_strings_1 (it
, 0, 0)
3325 setup_for_ellipsis (it
, 0);
3326 /* When handling a display spec, we might load an
3327 empty string. In that case, discard it here. We
3328 used to discard it in handle_single_display_spec,
3329 but that causes get_overlay_strings_1, above, to
3330 ignore overlay strings that we must check. */
3331 if (STRINGP (it
->string
) && !SCHARS (it
->string
))
3335 else if (STRINGP (it
->string
) && !SCHARS (it
->string
))
3339 it
->ignore_overlay_strings_at_pos_p
= 1;
3340 it
->string_from_display_prop_p
= 0;
3341 it
->from_disp_prop_p
= 0;
3342 handle_overlay_change_p
= 0;
3344 handled
= HANDLED_RECOMPUTE_PROPS
;
3347 else if (handled
== HANDLED_OVERLAY_STRING_CONSUMED
)
3348 handle_overlay_change_p
= 0;
3351 if (handled
!= HANDLED_RECOMPUTE_PROPS
)
3353 /* Don't check for overlay strings below when set to deliver
3354 characters from a display vector. */
3355 if (it
->method
== GET_FROM_DISPLAY_VECTOR
)
3356 handle_overlay_change_p
= 0;
3358 /* Handle overlay changes.
3359 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
3360 if it finds overlays. */
3361 if (handle_overlay_change_p
)
3362 handled
= handle_overlay_change (it
);
3367 setup_for_ellipsis (it
, 0);
3371 while (handled
== HANDLED_RECOMPUTE_PROPS
);
3373 /* Determine where to stop next. */
3374 if (handled
== HANDLED_NORMALLY
)
3375 compute_stop_pos (it
);
3379 /* Compute IT->stop_charpos from text property and overlay change
3380 information for IT's current position. */
3383 compute_stop_pos (struct it
*it
)
3385 register INTERVAL iv
, next_iv
;
3386 Lisp_Object object
, limit
, position
;
3387 ptrdiff_t charpos
, bytepos
;
3389 if (STRINGP (it
->string
))
3391 /* Strings are usually short, so don't limit the search for
3393 it
->stop_charpos
= it
->end_charpos
;
3394 object
= it
->string
;
3396 charpos
= IT_STRING_CHARPOS (*it
);
3397 bytepos
= IT_STRING_BYTEPOS (*it
);
3403 /* If end_charpos is out of range for some reason, such as a
3404 misbehaving display function, rationalize it (Bug#5984). */
3405 if (it
->end_charpos
> ZV
)
3406 it
->end_charpos
= ZV
;
3407 it
->stop_charpos
= it
->end_charpos
;
3409 /* If next overlay change is in front of the current stop pos
3410 (which is IT->end_charpos), stop there. Note: value of
3411 next_overlay_change is point-max if no overlay change
3413 charpos
= IT_CHARPOS (*it
);
3414 bytepos
= IT_BYTEPOS (*it
);
3415 pos
= next_overlay_change (charpos
);
3416 if (pos
< it
->stop_charpos
)
3417 it
->stop_charpos
= pos
;
3419 /* Set up variables for computing the stop position from text
3420 property changes. */
3421 XSETBUFFER (object
, current_buffer
);
3422 limit
= make_number (IT_CHARPOS (*it
) + TEXT_PROP_DISTANCE_LIMIT
);
3425 /* Get the interval containing IT's position. Value is a null
3426 interval if there isn't such an interval. */
3427 position
= make_number (charpos
);
3428 iv
= validate_interval_range (object
, &position
, &position
, 0);
3431 Lisp_Object values_here
[LAST_PROP_IDX
];
3434 /* Get properties here. */
3435 for (p
= it_props
; p
->handler
; ++p
)
3436 values_here
[p
->idx
] = textget (iv
->plist
, *p
->name
);
3438 /* Look for an interval following iv that has different
3440 for (next_iv
= next_interval (iv
);
3443 || XFASTINT (limit
) > next_iv
->position
));
3444 next_iv
= next_interval (next_iv
))
3446 for (p
= it_props
; p
->handler
; ++p
)
3448 Lisp_Object new_value
;
3450 new_value
= textget (next_iv
->plist
, *p
->name
);
3451 if (!EQ (values_here
[p
->idx
], new_value
))
3461 if (INTEGERP (limit
)
3462 && next_iv
->position
>= XFASTINT (limit
))
3463 /* No text property change up to limit. */
3464 it
->stop_charpos
= min (XFASTINT (limit
), it
->stop_charpos
);
3466 /* Text properties change in next_iv. */
3467 it
->stop_charpos
= min (it
->stop_charpos
, next_iv
->position
);
3471 if (it
->cmp_it
.id
< 0)
3473 ptrdiff_t stoppos
= it
->end_charpos
;
3475 if (it
->bidi_p
&& it
->bidi_it
.scan_dir
< 0)
3477 composition_compute_stop_pos (&it
->cmp_it
, charpos
, bytepos
,
3478 stoppos
, it
->string
);
3481 eassert (STRINGP (it
->string
)
3482 || (it
->stop_charpos
>= BEGV
3483 && it
->stop_charpos
>= IT_CHARPOS (*it
)));
3487 /* Return the position of the next overlay change after POS in
3488 current_buffer. Value is point-max if no overlay change
3489 follows. This is like `next-overlay-change' but doesn't use
3493 next_overlay_change (ptrdiff_t pos
)
3495 ptrdiff_t i
, noverlays
;
3497 Lisp_Object
*overlays
;
3499 /* Get all overlays at the given position. */
3500 GET_OVERLAYS_AT (pos
, overlays
, noverlays
, &endpos
, 1);
3502 /* If any of these overlays ends before endpos,
3503 use its ending point instead. */
3504 for (i
= 0; i
< noverlays
; ++i
)
3509 oend
= OVERLAY_END (overlays
[i
]);
3510 oendpos
= OVERLAY_POSITION (oend
);
3511 endpos
= min (endpos
, oendpos
);
3517 /* How many characters forward to search for a display property or
3518 display string. Searching too far forward makes the bidi display
3519 sluggish, especially in small windows. */
3520 #define MAX_DISP_SCAN 250
3522 /* Return the character position of a display string at or after
3523 position specified by POSITION. If no display string exists at or
3524 after POSITION, return ZV. A display string is either an overlay
3525 with `display' property whose value is a string, or a `display'
3526 text property whose value is a string. STRING is data about the
3527 string to iterate; if STRING->lstring is nil, we are iterating a
3528 buffer. FRAME_WINDOW_P is non-zero when we are displaying a window
3529 on a GUI frame. DISP_PROP is set to zero if we searched
3530 MAX_DISP_SCAN characters forward without finding any display
3531 strings, non-zero otherwise. It is set to 2 if the display string
3532 uses any kind of `(space ...)' spec that will produce a stretch of
3533 white space in the text area. */
3535 compute_display_string_pos (struct text_pos
*position
,
3536 struct bidi_string_data
*string
,
3538 int frame_window_p
, int *disp_prop
)
3540 /* OBJECT = nil means current buffer. */
3541 Lisp_Object object
, object1
;
3542 Lisp_Object pos
, spec
, limpos
;
3543 int string_p
= (string
&& (STRINGP (string
->lstring
) || string
->s
));
3544 ptrdiff_t eob
= string_p
? string
->schars
: ZV
;
3545 ptrdiff_t begb
= string_p
? 0 : BEGV
;
3546 ptrdiff_t bufpos
, charpos
= CHARPOS (*position
);
3548 (charpos
< eob
- MAX_DISP_SCAN
) ? charpos
+ MAX_DISP_SCAN
: eob
;
3549 struct text_pos tpos
;
3552 if (string
&& STRINGP (string
->lstring
))
3553 object1
= object
= string
->lstring
;
3554 else if (w
&& !string_p
)
3556 XSETWINDOW (object
, w
);
3560 object1
= object
= Qnil
;
3565 /* We don't support display properties whose values are strings
3566 that have display string properties. */
3567 || string
->from_disp_str
3568 /* C strings cannot have display properties. */
3569 || (string
->s
&& !STRINGP (object
)))
3575 /* If the character at CHARPOS is where the display string begins,
3577 pos
= make_number (charpos
);
3578 if (STRINGP (object
))
3579 bufpos
= string
->bufpos
;
3583 if (!NILP (spec
= Fget_char_property (pos
, Qdisplay
, object
))
3585 || !EQ (Fget_char_property (make_number (charpos
- 1), Qdisplay
,
3588 && (rv
= handle_display_spec (NULL
, spec
, object
, Qnil
, &tpos
, bufpos
,
3596 /* Look forward for the first character with a `display' property
3597 that will replace the underlying text when displayed. */
3598 limpos
= make_number (lim
);
3600 pos
= Fnext_single_char_property_change (pos
, Qdisplay
, object1
, limpos
);
3601 CHARPOS (tpos
) = XFASTINT (pos
);
3602 if (CHARPOS (tpos
) >= lim
)
3607 if (STRINGP (object
))
3608 BYTEPOS (tpos
) = string_char_to_byte (object
, CHARPOS (tpos
));
3610 BYTEPOS (tpos
) = CHAR_TO_BYTE (CHARPOS (tpos
));
3611 spec
= Fget_char_property (pos
, Qdisplay
, object
);
3612 if (!STRINGP (object
))
3613 bufpos
= CHARPOS (tpos
);
3614 } while (NILP (spec
)
3615 || !(rv
= handle_display_spec (NULL
, spec
, object
, Qnil
, &tpos
,
3616 bufpos
, frame_window_p
)));
3620 return CHARPOS (tpos
);
3623 /* Return the character position of the end of the display string that
3624 started at CHARPOS. If there's no display string at CHARPOS,
3625 return -1. A display string is either an overlay with `display'
3626 property whose value is a string or a `display' text property whose
3627 value is a string. */
3629 compute_display_string_end (ptrdiff_t charpos
, struct bidi_string_data
*string
)
3631 /* OBJECT = nil means current buffer. */
3632 Lisp_Object object
=
3633 (string
&& STRINGP (string
->lstring
)) ? string
->lstring
: Qnil
;
3634 Lisp_Object pos
= make_number (charpos
);
3636 (STRINGP (object
) || (string
&& string
->s
)) ? string
->schars
: ZV
;
3638 if (charpos
>= eob
|| (string
->s
&& !STRINGP (object
)))
3641 /* It could happen that the display property or overlay was removed
3642 since we found it in compute_display_string_pos above. One way
3643 this can happen is if JIT font-lock was called (through
3644 handle_fontified_prop), and jit-lock-functions remove text
3645 properties or overlays from the portion of buffer that includes
3646 CHARPOS. Muse mode is known to do that, for example. In this
3647 case, we return -1 to the caller, to signal that no display
3648 string is actually present at CHARPOS. See bidi_fetch_char for
3649 how this is handled.
3651 An alternative would be to never look for display properties past
3652 it->stop_charpos. But neither compute_display_string_pos nor
3653 bidi_fetch_char that calls it know or care where the next
3655 if (NILP (Fget_char_property (pos
, Qdisplay
, object
)))
3658 /* Look forward for the first character where the `display' property
3660 pos
= Fnext_single_char_property_change (pos
, Qdisplay
, object
, Qnil
);
3662 return XFASTINT (pos
);
3667 /***********************************************************************
3669 ***********************************************************************/
3671 /* Handle changes in the `fontified' property of the current buffer by
3672 calling hook functions from Qfontification_functions to fontify
3675 static enum prop_handled
3676 handle_fontified_prop (struct it
*it
)
3678 Lisp_Object prop
, pos
;
3679 enum prop_handled handled
= HANDLED_NORMALLY
;
3681 if (!NILP (Vmemory_full
))
3684 /* Get the value of the `fontified' property at IT's current buffer
3685 position. (The `fontified' property doesn't have a special
3686 meaning in strings.) If the value is nil, call functions from
3687 Qfontification_functions. */
3688 if (!STRINGP (it
->string
)
3690 && !NILP (Vfontification_functions
)
3691 && !NILP (Vrun_hooks
)
3692 && (pos
= make_number (IT_CHARPOS (*it
)),
3693 prop
= Fget_char_property (pos
, Qfontified
, Qnil
),
3694 /* Ignore the special cased nil value always present at EOB since
3695 no amount of fontifying will be able to change it. */
3696 NILP (prop
) && IT_CHARPOS (*it
) < Z
))
3698 ptrdiff_t count
= SPECPDL_INDEX ();
3700 struct buffer
*obuf
= current_buffer
;
3701 ptrdiff_t begv
= BEGV
, zv
= ZV
;
3702 bool old_clip_changed
= current_buffer
->clip_changed
;
3704 val
= Vfontification_functions
;
3705 specbind (Qfontification_functions
, Qnil
);
3707 eassert (it
->end_charpos
== ZV
);
3709 if (!CONSP (val
) || EQ (XCAR (val
), Qlambda
))
3710 safe_call1 (val
, pos
);
3713 Lisp_Object fns
, fn
;
3714 struct gcpro gcpro1
, gcpro2
;
3719 for (; CONSP (val
); val
= XCDR (val
))
3725 /* A value of t indicates this hook has a local
3726 binding; it means to run the global binding too.
3727 In a global value, t should not occur. If it
3728 does, we must ignore it to avoid an endless
3730 for (fns
= Fdefault_value (Qfontification_functions
);
3736 safe_call1 (fn
, pos
);
3740 safe_call1 (fn
, pos
);
3746 unbind_to (count
, Qnil
);
3748 /* Fontification functions routinely call `save-restriction'.
3749 Normally, this tags clip_changed, which can confuse redisplay
3750 (see discussion in Bug#6671). Since we don't perform any
3751 special handling of fontification changes in the case where
3752 `save-restriction' isn't called, there's no point doing so in
3753 this case either. So, if the buffer's restrictions are
3754 actually left unchanged, reset clip_changed. */
3755 if (obuf
== current_buffer
)
3757 if (begv
== BEGV
&& zv
== ZV
)
3758 current_buffer
->clip_changed
= old_clip_changed
;
3760 /* There isn't much we can reasonably do to protect against
3761 misbehaving fontification, but here's a fig leaf. */
3762 else if (BUFFER_LIVE_P (obuf
))
3763 set_buffer_internal_1 (obuf
);
3765 /* The fontification code may have added/removed text.
3766 It could do even a lot worse, but let's at least protect against
3767 the most obvious case where only the text past `pos' gets changed',
3768 as is/was done in grep.el where some escapes sequences are turned
3769 into face properties (bug#7876). */
3770 it
->end_charpos
= ZV
;
3772 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3773 something. This avoids an endless loop if they failed to
3774 fontify the text for which reason ever. */
3775 if (!NILP (Fget_char_property (pos
, Qfontified
, Qnil
)))
3776 handled
= HANDLED_RECOMPUTE_PROPS
;
3784 /***********************************************************************
3786 ***********************************************************************/
3788 /* Set up iterator IT from face properties at its current position.
3789 Called from handle_stop. */
3791 static enum prop_handled
3792 handle_face_prop (struct it
*it
)
3795 ptrdiff_t next_stop
;
3797 if (!STRINGP (it
->string
))
3800 = face_at_buffer_position (it
->w
,
3804 + TEXT_PROP_DISTANCE_LIMIT
),
3805 0, it
->base_face_id
);
3807 /* Is this a start of a run of characters with box face?
3808 Caveat: this can be called for a freshly initialized
3809 iterator; face_id is -1 in this case. We know that the new
3810 face will not change until limit, i.e. if the new face has a
3811 box, all characters up to limit will have one. But, as
3812 usual, we don't know whether limit is really the end. */
3813 if (new_face_id
!= it
->face_id
)
3815 struct face
*new_face
= FACE_FROM_ID (it
->f
, new_face_id
);
3816 /* If it->face_id is -1, old_face below will be NULL, see
3817 the definition of FACE_FROM_ID. This will happen if this
3818 is the initial call that gets the face. */
3819 struct face
*old_face
= FACE_FROM_ID (it
->f
, it
->face_id
);
3821 /* If the value of face_id of the iterator is -1, we have to
3822 look in front of IT's position and see whether there is a
3823 face there that's different from new_face_id. */
3824 if (!old_face
&& IT_CHARPOS (*it
) > BEG
)
3826 int prev_face_id
= face_before_it_pos (it
);
3828 old_face
= FACE_FROM_ID (it
->f
, prev_face_id
);
3831 /* If the new face has a box, but the old face does not,
3832 this is the start of a run of characters with box face,
3833 i.e. this character has a shadow on the left side. */
3834 it
->start_of_box_run_p
= (new_face
->box
!= FACE_NO_BOX
3835 && (old_face
== NULL
|| !old_face
->box
));
3836 it
->face_box_p
= new_face
->box
!= FACE_NO_BOX
;
3844 Lisp_Object from_overlay
3845 = (it
->current
.overlay_string_index
>= 0
3846 ? it
->string_overlays
[it
->current
.overlay_string_index
3847 % OVERLAY_STRING_CHUNK_SIZE
]
3850 /* See if we got to this string directly or indirectly from
3851 an overlay property. That includes the before-string or
3852 after-string of an overlay, strings in display properties
3853 provided by an overlay, their text properties, etc.
3855 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
3856 if (! NILP (from_overlay
))
3857 for (i
= it
->sp
- 1; i
>= 0; i
--)
3859 if (it
->stack
[i
].current
.overlay_string_index
>= 0)
3861 = it
->string_overlays
[it
->stack
[i
].current
.overlay_string_index
3862 % OVERLAY_STRING_CHUNK_SIZE
];
3863 else if (! NILP (it
->stack
[i
].from_overlay
))
3864 from_overlay
= it
->stack
[i
].from_overlay
;
3866 if (!NILP (from_overlay
))
3870 if (! NILP (from_overlay
))
3872 bufpos
= IT_CHARPOS (*it
);
3873 /* For a string from an overlay, the base face depends
3874 only on text properties and ignores overlays. */
3876 = face_for_overlay_string (it
->w
,
3880 + TEXT_PROP_DISTANCE_LIMIT
),
3888 /* For strings from a `display' property, use the face at
3889 IT's current buffer position as the base face to merge
3890 with, so that overlay strings appear in the same face as
3891 surrounding text, unless they specify their own faces.
3892 For strings from wrap-prefix and line-prefix properties,
3893 use the default face, possibly remapped via
3894 Vface_remapping_alist. */
3895 base_face_id
= it
->string_from_prefix_prop_p
3896 ? (!NILP (Vface_remapping_alist
)
3897 ? lookup_basic_face (it
->f
, DEFAULT_FACE_ID
)
3899 : underlying_face_id (it
);
3902 new_face_id
= face_at_string_position (it
->w
,
3904 IT_STRING_CHARPOS (*it
),
3909 /* Is this a start of a run of characters with box? Caveat:
3910 this can be called for a freshly allocated iterator; face_id
3911 is -1 is this case. We know that the new face will not
3912 change until the next check pos, i.e. if the new face has a
3913 box, all characters up to that position will have a
3914 box. But, as usual, we don't know whether that position
3915 is really the end. */
3916 if (new_face_id
!= it
->face_id
)
3918 struct face
*new_face
= FACE_FROM_ID (it
->f
, new_face_id
);
3919 struct face
*old_face
= FACE_FROM_ID (it
->f
, it
->face_id
);
3921 /* If new face has a box but old face hasn't, this is the
3922 start of a run of characters with box, i.e. it has a
3923 shadow on the left side. */
3924 it
->start_of_box_run_p
3925 = new_face
->box
&& (old_face
== NULL
|| !old_face
->box
);
3926 it
->face_box_p
= new_face
->box
!= FACE_NO_BOX
;
3930 it
->face_id
= new_face_id
;
3931 return HANDLED_NORMALLY
;
3935 /* Return the ID of the face ``underlying'' IT's current position,
3936 which is in a string. If the iterator is associated with a
3937 buffer, return the face at IT's current buffer position.
3938 Otherwise, use the iterator's base_face_id. */
3941 underlying_face_id (struct it
*it
)
3943 int face_id
= it
->base_face_id
, i
;
3945 eassert (STRINGP (it
->string
));
3947 for (i
= it
->sp
- 1; i
>= 0; --i
)
3948 if (NILP (it
->stack
[i
].string
))
3949 face_id
= it
->stack
[i
].face_id
;
3955 /* Compute the face one character before or after the current position
3956 of IT, in the visual order. BEFORE_P non-zero means get the face
3957 in front (to the left in L2R paragraphs, to the right in R2L
3958 paragraphs) of IT's screen position. Value is the ID of the face. */
3961 face_before_or_after_it_pos (struct it
*it
, int before_p
)
3964 ptrdiff_t next_check_charpos
;
3966 void *it_copy_data
= NULL
;
3968 eassert (it
->s
== NULL
);
3970 if (STRINGP (it
->string
))
3972 ptrdiff_t bufpos
, charpos
;
3975 /* No face change past the end of the string (for the case
3976 we are padding with spaces). No face change before the
3978 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
)
3979 || (IT_STRING_CHARPOS (*it
) == 0 && before_p
))
3984 /* Set charpos to the position before or after IT's current
3985 position, in the logical order, which in the non-bidi
3986 case is the same as the visual order. */
3988 charpos
= IT_STRING_CHARPOS (*it
) - 1;
3989 else if (it
->what
== IT_COMPOSITION
)
3990 /* For composition, we must check the character after the
3992 charpos
= IT_STRING_CHARPOS (*it
) + it
->cmp_it
.nchars
;
3994 charpos
= IT_STRING_CHARPOS (*it
) + 1;
4000 /* With bidi iteration, the character before the current
4001 in the visual order cannot be found by simple
4002 iteration, because "reverse" reordering is not
4003 supported. Instead, we need to use the move_it_*
4004 family of functions. */
4005 /* Ignore face changes before the first visible
4006 character on this display line. */
4007 if (it
->current_x
<= it
->first_visible_x
)
4009 SAVE_IT (it_copy
, *it
, it_copy_data
);
4010 /* Implementation note: Since move_it_in_display_line
4011 works in the iterator geometry, and thinks the first
4012 character is always the leftmost, even in R2L lines,
4013 we don't need to distinguish between the R2L and L2R
4015 move_it_in_display_line (&it_copy
, SCHARS (it_copy
.string
),
4016 it_copy
.current_x
- 1, MOVE_TO_X
);
4017 charpos
= IT_STRING_CHARPOS (it_copy
);
4018 RESTORE_IT (it
, it
, it_copy_data
);
4022 /* Set charpos to the string position of the character
4023 that comes after IT's current position in the visual
4025 int n
= (it
->what
== IT_COMPOSITION
? it
->cmp_it
.nchars
: 1);
4029 bidi_move_to_visually_next (&it_copy
.bidi_it
);
4031 charpos
= it_copy
.bidi_it
.charpos
;
4034 eassert (0 <= charpos
&& charpos
<= SCHARS (it
->string
));
4036 if (it
->current
.overlay_string_index
>= 0)
4037 bufpos
= IT_CHARPOS (*it
);
4041 base_face_id
= underlying_face_id (it
);
4043 /* Get the face for ASCII, or unibyte. */
4044 face_id
= face_at_string_position (it
->w
,
4048 &next_check_charpos
,
4051 /* Correct the face for charsets different from ASCII. Do it
4052 for the multibyte case only. The face returned above is
4053 suitable for unibyte text if IT->string is unibyte. */
4054 if (STRING_MULTIBYTE (it
->string
))
4056 struct text_pos pos1
= string_pos (charpos
, it
->string
);
4057 const unsigned char *p
= SDATA (it
->string
) + BYTEPOS (pos1
);
4059 struct face
*face
= FACE_FROM_ID (it
->f
, face_id
);
4061 c
= string_char_and_length (p
, &len
);
4062 face_id
= FACE_FOR_CHAR (it
->f
, face
, c
, charpos
, it
->string
);
4067 struct text_pos pos
;
4069 if ((IT_CHARPOS (*it
) >= ZV
&& !before_p
)
4070 || (IT_CHARPOS (*it
) <= BEGV
&& before_p
))
4073 limit
= IT_CHARPOS (*it
) + TEXT_PROP_DISTANCE_LIMIT
;
4074 pos
= it
->current
.pos
;
4079 DEC_TEXT_POS (pos
, it
->multibyte_p
);
4082 if (it
->what
== IT_COMPOSITION
)
4084 /* For composition, we must check the position after
4086 pos
.charpos
+= it
->cmp_it
.nchars
;
4087 pos
.bytepos
+= it
->len
;
4090 INC_TEXT_POS (pos
, it
->multibyte_p
);
4097 /* With bidi iteration, the character before the current
4098 in the visual order cannot be found by simple
4099 iteration, because "reverse" reordering is not
4100 supported. Instead, we need to use the move_it_*
4101 family of functions. */
4102 /* Ignore face changes before the first visible
4103 character on this display line. */
4104 if (it
->current_x
<= it
->first_visible_x
)
4106 SAVE_IT (it_copy
, *it
, it_copy_data
);
4107 /* Implementation note: Since move_it_in_display_line
4108 works in the iterator geometry, and thinks the first
4109 character is always the leftmost, even in R2L lines,
4110 we don't need to distinguish between the R2L and L2R
4112 move_it_in_display_line (&it_copy
, ZV
,
4113 it_copy
.current_x
- 1, MOVE_TO_X
);
4114 pos
= it_copy
.current
.pos
;
4115 RESTORE_IT (it
, it
, it_copy_data
);
4119 /* Set charpos to the buffer position of the character
4120 that comes after IT's current position in the visual
4122 int n
= (it
->what
== IT_COMPOSITION
? it
->cmp_it
.nchars
: 1);
4126 bidi_move_to_visually_next (&it_copy
.bidi_it
);
4129 it_copy
.bidi_it
.charpos
, it_copy
.bidi_it
.bytepos
);
4132 eassert (BEGV
<= CHARPOS (pos
) && CHARPOS (pos
) <= ZV
);
4134 /* Determine face for CHARSET_ASCII, or unibyte. */
4135 face_id
= face_at_buffer_position (it
->w
,
4137 &next_check_charpos
,
4140 /* Correct the face for charsets different from ASCII. Do it
4141 for the multibyte case only. The face returned above is
4142 suitable for unibyte text if current_buffer is unibyte. */
4143 if (it
->multibyte_p
)
4145 int c
= FETCH_MULTIBYTE_CHAR (BYTEPOS (pos
));
4146 struct face
*face
= FACE_FROM_ID (it
->f
, face_id
);
4147 face_id
= FACE_FOR_CHAR (it
->f
, face
, c
, CHARPOS (pos
), Qnil
);
4156 /***********************************************************************
4158 ***********************************************************************/
4160 /* Set up iterator IT from invisible properties at its current
4161 position. Called from handle_stop. */
4163 static enum prop_handled
4164 handle_invisible_prop (struct it
*it
)
4166 enum prop_handled handled
= HANDLED_NORMALLY
;
4170 if (STRINGP (it
->string
))
4172 Lisp_Object end_charpos
, limit
, charpos
;
4174 /* Get the value of the invisible text property at the
4175 current position. Value will be nil if there is no such
4177 charpos
= make_number (IT_STRING_CHARPOS (*it
));
4178 prop
= Fget_text_property (charpos
, Qinvisible
, it
->string
);
4179 invis_p
= TEXT_PROP_MEANS_INVISIBLE (prop
);
4181 if (invis_p
&& IT_STRING_CHARPOS (*it
) < it
->end_charpos
)
4183 /* Record whether we have to display an ellipsis for the
4185 int display_ellipsis_p
= (invis_p
== 2);
4186 ptrdiff_t len
, endpos
;
4188 handled
= HANDLED_RECOMPUTE_PROPS
;
4190 /* Get the position at which the next visible text can be
4191 found in IT->string, if any. */
4192 endpos
= len
= SCHARS (it
->string
);
4193 XSETINT (limit
, len
);
4196 end_charpos
= Fnext_single_property_change (charpos
, Qinvisible
,
4198 if (INTEGERP (end_charpos
))
4200 endpos
= XFASTINT (end_charpos
);
4201 prop
= Fget_text_property (end_charpos
, Qinvisible
, it
->string
);
4202 invis_p
= TEXT_PROP_MEANS_INVISIBLE (prop
);
4204 display_ellipsis_p
= 1;
4207 while (invis_p
&& endpos
< len
);
4209 if (display_ellipsis_p
)
4214 /* Text at END_CHARPOS is visible. Move IT there. */
4215 struct text_pos old
;
4218 old
= it
->current
.string_pos
;
4219 oldpos
= CHARPOS (old
);
4222 if (it
->bidi_it
.first_elt
4223 && it
->bidi_it
.charpos
< SCHARS (it
->string
))
4224 bidi_paragraph_init (it
->paragraph_embedding
,
4226 /* Bidi-iterate out of the invisible text. */
4229 bidi_move_to_visually_next (&it
->bidi_it
);
4231 while (oldpos
<= it
->bidi_it
.charpos
4232 && it
->bidi_it
.charpos
< endpos
);
4234 IT_STRING_CHARPOS (*it
) = it
->bidi_it
.charpos
;
4235 IT_STRING_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
4236 if (IT_CHARPOS (*it
) >= endpos
)
4237 it
->prev_stop
= endpos
;
4241 IT_STRING_CHARPOS (*it
) = XFASTINT (end_charpos
);
4242 compute_string_pos (&it
->current
.string_pos
, old
, it
->string
);
4247 /* The rest of the string is invisible. If this is an
4248 overlay string, proceed with the next overlay string
4249 or whatever comes and return a character from there. */
4250 if (it
->current
.overlay_string_index
>= 0
4251 && !display_ellipsis_p
)
4253 next_overlay_string (it
);
4254 /* Don't check for overlay strings when we just
4255 finished processing them. */
4256 handled
= HANDLED_OVERLAY_STRING_CONSUMED
;
4260 IT_STRING_CHARPOS (*it
) = SCHARS (it
->string
);
4261 IT_STRING_BYTEPOS (*it
) = SBYTES (it
->string
);
4268 ptrdiff_t newpos
, next_stop
, start_charpos
, tem
;
4269 Lisp_Object pos
, overlay
;
4271 /* First of all, is there invisible text at this position? */
4272 tem
= start_charpos
= IT_CHARPOS (*it
);
4273 pos
= make_number (tem
);
4274 prop
= get_char_property_and_overlay (pos
, Qinvisible
, it
->window
,
4276 invis_p
= TEXT_PROP_MEANS_INVISIBLE (prop
);
4278 /* If we are on invisible text, skip over it. */
4279 if (invis_p
&& start_charpos
< it
->end_charpos
)
4281 /* Record whether we have to display an ellipsis for the
4283 int display_ellipsis_p
= invis_p
== 2;
4285 handled
= HANDLED_RECOMPUTE_PROPS
;
4287 /* Loop skipping over invisible text. The loop is left at
4288 ZV or with IT on the first char being visible again. */
4291 /* Try to skip some invisible text. Return value is the
4292 position reached which can be equal to where we start
4293 if there is nothing invisible there. This skips both
4294 over invisible text properties and overlays with
4295 invisible property. */
4296 newpos
= skip_invisible (tem
, &next_stop
, ZV
, it
->window
);
4298 /* If we skipped nothing at all we weren't at invisible
4299 text in the first place. If everything to the end of
4300 the buffer was skipped, end the loop. */
4301 if (newpos
== tem
|| newpos
>= ZV
)
4305 /* We skipped some characters but not necessarily
4306 all there are. Check if we ended up on visible
4307 text. Fget_char_property returns the property of
4308 the char before the given position, i.e. if we
4309 get invis_p = 0, this means that the char at
4310 newpos is visible. */
4311 pos
= make_number (newpos
);
4312 prop
= Fget_char_property (pos
, Qinvisible
, it
->window
);
4313 invis_p
= TEXT_PROP_MEANS_INVISIBLE (prop
);
4316 /* If we ended up on invisible text, proceed to
4317 skip starting with next_stop. */
4321 /* If there are adjacent invisible texts, don't lose the
4322 second one's ellipsis. */
4324 display_ellipsis_p
= 1;
4328 /* The position newpos is now either ZV or on visible text. */
4331 ptrdiff_t bpos
= CHAR_TO_BYTE (newpos
);
4333 bpos
== ZV_BYTE
|| FETCH_BYTE (bpos
) == '\n';
4335 newpos
<= BEGV
|| FETCH_BYTE (bpos
- 1) == '\n';
4337 /* If the invisible text ends on a newline or on a
4338 character after a newline, we can avoid the costly,
4339 character by character, bidi iteration to NEWPOS, and
4340 instead simply reseat the iterator there. That's
4341 because all bidi reordering information is tossed at
4342 the newline. This is a big win for modes that hide
4343 complete lines, like Outline, Org, etc. */
4344 if (on_newline
|| after_newline
)
4346 struct text_pos tpos
;
4347 bidi_dir_t pdir
= it
->bidi_it
.paragraph_dir
;
4349 SET_TEXT_POS (tpos
, newpos
, bpos
);
4350 reseat_1 (it
, tpos
, 0);
4351 /* If we reseat on a newline/ZV, we need to prep the
4352 bidi iterator for advancing to the next character
4353 after the newline/EOB, keeping the current paragraph
4354 direction (so that PRODUCE_GLYPHS does TRT wrt
4355 prepending/appending glyphs to a glyph row). */
4358 it
->bidi_it
.first_elt
= 0;
4359 it
->bidi_it
.paragraph_dir
= pdir
;
4360 it
->bidi_it
.ch
= (bpos
== ZV_BYTE
) ? -1 : '\n';
4361 it
->bidi_it
.nchars
= 1;
4362 it
->bidi_it
.ch_len
= 1;
4365 else /* Must use the slow method. */
4367 /* With bidi iteration, the region of invisible text
4368 could start and/or end in the middle of a
4369 non-base embedding level. Therefore, we need to
4370 skip invisible text using the bidi iterator,
4371 starting at IT's current position, until we find
4372 ourselves outside of the invisible text.
4373 Skipping invisible text _after_ bidi iteration
4374 avoids affecting the visual order of the
4375 displayed text when invisible properties are
4376 added or removed. */
4377 if (it
->bidi_it
.first_elt
&& it
->bidi_it
.charpos
< ZV
)
4379 /* If we were `reseat'ed to a new paragraph,
4380 determine the paragraph base direction. We
4381 need to do it now because
4382 next_element_from_buffer may not have a
4383 chance to do it, if we are going to skip any
4384 text at the beginning, which resets the
4386 bidi_paragraph_init (it
->paragraph_embedding
,
4391 bidi_move_to_visually_next (&it
->bidi_it
);
4393 while (it
->stop_charpos
<= it
->bidi_it
.charpos
4394 && it
->bidi_it
.charpos
< newpos
);
4395 IT_CHARPOS (*it
) = it
->bidi_it
.charpos
;
4396 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
4397 /* If we overstepped NEWPOS, record its position in
4398 the iterator, so that we skip invisible text if
4399 later the bidi iteration lands us in the
4400 invisible region again. */
4401 if (IT_CHARPOS (*it
) >= newpos
)
4402 it
->prev_stop
= newpos
;
4407 IT_CHARPOS (*it
) = newpos
;
4408 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (newpos
);
4411 /* If there are before-strings at the start of invisible
4412 text, and the text is invisible because of a text
4413 property, arrange to show before-strings because 20.x did
4414 it that way. (If the text is invisible because of an
4415 overlay property instead of a text property, this is
4416 already handled in the overlay code.) */
4418 && get_overlay_strings (it
, it
->stop_charpos
))
4420 handled
= HANDLED_RECOMPUTE_PROPS
;
4421 it
->stack
[it
->sp
- 1].display_ellipsis_p
= display_ellipsis_p
;
4423 else if (display_ellipsis_p
)
4425 /* Make sure that the glyphs of the ellipsis will get
4426 correct `charpos' values. If we would not update
4427 it->position here, the glyphs would belong to the
4428 last visible character _before_ the invisible
4429 text, which confuses `set_cursor_from_row'.
4431 We use the last invisible position instead of the
4432 first because this way the cursor is always drawn on
4433 the first "." of the ellipsis, whenever PT is inside
4434 the invisible text. Otherwise the cursor would be
4435 placed _after_ the ellipsis when the point is after the
4436 first invisible character. */
4437 if (!STRINGP (it
->object
))
4439 it
->position
.charpos
= newpos
- 1;
4440 it
->position
.bytepos
= CHAR_TO_BYTE (it
->position
.charpos
);
4443 /* Let the ellipsis display before
4444 considering any properties of the following char.
4445 Fixes jasonr@gnu.org 01 Oct 07 bug. */
4446 handled
= HANDLED_RETURN
;
4455 /* Make iterator IT return `...' next.
4456 Replaces LEN characters from buffer. */
4459 setup_for_ellipsis (struct it
*it
, int len
)
4461 /* Use the display table definition for `...'. Invalid glyphs
4462 will be handled by the method returning elements from dpvec. */
4463 if (it
->dp
&& VECTORP (DISP_INVIS_VECTOR (it
->dp
)))
4465 struct Lisp_Vector
*v
= XVECTOR (DISP_INVIS_VECTOR (it
->dp
));
4466 it
->dpvec
= v
->contents
;
4467 it
->dpend
= v
->contents
+ v
->header
.size
;
4471 /* Default `...'. */
4472 it
->dpvec
= default_invis_vector
;
4473 it
->dpend
= default_invis_vector
+ 3;
4476 it
->dpvec_char_len
= len
;
4477 it
->current
.dpvec_index
= 0;
4478 it
->dpvec_face_id
= -1;
4480 /* Remember the current face id in case glyphs specify faces.
4481 IT's face is restored in set_iterator_to_next.
4482 saved_face_id was set to preceding char's face in handle_stop. */
4483 if (it
->saved_face_id
< 0 || it
->saved_face_id
!= it
->face_id
)
4484 it
->saved_face_id
= it
->face_id
= DEFAULT_FACE_ID
;
4486 it
->method
= GET_FROM_DISPLAY_VECTOR
;
4492 /***********************************************************************
4494 ***********************************************************************/
4496 /* Set up iterator IT from `display' property at its current position.
4497 Called from handle_stop.
4498 We return HANDLED_RETURN if some part of the display property
4499 overrides the display of the buffer text itself.
4500 Otherwise we return HANDLED_NORMALLY. */
4502 static enum prop_handled
4503 handle_display_prop (struct it
*it
)
4505 Lisp_Object propval
, object
, overlay
;
4506 struct text_pos
*position
;
4508 /* Nonzero if some property replaces the display of the text itself. */
4509 int display_replaced_p
= 0;
4511 if (STRINGP (it
->string
))
4513 object
= it
->string
;
4514 position
= &it
->current
.string_pos
;
4515 bufpos
= CHARPOS (it
->current
.pos
);
4519 XSETWINDOW (object
, it
->w
);
4520 position
= &it
->current
.pos
;
4521 bufpos
= CHARPOS (*position
);
4524 /* Reset those iterator values set from display property values. */
4525 it
->slice
.x
= it
->slice
.y
= it
->slice
.width
= it
->slice
.height
= Qnil
;
4526 it
->space_width
= Qnil
;
4527 it
->font_height
= Qnil
;
4530 /* We don't support recursive `display' properties, i.e. string
4531 values that have a string `display' property, that have a string
4532 `display' property etc. */
4533 if (!it
->string_from_display_prop_p
)
4534 it
->area
= TEXT_AREA
;
4536 propval
= get_char_property_and_overlay (make_number (position
->charpos
),
4537 Qdisplay
, object
, &overlay
);
4539 return HANDLED_NORMALLY
;
4540 /* Now OVERLAY is the overlay that gave us this property, or nil
4541 if it was a text property. */
4543 if (!STRINGP (it
->string
))
4544 object
= it
->w
->contents
;
4546 display_replaced_p
= handle_display_spec (it
, propval
, object
, overlay
,
4548 FRAME_WINDOW_P (it
->f
));
4550 return display_replaced_p
? HANDLED_RETURN
: HANDLED_NORMALLY
;
4553 /* Subroutine of handle_display_prop. Returns non-zero if the display
4554 specification in SPEC is a replacing specification, i.e. it would
4555 replace the text covered by `display' property with something else,
4556 such as an image or a display string. If SPEC includes any kind or
4557 `(space ...) specification, the value is 2; this is used by
4558 compute_display_string_pos, which see.
4560 See handle_single_display_spec for documentation of arguments.
4561 frame_window_p is non-zero if the window being redisplayed is on a
4562 GUI frame; this argument is used only if IT is NULL, see below.
4564 IT can be NULL, if this is called by the bidi reordering code
4565 through compute_display_string_pos, which see. In that case, this
4566 function only examines SPEC, but does not otherwise "handle" it, in
4567 the sense that it doesn't set up members of IT from the display
4570 handle_display_spec (struct it
*it
, Lisp_Object spec
, Lisp_Object object
,
4571 Lisp_Object overlay
, struct text_pos
*position
,
4572 ptrdiff_t bufpos
, int frame_window_p
)
4574 int replacing_p
= 0;
4578 /* Simple specifications. */
4579 && !EQ (XCAR (spec
), Qimage
)
4580 && !EQ (XCAR (spec
), Qspace
)
4581 && !EQ (XCAR (spec
), Qwhen
)
4582 && !EQ (XCAR (spec
), Qslice
)
4583 && !EQ (XCAR (spec
), Qspace_width
)
4584 && !EQ (XCAR (spec
), Qheight
)
4585 && !EQ (XCAR (spec
), Qraise
)
4586 /* Marginal area specifications. */
4587 && !(CONSP (XCAR (spec
)) && EQ (XCAR (XCAR (spec
)), Qmargin
))
4588 && !EQ (XCAR (spec
), Qleft_fringe
)
4589 && !EQ (XCAR (spec
), Qright_fringe
)
4590 && !NILP (XCAR (spec
)))
4592 for (; CONSP (spec
); spec
= XCDR (spec
))
4594 if ((rv
= handle_single_display_spec (it
, XCAR (spec
), object
,
4595 overlay
, position
, bufpos
,
4596 replacing_p
, frame_window_p
)))
4599 /* If some text in a string is replaced, `position' no
4600 longer points to the position of `object'. */
4601 if (!it
|| STRINGP (object
))
4606 else if (VECTORP (spec
))
4609 for (i
= 0; i
< ASIZE (spec
); ++i
)
4610 if ((rv
= handle_single_display_spec (it
, AREF (spec
, i
), object
,
4611 overlay
, position
, bufpos
,
4612 replacing_p
, frame_window_p
)))
4615 /* If some text in a string is replaced, `position' no
4616 longer points to the position of `object'. */
4617 if (!it
|| STRINGP (object
))
4623 if ((rv
= handle_single_display_spec (it
, spec
, object
, overlay
,
4624 position
, bufpos
, 0,
4632 /* Value is the position of the end of the `display' property starting
4633 at START_POS in OBJECT. */
4635 static struct text_pos
4636 display_prop_end (struct it
*it
, Lisp_Object object
, struct text_pos start_pos
)
4639 struct text_pos end_pos
;
4641 end
= Fnext_single_char_property_change (make_number (CHARPOS (start_pos
)),
4642 Qdisplay
, object
, Qnil
);
4643 CHARPOS (end_pos
) = XFASTINT (end
);
4644 if (STRINGP (object
))
4645 compute_string_pos (&end_pos
, start_pos
, it
->string
);
4647 BYTEPOS (end_pos
) = CHAR_TO_BYTE (XFASTINT (end
));
4653 /* Set up IT from a single `display' property specification SPEC. OBJECT
4654 is the object in which the `display' property was found. *POSITION
4655 is the position in OBJECT at which the `display' property was found.
4656 BUFPOS is the buffer position of OBJECT (different from POSITION if
4657 OBJECT is not a buffer). DISPLAY_REPLACED_P non-zero means that we
4658 previously saw a display specification which already replaced text
4659 display with something else, for example an image; we ignore such
4660 properties after the first one has been processed.
4662 OVERLAY is the overlay this `display' property came from,
4663 or nil if it was a text property.
4665 If SPEC is a `space' or `image' specification, and in some other
4666 cases too, set *POSITION to the position where the `display'
4669 If IT is NULL, only examine the property specification in SPEC, but
4670 don't set up IT. In that case, FRAME_WINDOW_P non-zero means SPEC
4671 is intended to be displayed in a window on a GUI frame.
4673 Value is non-zero if something was found which replaces the display
4674 of buffer or string text. */
4677 handle_single_display_spec (struct it
*it
, Lisp_Object spec
, Lisp_Object object
,
4678 Lisp_Object overlay
, struct text_pos
*position
,
4679 ptrdiff_t bufpos
, int display_replaced_p
,
4683 Lisp_Object location
, value
;
4684 struct text_pos start_pos
= *position
;
4687 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4688 If the result is non-nil, use VALUE instead of SPEC. */
4690 if (CONSP (spec
) && EQ (XCAR (spec
), Qwhen
))
4699 if (!NILP (form
) && !EQ (form
, Qt
))
4701 ptrdiff_t count
= SPECPDL_INDEX ();
4702 struct gcpro gcpro1
;
4704 /* Bind `object' to the object having the `display' property, a
4705 buffer or string. Bind `position' to the position in the
4706 object where the property was found, and `buffer-position'
4707 to the current position in the buffer. */
4710 XSETBUFFER (object
, current_buffer
);
4711 specbind (Qobject
, object
);
4712 specbind (Qposition
, make_number (CHARPOS (*position
)));
4713 specbind (Qbuffer_position
, make_number (bufpos
));
4715 form
= safe_eval (form
);
4717 unbind_to (count
, Qnil
);
4723 /* Handle `(height HEIGHT)' specifications. */
4725 && EQ (XCAR (spec
), Qheight
)
4726 && CONSP (XCDR (spec
)))
4730 if (!FRAME_WINDOW_P (it
->f
))
4733 it
->font_height
= XCAR (XCDR (spec
));
4734 if (!NILP (it
->font_height
))
4736 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
4737 int new_height
= -1;
4739 if (CONSP (it
->font_height
)
4740 && (EQ (XCAR (it
->font_height
), Qplus
)
4741 || EQ (XCAR (it
->font_height
), Qminus
))
4742 && CONSP (XCDR (it
->font_height
))
4743 && RANGED_INTEGERP (0, XCAR (XCDR (it
->font_height
)), INT_MAX
))
4745 /* `(+ N)' or `(- N)' where N is an integer. */
4746 int steps
= XINT (XCAR (XCDR (it
->font_height
)));
4747 if (EQ (XCAR (it
->font_height
), Qplus
))
4749 it
->face_id
= smaller_face (it
->f
, it
->face_id
, steps
);
4751 else if (FUNCTIONP (it
->font_height
))
4753 /* Call function with current height as argument.
4754 Value is the new height. */
4756 height
= safe_call1 (it
->font_height
,
4757 face
->lface
[LFACE_HEIGHT_INDEX
]);
4758 if (NUMBERP (height
))
4759 new_height
= XFLOATINT (height
);
4761 else if (NUMBERP (it
->font_height
))
4763 /* Value is a multiple of the canonical char height. */
4766 f
= FACE_FROM_ID (it
->f
,
4767 lookup_basic_face (it
->f
, DEFAULT_FACE_ID
));
4768 new_height
= (XFLOATINT (it
->font_height
)
4769 * XINT (f
->lface
[LFACE_HEIGHT_INDEX
]));
4773 /* Evaluate IT->font_height with `height' bound to the
4774 current specified height to get the new height. */
4775 ptrdiff_t count
= SPECPDL_INDEX ();
4777 specbind (Qheight
, face
->lface
[LFACE_HEIGHT_INDEX
]);
4778 value
= safe_eval (it
->font_height
);
4779 unbind_to (count
, Qnil
);
4781 if (NUMBERP (value
))
4782 new_height
= XFLOATINT (value
);
4786 it
->face_id
= face_with_height (it
->f
, it
->face_id
, new_height
);
4793 /* Handle `(space-width WIDTH)'. */
4795 && EQ (XCAR (spec
), Qspace_width
)
4796 && CONSP (XCDR (spec
)))
4800 if (!FRAME_WINDOW_P (it
->f
))
4803 value
= XCAR (XCDR (spec
));
4804 if (NUMBERP (value
) && XFLOATINT (value
) > 0)
4805 it
->space_width
= value
;
4811 /* Handle `(slice X Y WIDTH HEIGHT)'. */
4813 && EQ (XCAR (spec
), Qslice
))
4819 if (!FRAME_WINDOW_P (it
->f
))
4822 if (tem
= XCDR (spec
), CONSP (tem
))
4824 it
->slice
.x
= XCAR (tem
);
4825 if (tem
= XCDR (tem
), CONSP (tem
))
4827 it
->slice
.y
= XCAR (tem
);
4828 if (tem
= XCDR (tem
), CONSP (tem
))
4830 it
->slice
.width
= XCAR (tem
);
4831 if (tem
= XCDR (tem
), CONSP (tem
))
4832 it
->slice
.height
= XCAR (tem
);
4841 /* Handle `(raise FACTOR)'. */
4843 && EQ (XCAR (spec
), Qraise
)
4844 && CONSP (XCDR (spec
)))
4848 if (!FRAME_WINDOW_P (it
->f
))
4851 #ifdef HAVE_WINDOW_SYSTEM
4852 value
= XCAR (XCDR (spec
));
4853 if (NUMBERP (value
))
4855 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
4856 it
->voffset
= - (XFLOATINT (value
)
4857 * (FONT_HEIGHT (face
->font
)));
4859 #endif /* HAVE_WINDOW_SYSTEM */
4865 /* Don't handle the other kinds of display specifications
4866 inside a string that we got from a `display' property. */
4867 if (it
&& it
->string_from_display_prop_p
)
4870 /* Characters having this form of property are not displayed, so
4871 we have to find the end of the property. */
4874 start_pos
= *position
;
4875 *position
= display_prop_end (it
, object
, start_pos
);
4879 /* Stop the scan at that end position--we assume that all
4880 text properties change there. */
4882 it
->stop_charpos
= position
->charpos
;
4884 /* Handle `(left-fringe BITMAP [FACE])'
4885 and `(right-fringe BITMAP [FACE])'. */
4887 && (EQ (XCAR (spec
), Qleft_fringe
)
4888 || EQ (XCAR (spec
), Qright_fringe
))
4889 && CONSP (XCDR (spec
)))
4895 if (!FRAME_WINDOW_P (it
->f
))
4896 /* If we return here, POSITION has been advanced
4897 across the text with this property. */
4899 /* Synchronize the bidi iterator with POSITION. This is
4900 needed because we are not going to push the iterator
4901 on behalf of this display property, so there will be
4902 no pop_it call to do this synchronization for us. */
4905 it
->position
= *position
;
4906 iterate_out_of_display_property (it
);
4907 *position
= it
->position
;
4912 else if (!frame_window_p
)
4915 #ifdef HAVE_WINDOW_SYSTEM
4916 value
= XCAR (XCDR (spec
));
4917 if (!SYMBOLP (value
)
4918 || !(fringe_bitmap
= lookup_fringe_bitmap (value
)))
4919 /* If we return here, POSITION has been advanced
4920 across the text with this property. */
4922 if (it
&& it
->bidi_p
)
4924 it
->position
= *position
;
4925 iterate_out_of_display_property (it
);
4926 *position
= it
->position
;
4933 int face_id
= lookup_basic_face (it
->f
, DEFAULT_FACE_ID
);;
4935 if (CONSP (XCDR (XCDR (spec
))))
4937 Lisp_Object face_name
= XCAR (XCDR (XCDR (spec
)));
4938 int face_id2
= lookup_derived_face (it
->f
, face_name
,
4944 /* Save current settings of IT so that we can restore them
4945 when we are finished with the glyph property value. */
4946 push_it (it
, position
);
4948 it
->area
= TEXT_AREA
;
4949 it
->what
= IT_IMAGE
;
4950 it
->image_id
= -1; /* no image */
4951 it
->position
= start_pos
;
4952 it
->object
= NILP (object
) ? it
->w
->contents
: object
;
4953 it
->method
= GET_FROM_IMAGE
;
4954 it
->from_overlay
= Qnil
;
4955 it
->face_id
= face_id
;
4956 it
->from_disp_prop_p
= 1;
4958 /* Say that we haven't consumed the characters with
4959 `display' property yet. The call to pop_it in
4960 set_iterator_to_next will clean this up. */
4961 *position
= start_pos
;
4963 if (EQ (XCAR (spec
), Qleft_fringe
))
4965 it
->left_user_fringe_bitmap
= fringe_bitmap
;
4966 it
->left_user_fringe_face_id
= face_id
;
4970 it
->right_user_fringe_bitmap
= fringe_bitmap
;
4971 it
->right_user_fringe_face_id
= face_id
;
4974 #endif /* HAVE_WINDOW_SYSTEM */
4978 /* Prepare to handle `((margin left-margin) ...)',
4979 `((margin right-margin) ...)' and `((margin nil) ...)'
4980 prefixes for display specifications. */
4981 location
= Qunbound
;
4982 if (CONSP (spec
) && CONSP (XCAR (spec
)))
4986 value
= XCDR (spec
);
4988 value
= XCAR (value
);
4991 if (EQ (XCAR (tem
), Qmargin
)
4992 && (tem
= XCDR (tem
),
4993 tem
= CONSP (tem
) ? XCAR (tem
) : Qnil
,
4995 || EQ (tem
, Qleft_margin
)
4996 || EQ (tem
, Qright_margin
))))
5000 if (EQ (location
, Qunbound
))
5006 /* After this point, VALUE is the property after any
5007 margin prefix has been stripped. It must be a string,
5008 an image specification, or `(space ...)'.
5010 LOCATION specifies where to display: `left-margin',
5011 `right-margin' or nil. */
5013 valid_p
= (STRINGP (value
)
5014 #ifdef HAVE_WINDOW_SYSTEM
5015 || ((it
? FRAME_WINDOW_P (it
->f
) : frame_window_p
)
5016 && valid_image_p (value
))
5017 #endif /* not HAVE_WINDOW_SYSTEM */
5018 || (CONSP (value
) && EQ (XCAR (value
), Qspace
)));
5020 if (valid_p
&& !display_replaced_p
)
5026 /* Callers need to know whether the display spec is any kind
5027 of `(space ...)' spec that is about to affect text-area
5029 if (CONSP (value
) && EQ (XCAR (value
), Qspace
) && NILP (location
))
5034 /* Save current settings of IT so that we can restore them
5035 when we are finished with the glyph property value. */
5036 push_it (it
, position
);
5037 it
->from_overlay
= overlay
;
5038 it
->from_disp_prop_p
= 1;
5040 if (NILP (location
))
5041 it
->area
= TEXT_AREA
;
5042 else if (EQ (location
, Qleft_margin
))
5043 it
->area
= LEFT_MARGIN_AREA
;
5045 it
->area
= RIGHT_MARGIN_AREA
;
5047 if (STRINGP (value
))
5050 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
5051 it
->current
.overlay_string_index
= -1;
5052 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = 0;
5053 it
->end_charpos
= it
->string_nchars
= SCHARS (it
->string
);
5054 it
->method
= GET_FROM_STRING
;
5055 it
->stop_charpos
= 0;
5057 it
->base_level_stop
= 0;
5058 it
->string_from_display_prop_p
= 1;
5059 /* Say that we haven't consumed the characters with
5060 `display' property yet. The call to pop_it in
5061 set_iterator_to_next will clean this up. */
5062 if (BUFFERP (object
))
5063 *position
= start_pos
;
5065 /* Force paragraph direction to be that of the parent
5066 object. If the parent object's paragraph direction is
5067 not yet determined, default to L2R. */
5068 if (it
->bidi_p
&& it
->bidi_it
.paragraph_dir
== R2L
)
5069 it
->paragraph_embedding
= it
->bidi_it
.paragraph_dir
;
5071 it
->paragraph_embedding
= L2R
;
5073 /* Set up the bidi iterator for this display string. */
5076 it
->bidi_it
.string
.lstring
= it
->string
;
5077 it
->bidi_it
.string
.s
= NULL
;
5078 it
->bidi_it
.string
.schars
= it
->end_charpos
;
5079 it
->bidi_it
.string
.bufpos
= bufpos
;
5080 it
->bidi_it
.string
.from_disp_str
= 1;
5081 it
->bidi_it
.string
.unibyte
= !it
->multibyte_p
;
5082 it
->bidi_it
.w
= it
->w
;
5083 bidi_init_it (0, 0, FRAME_WINDOW_P (it
->f
), &it
->bidi_it
);
5086 else if (CONSP (value
) && EQ (XCAR (value
), Qspace
))
5088 it
->method
= GET_FROM_STRETCH
;
5090 *position
= it
->position
= start_pos
;
5091 retval
= 1 + (it
->area
== TEXT_AREA
);
5093 #ifdef HAVE_WINDOW_SYSTEM
5096 it
->what
= IT_IMAGE
;
5097 it
->image_id
= lookup_image (it
->f
, value
);
5098 it
->position
= start_pos
;
5099 it
->object
= NILP (object
) ? it
->w
->contents
: object
;
5100 it
->method
= GET_FROM_IMAGE
;
5102 /* Say that we haven't consumed the characters with
5103 `display' property yet. The call to pop_it in
5104 set_iterator_to_next will clean this up. */
5105 *position
= start_pos
;
5107 #endif /* HAVE_WINDOW_SYSTEM */
5112 /* Invalid property or property not supported. Restore
5113 POSITION to what it was before. */
5114 *position
= start_pos
;
5118 /* Check if PROP is a display property value whose text should be
5119 treated as intangible. OVERLAY is the overlay from which PROP
5120 came, or nil if it came from a text property. CHARPOS and BYTEPOS
5121 specify the buffer position covered by PROP. */
5124 display_prop_intangible_p (Lisp_Object prop
, Lisp_Object overlay
,
5125 ptrdiff_t charpos
, ptrdiff_t bytepos
)
5127 int frame_window_p
= FRAME_WINDOW_P (XFRAME (selected_frame
));
5128 struct text_pos position
;
5130 SET_TEXT_POS (position
, charpos
, bytepos
);
5131 return handle_display_spec (NULL
, prop
, Qnil
, overlay
,
5132 &position
, charpos
, frame_window_p
);
5136 /* Return 1 if PROP is a display sub-property value containing STRING.
5138 Implementation note: this and the following function are really
5139 special cases of handle_display_spec and
5140 handle_single_display_spec, and should ideally use the same code.
5141 Until they do, these two pairs must be consistent and must be
5142 modified in sync. */
5145 single_display_spec_string_p (Lisp_Object prop
, Lisp_Object string
)
5147 if (EQ (string
, prop
))
5150 /* Skip over `when FORM'. */
5151 if (CONSP (prop
) && EQ (XCAR (prop
), Qwhen
))
5156 /* Actually, the condition following `when' should be eval'ed,
5157 like handle_single_display_spec does, and we should return
5158 zero if it evaluates to nil. However, this function is
5159 called only when the buffer was already displayed and some
5160 glyph in the glyph matrix was found to come from a display
5161 string. Therefore, the condition was already evaluated, and
5162 the result was non-nil, otherwise the display string wouldn't
5163 have been displayed and we would have never been called for
5164 this property. Thus, we can skip the evaluation and assume
5165 its result is non-nil. */
5170 /* Skip over `margin LOCATION'. */
5171 if (EQ (XCAR (prop
), Qmargin
))
5182 return EQ (prop
, string
) || (CONSP (prop
) && EQ (XCAR (prop
), string
));
5186 /* Return 1 if STRING appears in the `display' property PROP. */
5189 display_prop_string_p (Lisp_Object prop
, Lisp_Object string
)
5192 && !EQ (XCAR (prop
), Qwhen
)
5193 && !(CONSP (XCAR (prop
)) && EQ (Qmargin
, XCAR (XCAR (prop
)))))
5195 /* A list of sub-properties. */
5196 while (CONSP (prop
))
5198 if (single_display_spec_string_p (XCAR (prop
), string
))
5203 else if (VECTORP (prop
))
5205 /* A vector of sub-properties. */
5207 for (i
= 0; i
< ASIZE (prop
); ++i
)
5208 if (single_display_spec_string_p (AREF (prop
, i
), string
))
5212 return single_display_spec_string_p (prop
, string
);
5217 /* Look for STRING in overlays and text properties in the current
5218 buffer, between character positions FROM and TO (excluding TO).
5219 BACK_P non-zero means look back (in this case, TO is supposed to be
5221 Value is the first character position where STRING was found, or
5222 zero if it wasn't found before hitting TO.
5224 This function may only use code that doesn't eval because it is
5225 called asynchronously from note_mouse_highlight. */
5228 string_buffer_position_lim (Lisp_Object string
,
5229 ptrdiff_t from
, ptrdiff_t to
, int back_p
)
5231 Lisp_Object limit
, prop
, pos
;
5234 pos
= make_number (max (from
, BEGV
));
5236 if (!back_p
) /* looking forward */
5238 limit
= make_number (min (to
, ZV
));
5239 while (!found
&& !EQ (pos
, limit
))
5241 prop
= Fget_char_property (pos
, Qdisplay
, Qnil
);
5242 if (!NILP (prop
) && display_prop_string_p (prop
, string
))
5245 pos
= Fnext_single_char_property_change (pos
, Qdisplay
, Qnil
,
5249 else /* looking back */
5251 limit
= make_number (max (to
, BEGV
));
5252 while (!found
&& !EQ (pos
, limit
))
5254 prop
= Fget_char_property (pos
, Qdisplay
, Qnil
);
5255 if (!NILP (prop
) && display_prop_string_p (prop
, string
))
5258 pos
= Fprevious_single_char_property_change (pos
, Qdisplay
, Qnil
,
5263 return found
? XINT (pos
) : 0;
5266 /* Determine which buffer position in current buffer STRING comes from.
5267 AROUND_CHARPOS is an approximate position where it could come from.
5268 Value is the buffer position or 0 if it couldn't be determined.
5270 This function is necessary because we don't record buffer positions
5271 in glyphs generated from strings (to keep struct glyph small).
5272 This function may only use code that doesn't eval because it is
5273 called asynchronously from note_mouse_highlight. */
5276 string_buffer_position (Lisp_Object string
, ptrdiff_t around_charpos
)
5278 const int MAX_DISTANCE
= 1000;
5279 ptrdiff_t found
= string_buffer_position_lim (string
, around_charpos
,
5280 around_charpos
+ MAX_DISTANCE
,
5284 found
= string_buffer_position_lim (string
, around_charpos
,
5285 around_charpos
- MAX_DISTANCE
, 1);
5291 /***********************************************************************
5292 `composition' property
5293 ***********************************************************************/
5295 /* Set up iterator IT from `composition' property at its current
5296 position. Called from handle_stop. */
5298 static enum prop_handled
5299 handle_composition_prop (struct it
*it
)
5301 Lisp_Object prop
, string
;
5302 ptrdiff_t pos
, pos_byte
, start
, end
;
5304 if (STRINGP (it
->string
))
5308 pos
= IT_STRING_CHARPOS (*it
);
5309 pos_byte
= IT_STRING_BYTEPOS (*it
);
5310 string
= it
->string
;
5311 s
= SDATA (string
) + pos_byte
;
5312 it
->c
= STRING_CHAR (s
);
5316 pos
= IT_CHARPOS (*it
);
5317 pos_byte
= IT_BYTEPOS (*it
);
5319 it
->c
= FETCH_CHAR (pos_byte
);
5322 /* If there's a valid composition and point is not inside of the
5323 composition (in the case that the composition is from the current
5324 buffer), draw a glyph composed from the composition components. */
5325 if (find_composition (pos
, -1, &start
, &end
, &prop
, string
)
5326 && composition_valid_p (start
, end
, prop
)
5327 && (STRINGP (it
->string
) || (PT
<= start
|| PT
>= end
)))
5330 /* As we can't handle this situation (perhaps font-lock added
5331 a new composition), we just return here hoping that next
5332 redisplay will detect this composition much earlier. */
5333 return HANDLED_NORMALLY
;
5336 if (STRINGP (it
->string
))
5337 pos_byte
= string_char_to_byte (it
->string
, start
);
5339 pos_byte
= CHAR_TO_BYTE (start
);
5341 it
->cmp_it
.id
= get_composition_id (start
, pos_byte
, end
- start
,
5344 if (it
->cmp_it
.id
>= 0)
5347 it
->cmp_it
.nchars
= COMPOSITION_LENGTH (prop
);
5348 it
->cmp_it
.nglyphs
= -1;
5352 return HANDLED_NORMALLY
;
5357 /***********************************************************************
5359 ***********************************************************************/
5361 /* The following structure is used to record overlay strings for
5362 later sorting in load_overlay_strings. */
5364 struct overlay_entry
5366 Lisp_Object overlay
;
5373 /* Set up iterator IT from overlay strings at its current position.
5374 Called from handle_stop. */
5376 static enum prop_handled
5377 handle_overlay_change (struct it
*it
)
5379 if (!STRINGP (it
->string
) && get_overlay_strings (it
, 0))
5380 return HANDLED_RECOMPUTE_PROPS
;
5382 return HANDLED_NORMALLY
;
5386 /* Set up the next overlay string for delivery by IT, if there is an
5387 overlay string to deliver. Called by set_iterator_to_next when the
5388 end of the current overlay string is reached. If there are more
5389 overlay strings to display, IT->string and
5390 IT->current.overlay_string_index are set appropriately here.
5391 Otherwise IT->string is set to nil. */
5394 next_overlay_string (struct it
*it
)
5396 ++it
->current
.overlay_string_index
;
5397 if (it
->current
.overlay_string_index
== it
->n_overlay_strings
)
5399 /* No more overlay strings. Restore IT's settings to what
5400 they were before overlay strings were processed, and
5401 continue to deliver from current_buffer. */
5403 it
->ellipsis_p
= (it
->stack
[it
->sp
- 1].display_ellipsis_p
!= 0);
5406 || (NILP (it
->string
)
5407 && it
->method
== GET_FROM_BUFFER
5408 && it
->stop_charpos
>= BEGV
5409 && it
->stop_charpos
<= it
->end_charpos
));
5410 it
->current
.overlay_string_index
= -1;
5411 it
->n_overlay_strings
= 0;
5412 it
->overlay_strings_charpos
= -1;
5413 /* If there's an empty display string on the stack, pop the
5414 stack, to resync the bidi iterator with IT's position. Such
5415 empty strings are pushed onto the stack in
5416 get_overlay_strings_1. */
5417 if (it
->sp
> 0 && STRINGP (it
->string
) && !SCHARS (it
->string
))
5420 /* If we're at the end of the buffer, record that we have
5421 processed the overlay strings there already, so that
5422 next_element_from_buffer doesn't try it again. */
5423 if (NILP (it
->string
) && IT_CHARPOS (*it
) >= it
->end_charpos
)
5424 it
->overlay_strings_at_end_processed_p
= 1;
5428 /* There are more overlay strings to process. If
5429 IT->current.overlay_string_index has advanced to a position
5430 where we must load IT->overlay_strings with more strings, do
5431 it. We must load at the IT->overlay_strings_charpos where
5432 IT->n_overlay_strings was originally computed; when invisible
5433 text is present, this might not be IT_CHARPOS (Bug#7016). */
5434 int i
= it
->current
.overlay_string_index
% OVERLAY_STRING_CHUNK_SIZE
;
5436 if (it
->current
.overlay_string_index
&& i
== 0)
5437 load_overlay_strings (it
, it
->overlay_strings_charpos
);
5439 /* Initialize IT to deliver display elements from the overlay
5441 it
->string
= it
->overlay_strings
[i
];
5442 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
5443 SET_TEXT_POS (it
->current
.string_pos
, 0, 0);
5444 it
->method
= GET_FROM_STRING
;
5445 it
->stop_charpos
= 0;
5446 it
->end_charpos
= SCHARS (it
->string
);
5447 if (it
->cmp_it
.stop_pos
>= 0)
5448 it
->cmp_it
.stop_pos
= 0;
5450 it
->base_level_stop
= 0;
5452 /* Set up the bidi iterator for this overlay string. */
5455 it
->bidi_it
.string
.lstring
= it
->string
;
5456 it
->bidi_it
.string
.s
= NULL
;
5457 it
->bidi_it
.string
.schars
= SCHARS (it
->string
);
5458 it
->bidi_it
.string
.bufpos
= it
->overlay_strings_charpos
;
5459 it
->bidi_it
.string
.from_disp_str
= it
->string_from_display_prop_p
;
5460 it
->bidi_it
.string
.unibyte
= !it
->multibyte_p
;
5461 it
->bidi_it
.w
= it
->w
;
5462 bidi_init_it (0, 0, FRAME_WINDOW_P (it
->f
), &it
->bidi_it
);
5470 /* Compare two overlay_entry structures E1 and E2. Used as a
5471 comparison function for qsort in load_overlay_strings. Overlay
5472 strings for the same position are sorted so that
5474 1. All after-strings come in front of before-strings, except
5475 when they come from the same overlay.
5477 2. Within after-strings, strings are sorted so that overlay strings
5478 from overlays with higher priorities come first.
5480 2. Within before-strings, strings are sorted so that overlay
5481 strings from overlays with higher priorities come last.
5483 Value is analogous to strcmp. */
5487 compare_overlay_entries (const void *e1
, const void *e2
)
5489 struct overlay_entry
const *entry1
= e1
;
5490 struct overlay_entry
const *entry2
= e2
;
5493 if (entry1
->after_string_p
!= entry2
->after_string_p
)
5495 /* Let after-strings appear in front of before-strings if
5496 they come from different overlays. */
5497 if (EQ (entry1
->overlay
, entry2
->overlay
))
5498 result
= entry1
->after_string_p
? 1 : -1;
5500 result
= entry1
->after_string_p
? -1 : 1;
5502 else if (entry1
->priority
!= entry2
->priority
)
5504 if (entry1
->after_string_p
)
5505 /* After-strings sorted in order of decreasing priority. */
5506 result
= entry2
->priority
< entry1
->priority
? -1 : 1;
5508 /* Before-strings sorted in order of increasing priority. */
5509 result
= entry1
->priority
< entry2
->priority
? -1 : 1;
5518 /* Load the vector IT->overlay_strings with overlay strings from IT's
5519 current buffer position, or from CHARPOS if that is > 0. Set
5520 IT->n_overlays to the total number of overlay strings found.
5522 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
5523 a time. On entry into load_overlay_strings,
5524 IT->current.overlay_string_index gives the number of overlay
5525 strings that have already been loaded by previous calls to this
5528 IT->add_overlay_start contains an additional overlay start
5529 position to consider for taking overlay strings from, if non-zero.
5530 This position comes into play when the overlay has an `invisible'
5531 property, and both before and after-strings. When we've skipped to
5532 the end of the overlay, because of its `invisible' property, we
5533 nevertheless want its before-string to appear.
5534 IT->add_overlay_start will contain the overlay start position
5537 Overlay strings are sorted so that after-string strings come in
5538 front of before-string strings. Within before and after-strings,
5539 strings are sorted by overlay priority. See also function
5540 compare_overlay_entries. */
5543 load_overlay_strings (struct it
*it
, ptrdiff_t charpos
)
5545 Lisp_Object overlay
, window
, str
, invisible
;
5546 struct Lisp_Overlay
*ov
;
5547 ptrdiff_t start
, end
;
5548 ptrdiff_t size
= 20;
5549 ptrdiff_t n
= 0, i
, j
;
5551 struct overlay_entry
*entries
= alloca (size
* sizeof *entries
);
5555 charpos
= IT_CHARPOS (*it
);
5557 /* Append the overlay string STRING of overlay OVERLAY to vector
5558 `entries' which has size `size' and currently contains `n'
5559 elements. AFTER_P non-zero means STRING is an after-string of
5561 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
5564 Lisp_Object priority; \
5568 struct overlay_entry *old = entries; \
5569 SAFE_NALLOCA (entries, 2, size); \
5570 memcpy (entries, old, size * sizeof *entries); \
5574 entries[n].string = (STRING); \
5575 entries[n].overlay = (OVERLAY); \
5576 priority = Foverlay_get ((OVERLAY), Qpriority); \
5577 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
5578 entries[n].after_string_p = (AFTER_P); \
5583 /* Process overlay before the overlay center. */
5584 for (ov
= current_buffer
->overlays_before
; ov
; ov
= ov
->next
)
5586 XSETMISC (overlay
, ov
);
5587 eassert (OVERLAYP (overlay
));
5588 start
= OVERLAY_POSITION (OVERLAY_START (overlay
));
5589 end
= OVERLAY_POSITION (OVERLAY_END (overlay
));
5594 /* Skip this overlay if it doesn't start or end at IT's current
5596 if (end
!= charpos
&& start
!= charpos
)
5599 /* Skip this overlay if it doesn't apply to IT->w. */
5600 window
= Foverlay_get (overlay
, Qwindow
);
5601 if (WINDOWP (window
) && XWINDOW (window
) != it
->w
)
5604 /* If the text ``under'' the overlay is invisible, both before-
5605 and after-strings from this overlay are visible; start and
5606 end position are indistinguishable. */
5607 invisible
= Foverlay_get (overlay
, Qinvisible
);
5608 invis_p
= TEXT_PROP_MEANS_INVISIBLE (invisible
);
5610 /* If overlay has a non-empty before-string, record it. */
5611 if ((start
== charpos
|| (end
== charpos
&& invis_p
))
5612 && (str
= Foverlay_get (overlay
, Qbefore_string
), STRINGP (str
))
5614 RECORD_OVERLAY_STRING (overlay
, str
, 0);
5616 /* If overlay has a non-empty after-string, record it. */
5617 if ((end
== charpos
|| (start
== charpos
&& invis_p
))
5618 && (str
= Foverlay_get (overlay
, Qafter_string
), STRINGP (str
))
5620 RECORD_OVERLAY_STRING (overlay
, str
, 1);
5623 /* Process overlays after the overlay center. */
5624 for (ov
= current_buffer
->overlays_after
; ov
; ov
= ov
->next
)
5626 XSETMISC (overlay
, ov
);
5627 eassert (OVERLAYP (overlay
));
5628 start
= OVERLAY_POSITION (OVERLAY_START (overlay
));
5629 end
= OVERLAY_POSITION (OVERLAY_END (overlay
));
5631 if (start
> charpos
)
5634 /* Skip this overlay if it doesn't start or end at IT's current
5636 if (end
!= charpos
&& start
!= charpos
)
5639 /* Skip this overlay if it doesn't apply to IT->w. */
5640 window
= Foverlay_get (overlay
, Qwindow
);
5641 if (WINDOWP (window
) && XWINDOW (window
) != it
->w
)
5644 /* If the text ``under'' the overlay is invisible, it has a zero
5645 dimension, and both before- and after-strings apply. */
5646 invisible
= Foverlay_get (overlay
, Qinvisible
);
5647 invis_p
= TEXT_PROP_MEANS_INVISIBLE (invisible
);
5649 /* If overlay has a non-empty before-string, record it. */
5650 if ((start
== charpos
|| (end
== charpos
&& invis_p
))
5651 && (str
= Foverlay_get (overlay
, Qbefore_string
), STRINGP (str
))
5653 RECORD_OVERLAY_STRING (overlay
, str
, 0);
5655 /* If overlay has a non-empty after-string, record it. */
5656 if ((end
== charpos
|| (start
== charpos
&& invis_p
))
5657 && (str
= Foverlay_get (overlay
, Qafter_string
), STRINGP (str
))
5659 RECORD_OVERLAY_STRING (overlay
, str
, 1);
5662 #undef RECORD_OVERLAY_STRING
5666 qsort (entries
, n
, sizeof *entries
, compare_overlay_entries
);
5668 /* Record number of overlay strings, and where we computed it. */
5669 it
->n_overlay_strings
= n
;
5670 it
->overlay_strings_charpos
= charpos
;
5672 /* IT->current.overlay_string_index is the number of overlay strings
5673 that have already been consumed by IT. Copy some of the
5674 remaining overlay strings to IT->overlay_strings. */
5676 j
= it
->current
.overlay_string_index
;
5677 while (i
< OVERLAY_STRING_CHUNK_SIZE
&& j
< n
)
5679 it
->overlay_strings
[i
] = entries
[j
].string
;
5680 it
->string_overlays
[i
++] = entries
[j
++].overlay
;
5688 /* Get the first chunk of overlay strings at IT's current buffer
5689 position, or at CHARPOS if that is > 0. Value is non-zero if at
5690 least one overlay string was found. */
5693 get_overlay_strings_1 (struct it
*it
, ptrdiff_t charpos
, int compute_stop_p
)
5695 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
5696 process. This fills IT->overlay_strings with strings, and sets
5697 IT->n_overlay_strings to the total number of strings to process.
5698 IT->pos.overlay_string_index has to be set temporarily to zero
5699 because load_overlay_strings needs this; it must be set to -1
5700 when no overlay strings are found because a zero value would
5701 indicate a position in the first overlay string. */
5702 it
->current
.overlay_string_index
= 0;
5703 load_overlay_strings (it
, charpos
);
5705 /* If we found overlay strings, set up IT to deliver display
5706 elements from the first one. Otherwise set up IT to deliver
5707 from current_buffer. */
5708 if (it
->n_overlay_strings
)
5710 /* Make sure we know settings in current_buffer, so that we can
5711 restore meaningful values when we're done with the overlay
5714 compute_stop_pos (it
);
5715 eassert (it
->face_id
>= 0);
5717 /* Save IT's settings. They are restored after all overlay
5718 strings have been processed. */
5719 eassert (!compute_stop_p
|| it
->sp
== 0);
5721 /* When called from handle_stop, there might be an empty display
5722 string loaded. In that case, don't bother saving it. But
5723 don't use this optimization with the bidi iterator, since we
5724 need the corresponding pop_it call to resync the bidi
5725 iterator's position with IT's position, after we are done
5726 with the overlay strings. (The corresponding call to pop_it
5727 in case of an empty display string is in
5728 next_overlay_string.) */
5730 && STRINGP (it
->string
) && !SCHARS (it
->string
)))
5733 /* Set up IT to deliver display elements from the first overlay
5735 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = 0;
5736 it
->string
= it
->overlay_strings
[0];
5737 it
->from_overlay
= Qnil
;
5738 it
->stop_charpos
= 0;
5739 eassert (STRINGP (it
->string
));
5740 it
->end_charpos
= SCHARS (it
->string
);
5742 it
->base_level_stop
= 0;
5743 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
5744 it
->method
= GET_FROM_STRING
;
5745 it
->from_disp_prop_p
= 0;
5747 /* Force paragraph direction to be that of the parent
5749 if (it
->bidi_p
&& it
->bidi_it
.paragraph_dir
== R2L
)
5750 it
->paragraph_embedding
= it
->bidi_it
.paragraph_dir
;
5752 it
->paragraph_embedding
= L2R
;
5754 /* Set up the bidi iterator for this overlay string. */
5757 ptrdiff_t pos
= (charpos
> 0 ? charpos
: IT_CHARPOS (*it
));
5759 it
->bidi_it
.string
.lstring
= it
->string
;
5760 it
->bidi_it
.string
.s
= NULL
;
5761 it
->bidi_it
.string
.schars
= SCHARS (it
->string
);
5762 it
->bidi_it
.string
.bufpos
= pos
;
5763 it
->bidi_it
.string
.from_disp_str
= it
->string_from_display_prop_p
;
5764 it
->bidi_it
.string
.unibyte
= !it
->multibyte_p
;
5765 it
->bidi_it
.w
= it
->w
;
5766 bidi_init_it (0, 0, FRAME_WINDOW_P (it
->f
), &it
->bidi_it
);
5771 it
->current
.overlay_string_index
= -1;
5776 get_overlay_strings (struct it
*it
, ptrdiff_t charpos
)
5779 it
->method
= GET_FROM_BUFFER
;
5781 (void) get_overlay_strings_1 (it
, charpos
, 1);
5785 /* Value is non-zero if we found at least one overlay string. */
5786 return STRINGP (it
->string
);
5791 /***********************************************************************
5792 Saving and restoring state
5793 ***********************************************************************/
5795 /* Save current settings of IT on IT->stack. Called, for example,
5796 before setting up IT for an overlay string, to be able to restore
5797 IT's settings to what they were after the overlay string has been
5798 processed. If POSITION is non-NULL, it is the position to save on
5799 the stack instead of IT->position. */
5802 push_it (struct it
*it
, struct text_pos
*position
)
5804 struct iterator_stack_entry
*p
;
5806 eassert (it
->sp
< IT_STACK_SIZE
);
5807 p
= it
->stack
+ it
->sp
;
5809 p
->stop_charpos
= it
->stop_charpos
;
5810 p
->prev_stop
= it
->prev_stop
;
5811 p
->base_level_stop
= it
->base_level_stop
;
5812 p
->cmp_it
= it
->cmp_it
;
5813 eassert (it
->face_id
>= 0);
5814 p
->face_id
= it
->face_id
;
5815 p
->string
= it
->string
;
5816 p
->method
= it
->method
;
5817 p
->from_overlay
= it
->from_overlay
;
5820 case GET_FROM_IMAGE
:
5821 p
->u
.image
.object
= it
->object
;
5822 p
->u
.image
.image_id
= it
->image_id
;
5823 p
->u
.image
.slice
= it
->slice
;
5825 case GET_FROM_STRETCH
:
5826 p
->u
.stretch
.object
= it
->object
;
5829 p
->position
= position
? *position
: it
->position
;
5830 p
->current
= it
->current
;
5831 p
->end_charpos
= it
->end_charpos
;
5832 p
->string_nchars
= it
->string_nchars
;
5834 p
->multibyte_p
= it
->multibyte_p
;
5835 p
->avoid_cursor_p
= it
->avoid_cursor_p
;
5836 p
->space_width
= it
->space_width
;
5837 p
->font_height
= it
->font_height
;
5838 p
->voffset
= it
->voffset
;
5839 p
->string_from_display_prop_p
= it
->string_from_display_prop_p
;
5840 p
->string_from_prefix_prop_p
= it
->string_from_prefix_prop_p
;
5841 p
->display_ellipsis_p
= 0;
5842 p
->line_wrap
= it
->line_wrap
;
5843 p
->bidi_p
= it
->bidi_p
;
5844 p
->paragraph_embedding
= it
->paragraph_embedding
;
5845 p
->from_disp_prop_p
= it
->from_disp_prop_p
;
5848 /* Save the state of the bidi iterator as well. */
5850 bidi_push_it (&it
->bidi_it
);
5854 iterate_out_of_display_property (struct it
*it
)
5856 int buffer_p
= !STRINGP (it
->string
);
5857 ptrdiff_t eob
= (buffer_p
? ZV
: it
->end_charpos
);
5858 ptrdiff_t bob
= (buffer_p
? BEGV
: 0);
5860 eassert (eob
>= CHARPOS (it
->position
) && CHARPOS (it
->position
) >= bob
);
5862 /* Maybe initialize paragraph direction. If we are at the beginning
5863 of a new paragraph, next_element_from_buffer may not have a
5864 chance to do that. */
5865 if (it
->bidi_it
.first_elt
&& it
->bidi_it
.charpos
< eob
)
5866 bidi_paragraph_init (it
->paragraph_embedding
, &it
->bidi_it
, 1);
5867 /* prev_stop can be zero, so check against BEGV as well. */
5868 while (it
->bidi_it
.charpos
>= bob
5869 && it
->prev_stop
<= it
->bidi_it
.charpos
5870 && it
->bidi_it
.charpos
< CHARPOS (it
->position
)
5871 && it
->bidi_it
.charpos
< eob
)
5872 bidi_move_to_visually_next (&it
->bidi_it
);
5873 /* Record the stop_pos we just crossed, for when we cross it
5875 if (it
->bidi_it
.charpos
> CHARPOS (it
->position
))
5876 it
->prev_stop
= CHARPOS (it
->position
);
5877 /* If we ended up not where pop_it put us, resync IT's
5878 positional members with the bidi iterator. */
5879 if (it
->bidi_it
.charpos
!= CHARPOS (it
->position
))
5880 SET_TEXT_POS (it
->position
, it
->bidi_it
.charpos
, it
->bidi_it
.bytepos
);
5882 it
->current
.pos
= it
->position
;
5884 it
->current
.string_pos
= it
->position
;
5887 /* Restore IT's settings from IT->stack. Called, for example, when no
5888 more overlay strings must be processed, and we return to delivering
5889 display elements from a buffer, or when the end of a string from a
5890 `display' property is reached and we return to delivering display
5891 elements from an overlay string, or from a buffer. */
5894 pop_it (struct it
*it
)
5896 struct iterator_stack_entry
*p
;
5897 int from_display_prop
= it
->from_disp_prop_p
;
5899 eassert (it
->sp
> 0);
5901 p
= it
->stack
+ it
->sp
;
5902 it
->stop_charpos
= p
->stop_charpos
;
5903 it
->prev_stop
= p
->prev_stop
;
5904 it
->base_level_stop
= p
->base_level_stop
;
5905 it
->cmp_it
= p
->cmp_it
;
5906 it
->face_id
= p
->face_id
;
5907 it
->current
= p
->current
;
5908 it
->position
= p
->position
;
5909 it
->string
= p
->string
;
5910 it
->from_overlay
= p
->from_overlay
;
5911 if (NILP (it
->string
))
5912 SET_TEXT_POS (it
->current
.string_pos
, -1, -1);
5913 it
->method
= p
->method
;
5916 case GET_FROM_IMAGE
:
5917 it
->image_id
= p
->u
.image
.image_id
;
5918 it
->object
= p
->u
.image
.object
;
5919 it
->slice
= p
->u
.image
.slice
;
5921 case GET_FROM_STRETCH
:
5922 it
->object
= p
->u
.stretch
.object
;
5924 case GET_FROM_BUFFER
:
5925 it
->object
= it
->w
->contents
;
5927 case GET_FROM_STRING
:
5928 it
->object
= it
->string
;
5930 case GET_FROM_DISPLAY_VECTOR
:
5932 it
->method
= GET_FROM_C_STRING
;
5933 else if (STRINGP (it
->string
))
5934 it
->method
= GET_FROM_STRING
;
5937 it
->method
= GET_FROM_BUFFER
;
5938 it
->object
= it
->w
->contents
;
5941 it
->end_charpos
= p
->end_charpos
;
5942 it
->string_nchars
= p
->string_nchars
;
5944 it
->multibyte_p
= p
->multibyte_p
;
5945 it
->avoid_cursor_p
= p
->avoid_cursor_p
;
5946 it
->space_width
= p
->space_width
;
5947 it
->font_height
= p
->font_height
;
5948 it
->voffset
= p
->voffset
;
5949 it
->string_from_display_prop_p
= p
->string_from_display_prop_p
;
5950 it
->string_from_prefix_prop_p
= p
->string_from_prefix_prop_p
;
5951 it
->line_wrap
= p
->line_wrap
;
5952 it
->bidi_p
= p
->bidi_p
;
5953 it
->paragraph_embedding
= p
->paragraph_embedding
;
5954 it
->from_disp_prop_p
= p
->from_disp_prop_p
;
5957 bidi_pop_it (&it
->bidi_it
);
5958 /* Bidi-iterate until we get out of the portion of text, if any,
5959 covered by a `display' text property or by an overlay with
5960 `display' property. (We cannot just jump there, because the
5961 internal coherency of the bidi iterator state can not be
5962 preserved across such jumps.) We also must determine the
5963 paragraph base direction if the overlay we just processed is
5964 at the beginning of a new paragraph. */
5965 if (from_display_prop
5966 && (it
->method
== GET_FROM_BUFFER
|| it
->method
== GET_FROM_STRING
))
5967 iterate_out_of_display_property (it
);
5969 eassert ((BUFFERP (it
->object
)
5970 && IT_CHARPOS (*it
) == it
->bidi_it
.charpos
5971 && IT_BYTEPOS (*it
) == it
->bidi_it
.bytepos
)
5972 || (STRINGP (it
->object
)
5973 && IT_STRING_CHARPOS (*it
) == it
->bidi_it
.charpos
5974 && IT_STRING_BYTEPOS (*it
) == it
->bidi_it
.bytepos
)
5975 || (CONSP (it
->object
) && it
->method
== GET_FROM_STRETCH
));
5981 /***********************************************************************
5983 ***********************************************************************/
5985 /* Set IT's current position to the previous line start. */
5988 back_to_previous_line_start (struct it
*it
)
5990 ptrdiff_t cp
= IT_CHARPOS (*it
), bp
= IT_BYTEPOS (*it
);
5993 IT_CHARPOS (*it
) = find_newline_no_quit (cp
, bp
, -1, &IT_BYTEPOS (*it
));
5997 /* Move IT to the next line start.
5999 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
6000 we skipped over part of the text (as opposed to moving the iterator
6001 continuously over the text). Otherwise, don't change the value
6004 If BIDI_IT_PREV is non-NULL, store into it the state of the bidi
6005 iterator on the newline, if it was found.
6007 Newlines may come from buffer text, overlay strings, or strings
6008 displayed via the `display' property. That's the reason we can't
6009 simply use find_newline_no_quit.
6011 Note that this function may not skip over invisible text that is so
6012 because of text properties and immediately follows a newline. If
6013 it would, function reseat_at_next_visible_line_start, when called
6014 from set_iterator_to_next, would effectively make invisible
6015 characters following a newline part of the wrong glyph row, which
6016 leads to wrong cursor motion. */
6019 forward_to_next_line_start (struct it
*it
, int *skipped_p
,
6020 struct bidi_it
*bidi_it_prev
)
6022 ptrdiff_t old_selective
;
6023 int newline_found_p
, n
;
6024 const int MAX_NEWLINE_DISTANCE
= 500;
6026 /* If already on a newline, just consume it to avoid unintended
6027 skipping over invisible text below. */
6028 if (it
->what
== IT_CHARACTER
6030 && CHARPOS (it
->position
) == IT_CHARPOS (*it
))
6032 if (it
->bidi_p
&& bidi_it_prev
)
6033 *bidi_it_prev
= it
->bidi_it
;
6034 set_iterator_to_next (it
, 0);
6039 /* Don't handle selective display in the following. It's (a)
6040 unnecessary because it's done by the caller, and (b) leads to an
6041 infinite recursion because next_element_from_ellipsis indirectly
6042 calls this function. */
6043 old_selective
= it
->selective
;
6046 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
6047 from buffer text. */
6048 for (n
= newline_found_p
= 0;
6049 !newline_found_p
&& n
< MAX_NEWLINE_DISTANCE
;
6050 n
+= STRINGP (it
->string
) ? 0 : 1)
6052 if (!get_next_display_element (it
))
6054 newline_found_p
= it
->what
== IT_CHARACTER
&& it
->c
== '\n';
6055 if (newline_found_p
&& it
->bidi_p
&& bidi_it_prev
)
6056 *bidi_it_prev
= it
->bidi_it
;
6057 set_iterator_to_next (it
, 0);
6060 /* If we didn't find a newline near enough, see if we can use a
6062 if (!newline_found_p
)
6064 ptrdiff_t bytepos
, start
= IT_CHARPOS (*it
);
6065 ptrdiff_t limit
= find_newline_no_quit (start
, IT_BYTEPOS (*it
),
6069 eassert (!STRINGP (it
->string
));
6071 /* If there isn't any `display' property in sight, and no
6072 overlays, we can just use the position of the newline in
6074 if (it
->stop_charpos
>= limit
6075 || ((pos
= Fnext_single_property_change (make_number (start
),
6077 make_number (limit
)),
6079 && next_overlay_change (start
) == ZV
))
6083 IT_CHARPOS (*it
) = limit
;
6084 IT_BYTEPOS (*it
) = bytepos
;
6088 struct bidi_it bprev
;
6090 /* Help bidi.c avoid expensive searches for display
6091 properties and overlays, by telling it that there are
6092 none up to `limit'. */
6093 if (it
->bidi_it
.disp_pos
< limit
)
6095 it
->bidi_it
.disp_pos
= limit
;
6096 it
->bidi_it
.disp_prop
= 0;
6099 bprev
= it
->bidi_it
;
6100 bidi_move_to_visually_next (&it
->bidi_it
);
6101 } while (it
->bidi_it
.charpos
!= limit
);
6102 IT_CHARPOS (*it
) = limit
;
6103 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
6105 *bidi_it_prev
= bprev
;
6107 *skipped_p
= newline_found_p
= 1;
6111 while (get_next_display_element (it
)
6112 && !newline_found_p
)
6114 newline_found_p
= ITERATOR_AT_END_OF_LINE_P (it
);
6115 if (newline_found_p
&& it
->bidi_p
&& bidi_it_prev
)
6116 *bidi_it_prev
= it
->bidi_it
;
6117 set_iterator_to_next (it
, 0);
6122 it
->selective
= old_selective
;
6123 return newline_found_p
;
6127 /* Set IT's current position to the previous visible line start. Skip
6128 invisible text that is so either due to text properties or due to
6129 selective display. Caution: this does not change IT->current_x and
6133 back_to_previous_visible_line_start (struct it
*it
)
6135 while (IT_CHARPOS (*it
) > BEGV
)
6137 back_to_previous_line_start (it
);
6139 if (IT_CHARPOS (*it
) <= BEGV
)
6142 /* If selective > 0, then lines indented more than its value are
6144 if (it
->selective
> 0
6145 && indented_beyond_p (IT_CHARPOS (*it
), IT_BYTEPOS (*it
),
6149 /* Check the newline before point for invisibility. */
6152 prop
= Fget_char_property (make_number (IT_CHARPOS (*it
) - 1),
6153 Qinvisible
, it
->window
);
6154 if (TEXT_PROP_MEANS_INVISIBLE (prop
))
6158 if (IT_CHARPOS (*it
) <= BEGV
)
6163 void *it2data
= NULL
;
6166 Lisp_Object val
, overlay
;
6168 SAVE_IT (it2
, *it
, it2data
);
6170 /* If newline is part of a composition, continue from start of composition */
6171 if (find_composition (IT_CHARPOS (*it
), -1, &beg
, &end
, &val
, Qnil
)
6172 && beg
< IT_CHARPOS (*it
))
6175 /* If newline is replaced by a display property, find start of overlay
6176 or interval and continue search from that point. */
6177 pos
= --IT_CHARPOS (it2
);
6180 bidi_unshelve_cache (NULL
, 0);
6181 it2
.string_from_display_prop_p
= 0;
6182 it2
.from_disp_prop_p
= 0;
6183 if (handle_display_prop (&it2
) == HANDLED_RETURN
6184 && !NILP (val
= get_char_property_and_overlay
6185 (make_number (pos
), Qdisplay
, Qnil
, &overlay
))
6186 && (OVERLAYP (overlay
)
6187 ? (beg
= OVERLAY_POSITION (OVERLAY_START (overlay
)))
6188 : get_property_and_range (pos
, Qdisplay
, &val
, &beg
, &end
, Qnil
)))
6190 RESTORE_IT (it
, it
, it2data
);
6194 /* Newline is not replaced by anything -- so we are done. */
6195 RESTORE_IT (it
, it
, it2data
);
6201 IT_CHARPOS (*it
) = beg
;
6202 IT_BYTEPOS (*it
) = buf_charpos_to_bytepos (current_buffer
, beg
);
6206 it
->continuation_lines_width
= 0;
6208 eassert (IT_CHARPOS (*it
) >= BEGV
);
6209 eassert (IT_CHARPOS (*it
) == BEGV
6210 || FETCH_BYTE (IT_BYTEPOS (*it
) - 1) == '\n');
6215 /* Reseat iterator IT at the previous visible line start. Skip
6216 invisible text that is so either due to text properties or due to
6217 selective display. At the end, update IT's overlay information,
6218 face information etc. */
6221 reseat_at_previous_visible_line_start (struct it
*it
)
6223 back_to_previous_visible_line_start (it
);
6224 reseat (it
, it
->current
.pos
, 1);
6229 /* Reseat iterator IT on the next visible line start in the current
6230 buffer. ON_NEWLINE_P non-zero means position IT on the newline
6231 preceding the line start. Skip over invisible text that is so
6232 because of selective display. Compute faces, overlays etc at the
6233 new position. Note that this function does not skip over text that
6234 is invisible because of text properties. */
6237 reseat_at_next_visible_line_start (struct it
*it
, int on_newline_p
)
6239 int newline_found_p
, skipped_p
= 0;
6240 struct bidi_it bidi_it_prev
;
6242 newline_found_p
= forward_to_next_line_start (it
, &skipped_p
, &bidi_it_prev
);
6244 /* Skip over lines that are invisible because they are indented
6245 more than the value of IT->selective. */
6246 if (it
->selective
> 0)
6247 while (IT_CHARPOS (*it
) < ZV
6248 && indented_beyond_p (IT_CHARPOS (*it
), IT_BYTEPOS (*it
),
6251 eassert (IT_BYTEPOS (*it
) == BEGV
6252 || FETCH_BYTE (IT_BYTEPOS (*it
) - 1) == '\n');
6254 forward_to_next_line_start (it
, &skipped_p
, &bidi_it_prev
);
6257 /* Position on the newline if that's what's requested. */
6258 if (on_newline_p
&& newline_found_p
)
6260 if (STRINGP (it
->string
))
6262 if (IT_STRING_CHARPOS (*it
) > 0)
6266 --IT_STRING_CHARPOS (*it
);
6267 --IT_STRING_BYTEPOS (*it
);
6271 /* We need to restore the bidi iterator to the state
6272 it had on the newline, and resync the IT's
6273 position with that. */
6274 it
->bidi_it
= bidi_it_prev
;
6275 IT_STRING_CHARPOS (*it
) = it
->bidi_it
.charpos
;
6276 IT_STRING_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
6280 else if (IT_CHARPOS (*it
) > BEGV
)
6289 /* We need to restore the bidi iterator to the state it
6290 had on the newline and resync IT with that. */
6291 it
->bidi_it
= bidi_it_prev
;
6292 IT_CHARPOS (*it
) = it
->bidi_it
.charpos
;
6293 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
6295 reseat (it
, it
->current
.pos
, 0);
6299 reseat (it
, it
->current
.pos
, 0);
6306 /***********************************************************************
6307 Changing an iterator's position
6308 ***********************************************************************/
6310 /* Change IT's current position to POS in current_buffer. If FORCE_P
6311 is non-zero, always check for text properties at the new position.
6312 Otherwise, text properties are only looked up if POS >=
6313 IT->check_charpos of a property. */
6316 reseat (struct it
*it
, struct text_pos pos
, int force_p
)
6318 ptrdiff_t original_pos
= IT_CHARPOS (*it
);
6320 reseat_1 (it
, pos
, 0);
6322 /* Determine where to check text properties. Avoid doing it
6323 where possible because text property lookup is very expensive. */
6325 || CHARPOS (pos
) > it
->stop_charpos
6326 || CHARPOS (pos
) < original_pos
)
6330 /* For bidi iteration, we need to prime prev_stop and
6331 base_level_stop with our best estimations. */
6332 /* Implementation note: Of course, POS is not necessarily a
6333 stop position, so assigning prev_pos to it is a lie; we
6334 should have called compute_stop_backwards. However, if
6335 the current buffer does not include any R2L characters,
6336 that call would be a waste of cycles, because the
6337 iterator will never move back, and thus never cross this
6338 "fake" stop position. So we delay that backward search
6339 until the time we really need it, in next_element_from_buffer. */
6340 if (CHARPOS (pos
) != it
->prev_stop
)
6341 it
->prev_stop
= CHARPOS (pos
);
6342 if (CHARPOS (pos
) < it
->base_level_stop
)
6343 it
->base_level_stop
= 0; /* meaning it's unknown */
6349 it
->prev_stop
= it
->base_level_stop
= 0;
6358 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
6359 IT->stop_pos to POS, also. */
6362 reseat_1 (struct it
*it
, struct text_pos pos
, int set_stop_p
)
6364 /* Don't call this function when scanning a C string. */
6365 eassert (it
->s
== NULL
);
6367 /* POS must be a reasonable value. */
6368 eassert (CHARPOS (pos
) >= BEGV
&& CHARPOS (pos
) <= ZV
);
6370 it
->current
.pos
= it
->position
= pos
;
6371 it
->end_charpos
= ZV
;
6373 it
->current
.dpvec_index
= -1;
6374 it
->current
.overlay_string_index
= -1;
6375 IT_STRING_CHARPOS (*it
) = -1;
6376 IT_STRING_BYTEPOS (*it
) = -1;
6378 it
->method
= GET_FROM_BUFFER
;
6379 it
->object
= it
->w
->contents
;
6380 it
->area
= TEXT_AREA
;
6381 it
->multibyte_p
= !NILP (BVAR (current_buffer
, enable_multibyte_characters
));
6383 it
->string_from_display_prop_p
= 0;
6384 it
->string_from_prefix_prop_p
= 0;
6386 it
->from_disp_prop_p
= 0;
6387 it
->face_before_selective_p
= 0;
6390 bidi_init_it (IT_CHARPOS (*it
), IT_BYTEPOS (*it
), FRAME_WINDOW_P (it
->f
),
6392 bidi_unshelve_cache (NULL
, 0);
6393 it
->bidi_it
.paragraph_dir
= NEUTRAL_DIR
;
6394 it
->bidi_it
.string
.s
= NULL
;
6395 it
->bidi_it
.string
.lstring
= Qnil
;
6396 it
->bidi_it
.string
.bufpos
= 0;
6397 it
->bidi_it
.string
.unibyte
= 0;
6398 it
->bidi_it
.w
= it
->w
;
6403 it
->stop_charpos
= CHARPOS (pos
);
6404 it
->base_level_stop
= CHARPOS (pos
);
6406 /* This make the information stored in it->cmp_it invalidate. */
6411 /* Set up IT for displaying a string, starting at CHARPOS in window W.
6412 If S is non-null, it is a C string to iterate over. Otherwise,
6413 STRING gives a Lisp string to iterate over.
6415 If PRECISION > 0, don't return more then PRECISION number of
6416 characters from the string.
6418 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
6419 characters have been returned. FIELD_WIDTH < 0 means an infinite
6422 MULTIBYTE = 0 means disable processing of multibyte characters,
6423 MULTIBYTE > 0 means enable it,
6424 MULTIBYTE < 0 means use IT->multibyte_p.
6426 IT must be initialized via a prior call to init_iterator before
6427 calling this function. */
6430 reseat_to_string (struct it
*it
, const char *s
, Lisp_Object string
,
6431 ptrdiff_t charpos
, ptrdiff_t precision
, int field_width
,
6434 /* No text property checks performed by default, but see below. */
6435 it
->stop_charpos
= -1;
6437 /* Set iterator position and end position. */
6438 memset (&it
->current
, 0, sizeof it
->current
);
6439 it
->current
.overlay_string_index
= -1;
6440 it
->current
.dpvec_index
= -1;
6441 eassert (charpos
>= 0);
6443 /* If STRING is specified, use its multibyteness, otherwise use the
6444 setting of MULTIBYTE, if specified. */
6446 it
->multibyte_p
= multibyte
> 0;
6448 /* Bidirectional reordering of strings is controlled by the default
6449 value of bidi-display-reordering. Don't try to reorder while
6450 loading loadup.el, as the necessary character property tables are
6451 not yet available. */
6454 && !NILP (BVAR (&buffer_defaults
, bidi_display_reordering
));
6458 eassert (STRINGP (string
));
6459 it
->string
= string
;
6461 it
->end_charpos
= it
->string_nchars
= SCHARS (string
);
6462 it
->method
= GET_FROM_STRING
;
6463 it
->current
.string_pos
= string_pos (charpos
, string
);
6467 it
->bidi_it
.string
.lstring
= string
;
6468 it
->bidi_it
.string
.s
= NULL
;
6469 it
->bidi_it
.string
.schars
= it
->end_charpos
;
6470 it
->bidi_it
.string
.bufpos
= 0;
6471 it
->bidi_it
.string
.from_disp_str
= 0;
6472 it
->bidi_it
.string
.unibyte
= !it
->multibyte_p
;
6473 it
->bidi_it
.w
= it
->w
;
6474 bidi_init_it (charpos
, IT_STRING_BYTEPOS (*it
),
6475 FRAME_WINDOW_P (it
->f
), &it
->bidi_it
);
6480 it
->s
= (const unsigned char *) s
;
6483 /* Note that we use IT->current.pos, not it->current.string_pos,
6484 for displaying C strings. */
6485 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = -1;
6486 if (it
->multibyte_p
)
6488 it
->current
.pos
= c_string_pos (charpos
, s
, 1);
6489 it
->end_charpos
= it
->string_nchars
= number_of_chars (s
, 1);
6493 IT_CHARPOS (*it
) = IT_BYTEPOS (*it
) = charpos
;
6494 it
->end_charpos
= it
->string_nchars
= strlen (s
);
6499 it
->bidi_it
.string
.lstring
= Qnil
;
6500 it
->bidi_it
.string
.s
= (const unsigned char *) s
;
6501 it
->bidi_it
.string
.schars
= it
->end_charpos
;
6502 it
->bidi_it
.string
.bufpos
= 0;
6503 it
->bidi_it
.string
.from_disp_str
= 0;
6504 it
->bidi_it
.string
.unibyte
= !it
->multibyte_p
;
6505 it
->bidi_it
.w
= it
->w
;
6506 bidi_init_it (charpos
, IT_BYTEPOS (*it
), FRAME_WINDOW_P (it
->f
),
6509 it
->method
= GET_FROM_C_STRING
;
6512 /* PRECISION > 0 means don't return more than PRECISION characters
6514 if (precision
> 0 && it
->end_charpos
- charpos
> precision
)
6516 it
->end_charpos
= it
->string_nchars
= charpos
+ precision
;
6518 it
->bidi_it
.string
.schars
= it
->end_charpos
;
6521 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
6522 characters have been returned. FIELD_WIDTH == 0 means don't pad,
6523 FIELD_WIDTH < 0 means infinite field width. This is useful for
6524 padding with `-' at the end of a mode line. */
6525 if (field_width
< 0)
6526 field_width
= INFINITY
;
6527 /* Implementation note: We deliberately don't enlarge
6528 it->bidi_it.string.schars here to fit it->end_charpos, because
6529 the bidi iterator cannot produce characters out of thin air. */
6530 if (field_width
> it
->end_charpos
- charpos
)
6531 it
->end_charpos
= charpos
+ field_width
;
6533 /* Use the standard display table for displaying strings. */
6534 if (DISP_TABLE_P (Vstandard_display_table
))
6535 it
->dp
= XCHAR_TABLE (Vstandard_display_table
);
6537 it
->stop_charpos
= charpos
;
6538 it
->prev_stop
= charpos
;
6539 it
->base_level_stop
= 0;
6542 it
->bidi_it
.first_elt
= 1;
6543 it
->bidi_it
.paragraph_dir
= NEUTRAL_DIR
;
6544 it
->bidi_it
.disp_pos
= -1;
6546 if (s
== NULL
&& it
->multibyte_p
)
6548 ptrdiff_t endpos
= SCHARS (it
->string
);
6549 if (endpos
> it
->end_charpos
)
6550 endpos
= it
->end_charpos
;
6551 composition_compute_stop_pos (&it
->cmp_it
, charpos
, -1, endpos
,
6559 /***********************************************************************
6561 ***********************************************************************/
6563 /* Map enum it_method value to corresponding next_element_from_* function. */
6565 static int (* get_next_element
[NUM_IT_METHODS
]) (struct it
*it
) =
6567 next_element_from_buffer
,
6568 next_element_from_display_vector
,
6569 next_element_from_string
,
6570 next_element_from_c_string
,
6571 next_element_from_image
,
6572 next_element_from_stretch
6575 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
6578 /* Return 1 iff a character at CHARPOS (and BYTEPOS) is composed
6579 (possibly with the following characters). */
6581 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS) \
6582 ((IT)->cmp_it.id >= 0 \
6583 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
6584 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
6585 END_CHARPOS, (IT)->w, \
6586 FACE_FROM_ID ((IT)->f, (IT)->face_id), \
6590 /* Lookup the char-table Vglyphless_char_display for character C (-1
6591 if we want information for no-font case), and return the display
6592 method symbol. By side-effect, update it->what and
6593 it->glyphless_method. This function is called from
6594 get_next_display_element for each character element, and from
6595 x_produce_glyphs when no suitable font was found. */
6598 lookup_glyphless_char_display (int c
, struct it
*it
)
6600 Lisp_Object glyphless_method
= Qnil
;
6602 if (CHAR_TABLE_P (Vglyphless_char_display
)
6603 && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display
)) >= 1)
6607 glyphless_method
= CHAR_TABLE_REF (Vglyphless_char_display
, c
);
6608 if (CONSP (glyphless_method
))
6609 glyphless_method
= FRAME_WINDOW_P (it
->f
)
6610 ? XCAR (glyphless_method
)
6611 : XCDR (glyphless_method
);
6614 glyphless_method
= XCHAR_TABLE (Vglyphless_char_display
)->extras
[0];
6618 if (NILP (glyphless_method
))
6621 /* The default is to display the character by a proper font. */
6623 /* The default for the no-font case is to display an empty box. */
6624 glyphless_method
= Qempty_box
;
6626 if (EQ (glyphless_method
, Qzero_width
))
6629 return glyphless_method
;
6630 /* This method can't be used for the no-font case. */
6631 glyphless_method
= Qempty_box
;
6633 if (EQ (glyphless_method
, Qthin_space
))
6634 it
->glyphless_method
= GLYPHLESS_DISPLAY_THIN_SPACE
;
6635 else if (EQ (glyphless_method
, Qempty_box
))
6636 it
->glyphless_method
= GLYPHLESS_DISPLAY_EMPTY_BOX
;
6637 else if (EQ (glyphless_method
, Qhex_code
))
6638 it
->glyphless_method
= GLYPHLESS_DISPLAY_HEX_CODE
;
6639 else if (STRINGP (glyphless_method
))
6640 it
->glyphless_method
= GLYPHLESS_DISPLAY_ACRONYM
;
6643 /* Invalid value. We use the default method. */
6644 glyphless_method
= Qnil
;
6647 it
->what
= IT_GLYPHLESS
;
6648 return glyphless_method
;
6651 /* Merge escape glyph face and cache the result. */
6653 static struct frame
*last_escape_glyph_frame
= NULL
;
6654 static int last_escape_glyph_face_id
= (1 << FACE_ID_BITS
);
6655 static int last_escape_glyph_merged_face_id
= 0;
6658 merge_escape_glyph_face (struct it
*it
)
6662 if (it
->f
== last_escape_glyph_frame
6663 && it
->face_id
== last_escape_glyph_face_id
)
6664 face_id
= last_escape_glyph_merged_face_id
;
6667 /* Merge the `escape-glyph' face into the current face. */
6668 face_id
= merge_faces (it
->f
, Qescape_glyph
, 0, it
->face_id
);
6669 last_escape_glyph_frame
= it
->f
;
6670 last_escape_glyph_face_id
= it
->face_id
;
6671 last_escape_glyph_merged_face_id
= face_id
;
6676 /* Likewise for glyphless glyph face. */
6678 static struct frame
*last_glyphless_glyph_frame
= NULL
;
6679 static int last_glyphless_glyph_face_id
= (1 << FACE_ID_BITS
);
6680 static int last_glyphless_glyph_merged_face_id
= 0;
6683 merge_glyphless_glyph_face (struct it
*it
)
6687 if (it
->f
== last_glyphless_glyph_frame
6688 && it
->face_id
== last_glyphless_glyph_face_id
)
6689 face_id
= last_glyphless_glyph_merged_face_id
;
6692 /* Merge the `glyphless-char' face into the current face. */
6693 face_id
= merge_faces (it
->f
, Qglyphless_char
, 0, it
->face_id
);
6694 last_glyphless_glyph_frame
= it
->f
;
6695 last_glyphless_glyph_face_id
= it
->face_id
;
6696 last_glyphless_glyph_merged_face_id
= face_id
;
6701 /* Load IT's display element fields with information about the next
6702 display element from the current position of IT. Value is zero if
6703 end of buffer (or C string) is reached. */
6706 get_next_display_element (struct it
*it
)
6708 /* Non-zero means that we found a display element. Zero means that
6709 we hit the end of what we iterate over. Performance note: the
6710 function pointer `method' used here turns out to be faster than
6711 using a sequence of if-statements. */
6715 success_p
= GET_NEXT_DISPLAY_ELEMENT (it
);
6717 if (it
->what
== IT_CHARACTER
)
6719 /* UAX#9, L4: "A character is depicted by a mirrored glyph if
6720 and only if (a) the resolved directionality of that character
6722 /* FIXME: Do we need an exception for characters from display
6724 if (it
->bidi_p
&& it
->bidi_it
.type
== STRONG_R
)
6725 it
->c
= bidi_mirror_char (it
->c
);
6726 /* Map via display table or translate control characters.
6727 IT->c, IT->len etc. have been set to the next character by
6728 the function call above. If we have a display table, and it
6729 contains an entry for IT->c, translate it. Don't do this if
6730 IT->c itself comes from a display table, otherwise we could
6731 end up in an infinite recursion. (An alternative could be to
6732 count the recursion depth of this function and signal an
6733 error when a certain maximum depth is reached.) Is it worth
6735 if (success_p
&& it
->dpvec
== NULL
)
6738 struct charset
*unibyte
= CHARSET_FROM_ID (charset_unibyte
);
6739 int nonascii_space_p
= 0;
6740 int nonascii_hyphen_p
= 0;
6741 int c
= it
->c
; /* This is the character to display. */
6743 if (! it
->multibyte_p
&& ! ASCII_CHAR_P (c
))
6745 eassert (SINGLE_BYTE_CHAR_P (c
));
6746 if (unibyte_display_via_language_environment
)
6748 c
= DECODE_CHAR (unibyte
, c
);
6750 c
= BYTE8_TO_CHAR (it
->c
);
6753 c
= BYTE8_TO_CHAR (it
->c
);
6757 && (dv
= DISP_CHAR_VECTOR (it
->dp
, c
),
6760 struct Lisp_Vector
*v
= XVECTOR (dv
);
6762 /* Return the first character from the display table
6763 entry, if not empty. If empty, don't display the
6764 current character. */
6767 it
->dpvec_char_len
= it
->len
;
6768 it
->dpvec
= v
->contents
;
6769 it
->dpend
= v
->contents
+ v
->header
.size
;
6770 it
->current
.dpvec_index
= 0;
6771 it
->dpvec_face_id
= -1;
6772 it
->saved_face_id
= it
->face_id
;
6773 it
->method
= GET_FROM_DISPLAY_VECTOR
;
6778 set_iterator_to_next (it
, 0);
6783 if (! NILP (lookup_glyphless_char_display (c
, it
)))
6785 if (it
->what
== IT_GLYPHLESS
)
6787 /* Don't display this character. */
6788 set_iterator_to_next (it
, 0);
6792 /* If `nobreak-char-display' is non-nil, we display
6793 non-ASCII spaces and hyphens specially. */
6794 if (! ASCII_CHAR_P (c
) && ! NILP (Vnobreak_char_display
))
6797 nonascii_space_p
= 1;
6798 else if (c
== 0xAD || c
== 0x2010 || c
== 0x2011)
6799 nonascii_hyphen_p
= 1;
6802 /* Translate control characters into `\003' or `^C' form.
6803 Control characters coming from a display table entry are
6804 currently not translated because we use IT->dpvec to hold
6805 the translation. This could easily be changed but I
6806 don't believe that it is worth doing.
6808 The characters handled by `nobreak-char-display' must be
6811 Non-printable characters and raw-byte characters are also
6812 translated to octal form. */
6813 if (((c
< ' ' || c
== 127) /* ASCII control chars. */
6814 ? (it
->area
!= TEXT_AREA
6815 /* In mode line, treat \n, \t like other crl chars. */
6818 && (it
->glyph_row
->mode_line_p
|| it
->avoid_cursor_p
))
6819 || (c
!= '\n' && c
!= '\t'))
6821 || nonascii_hyphen_p
6823 || ! CHAR_PRINTABLE_P (c
))))
6825 /* C is a control character, non-ASCII space/hyphen,
6826 raw-byte, or a non-printable character which must be
6827 displayed either as '\003' or as `^C' where the '\\'
6828 and '^' can be defined in the display table. Fill
6829 IT->ctl_chars with glyphs for what we have to
6830 display. Then, set IT->dpvec to these glyphs. */
6837 /* Handle control characters with ^. */
6839 if (ASCII_CHAR_P (c
) && it
->ctl_arrow_p
)
6843 g
= '^'; /* default glyph for Control */
6844 /* Set IT->ctl_chars[0] to the glyph for `^'. */
6846 && (gc
= DISP_CTRL_GLYPH (it
->dp
), GLYPH_CODE_P (gc
)))
6848 g
= GLYPH_CODE_CHAR (gc
);
6849 lface_id
= GLYPH_CODE_FACE (gc
);
6853 ? merge_faces (it
->f
, Qt
, lface_id
, it
->face_id
)
6854 : merge_escape_glyph_face (it
));
6856 XSETINT (it
->ctl_chars
[0], g
);
6857 XSETINT (it
->ctl_chars
[1], c
^ 0100);
6859 goto display_control
;
6862 /* Handle non-ascii space in the mode where it only gets
6865 if (nonascii_space_p
&& EQ (Vnobreak_char_display
, Qt
))
6867 /* Merge `nobreak-space' into the current face. */
6868 face_id
= merge_faces (it
->f
, Qnobreak_space
, 0,
6870 XSETINT (it
->ctl_chars
[0], ' ');
6872 goto display_control
;
6875 /* Handle sequences that start with the "escape glyph". */
6877 /* the default escape glyph is \. */
6878 escape_glyph
= '\\';
6881 && (gc
= DISP_ESCAPE_GLYPH (it
->dp
), GLYPH_CODE_P (gc
)))
6883 escape_glyph
= GLYPH_CODE_CHAR (gc
);
6884 lface_id
= GLYPH_CODE_FACE (gc
);
6888 ? merge_faces (it
->f
, Qt
, lface_id
, it
->face_id
)
6889 : merge_escape_glyph_face (it
));
6891 /* Draw non-ASCII hyphen with just highlighting: */
6893 if (nonascii_hyphen_p
&& EQ (Vnobreak_char_display
, Qt
))
6895 XSETINT (it
->ctl_chars
[0], '-');
6897 goto display_control
;
6900 /* Draw non-ASCII space/hyphen with escape glyph: */
6902 if (nonascii_space_p
|| nonascii_hyphen_p
)
6904 XSETINT (it
->ctl_chars
[0], escape_glyph
);
6905 XSETINT (it
->ctl_chars
[1], nonascii_space_p
? ' ' : '-');
6907 goto display_control
;
6914 if (CHAR_BYTE8_P (c
))
6915 /* Display \200 instead of \17777600. */
6916 c
= CHAR_TO_BYTE8 (c
);
6917 len
= sprintf (str
, "%03o", c
);
6919 XSETINT (it
->ctl_chars
[0], escape_glyph
);
6920 for (i
= 0; i
< len
; i
++)
6921 XSETINT (it
->ctl_chars
[i
+ 1], str
[i
]);
6926 /* Set up IT->dpvec and return first character from it. */
6927 it
->dpvec_char_len
= it
->len
;
6928 it
->dpvec
= it
->ctl_chars
;
6929 it
->dpend
= it
->dpvec
+ ctl_len
;
6930 it
->current
.dpvec_index
= 0;
6931 it
->dpvec_face_id
= face_id
;
6932 it
->saved_face_id
= it
->face_id
;
6933 it
->method
= GET_FROM_DISPLAY_VECTOR
;
6937 it
->char_to_display
= c
;
6941 it
->char_to_display
= it
->c
;
6945 #ifdef HAVE_WINDOW_SYSTEM
6946 /* Adjust face id for a multibyte character. There are no multibyte
6947 character in unibyte text. */
6948 if ((it
->what
== IT_CHARACTER
|| it
->what
== IT_COMPOSITION
)
6951 && FRAME_WINDOW_P (it
->f
))
6953 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
6955 if (it
->what
== IT_COMPOSITION
&& it
->cmp_it
.ch
>= 0)
6957 /* Automatic composition with glyph-string. */
6958 Lisp_Object gstring
= composition_gstring_from_id (it
->cmp_it
.id
);
6960 it
->face_id
= face_for_font (it
->f
, LGSTRING_FONT (gstring
), face
);
6964 ptrdiff_t pos
= (it
->s
? -1
6965 : STRINGP (it
->string
) ? IT_STRING_CHARPOS (*it
)
6966 : IT_CHARPOS (*it
));
6969 if (it
->what
== IT_CHARACTER
)
6970 c
= it
->char_to_display
;
6973 struct composition
*cmp
= composition_table
[it
->cmp_it
.id
];
6977 for (i
= 0; i
< cmp
->glyph_len
; i
++)
6978 /* TAB in a composition means display glyphs with
6979 padding space on the left or right. */
6980 if ((c
= COMPOSITION_GLYPH (cmp
, i
)) != '\t')
6983 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, c
, pos
, it
->string
);
6986 #endif /* HAVE_WINDOW_SYSTEM */
6989 /* Is this character the last one of a run of characters with
6990 box? If yes, set IT->end_of_box_run_p to 1. */
6994 if (it
->method
== GET_FROM_STRING
&& it
->sp
)
6996 int face_id
= underlying_face_id (it
);
6997 struct face
*face
= FACE_FROM_ID (it
->f
, face_id
);
7001 if (face
->box
== FACE_NO_BOX
)
7003 /* If the box comes from face properties in a
7004 display string, check faces in that string. */
7005 int string_face_id
= face_after_it_pos (it
);
7006 it
->end_of_box_run_p
7007 = (FACE_FROM_ID (it
->f
, string_face_id
)->box
7010 /* Otherwise, the box comes from the underlying face.
7011 If this is the last string character displayed, check
7012 the next buffer location. */
7013 else if ((IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
) - 1)
7014 && (it
->current
.overlay_string_index
7015 == it
->n_overlay_strings
- 1))
7019 struct text_pos pos
= it
->current
.pos
;
7020 INC_TEXT_POS (pos
, it
->multibyte_p
);
7022 next_face_id
= face_at_buffer_position
7023 (it
->w
, CHARPOS (pos
), &ignore
,
7024 (IT_CHARPOS (*it
) + TEXT_PROP_DISTANCE_LIMIT
), 0,
7026 it
->end_of_box_run_p
7027 = (FACE_FROM_ID (it
->f
, next_face_id
)->box
7032 /* next_element_from_display_vector sets this flag according to
7033 faces of the display vector glyphs, see there. */
7034 else if (it
->method
!= GET_FROM_DISPLAY_VECTOR
)
7036 int face_id
= face_after_it_pos (it
);
7037 it
->end_of_box_run_p
7038 = (face_id
!= it
->face_id
7039 && FACE_FROM_ID (it
->f
, face_id
)->box
== FACE_NO_BOX
);
7042 /* If we reached the end of the object we've been iterating (e.g., a
7043 display string or an overlay string), and there's something on
7044 IT->stack, proceed with what's on the stack. It doesn't make
7045 sense to return zero if there's unprocessed stuff on the stack,
7046 because otherwise that stuff will never be displayed. */
7047 if (!success_p
&& it
->sp
> 0)
7049 set_iterator_to_next (it
, 0);
7050 success_p
= get_next_display_element (it
);
7053 /* Value is 0 if end of buffer or string reached. */
7058 /* Move IT to the next display element.
7060 RESEAT_P non-zero means if called on a newline in buffer text,
7061 skip to the next visible line start.
7063 Functions get_next_display_element and set_iterator_to_next are
7064 separate because I find this arrangement easier to handle than a
7065 get_next_display_element function that also increments IT's
7066 position. The way it is we can first look at an iterator's current
7067 display element, decide whether it fits on a line, and if it does,
7068 increment the iterator position. The other way around we probably
7069 would either need a flag indicating whether the iterator has to be
7070 incremented the next time, or we would have to implement a
7071 decrement position function which would not be easy to write. */
7074 set_iterator_to_next (struct it
*it
, int reseat_p
)
7076 /* Reset flags indicating start and end of a sequence of characters
7077 with box. Reset them at the start of this function because
7078 moving the iterator to a new position might set them. */
7079 it
->start_of_box_run_p
= it
->end_of_box_run_p
= 0;
7083 case GET_FROM_BUFFER
:
7084 /* The current display element of IT is a character from
7085 current_buffer. Advance in the buffer, and maybe skip over
7086 invisible lines that are so because of selective display. */
7087 if (ITERATOR_AT_END_OF_LINE_P (it
) && reseat_p
)
7088 reseat_at_next_visible_line_start (it
, 0);
7089 else if (it
->cmp_it
.id
>= 0)
7091 /* We are currently getting glyphs from a composition. */
7096 IT_CHARPOS (*it
) += it
->cmp_it
.nchars
;
7097 IT_BYTEPOS (*it
) += it
->cmp_it
.nbytes
;
7098 if (it
->cmp_it
.to
< it
->cmp_it
.nglyphs
)
7100 it
->cmp_it
.from
= it
->cmp_it
.to
;
7105 composition_compute_stop_pos (&it
->cmp_it
, IT_CHARPOS (*it
),
7107 it
->end_charpos
, Qnil
);
7110 else if (! it
->cmp_it
.reversed_p
)
7112 /* Composition created while scanning forward. */
7113 /* Update IT's char/byte positions to point to the first
7114 character of the next grapheme cluster, or to the
7115 character visually after the current composition. */
7116 for (i
= 0; i
< it
->cmp_it
.nchars
; i
++)
7117 bidi_move_to_visually_next (&it
->bidi_it
);
7118 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
7119 IT_CHARPOS (*it
) = it
->bidi_it
.charpos
;
7121 if (it
->cmp_it
.to
< it
->cmp_it
.nglyphs
)
7123 /* Proceed to the next grapheme cluster. */
7124 it
->cmp_it
.from
= it
->cmp_it
.to
;
7128 /* No more grapheme clusters in this composition.
7129 Find the next stop position. */
7130 ptrdiff_t stop
= it
->end_charpos
;
7131 if (it
->bidi_it
.scan_dir
< 0)
7132 /* Now we are scanning backward and don't know
7135 composition_compute_stop_pos (&it
->cmp_it
, IT_CHARPOS (*it
),
7136 IT_BYTEPOS (*it
), stop
, Qnil
);
7141 /* Composition created while scanning backward. */
7142 /* Update IT's char/byte positions to point to the last
7143 character of the previous grapheme cluster, or the
7144 character visually after the current composition. */
7145 for (i
= 0; i
< it
->cmp_it
.nchars
; i
++)
7146 bidi_move_to_visually_next (&it
->bidi_it
);
7147 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
7148 IT_CHARPOS (*it
) = it
->bidi_it
.charpos
;
7149 if (it
->cmp_it
.from
> 0)
7151 /* Proceed to the previous grapheme cluster. */
7152 it
->cmp_it
.to
= it
->cmp_it
.from
;
7156 /* No more grapheme clusters in this composition.
7157 Find the next stop position. */
7158 ptrdiff_t stop
= it
->end_charpos
;
7159 if (it
->bidi_it
.scan_dir
< 0)
7160 /* Now we are scanning backward and don't know
7163 composition_compute_stop_pos (&it
->cmp_it
, IT_CHARPOS (*it
),
7164 IT_BYTEPOS (*it
), stop
, Qnil
);
7170 eassert (it
->len
!= 0);
7174 IT_BYTEPOS (*it
) += it
->len
;
7175 IT_CHARPOS (*it
) += 1;
7179 int prev_scan_dir
= it
->bidi_it
.scan_dir
;
7180 /* If this is a new paragraph, determine its base
7181 direction (a.k.a. its base embedding level). */
7182 if (it
->bidi_it
.new_paragraph
)
7183 bidi_paragraph_init (it
->paragraph_embedding
, &it
->bidi_it
, 0);
7184 bidi_move_to_visually_next (&it
->bidi_it
);
7185 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
7186 IT_CHARPOS (*it
) = it
->bidi_it
.charpos
;
7187 if (prev_scan_dir
!= it
->bidi_it
.scan_dir
)
7189 /* As the scan direction was changed, we must
7190 re-compute the stop position for composition. */
7191 ptrdiff_t stop
= it
->end_charpos
;
7192 if (it
->bidi_it
.scan_dir
< 0)
7194 composition_compute_stop_pos (&it
->cmp_it
, IT_CHARPOS (*it
),
7195 IT_BYTEPOS (*it
), stop
, Qnil
);
7198 eassert (IT_BYTEPOS (*it
) == CHAR_TO_BYTE (IT_CHARPOS (*it
)));
7202 case GET_FROM_C_STRING
:
7203 /* Current display element of IT is from a C string. */
7205 /* If the string position is beyond string's end, it means
7206 next_element_from_c_string is padding the string with
7207 blanks, in which case we bypass the bidi iterator,
7208 because it cannot deal with such virtual characters. */
7209 || IT_CHARPOS (*it
) >= it
->bidi_it
.string
.schars
)
7211 IT_BYTEPOS (*it
) += it
->len
;
7212 IT_CHARPOS (*it
) += 1;
7216 bidi_move_to_visually_next (&it
->bidi_it
);
7217 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
7218 IT_CHARPOS (*it
) = it
->bidi_it
.charpos
;
7222 case GET_FROM_DISPLAY_VECTOR
:
7223 /* Current display element of IT is from a display table entry.
7224 Advance in the display table definition. Reset it to null if
7225 end reached, and continue with characters from buffers/
7227 ++it
->current
.dpvec_index
;
7229 /* Restore face of the iterator to what they were before the
7230 display vector entry (these entries may contain faces). */
7231 it
->face_id
= it
->saved_face_id
;
7233 if (it
->dpvec
+ it
->current
.dpvec_index
>= it
->dpend
)
7235 int recheck_faces
= it
->ellipsis_p
;
7238 it
->method
= GET_FROM_C_STRING
;
7239 else if (STRINGP (it
->string
))
7240 it
->method
= GET_FROM_STRING
;
7243 it
->method
= GET_FROM_BUFFER
;
7244 it
->object
= it
->w
->contents
;
7248 it
->current
.dpvec_index
= -1;
7250 /* Skip over characters which were displayed via IT->dpvec. */
7251 if (it
->dpvec_char_len
< 0)
7252 reseat_at_next_visible_line_start (it
, 1);
7253 else if (it
->dpvec_char_len
> 0)
7255 if (it
->method
== GET_FROM_STRING
7256 && it
->current
.overlay_string_index
>= 0
7257 && it
->n_overlay_strings
> 0)
7258 it
->ignore_overlay_strings_at_pos_p
= 1;
7259 it
->len
= it
->dpvec_char_len
;
7260 set_iterator_to_next (it
, reseat_p
);
7263 /* Maybe recheck faces after display vector */
7265 it
->stop_charpos
= IT_CHARPOS (*it
);
7269 case GET_FROM_STRING
:
7270 /* Current display element is a character from a Lisp string. */
7271 eassert (it
->s
== NULL
&& STRINGP (it
->string
));
7272 /* Don't advance past string end. These conditions are true
7273 when set_iterator_to_next is called at the end of
7274 get_next_display_element, in which case the Lisp string is
7275 already exhausted, and all we want is pop the iterator
7277 if (it
->current
.overlay_string_index
>= 0)
7279 /* This is an overlay string, so there's no padding with
7280 spaces, and the number of characters in the string is
7281 where the string ends. */
7282 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
))
7283 goto consider_string_end
;
7287 /* Not an overlay string. There could be padding, so test
7288 against it->end_charpos . */
7289 if (IT_STRING_CHARPOS (*it
) >= it
->end_charpos
)
7290 goto consider_string_end
;
7292 if (it
->cmp_it
.id
>= 0)
7298 IT_STRING_CHARPOS (*it
) += it
->cmp_it
.nchars
;
7299 IT_STRING_BYTEPOS (*it
) += it
->cmp_it
.nbytes
;
7300 if (it
->cmp_it
.to
< it
->cmp_it
.nglyphs
)
7301 it
->cmp_it
.from
= it
->cmp_it
.to
;
7305 composition_compute_stop_pos (&it
->cmp_it
,
7306 IT_STRING_CHARPOS (*it
),
7307 IT_STRING_BYTEPOS (*it
),
7308 it
->end_charpos
, it
->string
);
7311 else if (! it
->cmp_it
.reversed_p
)
7313 for (i
= 0; i
< it
->cmp_it
.nchars
; i
++)
7314 bidi_move_to_visually_next (&it
->bidi_it
);
7315 IT_STRING_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
7316 IT_STRING_CHARPOS (*it
) = it
->bidi_it
.charpos
;
7318 if (it
->cmp_it
.to
< it
->cmp_it
.nglyphs
)
7319 it
->cmp_it
.from
= it
->cmp_it
.to
;
7322 ptrdiff_t stop
= it
->end_charpos
;
7323 if (it
->bidi_it
.scan_dir
< 0)
7325 composition_compute_stop_pos (&it
->cmp_it
,
7326 IT_STRING_CHARPOS (*it
),
7327 IT_STRING_BYTEPOS (*it
), stop
,
7333 for (i
= 0; i
< it
->cmp_it
.nchars
; i
++)
7334 bidi_move_to_visually_next (&it
->bidi_it
);
7335 IT_STRING_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
7336 IT_STRING_CHARPOS (*it
) = it
->bidi_it
.charpos
;
7337 if (it
->cmp_it
.from
> 0)
7338 it
->cmp_it
.to
= it
->cmp_it
.from
;
7341 ptrdiff_t stop
= it
->end_charpos
;
7342 if (it
->bidi_it
.scan_dir
< 0)
7344 composition_compute_stop_pos (&it
->cmp_it
,
7345 IT_STRING_CHARPOS (*it
),
7346 IT_STRING_BYTEPOS (*it
), stop
,
7354 /* If the string position is beyond string's end, it
7355 means next_element_from_string is padding the string
7356 with blanks, in which case we bypass the bidi
7357 iterator, because it cannot deal with such virtual
7359 || IT_STRING_CHARPOS (*it
) >= it
->bidi_it
.string
.schars
)
7361 IT_STRING_BYTEPOS (*it
) += it
->len
;
7362 IT_STRING_CHARPOS (*it
) += 1;
7366 int prev_scan_dir
= it
->bidi_it
.scan_dir
;
7368 bidi_move_to_visually_next (&it
->bidi_it
);
7369 IT_STRING_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
7370 IT_STRING_CHARPOS (*it
) = it
->bidi_it
.charpos
;
7371 if (prev_scan_dir
!= it
->bidi_it
.scan_dir
)
7373 ptrdiff_t stop
= it
->end_charpos
;
7375 if (it
->bidi_it
.scan_dir
< 0)
7377 composition_compute_stop_pos (&it
->cmp_it
,
7378 IT_STRING_CHARPOS (*it
),
7379 IT_STRING_BYTEPOS (*it
), stop
,
7385 consider_string_end
:
7387 if (it
->current
.overlay_string_index
>= 0)
7389 /* IT->string is an overlay string. Advance to the
7390 next, if there is one. */
7391 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
))
7394 next_overlay_string (it
);
7396 setup_for_ellipsis (it
, 0);
7401 /* IT->string is not an overlay string. If we reached
7402 its end, and there is something on IT->stack, proceed
7403 with what is on the stack. This can be either another
7404 string, this time an overlay string, or a buffer. */
7405 if (IT_STRING_CHARPOS (*it
) == SCHARS (it
->string
)
7409 if (it
->method
== GET_FROM_STRING
)
7410 goto consider_string_end
;
7415 case GET_FROM_IMAGE
:
7416 case GET_FROM_STRETCH
:
7417 /* The position etc with which we have to proceed are on
7418 the stack. The position may be at the end of a string,
7419 if the `display' property takes up the whole string. */
7420 eassert (it
->sp
> 0);
7422 if (it
->method
== GET_FROM_STRING
)
7423 goto consider_string_end
;
7427 /* There are no other methods defined, so this should be a bug. */
7431 eassert (it
->method
!= GET_FROM_STRING
7432 || (STRINGP (it
->string
)
7433 && IT_STRING_CHARPOS (*it
) >= 0));
7436 /* Load IT's display element fields with information about the next
7437 display element which comes from a display table entry or from the
7438 result of translating a control character to one of the forms `^C'
7441 IT->dpvec holds the glyphs to return as characters.
7442 IT->saved_face_id holds the face id before the display vector--it
7443 is restored into IT->face_id in set_iterator_to_next. */
7446 next_element_from_display_vector (struct it
*it
)
7449 int prev_face_id
= it
->face_id
;
7453 eassert (it
->dpvec
&& it
->current
.dpvec_index
>= 0);
7455 it
->face_id
= it
->saved_face_id
;
7457 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
7458 That seemed totally bogus - so I changed it... */
7459 gc
= it
->dpvec
[it
->current
.dpvec_index
];
7461 if (GLYPH_CODE_P (gc
))
7463 struct face
*this_face
, *prev_face
, *next_face
;
7465 it
->c
= GLYPH_CODE_CHAR (gc
);
7466 it
->len
= CHAR_BYTES (it
->c
);
7468 /* The entry may contain a face id to use. Such a face id is
7469 the id of a Lisp face, not a realized face. A face id of
7470 zero means no face is specified. */
7471 if (it
->dpvec_face_id
>= 0)
7472 it
->face_id
= it
->dpvec_face_id
;
7475 int lface_id
= GLYPH_CODE_FACE (gc
);
7477 it
->face_id
= merge_faces (it
->f
, Qt
, lface_id
,
7481 /* Glyphs in the display vector could have the box face, so we
7482 need to set the related flags in the iterator, as
7484 this_face
= FACE_FROM_ID (it
->f
, it
->face_id
);
7485 prev_face
= FACE_FROM_ID (it
->f
, prev_face_id
);
7487 /* Is this character the first character of a box-face run? */
7488 it
->start_of_box_run_p
= (this_face
&& this_face
->box
!= FACE_NO_BOX
7490 || prev_face
->box
== FACE_NO_BOX
));
7492 /* For the last character of the box-face run, we need to look
7493 either at the next glyph from the display vector, or at the
7494 face we saw before the display vector. */
7495 next_face_id
= it
->saved_face_id
;
7496 if (it
->current
.dpvec_index
< it
->dpend
- it
->dpvec
- 1)
7498 if (it
->dpvec_face_id
>= 0)
7499 next_face_id
= it
->dpvec_face_id
;
7503 GLYPH_CODE_FACE (it
->dpvec
[it
->current
.dpvec_index
+ 1]);
7506 next_face_id
= merge_faces (it
->f
, Qt
, lface_id
,
7510 next_face
= FACE_FROM_ID (it
->f
, next_face_id
);
7511 it
->end_of_box_run_p
= (this_face
&& this_face
->box
!= FACE_NO_BOX
7513 || next_face
->box
== FACE_NO_BOX
));
7514 it
->face_box_p
= this_face
&& this_face
->box
!= FACE_NO_BOX
;
7517 /* Display table entry is invalid. Return a space. */
7518 it
->c
= ' ', it
->len
= 1;
7520 /* Don't change position and object of the iterator here. They are
7521 still the values of the character that had this display table
7522 entry or was translated, and that's what we want. */
7523 it
->what
= IT_CHARACTER
;
7527 /* Get the first element of string/buffer in the visual order, after
7528 being reseated to a new position in a string or a buffer. */
7530 get_visually_first_element (struct it
*it
)
7532 int string_p
= STRINGP (it
->string
) || it
->s
;
7533 ptrdiff_t eob
= (string_p
? it
->bidi_it
.string
.schars
: ZV
);
7534 ptrdiff_t bob
= (string_p
? 0 : BEGV
);
7536 if (STRINGP (it
->string
))
7538 it
->bidi_it
.charpos
= IT_STRING_CHARPOS (*it
);
7539 it
->bidi_it
.bytepos
= IT_STRING_BYTEPOS (*it
);
7543 it
->bidi_it
.charpos
= IT_CHARPOS (*it
);
7544 it
->bidi_it
.bytepos
= IT_BYTEPOS (*it
);
7547 if (it
->bidi_it
.charpos
== eob
)
7549 /* Nothing to do, but reset the FIRST_ELT flag, like
7550 bidi_paragraph_init does, because we are not going to
7552 it
->bidi_it
.first_elt
= 0;
7554 else if (it
->bidi_it
.charpos
== bob
7556 && (FETCH_CHAR (it
->bidi_it
.bytepos
- 1) == '\n'
7557 || FETCH_CHAR (it
->bidi_it
.bytepos
) == '\n')))
7559 /* If we are at the beginning of a line/string, we can produce
7560 the next element right away. */
7561 bidi_paragraph_init (it
->paragraph_embedding
, &it
->bidi_it
, 1);
7562 bidi_move_to_visually_next (&it
->bidi_it
);
7566 ptrdiff_t orig_bytepos
= it
->bidi_it
.bytepos
;
7568 /* We need to prime the bidi iterator starting at the line's or
7569 string's beginning, before we will be able to produce the
7572 it
->bidi_it
.charpos
= it
->bidi_it
.bytepos
= 0;
7574 it
->bidi_it
.charpos
= find_newline_no_quit (IT_CHARPOS (*it
),
7575 IT_BYTEPOS (*it
), -1,
7576 &it
->bidi_it
.bytepos
);
7577 bidi_paragraph_init (it
->paragraph_embedding
, &it
->bidi_it
, 1);
7580 /* Now return to buffer/string position where we were asked
7581 to get the next display element, and produce that. */
7582 bidi_move_to_visually_next (&it
->bidi_it
);
7584 while (it
->bidi_it
.bytepos
!= orig_bytepos
7585 && it
->bidi_it
.charpos
< eob
);
7588 /* Adjust IT's position information to where we ended up. */
7589 if (STRINGP (it
->string
))
7591 IT_STRING_CHARPOS (*it
) = it
->bidi_it
.charpos
;
7592 IT_STRING_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
7596 IT_CHARPOS (*it
) = it
->bidi_it
.charpos
;
7597 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
7600 if (STRINGP (it
->string
) || !it
->s
)
7602 ptrdiff_t stop
, charpos
, bytepos
;
7604 if (STRINGP (it
->string
))
7607 stop
= SCHARS (it
->string
);
7608 if (stop
> it
->end_charpos
)
7609 stop
= it
->end_charpos
;
7610 charpos
= IT_STRING_CHARPOS (*it
);
7611 bytepos
= IT_STRING_BYTEPOS (*it
);
7615 stop
= it
->end_charpos
;
7616 charpos
= IT_CHARPOS (*it
);
7617 bytepos
= IT_BYTEPOS (*it
);
7619 if (it
->bidi_it
.scan_dir
< 0)
7621 composition_compute_stop_pos (&it
->cmp_it
, charpos
, bytepos
, stop
,
7626 /* Load IT with the next display element from Lisp string IT->string.
7627 IT->current.string_pos is the current position within the string.
7628 If IT->current.overlay_string_index >= 0, the Lisp string is an
7632 next_element_from_string (struct it
*it
)
7634 struct text_pos position
;
7636 eassert (STRINGP (it
->string
));
7637 eassert (!it
->bidi_p
|| EQ (it
->string
, it
->bidi_it
.string
.lstring
));
7638 eassert (IT_STRING_CHARPOS (*it
) >= 0);
7639 position
= it
->current
.string_pos
;
7641 /* With bidi reordering, the character to display might not be the
7642 character at IT_STRING_CHARPOS. BIDI_IT.FIRST_ELT non-zero means
7643 that we were reseat()ed to a new string, whose paragraph
7644 direction is not known. */
7645 if (it
->bidi_p
&& it
->bidi_it
.first_elt
)
7647 get_visually_first_element (it
);
7648 SET_TEXT_POS (position
, IT_STRING_CHARPOS (*it
), IT_STRING_BYTEPOS (*it
));
7651 /* Time to check for invisible text? */
7652 if (IT_STRING_CHARPOS (*it
) < it
->end_charpos
)
7654 if (IT_STRING_CHARPOS (*it
) >= it
->stop_charpos
)
7657 || BIDI_AT_BASE_LEVEL (it
->bidi_it
)
7658 || IT_STRING_CHARPOS (*it
) == it
->stop_charpos
))
7660 /* With bidi non-linear iteration, we could find
7661 ourselves far beyond the last computed stop_charpos,
7662 with several other stop positions in between that we
7663 missed. Scan them all now, in buffer's logical
7664 order, until we find and handle the last stop_charpos
7665 that precedes our current position. */
7666 handle_stop_backwards (it
, it
->stop_charpos
);
7667 return GET_NEXT_DISPLAY_ELEMENT (it
);
7673 /* Take note of the stop position we just moved
7674 across, for when we will move back across it. */
7675 it
->prev_stop
= it
->stop_charpos
;
7676 /* If we are at base paragraph embedding level, take
7677 note of the last stop position seen at this
7679 if (BIDI_AT_BASE_LEVEL (it
->bidi_it
))
7680 it
->base_level_stop
= it
->stop_charpos
;
7684 /* Since a handler may have changed IT->method, we must
7686 return GET_NEXT_DISPLAY_ELEMENT (it
);
7690 /* If we are before prev_stop, we may have overstepped
7691 on our way backwards a stop_pos, and if so, we need
7692 to handle that stop_pos. */
7693 && IT_STRING_CHARPOS (*it
) < it
->prev_stop
7694 /* We can sometimes back up for reasons that have nothing
7695 to do with bidi reordering. E.g., compositions. The
7696 code below is only needed when we are above the base
7697 embedding level, so test for that explicitly. */
7698 && !BIDI_AT_BASE_LEVEL (it
->bidi_it
))
7700 /* If we lost track of base_level_stop, we have no better
7701 place for handle_stop_backwards to start from than string
7702 beginning. This happens, e.g., when we were reseated to
7703 the previous screenful of text by vertical-motion. */
7704 if (it
->base_level_stop
<= 0
7705 || IT_STRING_CHARPOS (*it
) < it
->base_level_stop
)
7706 it
->base_level_stop
= 0;
7707 handle_stop_backwards (it
, it
->base_level_stop
);
7708 return GET_NEXT_DISPLAY_ELEMENT (it
);
7712 if (it
->current
.overlay_string_index
>= 0)
7714 /* Get the next character from an overlay string. In overlay
7715 strings, there is no field width or padding with spaces to
7717 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
))
7722 else if (CHAR_COMPOSED_P (it
, IT_STRING_CHARPOS (*it
),
7723 IT_STRING_BYTEPOS (*it
),
7724 it
->bidi_it
.scan_dir
< 0
7726 : SCHARS (it
->string
))
7727 && next_element_from_composition (it
))
7731 else if (STRING_MULTIBYTE (it
->string
))
7733 const unsigned char *s
= (SDATA (it
->string
)
7734 + IT_STRING_BYTEPOS (*it
));
7735 it
->c
= string_char_and_length (s
, &it
->len
);
7739 it
->c
= SREF (it
->string
, IT_STRING_BYTEPOS (*it
));
7745 /* Get the next character from a Lisp string that is not an
7746 overlay string. Such strings come from the mode line, for
7747 example. We may have to pad with spaces, or truncate the
7748 string. See also next_element_from_c_string. */
7749 if (IT_STRING_CHARPOS (*it
) >= it
->end_charpos
)
7754 else if (IT_STRING_CHARPOS (*it
) >= it
->string_nchars
)
7756 /* Pad with spaces. */
7757 it
->c
= ' ', it
->len
= 1;
7758 CHARPOS (position
) = BYTEPOS (position
) = -1;
7760 else if (CHAR_COMPOSED_P (it
, IT_STRING_CHARPOS (*it
),
7761 IT_STRING_BYTEPOS (*it
),
7762 it
->bidi_it
.scan_dir
< 0
7764 : it
->string_nchars
)
7765 && next_element_from_composition (it
))
7769 else if (STRING_MULTIBYTE (it
->string
))
7771 const unsigned char *s
= (SDATA (it
->string
)
7772 + IT_STRING_BYTEPOS (*it
));
7773 it
->c
= string_char_and_length (s
, &it
->len
);
7777 it
->c
= SREF (it
->string
, IT_STRING_BYTEPOS (*it
));
7782 /* Record what we have and where it came from. */
7783 it
->what
= IT_CHARACTER
;
7784 it
->object
= it
->string
;
7785 it
->position
= position
;
7790 /* Load IT with next display element from C string IT->s.
7791 IT->string_nchars is the maximum number of characters to return
7792 from the string. IT->end_charpos may be greater than
7793 IT->string_nchars when this function is called, in which case we
7794 may have to return padding spaces. Value is zero if end of string
7795 reached, including padding spaces. */
7798 next_element_from_c_string (struct it
*it
)
7803 eassert (!it
->bidi_p
|| it
->s
== it
->bidi_it
.string
.s
);
7804 it
->what
= IT_CHARACTER
;
7805 BYTEPOS (it
->position
) = CHARPOS (it
->position
) = 0;
7808 /* With bidi reordering, the character to display might not be the
7809 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
7810 we were reseated to a new string, whose paragraph direction is
7812 if (it
->bidi_p
&& it
->bidi_it
.first_elt
)
7813 get_visually_first_element (it
);
7815 /* IT's position can be greater than IT->string_nchars in case a
7816 field width or precision has been specified when the iterator was
7818 if (IT_CHARPOS (*it
) >= it
->end_charpos
)
7820 /* End of the game. */
7824 else if (IT_CHARPOS (*it
) >= it
->string_nchars
)
7826 /* Pad with spaces. */
7827 it
->c
= ' ', it
->len
= 1;
7828 BYTEPOS (it
->position
) = CHARPOS (it
->position
) = -1;
7830 else if (it
->multibyte_p
)
7831 it
->c
= string_char_and_length (it
->s
+ IT_BYTEPOS (*it
), &it
->len
);
7833 it
->c
= it
->s
[IT_BYTEPOS (*it
)], it
->len
= 1;
7839 /* Set up IT to return characters from an ellipsis, if appropriate.
7840 The definition of the ellipsis glyphs may come from a display table
7841 entry. This function fills IT with the first glyph from the
7842 ellipsis if an ellipsis is to be displayed. */
7845 next_element_from_ellipsis (struct it
*it
)
7847 if (it
->selective_display_ellipsis_p
)
7848 setup_for_ellipsis (it
, it
->len
);
7851 /* The face at the current position may be different from the
7852 face we find after the invisible text. Remember what it
7853 was in IT->saved_face_id, and signal that it's there by
7854 setting face_before_selective_p. */
7855 it
->saved_face_id
= it
->face_id
;
7856 it
->method
= GET_FROM_BUFFER
;
7857 it
->object
= it
->w
->contents
;
7858 reseat_at_next_visible_line_start (it
, 1);
7859 it
->face_before_selective_p
= 1;
7862 return GET_NEXT_DISPLAY_ELEMENT (it
);
7866 /* Deliver an image display element. The iterator IT is already
7867 filled with image information (done in handle_display_prop). Value
7872 next_element_from_image (struct it
*it
)
7874 it
->what
= IT_IMAGE
;
7875 it
->ignore_overlay_strings_at_pos_p
= 0;
7880 /* Fill iterator IT with next display element from a stretch glyph
7881 property. IT->object is the value of the text property. Value is
7885 next_element_from_stretch (struct it
*it
)
7887 it
->what
= IT_STRETCH
;
7891 /* Scan backwards from IT's current position until we find a stop
7892 position, or until BEGV. This is called when we find ourself
7893 before both the last known prev_stop and base_level_stop while
7894 reordering bidirectional text. */
7897 compute_stop_pos_backwards (struct it
*it
)
7899 const int SCAN_BACK_LIMIT
= 1000;
7900 struct text_pos pos
;
7901 struct display_pos save_current
= it
->current
;
7902 struct text_pos save_position
= it
->position
;
7903 ptrdiff_t charpos
= IT_CHARPOS (*it
);
7904 ptrdiff_t where_we_are
= charpos
;
7905 ptrdiff_t save_stop_pos
= it
->stop_charpos
;
7906 ptrdiff_t save_end_pos
= it
->end_charpos
;
7908 eassert (NILP (it
->string
) && !it
->s
);
7909 eassert (it
->bidi_p
);
7913 it
->end_charpos
= min (charpos
+ 1, ZV
);
7914 charpos
= max (charpos
- SCAN_BACK_LIMIT
, BEGV
);
7915 SET_TEXT_POS (pos
, charpos
, CHAR_TO_BYTE (charpos
));
7916 reseat_1 (it
, pos
, 0);
7917 compute_stop_pos (it
);
7918 /* We must advance forward, right? */
7919 if (it
->stop_charpos
<= charpos
)
7922 while (charpos
> BEGV
&& it
->stop_charpos
>= it
->end_charpos
);
7924 if (it
->stop_charpos
<= where_we_are
)
7925 it
->prev_stop
= it
->stop_charpos
;
7927 it
->prev_stop
= BEGV
;
7929 it
->current
= save_current
;
7930 it
->position
= save_position
;
7931 it
->stop_charpos
= save_stop_pos
;
7932 it
->end_charpos
= save_end_pos
;
7935 /* Scan forward from CHARPOS in the current buffer/string, until we
7936 find a stop position > current IT's position. Then handle the stop
7937 position before that. This is called when we bump into a stop
7938 position while reordering bidirectional text. CHARPOS should be
7939 the last previously processed stop_pos (or BEGV/0, if none were
7940 processed yet) whose position is less that IT's current
7944 handle_stop_backwards (struct it
*it
, ptrdiff_t charpos
)
7946 int bufp
= !STRINGP (it
->string
);
7947 ptrdiff_t where_we_are
= (bufp
? IT_CHARPOS (*it
) : IT_STRING_CHARPOS (*it
));
7948 struct display_pos save_current
= it
->current
;
7949 struct text_pos save_position
= it
->position
;
7950 struct text_pos pos1
;
7951 ptrdiff_t next_stop
;
7953 /* Scan in strict logical order. */
7954 eassert (it
->bidi_p
);
7958 it
->prev_stop
= charpos
;
7961 SET_TEXT_POS (pos1
, charpos
, CHAR_TO_BYTE (charpos
));
7962 reseat_1 (it
, pos1
, 0);
7965 it
->current
.string_pos
= string_pos (charpos
, it
->string
);
7966 compute_stop_pos (it
);
7967 /* We must advance forward, right? */
7968 if (it
->stop_charpos
<= it
->prev_stop
)
7970 charpos
= it
->stop_charpos
;
7972 while (charpos
<= where_we_are
);
7975 it
->current
= save_current
;
7976 it
->position
= save_position
;
7977 next_stop
= it
->stop_charpos
;
7978 it
->stop_charpos
= it
->prev_stop
;
7980 it
->stop_charpos
= next_stop
;
7983 /* Load IT with the next display element from current_buffer. Value
7984 is zero if end of buffer reached. IT->stop_charpos is the next
7985 position at which to stop and check for text properties or buffer
7989 next_element_from_buffer (struct it
*it
)
7993 eassert (IT_CHARPOS (*it
) >= BEGV
);
7994 eassert (NILP (it
->string
) && !it
->s
);
7995 eassert (!it
->bidi_p
7996 || (EQ (it
->bidi_it
.string
.lstring
, Qnil
)
7997 && it
->bidi_it
.string
.s
== NULL
));
7999 /* With bidi reordering, the character to display might not be the
8000 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
8001 we were reseat()ed to a new buffer position, which is potentially
8002 a different paragraph. */
8003 if (it
->bidi_p
&& it
->bidi_it
.first_elt
)
8005 get_visually_first_element (it
);
8006 SET_TEXT_POS (it
->position
, IT_CHARPOS (*it
), IT_BYTEPOS (*it
));
8009 if (IT_CHARPOS (*it
) >= it
->stop_charpos
)
8011 if (IT_CHARPOS (*it
) >= it
->end_charpos
)
8013 int overlay_strings_follow_p
;
8015 /* End of the game, except when overlay strings follow that
8016 haven't been returned yet. */
8017 if (it
->overlay_strings_at_end_processed_p
)
8018 overlay_strings_follow_p
= 0;
8021 it
->overlay_strings_at_end_processed_p
= 1;
8022 overlay_strings_follow_p
= get_overlay_strings (it
, 0);
8025 if (overlay_strings_follow_p
)
8026 success_p
= GET_NEXT_DISPLAY_ELEMENT (it
);
8030 it
->position
= it
->current
.pos
;
8034 else if (!(!it
->bidi_p
8035 || BIDI_AT_BASE_LEVEL (it
->bidi_it
)
8036 || IT_CHARPOS (*it
) == it
->stop_charpos
))
8038 /* With bidi non-linear iteration, we could find ourselves
8039 far beyond the last computed stop_charpos, with several
8040 other stop positions in between that we missed. Scan
8041 them all now, in buffer's logical order, until we find
8042 and handle the last stop_charpos that precedes our
8043 current position. */
8044 handle_stop_backwards (it
, it
->stop_charpos
);
8045 return GET_NEXT_DISPLAY_ELEMENT (it
);
8051 /* Take note of the stop position we just moved across,
8052 for when we will move back across it. */
8053 it
->prev_stop
= it
->stop_charpos
;
8054 /* If we are at base paragraph embedding level, take
8055 note of the last stop position seen at this
8057 if (BIDI_AT_BASE_LEVEL (it
->bidi_it
))
8058 it
->base_level_stop
= it
->stop_charpos
;
8061 return GET_NEXT_DISPLAY_ELEMENT (it
);
8065 /* If we are before prev_stop, we may have overstepped on
8066 our way backwards a stop_pos, and if so, we need to
8067 handle that stop_pos. */
8068 && IT_CHARPOS (*it
) < it
->prev_stop
8069 /* We can sometimes back up for reasons that have nothing
8070 to do with bidi reordering. E.g., compositions. The
8071 code below is only needed when we are above the base
8072 embedding level, so test for that explicitly. */
8073 && !BIDI_AT_BASE_LEVEL (it
->bidi_it
))
8075 if (it
->base_level_stop
<= 0
8076 || IT_CHARPOS (*it
) < it
->base_level_stop
)
8078 /* If we lost track of base_level_stop, we need to find
8079 prev_stop by looking backwards. This happens, e.g., when
8080 we were reseated to the previous screenful of text by
8082 it
->base_level_stop
= BEGV
;
8083 compute_stop_pos_backwards (it
);
8084 handle_stop_backwards (it
, it
->prev_stop
);
8087 handle_stop_backwards (it
, it
->base_level_stop
);
8088 return GET_NEXT_DISPLAY_ELEMENT (it
);
8092 /* No face changes, overlays etc. in sight, so just return a
8093 character from current_buffer. */
8097 /* Maybe run the redisplay end trigger hook. Performance note:
8098 This doesn't seem to cost measurable time. */
8099 if (it
->redisplay_end_trigger_charpos
8101 && IT_CHARPOS (*it
) >= it
->redisplay_end_trigger_charpos
)
8102 run_redisplay_end_trigger_hook (it
);
8104 stop
= it
->bidi_it
.scan_dir
< 0 ? -1 : it
->end_charpos
;
8105 if (CHAR_COMPOSED_P (it
, IT_CHARPOS (*it
), IT_BYTEPOS (*it
),
8107 && next_element_from_composition (it
))
8112 /* Get the next character, maybe multibyte. */
8113 p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
8114 if (it
->multibyte_p
&& !ASCII_BYTE_P (*p
))
8115 it
->c
= STRING_CHAR_AND_LENGTH (p
, it
->len
);
8117 it
->c
= *p
, it
->len
= 1;
8119 /* Record what we have and where it came from. */
8120 it
->what
= IT_CHARACTER
;
8121 it
->object
= it
->w
->contents
;
8122 it
->position
= it
->current
.pos
;
8124 /* Normally we return the character found above, except when we
8125 really want to return an ellipsis for selective display. */
8130 /* A value of selective > 0 means hide lines indented more
8131 than that number of columns. */
8132 if (it
->selective
> 0
8133 && IT_CHARPOS (*it
) + 1 < ZV
8134 && indented_beyond_p (IT_CHARPOS (*it
) + 1,
8135 IT_BYTEPOS (*it
) + 1,
8138 success_p
= next_element_from_ellipsis (it
);
8139 it
->dpvec_char_len
= -1;
8142 else if (it
->c
== '\r' && it
->selective
== -1)
8144 /* A value of selective == -1 means that everything from the
8145 CR to the end of the line is invisible, with maybe an
8146 ellipsis displayed for it. */
8147 success_p
= next_element_from_ellipsis (it
);
8148 it
->dpvec_char_len
= -1;
8153 /* Value is zero if end of buffer reached. */
8154 eassert (!success_p
|| it
->what
!= IT_CHARACTER
|| it
->len
> 0);
8159 /* Run the redisplay end trigger hook for IT. */
8162 run_redisplay_end_trigger_hook (struct it
*it
)
8164 Lisp_Object args
[3];
8166 /* IT->glyph_row should be non-null, i.e. we should be actually
8167 displaying something, or otherwise we should not run the hook. */
8168 eassert (it
->glyph_row
);
8170 /* Set up hook arguments. */
8171 args
[0] = Qredisplay_end_trigger_functions
;
8172 args
[1] = it
->window
;
8173 XSETINT (args
[2], it
->redisplay_end_trigger_charpos
);
8174 it
->redisplay_end_trigger_charpos
= 0;
8176 /* Since we are *trying* to run these functions, don't try to run
8177 them again, even if they get an error. */
8178 wset_redisplay_end_trigger (it
->w
, Qnil
);
8179 Frun_hook_with_args (3, args
);
8181 /* Notice if it changed the face of the character we are on. */
8182 handle_face_prop (it
);
8186 /* Deliver a composition display element. Unlike the other
8187 next_element_from_XXX, this function is not registered in the array
8188 get_next_element[]. It is called from next_element_from_buffer and
8189 next_element_from_string when necessary. */
8192 next_element_from_composition (struct it
*it
)
8194 it
->what
= IT_COMPOSITION
;
8195 it
->len
= it
->cmp_it
.nbytes
;
8196 if (STRINGP (it
->string
))
8200 IT_STRING_CHARPOS (*it
) += it
->cmp_it
.nchars
;
8201 IT_STRING_BYTEPOS (*it
) += it
->cmp_it
.nbytes
;
8204 it
->position
= it
->current
.string_pos
;
8205 it
->object
= it
->string
;
8206 it
->c
= composition_update_it (&it
->cmp_it
, IT_STRING_CHARPOS (*it
),
8207 IT_STRING_BYTEPOS (*it
), it
->string
);
8213 IT_CHARPOS (*it
) += it
->cmp_it
.nchars
;
8214 IT_BYTEPOS (*it
) += it
->cmp_it
.nbytes
;
8217 if (it
->bidi_it
.new_paragraph
)
8218 bidi_paragraph_init (it
->paragraph_embedding
, &it
->bidi_it
, 0);
8219 /* Resync the bidi iterator with IT's new position.
8220 FIXME: this doesn't support bidirectional text. */
8221 while (it
->bidi_it
.charpos
< IT_CHARPOS (*it
))
8222 bidi_move_to_visually_next (&it
->bidi_it
);
8226 it
->position
= it
->current
.pos
;
8227 it
->object
= it
->w
->contents
;
8228 it
->c
= composition_update_it (&it
->cmp_it
, IT_CHARPOS (*it
),
8229 IT_BYTEPOS (*it
), Qnil
);
8236 /***********************************************************************
8237 Moving an iterator without producing glyphs
8238 ***********************************************************************/
8240 /* Check if iterator is at a position corresponding to a valid buffer
8241 position after some move_it_ call. */
8243 #define IT_POS_VALID_AFTER_MOVE_P(it) \
8244 ((it)->method == GET_FROM_STRING \
8245 ? IT_STRING_CHARPOS (*it) == 0 \
8249 /* Move iterator IT to a specified buffer or X position within one
8250 line on the display without producing glyphs.
8252 OP should be a bit mask including some or all of these bits:
8253 MOVE_TO_X: Stop upon reaching x-position TO_X.
8254 MOVE_TO_POS: Stop upon reaching buffer or string position TO_CHARPOS.
8255 Regardless of OP's value, stop upon reaching the end of the display line.
8257 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
8258 This means, in particular, that TO_X includes window's horizontal
8261 The return value has several possible values that
8262 say what condition caused the scan to stop:
8264 MOVE_POS_MATCH_OR_ZV
8265 - when TO_POS or ZV was reached.
8268 -when TO_X was reached before TO_POS or ZV were reached.
8271 - when we reached the end of the display area and the line must
8275 - when we reached the end of the display area and the line is
8279 - when we stopped at a line end, i.e. a newline or a CR and selective
8282 static enum move_it_result
8283 move_it_in_display_line_to (struct it
*it
,
8284 ptrdiff_t to_charpos
, int to_x
,
8285 enum move_operation_enum op
)
8287 enum move_it_result result
= MOVE_UNDEFINED
;
8288 struct glyph_row
*saved_glyph_row
;
8289 struct it wrap_it
, atpos_it
, atx_it
, ppos_it
;
8290 void *wrap_data
= NULL
, *atpos_data
= NULL
, *atx_data
= NULL
;
8291 void *ppos_data
= NULL
;
8293 enum it_method prev_method
= it
->method
;
8294 ptrdiff_t prev_pos
= IT_CHARPOS (*it
);
8295 int saw_smaller_pos
= prev_pos
< to_charpos
;
8297 /* Don't produce glyphs in produce_glyphs. */
8298 saved_glyph_row
= it
->glyph_row
;
8299 it
->glyph_row
= NULL
;
8301 /* Use wrap_it to save a copy of IT wherever a word wrap could
8302 occur. Use atpos_it to save a copy of IT at the desired buffer
8303 position, if found, so that we can scan ahead and check if the
8304 word later overshoots the window edge. Use atx_it similarly, for
8310 /* Use ppos_it under bidi reordering to save a copy of IT for the
8311 position > CHARPOS that is the closest to CHARPOS. We restore
8312 that position in IT when we have scanned the entire display line
8313 without finding a match for CHARPOS and all the character
8314 positions are greater than CHARPOS. */
8317 SAVE_IT (ppos_it
, *it
, ppos_data
);
8318 SET_TEXT_POS (ppos_it
.current
.pos
, ZV
, ZV_BYTE
);
8319 if ((op
& MOVE_TO_POS
) && IT_CHARPOS (*it
) >= to_charpos
)
8320 SAVE_IT (ppos_it
, *it
, ppos_data
);
8323 #define BUFFER_POS_REACHED_P() \
8324 ((op & MOVE_TO_POS) != 0 \
8325 && BUFFERP (it->object) \
8326 && (IT_CHARPOS (*it) == to_charpos \
8328 || BIDI_AT_BASE_LEVEL (it->bidi_it)) \
8329 && IT_CHARPOS (*it) > to_charpos) \
8330 || (it->what == IT_COMPOSITION \
8331 && ((IT_CHARPOS (*it) > to_charpos \
8332 && to_charpos >= it->cmp_it.charpos) \
8333 || (IT_CHARPOS (*it) < to_charpos \
8334 && to_charpos <= it->cmp_it.charpos)))) \
8335 && (it->method == GET_FROM_BUFFER \
8336 || (it->method == GET_FROM_DISPLAY_VECTOR \
8337 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
8339 /* If there's a line-/wrap-prefix, handle it. */
8340 if (it
->hpos
== 0 && it
->method
== GET_FROM_BUFFER
8341 && it
->current_y
< it
->last_visible_y
)
8342 handle_line_prefix (it
);
8344 if (IT_CHARPOS (*it
) < CHARPOS (this_line_min_pos
))
8345 SET_TEXT_POS (this_line_min_pos
, IT_CHARPOS (*it
), IT_BYTEPOS (*it
));
8349 int x
, i
, ascent
= 0, descent
= 0;
8351 /* Utility macro to reset an iterator with x, ascent, and descent. */
8352 #define IT_RESET_X_ASCENT_DESCENT(IT) \
8353 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
8354 (IT)->max_descent = descent)
8356 /* Stop if we move beyond TO_CHARPOS (after an image or a
8357 display string or stretch glyph). */
8358 if ((op
& MOVE_TO_POS
) != 0
8359 && BUFFERP (it
->object
)
8360 && it
->method
== GET_FROM_BUFFER
8362 /* When the iterator is at base embedding level, we
8363 are guaranteed that characters are delivered for
8364 display in strictly increasing order of their
8365 buffer positions. */
8366 || BIDI_AT_BASE_LEVEL (it
->bidi_it
))
8367 && IT_CHARPOS (*it
) > to_charpos
)
8369 && (prev_method
== GET_FROM_IMAGE
8370 || prev_method
== GET_FROM_STRETCH
8371 || prev_method
== GET_FROM_STRING
)
8372 /* Passed TO_CHARPOS from left to right. */
8373 && ((prev_pos
< to_charpos
8374 && IT_CHARPOS (*it
) > to_charpos
)
8375 /* Passed TO_CHARPOS from right to left. */
8376 || (prev_pos
> to_charpos
8377 && IT_CHARPOS (*it
) < to_charpos
)))))
8379 if (it
->line_wrap
!= WORD_WRAP
|| wrap_it
.sp
< 0)
8381 result
= MOVE_POS_MATCH_OR_ZV
;
8384 else if (it
->line_wrap
== WORD_WRAP
&& atpos_it
.sp
< 0)
8385 /* If wrap_it is valid, the current position might be in a
8386 word that is wrapped. So, save the iterator in
8387 atpos_it and continue to see if wrapping happens. */
8388 SAVE_IT (atpos_it
, *it
, atpos_data
);
8391 /* Stop when ZV reached.
8392 We used to stop here when TO_CHARPOS reached as well, but that is
8393 too soon if this glyph does not fit on this line. So we handle it
8394 explicitly below. */
8395 if (!get_next_display_element (it
))
8397 result
= MOVE_POS_MATCH_OR_ZV
;
8401 if (it
->line_wrap
== TRUNCATE
)
8403 if (BUFFER_POS_REACHED_P ())
8405 result
= MOVE_POS_MATCH_OR_ZV
;
8411 if (it
->line_wrap
== WORD_WRAP
)
8413 if (IT_DISPLAYING_WHITESPACE (it
))
8417 /* We have reached a glyph that follows one or more
8418 whitespace characters. If the position is
8419 already found, we are done. */
8420 if (atpos_it
.sp
>= 0)
8422 RESTORE_IT (it
, &atpos_it
, atpos_data
);
8423 result
= MOVE_POS_MATCH_OR_ZV
;
8428 RESTORE_IT (it
, &atx_it
, atx_data
);
8429 result
= MOVE_X_REACHED
;
8432 /* Otherwise, we can wrap here. */
8433 SAVE_IT (wrap_it
, *it
, wrap_data
);
8439 /* Remember the line height for the current line, in case
8440 the next element doesn't fit on the line. */
8441 ascent
= it
->max_ascent
;
8442 descent
= it
->max_descent
;
8444 /* The call to produce_glyphs will get the metrics of the
8445 display element IT is loaded with. Record the x-position
8446 before this display element, in case it doesn't fit on the
8450 PRODUCE_GLYPHS (it
);
8452 if (it
->area
!= TEXT_AREA
)
8454 prev_method
= it
->method
;
8455 if (it
->method
== GET_FROM_BUFFER
)
8456 prev_pos
= IT_CHARPOS (*it
);
8457 set_iterator_to_next (it
, 1);
8458 if (IT_CHARPOS (*it
) < CHARPOS (this_line_min_pos
))
8459 SET_TEXT_POS (this_line_min_pos
,
8460 IT_CHARPOS (*it
), IT_BYTEPOS (*it
));
8462 && (op
& MOVE_TO_POS
)
8463 && IT_CHARPOS (*it
) > to_charpos
8464 && IT_CHARPOS (*it
) < IT_CHARPOS (ppos_it
))
8465 SAVE_IT (ppos_it
, *it
, ppos_data
);
8469 /* The number of glyphs we get back in IT->nglyphs will normally
8470 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
8471 character on a terminal frame, or (iii) a line end. For the
8472 second case, IT->nglyphs - 1 padding glyphs will be present.
8473 (On X frames, there is only one glyph produced for a
8474 composite character.)
8476 The behavior implemented below means, for continuation lines,
8477 that as many spaces of a TAB as fit on the current line are
8478 displayed there. For terminal frames, as many glyphs of a
8479 multi-glyph character are displayed in the current line, too.
8480 This is what the old redisplay code did, and we keep it that
8481 way. Under X, the whole shape of a complex character must
8482 fit on the line or it will be completely displayed in the
8485 Note that both for tabs and padding glyphs, all glyphs have
8489 /* More than one glyph or glyph doesn't fit on line. All
8490 glyphs have the same width. */
8491 int single_glyph_width
= it
->pixel_width
/ it
->nglyphs
;
8493 int x_before_this_char
= x
;
8494 int hpos_before_this_char
= it
->hpos
;
8496 for (i
= 0; i
< it
->nglyphs
; ++i
, x
= new_x
)
8498 new_x
= x
+ single_glyph_width
;
8500 /* We want to leave anything reaching TO_X to the caller. */
8501 if ((op
& MOVE_TO_X
) && new_x
> to_x
)
8503 if (BUFFER_POS_REACHED_P ())
8505 if (it
->line_wrap
!= WORD_WRAP
|| wrap_it
.sp
< 0)
8506 goto buffer_pos_reached
;
8507 if (atpos_it
.sp
< 0)
8509 SAVE_IT (atpos_it
, *it
, atpos_data
);
8510 IT_RESET_X_ASCENT_DESCENT (&atpos_it
);
8515 if (it
->line_wrap
!= WORD_WRAP
|| wrap_it
.sp
< 0)
8518 result
= MOVE_X_REACHED
;
8523 SAVE_IT (atx_it
, *it
, atx_data
);
8524 IT_RESET_X_ASCENT_DESCENT (&atx_it
);
8529 if (/* Lines are continued. */
8530 it
->line_wrap
!= TRUNCATE
8531 && (/* And glyph doesn't fit on the line. */
8532 new_x
> it
->last_visible_x
8533 /* Or it fits exactly and we're on a window
8535 || (new_x
== it
->last_visible_x
8536 && FRAME_WINDOW_P (it
->f
)
8537 && ((it
->bidi_p
&& it
->bidi_it
.paragraph_dir
== R2L
)
8538 ? WINDOW_LEFT_FRINGE_WIDTH (it
->w
)
8539 : WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)))))
8541 if (/* IT->hpos == 0 means the very first glyph
8542 doesn't fit on the line, e.g. a wide image. */
8544 || (new_x
== it
->last_visible_x
8545 && FRAME_WINDOW_P (it
->f
)))
8548 it
->current_x
= new_x
;
8550 /* The character's last glyph just barely fits
8552 if (i
== it
->nglyphs
- 1)
8554 /* If this is the destination position,
8555 return a position *before* it in this row,
8556 now that we know it fits in this row. */
8557 if (BUFFER_POS_REACHED_P ())
8559 if (it
->line_wrap
!= WORD_WRAP
8562 it
->hpos
= hpos_before_this_char
;
8563 it
->current_x
= x_before_this_char
;
8564 result
= MOVE_POS_MATCH_OR_ZV
;
8567 if (it
->line_wrap
== WORD_WRAP
8570 SAVE_IT (atpos_it
, *it
, atpos_data
);
8571 atpos_it
.current_x
= x_before_this_char
;
8572 atpos_it
.hpos
= hpos_before_this_char
;
8576 prev_method
= it
->method
;
8577 if (it
->method
== GET_FROM_BUFFER
)
8578 prev_pos
= IT_CHARPOS (*it
);
8579 set_iterator_to_next (it
, 1);
8580 if (IT_CHARPOS (*it
) < CHARPOS (this_line_min_pos
))
8581 SET_TEXT_POS (this_line_min_pos
,
8582 IT_CHARPOS (*it
), IT_BYTEPOS (*it
));
8583 /* On graphical terminals, newlines may
8584 "overflow" into the fringe if
8585 overflow-newline-into-fringe is non-nil.
8586 On text terminals, and on graphical
8587 terminals with no right margin, newlines
8588 may overflow into the last glyph on the
8590 if (!FRAME_WINDOW_P (it
->f
)
8592 && it
->bidi_it
.paragraph_dir
== R2L
)
8593 ? WINDOW_LEFT_FRINGE_WIDTH (it
->w
)
8594 : WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)) == 0
8595 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
8597 if (!get_next_display_element (it
))
8599 result
= MOVE_POS_MATCH_OR_ZV
;
8602 if (BUFFER_POS_REACHED_P ())
8604 if (ITERATOR_AT_END_OF_LINE_P (it
))
8605 result
= MOVE_POS_MATCH_OR_ZV
;
8607 result
= MOVE_LINE_CONTINUED
;
8610 if (ITERATOR_AT_END_OF_LINE_P (it
)
8611 && (it
->line_wrap
!= WORD_WRAP
8614 result
= MOVE_NEWLINE_OR_CR
;
8621 IT_RESET_X_ASCENT_DESCENT (it
);
8623 if (wrap_it
.sp
>= 0)
8625 RESTORE_IT (it
, &wrap_it
, wrap_data
);
8630 TRACE_MOVE ((stderr
, "move_it_in: continued at %d\n",
8632 result
= MOVE_LINE_CONTINUED
;
8636 if (BUFFER_POS_REACHED_P ())
8638 if (it
->line_wrap
!= WORD_WRAP
|| wrap_it
.sp
< 0)
8639 goto buffer_pos_reached
;
8640 if (it
->line_wrap
== WORD_WRAP
&& atpos_it
.sp
< 0)
8642 SAVE_IT (atpos_it
, *it
, atpos_data
);
8643 IT_RESET_X_ASCENT_DESCENT (&atpos_it
);
8647 if (new_x
> it
->first_visible_x
)
8649 /* Glyph is visible. Increment number of glyphs that
8650 would be displayed. */
8655 if (result
!= MOVE_UNDEFINED
)
8658 else if (BUFFER_POS_REACHED_P ())
8661 IT_RESET_X_ASCENT_DESCENT (it
);
8662 result
= MOVE_POS_MATCH_OR_ZV
;
8665 else if ((op
& MOVE_TO_X
) && it
->current_x
>= to_x
)
8667 /* Stop when TO_X specified and reached. This check is
8668 necessary here because of lines consisting of a line end,
8669 only. The line end will not produce any glyphs and we
8670 would never get MOVE_X_REACHED. */
8671 eassert (it
->nglyphs
== 0);
8672 result
= MOVE_X_REACHED
;
8676 /* Is this a line end? If yes, we're done. */
8677 if (ITERATOR_AT_END_OF_LINE_P (it
))
8679 /* If we are past TO_CHARPOS, but never saw any character
8680 positions smaller than TO_CHARPOS, return
8681 MOVE_POS_MATCH_OR_ZV, like the unidirectional display
8683 if (it
->bidi_p
&& (op
& MOVE_TO_POS
) != 0)
8685 if (!saw_smaller_pos
&& IT_CHARPOS (*it
) > to_charpos
)
8687 if (IT_CHARPOS (ppos_it
) < ZV
)
8689 RESTORE_IT (it
, &ppos_it
, ppos_data
);
8690 result
= MOVE_POS_MATCH_OR_ZV
;
8693 goto buffer_pos_reached
;
8695 else if (it
->line_wrap
== WORD_WRAP
&& atpos_it
.sp
>= 0
8696 && IT_CHARPOS (*it
) > to_charpos
)
8697 goto buffer_pos_reached
;
8699 result
= MOVE_NEWLINE_OR_CR
;
8702 result
= MOVE_NEWLINE_OR_CR
;
8706 prev_method
= it
->method
;
8707 if (it
->method
== GET_FROM_BUFFER
)
8708 prev_pos
= IT_CHARPOS (*it
);
8709 /* The current display element has been consumed. Advance
8711 set_iterator_to_next (it
, 1);
8712 if (IT_CHARPOS (*it
) < CHARPOS (this_line_min_pos
))
8713 SET_TEXT_POS (this_line_min_pos
, IT_CHARPOS (*it
), IT_BYTEPOS (*it
));
8714 if (IT_CHARPOS (*it
) < to_charpos
)
8715 saw_smaller_pos
= 1;
8717 && (op
& MOVE_TO_POS
)
8718 && IT_CHARPOS (*it
) >= to_charpos
8719 && IT_CHARPOS (*it
) < IT_CHARPOS (ppos_it
))
8720 SAVE_IT (ppos_it
, *it
, ppos_data
);
8722 /* Stop if lines are truncated and IT's current x-position is
8723 past the right edge of the window now. */
8724 if (it
->line_wrap
== TRUNCATE
8725 && it
->current_x
>= it
->last_visible_x
)
8727 if (!FRAME_WINDOW_P (it
->f
)
8728 || ((it
->bidi_p
&& it
->bidi_it
.paragraph_dir
== R2L
)
8729 ? WINDOW_LEFT_FRINGE_WIDTH (it
->w
)
8730 : WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)) == 0
8731 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
8735 if ((at_eob_p
= !get_next_display_element (it
))
8736 || BUFFER_POS_REACHED_P ()
8737 /* If we are past TO_CHARPOS, but never saw any
8738 character positions smaller than TO_CHARPOS,
8739 return MOVE_POS_MATCH_OR_ZV, like the
8740 unidirectional display did. */
8741 || (it
->bidi_p
&& (op
& MOVE_TO_POS
) != 0
8743 && IT_CHARPOS (*it
) > to_charpos
))
8746 && !at_eob_p
&& IT_CHARPOS (ppos_it
) < ZV
)
8747 RESTORE_IT (it
, &ppos_it
, ppos_data
);
8748 result
= MOVE_POS_MATCH_OR_ZV
;
8751 if (ITERATOR_AT_END_OF_LINE_P (it
))
8753 result
= MOVE_NEWLINE_OR_CR
;
8757 else if (it
->bidi_p
&& (op
& MOVE_TO_POS
) != 0
8759 && IT_CHARPOS (*it
) > to_charpos
)
8761 if (IT_CHARPOS (ppos_it
) < ZV
)
8762 RESTORE_IT (it
, &ppos_it
, ppos_data
);
8763 result
= MOVE_POS_MATCH_OR_ZV
;
8766 result
= MOVE_LINE_TRUNCATED
;
8769 #undef IT_RESET_X_ASCENT_DESCENT
8772 #undef BUFFER_POS_REACHED_P
8774 /* If we scanned beyond to_pos and didn't find a point to wrap at,
8775 restore the saved iterator. */
8776 if (atpos_it
.sp
>= 0)
8777 RESTORE_IT (it
, &atpos_it
, atpos_data
);
8778 else if (atx_it
.sp
>= 0)
8779 RESTORE_IT (it
, &atx_it
, atx_data
);
8784 bidi_unshelve_cache (atpos_data
, 1);
8786 bidi_unshelve_cache (atx_data
, 1);
8788 bidi_unshelve_cache (wrap_data
, 1);
8790 bidi_unshelve_cache (ppos_data
, 1);
8792 /* Restore the iterator settings altered at the beginning of this
8794 it
->glyph_row
= saved_glyph_row
;
8798 /* For external use. */
8800 move_it_in_display_line (struct it
*it
,
8801 ptrdiff_t to_charpos
, int to_x
,
8802 enum move_operation_enum op
)
8804 if (it
->line_wrap
== WORD_WRAP
8805 && (op
& MOVE_TO_X
))
8808 void *save_data
= NULL
;
8811 SAVE_IT (save_it
, *it
, save_data
);
8812 skip
= move_it_in_display_line_to (it
, to_charpos
, to_x
, op
);
8813 /* When word-wrap is on, TO_X may lie past the end
8814 of a wrapped line. Then it->current is the
8815 character on the next line, so backtrack to the
8816 space before the wrap point. */
8817 if (skip
== MOVE_LINE_CONTINUED
)
8819 int prev_x
= max (it
->current_x
- 1, 0);
8820 RESTORE_IT (it
, &save_it
, save_data
);
8821 move_it_in_display_line_to
8822 (it
, -1, prev_x
, MOVE_TO_X
);
8825 bidi_unshelve_cache (save_data
, 1);
8828 move_it_in_display_line_to (it
, to_charpos
, to_x
, op
);
8832 /* Move IT forward until it satisfies one or more of the criteria in
8833 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
8835 OP is a bit-mask that specifies where to stop, and in particular,
8836 which of those four position arguments makes a difference. See the
8837 description of enum move_operation_enum.
8839 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
8840 screen line, this function will set IT to the next position that is
8841 displayed to the right of TO_CHARPOS on the screen. */
8844 move_it_to (struct it
*it
, ptrdiff_t to_charpos
, int to_x
, int to_y
, int to_vpos
, int op
)
8846 enum move_it_result skip
, skip2
= MOVE_X_REACHED
;
8847 int line_height
, line_start_x
= 0, reached
= 0;
8848 void *backup_data
= NULL
;
8852 if (op
& MOVE_TO_VPOS
)
8854 /* If no TO_CHARPOS and no TO_X specified, stop at the
8855 start of the line TO_VPOS. */
8856 if ((op
& (MOVE_TO_X
| MOVE_TO_POS
)) == 0)
8858 if (it
->vpos
== to_vpos
)
8864 skip
= move_it_in_display_line_to (it
, -1, -1, 0);
8868 /* TO_VPOS >= 0 means stop at TO_X in the line at
8869 TO_VPOS, or at TO_POS, whichever comes first. */
8870 if (it
->vpos
== to_vpos
)
8876 skip
= move_it_in_display_line_to (it
, to_charpos
, to_x
, op
);
8878 if (skip
== MOVE_POS_MATCH_OR_ZV
|| it
->vpos
== to_vpos
)
8883 else if (skip
== MOVE_X_REACHED
&& it
->vpos
!= to_vpos
)
8885 /* We have reached TO_X but not in the line we want. */
8886 skip
= move_it_in_display_line_to (it
, to_charpos
,
8888 if (skip
== MOVE_POS_MATCH_OR_ZV
)
8896 else if (op
& MOVE_TO_Y
)
8898 struct it it_backup
;
8900 if (it
->line_wrap
== WORD_WRAP
)
8901 SAVE_IT (it_backup
, *it
, backup_data
);
8903 /* TO_Y specified means stop at TO_X in the line containing
8904 TO_Y---or at TO_CHARPOS if this is reached first. The
8905 problem is that we can't really tell whether the line
8906 contains TO_Y before we have completely scanned it, and
8907 this may skip past TO_X. What we do is to first scan to
8910 If TO_X is not specified, use a TO_X of zero. The reason
8911 is to make the outcome of this function more predictable.
8912 If we didn't use TO_X == 0, we would stop at the end of
8913 the line which is probably not what a caller would expect
8915 skip
= move_it_in_display_line_to
8916 (it
, to_charpos
, ((op
& MOVE_TO_X
) ? to_x
: 0),
8917 (MOVE_TO_X
| (op
& MOVE_TO_POS
)));
8919 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
8920 if (skip
== MOVE_POS_MATCH_OR_ZV
)
8922 else if (skip
== MOVE_X_REACHED
)
8924 /* If TO_X was reached, we want to know whether TO_Y is
8925 in the line. We know this is the case if the already
8926 scanned glyphs make the line tall enough. Otherwise,
8927 we must check by scanning the rest of the line. */
8928 line_height
= it
->max_ascent
+ it
->max_descent
;
8929 if (to_y
>= it
->current_y
8930 && to_y
< it
->current_y
+ line_height
)
8935 SAVE_IT (it_backup
, *it
, backup_data
);
8936 TRACE_MOVE ((stderr
, "move_it: from %d\n", IT_CHARPOS (*it
)));
8937 skip2
= move_it_in_display_line_to (it
, to_charpos
, -1,
8939 TRACE_MOVE ((stderr
, "move_it: to %d\n", IT_CHARPOS (*it
)));
8940 line_height
= it
->max_ascent
+ it
->max_descent
;
8941 TRACE_MOVE ((stderr
, "move_it: line_height = %d\n", line_height
));
8943 if (to_y
>= it
->current_y
8944 && to_y
< it
->current_y
+ line_height
)
8946 /* If TO_Y is in this line and TO_X was reached
8947 above, we scanned too far. We have to restore
8948 IT's settings to the ones before skipping. But
8949 keep the more accurate values of max_ascent and
8950 max_descent we've found while skipping the rest
8951 of the line, for the sake of callers, such as
8952 pos_visible_p, that need to know the line
8954 int max_ascent
= it
->max_ascent
;
8955 int max_descent
= it
->max_descent
;
8957 RESTORE_IT (it
, &it_backup
, backup_data
);
8958 it
->max_ascent
= max_ascent
;
8959 it
->max_descent
= max_descent
;
8965 if (skip
== MOVE_POS_MATCH_OR_ZV
)
8971 /* Check whether TO_Y is in this line. */
8972 line_height
= it
->max_ascent
+ it
->max_descent
;
8973 TRACE_MOVE ((stderr
, "move_it: line_height = %d\n", line_height
));
8975 if (to_y
>= it
->current_y
8976 && to_y
< it
->current_y
+ line_height
)
8978 /* When word-wrap is on, TO_X may lie past the end
8979 of a wrapped line. Then it->current is the
8980 character on the next line, so backtrack to the
8981 space before the wrap point. */
8982 if (skip
== MOVE_LINE_CONTINUED
8983 && it
->line_wrap
== WORD_WRAP
)
8985 int prev_x
= max (it
->current_x
- 1, 0);
8986 RESTORE_IT (it
, &it_backup
, backup_data
);
8987 skip
= move_it_in_display_line_to
8988 (it
, -1, prev_x
, MOVE_TO_X
);
8997 else if (BUFFERP (it
->object
)
8998 && (it
->method
== GET_FROM_BUFFER
8999 || it
->method
== GET_FROM_STRETCH
)
9000 && IT_CHARPOS (*it
) >= to_charpos
9001 /* Under bidi iteration, a call to set_iterator_to_next
9002 can scan far beyond to_charpos if the initial
9003 portion of the next line needs to be reordered. In
9004 that case, give move_it_in_display_line_to another
9007 && it
->bidi_it
.scan_dir
== -1))
9008 skip
= MOVE_POS_MATCH_OR_ZV
;
9010 skip
= move_it_in_display_line_to (it
, to_charpos
, -1, MOVE_TO_POS
);
9014 case MOVE_POS_MATCH_OR_ZV
:
9018 case MOVE_NEWLINE_OR_CR
:
9019 set_iterator_to_next (it
, 1);
9020 it
->continuation_lines_width
= 0;
9023 case MOVE_LINE_TRUNCATED
:
9024 it
->continuation_lines_width
= 0;
9025 reseat_at_next_visible_line_start (it
, 0);
9026 if ((op
& MOVE_TO_POS
) != 0
9027 && IT_CHARPOS (*it
) > to_charpos
)
9034 case MOVE_LINE_CONTINUED
:
9035 /* For continued lines ending in a tab, some of the glyphs
9036 associated with the tab are displayed on the current
9037 line. Since it->current_x does not include these glyphs,
9038 we use it->last_visible_x instead. */
9041 it
->continuation_lines_width
+= it
->last_visible_x
;
9042 /* When moving by vpos, ensure that the iterator really
9043 advances to the next line (bug#847, bug#969). Fixme:
9044 do we need to do this in other circumstances? */
9045 if (it
->current_x
!= it
->last_visible_x
9046 && (op
& MOVE_TO_VPOS
)
9047 && !(op
& (MOVE_TO_X
| MOVE_TO_POS
)))
9049 line_start_x
= it
->current_x
+ it
->pixel_width
9050 - it
->last_visible_x
;
9051 set_iterator_to_next (it
, 0);
9055 it
->continuation_lines_width
+= it
->current_x
;
9062 /* Reset/increment for the next run. */
9063 recenter_overlay_lists (current_buffer
, IT_CHARPOS (*it
));
9064 it
->current_x
= line_start_x
;
9067 it
->current_y
+= it
->max_ascent
+ it
->max_descent
;
9069 last_height
= it
->max_ascent
+ it
->max_descent
;
9070 it
->max_ascent
= it
->max_descent
= 0;
9075 /* On text terminals, we may stop at the end of a line in the middle
9076 of a multi-character glyph. If the glyph itself is continued,
9077 i.e. it is actually displayed on the next line, don't treat this
9078 stopping point as valid; move to the next line instead (unless
9079 that brings us offscreen). */
9080 if (!FRAME_WINDOW_P (it
->f
)
9082 && IT_CHARPOS (*it
) == to_charpos
9083 && it
->what
== IT_CHARACTER
9085 && it
->line_wrap
== WINDOW_WRAP
9086 && it
->current_x
== it
->last_visible_x
- 1
9089 && it
->vpos
< it
->w
->window_end_vpos
)
9091 it
->continuation_lines_width
+= it
->current_x
;
9092 it
->current_x
= it
->hpos
= it
->max_ascent
= it
->max_descent
= 0;
9093 it
->current_y
+= it
->max_ascent
+ it
->max_descent
;
9095 last_height
= it
->max_ascent
+ it
->max_descent
;
9099 bidi_unshelve_cache (backup_data
, 1);
9101 TRACE_MOVE ((stderr
, "move_it_to: reached %d\n", reached
));
9105 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
9107 If DY > 0, move IT backward at least that many pixels. DY = 0
9108 means move IT backward to the preceding line start or BEGV. This
9109 function may move over more than DY pixels if IT->current_y - DY
9110 ends up in the middle of a line; in this case IT->current_y will be
9111 set to the top of the line moved to. */
9114 move_it_vertically_backward (struct it
*it
, int dy
)
9118 void *it2data
= NULL
, *it3data
= NULL
;
9119 ptrdiff_t start_pos
;
9121 = (it
->last_visible_x
- it
->first_visible_x
) / FRAME_COLUMN_WIDTH (it
->f
);
9122 ptrdiff_t pos_limit
;
9127 start_pos
= IT_CHARPOS (*it
);
9129 /* Estimate how many newlines we must move back. */
9130 nlines
= max (1, dy
/ default_line_pixel_height (it
->w
));
9131 if (it
->line_wrap
== TRUNCATE
)
9134 pos_limit
= max (start_pos
- nlines
* nchars_per_row
, BEGV
);
9136 /* Set the iterator's position that many lines back. But don't go
9137 back more than NLINES full screen lines -- this wins a day with
9138 buffers which have very long lines. */
9139 while (nlines
-- && IT_CHARPOS (*it
) > pos_limit
)
9140 back_to_previous_visible_line_start (it
);
9142 /* Reseat the iterator here. When moving backward, we don't want
9143 reseat to skip forward over invisible text, set up the iterator
9144 to deliver from overlay strings at the new position etc. So,
9145 use reseat_1 here. */
9146 reseat_1 (it
, it
->current
.pos
, 1);
9148 /* We are now surely at a line start. */
9149 it
->current_x
= it
->hpos
= 0; /* FIXME: this is incorrect when bidi
9150 reordering is in effect. */
9151 it
->continuation_lines_width
= 0;
9153 /* Move forward and see what y-distance we moved. First move to the
9154 start of the next line so that we get its height. We need this
9155 height to be able to tell whether we reached the specified
9157 SAVE_IT (it2
, *it
, it2data
);
9158 it2
.max_ascent
= it2
.max_descent
= 0;
9161 move_it_to (&it2
, start_pos
, -1, -1, it2
.vpos
+ 1,
9162 MOVE_TO_POS
| MOVE_TO_VPOS
);
9164 while (!(IT_POS_VALID_AFTER_MOVE_P (&it2
)
9165 /* If we are in a display string which starts at START_POS,
9166 and that display string includes a newline, and we are
9167 right after that newline (i.e. at the beginning of a
9168 display line), exit the loop, because otherwise we will
9169 infloop, since move_it_to will see that it is already at
9170 START_POS and will not move. */
9171 || (it2
.method
== GET_FROM_STRING
9172 && IT_CHARPOS (it2
) == start_pos
9173 && SREF (it2
.string
, IT_STRING_BYTEPOS (it2
) - 1) == '\n')));
9174 eassert (IT_CHARPOS (*it
) >= BEGV
);
9175 SAVE_IT (it3
, it2
, it3data
);
9177 move_it_to (&it2
, start_pos
, -1, -1, -1, MOVE_TO_POS
);
9178 eassert (IT_CHARPOS (*it
) >= BEGV
);
9179 /* H is the actual vertical distance from the position in *IT
9180 and the starting position. */
9181 h
= it2
.current_y
- it
->current_y
;
9182 /* NLINES is the distance in number of lines. */
9183 nlines
= it2
.vpos
- it
->vpos
;
9185 /* Correct IT's y and vpos position
9186 so that they are relative to the starting point. */
9192 /* DY == 0 means move to the start of the screen line. The
9193 value of nlines is > 0 if continuation lines were involved,
9194 or if the original IT position was at start of a line. */
9195 RESTORE_IT (it
, it
, it2data
);
9197 move_it_by_lines (it
, nlines
);
9198 /* The above code moves us to some position NLINES down,
9199 usually to its first glyph (leftmost in an L2R line), but
9200 that's not necessarily the start of the line, under bidi
9201 reordering. We want to get to the character position
9202 that is immediately after the newline of the previous
9205 && !it
->continuation_lines_width
9206 && !STRINGP (it
->string
)
9207 && IT_CHARPOS (*it
) > BEGV
9208 && FETCH_BYTE (IT_BYTEPOS (*it
) - 1) != '\n')
9210 ptrdiff_t cp
= IT_CHARPOS (*it
), bp
= IT_BYTEPOS (*it
);
9213 cp
= find_newline_no_quit (cp
, bp
, -1, NULL
);
9214 move_it_to (it
, cp
, -1, -1, -1, MOVE_TO_POS
);
9216 bidi_unshelve_cache (it3data
, 1);
9220 /* The y-position we try to reach, relative to *IT.
9221 Note that H has been subtracted in front of the if-statement. */
9222 int target_y
= it
->current_y
+ h
- dy
;
9223 int y0
= it3
.current_y
;
9227 RESTORE_IT (&it3
, &it3
, it3data
);
9228 y1
= line_bottom_y (&it3
);
9229 line_height
= y1
- y0
;
9230 RESTORE_IT (it
, it
, it2data
);
9231 /* If we did not reach target_y, try to move further backward if
9232 we can. If we moved too far backward, try to move forward. */
9233 if (target_y
< it
->current_y
9234 /* This is heuristic. In a window that's 3 lines high, with
9235 a line height of 13 pixels each, recentering with point
9236 on the bottom line will try to move -39/2 = 19 pixels
9237 backward. Try to avoid moving into the first line. */
9238 && (it
->current_y
- target_y
9239 > min (window_box_height (it
->w
), line_height
* 2 / 3))
9240 && IT_CHARPOS (*it
) > BEGV
)
9242 TRACE_MOVE ((stderr
, " not far enough -> move_vert %d\n",
9243 target_y
- it
->current_y
));
9244 dy
= it
->current_y
- target_y
;
9245 goto move_further_back
;
9247 else if (target_y
>= it
->current_y
+ line_height
9248 && IT_CHARPOS (*it
) < ZV
)
9250 /* Should move forward by at least one line, maybe more.
9252 Note: Calling move_it_by_lines can be expensive on
9253 terminal frames, where compute_motion is used (via
9254 vmotion) to do the job, when there are very long lines
9255 and truncate-lines is nil. That's the reason for
9256 treating terminal frames specially here. */
9258 if (!FRAME_WINDOW_P (it
->f
))
9259 move_it_vertically (it
, target_y
- (it
->current_y
+ line_height
));
9264 move_it_by_lines (it
, 1);
9266 while (target_y
>= line_bottom_y (it
) && IT_CHARPOS (*it
) < ZV
);
9273 /* Move IT by a specified amount of pixel lines DY. DY negative means
9274 move backwards. DY = 0 means move to start of screen line. At the
9275 end, IT will be on the start of a screen line. */
9278 move_it_vertically (struct it
*it
, int dy
)
9281 move_it_vertically_backward (it
, -dy
);
9284 TRACE_MOVE ((stderr
, "move_it_v: from %d, %d\n", IT_CHARPOS (*it
), dy
));
9285 move_it_to (it
, ZV
, -1, it
->current_y
+ dy
, -1,
9286 MOVE_TO_POS
| MOVE_TO_Y
);
9287 TRACE_MOVE ((stderr
, "move_it_v: to %d\n", IT_CHARPOS (*it
)));
9289 /* If buffer ends in ZV without a newline, move to the start of
9290 the line to satisfy the post-condition. */
9291 if (IT_CHARPOS (*it
) == ZV
9293 && FETCH_BYTE (IT_BYTEPOS (*it
) - 1) != '\n')
9294 move_it_by_lines (it
, 0);
9299 /* Move iterator IT past the end of the text line it is in. */
9302 move_it_past_eol (struct it
*it
)
9304 enum move_it_result rc
;
9306 rc
= move_it_in_display_line_to (it
, Z
, 0, MOVE_TO_POS
);
9307 if (rc
== MOVE_NEWLINE_OR_CR
)
9308 set_iterator_to_next (it
, 0);
9312 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
9313 negative means move up. DVPOS == 0 means move to the start of the
9316 Optimization idea: If we would know that IT->f doesn't use
9317 a face with proportional font, we could be faster for
9318 truncate-lines nil. */
9321 move_it_by_lines (struct it
*it
, ptrdiff_t dvpos
)
9324 /* The commented-out optimization uses vmotion on terminals. This
9325 gives bad results, because elements like it->what, on which
9326 callers such as pos_visible_p rely, aren't updated. */
9327 /* struct position pos;
9328 if (!FRAME_WINDOW_P (it->f))
9330 struct text_pos textpos;
9332 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
9333 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
9334 reseat (it, textpos, 1);
9335 it->vpos += pos.vpos;
9336 it->current_y += pos.vpos;
9342 /* DVPOS == 0 means move to the start of the screen line. */
9343 move_it_vertically_backward (it
, 0);
9344 /* Let next call to line_bottom_y calculate real line height. */
9349 move_it_to (it
, -1, -1, -1, it
->vpos
+ dvpos
, MOVE_TO_VPOS
);
9350 if (!IT_POS_VALID_AFTER_MOVE_P (it
))
9352 /* Only move to the next buffer position if we ended up in a
9353 string from display property, not in an overlay string
9354 (before-string or after-string). That is because the
9355 latter don't conceal the underlying buffer position, so
9356 we can ask to move the iterator to the exact position we
9357 are interested in. Note that, even if we are already at
9358 IT_CHARPOS (*it), the call below is not a no-op, as it
9359 will detect that we are at the end of the string, pop the
9360 iterator, and compute it->current_x and it->hpos
9362 move_it_to (it
, IT_CHARPOS (*it
) + it
->string_from_display_prop_p
,
9363 -1, -1, -1, MOVE_TO_POS
);
9369 void *it2data
= NULL
;
9370 ptrdiff_t start_charpos
, i
;
9372 = (it
->last_visible_x
- it
->first_visible_x
) / FRAME_COLUMN_WIDTH (it
->f
);
9373 ptrdiff_t pos_limit
;
9375 /* Start at the beginning of the screen line containing IT's
9376 position. This may actually move vertically backwards,
9377 in case of overlays, so adjust dvpos accordingly. */
9379 move_it_vertically_backward (it
, 0);
9382 /* Go back -DVPOS buffer lines, but no farther than -DVPOS full
9383 screen lines, and reseat the iterator there. */
9384 start_charpos
= IT_CHARPOS (*it
);
9385 if (it
->line_wrap
== TRUNCATE
)
9388 pos_limit
= max (start_charpos
+ dvpos
* nchars_per_row
, BEGV
);
9389 for (i
= -dvpos
; i
> 0 && IT_CHARPOS (*it
) > pos_limit
; --i
)
9390 back_to_previous_visible_line_start (it
);
9391 reseat (it
, it
->current
.pos
, 1);
9393 /* Move further back if we end up in a string or an image. */
9394 while (!IT_POS_VALID_AFTER_MOVE_P (it
))
9396 /* First try to move to start of display line. */
9398 move_it_vertically_backward (it
, 0);
9400 if (IT_POS_VALID_AFTER_MOVE_P (it
))
9402 /* If start of line is still in string or image,
9403 move further back. */
9404 back_to_previous_visible_line_start (it
);
9405 reseat (it
, it
->current
.pos
, 1);
9409 it
->current_x
= it
->hpos
= 0;
9411 /* Above call may have moved too far if continuation lines
9412 are involved. Scan forward and see if it did. */
9413 SAVE_IT (it2
, *it
, it2data
);
9414 it2
.vpos
= it2
.current_y
= 0;
9415 move_it_to (&it2
, start_charpos
, -1, -1, -1, MOVE_TO_POS
);
9416 it
->vpos
-= it2
.vpos
;
9417 it
->current_y
-= it2
.current_y
;
9418 it
->current_x
= it
->hpos
= 0;
9420 /* If we moved too far back, move IT some lines forward. */
9421 if (it2
.vpos
> -dvpos
)
9423 int delta
= it2
.vpos
+ dvpos
;
9425 RESTORE_IT (&it2
, &it2
, it2data
);
9426 SAVE_IT (it2
, *it
, it2data
);
9427 move_it_to (it
, -1, -1, -1, it
->vpos
+ delta
, MOVE_TO_VPOS
);
9428 /* Move back again if we got too far ahead. */
9429 if (IT_CHARPOS (*it
) >= start_charpos
)
9430 RESTORE_IT (it
, &it2
, it2data
);
9432 bidi_unshelve_cache (it2data
, 1);
9435 RESTORE_IT (it
, it
, it2data
);
9439 /* Return 1 if IT points into the middle of a display vector. */
9442 in_display_vector_p (struct it
*it
)
9444 return (it
->method
== GET_FROM_DISPLAY_VECTOR
9445 && it
->current
.dpvec_index
> 0
9446 && it
->dpvec
+ it
->current
.dpvec_index
!= it
->dpend
);
9450 /***********************************************************************
9452 ***********************************************************************/
9455 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
9459 add_to_log (const char *format
, Lisp_Object arg1
, Lisp_Object arg2
)
9461 Lisp_Object args
[3];
9462 Lisp_Object msg
, fmt
;
9465 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
9469 GCPRO4 (fmt
, msg
, arg1
, arg2
);
9471 args
[0] = fmt
= build_string (format
);
9474 msg
= Fformat (3, args
);
9476 len
= SBYTES (msg
) + 1;
9477 buffer
= SAFE_ALLOCA (len
);
9478 memcpy (buffer
, SDATA (msg
), len
);
9480 message_dolog (buffer
, len
- 1, 1, 0);
9487 /* Output a newline in the *Messages* buffer if "needs" one. */
9490 message_log_maybe_newline (void)
9492 if (message_log_need_newline
)
9493 message_dolog ("", 0, 1, 0);
9497 /* Add a string M of length NBYTES to the message log, optionally
9498 terminated with a newline when NLFLAG is true. MULTIBYTE, if
9499 true, means interpret the contents of M as multibyte. This
9500 function calls low-level routines in order to bypass text property
9501 hooks, etc. which might not be safe to run.
9503 This may GC (insert may run before/after change hooks),
9504 so the buffer M must NOT point to a Lisp string. */
9507 message_dolog (const char *m
, ptrdiff_t nbytes
, bool nlflag
, bool multibyte
)
9509 const unsigned char *msg
= (const unsigned char *) m
;
9511 if (!NILP (Vmemory_full
))
9514 if (!NILP (Vmessage_log_max
))
9516 struct buffer
*oldbuf
;
9517 Lisp_Object oldpoint
, oldbegv
, oldzv
;
9518 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
9519 ptrdiff_t point_at_end
= 0;
9520 ptrdiff_t zv_at_end
= 0;
9521 Lisp_Object old_deactivate_mark
;
9522 struct gcpro gcpro1
;
9524 old_deactivate_mark
= Vdeactivate_mark
;
9525 oldbuf
= current_buffer
;
9527 /* Ensure the Messages buffer exists, and switch to it.
9528 If we created it, set the major-mode. */
9531 if (NILP (Fget_buffer (Vmessages_buffer_name
))) newbuffer
= 1;
9533 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name
));
9536 && !NILP (Ffboundp (intern ("messages-buffer-mode"))))
9537 call0 (intern ("messages-buffer-mode"));
9540 bset_undo_list (current_buffer
, Qt
);
9541 bset_cache_long_scans (current_buffer
, Qnil
);
9543 oldpoint
= message_dolog_marker1
;
9544 set_marker_restricted_both (oldpoint
, Qnil
, PT
, PT_BYTE
);
9545 oldbegv
= message_dolog_marker2
;
9546 set_marker_restricted_both (oldbegv
, Qnil
, BEGV
, BEGV_BYTE
);
9547 oldzv
= message_dolog_marker3
;
9548 set_marker_restricted_both (oldzv
, Qnil
, ZV
, ZV_BYTE
);
9549 GCPRO1 (old_deactivate_mark
);
9557 BEGV_BYTE
= BEG_BYTE
;
9560 TEMP_SET_PT_BOTH (Z
, Z_BYTE
);
9562 /* Insert the string--maybe converting multibyte to single byte
9563 or vice versa, so that all the text fits the buffer. */
9565 && NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
9571 /* Convert a multibyte string to single-byte
9572 for the *Message* buffer. */
9573 for (i
= 0; i
< nbytes
; i
+= char_bytes
)
9575 c
= string_char_and_length (msg
+ i
, &char_bytes
);
9576 work
[0] = (ASCII_CHAR_P (c
)
9578 : multibyte_char_to_unibyte (c
));
9579 insert_1_both (work
, 1, 1, 1, 0, 0);
9582 else if (! multibyte
9583 && ! NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
9587 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
9588 /* Convert a single-byte string to multibyte
9589 for the *Message* buffer. */
9590 for (i
= 0; i
< nbytes
; i
++)
9593 MAKE_CHAR_MULTIBYTE (c
);
9594 char_bytes
= CHAR_STRING (c
, str
);
9595 insert_1_both ((char *) str
, 1, char_bytes
, 1, 0, 0);
9599 insert_1_both (m
, chars_in_text (msg
, nbytes
), nbytes
, 1, 0, 0);
9603 ptrdiff_t this_bol
, this_bol_byte
, prev_bol
, prev_bol_byte
;
9606 insert_1_both ("\n", 1, 1, 1, 0, 0);
9608 scan_newline (Z
, Z_BYTE
, BEG
, BEG_BYTE
, -2, 0);
9610 this_bol_byte
= PT_BYTE
;
9612 /* See if this line duplicates the previous one.
9613 If so, combine duplicates. */
9616 scan_newline (PT
, PT_BYTE
, BEG
, BEG_BYTE
, -2, 0);
9618 prev_bol_byte
= PT_BYTE
;
9620 dups
= message_log_check_duplicate (prev_bol_byte
,
9624 del_range_both (prev_bol
, prev_bol_byte
,
9625 this_bol
, this_bol_byte
, 0);
9628 char dupstr
[sizeof " [ times]"
9629 + INT_STRLEN_BOUND (printmax_t
)];
9631 /* If you change this format, don't forget to also
9632 change message_log_check_duplicate. */
9633 int duplen
= sprintf (dupstr
, " [%"pMd
" times]", dups
);
9634 TEMP_SET_PT_BOTH (Z
- 1, Z_BYTE
- 1);
9635 insert_1_both (dupstr
, duplen
, duplen
, 1, 0, 1);
9640 /* If we have more than the desired maximum number of lines
9641 in the *Messages* buffer now, delete the oldest ones.
9642 This is safe because we don't have undo in this buffer. */
9644 if (NATNUMP (Vmessage_log_max
))
9646 scan_newline (Z
, Z_BYTE
, BEG
, BEG_BYTE
,
9647 -XFASTINT (Vmessage_log_max
) - 1, 0);
9648 del_range_both (BEG
, BEG_BYTE
, PT
, PT_BYTE
, 0);
9651 BEGV
= marker_position (oldbegv
);
9652 BEGV_BYTE
= marker_byte_position (oldbegv
);
9661 ZV
= marker_position (oldzv
);
9662 ZV_BYTE
= marker_byte_position (oldzv
);
9666 TEMP_SET_PT_BOTH (Z
, Z_BYTE
);
9668 /* We can't do Fgoto_char (oldpoint) because it will run some
9670 TEMP_SET_PT_BOTH (marker_position (oldpoint
),
9671 marker_byte_position (oldpoint
));
9674 unchain_marker (XMARKER (oldpoint
));
9675 unchain_marker (XMARKER (oldbegv
));
9676 unchain_marker (XMARKER (oldzv
));
9678 /* We called insert_1_both above with its 5th argument (PREPARE)
9679 zero, which prevents insert_1_both from calling
9680 prepare_to_modify_buffer, which in turns prevents us from
9681 incrementing windows_or_buffers_changed even if *Messages* is
9682 shown in some window. So we must manually set
9683 windows_or_buffers_changed here to make up for that. */
9684 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
9685 bset_redisplay (current_buffer
);
9687 set_buffer_internal (oldbuf
);
9689 message_log_need_newline
= !nlflag
;
9690 Vdeactivate_mark
= old_deactivate_mark
;
9695 /* We are at the end of the buffer after just having inserted a newline.
9696 (Note: We depend on the fact we won't be crossing the gap.)
9697 Check to see if the most recent message looks a lot like the previous one.
9698 Return 0 if different, 1 if the new one should just replace it, or a
9699 value N > 1 if we should also append " [N times]". */
9702 message_log_check_duplicate (ptrdiff_t prev_bol_byte
, ptrdiff_t this_bol_byte
)
9705 ptrdiff_t len
= Z_BYTE
- 1 - this_bol_byte
;
9707 unsigned char *p1
= BUF_BYTE_ADDRESS (current_buffer
, prev_bol_byte
);
9708 unsigned char *p2
= BUF_BYTE_ADDRESS (current_buffer
, this_bol_byte
);
9710 for (i
= 0; i
< len
; i
++)
9712 if (i
>= 3 && p1
[i
- 3] == '.' && p1
[i
- 2] == '.' && p1
[i
- 1] == '.')
9720 if (*p1
++ == ' ' && *p1
++ == '[')
9723 intmax_t n
= strtoimax ((char *) p1
, &pend
, 10);
9724 if (0 < n
&& n
< INTMAX_MAX
&& strncmp (pend
, " times]\n", 8) == 0)
9731 /* Display an echo area message M with a specified length of NBYTES
9732 bytes. The string may include null characters. If M is not a
9733 string, clear out any existing message, and let the mini-buffer
9736 This function cancels echoing. */
9739 message3 (Lisp_Object m
)
9741 struct gcpro gcpro1
;
9744 clear_message (1,1);
9747 /* First flush out any partial line written with print. */
9748 message_log_maybe_newline ();
9751 ptrdiff_t nbytes
= SBYTES (m
);
9752 bool multibyte
= STRING_MULTIBYTE (m
);
9754 char *buffer
= SAFE_ALLOCA (nbytes
);
9755 memcpy (buffer
, SDATA (m
), nbytes
);
9756 message_dolog (buffer
, nbytes
, 1, multibyte
);
9765 /* The non-logging version of message3.
9766 This does not cancel echoing, because it is used for echoing.
9767 Perhaps we need to make a separate function for echoing
9768 and make this cancel echoing. */
9771 message3_nolog (Lisp_Object m
)
9773 struct frame
*sf
= SELECTED_FRAME ();
9775 if (FRAME_INITIAL_P (sf
))
9777 if (noninteractive_need_newline
)
9778 putc ('\n', stderr
);
9779 noninteractive_need_newline
= 0;
9782 Lisp_Object s
= ENCODE_SYSTEM (m
);
9784 fwrite (SDATA (s
), SBYTES (s
), 1, stderr
);
9786 if (cursor_in_echo_area
== 0)
9787 fprintf (stderr
, "\n");
9790 /* Error messages get reported properly by cmd_error, so this must be just an
9791 informative message; if the frame hasn't really been initialized yet, just
9793 else if (INTERACTIVE
&& sf
->glyphs_initialized_p
)
9795 /* Get the frame containing the mini-buffer
9796 that the selected frame is using. */
9797 Lisp_Object mini_window
= FRAME_MINIBUF_WINDOW (sf
);
9798 Lisp_Object frame
= XWINDOW (mini_window
)->frame
;
9799 struct frame
*f
= XFRAME (frame
);
9801 if (FRAME_VISIBLE_P (sf
) && !FRAME_VISIBLE_P (f
))
9802 Fmake_frame_visible (frame
);
9804 if (STRINGP (m
) && SCHARS (m
) > 0)
9807 if (minibuffer_auto_raise
)
9808 Fraise_frame (frame
);
9809 /* Assume we are not echoing.
9810 (If we are, echo_now will override this.) */
9811 echo_message_buffer
= Qnil
;
9814 clear_message (1, 1);
9816 do_pending_window_change (0);
9817 echo_area_display (1);
9818 do_pending_window_change (0);
9819 if (FRAME_TERMINAL (f
)->frame_up_to_date_hook
)
9820 (*FRAME_TERMINAL (f
)->frame_up_to_date_hook
) (f
);
9825 /* Display a null-terminated echo area message M. If M is 0, clear
9826 out any existing message, and let the mini-buffer text show through.
9828 The buffer M must continue to exist until after the echo area gets
9829 cleared or some other message gets displayed there. Do not pass
9830 text that is stored in a Lisp string. Do not pass text in a buffer
9831 that was alloca'd. */
9834 message1 (const char *m
)
9836 message3 (m
? build_unibyte_string (m
) : Qnil
);
9840 /* The non-logging counterpart of message1. */
9843 message1_nolog (const char *m
)
9845 message3_nolog (m
? build_unibyte_string (m
) : Qnil
);
9848 /* Display a message M which contains a single %s
9849 which gets replaced with STRING. */
9852 message_with_string (const char *m
, Lisp_Object string
, int log
)
9854 CHECK_STRING (string
);
9860 /* ENCODE_SYSTEM below can GC and/or relocate the Lisp
9861 String whose data pointer might be passed to us in M. So
9862 we use a local copy. */
9863 char *fmt
= xstrdup (m
);
9865 if (noninteractive_need_newline
)
9866 putc ('\n', stderr
);
9867 noninteractive_need_newline
= 0;
9868 fprintf (stderr
, fmt
, SDATA (ENCODE_SYSTEM (string
)));
9869 if (!cursor_in_echo_area
)
9870 fprintf (stderr
, "\n");
9875 else if (INTERACTIVE
)
9877 /* The frame whose minibuffer we're going to display the message on.
9878 It may be larger than the selected frame, so we need
9879 to use its buffer, not the selected frame's buffer. */
9880 Lisp_Object mini_window
;
9881 struct frame
*f
, *sf
= SELECTED_FRAME ();
9883 /* Get the frame containing the minibuffer
9884 that the selected frame is using. */
9885 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
9886 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
9888 /* Error messages get reported properly by cmd_error, so this must be
9889 just an informative message; if the frame hasn't really been
9890 initialized yet, just toss it. */
9891 if (f
->glyphs_initialized_p
)
9893 Lisp_Object args
[2], msg
;
9894 struct gcpro gcpro1
, gcpro2
;
9896 args
[0] = build_string (m
);
9897 args
[1] = msg
= string
;
9898 GCPRO2 (args
[0], msg
);
9901 msg
= Fformat (2, args
);
9906 message3_nolog (msg
);
9910 /* Print should start at the beginning of the message
9911 buffer next time. */
9912 message_buf_print
= 0;
9918 /* Dump an informative message to the minibuf. If M is 0, clear out
9919 any existing message, and let the mini-buffer text show through. */
9922 vmessage (const char *m
, va_list ap
)
9928 if (noninteractive_need_newline
)
9929 putc ('\n', stderr
);
9930 noninteractive_need_newline
= 0;
9931 vfprintf (stderr
, m
, ap
);
9932 if (cursor_in_echo_area
== 0)
9933 fprintf (stderr
, "\n");
9937 else if (INTERACTIVE
)
9939 /* The frame whose mini-buffer we're going to display the message
9940 on. It may be larger than the selected frame, so we need to
9941 use its buffer, not the selected frame's buffer. */
9942 Lisp_Object mini_window
;
9943 struct frame
*f
, *sf
= SELECTED_FRAME ();
9945 /* Get the frame containing the mini-buffer
9946 that the selected frame is using. */
9947 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
9948 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
9950 /* Error messages get reported properly by cmd_error, so this must be
9951 just an informative message; if the frame hasn't really been
9952 initialized yet, just toss it. */
9953 if (f
->glyphs_initialized_p
)
9958 ptrdiff_t maxsize
= FRAME_MESSAGE_BUF_SIZE (f
);
9959 char *message_buf
= alloca (maxsize
+ 1);
9961 len
= doprnt (message_buf
, maxsize
, m
, 0, ap
);
9963 message3 (make_string (message_buf
, len
));
9968 /* Print should start at the beginning of the message
9969 buffer next time. */
9970 message_buf_print
= 0;
9976 message (const char *m
, ...)
9986 /* The non-logging version of message. */
9989 message_nolog (const char *m
, ...)
9991 Lisp_Object old_log_max
;
9994 old_log_max
= Vmessage_log_max
;
9995 Vmessage_log_max
= Qnil
;
9997 Vmessage_log_max
= old_log_max
;
10003 /* Display the current message in the current mini-buffer. This is
10004 only called from error handlers in process.c, and is not time
10008 update_echo_area (void)
10010 if (!NILP (echo_area_buffer
[0]))
10012 Lisp_Object string
;
10013 string
= Fcurrent_message ();
10019 /* Make sure echo area buffers in `echo_buffers' are live.
10020 If they aren't, make new ones. */
10023 ensure_echo_area_buffers (void)
10027 for (i
= 0; i
< 2; ++i
)
10028 if (!BUFFERP (echo_buffer
[i
])
10029 || !BUFFER_LIVE_P (XBUFFER (echo_buffer
[i
])))
10032 Lisp_Object old_buffer
;
10035 old_buffer
= echo_buffer
[i
];
10036 echo_buffer
[i
] = Fget_buffer_create
10037 (make_formatted_string (name
, " *Echo Area %d*", i
));
10038 bset_truncate_lines (XBUFFER (echo_buffer
[i
]), Qnil
);
10039 /* to force word wrap in echo area -
10040 it was decided to postpone this*/
10041 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
10043 for (j
= 0; j
< 2; ++j
)
10044 if (EQ (old_buffer
, echo_area_buffer
[j
]))
10045 echo_area_buffer
[j
] = echo_buffer
[i
];
10050 /* Call FN with args A1..A2 with either the current or last displayed
10051 echo_area_buffer as current buffer.
10053 WHICH zero means use the current message buffer
10054 echo_area_buffer[0]. If that is nil, choose a suitable buffer
10055 from echo_buffer[] and clear it.
10057 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
10058 suitable buffer from echo_buffer[] and clear it.
10060 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
10061 that the current message becomes the last displayed one, make
10062 choose a suitable buffer for echo_area_buffer[0], and clear it.
10064 Value is what FN returns. */
10067 with_echo_area_buffer (struct window
*w
, int which
,
10068 int (*fn
) (ptrdiff_t, Lisp_Object
),
10069 ptrdiff_t a1
, Lisp_Object a2
)
10071 Lisp_Object buffer
;
10072 int this_one
, the_other
, clear_buffer_p
, rc
;
10073 ptrdiff_t count
= SPECPDL_INDEX ();
10075 /* If buffers aren't live, make new ones. */
10076 ensure_echo_area_buffers ();
10078 clear_buffer_p
= 0;
10081 this_one
= 0, the_other
= 1;
10082 else if (which
> 0)
10083 this_one
= 1, the_other
= 0;
10086 this_one
= 0, the_other
= 1;
10087 clear_buffer_p
= 1;
10089 /* We need a fresh one in case the current echo buffer equals
10090 the one containing the last displayed echo area message. */
10091 if (!NILP (echo_area_buffer
[this_one
])
10092 && EQ (echo_area_buffer
[this_one
], echo_area_buffer
[the_other
]))
10093 echo_area_buffer
[this_one
] = Qnil
;
10096 /* Choose a suitable buffer from echo_buffer[] is we don't
10098 if (NILP (echo_area_buffer
[this_one
]))
10100 echo_area_buffer
[this_one
]
10101 = (EQ (echo_area_buffer
[the_other
], echo_buffer
[this_one
])
10102 ? echo_buffer
[the_other
]
10103 : echo_buffer
[this_one
]);
10104 clear_buffer_p
= 1;
10107 buffer
= echo_area_buffer
[this_one
];
10109 /* Don't get confused by reusing the buffer used for echoing
10110 for a different purpose. */
10111 if (echo_kboard
== NULL
&& EQ (buffer
, echo_message_buffer
))
10114 record_unwind_protect (unwind_with_echo_area_buffer
,
10115 with_echo_area_buffer_unwind_data (w
));
10117 /* Make the echo area buffer current. Note that for display
10118 purposes, it is not necessary that the displayed window's buffer
10119 == current_buffer, except for text property lookup. So, let's
10120 only set that buffer temporarily here without doing a full
10121 Fset_window_buffer. We must also change w->pointm, though,
10122 because otherwise an assertions in unshow_buffer fails, and Emacs
10124 set_buffer_internal_1 (XBUFFER (buffer
));
10127 wset_buffer (w
, buffer
);
10128 set_marker_both (w
->pointm
, buffer
, BEG
, BEG_BYTE
);
10131 bset_undo_list (current_buffer
, Qt
);
10132 bset_read_only (current_buffer
, Qnil
);
10133 specbind (Qinhibit_read_only
, Qt
);
10134 specbind (Qinhibit_modification_hooks
, Qt
);
10136 if (clear_buffer_p
&& Z
> BEG
)
10137 del_range (BEG
, Z
);
10139 eassert (BEGV
>= BEG
);
10140 eassert (ZV
<= Z
&& ZV
>= BEGV
);
10144 eassert (BEGV
>= BEG
);
10145 eassert (ZV
<= Z
&& ZV
>= BEGV
);
10147 unbind_to (count
, Qnil
);
10152 /* Save state that should be preserved around the call to the function
10153 FN called in with_echo_area_buffer. */
10156 with_echo_area_buffer_unwind_data (struct window
*w
)
10159 Lisp_Object vector
, tmp
;
10161 /* Reduce consing by keeping one vector in
10162 Vwith_echo_area_save_vector. */
10163 vector
= Vwith_echo_area_save_vector
;
10164 Vwith_echo_area_save_vector
= Qnil
;
10167 vector
= Fmake_vector (make_number (9), Qnil
);
10169 XSETBUFFER (tmp
, current_buffer
); ASET (vector
, i
, tmp
); ++i
;
10170 ASET (vector
, i
, Vdeactivate_mark
); ++i
;
10171 ASET (vector
, i
, make_number (windows_or_buffers_changed
)); ++i
;
10175 XSETWINDOW (tmp
, w
); ASET (vector
, i
, tmp
); ++i
;
10176 ASET (vector
, i
, w
->contents
); ++i
;
10177 ASET (vector
, i
, make_number (marker_position (w
->pointm
))); ++i
;
10178 ASET (vector
, i
, make_number (marker_byte_position (w
->pointm
))); ++i
;
10179 ASET (vector
, i
, make_number (marker_position (w
->start
))); ++i
;
10180 ASET (vector
, i
, make_number (marker_byte_position (w
->start
))); ++i
;
10185 for (; i
< end
; ++i
)
10186 ASET (vector
, i
, Qnil
);
10189 eassert (i
== ASIZE (vector
));
10194 /* Restore global state from VECTOR which was created by
10195 with_echo_area_buffer_unwind_data. */
10198 unwind_with_echo_area_buffer (Lisp_Object vector
)
10200 set_buffer_internal_1 (XBUFFER (AREF (vector
, 0)));
10201 Vdeactivate_mark
= AREF (vector
, 1);
10202 windows_or_buffers_changed
= XFASTINT (AREF (vector
, 2));
10204 if (WINDOWP (AREF (vector
, 3)))
10207 Lisp_Object buffer
;
10209 w
= XWINDOW (AREF (vector
, 3));
10210 buffer
= AREF (vector
, 4);
10212 wset_buffer (w
, buffer
);
10213 set_marker_both (w
->pointm
, buffer
,
10214 XFASTINT (AREF (vector
, 5)),
10215 XFASTINT (AREF (vector
, 6)));
10216 set_marker_both (w
->start
, buffer
,
10217 XFASTINT (AREF (vector
, 7)),
10218 XFASTINT (AREF (vector
, 8)));
10221 Vwith_echo_area_save_vector
= vector
;
10225 /* Set up the echo area for use by print functions. MULTIBYTE_P
10226 non-zero means we will print multibyte. */
10229 setup_echo_area_for_printing (int multibyte_p
)
10231 /* If we can't find an echo area any more, exit. */
10232 if (! FRAME_LIVE_P (XFRAME (selected_frame
)))
10233 Fkill_emacs (Qnil
);
10235 ensure_echo_area_buffers ();
10237 if (!message_buf_print
)
10239 /* A message has been output since the last time we printed.
10240 Choose a fresh echo area buffer. */
10241 if (EQ (echo_area_buffer
[1], echo_buffer
[0]))
10242 echo_area_buffer
[0] = echo_buffer
[1];
10244 echo_area_buffer
[0] = echo_buffer
[0];
10246 /* Switch to that buffer and clear it. */
10247 set_buffer_internal (XBUFFER (echo_area_buffer
[0]));
10248 bset_truncate_lines (current_buffer
, Qnil
);
10252 ptrdiff_t count
= SPECPDL_INDEX ();
10253 specbind (Qinhibit_read_only
, Qt
);
10254 /* Note that undo recording is always disabled. */
10255 del_range (BEG
, Z
);
10256 unbind_to (count
, Qnil
);
10258 TEMP_SET_PT_BOTH (BEG
, BEG_BYTE
);
10260 /* Set up the buffer for the multibyteness we need. */
10262 != !NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
10263 Fset_buffer_multibyte (multibyte_p
? Qt
: Qnil
);
10265 /* Raise the frame containing the echo area. */
10266 if (minibuffer_auto_raise
)
10268 struct frame
*sf
= SELECTED_FRAME ();
10269 Lisp_Object mini_window
;
10270 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
10271 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window
)));
10274 message_log_maybe_newline ();
10275 message_buf_print
= 1;
10279 if (NILP (echo_area_buffer
[0]))
10281 if (EQ (echo_area_buffer
[1], echo_buffer
[0]))
10282 echo_area_buffer
[0] = echo_buffer
[1];
10284 echo_area_buffer
[0] = echo_buffer
[0];
10287 if (current_buffer
!= XBUFFER (echo_area_buffer
[0]))
10289 /* Someone switched buffers between print requests. */
10290 set_buffer_internal (XBUFFER (echo_area_buffer
[0]));
10291 bset_truncate_lines (current_buffer
, Qnil
);
10297 /* Display an echo area message in window W. Value is non-zero if W's
10298 height is changed. If display_last_displayed_message_p is
10299 non-zero, display the message that was last displayed, otherwise
10300 display the current message. */
10303 display_echo_area (struct window
*w
)
10305 int i
, no_message_p
, window_height_changed_p
;
10307 /* Temporarily disable garbage collections while displaying the echo
10308 area. This is done because a GC can print a message itself.
10309 That message would modify the echo area buffer's contents while a
10310 redisplay of the buffer is going on, and seriously confuse
10312 ptrdiff_t count
= inhibit_garbage_collection ();
10314 /* If there is no message, we must call display_echo_area_1
10315 nevertheless because it resizes the window. But we will have to
10316 reset the echo_area_buffer in question to nil at the end because
10317 with_echo_area_buffer will sets it to an empty buffer. */
10318 i
= display_last_displayed_message_p
? 1 : 0;
10319 no_message_p
= NILP (echo_area_buffer
[i
]);
10321 window_height_changed_p
10322 = with_echo_area_buffer (w
, display_last_displayed_message_p
,
10323 display_echo_area_1
,
10324 (intptr_t) w
, Qnil
);
10327 echo_area_buffer
[i
] = Qnil
;
10329 unbind_to (count
, Qnil
);
10330 return window_height_changed_p
;
10334 /* Helper for display_echo_area. Display the current buffer which
10335 contains the current echo area message in window W, a mini-window,
10336 a pointer to which is passed in A1. A2..A4 are currently not used.
10337 Change the height of W so that all of the message is displayed.
10338 Value is non-zero if height of W was changed. */
10341 display_echo_area_1 (ptrdiff_t a1
, Lisp_Object a2
)
10344 struct window
*w
= (struct window
*) i1
;
10345 Lisp_Object window
;
10346 struct text_pos start
;
10347 int window_height_changed_p
= 0;
10349 /* Do this before displaying, so that we have a large enough glyph
10350 matrix for the display. If we can't get enough space for the
10351 whole text, display the last N lines. That works by setting w->start. */
10352 window_height_changed_p
= resize_mini_window (w
, 0);
10354 /* Use the starting position chosen by resize_mini_window. */
10355 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
10358 clear_glyph_matrix (w
->desired_matrix
);
10359 XSETWINDOW (window
, w
);
10360 try_window (window
, start
, 0);
10362 return window_height_changed_p
;
10366 /* Resize the echo area window to exactly the size needed for the
10367 currently displayed message, if there is one. If a mini-buffer
10368 is active, don't shrink it. */
10371 resize_echo_area_exactly (void)
10373 if (BUFFERP (echo_area_buffer
[0])
10374 && WINDOWP (echo_area_window
))
10376 struct window
*w
= XWINDOW (echo_area_window
);
10377 Lisp_Object resize_exactly
= (minibuf_level
== 0 ? Qt
: Qnil
);
10378 int resized_p
= with_echo_area_buffer (w
, 0, resize_mini_window_1
,
10379 (intptr_t) w
, resize_exactly
);
10382 windows_or_buffers_changed
= 42;
10383 update_mode_lines
= 30;
10384 redisplay_internal ();
10390 /* Callback function for with_echo_area_buffer, when used from
10391 resize_echo_area_exactly. A1 contains a pointer to the window to
10392 resize, EXACTLY non-nil means resize the mini-window exactly to the
10393 size of the text displayed. A3 and A4 are not used. Value is what
10394 resize_mini_window returns. */
10397 resize_mini_window_1 (ptrdiff_t a1
, Lisp_Object exactly
)
10400 return resize_mini_window ((struct window
*) i1
, !NILP (exactly
));
10404 /* Resize mini-window W to fit the size of its contents. EXACT_P
10405 means size the window exactly to the size needed. Otherwise, it's
10406 only enlarged until W's buffer is empty.
10408 Set W->start to the right place to begin display. If the whole
10409 contents fit, start at the beginning. Otherwise, start so as
10410 to make the end of the contents appear. This is particularly
10411 important for y-or-n-p, but seems desirable generally.
10413 Value is non-zero if the window height has been changed. */
10416 resize_mini_window (struct window
*w
, int exact_p
)
10418 struct frame
*f
= XFRAME (w
->frame
);
10419 int window_height_changed_p
= 0;
10421 eassert (MINI_WINDOW_P (w
));
10423 /* By default, start display at the beginning. */
10424 set_marker_both (w
->start
, w
->contents
,
10425 BUF_BEGV (XBUFFER (w
->contents
)),
10426 BUF_BEGV_BYTE (XBUFFER (w
->contents
)));
10428 /* Don't resize windows while redisplaying a window; it would
10429 confuse redisplay functions when the size of the window they are
10430 displaying changes from under them. Such a resizing can happen,
10431 for instance, when which-func prints a long message while
10432 we are running fontification-functions. We're running these
10433 functions with safe_call which binds inhibit-redisplay to t. */
10434 if (!NILP (Vinhibit_redisplay
))
10437 /* Nil means don't try to resize. */
10438 if (NILP (Vresize_mini_windows
)
10439 || (FRAME_X_P (f
) && FRAME_X_OUTPUT (f
) == NULL
))
10442 if (!FRAME_MINIBUF_ONLY_P (f
))
10445 struct window
*root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
10446 int total_height
= WINDOW_TOTAL_LINES (root
) + WINDOW_TOTAL_LINES (w
);
10448 EMACS_INT max_height
;
10449 int unit
= FRAME_LINE_HEIGHT (f
);
10450 struct text_pos start
;
10451 struct buffer
*old_current_buffer
= NULL
;
10453 if (current_buffer
!= XBUFFER (w
->contents
))
10455 old_current_buffer
= current_buffer
;
10456 set_buffer_internal (XBUFFER (w
->contents
));
10459 init_iterator (&it
, w
, BEGV
, BEGV_BYTE
, NULL
, DEFAULT_FACE_ID
);
10461 /* Compute the max. number of lines specified by the user. */
10462 if (FLOATP (Vmax_mini_window_height
))
10463 max_height
= XFLOATINT (Vmax_mini_window_height
) * FRAME_LINES (f
);
10464 else if (INTEGERP (Vmax_mini_window_height
))
10465 max_height
= XINT (Vmax_mini_window_height
);
10467 max_height
= total_height
/ 4;
10469 /* Correct that max. height if it's bogus. */
10470 max_height
= clip_to_bounds (1, max_height
, total_height
);
10472 /* Find out the height of the text in the window. */
10473 if (it
.line_wrap
== TRUNCATE
)
10478 move_it_to (&it
, ZV
, -1, -1, -1, MOVE_TO_POS
);
10479 if (it
.max_ascent
== 0 && it
.max_descent
== 0)
10480 height
= it
.current_y
+ last_height
;
10482 height
= it
.current_y
+ it
.max_ascent
+ it
.max_descent
;
10483 height
-= min (it
.extra_line_spacing
, it
.max_extra_line_spacing
);
10484 height
= (height
+ unit
- 1) / unit
;
10487 /* Compute a suitable window start. */
10488 if (height
> max_height
)
10490 height
= max_height
;
10491 init_iterator (&it
, w
, ZV
, ZV_BYTE
, NULL
, DEFAULT_FACE_ID
);
10492 move_it_vertically_backward (&it
, (height
- 1) * unit
);
10493 start
= it
.current
.pos
;
10496 SET_TEXT_POS (start
, BEGV
, BEGV_BYTE
);
10497 SET_MARKER_FROM_TEXT_POS (w
->start
, start
);
10499 if (EQ (Vresize_mini_windows
, Qgrow_only
))
10501 /* Let it grow only, until we display an empty message, in which
10502 case the window shrinks again. */
10503 if (height
> WINDOW_TOTAL_LINES (w
))
10505 int old_height
= WINDOW_TOTAL_LINES (w
);
10507 FRAME_WINDOWS_FROZEN (f
) = 1;
10508 grow_mini_window (w
, height
- WINDOW_TOTAL_LINES (w
));
10509 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
10511 else if (height
< WINDOW_TOTAL_LINES (w
)
10512 && (exact_p
|| BEGV
== ZV
))
10514 int old_height
= WINDOW_TOTAL_LINES (w
);
10516 FRAME_WINDOWS_FROZEN (f
) = 0;
10517 shrink_mini_window (w
);
10518 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
10523 /* Always resize to exact size needed. */
10524 if (height
> WINDOW_TOTAL_LINES (w
))
10526 int old_height
= WINDOW_TOTAL_LINES (w
);
10528 FRAME_WINDOWS_FROZEN (f
) = 1;
10529 grow_mini_window (w
, height
- WINDOW_TOTAL_LINES (w
));
10530 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
10532 else if (height
< WINDOW_TOTAL_LINES (w
))
10534 int old_height
= WINDOW_TOTAL_LINES (w
);
10536 FRAME_WINDOWS_FROZEN (f
) = 0;
10537 shrink_mini_window (w
);
10541 FRAME_WINDOWS_FROZEN (f
) = 1;
10542 grow_mini_window (w
, height
- WINDOW_TOTAL_LINES (w
));
10545 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
10549 if (old_current_buffer
)
10550 set_buffer_internal (old_current_buffer
);
10553 return window_height_changed_p
;
10557 /* Value is the current message, a string, or nil if there is no
10558 current message. */
10561 current_message (void)
10565 if (!BUFFERP (echo_area_buffer
[0]))
10569 with_echo_area_buffer (0, 0, current_message_1
,
10570 (intptr_t) &msg
, Qnil
);
10572 echo_area_buffer
[0] = Qnil
;
10580 current_message_1 (ptrdiff_t a1
, Lisp_Object a2
)
10583 Lisp_Object
*msg
= (Lisp_Object
*) i1
;
10586 *msg
= make_buffer_string (BEG
, Z
, 1);
10593 /* Push the current message on Vmessage_stack for later restoration
10594 by restore_message. Value is non-zero if the current message isn't
10595 empty. This is a relatively infrequent operation, so it's not
10596 worth optimizing. */
10599 push_message (void)
10601 Lisp_Object msg
= current_message ();
10602 Vmessage_stack
= Fcons (msg
, Vmessage_stack
);
10603 return STRINGP (msg
);
10607 /* Restore message display from the top of Vmessage_stack. */
10610 restore_message (void)
10612 eassert (CONSP (Vmessage_stack
));
10613 message3_nolog (XCAR (Vmessage_stack
));
10617 /* Handler for unwind-protect calling pop_message. */
10620 pop_message_unwind (void)
10622 /* Pop the top-most entry off Vmessage_stack. */
10623 eassert (CONSP (Vmessage_stack
));
10624 Vmessage_stack
= XCDR (Vmessage_stack
);
10628 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
10629 exits. If the stack is not empty, we have a missing pop_message
10633 check_message_stack (void)
10635 if (!NILP (Vmessage_stack
))
10640 /* Truncate to NCHARS what will be displayed in the echo area the next
10641 time we display it---but don't redisplay it now. */
10644 truncate_echo_area (ptrdiff_t nchars
)
10647 echo_area_buffer
[0] = Qnil
;
10648 else if (!noninteractive
10650 && !NILP (echo_area_buffer
[0]))
10652 struct frame
*sf
= SELECTED_FRAME ();
10653 /* Error messages get reported properly by cmd_error, so this must be
10654 just an informative message; if the frame hasn't really been
10655 initialized yet, just toss it. */
10656 if (sf
->glyphs_initialized_p
)
10657 with_echo_area_buffer (0, 0, truncate_message_1
, nchars
, Qnil
);
10662 /* Helper function for truncate_echo_area. Truncate the current
10663 message to at most NCHARS characters. */
10666 truncate_message_1 (ptrdiff_t nchars
, Lisp_Object a2
)
10668 if (BEG
+ nchars
< Z
)
10669 del_range (BEG
+ nchars
, Z
);
10671 echo_area_buffer
[0] = Qnil
;
10675 /* Set the current message to STRING. */
10678 set_message (Lisp_Object string
)
10680 eassert (STRINGP (string
));
10682 message_enable_multibyte
= STRING_MULTIBYTE (string
);
10684 with_echo_area_buffer (0, -1, set_message_1
, 0, string
);
10685 message_buf_print
= 0;
10686 help_echo_showing_p
= 0;
10688 if (STRINGP (Vdebug_on_message
)
10689 && STRINGP (string
)
10690 && fast_string_match (Vdebug_on_message
, string
) >= 0)
10691 call_debugger (list2 (Qerror
, string
));
10695 /* Helper function for set_message. First argument is ignored and second
10696 argument has the same meaning as for set_message.
10697 This function is called with the echo area buffer being current. */
10700 set_message_1 (ptrdiff_t a1
, Lisp_Object string
)
10702 eassert (STRINGP (string
));
10704 /* Change multibyteness of the echo buffer appropriately. */
10705 if (message_enable_multibyte
10706 != !NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
10707 Fset_buffer_multibyte (message_enable_multibyte
? Qt
: Qnil
);
10709 bset_truncate_lines (current_buffer
, message_truncate_lines
? Qt
: Qnil
);
10710 if (!NILP (BVAR (current_buffer
, bidi_display_reordering
)))
10711 bset_bidi_paragraph_direction (current_buffer
, Qleft_to_right
);
10713 /* Insert new message at BEG. */
10714 TEMP_SET_PT_BOTH (BEG
, BEG_BYTE
);
10716 /* This function takes care of single/multibyte conversion.
10717 We just have to ensure that the echo area buffer has the right
10718 setting of enable_multibyte_characters. */
10719 insert_from_string (string
, 0, 0, SCHARS (string
), SBYTES (string
), 1);
10725 /* Clear messages. CURRENT_P non-zero means clear the current
10726 message. LAST_DISPLAYED_P non-zero means clear the message
10730 clear_message (int current_p
, int last_displayed_p
)
10734 echo_area_buffer
[0] = Qnil
;
10735 message_cleared_p
= 1;
10738 if (last_displayed_p
)
10739 echo_area_buffer
[1] = Qnil
;
10741 message_buf_print
= 0;
10744 /* Clear garbaged frames.
10746 This function is used where the old redisplay called
10747 redraw_garbaged_frames which in turn called redraw_frame which in
10748 turn called clear_frame. The call to clear_frame was a source of
10749 flickering. I believe a clear_frame is not necessary. It should
10750 suffice in the new redisplay to invalidate all current matrices,
10751 and ensure a complete redisplay of all windows. */
10754 clear_garbaged_frames (void)
10756 if (frame_garbaged
)
10758 Lisp_Object tail
, frame
;
10760 FOR_EACH_FRAME (tail
, frame
)
10762 struct frame
*f
= XFRAME (frame
);
10764 if (FRAME_VISIBLE_P (f
) && FRAME_GARBAGED_P (f
))
10769 clear_current_matrices (f
);
10770 fset_redisplay (f
);
10771 f
->garbaged
= false;
10772 f
->resized_p
= false;
10776 frame_garbaged
= false;
10781 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
10782 is non-zero update selected_frame. Value is non-zero if the
10783 mini-windows height has been changed. */
10786 echo_area_display (int update_frame_p
)
10788 Lisp_Object mini_window
;
10791 int window_height_changed_p
= 0;
10792 struct frame
*sf
= SELECTED_FRAME ();
10794 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
10795 w
= XWINDOW (mini_window
);
10796 f
= XFRAME (WINDOW_FRAME (w
));
10798 /* Don't display if frame is invisible or not yet initialized. */
10799 if (!FRAME_VISIBLE_P (f
) || !f
->glyphs_initialized_p
)
10802 #ifdef HAVE_WINDOW_SYSTEM
10803 /* When Emacs starts, selected_frame may be the initial terminal
10804 frame. If we let this through, a message would be displayed on
10806 if (FRAME_INITIAL_P (XFRAME (selected_frame
)))
10808 #endif /* HAVE_WINDOW_SYSTEM */
10810 /* Redraw garbaged frames. */
10811 clear_garbaged_frames ();
10813 if (!NILP (echo_area_buffer
[0]) || minibuf_level
== 0)
10815 echo_area_window
= mini_window
;
10816 window_height_changed_p
= display_echo_area (w
);
10817 w
->must_be_updated_p
= 1;
10819 /* Update the display, unless called from redisplay_internal.
10820 Also don't update the screen during redisplay itself. The
10821 update will happen at the end of redisplay, and an update
10822 here could cause confusion. */
10823 if (update_frame_p
&& !redisplaying_p
)
10827 /* If the display update has been interrupted by pending
10828 input, update mode lines in the frame. Due to the
10829 pending input, it might have been that redisplay hasn't
10830 been called, so that mode lines above the echo area are
10831 garbaged. This looks odd, so we prevent it here. */
10832 if (!display_completed
)
10833 n
= redisplay_mode_lines (FRAME_ROOT_WINDOW (f
), 0);
10835 if (window_height_changed_p
10836 /* Don't do this if Emacs is shutting down. Redisplay
10837 needs to run hooks. */
10838 && !NILP (Vrun_hooks
))
10840 /* Must update other windows. Likewise as in other
10841 cases, don't let this update be interrupted by
10843 ptrdiff_t count
= SPECPDL_INDEX ();
10844 specbind (Qredisplay_dont_pause
, Qt
);
10845 windows_or_buffers_changed
= 44;
10846 redisplay_internal ();
10847 unbind_to (count
, Qnil
);
10849 else if (FRAME_WINDOW_P (f
) && n
== 0)
10851 /* Window configuration is the same as before.
10852 Can do with a display update of the echo area,
10853 unless we displayed some mode lines. */
10854 update_single_window (w
, 1);
10858 update_frame (f
, 1, 1);
10860 /* If cursor is in the echo area, make sure that the next
10861 redisplay displays the minibuffer, so that the cursor will
10862 be replaced with what the minibuffer wants. */
10863 if (cursor_in_echo_area
)
10864 wset_redisplay (XWINDOW (mini_window
));
10867 else if (!EQ (mini_window
, selected_window
))
10868 wset_redisplay (XWINDOW (mini_window
));
10870 /* Last displayed message is now the current message. */
10871 echo_area_buffer
[1] = echo_area_buffer
[0];
10872 /* Inform read_char that we're not echoing. */
10873 echo_message_buffer
= Qnil
;
10875 /* Prevent redisplay optimization in redisplay_internal by resetting
10876 this_line_start_pos. This is done because the mini-buffer now
10877 displays the message instead of its buffer text. */
10878 if (EQ (mini_window
, selected_window
))
10879 CHARPOS (this_line_start_pos
) = 0;
10881 return window_height_changed_p
;
10884 /* Nonzero if W's buffer was changed but not saved. */
10887 window_buffer_changed (struct window
*w
)
10889 struct buffer
*b
= XBUFFER (w
->contents
);
10891 eassert (BUFFER_LIVE_P (b
));
10893 return (((BUF_SAVE_MODIFF (b
) < BUF_MODIFF (b
)) != w
->last_had_star
));
10896 /* Nonzero if W has %c in its mode line and mode line should be updated. */
10899 mode_line_update_needed (struct window
*w
)
10901 return (w
->column_number_displayed
!= -1
10902 && !(PT
== w
->last_point
&& !window_outdated (w
))
10903 && (w
->column_number_displayed
!= current_column ()));
10906 /* Nonzero if window start of W is frozen and may not be changed during
10910 window_frozen_p (struct window
*w
)
10912 if (FRAME_WINDOWS_FROZEN (XFRAME (WINDOW_FRAME (w
))))
10914 Lisp_Object window
;
10916 XSETWINDOW (window
, w
);
10917 if (MINI_WINDOW_P (w
))
10919 else if (EQ (window
, selected_window
))
10921 else if (MINI_WINDOW_P (XWINDOW (selected_window
))
10922 && EQ (window
, Vminibuf_scroll_window
))
10923 /* This special window can't be frozen too. */
10931 /***********************************************************************
10932 Mode Lines and Frame Titles
10933 ***********************************************************************/
10935 /* A buffer for constructing non-propertized mode-line strings and
10936 frame titles in it; allocated from the heap in init_xdisp and
10937 resized as needed in store_mode_line_noprop_char. */
10939 static char *mode_line_noprop_buf
;
10941 /* The buffer's end, and a current output position in it. */
10943 static char *mode_line_noprop_buf_end
;
10944 static char *mode_line_noprop_ptr
;
10946 #define MODE_LINE_NOPROP_LEN(start) \
10947 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
10950 MODE_LINE_DISPLAY
= 0,
10954 } mode_line_target
;
10956 /* Alist that caches the results of :propertize.
10957 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
10958 static Lisp_Object mode_line_proptrans_alist
;
10960 /* List of strings making up the mode-line. */
10961 static Lisp_Object mode_line_string_list
;
10963 /* Base face property when building propertized mode line string. */
10964 static Lisp_Object mode_line_string_face
;
10965 static Lisp_Object mode_line_string_face_prop
;
10968 /* Unwind data for mode line strings */
10970 static Lisp_Object Vmode_line_unwind_vector
;
10973 format_mode_line_unwind_data (struct frame
*target_frame
,
10974 struct buffer
*obuf
,
10976 int save_proptrans
)
10978 Lisp_Object vector
, tmp
;
10980 /* Reduce consing by keeping one vector in
10981 Vwith_echo_area_save_vector. */
10982 vector
= Vmode_line_unwind_vector
;
10983 Vmode_line_unwind_vector
= Qnil
;
10986 vector
= Fmake_vector (make_number (10), Qnil
);
10988 ASET (vector
, 0, make_number (mode_line_target
));
10989 ASET (vector
, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
10990 ASET (vector
, 2, mode_line_string_list
);
10991 ASET (vector
, 3, save_proptrans
? mode_line_proptrans_alist
: Qt
);
10992 ASET (vector
, 4, mode_line_string_face
);
10993 ASET (vector
, 5, mode_line_string_face_prop
);
10996 XSETBUFFER (tmp
, obuf
);
10999 ASET (vector
, 6, tmp
);
11000 ASET (vector
, 7, owin
);
11003 /* Similarly to `with-selected-window', if the operation selects
11004 a window on another frame, we must restore that frame's
11005 selected window, and (for a tty) the top-frame. */
11006 ASET (vector
, 8, target_frame
->selected_window
);
11007 if (FRAME_TERMCAP_P (target_frame
))
11008 ASET (vector
, 9, FRAME_TTY (target_frame
)->top_frame
);
11015 unwind_format_mode_line (Lisp_Object vector
)
11017 Lisp_Object old_window
= AREF (vector
, 7);
11018 Lisp_Object target_frame_window
= AREF (vector
, 8);
11019 Lisp_Object old_top_frame
= AREF (vector
, 9);
11021 mode_line_target
= XINT (AREF (vector
, 0));
11022 mode_line_noprop_ptr
= mode_line_noprop_buf
+ XINT (AREF (vector
, 1));
11023 mode_line_string_list
= AREF (vector
, 2);
11024 if (! EQ (AREF (vector
, 3), Qt
))
11025 mode_line_proptrans_alist
= AREF (vector
, 3);
11026 mode_line_string_face
= AREF (vector
, 4);
11027 mode_line_string_face_prop
= AREF (vector
, 5);
11029 /* Select window before buffer, since it may change the buffer. */
11030 if (!NILP (old_window
))
11032 /* If the operation that we are unwinding had selected a window
11033 on a different frame, reset its frame-selected-window. For a
11034 text terminal, reset its top-frame if necessary. */
11035 if (!NILP (target_frame_window
))
11038 = WINDOW_FRAME (XWINDOW (target_frame_window
));
11040 if (!EQ (frame
, WINDOW_FRAME (XWINDOW (old_window
))))
11041 Fselect_window (target_frame_window
, Qt
);
11043 if (!NILP (old_top_frame
) && !EQ (old_top_frame
, frame
))
11044 Fselect_frame (old_top_frame
, Qt
);
11047 Fselect_window (old_window
, Qt
);
11050 if (!NILP (AREF (vector
, 6)))
11052 set_buffer_internal_1 (XBUFFER (AREF (vector
, 6)));
11053 ASET (vector
, 6, Qnil
);
11056 Vmode_line_unwind_vector
= vector
;
11060 /* Store a single character C for the frame title in mode_line_noprop_buf.
11061 Re-allocate mode_line_noprop_buf if necessary. */
11064 store_mode_line_noprop_char (char c
)
11066 /* If output position has reached the end of the allocated buffer,
11067 increase the buffer's size. */
11068 if (mode_line_noprop_ptr
== mode_line_noprop_buf_end
)
11070 ptrdiff_t len
= MODE_LINE_NOPROP_LEN (0);
11071 ptrdiff_t size
= len
;
11072 mode_line_noprop_buf
=
11073 xpalloc (mode_line_noprop_buf
, &size
, 1, STRING_BYTES_BOUND
, 1);
11074 mode_line_noprop_buf_end
= mode_line_noprop_buf
+ size
;
11075 mode_line_noprop_ptr
= mode_line_noprop_buf
+ len
;
11078 *mode_line_noprop_ptr
++ = c
;
11082 /* Store part of a frame title in mode_line_noprop_buf, beginning at
11083 mode_line_noprop_ptr. STRING is the string to store. Do not copy
11084 characters that yield more columns than PRECISION; PRECISION <= 0
11085 means copy the whole string. Pad with spaces until FIELD_WIDTH
11086 number of characters have been copied; FIELD_WIDTH <= 0 means don't
11087 pad. Called from display_mode_element when it is used to build a
11091 store_mode_line_noprop (const char *string
, int field_width
, int precision
)
11093 const unsigned char *str
= (const unsigned char *) string
;
11095 ptrdiff_t dummy
, nbytes
;
11097 /* Copy at most PRECISION chars from STR. */
11098 nbytes
= strlen (string
);
11099 n
+= c_string_width (str
, nbytes
, precision
, &dummy
, &nbytes
);
11101 store_mode_line_noprop_char (*str
++);
11103 /* Fill up with spaces until FIELD_WIDTH reached. */
11104 while (field_width
> 0
11105 && n
< field_width
)
11107 store_mode_line_noprop_char (' ');
11114 /***********************************************************************
11116 ***********************************************************************/
11118 #ifdef HAVE_WINDOW_SYSTEM
11120 /* Set the title of FRAME, if it has changed. The title format is
11121 Vicon_title_format if FRAME is iconified, otherwise it is
11122 frame_title_format. */
11125 x_consider_frame_title (Lisp_Object frame
)
11127 struct frame
*f
= XFRAME (frame
);
11129 if (FRAME_WINDOW_P (f
)
11130 || FRAME_MINIBUF_ONLY_P (f
)
11131 || f
->explicit_name
)
11133 /* Do we have more than one visible frame on this X display? */
11134 Lisp_Object tail
, other_frame
, fmt
;
11135 ptrdiff_t title_start
;
11139 ptrdiff_t count
= SPECPDL_INDEX ();
11141 FOR_EACH_FRAME (tail
, other_frame
)
11143 struct frame
*tf
= XFRAME (other_frame
);
11146 && FRAME_KBOARD (tf
) == FRAME_KBOARD (f
)
11147 && !FRAME_MINIBUF_ONLY_P (tf
)
11148 && !EQ (other_frame
, tip_frame
)
11149 && (FRAME_VISIBLE_P (tf
) || FRAME_ICONIFIED_P (tf
)))
11153 /* Set global variable indicating that multiple frames exist. */
11154 multiple_frames
= CONSP (tail
);
11156 /* Switch to the buffer of selected window of the frame. Set up
11157 mode_line_target so that display_mode_element will output into
11158 mode_line_noprop_buf; then display the title. */
11159 record_unwind_protect (unwind_format_mode_line
,
11160 format_mode_line_unwind_data
11161 (f
, current_buffer
, selected_window
, 0));
11163 Fselect_window (f
->selected_window
, Qt
);
11164 set_buffer_internal_1
11165 (XBUFFER (XWINDOW (f
->selected_window
)->contents
));
11166 fmt
= FRAME_ICONIFIED_P (f
) ? Vicon_title_format
: Vframe_title_format
;
11168 mode_line_target
= MODE_LINE_TITLE
;
11169 title_start
= MODE_LINE_NOPROP_LEN (0);
11170 init_iterator (&it
, XWINDOW (f
->selected_window
), -1, -1,
11171 NULL
, DEFAULT_FACE_ID
);
11172 display_mode_element (&it
, 0, -1, -1, fmt
, Qnil
, 0);
11173 len
= MODE_LINE_NOPROP_LEN (title_start
);
11174 title
= mode_line_noprop_buf
+ title_start
;
11175 unbind_to (count
, Qnil
);
11177 /* Set the title only if it's changed. This avoids consing in
11178 the common case where it hasn't. (If it turns out that we've
11179 already wasted too much time by walking through the list with
11180 display_mode_element, then we might need to optimize at a
11181 higher level than this.) */
11182 if (! STRINGP (f
->name
)
11183 || SBYTES (f
->name
) != len
11184 || memcmp (title
, SDATA (f
->name
), len
) != 0)
11185 x_implicitly_set_name (f
, make_string (title
, len
), Qnil
);
11189 #endif /* not HAVE_WINDOW_SYSTEM */
11192 /***********************************************************************
11194 ***********************************************************************/
11197 /* Prepare for redisplay by updating menu-bar item lists when
11198 appropriate. This can call eval. */
11201 prepare_menu_bars (void)
11203 bool all_windows
= windows_or_buffers_changed
|| update_mode_lines
;
11205 = (windows_or_buffers_changed
== 0
11206 || windows_or_buffers_changed
== REDISPLAY_SOME
)
11207 && (update_mode_lines
== 0
11208 || update_mode_lines
== REDISPLAY_SOME
);
11209 struct gcpro gcpro1
, gcpro2
;
11210 Lisp_Object tooltip_frame
;
11212 #ifdef HAVE_WINDOW_SYSTEM
11213 tooltip_frame
= tip_frame
;
11215 tooltip_frame
= Qnil
;
11218 if (FUNCTIONP (Vpre_redisplay_function
))
11220 Lisp_Object windows
= all_windows
? Qt
: Qnil
;
11221 if (all_windows
&& some_windows
)
11223 Lisp_Object ws
= window_list ();
11224 for (windows
= Qnil
; CONSP (ws
); ws
= XCDR (ws
))
11226 Lisp_Object
this = XCAR (ws
);
11227 struct window
*w
= XWINDOW (this);
11229 || XFRAME (w
->frame
)->redisplay
11230 || XBUFFER (w
->contents
)->text
->redisplay
)
11232 windows
= Fcons (this, windows
);
11236 safe_call1 (Vpre_redisplay_function
, windows
);
11239 /* Update all frame titles based on their buffer names, etc. We do
11240 this before the menu bars so that the buffer-menu will show the
11241 up-to-date frame titles. */
11242 #ifdef HAVE_WINDOW_SYSTEM
11245 Lisp_Object tail
, frame
;
11247 FOR_EACH_FRAME (tail
, frame
)
11249 struct frame
*f
= XFRAME (frame
);
11250 struct window
*w
= XWINDOW (FRAME_SELECTED_WINDOW (f
));
11254 && !XBUFFER (w
->contents
)->text
->redisplay
)
11257 if (!EQ (frame
, tooltip_frame
)
11258 && (FRAME_ICONIFIED_P (f
)
11259 || FRAME_VISIBLE_P (f
) == 1
11260 /* Exclude TTY frames that are obscured because they
11261 are not the top frame on their console. This is
11262 because x_consider_frame_title actually switches
11263 to the frame, which for TTY frames means it is
11264 marked as garbaged, and will be completely
11265 redrawn on the next redisplay cycle. This causes
11266 TTY frames to be completely redrawn, when there
11267 are more than one of them, even though nothing
11268 should be changed on display. */
11269 || (FRAME_VISIBLE_P (f
) == 2 && FRAME_WINDOW_P (f
))))
11270 x_consider_frame_title (frame
);
11273 #endif /* HAVE_WINDOW_SYSTEM */
11275 /* Update the menu bar item lists, if appropriate. This has to be
11276 done before any actual redisplay or generation of display lines. */
11280 Lisp_Object tail
, frame
;
11281 ptrdiff_t count
= SPECPDL_INDEX ();
11282 /* 1 means that update_menu_bar has run its hooks
11283 so any further calls to update_menu_bar shouldn't do so again. */
11284 int menu_bar_hooks_run
= 0;
11286 record_unwind_save_match_data ();
11288 FOR_EACH_FRAME (tail
, frame
)
11290 struct frame
*f
= XFRAME (frame
);
11291 struct window
*w
= XWINDOW (FRAME_SELECTED_WINDOW (f
));
11293 /* Ignore tooltip frame. */
11294 if (EQ (frame
, tooltip_frame
))
11300 && !XBUFFER (w
->contents
)->text
->redisplay
)
11303 /* If a window on this frame changed size, report that to
11304 the user and clear the size-change flag. */
11305 if (FRAME_WINDOW_SIZES_CHANGED (f
))
11307 Lisp_Object functions
;
11309 /* Clear flag first in case we get an error below. */
11310 FRAME_WINDOW_SIZES_CHANGED (f
) = 0;
11311 functions
= Vwindow_size_change_functions
;
11312 GCPRO2 (tail
, functions
);
11314 while (CONSP (functions
))
11316 if (!EQ (XCAR (functions
), Qt
))
11317 call1 (XCAR (functions
), frame
);
11318 functions
= XCDR (functions
);
11324 menu_bar_hooks_run
= update_menu_bar (f
, 0, menu_bar_hooks_run
);
11325 #ifdef HAVE_WINDOW_SYSTEM
11326 update_tool_bar (f
, 0);
11329 if (windows_or_buffers_changed
11332 (f
, Fbuffer_modified_p (XWINDOW (f
->selected_window
)->contents
));
11337 unbind_to (count
, Qnil
);
11341 struct frame
*sf
= SELECTED_FRAME ();
11342 update_menu_bar (sf
, 1, 0);
11343 #ifdef HAVE_WINDOW_SYSTEM
11344 update_tool_bar (sf
, 1);
11350 /* Update the menu bar item list for frame F. This has to be done
11351 before we start to fill in any display lines, because it can call
11354 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
11356 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
11357 already ran the menu bar hooks for this redisplay, so there
11358 is no need to run them again. The return value is the
11359 updated value of this flag, to pass to the next call. */
11362 update_menu_bar (struct frame
*f
, int save_match_data
, int hooks_run
)
11364 Lisp_Object window
;
11365 register struct window
*w
;
11367 /* If called recursively during a menu update, do nothing. This can
11368 happen when, for instance, an activate-menubar-hook causes a
11370 if (inhibit_menubar_update
)
11373 window
= FRAME_SELECTED_WINDOW (f
);
11374 w
= XWINDOW (window
);
11376 if (FRAME_WINDOW_P (f
)
11378 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11379 || defined (HAVE_NS) || defined (USE_GTK)
11380 FRAME_EXTERNAL_MENU_BAR (f
)
11382 FRAME_MENU_BAR_LINES (f
) > 0
11384 : FRAME_MENU_BAR_LINES (f
) > 0)
11386 /* If the user has switched buffers or windows, we need to
11387 recompute to reflect the new bindings. But we'll
11388 recompute when update_mode_lines is set too; that means
11389 that people can use force-mode-line-update to request
11390 that the menu bar be recomputed. The adverse effect on
11391 the rest of the redisplay algorithm is about the same as
11392 windows_or_buffers_changed anyway. */
11393 if (windows_or_buffers_changed
11394 /* This used to test w->update_mode_line, but we believe
11395 there is no need to recompute the menu in that case. */
11396 || update_mode_lines
11397 || window_buffer_changed (w
))
11399 struct buffer
*prev
= current_buffer
;
11400 ptrdiff_t count
= SPECPDL_INDEX ();
11402 specbind (Qinhibit_menubar_update
, Qt
);
11404 set_buffer_internal_1 (XBUFFER (w
->contents
));
11405 if (save_match_data
)
11406 record_unwind_save_match_data ();
11407 if (NILP (Voverriding_local_map_menu_flag
))
11409 specbind (Qoverriding_terminal_local_map
, Qnil
);
11410 specbind (Qoverriding_local_map
, Qnil
);
11415 /* Run the Lucid hook. */
11416 safe_run_hooks (Qactivate_menubar_hook
);
11418 /* If it has changed current-menubar from previous value,
11419 really recompute the menu-bar from the value. */
11420 if (! NILP (Vlucid_menu_bar_dirty_flag
))
11421 call0 (Qrecompute_lucid_menubar
);
11423 safe_run_hooks (Qmenu_bar_update_hook
);
11428 XSETFRAME (Vmenu_updating_frame
, f
);
11429 fset_menu_bar_items (f
, menu_bar_items (FRAME_MENU_BAR_ITEMS (f
)));
11431 /* Redisplay the menu bar in case we changed it. */
11432 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11433 || defined (HAVE_NS) || defined (USE_GTK)
11434 if (FRAME_WINDOW_P (f
))
11436 #if defined (HAVE_NS)
11437 /* All frames on Mac OS share the same menubar. So only
11438 the selected frame should be allowed to set it. */
11439 if (f
== SELECTED_FRAME ())
11441 set_frame_menubar (f
, 0, 0);
11444 /* On a terminal screen, the menu bar is an ordinary screen
11445 line, and this makes it get updated. */
11446 w
->update_mode_line
= 1;
11447 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11448 /* In the non-toolkit version, the menu bar is an ordinary screen
11449 line, and this makes it get updated. */
11450 w
->update_mode_line
= 1;
11451 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11453 unbind_to (count
, Qnil
);
11454 set_buffer_internal_1 (prev
);
11461 /***********************************************************************
11463 ***********************************************************************/
11465 #ifdef HAVE_WINDOW_SYSTEM
11467 /* Tool-bar item index of the item on which a mouse button was pressed
11470 int last_tool_bar_item
;
11472 /* Select `frame' temporarily without running all the code in
11474 FIXME: Maybe do_switch_frame should be trimmed down similarly
11475 when `norecord' is set. */
11477 fast_set_selected_frame (Lisp_Object frame
)
11479 if (!EQ (selected_frame
, frame
))
11481 selected_frame
= frame
;
11482 selected_window
= XFRAME (frame
)->selected_window
;
11486 /* Update the tool-bar item list for frame F. This has to be done
11487 before we start to fill in any display lines. Called from
11488 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
11489 and restore it here. */
11492 update_tool_bar (struct frame
*f
, int save_match_data
)
11494 #if defined (USE_GTK) || defined (HAVE_NS)
11495 int do_update
= FRAME_EXTERNAL_TOOL_BAR (f
);
11497 int do_update
= WINDOWP (f
->tool_bar_window
)
11498 && WINDOW_TOTAL_LINES (XWINDOW (f
->tool_bar_window
)) > 0;
11503 Lisp_Object window
;
11506 window
= FRAME_SELECTED_WINDOW (f
);
11507 w
= XWINDOW (window
);
11509 /* If the user has switched buffers or windows, we need to
11510 recompute to reflect the new bindings. But we'll
11511 recompute when update_mode_lines is set too; that means
11512 that people can use force-mode-line-update to request
11513 that the menu bar be recomputed. The adverse effect on
11514 the rest of the redisplay algorithm is about the same as
11515 windows_or_buffers_changed anyway. */
11516 if (windows_or_buffers_changed
11517 || w
->update_mode_line
11518 || update_mode_lines
11519 || window_buffer_changed (w
))
11521 struct buffer
*prev
= current_buffer
;
11522 ptrdiff_t count
= SPECPDL_INDEX ();
11523 Lisp_Object frame
, new_tool_bar
;
11524 int new_n_tool_bar
;
11525 struct gcpro gcpro1
;
11527 /* Set current_buffer to the buffer of the selected
11528 window of the frame, so that we get the right local
11530 set_buffer_internal_1 (XBUFFER (w
->contents
));
11532 /* Save match data, if we must. */
11533 if (save_match_data
)
11534 record_unwind_save_match_data ();
11536 /* Make sure that we don't accidentally use bogus keymaps. */
11537 if (NILP (Voverriding_local_map_menu_flag
))
11539 specbind (Qoverriding_terminal_local_map
, Qnil
);
11540 specbind (Qoverriding_local_map
, Qnil
);
11543 GCPRO1 (new_tool_bar
);
11545 /* We must temporarily set the selected frame to this frame
11546 before calling tool_bar_items, because the calculation of
11547 the tool-bar keymap uses the selected frame (see
11548 `tool-bar-make-keymap' in tool-bar.el). */
11549 eassert (EQ (selected_window
,
11550 /* Since we only explicitly preserve selected_frame,
11551 check that selected_window would be redundant. */
11552 XFRAME (selected_frame
)->selected_window
));
11553 record_unwind_protect (fast_set_selected_frame
, selected_frame
);
11554 XSETFRAME (frame
, f
);
11555 fast_set_selected_frame (frame
);
11557 /* Build desired tool-bar items from keymaps. */
11559 = tool_bar_items (Fcopy_sequence (f
->tool_bar_items
),
11562 /* Redisplay the tool-bar if we changed it. */
11563 if (new_n_tool_bar
!= f
->n_tool_bar_items
11564 || NILP (Fequal (new_tool_bar
, f
->tool_bar_items
)))
11566 /* Redisplay that happens asynchronously due to an expose event
11567 may access f->tool_bar_items. Make sure we update both
11568 variables within BLOCK_INPUT so no such event interrupts. */
11570 fset_tool_bar_items (f
, new_tool_bar
);
11571 f
->n_tool_bar_items
= new_n_tool_bar
;
11572 w
->update_mode_line
= 1;
11578 unbind_to (count
, Qnil
);
11579 set_buffer_internal_1 (prev
);
11584 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
11586 /* Set F->desired_tool_bar_string to a Lisp string representing frame
11587 F's desired tool-bar contents. F->tool_bar_items must have
11588 been set up previously by calling prepare_menu_bars. */
11591 build_desired_tool_bar_string (struct frame
*f
)
11593 int i
, size
, size_needed
;
11594 struct gcpro gcpro1
, gcpro2
, gcpro3
;
11595 Lisp_Object image
, plist
, props
;
11597 image
= plist
= props
= Qnil
;
11598 GCPRO3 (image
, plist
, props
);
11600 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
11601 Otherwise, make a new string. */
11603 /* The size of the string we might be able to reuse. */
11604 size
= (STRINGP (f
->desired_tool_bar_string
)
11605 ? SCHARS (f
->desired_tool_bar_string
)
11608 /* We need one space in the string for each image. */
11609 size_needed
= f
->n_tool_bar_items
;
11611 /* Reuse f->desired_tool_bar_string, if possible. */
11612 if (size
< size_needed
|| NILP (f
->desired_tool_bar_string
))
11613 fset_desired_tool_bar_string
11614 (f
, Fmake_string (make_number (size_needed
), make_number (' ')));
11617 props
= list4 (Qdisplay
, Qnil
, Qmenu_item
, Qnil
);
11618 Fremove_text_properties (make_number (0), make_number (size
),
11619 props
, f
->desired_tool_bar_string
);
11622 /* Put a `display' property on the string for the images to display,
11623 put a `menu_item' property on tool-bar items with a value that
11624 is the index of the item in F's tool-bar item vector. */
11625 for (i
= 0; i
< f
->n_tool_bar_items
; ++i
)
11627 #define PROP(IDX) \
11628 AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
11630 int enabled_p
= !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P
));
11631 int selected_p
= !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P
));
11632 int hmargin
, vmargin
, relief
, idx
, end
;
11634 /* If image is a vector, choose the image according to the
11636 image
= PROP (TOOL_BAR_ITEM_IMAGES
);
11637 if (VECTORP (image
))
11641 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
11642 : TOOL_BAR_IMAGE_ENABLED_DESELECTED
);
11645 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
11646 : TOOL_BAR_IMAGE_DISABLED_DESELECTED
);
11648 eassert (ASIZE (image
) >= idx
);
11649 image
= AREF (image
, idx
);
11654 /* Ignore invalid image specifications. */
11655 if (!valid_image_p (image
))
11658 /* Display the tool-bar button pressed, or depressed. */
11659 plist
= Fcopy_sequence (XCDR (image
));
11661 /* Compute margin and relief to draw. */
11662 relief
= (tool_bar_button_relief
>= 0
11663 ? tool_bar_button_relief
11664 : DEFAULT_TOOL_BAR_BUTTON_RELIEF
);
11665 hmargin
= vmargin
= relief
;
11667 if (RANGED_INTEGERP (1, Vtool_bar_button_margin
,
11668 INT_MAX
- max (hmargin
, vmargin
)))
11670 hmargin
+= XFASTINT (Vtool_bar_button_margin
);
11671 vmargin
+= XFASTINT (Vtool_bar_button_margin
);
11673 else if (CONSP (Vtool_bar_button_margin
))
11675 if (RANGED_INTEGERP (1, XCAR (Vtool_bar_button_margin
),
11676 INT_MAX
- hmargin
))
11677 hmargin
+= XFASTINT (XCAR (Vtool_bar_button_margin
));
11679 if (RANGED_INTEGERP (1, XCDR (Vtool_bar_button_margin
),
11680 INT_MAX
- vmargin
))
11681 vmargin
+= XFASTINT (XCDR (Vtool_bar_button_margin
));
11684 if (auto_raise_tool_bar_buttons_p
)
11686 /* Add a `:relief' property to the image spec if the item is
11690 plist
= Fplist_put (plist
, QCrelief
, make_number (-relief
));
11697 /* If image is selected, display it pressed, i.e. with a
11698 negative relief. If it's not selected, display it with a
11700 plist
= Fplist_put (plist
, QCrelief
,
11702 ? make_number (-relief
)
11703 : make_number (relief
)));
11708 /* Put a margin around the image. */
11709 if (hmargin
|| vmargin
)
11711 if (hmargin
== vmargin
)
11712 plist
= Fplist_put (plist
, QCmargin
, make_number (hmargin
));
11714 plist
= Fplist_put (plist
, QCmargin
,
11715 Fcons (make_number (hmargin
),
11716 make_number (vmargin
)));
11719 /* If button is not enabled, and we don't have special images
11720 for the disabled state, make the image appear disabled by
11721 applying an appropriate algorithm to it. */
11722 if (!enabled_p
&& idx
< 0)
11723 plist
= Fplist_put (plist
, QCconversion
, Qdisabled
);
11725 /* Put a `display' text property on the string for the image to
11726 display. Put a `menu-item' property on the string that gives
11727 the start of this item's properties in the tool-bar items
11729 image
= Fcons (Qimage
, plist
);
11730 props
= list4 (Qdisplay
, image
,
11731 Qmenu_item
, make_number (i
* TOOL_BAR_ITEM_NSLOTS
));
11733 /* Let the last image hide all remaining spaces in the tool bar
11734 string. The string can be longer than needed when we reuse a
11735 previous string. */
11736 if (i
+ 1 == f
->n_tool_bar_items
)
11737 end
= SCHARS (f
->desired_tool_bar_string
);
11740 Fadd_text_properties (make_number (i
), make_number (end
),
11741 props
, f
->desired_tool_bar_string
);
11749 /* Display one line of the tool-bar of frame IT->f.
11751 HEIGHT specifies the desired height of the tool-bar line.
11752 If the actual height of the glyph row is less than HEIGHT, the
11753 row's height is increased to HEIGHT, and the icons are centered
11754 vertically in the new height.
11756 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
11757 count a final empty row in case the tool-bar width exactly matches
11762 display_tool_bar_line (struct it
*it
, int height
)
11764 struct glyph_row
*row
= it
->glyph_row
;
11765 int max_x
= it
->last_visible_x
;
11766 struct glyph
*last
;
11768 prepare_desired_row (row
);
11769 row
->y
= it
->current_y
;
11771 /* Note that this isn't made use of if the face hasn't a box,
11772 so there's no need to check the face here. */
11773 it
->start_of_box_run_p
= 1;
11775 while (it
->current_x
< max_x
)
11777 int x
, n_glyphs_before
, i
, nglyphs
;
11778 struct it it_before
;
11780 /* Get the next display element. */
11781 if (!get_next_display_element (it
))
11783 /* Don't count empty row if we are counting needed tool-bar lines. */
11784 if (height
< 0 && !it
->hpos
)
11789 /* Produce glyphs. */
11790 n_glyphs_before
= row
->used
[TEXT_AREA
];
11793 PRODUCE_GLYPHS (it
);
11795 nglyphs
= row
->used
[TEXT_AREA
] - n_glyphs_before
;
11797 x
= it_before
.current_x
;
11798 while (i
< nglyphs
)
11800 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
11802 if (x
+ glyph
->pixel_width
> max_x
)
11804 /* Glyph doesn't fit on line. Backtrack. */
11805 row
->used
[TEXT_AREA
] = n_glyphs_before
;
11807 /* If this is the only glyph on this line, it will never fit on the
11808 tool-bar, so skip it. But ensure there is at least one glyph,
11809 so we don't accidentally disable the tool-bar. */
11810 if (n_glyphs_before
== 0
11811 && (it
->vpos
> 0 || IT_STRING_CHARPOS (*it
) < it
->end_charpos
-1))
11817 x
+= glyph
->pixel_width
;
11821 /* Stop at line end. */
11822 if (ITERATOR_AT_END_OF_LINE_P (it
))
11825 set_iterator_to_next (it
, 1);
11830 row
->displays_text_p
= row
->used
[TEXT_AREA
] != 0;
11832 /* Use default face for the border below the tool bar.
11834 FIXME: When auto-resize-tool-bars is grow-only, there is
11835 no additional border below the possibly empty tool-bar lines.
11836 So to make the extra empty lines look "normal", we have to
11837 use the tool-bar face for the border too. */
11838 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row
)
11839 && !EQ (Vauto_resize_tool_bars
, Qgrow_only
))
11840 it
->face_id
= DEFAULT_FACE_ID
;
11842 extend_face_to_end_of_line (it
);
11843 last
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
] - 1;
11844 last
->right_box_line_p
= 1;
11845 if (last
== row
->glyphs
[TEXT_AREA
])
11846 last
->left_box_line_p
= 1;
11848 /* Make line the desired height and center it vertically. */
11849 if ((height
-= it
->max_ascent
+ it
->max_descent
) > 0)
11851 /* Don't add more than one line height. */
11852 height
%= FRAME_LINE_HEIGHT (it
->f
);
11853 it
->max_ascent
+= height
/ 2;
11854 it
->max_descent
+= (height
+ 1) / 2;
11857 compute_line_metrics (it
);
11859 /* If line is empty, make it occupy the rest of the tool-bar. */
11860 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row
))
11862 row
->height
= row
->phys_height
= it
->last_visible_y
- row
->y
;
11863 row
->visible_height
= row
->height
;
11864 row
->ascent
= row
->phys_ascent
= 0;
11865 row
->extra_line_spacing
= 0;
11868 row
->full_width_p
= 1;
11869 row
->continued_p
= 0;
11870 row
->truncated_on_left_p
= 0;
11871 row
->truncated_on_right_p
= 0;
11873 it
->current_x
= it
->hpos
= 0;
11874 it
->current_y
+= row
->height
;
11880 /* Max tool-bar height. */
11882 #define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
11883 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
11885 /* Value is the number of screen lines needed to make all tool-bar
11886 items of frame F visible. The number of actual rows needed is
11887 returned in *N_ROWS if non-NULL. */
11890 tool_bar_lines_needed (struct frame
*f
, int *n_rows
)
11892 struct window
*w
= XWINDOW (f
->tool_bar_window
);
11894 /* tool_bar_lines_needed is called from redisplay_tool_bar after building
11895 the desired matrix, so use (unused) mode-line row as temporary row to
11896 avoid destroying the first tool-bar row. */
11897 struct glyph_row
*temp_row
= MATRIX_MODE_LINE_ROW (w
->desired_matrix
);
11899 /* Initialize an iterator for iteration over
11900 F->desired_tool_bar_string in the tool-bar window of frame F. */
11901 init_iterator (&it
, w
, -1, -1, temp_row
, TOOL_BAR_FACE_ID
);
11902 it
.first_visible_x
= 0;
11903 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
11904 reseat_to_string (&it
, NULL
, f
->desired_tool_bar_string
, 0, 0, 0, -1);
11905 it
.paragraph_embedding
= L2R
;
11907 while (!ITERATOR_AT_END_P (&it
))
11909 clear_glyph_row (temp_row
);
11910 it
.glyph_row
= temp_row
;
11911 display_tool_bar_line (&it
, -1);
11913 clear_glyph_row (temp_row
);
11915 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
11917 *n_rows
= it
.vpos
> 0 ? it
.vpos
: -1;
11919 return (it
.current_y
+ FRAME_LINE_HEIGHT (f
) - 1) / FRAME_LINE_HEIGHT (f
);
11922 #endif /* !USE_GTK && !HAVE_NS */
11924 #if defined USE_GTK || defined HAVE_NS
11925 EXFUN (Ftool_bar_lines_needed
, 1) ATTRIBUTE_CONST
;
11928 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed
, Stool_bar_lines_needed
,
11930 doc
: /* Return the number of lines occupied by the tool bar of FRAME.
11931 If FRAME is nil or omitted, use the selected frame. */)
11932 (Lisp_Object frame
)
11935 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
11936 struct frame
*f
= decode_any_frame (frame
);
11939 if (WINDOWP (f
->tool_bar_window
)
11940 && (w
= XWINDOW (f
->tool_bar_window
),
11941 WINDOW_TOTAL_LINES (w
) > 0))
11943 update_tool_bar (f
, 1);
11944 if (f
->n_tool_bar_items
)
11946 build_desired_tool_bar_string (f
);
11947 nlines
= tool_bar_lines_needed (f
, NULL
);
11951 return make_number (nlines
);
11955 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
11956 height should be changed. */
11959 redisplay_tool_bar (struct frame
*f
)
11961 #if defined (USE_GTK) || defined (HAVE_NS)
11963 if (FRAME_EXTERNAL_TOOL_BAR (f
))
11964 update_frame_tool_bar (f
);
11967 #else /* !USE_GTK && !HAVE_NS */
11971 struct glyph_row
*row
;
11973 /* If frame hasn't a tool-bar window or if it is zero-height, don't
11974 do anything. This means you must start with tool-bar-lines
11975 non-zero to get the auto-sizing effect. Or in other words, you
11976 can turn off tool-bars by specifying tool-bar-lines zero. */
11977 if (!WINDOWP (f
->tool_bar_window
)
11978 || (w
= XWINDOW (f
->tool_bar_window
),
11979 WINDOW_TOTAL_LINES (w
) == 0))
11982 /* Set up an iterator for the tool-bar window. */
11983 init_iterator (&it
, w
, -1, -1, w
->desired_matrix
->rows
, TOOL_BAR_FACE_ID
);
11984 it
.first_visible_x
= 0;
11985 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
11986 row
= it
.glyph_row
;
11988 /* Build a string that represents the contents of the tool-bar. */
11989 build_desired_tool_bar_string (f
);
11990 reseat_to_string (&it
, NULL
, f
->desired_tool_bar_string
, 0, 0, 0, -1);
11991 /* FIXME: This should be controlled by a user option. But it
11992 doesn't make sense to have an R2L tool bar if the menu bar cannot
11993 be drawn also R2L, and making the menu bar R2L is tricky due
11994 toolkit-specific code that implements it. If an R2L tool bar is
11995 ever supported, display_tool_bar_line should also be augmented to
11996 call unproduce_glyphs like display_line and display_string
11998 it
.paragraph_embedding
= L2R
;
12000 if (f
->n_tool_bar_rows
== 0)
12004 if ((nlines
= tool_bar_lines_needed (f
, &f
->n_tool_bar_rows
),
12005 nlines
!= WINDOW_TOTAL_LINES (w
)))
12008 int old_height
= WINDOW_TOTAL_LINES (w
);
12010 XSETFRAME (frame
, f
);
12011 Fmodify_frame_parameters (frame
,
12012 list1 (Fcons (Qtool_bar_lines
,
12013 make_number (nlines
))));
12014 if (WINDOW_TOTAL_LINES (w
) != old_height
)
12016 clear_glyph_matrix (w
->desired_matrix
);
12017 f
->fonts_changed
= 1;
12023 /* Display as many lines as needed to display all tool-bar items. */
12025 if (f
->n_tool_bar_rows
> 0)
12027 int border
, rows
, height
, extra
;
12029 if (TYPE_RANGED_INTEGERP (int, Vtool_bar_border
))
12030 border
= XINT (Vtool_bar_border
);
12031 else if (EQ (Vtool_bar_border
, Qinternal_border_width
))
12032 border
= FRAME_INTERNAL_BORDER_WIDTH (f
);
12033 else if (EQ (Vtool_bar_border
, Qborder_width
))
12034 border
= f
->border_width
;
12040 rows
= f
->n_tool_bar_rows
;
12041 height
= max (1, (it
.last_visible_y
- border
) / rows
);
12042 extra
= it
.last_visible_y
- border
- height
* rows
;
12044 while (it
.current_y
< it
.last_visible_y
)
12047 if (extra
> 0 && rows
-- > 0)
12049 h
= (extra
+ rows
- 1) / rows
;
12052 display_tool_bar_line (&it
, height
+ h
);
12057 while (it
.current_y
< it
.last_visible_y
)
12058 display_tool_bar_line (&it
, 0);
12061 /* It doesn't make much sense to try scrolling in the tool-bar
12062 window, so don't do it. */
12063 w
->desired_matrix
->no_scrolling_p
= 1;
12064 w
->must_be_updated_p
= 1;
12066 if (!NILP (Vauto_resize_tool_bars
))
12068 int max_tool_bar_height
= MAX_FRAME_TOOL_BAR_HEIGHT (f
);
12069 int change_height_p
= 0;
12071 /* If we couldn't display everything, change the tool-bar's
12072 height if there is room for more. */
12073 if (IT_STRING_CHARPOS (it
) < it
.end_charpos
12074 && it
.current_y
< max_tool_bar_height
)
12075 change_height_p
= 1;
12077 row
= it
.glyph_row
- 1;
12079 /* If there are blank lines at the end, except for a partially
12080 visible blank line at the end that is smaller than
12081 FRAME_LINE_HEIGHT, change the tool-bar's height. */
12082 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row
)
12083 && row
->height
>= FRAME_LINE_HEIGHT (f
))
12084 change_height_p
= 1;
12086 /* If row displays tool-bar items, but is partially visible,
12087 change the tool-bar's height. */
12088 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
)
12089 && MATRIX_ROW_BOTTOM_Y (row
) > it
.last_visible_y
12090 && MATRIX_ROW_BOTTOM_Y (row
) < max_tool_bar_height
)
12091 change_height_p
= 1;
12093 /* Resize windows as needed by changing the `tool-bar-lines'
12094 frame parameter. */
12095 if (change_height_p
)
12098 int old_height
= WINDOW_TOTAL_LINES (w
);
12100 int nlines
= tool_bar_lines_needed (f
, &nrows
);
12102 change_height_p
= ((EQ (Vauto_resize_tool_bars
, Qgrow_only
)
12103 && !f
->minimize_tool_bar_window_p
)
12104 ? (nlines
> old_height
)
12105 : (nlines
!= old_height
));
12106 f
->minimize_tool_bar_window_p
= 0;
12108 if (change_height_p
)
12110 XSETFRAME (frame
, f
);
12111 Fmodify_frame_parameters (frame
,
12112 list1 (Fcons (Qtool_bar_lines
,
12113 make_number (nlines
))));
12114 if (WINDOW_TOTAL_LINES (w
) != old_height
)
12116 clear_glyph_matrix (w
->desired_matrix
);
12117 f
->n_tool_bar_rows
= nrows
;
12118 f
->fonts_changed
= 1;
12125 f
->minimize_tool_bar_window_p
= 0;
12128 #endif /* USE_GTK || HAVE_NS */
12131 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
12133 /* Get information about the tool-bar item which is displayed in GLYPH
12134 on frame F. Return in *PROP_IDX the index where tool-bar item
12135 properties start in F->tool_bar_items. Value is zero if
12136 GLYPH doesn't display a tool-bar item. */
12139 tool_bar_item_info (struct frame
*f
, struct glyph
*glyph
, int *prop_idx
)
12145 /* This function can be called asynchronously, which means we must
12146 exclude any possibility that Fget_text_property signals an
12148 charpos
= min (SCHARS (f
->current_tool_bar_string
), glyph
->charpos
);
12149 charpos
= max (0, charpos
);
12151 /* Get the text property `menu-item' at pos. The value of that
12152 property is the start index of this item's properties in
12153 F->tool_bar_items. */
12154 prop
= Fget_text_property (make_number (charpos
),
12155 Qmenu_item
, f
->current_tool_bar_string
);
12156 if (INTEGERP (prop
))
12158 *prop_idx
= XINT (prop
);
12168 /* Get information about the tool-bar item at position X/Y on frame F.
12169 Return in *GLYPH a pointer to the glyph of the tool-bar item in
12170 the current matrix of the tool-bar window of F, or NULL if not
12171 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
12172 item in F->tool_bar_items. Value is
12174 -1 if X/Y is not on a tool-bar item
12175 0 if X/Y is on the same item that was highlighted before.
12179 get_tool_bar_item (struct frame
*f
, int x
, int y
, struct glyph
**glyph
,
12180 int *hpos
, int *vpos
, int *prop_idx
)
12182 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
12183 struct window
*w
= XWINDOW (f
->tool_bar_window
);
12186 /* Find the glyph under X/Y. */
12187 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, 0, 0, &area
);
12188 if (*glyph
== NULL
)
12191 /* Get the start of this tool-bar item's properties in
12192 f->tool_bar_items. */
12193 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
12196 /* Is mouse on the highlighted item? */
12197 if (EQ (f
->tool_bar_window
, hlinfo
->mouse_face_window
)
12198 && *vpos
>= hlinfo
->mouse_face_beg_row
12199 && *vpos
<= hlinfo
->mouse_face_end_row
12200 && (*vpos
> hlinfo
->mouse_face_beg_row
12201 || *hpos
>= hlinfo
->mouse_face_beg_col
)
12202 && (*vpos
< hlinfo
->mouse_face_end_row
12203 || *hpos
< hlinfo
->mouse_face_end_col
12204 || hlinfo
->mouse_face_past_end
))
12212 Handle mouse button event on the tool-bar of frame F, at
12213 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
12214 0 for button release. MODIFIERS is event modifiers for button
12218 handle_tool_bar_click (struct frame
*f
, int x
, int y
, int down_p
,
12221 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
12222 struct window
*w
= XWINDOW (f
->tool_bar_window
);
12223 int hpos
, vpos
, prop_idx
;
12224 struct glyph
*glyph
;
12225 Lisp_Object enabled_p
;
12228 /* If not on the highlighted tool-bar item, and mouse-highlight is
12229 non-nil, return. This is so we generate the tool-bar button
12230 click only when the mouse button is released on the same item as
12231 where it was pressed. However, when mouse-highlight is disabled,
12232 generate the click when the button is released regardless of the
12233 highlight, since tool-bar items are not highlighted in that
12235 frame_to_window_pixel_xy (w
, &x
, &y
);
12236 ts
= get_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
12238 || (ts
!= 0 && !NILP (Vmouse_highlight
)))
12241 /* When mouse-highlight is off, generate the click for the item
12242 where the button was pressed, disregarding where it was
12244 if (NILP (Vmouse_highlight
) && !down_p
)
12245 prop_idx
= last_tool_bar_item
;
12247 /* If item is disabled, do nothing. */
12248 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
12249 if (NILP (enabled_p
))
12254 /* Show item in pressed state. */
12255 if (!NILP (Vmouse_highlight
))
12256 show_mouse_face (hlinfo
, DRAW_IMAGE_SUNKEN
);
12257 last_tool_bar_item
= prop_idx
;
12261 Lisp_Object key
, frame
;
12262 struct input_event event
;
12263 EVENT_INIT (event
);
12265 /* Show item in released state. */
12266 if (!NILP (Vmouse_highlight
))
12267 show_mouse_face (hlinfo
, DRAW_IMAGE_RAISED
);
12269 key
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_KEY
);
12271 XSETFRAME (frame
, f
);
12272 event
.kind
= TOOL_BAR_EVENT
;
12273 event
.frame_or_window
= frame
;
12275 kbd_buffer_store_event (&event
);
12277 event
.kind
= TOOL_BAR_EVENT
;
12278 event
.frame_or_window
= frame
;
12280 event
.modifiers
= modifiers
;
12281 kbd_buffer_store_event (&event
);
12282 last_tool_bar_item
= -1;
12287 /* Possibly highlight a tool-bar item on frame F when mouse moves to
12288 tool-bar window-relative coordinates X/Y. Called from
12289 note_mouse_highlight. */
12292 note_tool_bar_highlight (struct frame
*f
, int x
, int y
)
12294 Lisp_Object window
= f
->tool_bar_window
;
12295 struct window
*w
= XWINDOW (window
);
12296 Display_Info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
12297 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
12299 struct glyph
*glyph
;
12300 struct glyph_row
*row
;
12302 Lisp_Object enabled_p
;
12304 enum draw_glyphs_face draw
= DRAW_IMAGE_RAISED
;
12305 int mouse_down_p
, rc
;
12307 /* Function note_mouse_highlight is called with negative X/Y
12308 values when mouse moves outside of the frame. */
12309 if (x
<= 0 || y
<= 0)
12311 clear_mouse_face (hlinfo
);
12315 rc
= get_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
12318 /* Not on tool-bar item. */
12319 clear_mouse_face (hlinfo
);
12323 /* On same tool-bar item as before. */
12324 goto set_help_echo
;
12326 clear_mouse_face (hlinfo
);
12328 /* Mouse is down, but on different tool-bar item? */
12329 mouse_down_p
= (x_mouse_grabbed (dpyinfo
)
12330 && f
== dpyinfo
->last_mouse_frame
);
12333 && last_tool_bar_item
!= prop_idx
)
12336 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
12338 /* If tool-bar item is not enabled, don't highlight it. */
12339 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
12340 if (!NILP (enabled_p
) && !NILP (Vmouse_highlight
))
12342 /* Compute the x-position of the glyph. In front and past the
12343 image is a space. We include this in the highlighted area. */
12344 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
12345 for (i
= x
= 0; i
< hpos
; ++i
)
12346 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
12348 /* Record this as the current active region. */
12349 hlinfo
->mouse_face_beg_col
= hpos
;
12350 hlinfo
->mouse_face_beg_row
= vpos
;
12351 hlinfo
->mouse_face_beg_x
= x
;
12352 hlinfo
->mouse_face_past_end
= 0;
12354 hlinfo
->mouse_face_end_col
= hpos
+ 1;
12355 hlinfo
->mouse_face_end_row
= vpos
;
12356 hlinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
12357 hlinfo
->mouse_face_window
= window
;
12358 hlinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
12360 /* Display it as active. */
12361 show_mouse_face (hlinfo
, draw
);
12366 /* Set help_echo_string to a help string to display for this tool-bar item.
12367 XTread_socket does the rest. */
12368 help_echo_object
= help_echo_window
= Qnil
;
12369 help_echo_pos
= -1;
12370 help_echo_string
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_HELP
);
12371 if (NILP (help_echo_string
))
12372 help_echo_string
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_CAPTION
);
12375 #endif /* !USE_GTK && !HAVE_NS */
12377 #endif /* HAVE_WINDOW_SYSTEM */
12381 /************************************************************************
12382 Horizontal scrolling
12383 ************************************************************************/
12385 static int hscroll_window_tree (Lisp_Object
);
12386 static int hscroll_windows (Lisp_Object
);
12388 /* For all leaf windows in the window tree rooted at WINDOW, set their
12389 hscroll value so that PT is (i) visible in the window, and (ii) so
12390 that it is not within a certain margin at the window's left and
12391 right border. Value is non-zero if any window's hscroll has been
12395 hscroll_window_tree (Lisp_Object window
)
12397 int hscrolled_p
= 0;
12398 int hscroll_relative_p
= FLOATP (Vhscroll_step
);
12399 int hscroll_step_abs
= 0;
12400 double hscroll_step_rel
= 0;
12402 if (hscroll_relative_p
)
12404 hscroll_step_rel
= XFLOAT_DATA (Vhscroll_step
);
12405 if (hscroll_step_rel
< 0)
12407 hscroll_relative_p
= 0;
12408 hscroll_step_abs
= 0;
12411 else if (TYPE_RANGED_INTEGERP (int, Vhscroll_step
))
12413 hscroll_step_abs
= XINT (Vhscroll_step
);
12414 if (hscroll_step_abs
< 0)
12415 hscroll_step_abs
= 0;
12418 hscroll_step_abs
= 0;
12420 while (WINDOWP (window
))
12422 struct window
*w
= XWINDOW (window
);
12424 if (WINDOWP (w
->contents
))
12425 hscrolled_p
|= hscroll_window_tree (w
->contents
);
12426 else if (w
->cursor
.vpos
>= 0)
12429 int text_area_width
;
12430 struct glyph_row
*current_cursor_row
12431 = MATRIX_ROW (w
->current_matrix
, w
->cursor
.vpos
);
12432 struct glyph_row
*desired_cursor_row
12433 = MATRIX_ROW (w
->desired_matrix
, w
->cursor
.vpos
);
12434 struct glyph_row
*cursor_row
12435 = (desired_cursor_row
->enabled_p
12436 ? desired_cursor_row
12437 : current_cursor_row
);
12438 int row_r2l_p
= cursor_row
->reversed_p
;
12440 text_area_width
= window_box_width (w
, TEXT_AREA
);
12442 /* Scroll when cursor is inside this scroll margin. */
12443 h_margin
= hscroll_margin
* WINDOW_FRAME_COLUMN_WIDTH (w
);
12445 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode
, w
->contents
))
12446 /* For left-to-right rows, hscroll when cursor is either
12447 (i) inside the right hscroll margin, or (ii) if it is
12448 inside the left margin and the window is already
12452 && w
->cursor
.x
<= h_margin
)
12453 || (cursor_row
->enabled_p
12454 && cursor_row
->truncated_on_right_p
12455 && (w
->cursor
.x
>= text_area_width
- h_margin
))))
12456 /* For right-to-left rows, the logic is similar,
12457 except that rules for scrolling to left and right
12458 are reversed. E.g., if cursor.x <= h_margin, we
12459 need to hscroll "to the right" unconditionally,
12460 and that will scroll the screen to the left so as
12461 to reveal the next portion of the row. */
12463 && ((cursor_row
->enabled_p
12464 /* FIXME: It is confusing to set the
12465 truncated_on_right_p flag when R2L rows
12466 are actually truncated on the left. */
12467 && cursor_row
->truncated_on_right_p
12468 && w
->cursor
.x
<= h_margin
)
12470 && (w
->cursor
.x
>= text_area_width
- h_margin
))))))
12474 struct buffer
*saved_current_buffer
;
12478 /* Find point in a display of infinite width. */
12479 saved_current_buffer
= current_buffer
;
12480 current_buffer
= XBUFFER (w
->contents
);
12482 if (w
== XWINDOW (selected_window
))
12485 pt
= clip_to_bounds (BEGV
, marker_position (w
->pointm
), ZV
);
12487 /* Move iterator to pt starting at cursor_row->start in
12488 a line with infinite width. */
12489 init_to_row_start (&it
, w
, cursor_row
);
12490 it
.last_visible_x
= INFINITY
;
12491 move_it_in_display_line_to (&it
, pt
, -1, MOVE_TO_POS
);
12492 current_buffer
= saved_current_buffer
;
12494 /* Position cursor in window. */
12495 if (!hscroll_relative_p
&& hscroll_step_abs
== 0)
12496 hscroll
= max (0, (it
.current_x
12497 - (ITERATOR_AT_END_OF_LINE_P (&it
)
12498 ? (text_area_width
- 4 * FRAME_COLUMN_WIDTH (it
.f
))
12499 : (text_area_width
/ 2))))
12500 / FRAME_COLUMN_WIDTH (it
.f
);
12501 else if ((!row_r2l_p
12502 && w
->cursor
.x
>= text_area_width
- h_margin
)
12503 || (row_r2l_p
&& w
->cursor
.x
<= h_margin
))
12505 if (hscroll_relative_p
)
12506 wanted_x
= text_area_width
* (1 - hscroll_step_rel
)
12509 wanted_x
= text_area_width
12510 - hscroll_step_abs
* FRAME_COLUMN_WIDTH (it
.f
)
12513 = max (0, it
.current_x
- wanted_x
) / FRAME_COLUMN_WIDTH (it
.f
);
12517 if (hscroll_relative_p
)
12518 wanted_x
= text_area_width
* hscroll_step_rel
12521 wanted_x
= hscroll_step_abs
* FRAME_COLUMN_WIDTH (it
.f
)
12524 = max (0, it
.current_x
- wanted_x
) / FRAME_COLUMN_WIDTH (it
.f
);
12526 hscroll
= max (hscroll
, w
->min_hscroll
);
12528 /* Don't prevent redisplay optimizations if hscroll
12529 hasn't changed, as it will unnecessarily slow down
12531 if (w
->hscroll
!= hscroll
)
12533 XBUFFER (w
->contents
)->prevent_redisplay_optimizations_p
= 1;
12534 w
->hscroll
= hscroll
;
12543 /* Value is non-zero if hscroll of any leaf window has been changed. */
12544 return hscrolled_p
;
12548 /* Set hscroll so that cursor is visible and not inside horizontal
12549 scroll margins for all windows in the tree rooted at WINDOW. See
12550 also hscroll_window_tree above. Value is non-zero if any window's
12551 hscroll has been changed. If it has, desired matrices on the frame
12552 of WINDOW are cleared. */
12555 hscroll_windows (Lisp_Object window
)
12557 int hscrolled_p
= hscroll_window_tree (window
);
12559 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window
))));
12560 return hscrolled_p
;
12565 /************************************************************************
12567 ************************************************************************/
12569 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
12570 to a non-zero value. This is sometimes handy to have in a debugger
12575 /* First and last unchanged row for try_window_id. */
12577 static int debug_first_unchanged_at_end_vpos
;
12578 static int debug_last_unchanged_at_beg_vpos
;
12580 /* Delta vpos and y. */
12582 static int debug_dvpos
, debug_dy
;
12584 /* Delta in characters and bytes for try_window_id. */
12586 static ptrdiff_t debug_delta
, debug_delta_bytes
;
12588 /* Values of window_end_pos and window_end_vpos at the end of
12591 static ptrdiff_t debug_end_vpos
;
12593 /* Append a string to W->desired_matrix->method. FMT is a printf
12594 format string. If trace_redisplay_p is non-zero also printf the
12595 resulting string to stderr. */
12597 static void debug_method_add (struct window
*, char const *, ...)
12598 ATTRIBUTE_FORMAT_PRINTF (2, 3);
12601 debug_method_add (struct window
*w
, char const *fmt
, ...)
12604 char *method
= w
->desired_matrix
->method
;
12605 int len
= strlen (method
);
12606 int size
= sizeof w
->desired_matrix
->method
;
12607 int remaining
= size
- len
- 1;
12610 if (len
&& remaining
)
12613 --remaining
, ++len
;
12616 va_start (ap
, fmt
);
12617 vsnprintf (method
+ len
, remaining
+ 1, fmt
, ap
);
12620 if (trace_redisplay_p
)
12621 fprintf (stderr
, "%p (%s): %s\n",
12623 ((BUFFERP (w
->contents
)
12624 && STRINGP (BVAR (XBUFFER (w
->contents
), name
)))
12625 ? SSDATA (BVAR (XBUFFER (w
->contents
), name
))
12630 #endif /* GLYPH_DEBUG */
12633 /* Value is non-zero if all changes in window W, which displays
12634 current_buffer, are in the text between START and END. START is a
12635 buffer position, END is given as a distance from Z. Used in
12636 redisplay_internal for display optimization. */
12639 text_outside_line_unchanged_p (struct window
*w
,
12640 ptrdiff_t start
, ptrdiff_t end
)
12642 int unchanged_p
= 1;
12644 /* If text or overlays have changed, see where. */
12645 if (window_outdated (w
))
12647 /* Gap in the line? */
12648 if (GPT
< start
|| Z
- GPT
< end
)
12651 /* Changes start in front of the line, or end after it? */
12653 && (BEG_UNCHANGED
< start
- 1
12654 || END_UNCHANGED
< end
))
12657 /* If selective display, can't optimize if changes start at the
12658 beginning of the line. */
12660 && INTEGERP (BVAR (current_buffer
, selective_display
))
12661 && XINT (BVAR (current_buffer
, selective_display
)) > 0
12662 && (BEG_UNCHANGED
< start
|| GPT
<= start
))
12665 /* If there are overlays at the start or end of the line, these
12666 may have overlay strings with newlines in them. A change at
12667 START, for instance, may actually concern the display of such
12668 overlay strings as well, and they are displayed on different
12669 lines. So, quickly rule out this case. (For the future, it
12670 might be desirable to implement something more telling than
12671 just BEG/END_UNCHANGED.) */
12674 if (BEG
+ BEG_UNCHANGED
== start
12675 && overlay_touches_p (start
))
12677 if (END_UNCHANGED
== end
12678 && overlay_touches_p (Z
- end
))
12682 /* Under bidi reordering, adding or deleting a character in the
12683 beginning of a paragraph, before the first strong directional
12684 character, can change the base direction of the paragraph (unless
12685 the buffer specifies a fixed paragraph direction), which will
12686 require to redisplay the whole paragraph. It might be worthwhile
12687 to find the paragraph limits and widen the range of redisplayed
12688 lines to that, but for now just give up this optimization. */
12689 if (!NILP (BVAR (XBUFFER (w
->contents
), bidi_display_reordering
))
12690 && NILP (BVAR (XBUFFER (w
->contents
), bidi_paragraph_direction
)))
12694 return unchanged_p
;
12698 /* Do a frame update, taking possible shortcuts into account. This is
12699 the main external entry point for redisplay.
12701 If the last redisplay displayed an echo area message and that message
12702 is no longer requested, we clear the echo area or bring back the
12703 mini-buffer if that is in use. */
12708 redisplay_internal ();
12713 overlay_arrow_string_or_property (Lisp_Object var
)
12717 if (val
= Fget (var
, Qoverlay_arrow_string
), STRINGP (val
))
12720 return Voverlay_arrow_string
;
12723 /* Return 1 if there are any overlay-arrows in current_buffer. */
12725 overlay_arrow_in_current_buffer_p (void)
12729 for (vlist
= Voverlay_arrow_variable_list
;
12731 vlist
= XCDR (vlist
))
12733 Lisp_Object var
= XCAR (vlist
);
12736 if (!SYMBOLP (var
))
12738 val
= find_symbol_value (var
);
12740 && current_buffer
== XMARKER (val
)->buffer
)
12747 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
12751 overlay_arrows_changed_p (void)
12755 for (vlist
= Voverlay_arrow_variable_list
;
12757 vlist
= XCDR (vlist
))
12759 Lisp_Object var
= XCAR (vlist
);
12760 Lisp_Object val
, pstr
;
12762 if (!SYMBOLP (var
))
12764 val
= find_symbol_value (var
);
12765 if (!MARKERP (val
))
12767 if (! EQ (COERCE_MARKER (val
),
12768 Fget (var
, Qlast_arrow_position
))
12769 || ! (pstr
= overlay_arrow_string_or_property (var
),
12770 EQ (pstr
, Fget (var
, Qlast_arrow_string
))))
12776 /* Mark overlay arrows to be updated on next redisplay. */
12779 update_overlay_arrows (int up_to_date
)
12783 for (vlist
= Voverlay_arrow_variable_list
;
12785 vlist
= XCDR (vlist
))
12787 Lisp_Object var
= XCAR (vlist
);
12789 if (!SYMBOLP (var
))
12792 if (up_to_date
> 0)
12794 Lisp_Object val
= find_symbol_value (var
);
12795 Fput (var
, Qlast_arrow_position
,
12796 COERCE_MARKER (val
));
12797 Fput (var
, Qlast_arrow_string
,
12798 overlay_arrow_string_or_property (var
));
12800 else if (up_to_date
< 0
12801 || !NILP (Fget (var
, Qlast_arrow_position
)))
12803 Fput (var
, Qlast_arrow_position
, Qt
);
12804 Fput (var
, Qlast_arrow_string
, Qt
);
12810 /* Return overlay arrow string to display at row.
12811 Return integer (bitmap number) for arrow bitmap in left fringe.
12812 Return nil if no overlay arrow. */
12815 overlay_arrow_at_row (struct it
*it
, struct glyph_row
*row
)
12819 for (vlist
= Voverlay_arrow_variable_list
;
12821 vlist
= XCDR (vlist
))
12823 Lisp_Object var
= XCAR (vlist
);
12826 if (!SYMBOLP (var
))
12829 val
= find_symbol_value (var
);
12832 && current_buffer
== XMARKER (val
)->buffer
12833 && (MATRIX_ROW_START_CHARPOS (row
) == marker_position (val
)))
12835 if (FRAME_WINDOW_P (it
->f
)
12836 /* FIXME: if ROW->reversed_p is set, this should test
12837 the right fringe, not the left one. */
12838 && WINDOW_LEFT_FRINGE_WIDTH (it
->w
) > 0)
12840 #ifdef HAVE_WINDOW_SYSTEM
12841 if (val
= Fget (var
, Qoverlay_arrow_bitmap
), SYMBOLP (val
))
12844 if ((fringe_bitmap
= lookup_fringe_bitmap (val
)) != 0)
12845 return make_number (fringe_bitmap
);
12848 return make_number (-1); /* Use default arrow bitmap. */
12850 return overlay_arrow_string_or_property (var
);
12857 /* Return 1 if point moved out of or into a composition. Otherwise
12858 return 0. PREV_BUF and PREV_PT are the last point buffer and
12859 position. BUF and PT are the current point buffer and position. */
12862 check_point_in_composition (struct buffer
*prev_buf
, ptrdiff_t prev_pt
,
12863 struct buffer
*buf
, ptrdiff_t pt
)
12865 ptrdiff_t start
, end
;
12867 Lisp_Object buffer
;
12869 XSETBUFFER (buffer
, buf
);
12870 /* Check a composition at the last point if point moved within the
12872 if (prev_buf
== buf
)
12875 /* Point didn't move. */
12878 if (prev_pt
> BUF_BEGV (buf
) && prev_pt
< BUF_ZV (buf
)
12879 && find_composition (prev_pt
, -1, &start
, &end
, &prop
, buffer
)
12880 && composition_valid_p (start
, end
, prop
)
12881 && start
< prev_pt
&& end
> prev_pt
)
12882 /* The last point was within the composition. Return 1 iff
12883 point moved out of the composition. */
12884 return (pt
<= start
|| pt
>= end
);
12887 /* Check a composition at the current point. */
12888 return (pt
> BUF_BEGV (buf
) && pt
< BUF_ZV (buf
)
12889 && find_composition (pt
, -1, &start
, &end
, &prop
, buffer
)
12890 && composition_valid_p (start
, end
, prop
)
12891 && start
< pt
&& end
> pt
);
12894 /* Reconsider the clip changes of buffer which is displayed in W. */
12897 reconsider_clip_changes (struct window
*w
)
12899 struct buffer
*b
= XBUFFER (w
->contents
);
12901 if (b
->clip_changed
12902 && w
->window_end_valid
12903 && w
->current_matrix
->buffer
== b
12904 && w
->current_matrix
->zv
== BUF_ZV (b
)
12905 && w
->current_matrix
->begv
== BUF_BEGV (b
))
12906 b
->clip_changed
= 0;
12908 /* If display wasn't paused, and W is not a tool bar window, see if
12909 point has been moved into or out of a composition. In that case,
12910 we set b->clip_changed to 1 to force updating the screen. If
12911 b->clip_changed has already been set to 1, we can skip this
12913 if (!b
->clip_changed
&& w
->window_end_valid
)
12915 ptrdiff_t pt
= (w
== XWINDOW (selected_window
)
12916 ? PT
: marker_position (w
->pointm
));
12918 if ((w
->current_matrix
->buffer
!= b
|| pt
!= w
->last_point
)
12919 && check_point_in_composition (w
->current_matrix
->buffer
,
12920 w
->last_point
, b
, pt
))
12921 b
->clip_changed
= 1;
12925 void propagate_buffer_redisplay (void)
12926 { /* Resetting b->text->redisplay is problematic!
12927 We can't just reset it in the case that some window that displays
12928 it has not been redisplayed; and such a window can stay
12929 unredisplayed for a long time if it's currently invisible.
12930 But we do want to reset it at the end of redisplay otherwise
12931 its displayed windows will keep being redisplayed over and over
12933 So we copy all b->text->redisplay flags up to their windows here,
12934 such that mark_window_display_accurate can safely reset
12935 b->text->redisplay. */
12936 Lisp_Object ws
= window_list ();
12937 for (; CONSP (ws
); ws
= XCDR (ws
))
12939 struct window
*thisw
= XWINDOW (XCAR (ws
));
12940 struct buffer
*thisb
= XBUFFER (thisw
->contents
);
12941 if (thisb
->text
->redisplay
)
12942 thisw
->redisplay
= true;
12946 #define STOP_POLLING \
12947 do { if (! polling_stopped_here) stop_polling (); \
12948 polling_stopped_here = 1; } while (0)
12950 #define RESUME_POLLING \
12951 do { if (polling_stopped_here) start_polling (); \
12952 polling_stopped_here = 0; } while (0)
12955 /* Perhaps in the future avoid recentering windows if it
12956 is not necessary; currently that causes some problems. */
12959 redisplay_internal (void)
12961 struct window
*w
= XWINDOW (selected_window
);
12965 bool must_finish
= 0, match_p
;
12966 struct text_pos tlbufpos
, tlendpos
;
12967 int number_of_visible_frames
;
12970 int polling_stopped_here
= 0;
12971 Lisp_Object tail
, frame
;
12973 /* True means redisplay has to consider all windows on all
12974 frames. False, only selected_window is considered. */
12975 bool consider_all_windows_p
;
12977 /* True means redisplay has to redisplay the miniwindow. */
12978 bool update_miniwindow_p
= false;
12980 TRACE ((stderr
, "redisplay_internal %d\n", redisplaying_p
));
12982 /* No redisplay if running in batch mode or frame is not yet fully
12983 initialized, or redisplay is explicitly turned off by setting
12984 Vinhibit_redisplay. */
12985 if (FRAME_INITIAL_P (SELECTED_FRAME ())
12986 || !NILP (Vinhibit_redisplay
))
12989 /* Don't examine these until after testing Vinhibit_redisplay.
12990 When Emacs is shutting down, perhaps because its connection to
12991 X has dropped, we should not look at them at all. */
12992 fr
= XFRAME (w
->frame
);
12993 sf
= SELECTED_FRAME ();
12995 if (!fr
->glyphs_initialized_p
)
12998 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
12999 if (popup_activated ())
13003 /* I don't think this happens but let's be paranoid. */
13004 if (redisplaying_p
)
13007 /* Record a function that clears redisplaying_p
13008 when we leave this function. */
13009 count
= SPECPDL_INDEX ();
13010 record_unwind_protect_void (unwind_redisplay
);
13011 redisplaying_p
= 1;
13012 specbind (Qinhibit_free_realized_faces
, Qnil
);
13014 /* Record this function, so it appears on the profiler's backtraces. */
13015 record_in_backtrace (Qredisplay_internal
, &Qnil
, 0);
13017 FOR_EACH_FRAME (tail
, frame
)
13018 XFRAME (frame
)->already_hscrolled_p
= 0;
13021 /* Remember the currently selected window. */
13025 last_escape_glyph_frame
= NULL
;
13026 last_escape_glyph_face_id
= (1 << FACE_ID_BITS
);
13027 last_glyphless_glyph_frame
= NULL
;
13028 last_glyphless_glyph_face_id
= (1 << FACE_ID_BITS
);
13030 /* If face_change_count is non-zero, init_iterator will free all
13031 realized faces, which includes the faces referenced from current
13032 matrices. So, we can't reuse current matrices in this case. */
13033 if (face_change_count
)
13034 windows_or_buffers_changed
= 47;
13036 if ((FRAME_TERMCAP_P (sf
) || FRAME_MSDOS_P (sf
))
13037 && FRAME_TTY (sf
)->previous_frame
!= sf
)
13039 /* Since frames on a single ASCII terminal share the same
13040 display area, displaying a different frame means redisplay
13041 the whole thing. */
13042 SET_FRAME_GARBAGED (sf
);
13044 set_tty_color_mode (FRAME_TTY (sf
), sf
);
13046 FRAME_TTY (sf
)->previous_frame
= sf
;
13049 /* Set the visible flags for all frames. Do this before checking for
13050 resized or garbaged frames; they want to know if their frames are
13051 visible. See the comment in frame.h for FRAME_SAMPLE_VISIBILITY. */
13052 number_of_visible_frames
= 0;
13054 FOR_EACH_FRAME (tail
, frame
)
13056 struct frame
*f
= XFRAME (frame
);
13058 if (FRAME_VISIBLE_P (f
))
13060 ++number_of_visible_frames
;
13061 /* Adjust matrices for visible frames only. */
13062 if (f
->fonts_changed
)
13064 adjust_frame_glyphs (f
);
13065 f
->fonts_changed
= 0;
13067 /* If cursor type has been changed on the frame
13068 other than selected, consider all frames. */
13069 if (f
!= sf
&& f
->cursor_type_changed
)
13070 update_mode_lines
= 31;
13072 clear_desired_matrices (f
);
13075 /* Notice any pending interrupt request to change frame size. */
13076 do_pending_window_change (1);
13078 /* do_pending_window_change could change the selected_window due to
13079 frame resizing which makes the selected window too small. */
13080 if (WINDOWP (selected_window
) && (w
= XWINDOW (selected_window
)) != sw
)
13083 /* Clear frames marked as garbaged. */
13084 clear_garbaged_frames ();
13086 /* Build menubar and tool-bar items. */
13087 if (NILP (Vmemory_full
))
13088 prepare_menu_bars ();
13090 reconsider_clip_changes (w
);
13092 /* In most cases selected window displays current buffer. */
13093 match_p
= XBUFFER (w
->contents
) == current_buffer
;
13096 /* Detect case that we need to write or remove a star in the mode line. */
13097 if ((SAVE_MODIFF
< MODIFF
) != w
->last_had_star
)
13098 w
->update_mode_line
= 1;
13100 if (mode_line_update_needed (w
))
13101 w
->update_mode_line
= 1;
13104 /* Normally the message* functions will have already displayed and
13105 updated the echo area, but the frame may have been trashed, or
13106 the update may have been preempted, so display the echo area
13107 again here. Checking message_cleared_p captures the case that
13108 the echo area should be cleared. */
13109 if ((!NILP (echo_area_buffer
[0]) && !display_last_displayed_message_p
)
13110 || (!NILP (echo_area_buffer
[1]) && display_last_displayed_message_p
)
13111 || (message_cleared_p
13112 && minibuf_level
== 0
13113 /* If the mini-window is currently selected, this means the
13114 echo-area doesn't show through. */
13115 && !MINI_WINDOW_P (XWINDOW (selected_window
))))
13117 int window_height_changed_p
= echo_area_display (0);
13119 if (message_cleared_p
)
13120 update_miniwindow_p
= true;
13124 /* If we don't display the current message, don't clear the
13125 message_cleared_p flag, because, if we did, we wouldn't clear
13126 the echo area in the next redisplay which doesn't preserve
13128 if (!display_last_displayed_message_p
)
13129 message_cleared_p
= 0;
13131 if (window_height_changed_p
)
13133 windows_or_buffers_changed
= 50;
13135 /* If window configuration was changed, frames may have been
13136 marked garbaged. Clear them or we will experience
13137 surprises wrt scrolling. */
13138 clear_garbaged_frames ();
13141 else if (EQ (selected_window
, minibuf_window
)
13142 && (current_buffer
->clip_changed
|| window_outdated (w
))
13143 && resize_mini_window (w
, 0))
13145 /* Resized active mini-window to fit the size of what it is
13146 showing if its contents might have changed. */
13149 /* If window configuration was changed, frames may have been
13150 marked garbaged. Clear them or we will experience
13151 surprises wrt scrolling. */
13152 clear_garbaged_frames ();
13155 if (windows_or_buffers_changed
&& !update_mode_lines
)
13156 /* Code that sets windows_or_buffers_changed doesn't distinguish whether
13157 only the windows's contents needs to be refreshed, or whether the
13158 mode-lines also need a refresh. */
13159 update_mode_lines
= (windows_or_buffers_changed
== REDISPLAY_SOME
13160 ? REDISPLAY_SOME
: 32);
13162 /* If specs for an arrow have changed, do thorough redisplay
13163 to ensure we remove any arrow that should no longer exist. */
13164 if (overlay_arrows_changed_p ())
13165 /* Apparently, this is the only case where we update other windows,
13166 without updating other mode-lines. */
13167 windows_or_buffers_changed
= 49;
13169 consider_all_windows_p
= (update_mode_lines
13170 || windows_or_buffers_changed
);
13172 #define AINC(a,i) \
13173 if (VECTORP (a) && i >= 0 && i < ASIZE (a) && INTEGERP (AREF (a, i))) \
13174 ASET (a, i, make_number (1 + XINT (AREF (a, i))))
13176 AINC (Vredisplay__all_windows_cause
, windows_or_buffers_changed
);
13177 AINC (Vredisplay__mode_lines_cause
, update_mode_lines
);
13179 /* Optimize the case that only the line containing the cursor in the
13180 selected window has changed. Variables starting with this_ are
13181 set in display_line and record information about the line
13182 containing the cursor. */
13183 tlbufpos
= this_line_start_pos
;
13184 tlendpos
= this_line_end_pos
;
13185 if (!consider_all_windows_p
13186 && CHARPOS (tlbufpos
) > 0
13187 && !w
->update_mode_line
13188 && !current_buffer
->clip_changed
13189 && !current_buffer
->prevent_redisplay_optimizations_p
13190 && FRAME_VISIBLE_P (XFRAME (w
->frame
))
13191 && !FRAME_OBSCURED_P (XFRAME (w
->frame
))
13192 && !XFRAME (w
->frame
)->cursor_type_changed
13193 /* Make sure recorded data applies to current buffer, etc. */
13194 && this_line_buffer
== current_buffer
13197 && !w
->optional_new_start
13198 /* Point must be on the line that we have info recorded about. */
13199 && PT
>= CHARPOS (tlbufpos
)
13200 && PT
<= Z
- CHARPOS (tlendpos
)
13201 /* All text outside that line, including its final newline,
13202 must be unchanged. */
13203 && text_outside_line_unchanged_p (w
, CHARPOS (tlbufpos
),
13204 CHARPOS (tlendpos
)))
13206 if (CHARPOS (tlbufpos
) > BEGV
13207 && FETCH_BYTE (BYTEPOS (tlbufpos
) - 1) != '\n'
13208 && (CHARPOS (tlbufpos
) == ZV
13209 || FETCH_BYTE (BYTEPOS (tlbufpos
)) == '\n'))
13210 /* Former continuation line has disappeared by becoming empty. */
13212 else if (window_outdated (w
) || MINI_WINDOW_P (w
))
13214 /* We have to handle the case of continuation around a
13215 wide-column character (see the comment in indent.c around
13218 For instance, in the following case:
13220 -------- Insert --------
13221 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
13222 J_I_ ==> J_I_ `^^' are cursors.
13226 As we have to redraw the line above, we cannot use this
13230 int line_height_before
= this_line_pixel_height
;
13232 /* Note that start_display will handle the case that the
13233 line starting at tlbufpos is a continuation line. */
13234 start_display (&it
, w
, tlbufpos
);
13236 /* Implementation note: It this still necessary? */
13237 if (it
.current_x
!= this_line_start_x
)
13240 TRACE ((stderr
, "trying display optimization 1\n"));
13241 w
->cursor
.vpos
= -1;
13242 overlay_arrow_seen
= 0;
13243 it
.vpos
= this_line_vpos
;
13244 it
.current_y
= this_line_y
;
13245 it
.glyph_row
= MATRIX_ROW (w
->desired_matrix
, this_line_vpos
);
13246 display_line (&it
);
13248 /* If line contains point, is not continued,
13249 and ends at same distance from eob as before, we win. */
13250 if (w
->cursor
.vpos
>= 0
13251 /* Line is not continued, otherwise this_line_start_pos
13252 would have been set to 0 in display_line. */
13253 && CHARPOS (this_line_start_pos
)
13254 /* Line ends as before. */
13255 && CHARPOS (this_line_end_pos
) == CHARPOS (tlendpos
)
13256 /* Line has same height as before. Otherwise other lines
13257 would have to be shifted up or down. */
13258 && this_line_pixel_height
== line_height_before
)
13260 /* If this is not the window's last line, we must adjust
13261 the charstarts of the lines below. */
13262 if (it
.current_y
< it
.last_visible_y
)
13264 struct glyph_row
*row
13265 = MATRIX_ROW (w
->current_matrix
, this_line_vpos
+ 1);
13266 ptrdiff_t delta
, delta_bytes
;
13268 /* We used to distinguish between two cases here,
13269 conditioned by Z - CHARPOS (tlendpos) == ZV, for
13270 when the line ends in a newline or the end of the
13271 buffer's accessible portion. But both cases did
13272 the same, so they were collapsed. */
13274 - CHARPOS (tlendpos
)
13275 - MATRIX_ROW_START_CHARPOS (row
));
13276 delta_bytes
= (Z_BYTE
13277 - BYTEPOS (tlendpos
)
13278 - MATRIX_ROW_START_BYTEPOS (row
));
13280 increment_matrix_positions (w
->current_matrix
,
13281 this_line_vpos
+ 1,
13282 w
->current_matrix
->nrows
,
13283 delta
, delta_bytes
);
13286 /* If this row displays text now but previously didn't,
13287 or vice versa, w->window_end_vpos may have to be
13289 if (MATRIX_ROW_DISPLAYS_TEXT_P (it
.glyph_row
- 1))
13291 if (w
->window_end_vpos
< this_line_vpos
)
13292 w
->window_end_vpos
= this_line_vpos
;
13294 else if (w
->window_end_vpos
== this_line_vpos
13295 && this_line_vpos
> 0)
13296 w
->window_end_vpos
= this_line_vpos
- 1;
13297 w
->window_end_valid
= 0;
13299 /* Update hint: No need to try to scroll in update_window. */
13300 w
->desired_matrix
->no_scrolling_p
= 1;
13303 *w
->desired_matrix
->method
= 0;
13304 debug_method_add (w
, "optimization 1");
13306 #ifdef HAVE_WINDOW_SYSTEM
13307 update_window_fringes (w
, 0);
13314 else if (/* Cursor position hasn't changed. */
13315 PT
== w
->last_point
13316 /* Make sure the cursor was last displayed
13317 in this window. Otherwise we have to reposition it. */
13318 && 0 <= w
->cursor
.vpos
13319 && w
->cursor
.vpos
< WINDOW_TOTAL_LINES (w
))
13323 do_pending_window_change (1);
13324 /* If selected_window changed, redisplay again. */
13325 if (WINDOWP (selected_window
)
13326 && (w
= XWINDOW (selected_window
)) != sw
)
13329 /* We used to always goto end_of_redisplay here, but this
13330 isn't enough if we have a blinking cursor. */
13331 if (w
->cursor_off_p
== w
->last_cursor_off_p
)
13332 goto end_of_redisplay
;
13336 /* If highlighting the region, or if the cursor is in the echo area,
13337 then we can't just move the cursor. */
13338 else if (NILP (Vshow_trailing_whitespace
)
13339 && !cursor_in_echo_area
)
13342 struct glyph_row
*row
;
13344 /* Skip from tlbufpos to PT and see where it is. Note that
13345 PT may be in invisible text. If so, we will end at the
13346 next visible position. */
13347 init_iterator (&it
, w
, CHARPOS (tlbufpos
), BYTEPOS (tlbufpos
),
13348 NULL
, DEFAULT_FACE_ID
);
13349 it
.current_x
= this_line_start_x
;
13350 it
.current_y
= this_line_y
;
13351 it
.vpos
= this_line_vpos
;
13353 /* The call to move_it_to stops in front of PT, but
13354 moves over before-strings. */
13355 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
13357 if (it
.vpos
== this_line_vpos
13358 && (row
= MATRIX_ROW (w
->current_matrix
, this_line_vpos
),
13361 eassert (this_line_vpos
== it
.vpos
);
13362 eassert (this_line_y
== it
.current_y
);
13363 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
13365 *w
->desired_matrix
->method
= 0;
13366 debug_method_add (w
, "optimization 3");
13375 /* Text changed drastically or point moved off of line. */
13376 SET_MATRIX_ROW_ENABLED_P (w
->desired_matrix
, this_line_vpos
, 0);
13379 CHARPOS (this_line_start_pos
) = 0;
13380 ++clear_face_cache_count
;
13381 #ifdef HAVE_WINDOW_SYSTEM
13382 ++clear_image_cache_count
;
13385 /* Build desired matrices, and update the display. If
13386 consider_all_windows_p is non-zero, do it for all windows on all
13387 frames. Otherwise do it for selected_window, only. */
13389 if (consider_all_windows_p
)
13391 FOR_EACH_FRAME (tail
, frame
)
13392 XFRAME (frame
)->updated_p
= 0;
13394 propagate_buffer_redisplay ();
13396 FOR_EACH_FRAME (tail
, frame
)
13398 struct frame
*f
= XFRAME (frame
);
13400 /* We don't have to do anything for unselected terminal
13402 if ((FRAME_TERMCAP_P (f
) || FRAME_MSDOS_P (f
))
13403 && !EQ (FRAME_TTY (f
)->top_frame
, frame
))
13408 if (FRAME_WINDOW_P (f
) || FRAME_TERMCAP_P (f
) || f
== sf
)
13411 /* Only GC scollbars when we redisplay the whole frame. */
13412 = f
->redisplay
|| windows_or_buffers_changed
!= REDISPLAY_SOME
;
13413 /* Mark all the scroll bars to be removed; we'll redeem
13414 the ones we want when we redisplay their windows. */
13415 if (gcscrollbars
&& FRAME_TERMINAL (f
)->condemn_scroll_bars_hook
)
13416 FRAME_TERMINAL (f
)->condemn_scroll_bars_hook (f
);
13418 if (FRAME_VISIBLE_P (f
) && !FRAME_OBSCURED_P (f
))
13419 redisplay_windows (FRAME_ROOT_WINDOW (f
));
13421 /* The X error handler may have deleted that frame. */
13422 if (!FRAME_LIVE_P (f
))
13425 /* Any scroll bars which redisplay_windows should have
13426 nuked should now go away. */
13427 if (gcscrollbars
&& FRAME_TERMINAL (f
)->judge_scroll_bars_hook
)
13428 FRAME_TERMINAL (f
)->judge_scroll_bars_hook (f
);
13430 if (FRAME_VISIBLE_P (f
) && !FRAME_OBSCURED_P (f
))
13432 /* If fonts changed on visible frame, display again. */
13433 if (f
->fonts_changed
)
13435 adjust_frame_glyphs (f
);
13436 f
->fonts_changed
= 0;
13440 /* See if we have to hscroll. */
13441 if (!f
->already_hscrolled_p
)
13443 f
->already_hscrolled_p
= 1;
13444 if (hscroll_windows (f
->root_window
))
13448 /* Prevent various kinds of signals during display
13449 update. stdio is not robust about handling
13450 signals, which can cause an apparent I/O
13452 if (interrupt_input
)
13453 unrequest_sigio ();
13456 /* Mark windows on frame F to update. If we decide to
13457 update all frames but windows_or_buffers_changed is
13458 zero, we assume that only the windows that shows
13459 current buffer should be really updated. */
13460 set_window_update_flags
13461 (XWINDOW (f
->root_window
),
13462 (windows_or_buffers_changed
? NULL
: current_buffer
), 1);
13463 pending
|= update_frame (f
, 0, 0);
13464 f
->cursor_type_changed
= 0;
13470 eassert (EQ (XFRAME (selected_frame
)->selected_window
, selected_window
));
13474 /* Do the mark_window_display_accurate after all windows have
13475 been redisplayed because this call resets flags in buffers
13476 which are needed for proper redisplay. */
13477 FOR_EACH_FRAME (tail
, frame
)
13479 struct frame
*f
= XFRAME (frame
);
13482 f
->redisplay
= false;
13483 mark_window_display_accurate (f
->root_window
, 1);
13484 if (FRAME_TERMINAL (f
)->frame_up_to_date_hook
)
13485 FRAME_TERMINAL (f
)->frame_up_to_date_hook (f
);
13490 else if (FRAME_VISIBLE_P (sf
) && !FRAME_OBSCURED_P (sf
))
13492 Lisp_Object mini_window
= FRAME_MINIBUF_WINDOW (sf
);
13493 struct frame
*mini_frame
;
13495 displayed_buffer
= XBUFFER (XWINDOW (selected_window
)->contents
);
13496 /* Use list_of_error, not Qerror, so that
13497 we catch only errors and don't run the debugger. */
13498 internal_condition_case_1 (redisplay_window_1
, selected_window
,
13500 redisplay_window_error
);
13501 if (update_miniwindow_p
)
13502 internal_condition_case_1 (redisplay_window_1
, mini_window
,
13504 redisplay_window_error
);
13506 /* Compare desired and current matrices, perform output. */
13509 /* If fonts changed, display again. */
13510 if (sf
->fonts_changed
)
13513 /* Prevent various kinds of signals during display update.
13514 stdio is not robust about handling signals,
13515 which can cause an apparent I/O error. */
13516 if (interrupt_input
)
13517 unrequest_sigio ();
13520 if (FRAME_VISIBLE_P (sf
) && !FRAME_OBSCURED_P (sf
))
13522 if (hscroll_windows (selected_window
))
13525 XWINDOW (selected_window
)->must_be_updated_p
= 1;
13526 pending
= update_frame (sf
, 0, 0);
13527 sf
->cursor_type_changed
= 0;
13530 /* We may have called echo_area_display at the top of this
13531 function. If the echo area is on another frame, that may
13532 have put text on a frame other than the selected one, so the
13533 above call to update_frame would not have caught it. Catch
13535 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
13536 mini_frame
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
13538 if (mini_frame
!= sf
&& FRAME_WINDOW_P (mini_frame
))
13540 XWINDOW (mini_window
)->must_be_updated_p
= 1;
13541 pending
|= update_frame (mini_frame
, 0, 0);
13542 mini_frame
->cursor_type_changed
= 0;
13543 if (!pending
&& hscroll_windows (mini_window
))
13548 /* If display was paused because of pending input, make sure we do a
13549 thorough update the next time. */
13552 /* Prevent the optimization at the beginning of
13553 redisplay_internal that tries a single-line update of the
13554 line containing the cursor in the selected window. */
13555 CHARPOS (this_line_start_pos
) = 0;
13557 /* Let the overlay arrow be updated the next time. */
13558 update_overlay_arrows (0);
13560 /* If we pause after scrolling, some rows in the current
13561 matrices of some windows are not valid. */
13562 if (!WINDOW_FULL_WIDTH_P (w
)
13563 && !FRAME_WINDOW_P (XFRAME (w
->frame
)))
13564 update_mode_lines
= 36;
13568 if (!consider_all_windows_p
)
13570 /* This has already been done above if
13571 consider_all_windows_p is set. */
13572 if (XBUFFER (w
->contents
)->text
->redisplay
13573 && buffer_window_count (XBUFFER (w
->contents
)) > 1)
13574 /* This can happen if b->text->redisplay was set during
13576 propagate_buffer_redisplay ();
13577 mark_window_display_accurate_1 (w
, 1);
13579 /* Say overlay arrows are up to date. */
13580 update_overlay_arrows (1);
13582 if (FRAME_TERMINAL (sf
)->frame_up_to_date_hook
!= 0)
13583 FRAME_TERMINAL (sf
)->frame_up_to_date_hook (sf
);
13586 update_mode_lines
= 0;
13587 windows_or_buffers_changed
= 0;
13590 /* Start SIGIO interrupts coming again. Having them off during the
13591 code above makes it less likely one will discard output, but not
13592 impossible, since there might be stuff in the system buffer here.
13593 But it is much hairier to try to do anything about that. */
13594 if (interrupt_input
)
13598 /* If a frame has become visible which was not before, redisplay
13599 again, so that we display it. Expose events for such a frame
13600 (which it gets when becoming visible) don't call the parts of
13601 redisplay constructing glyphs, so simply exposing a frame won't
13602 display anything in this case. So, we have to display these
13603 frames here explicitly. */
13608 FOR_EACH_FRAME (tail
, frame
)
13610 if (XFRAME (frame
)->visible
)
13614 if (new_count
!= number_of_visible_frames
)
13615 windows_or_buffers_changed
= 52;
13618 /* Change frame size now if a change is pending. */
13619 do_pending_window_change (1);
13621 /* If we just did a pending size change, or have additional
13622 visible frames, or selected_window changed, redisplay again. */
13623 if ((windows_or_buffers_changed
&& !pending
)
13624 || (WINDOWP (selected_window
) && (w
= XWINDOW (selected_window
)) != sw
))
13627 /* Clear the face and image caches.
13629 We used to do this only if consider_all_windows_p. But the cache
13630 needs to be cleared if a timer creates images in the current
13631 buffer (e.g. the test case in Bug#6230). */
13633 if (clear_face_cache_count
> CLEAR_FACE_CACHE_COUNT
)
13635 clear_face_cache (0);
13636 clear_face_cache_count
= 0;
13639 #ifdef HAVE_WINDOW_SYSTEM
13640 if (clear_image_cache_count
> CLEAR_IMAGE_CACHE_COUNT
)
13642 clear_image_caches (Qnil
);
13643 clear_image_cache_count
= 0;
13645 #endif /* HAVE_WINDOW_SYSTEM */
13648 unbind_to (count
, Qnil
);
13653 /* Redisplay, but leave alone any recent echo area message unless
13654 another message has been requested in its place.
13656 This is useful in situations where you need to redisplay but no
13657 user action has occurred, making it inappropriate for the message
13658 area to be cleared. See tracking_off and
13659 wait_reading_process_output for examples of these situations.
13661 FROM_WHERE is an integer saying from where this function was
13662 called. This is useful for debugging. */
13665 redisplay_preserve_echo_area (int from_where
)
13667 TRACE ((stderr
, "redisplay_preserve_echo_area (%d)\n", from_where
));
13669 if (!NILP (echo_area_buffer
[1]))
13671 /* We have a previously displayed message, but no current
13672 message. Redisplay the previous message. */
13673 display_last_displayed_message_p
= 1;
13674 redisplay_internal ();
13675 display_last_displayed_message_p
= 0;
13678 redisplay_internal ();
13680 flush_frame (SELECTED_FRAME ());
13684 /* Function registered with record_unwind_protect in redisplay_internal. */
13687 unwind_redisplay (void)
13689 redisplaying_p
= 0;
13693 /* Mark the display of leaf window W as accurate or inaccurate.
13694 If ACCURATE_P is non-zero mark display of W as accurate. If
13695 ACCURATE_P is zero, arrange for W to be redisplayed the next
13696 time redisplay_internal is called. */
13699 mark_window_display_accurate_1 (struct window
*w
, int accurate_p
)
13701 struct buffer
*b
= XBUFFER (w
->contents
);
13703 w
->last_modified
= accurate_p
? BUF_MODIFF (b
) : 0;
13704 w
->last_overlay_modified
= accurate_p
? BUF_OVERLAY_MODIFF (b
) : 0;
13705 w
->last_had_star
= BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
);
13709 b
->clip_changed
= false;
13710 b
->prevent_redisplay_optimizations_p
= false;
13711 eassert (buffer_window_count (b
) > 0);
13712 /* Resetting b->text->redisplay is problematic!
13713 In order to make it safer to do it here, redisplay_internal must
13714 have copied all b->text->redisplay to their respective windows. */
13715 b
->text
->redisplay
= false;
13717 BUF_UNCHANGED_MODIFIED (b
) = BUF_MODIFF (b
);
13718 BUF_OVERLAY_UNCHANGED_MODIFIED (b
) = BUF_OVERLAY_MODIFF (b
);
13719 BUF_BEG_UNCHANGED (b
) = BUF_GPT (b
) - BUF_BEG (b
);
13720 BUF_END_UNCHANGED (b
) = BUF_Z (b
) - BUF_GPT (b
);
13722 w
->current_matrix
->buffer
= b
;
13723 w
->current_matrix
->begv
= BUF_BEGV (b
);
13724 w
->current_matrix
->zv
= BUF_ZV (b
);
13726 w
->last_cursor_vpos
= w
->cursor
.vpos
;
13727 w
->last_cursor_off_p
= w
->cursor_off_p
;
13729 if (w
== XWINDOW (selected_window
))
13730 w
->last_point
= BUF_PT (b
);
13732 w
->last_point
= marker_position (w
->pointm
);
13734 w
->window_end_valid
= true;
13735 w
->update_mode_line
= false;
13738 w
->redisplay
= !accurate_p
;
13742 /* Mark the display of windows in the window tree rooted at WINDOW as
13743 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
13744 windows as accurate. If ACCURATE_P is zero, arrange for windows to
13745 be redisplayed the next time redisplay_internal is called. */
13748 mark_window_display_accurate (Lisp_Object window
, int accurate_p
)
13752 for (; !NILP (window
); window
= w
->next
)
13754 w
= XWINDOW (window
);
13755 if (WINDOWP (w
->contents
))
13756 mark_window_display_accurate (w
->contents
, accurate_p
);
13758 mark_window_display_accurate_1 (w
, accurate_p
);
13762 update_overlay_arrows (1);
13764 /* Force a thorough redisplay the next time by setting
13765 last_arrow_position and last_arrow_string to t, which is
13766 unequal to any useful value of Voverlay_arrow_... */
13767 update_overlay_arrows (-1);
13771 /* Return value in display table DP (Lisp_Char_Table *) for character
13772 C. Since a display table doesn't have any parent, we don't have to
13773 follow parent. Do not call this function directly but use the
13774 macro DISP_CHAR_VECTOR. */
13777 disp_char_vector (struct Lisp_Char_Table
*dp
, int c
)
13781 if (ASCII_CHAR_P (c
))
13784 if (SUB_CHAR_TABLE_P (val
))
13785 val
= XSUB_CHAR_TABLE (val
)->contents
[c
];
13791 XSETCHAR_TABLE (table
, dp
);
13792 val
= char_table_ref (table
, c
);
13801 /***********************************************************************
13803 ***********************************************************************/
13805 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
13808 redisplay_windows (Lisp_Object window
)
13810 while (!NILP (window
))
13812 struct window
*w
= XWINDOW (window
);
13814 if (WINDOWP (w
->contents
))
13815 redisplay_windows (w
->contents
);
13816 else if (BUFFERP (w
->contents
))
13818 displayed_buffer
= XBUFFER (w
->contents
);
13819 /* Use list_of_error, not Qerror, so that
13820 we catch only errors and don't run the debugger. */
13821 internal_condition_case_1 (redisplay_window_0
, window
,
13823 redisplay_window_error
);
13831 redisplay_window_error (Lisp_Object ignore
)
13833 displayed_buffer
->display_error_modiff
= BUF_MODIFF (displayed_buffer
);
13838 redisplay_window_0 (Lisp_Object window
)
13840 if (displayed_buffer
->display_error_modiff
< BUF_MODIFF (displayed_buffer
))
13841 redisplay_window (window
, 0);
13846 redisplay_window_1 (Lisp_Object window
)
13848 if (displayed_buffer
->display_error_modiff
< BUF_MODIFF (displayed_buffer
))
13849 redisplay_window (window
, 1);
13854 /* Set cursor position of W. PT is assumed to be displayed in ROW.
13855 DELTA and DELTA_BYTES are the numbers of characters and bytes by
13856 which positions recorded in ROW differ from current buffer
13859 Return 0 if cursor is not on this row, 1 otherwise. */
13862 set_cursor_from_row (struct window
*w
, struct glyph_row
*row
,
13863 struct glyph_matrix
*matrix
,
13864 ptrdiff_t delta
, ptrdiff_t delta_bytes
,
13867 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
13868 struct glyph
*end
= glyph
+ row
->used
[TEXT_AREA
];
13869 struct glyph
*cursor
= NULL
;
13870 /* The last known character position in row. */
13871 ptrdiff_t last_pos
= MATRIX_ROW_START_CHARPOS (row
) + delta
;
13873 ptrdiff_t pt_old
= PT
- delta
;
13874 ptrdiff_t pos_before
= MATRIX_ROW_START_CHARPOS (row
) + delta
;
13875 ptrdiff_t pos_after
= MATRIX_ROW_END_CHARPOS (row
) + delta
;
13876 struct glyph
*glyph_before
= glyph
- 1, *glyph_after
= end
;
13877 /* A glyph beyond the edge of TEXT_AREA which we should never
13879 struct glyph
*glyphs_end
= end
;
13880 /* Non-zero means we've found a match for cursor position, but that
13881 glyph has the avoid_cursor_p flag set. */
13882 int match_with_avoid_cursor
= 0;
13883 /* Non-zero means we've seen at least one glyph that came from a
13885 int string_seen
= 0;
13886 /* Largest and smallest buffer positions seen so far during scan of
13888 ptrdiff_t bpos_max
= pos_before
;
13889 ptrdiff_t bpos_min
= pos_after
;
13890 /* Last buffer position covered by an overlay string with an integer
13891 `cursor' property. */
13892 ptrdiff_t bpos_covered
= 0;
13893 /* Non-zero means the display string on which to display the cursor
13894 comes from a text property, not from an overlay. */
13895 int string_from_text_prop
= 0;
13897 /* Don't even try doing anything if called for a mode-line or
13898 header-line row, since the rest of the code isn't prepared to
13899 deal with such calamities. */
13900 eassert (!row
->mode_line_p
);
13901 if (row
->mode_line_p
)
13904 /* Skip over glyphs not having an object at the start and the end of
13905 the row. These are special glyphs like truncation marks on
13906 terminal frames. */
13907 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
13909 if (!row
->reversed_p
)
13912 && INTEGERP (glyph
->object
)
13913 && glyph
->charpos
< 0)
13915 x
+= glyph
->pixel_width
;
13919 && INTEGERP ((end
- 1)->object
)
13920 /* CHARPOS is zero for blanks and stretch glyphs
13921 inserted by extend_face_to_end_of_line. */
13922 && (end
- 1)->charpos
<= 0)
13924 glyph_before
= glyph
- 1;
13931 /* If the glyph row is reversed, we need to process it from back
13932 to front, so swap the edge pointers. */
13933 glyphs_end
= end
= glyph
- 1;
13934 glyph
+= row
->used
[TEXT_AREA
] - 1;
13936 while (glyph
> end
+ 1
13937 && INTEGERP (glyph
->object
)
13938 && glyph
->charpos
< 0)
13941 x
-= glyph
->pixel_width
;
13943 if (INTEGERP (glyph
->object
) && glyph
->charpos
< 0)
13945 /* By default, in reversed rows we put the cursor on the
13946 rightmost (first in the reading order) glyph. */
13947 for (g
= end
+ 1; g
< glyph
; g
++)
13948 x
+= g
->pixel_width
;
13950 && INTEGERP ((end
+ 1)->object
)
13951 && (end
+ 1)->charpos
<= 0)
13953 glyph_before
= glyph
+ 1;
13957 else if (row
->reversed_p
)
13959 /* In R2L rows that don't display text, put the cursor on the
13960 rightmost glyph. Case in point: an empty last line that is
13961 part of an R2L paragraph. */
13963 /* Avoid placing the cursor on the last glyph of the row, where
13964 on terminal frames we hold the vertical border between
13965 adjacent windows. */
13966 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w
))
13967 && !WINDOW_RIGHTMOST_P (w
)
13968 && cursor
== row
->glyphs
[LAST_AREA
] - 1)
13970 x
= -1; /* will be computed below, at label compute_x */
13973 /* Step 1: Try to find the glyph whose character position
13974 corresponds to point. If that's not possible, find 2 glyphs
13975 whose character positions are the closest to point, one before
13976 point, the other after it. */
13977 if (!row
->reversed_p
)
13978 while (/* not marched to end of glyph row */
13980 /* glyph was not inserted by redisplay for internal purposes */
13981 && !INTEGERP (glyph
->object
))
13983 if (BUFFERP (glyph
->object
))
13985 ptrdiff_t dpos
= glyph
->charpos
- pt_old
;
13987 if (glyph
->charpos
> bpos_max
)
13988 bpos_max
= glyph
->charpos
;
13989 if (glyph
->charpos
< bpos_min
)
13990 bpos_min
= glyph
->charpos
;
13991 if (!glyph
->avoid_cursor_p
)
13993 /* If we hit point, we've found the glyph on which to
13994 display the cursor. */
13997 match_with_avoid_cursor
= 0;
14000 /* See if we've found a better approximation to
14001 POS_BEFORE or to POS_AFTER. */
14002 if (0 > dpos
&& dpos
> pos_before
- pt_old
)
14004 pos_before
= glyph
->charpos
;
14005 glyph_before
= glyph
;
14007 else if (0 < dpos
&& dpos
< pos_after
- pt_old
)
14009 pos_after
= glyph
->charpos
;
14010 glyph_after
= glyph
;
14013 else if (dpos
== 0)
14014 match_with_avoid_cursor
= 1;
14016 else if (STRINGP (glyph
->object
))
14018 Lisp_Object chprop
;
14019 ptrdiff_t glyph_pos
= glyph
->charpos
;
14021 chprop
= Fget_char_property (make_number (glyph_pos
), Qcursor
,
14023 if (!NILP (chprop
))
14025 /* If the string came from a `display' text property,
14026 look up the buffer position of that property and
14027 use that position to update bpos_max, as if we
14028 actually saw such a position in one of the row's
14029 glyphs. This helps with supporting integer values
14030 of `cursor' property on the display string in
14031 situations where most or all of the row's buffer
14032 text is completely covered by display properties,
14033 so that no glyph with valid buffer positions is
14034 ever seen in the row. */
14035 ptrdiff_t prop_pos
=
14036 string_buffer_position_lim (glyph
->object
, pos_before
,
14039 if (prop_pos
>= pos_before
)
14040 bpos_max
= prop_pos
- 1;
14042 if (INTEGERP (chprop
))
14044 bpos_covered
= bpos_max
+ XINT (chprop
);
14045 /* If the `cursor' property covers buffer positions up
14046 to and including point, we should display cursor on
14047 this glyph. Note that, if a `cursor' property on one
14048 of the string's characters has an integer value, we
14049 will break out of the loop below _before_ we get to
14050 the position match above. IOW, integer values of
14051 the `cursor' property override the "exact match for
14052 point" strategy of positioning the cursor. */
14053 /* Implementation note: bpos_max == pt_old when, e.g.,
14054 we are in an empty line, where bpos_max is set to
14055 MATRIX_ROW_START_CHARPOS, see above. */
14056 if (bpos_max
<= pt_old
&& bpos_covered
>= pt_old
)
14065 x
+= glyph
->pixel_width
;
14068 else if (glyph
> end
) /* row is reversed */
14069 while (!INTEGERP (glyph
->object
))
14071 if (BUFFERP (glyph
->object
))
14073 ptrdiff_t dpos
= glyph
->charpos
- pt_old
;
14075 if (glyph
->charpos
> bpos_max
)
14076 bpos_max
= glyph
->charpos
;
14077 if (glyph
->charpos
< bpos_min
)
14078 bpos_min
= glyph
->charpos
;
14079 if (!glyph
->avoid_cursor_p
)
14083 match_with_avoid_cursor
= 0;
14086 if (0 > dpos
&& dpos
> pos_before
- pt_old
)
14088 pos_before
= glyph
->charpos
;
14089 glyph_before
= glyph
;
14091 else if (0 < dpos
&& dpos
< pos_after
- pt_old
)
14093 pos_after
= glyph
->charpos
;
14094 glyph_after
= glyph
;
14097 else if (dpos
== 0)
14098 match_with_avoid_cursor
= 1;
14100 else if (STRINGP (glyph
->object
))
14102 Lisp_Object chprop
;
14103 ptrdiff_t glyph_pos
= glyph
->charpos
;
14105 chprop
= Fget_char_property (make_number (glyph_pos
), Qcursor
,
14107 if (!NILP (chprop
))
14109 ptrdiff_t prop_pos
=
14110 string_buffer_position_lim (glyph
->object
, pos_before
,
14113 if (prop_pos
>= pos_before
)
14114 bpos_max
= prop_pos
- 1;
14116 if (INTEGERP (chprop
))
14118 bpos_covered
= bpos_max
+ XINT (chprop
);
14119 /* If the `cursor' property covers buffer positions up
14120 to and including point, we should display cursor on
14122 if (bpos_max
<= pt_old
&& bpos_covered
>= pt_old
)
14131 if (glyph
== glyphs_end
) /* don't dereference outside TEXT_AREA */
14133 x
--; /* can't use any pixel_width */
14136 x
-= glyph
->pixel_width
;
14139 /* Step 2: If we didn't find an exact match for point, we need to
14140 look for a proper place to put the cursor among glyphs between
14141 GLYPH_BEFORE and GLYPH_AFTER. */
14142 if (!((row
->reversed_p
? glyph
> glyphs_end
: glyph
< glyphs_end
)
14143 && BUFFERP (glyph
->object
) && glyph
->charpos
== pt_old
)
14144 && !(bpos_max
< pt_old
&& pt_old
<= bpos_covered
))
14146 /* An empty line has a single glyph whose OBJECT is zero and
14147 whose CHARPOS is the position of a newline on that line.
14148 Note that on a TTY, there are more glyphs after that, which
14149 were produced by extend_face_to_end_of_line, but their
14150 CHARPOS is zero or negative. */
14152 (row
->reversed_p
? glyph
> glyphs_end
: glyph
< glyphs_end
)
14153 && INTEGERP (glyph
->object
) && glyph
->charpos
> 0
14154 /* On a TTY, continued and truncated rows also have a glyph at
14155 their end whose OBJECT is zero and whose CHARPOS is
14156 positive (the continuation and truncation glyphs), but such
14157 rows are obviously not "empty". */
14158 && !(row
->continued_p
|| row
->truncated_on_right_p
);
14160 if (row
->ends_in_ellipsis_p
&& pos_after
== last_pos
)
14162 ptrdiff_t ellipsis_pos
;
14164 /* Scan back over the ellipsis glyphs. */
14165 if (!row
->reversed_p
)
14167 ellipsis_pos
= (glyph
- 1)->charpos
;
14168 while (glyph
> row
->glyphs
[TEXT_AREA
]
14169 && (glyph
- 1)->charpos
== ellipsis_pos
)
14170 glyph
--, x
-= glyph
->pixel_width
;
14171 /* That loop always goes one position too far, including
14172 the glyph before the ellipsis. So scan forward over
14174 x
+= glyph
->pixel_width
;
14177 else /* row is reversed */
14179 ellipsis_pos
= (glyph
+ 1)->charpos
;
14180 while (glyph
< row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
] - 1
14181 && (glyph
+ 1)->charpos
== ellipsis_pos
)
14182 glyph
++, x
+= glyph
->pixel_width
;
14183 x
-= glyph
->pixel_width
;
14187 else if (match_with_avoid_cursor
)
14189 cursor
= glyph_after
;
14192 else if (string_seen
)
14194 int incr
= row
->reversed_p
? -1 : +1;
14196 /* Need to find the glyph that came out of a string which is
14197 present at point. That glyph is somewhere between
14198 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
14199 positioned between POS_BEFORE and POS_AFTER in the
14201 struct glyph
*start
, *stop
;
14202 ptrdiff_t pos
= pos_before
;
14206 /* If the row ends in a newline from a display string,
14207 reordering could have moved the glyphs belonging to the
14208 string out of the [GLYPH_BEFORE..GLYPH_AFTER] range. So
14209 in this case we extend the search to the last glyph in
14210 the row that was not inserted by redisplay. */
14211 if (row
->ends_in_newline_from_string_p
)
14214 pos_after
= MATRIX_ROW_END_CHARPOS (row
) + delta
;
14217 /* GLYPH_BEFORE and GLYPH_AFTER are the glyphs that
14218 correspond to POS_BEFORE and POS_AFTER, respectively. We
14219 need START and STOP in the order that corresponds to the
14220 row's direction as given by its reversed_p flag. If the
14221 directionality of characters between POS_BEFORE and
14222 POS_AFTER is the opposite of the row's base direction,
14223 these characters will have been reordered for display,
14224 and we need to reverse START and STOP. */
14225 if (!row
->reversed_p
)
14227 start
= min (glyph_before
, glyph_after
);
14228 stop
= max (glyph_before
, glyph_after
);
14232 start
= max (glyph_before
, glyph_after
);
14233 stop
= min (glyph_before
, glyph_after
);
14235 for (glyph
= start
+ incr
;
14236 row
->reversed_p
? glyph
> stop
: glyph
< stop
; )
14239 /* Any glyphs that come from the buffer are here because
14240 of bidi reordering. Skip them, and only pay
14241 attention to glyphs that came from some string. */
14242 if (STRINGP (glyph
->object
))
14246 /* If the display property covers the newline, we
14247 need to search for it one position farther. */
14248 ptrdiff_t lim
= pos_after
14249 + (pos_after
== MATRIX_ROW_END_CHARPOS (row
) + delta
);
14251 string_from_text_prop
= 0;
14252 str
= glyph
->object
;
14253 tem
= string_buffer_position_lim (str
, pos
, lim
, 0);
14254 if (tem
== 0 /* from overlay */
14257 /* If the string from which this glyph came is
14258 found in the buffer at point, or at position
14259 that is closer to point than pos_after, then
14260 we've found the glyph we've been looking for.
14261 If it comes from an overlay (tem == 0), and
14262 it has the `cursor' property on one of its
14263 glyphs, record that glyph as a candidate for
14264 displaying the cursor. (As in the
14265 unidirectional version, we will display the
14266 cursor on the last candidate we find.) */
14269 || (tem
- pt_old
> 0 && tem
< pos_after
))
14271 /* The glyphs from this string could have
14272 been reordered. Find the one with the
14273 smallest string position. Or there could
14274 be a character in the string with the
14275 `cursor' property, which means display
14276 cursor on that character's glyph. */
14277 ptrdiff_t strpos
= glyph
->charpos
;
14282 string_from_text_prop
= 1;
14285 (row
->reversed_p
? glyph
> stop
: glyph
< stop
)
14286 && EQ (glyph
->object
, str
);
14290 ptrdiff_t gpos
= glyph
->charpos
;
14292 cprop
= Fget_char_property (make_number (gpos
),
14300 if (tem
&& glyph
->charpos
< strpos
)
14302 strpos
= glyph
->charpos
;
14308 || (tem
- pt_old
> 0 && tem
< pos_after
))
14312 pos
= tem
+ 1; /* don't find previous instances */
14314 /* This string is not what we want; skip all of the
14315 glyphs that came from it. */
14316 while ((row
->reversed_p
? glyph
> stop
: glyph
< stop
)
14317 && EQ (glyph
->object
, str
))
14324 /* If we reached the end of the line, and END was from a string,
14325 the cursor is not on this line. */
14327 && (row
->reversed_p
? glyph
<= end
: glyph
>= end
)
14328 && (row
->reversed_p
? end
> glyphs_end
: end
< glyphs_end
)
14329 && STRINGP (end
->object
)
14330 && row
->continued_p
)
14333 /* A truncated row may not include PT among its character positions.
14334 Setting the cursor inside the scroll margin will trigger
14335 recalculation of hscroll in hscroll_window_tree. But if a
14336 display string covers point, defer to the string-handling
14337 code below to figure this out. */
14338 else if (row
->truncated_on_left_p
&& pt_old
< bpos_min
)
14340 cursor
= glyph_before
;
14343 else if ((row
->truncated_on_right_p
&& pt_old
> bpos_max
)
14344 /* Zero-width characters produce no glyphs. */
14346 && (row
->reversed_p
14347 ? glyph_after
> glyphs_end
14348 : glyph_after
< glyphs_end
)))
14350 cursor
= glyph_after
;
14356 if (cursor
!= NULL
)
14358 else if (glyph
== glyphs_end
14359 && pos_before
== pos_after
14360 && STRINGP ((row
->reversed_p
14361 ? row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
] - 1
14362 : row
->glyphs
[TEXT_AREA
])->object
))
14364 /* If all the glyphs of this row came from strings, put the
14365 cursor on the first glyph of the row. This avoids having the
14366 cursor outside of the text area in this very rare and hard
14370 ? row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
] - 1
14371 : row
->glyphs
[TEXT_AREA
];
14377 /* Need to compute x that corresponds to GLYPH. */
14378 for (g
= row
->glyphs
[TEXT_AREA
], x
= row
->x
; g
< glyph
; g
++)
14380 if (g
>= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
])
14382 x
+= g
->pixel_width
;
14386 /* ROW could be part of a continued line, which, under bidi
14387 reordering, might have other rows whose start and end charpos
14388 occlude point. Only set w->cursor if we found a better
14389 approximation to the cursor position than we have from previously
14390 examined candidate rows belonging to the same continued line. */
14391 if (/* We already have a candidate row. */
14392 w
->cursor
.vpos
>= 0
14393 /* That candidate is not the row we are processing. */
14394 && MATRIX_ROW (matrix
, w
->cursor
.vpos
) != row
14395 /* Make sure cursor.vpos specifies a row whose start and end
14396 charpos occlude point, and it is valid candidate for being a
14397 cursor-row. This is because some callers of this function
14398 leave cursor.vpos at the row where the cursor was displayed
14399 during the last redisplay cycle. */
14400 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix
, w
->cursor
.vpos
)) <= pt_old
14401 && pt_old
<= MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix
, w
->cursor
.vpos
))
14402 && cursor_row_p (MATRIX_ROW (matrix
, w
->cursor
.vpos
)))
14405 = MATRIX_ROW_GLYPH_START (matrix
, w
->cursor
.vpos
) + w
->cursor
.hpos
;
14407 /* Don't consider glyphs that are outside TEXT_AREA. */
14408 if (!(row
->reversed_p
? glyph
> glyphs_end
: glyph
< glyphs_end
))
14410 /* Keep the candidate whose buffer position is the closest to
14411 point or has the `cursor' property. */
14412 if (/* Previous candidate is a glyph in TEXT_AREA of that row. */
14413 w
->cursor
.hpos
>= 0
14414 && w
->cursor
.hpos
< MATRIX_ROW_USED (matrix
, w
->cursor
.vpos
)
14415 && ((BUFFERP (g1
->object
)
14416 && (g1
->charpos
== pt_old
/* An exact match always wins. */
14417 || (BUFFERP (glyph
->object
)
14418 && eabs (g1
->charpos
- pt_old
)
14419 < eabs (glyph
->charpos
- pt_old
))))
14420 /* Previous candidate is a glyph from a string that has
14421 a non-nil `cursor' property. */
14422 || (STRINGP (g1
->object
)
14423 && (!NILP (Fget_char_property (make_number (g1
->charpos
),
14424 Qcursor
, g1
->object
))
14425 /* Previous candidate is from the same display
14426 string as this one, and the display string
14427 came from a text property. */
14428 || (EQ (g1
->object
, glyph
->object
)
14429 && string_from_text_prop
)
14430 /* this candidate is from newline and its
14431 position is not an exact match */
14432 || (INTEGERP (glyph
->object
)
14433 && glyph
->charpos
!= pt_old
)))))
14435 /* If this candidate gives an exact match, use that. */
14436 if (!((BUFFERP (glyph
->object
) && glyph
->charpos
== pt_old
)
14437 /* If this candidate is a glyph created for the
14438 terminating newline of a line, and point is on that
14439 newline, it wins because it's an exact match. */
14440 || (!row
->continued_p
14441 && INTEGERP (glyph
->object
)
14442 && glyph
->charpos
== 0
14443 && pt_old
== MATRIX_ROW_END_CHARPOS (row
) - 1))
14444 /* Otherwise, keep the candidate that comes from a row
14445 spanning less buffer positions. This may win when one or
14446 both candidate positions are on glyphs that came from
14447 display strings, for which we cannot compare buffer
14449 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix
, w
->cursor
.vpos
))
14450 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix
, w
->cursor
.vpos
))
14451 < MATRIX_ROW_END_CHARPOS (row
) - MATRIX_ROW_START_CHARPOS (row
))
14454 w
->cursor
.hpos
= glyph
- row
->glyphs
[TEXT_AREA
];
14456 w
->cursor
.vpos
= MATRIX_ROW_VPOS (row
, matrix
) + dvpos
;
14457 w
->cursor
.y
= row
->y
+ dy
;
14459 if (w
== XWINDOW (selected_window
))
14461 if (!row
->continued_p
14462 && !MATRIX_ROW_CONTINUATION_LINE_P (row
)
14465 this_line_buffer
= XBUFFER (w
->contents
);
14467 CHARPOS (this_line_start_pos
)
14468 = MATRIX_ROW_START_CHARPOS (row
) + delta
;
14469 BYTEPOS (this_line_start_pos
)
14470 = MATRIX_ROW_START_BYTEPOS (row
) + delta_bytes
;
14472 CHARPOS (this_line_end_pos
)
14473 = Z
- (MATRIX_ROW_END_CHARPOS (row
) + delta
);
14474 BYTEPOS (this_line_end_pos
)
14475 = Z_BYTE
- (MATRIX_ROW_END_BYTEPOS (row
) + delta_bytes
);
14477 this_line_y
= w
->cursor
.y
;
14478 this_line_pixel_height
= row
->height
;
14479 this_line_vpos
= w
->cursor
.vpos
;
14480 this_line_start_x
= row
->x
;
14483 CHARPOS (this_line_start_pos
) = 0;
14490 /* Run window scroll functions, if any, for WINDOW with new window
14491 start STARTP. Sets the window start of WINDOW to that position.
14493 We assume that the window's buffer is really current. */
14495 static struct text_pos
14496 run_window_scroll_functions (Lisp_Object window
, struct text_pos startp
)
14498 struct window
*w
= XWINDOW (window
);
14499 SET_MARKER_FROM_TEXT_POS (w
->start
, startp
);
14501 eassert (current_buffer
== XBUFFER (w
->contents
));
14503 if (!NILP (Vwindow_scroll_functions
))
14505 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
14506 make_number (CHARPOS (startp
)));
14507 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
14508 /* In case the hook functions switch buffers. */
14509 set_buffer_internal (XBUFFER (w
->contents
));
14516 /* Make sure the line containing the cursor is fully visible.
14517 A value of 1 means there is nothing to be done.
14518 (Either the line is fully visible, or it cannot be made so,
14519 or we cannot tell.)
14521 If FORCE_P is non-zero, return 0 even if partial visible cursor row
14522 is higher than window.
14524 A value of 0 means the caller should do scrolling
14525 as if point had gone off the screen. */
14528 cursor_row_fully_visible_p (struct window
*w
, int force_p
, int current_matrix_p
)
14530 struct glyph_matrix
*matrix
;
14531 struct glyph_row
*row
;
14534 if (!make_cursor_line_fully_visible_p
)
14537 /* It's not always possible to find the cursor, e.g, when a window
14538 is full of overlay strings. Don't do anything in that case. */
14539 if (w
->cursor
.vpos
< 0)
14542 matrix
= current_matrix_p
? w
->current_matrix
: w
->desired_matrix
;
14543 row
= MATRIX_ROW (matrix
, w
->cursor
.vpos
);
14545 /* If the cursor row is not partially visible, there's nothing to do. */
14546 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w
, row
))
14549 /* If the row the cursor is in is taller than the window's height,
14550 it's not clear what to do, so do nothing. */
14551 window_height
= window_box_height (w
);
14552 if (row
->height
>= window_height
)
14554 if (!force_p
|| MINI_WINDOW_P (w
)
14555 || w
->vscroll
|| w
->cursor
.vpos
== 0)
14562 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
14563 non-zero means only WINDOW is redisplayed in redisplay_internal.
14564 TEMP_SCROLL_STEP has the same meaning as emacs_scroll_step, and is used
14565 in redisplay_window to bring a partially visible line into view in
14566 the case that only the cursor has moved.
14568 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
14569 last screen line's vertical height extends past the end of the screen.
14573 1 if scrolling succeeded
14575 0 if scrolling didn't find point.
14577 -1 if new fonts have been loaded so that we must interrupt
14578 redisplay, adjust glyph matrices, and try again. */
14584 SCROLLING_NEED_LARGER_MATRICES
14587 /* If scroll-conservatively is more than this, never recenter.
14589 If you change this, don't forget to update the doc string of
14590 `scroll-conservatively' and the Emacs manual. */
14591 #define SCROLL_LIMIT 100
14594 try_scrolling (Lisp_Object window
, int just_this_one_p
,
14595 ptrdiff_t arg_scroll_conservatively
, ptrdiff_t scroll_step
,
14596 int temp_scroll_step
, int last_line_misfit
)
14598 struct window
*w
= XWINDOW (window
);
14599 struct frame
*f
= XFRAME (w
->frame
);
14600 struct text_pos pos
, startp
;
14602 int this_scroll_margin
, scroll_max
, rc
, height
;
14603 int dy
= 0, amount_to_scroll
= 0, scroll_down_p
= 0;
14604 int extra_scroll_margin_lines
= last_line_misfit
? 1 : 0;
14605 Lisp_Object aggressive
;
14606 /* We will never try scrolling more than this number of lines. */
14607 int scroll_limit
= SCROLL_LIMIT
;
14608 int frame_line_height
= default_line_pixel_height (w
);
14609 int window_total_lines
14610 = WINDOW_TOTAL_LINES (w
) * FRAME_LINE_HEIGHT (f
) / frame_line_height
;
14613 debug_method_add (w
, "try_scrolling");
14616 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
14618 /* Compute scroll margin height in pixels. We scroll when point is
14619 within this distance from the top or bottom of the window. */
14620 if (scroll_margin
> 0)
14621 this_scroll_margin
= min (scroll_margin
, window_total_lines
/ 4)
14622 * frame_line_height
;
14624 this_scroll_margin
= 0;
14626 /* Force arg_scroll_conservatively to have a reasonable value, to
14627 avoid scrolling too far away with slow move_it_* functions. Note
14628 that the user can supply scroll-conservatively equal to
14629 `most-positive-fixnum', which can be larger than INT_MAX. */
14630 if (arg_scroll_conservatively
> scroll_limit
)
14632 arg_scroll_conservatively
= scroll_limit
+ 1;
14633 scroll_max
= scroll_limit
* frame_line_height
;
14635 else if (scroll_step
|| arg_scroll_conservatively
|| temp_scroll_step
)
14636 /* Compute how much we should try to scroll maximally to bring
14637 point into view. */
14638 scroll_max
= (max (scroll_step
,
14639 max (arg_scroll_conservatively
, temp_scroll_step
))
14640 * frame_line_height
);
14641 else if (NUMBERP (BVAR (current_buffer
, scroll_down_aggressively
))
14642 || NUMBERP (BVAR (current_buffer
, scroll_up_aggressively
)))
14643 /* We're trying to scroll because of aggressive scrolling but no
14644 scroll_step is set. Choose an arbitrary one. */
14645 scroll_max
= 10 * frame_line_height
;
14651 /* Decide whether to scroll down. */
14652 if (PT
> CHARPOS (startp
))
14654 int scroll_margin_y
;
14656 /* Compute the pixel ypos of the scroll margin, then move IT to
14657 either that ypos or PT, whichever comes first. */
14658 start_display (&it
, w
, startp
);
14659 scroll_margin_y
= it
.last_visible_y
- this_scroll_margin
14660 - frame_line_height
* extra_scroll_margin_lines
;
14661 move_it_to (&it
, PT
, -1, scroll_margin_y
- 1, -1,
14662 (MOVE_TO_POS
| MOVE_TO_Y
));
14664 if (PT
> CHARPOS (it
.current
.pos
))
14666 int y0
= line_bottom_y (&it
);
14667 /* Compute how many pixels below window bottom to stop searching
14668 for PT. This avoids costly search for PT that is far away if
14669 the user limited scrolling by a small number of lines, but
14670 always finds PT if scroll_conservatively is set to a large
14671 number, such as most-positive-fixnum. */
14672 int slack
= max (scroll_max
, 10 * frame_line_height
);
14673 int y_to_move
= it
.last_visible_y
+ slack
;
14675 /* Compute the distance from the scroll margin to PT or to
14676 the scroll limit, whichever comes first. This should
14677 include the height of the cursor line, to make that line
14679 move_it_to (&it
, PT
, -1, y_to_move
,
14680 -1, MOVE_TO_POS
| MOVE_TO_Y
);
14681 dy
= line_bottom_y (&it
) - y0
;
14683 if (dy
> scroll_max
)
14684 return SCROLLING_FAILED
;
14693 /* Point is in or below the bottom scroll margin, so move the
14694 window start down. If scrolling conservatively, move it just
14695 enough down to make point visible. If scroll_step is set,
14696 move it down by scroll_step. */
14697 if (arg_scroll_conservatively
)
14699 = min (max (dy
, frame_line_height
),
14700 frame_line_height
* arg_scroll_conservatively
);
14701 else if (scroll_step
|| temp_scroll_step
)
14702 amount_to_scroll
= scroll_max
;
14705 aggressive
= BVAR (current_buffer
, scroll_up_aggressively
);
14706 height
= WINDOW_BOX_TEXT_HEIGHT (w
);
14707 if (NUMBERP (aggressive
))
14709 double float_amount
= XFLOATINT (aggressive
) * height
;
14710 int aggressive_scroll
= float_amount
;
14711 if (aggressive_scroll
== 0 && float_amount
> 0)
14712 aggressive_scroll
= 1;
14713 /* Don't let point enter the scroll margin near top of
14714 the window. This could happen if the value of
14715 scroll_up_aggressively is too large and there are
14716 non-zero margins, because scroll_up_aggressively
14717 means put point that fraction of window height
14718 _from_the_bottom_margin_. */
14719 if (aggressive_scroll
+ 2*this_scroll_margin
> height
)
14720 aggressive_scroll
= height
- 2*this_scroll_margin
;
14721 amount_to_scroll
= dy
+ aggressive_scroll
;
14725 if (amount_to_scroll
<= 0)
14726 return SCROLLING_FAILED
;
14728 start_display (&it
, w
, startp
);
14729 if (arg_scroll_conservatively
<= scroll_limit
)
14730 move_it_vertically (&it
, amount_to_scroll
);
14733 /* Extra precision for users who set scroll-conservatively
14734 to a large number: make sure the amount we scroll
14735 the window start is never less than amount_to_scroll,
14736 which was computed as distance from window bottom to
14737 point. This matters when lines at window top and lines
14738 below window bottom have different height. */
14740 void *it1data
= NULL
;
14741 /* We use a temporary it1 because line_bottom_y can modify
14742 its argument, if it moves one line down; see there. */
14745 SAVE_IT (it1
, it
, it1data
);
14746 start_y
= line_bottom_y (&it1
);
14748 RESTORE_IT (&it
, &it
, it1data
);
14749 move_it_by_lines (&it
, 1);
14750 SAVE_IT (it1
, it
, it1data
);
14751 } while (line_bottom_y (&it1
) - start_y
< amount_to_scroll
);
14754 /* If STARTP is unchanged, move it down another screen line. */
14755 if (CHARPOS (it
.current
.pos
) == CHARPOS (startp
))
14756 move_it_by_lines (&it
, 1);
14757 startp
= it
.current
.pos
;
14761 struct text_pos scroll_margin_pos
= startp
;
14764 /* See if point is inside the scroll margin at the top of the
14766 if (this_scroll_margin
)
14770 start_display (&it
, w
, startp
);
14771 y_start
= it
.current_y
;
14772 move_it_vertically (&it
, this_scroll_margin
);
14773 scroll_margin_pos
= it
.current
.pos
;
14774 /* If we didn't move enough before hitting ZV, request
14775 additional amount of scroll, to move point out of the
14777 if (IT_CHARPOS (it
) == ZV
14778 && it
.current_y
- y_start
< this_scroll_margin
)
14779 y_offset
= this_scroll_margin
- (it
.current_y
- y_start
);
14782 if (PT
< CHARPOS (scroll_margin_pos
))
14784 /* Point is in the scroll margin at the top of the window or
14785 above what is displayed in the window. */
14788 /* Compute the vertical distance from PT to the scroll
14789 margin position. Move as far as scroll_max allows, or
14790 one screenful, or 10 screen lines, whichever is largest.
14791 Give up if distance is greater than scroll_max or if we
14792 didn't reach the scroll margin position. */
14793 SET_TEXT_POS (pos
, PT
, PT_BYTE
);
14794 start_display (&it
, w
, pos
);
14796 y_to_move
= max (it
.last_visible_y
,
14797 max (scroll_max
, 10 * frame_line_height
));
14798 move_it_to (&it
, CHARPOS (scroll_margin_pos
), 0,
14800 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
14801 dy
= it
.current_y
- y0
;
14802 if (dy
> scroll_max
14803 || IT_CHARPOS (it
) < CHARPOS (scroll_margin_pos
))
14804 return SCROLLING_FAILED
;
14806 /* Additional scroll for when ZV was too close to point. */
14809 /* Compute new window start. */
14810 start_display (&it
, w
, startp
);
14812 if (arg_scroll_conservatively
)
14813 amount_to_scroll
= max (dy
, frame_line_height
*
14814 max (scroll_step
, temp_scroll_step
));
14815 else if (scroll_step
|| temp_scroll_step
)
14816 amount_to_scroll
= scroll_max
;
14819 aggressive
= BVAR (current_buffer
, scroll_down_aggressively
);
14820 height
= WINDOW_BOX_TEXT_HEIGHT (w
);
14821 if (NUMBERP (aggressive
))
14823 double float_amount
= XFLOATINT (aggressive
) * height
;
14824 int aggressive_scroll
= float_amount
;
14825 if (aggressive_scroll
== 0 && float_amount
> 0)
14826 aggressive_scroll
= 1;
14827 /* Don't let point enter the scroll margin near
14828 bottom of the window, if the value of
14829 scroll_down_aggressively happens to be too
14831 if (aggressive_scroll
+ 2*this_scroll_margin
> height
)
14832 aggressive_scroll
= height
- 2*this_scroll_margin
;
14833 amount_to_scroll
= dy
+ aggressive_scroll
;
14837 if (amount_to_scroll
<= 0)
14838 return SCROLLING_FAILED
;
14840 move_it_vertically_backward (&it
, amount_to_scroll
);
14841 startp
= it
.current
.pos
;
14845 /* Run window scroll functions. */
14846 startp
= run_window_scroll_functions (window
, startp
);
14848 /* Display the window. Give up if new fonts are loaded, or if point
14850 if (!try_window (window
, startp
, 0))
14851 rc
= SCROLLING_NEED_LARGER_MATRICES
;
14852 else if (w
->cursor
.vpos
< 0)
14854 clear_glyph_matrix (w
->desired_matrix
);
14855 rc
= SCROLLING_FAILED
;
14859 /* Maybe forget recorded base line for line number display. */
14860 if (!just_this_one_p
14861 || current_buffer
->clip_changed
14862 || BEG_UNCHANGED
< CHARPOS (startp
))
14863 w
->base_line_number
= 0;
14865 /* If cursor ends up on a partially visible line,
14866 treat that as being off the bottom of the screen. */
14867 if (! cursor_row_fully_visible_p (w
, extra_scroll_margin_lines
<= 1, 0)
14868 /* It's possible that the cursor is on the first line of the
14869 buffer, which is partially obscured due to a vscroll
14870 (Bug#7537). In that case, avoid looping forever . */
14871 && extra_scroll_margin_lines
< w
->desired_matrix
->nrows
- 1)
14873 clear_glyph_matrix (w
->desired_matrix
);
14874 ++extra_scroll_margin_lines
;
14877 rc
= SCROLLING_SUCCESS
;
14884 /* Compute a suitable window start for window W if display of W starts
14885 on a continuation line. Value is non-zero if a new window start
14888 The new window start will be computed, based on W's width, starting
14889 from the start of the continued line. It is the start of the
14890 screen line with the minimum distance from the old start W->start. */
14893 compute_window_start_on_continuation_line (struct window
*w
)
14895 struct text_pos pos
, start_pos
;
14896 int window_start_changed_p
= 0;
14898 SET_TEXT_POS_FROM_MARKER (start_pos
, w
->start
);
14900 /* If window start is on a continuation line... Window start may be
14901 < BEGV in case there's invisible text at the start of the
14902 buffer (M-x rmail, for example). */
14903 if (CHARPOS (start_pos
) > BEGV
14904 && FETCH_BYTE (BYTEPOS (start_pos
) - 1) != '\n')
14907 struct glyph_row
*row
;
14909 /* Handle the case that the window start is out of range. */
14910 if (CHARPOS (start_pos
) < BEGV
)
14911 SET_TEXT_POS (start_pos
, BEGV
, BEGV_BYTE
);
14912 else if (CHARPOS (start_pos
) > ZV
)
14913 SET_TEXT_POS (start_pos
, ZV
, ZV_BYTE
);
14915 /* Find the start of the continued line. This should be fast
14916 because find_newline is fast (newline cache). */
14917 row
= w
->desired_matrix
->rows
+ (WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0);
14918 init_iterator (&it
, w
, CHARPOS (start_pos
), BYTEPOS (start_pos
),
14919 row
, DEFAULT_FACE_ID
);
14920 reseat_at_previous_visible_line_start (&it
);
14922 /* If the line start is "too far" away from the window start,
14923 say it takes too much time to compute a new window start. */
14924 if (CHARPOS (start_pos
) - IT_CHARPOS (it
)
14925 < WINDOW_TOTAL_LINES (w
) * WINDOW_TOTAL_COLS (w
))
14927 int min_distance
, distance
;
14929 /* Move forward by display lines to find the new window
14930 start. If window width was enlarged, the new start can
14931 be expected to be > the old start. If window width was
14932 decreased, the new window start will be < the old start.
14933 So, we're looking for the display line start with the
14934 minimum distance from the old window start. */
14935 pos
= it
.current
.pos
;
14936 min_distance
= INFINITY
;
14937 while ((distance
= eabs (CHARPOS (start_pos
) - IT_CHARPOS (it
))),
14938 distance
< min_distance
)
14940 min_distance
= distance
;
14941 pos
= it
.current
.pos
;
14942 if (it
.line_wrap
== WORD_WRAP
)
14944 /* Under WORD_WRAP, move_it_by_lines is likely to
14945 overshoot and stop not at the first, but the
14946 second character from the left margin. So in
14947 that case, we need a more tight control on the X
14948 coordinate of the iterator than move_it_by_lines
14949 promises in its contract. The method is to first
14950 go to the last (rightmost) visible character of a
14951 line, then move to the leftmost character on the
14952 next line in a separate call. */
14953 move_it_to (&it
, ZV
, it
.last_visible_x
, it
.current_y
, -1,
14954 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
14955 move_it_to (&it
, ZV
, 0,
14956 it
.current_y
+ it
.max_ascent
+ it
.max_descent
, -1,
14957 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
14960 move_it_by_lines (&it
, 1);
14963 /* Set the window start there. */
14964 SET_MARKER_FROM_TEXT_POS (w
->start
, pos
);
14965 window_start_changed_p
= 1;
14969 return window_start_changed_p
;
14973 /* Try cursor movement in case text has not changed in window WINDOW,
14974 with window start STARTP. Value is
14976 CURSOR_MOVEMENT_SUCCESS if successful
14978 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
14980 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
14981 display. *SCROLL_STEP is set to 1, under certain circumstances, if
14982 we want to scroll as if scroll-step were set to 1. See the code.
14984 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
14985 which case we have to abort this redisplay, and adjust matrices
14990 CURSOR_MOVEMENT_SUCCESS
,
14991 CURSOR_MOVEMENT_CANNOT_BE_USED
,
14992 CURSOR_MOVEMENT_MUST_SCROLL
,
14993 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
14997 try_cursor_movement (Lisp_Object window
, struct text_pos startp
, int *scroll_step
)
14999 struct window
*w
= XWINDOW (window
);
15000 struct frame
*f
= XFRAME (w
->frame
);
15001 int rc
= CURSOR_MOVEMENT_CANNOT_BE_USED
;
15004 if (inhibit_try_cursor_movement
)
15008 /* Previously, there was a check for Lisp integer in the
15009 if-statement below. Now, this field is converted to
15010 ptrdiff_t, thus zero means invalid position in a buffer. */
15011 eassert (w
->last_point
> 0);
15012 /* Likewise there was a check whether window_end_vpos is nil or larger
15013 than the window. Now window_end_vpos is int and so never nil, but
15014 let's leave eassert to check whether it fits in the window. */
15015 eassert (w
->window_end_vpos
< w
->current_matrix
->nrows
);
15017 /* Handle case where text has not changed, only point, and it has
15018 not moved off the frame. */
15019 if (/* Point may be in this window. */
15020 PT
>= CHARPOS (startp
)
15021 /* Selective display hasn't changed. */
15022 && !current_buffer
->clip_changed
15023 /* Function force-mode-line-update is used to force a thorough
15024 redisplay. It sets either windows_or_buffers_changed or
15025 update_mode_lines. So don't take a shortcut here for these
15027 && !update_mode_lines
15028 && !windows_or_buffers_changed
15029 && !f
->cursor_type_changed
15030 && NILP (Vshow_trailing_whitespace
)
15031 /* This code is not used for mini-buffer for the sake of the case
15032 of redisplaying to replace an echo area message; since in
15033 that case the mini-buffer contents per se are usually
15034 unchanged. This code is of no real use in the mini-buffer
15035 since the handling of this_line_start_pos, etc., in redisplay
15036 handles the same cases. */
15037 && !EQ (window
, minibuf_window
)
15038 && (FRAME_WINDOW_P (f
)
15039 || !overlay_arrow_in_current_buffer_p ()))
15041 int this_scroll_margin
, top_scroll_margin
;
15042 struct glyph_row
*row
= NULL
;
15043 int frame_line_height
= default_line_pixel_height (w
);
15044 int window_total_lines
15045 = WINDOW_TOTAL_LINES (w
) * FRAME_LINE_HEIGHT (f
) / frame_line_height
;
15048 debug_method_add (w
, "cursor movement");
15051 /* Scroll if point within this distance from the top or bottom
15052 of the window. This is a pixel value. */
15053 if (scroll_margin
> 0)
15055 this_scroll_margin
= min (scroll_margin
, window_total_lines
/ 4);
15056 this_scroll_margin
*= frame_line_height
;
15059 this_scroll_margin
= 0;
15061 top_scroll_margin
= this_scroll_margin
;
15062 if (WINDOW_WANTS_HEADER_LINE_P (w
))
15063 top_scroll_margin
+= CURRENT_HEADER_LINE_HEIGHT (w
);
15065 /* Start with the row the cursor was displayed during the last
15066 not paused redisplay. Give up if that row is not valid. */
15067 if (w
->last_cursor_vpos
< 0
15068 || w
->last_cursor_vpos
>= w
->current_matrix
->nrows
)
15069 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
15072 row
= MATRIX_ROW (w
->current_matrix
, w
->last_cursor_vpos
);
15073 if (row
->mode_line_p
)
15075 if (!row
->enabled_p
)
15076 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
15079 if (rc
== CURSOR_MOVEMENT_CANNOT_BE_USED
)
15081 int scroll_p
= 0, must_scroll
= 0;
15082 int last_y
= window_text_bottom_y (w
) - this_scroll_margin
;
15084 if (PT
> w
->last_point
)
15086 /* Point has moved forward. */
15087 while (MATRIX_ROW_END_CHARPOS (row
) < PT
15088 && MATRIX_ROW_BOTTOM_Y (row
) < last_y
)
15090 eassert (row
->enabled_p
);
15094 /* If the end position of a row equals the start
15095 position of the next row, and PT is at that position,
15096 we would rather display cursor in the next line. */
15097 while (MATRIX_ROW_BOTTOM_Y (row
) < last_y
15098 && MATRIX_ROW_END_CHARPOS (row
) == PT
15099 && row
< MATRIX_MODE_LINE_ROW (w
->current_matrix
)
15100 && MATRIX_ROW_START_CHARPOS (row
+1) == PT
15101 && !cursor_row_p (row
))
15104 /* If within the scroll margin, scroll. Note that
15105 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
15106 the next line would be drawn, and that
15107 this_scroll_margin can be zero. */
15108 if (MATRIX_ROW_BOTTOM_Y (row
) > last_y
15109 || PT
> MATRIX_ROW_END_CHARPOS (row
)
15110 /* Line is completely visible last line in window
15111 and PT is to be set in the next line. */
15112 || (MATRIX_ROW_BOTTOM_Y (row
) == last_y
15113 && PT
== MATRIX_ROW_END_CHARPOS (row
)
15114 && !row
->ends_at_zv_p
15115 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
)))
15118 else if (PT
< w
->last_point
)
15120 /* Cursor has to be moved backward. Note that PT >=
15121 CHARPOS (startp) because of the outer if-statement. */
15122 while (!row
->mode_line_p
15123 && (MATRIX_ROW_START_CHARPOS (row
) > PT
15124 || (MATRIX_ROW_START_CHARPOS (row
) == PT
15125 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row
)
15126 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
15127 row
> w
->current_matrix
->rows
15128 && (row
-1)->ends_in_newline_from_string_p
))))
15129 && (row
->y
> top_scroll_margin
15130 || CHARPOS (startp
) == BEGV
))
15132 eassert (row
->enabled_p
);
15136 /* Consider the following case: Window starts at BEGV,
15137 there is invisible, intangible text at BEGV, so that
15138 display starts at some point START > BEGV. It can
15139 happen that we are called with PT somewhere between
15140 BEGV and START. Try to handle that case. */
15141 if (row
< w
->current_matrix
->rows
15142 || row
->mode_line_p
)
15144 row
= w
->current_matrix
->rows
;
15145 if (row
->mode_line_p
)
15149 /* Due to newlines in overlay strings, we may have to
15150 skip forward over overlay strings. */
15151 while (MATRIX_ROW_BOTTOM_Y (row
) < last_y
15152 && MATRIX_ROW_END_CHARPOS (row
) == PT
15153 && !cursor_row_p (row
))
15156 /* If within the scroll margin, scroll. */
15157 if (row
->y
< top_scroll_margin
15158 && CHARPOS (startp
) != BEGV
)
15163 /* Cursor did not move. So don't scroll even if cursor line
15164 is partially visible, as it was so before. */
15165 rc
= CURSOR_MOVEMENT_SUCCESS
;
15168 if (PT
< MATRIX_ROW_START_CHARPOS (row
)
15169 || PT
> MATRIX_ROW_END_CHARPOS (row
))
15171 /* if PT is not in the glyph row, give up. */
15172 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
15175 else if (rc
!= CURSOR_MOVEMENT_SUCCESS
15176 && !NILP (BVAR (XBUFFER (w
->contents
), bidi_display_reordering
)))
15178 struct glyph_row
*row1
;
15180 /* If rows are bidi-reordered and point moved, back up
15181 until we find a row that does not belong to a
15182 continuation line. This is because we must consider
15183 all rows of a continued line as candidates for the
15184 new cursor positioning, since row start and end
15185 positions change non-linearly with vertical position
15187 /* FIXME: Revisit this when glyph ``spilling'' in
15188 continuation lines' rows is implemented for
15189 bidi-reordered rows. */
15190 for (row1
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
15191 MATRIX_ROW_CONTINUATION_LINE_P (row
);
15194 /* If we hit the beginning of the displayed portion
15195 without finding the first row of a continued
15199 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
15202 eassert (row
->enabled_p
);
15207 else if (rc
!= CURSOR_MOVEMENT_SUCCESS
15208 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w
, row
)
15209 /* Make sure this isn't a header line by any chance, since
15210 then MATRIX_ROW_PARTIALLY_VISIBLE_P might yield non-zero. */
15211 && !row
->mode_line_p
15212 && make_cursor_line_fully_visible_p
)
15214 if (PT
== MATRIX_ROW_END_CHARPOS (row
)
15215 && !row
->ends_at_zv_p
15216 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
))
15217 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
15218 else if (row
->height
> window_box_height (w
))
15220 /* If we end up in a partially visible line, let's
15221 make it fully visible, except when it's taller
15222 than the window, in which case we can't do much
15225 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
15229 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
15230 if (!cursor_row_fully_visible_p (w
, 0, 1))
15231 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
15233 rc
= CURSOR_MOVEMENT_SUCCESS
;
15237 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
15238 else if (rc
!= CURSOR_MOVEMENT_SUCCESS
15239 && !NILP (BVAR (XBUFFER (w
->contents
), bidi_display_reordering
)))
15241 /* With bidi-reordered rows, there could be more than
15242 one candidate row whose start and end positions
15243 occlude point. We need to let set_cursor_from_row
15244 find the best candidate. */
15245 /* FIXME: Revisit this when glyph ``spilling'' in
15246 continuation lines' rows is implemented for
15247 bidi-reordered rows. */
15252 int at_zv_p
= 0, exact_match_p
= 0;
15254 if (MATRIX_ROW_START_CHARPOS (row
) <= PT
15255 && PT
<= MATRIX_ROW_END_CHARPOS (row
)
15256 && cursor_row_p (row
))
15257 rv
|= set_cursor_from_row (w
, row
, w
->current_matrix
,
15259 /* As soon as we've found the exact match for point,
15260 or the first suitable row whose ends_at_zv_p flag
15261 is set, we are done. */
15263 MATRIX_ROW (w
->current_matrix
, w
->cursor
.vpos
)->ends_at_zv_p
;
15265 && w
->cursor
.hpos
>= 0
15266 && w
->cursor
.hpos
< MATRIX_ROW_USED (w
->current_matrix
,
15269 struct glyph_row
*candidate
=
15270 MATRIX_ROW (w
->current_matrix
, w
->cursor
.vpos
);
15272 candidate
->glyphs
[TEXT_AREA
] + w
->cursor
.hpos
;
15273 ptrdiff_t endpos
= MATRIX_ROW_END_CHARPOS (candidate
);
15276 (BUFFERP (g
->object
) && g
->charpos
== PT
)
15277 || (INTEGERP (g
->object
)
15278 && (g
->charpos
== PT
15279 || (g
->charpos
== 0 && endpos
- 1 == PT
)));
15281 if (rv
&& (at_zv_p
|| exact_match_p
))
15283 rc
= CURSOR_MOVEMENT_SUCCESS
;
15286 if (MATRIX_ROW_BOTTOM_Y (row
) == last_y
)
15290 while (((MATRIX_ROW_CONTINUATION_LINE_P (row
)
15291 || row
->continued_p
)
15292 && MATRIX_ROW_BOTTOM_Y (row
) <= last_y
)
15293 || (MATRIX_ROW_START_CHARPOS (row
) == PT
15294 && MATRIX_ROW_BOTTOM_Y (row
) < last_y
));
15295 /* If we didn't find any candidate rows, or exited the
15296 loop before all the candidates were examined, signal
15297 to the caller that this method failed. */
15298 if (rc
!= CURSOR_MOVEMENT_SUCCESS
15300 && !MATRIX_ROW_CONTINUATION_LINE_P (row
)
15301 && !row
->continued_p
))
15302 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
15304 rc
= CURSOR_MOVEMENT_SUCCESS
;
15310 if (set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0))
15312 rc
= CURSOR_MOVEMENT_SUCCESS
;
15317 while (MATRIX_ROW_BOTTOM_Y (row
) < last_y
15318 && MATRIX_ROW_START_CHARPOS (row
) == PT
15319 && cursor_row_p (row
));
15327 #if !defined USE_TOOLKIT_SCROLL_BARS || defined USE_GTK
15331 set_vertical_scroll_bar (struct window
*w
)
15333 ptrdiff_t start
, end
, whole
;
15335 /* Calculate the start and end positions for the current window.
15336 At some point, it would be nice to choose between scrollbars
15337 which reflect the whole buffer size, with special markers
15338 indicating narrowing, and scrollbars which reflect only the
15341 Note that mini-buffers sometimes aren't displaying any text. */
15342 if (!MINI_WINDOW_P (w
)
15343 || (w
== XWINDOW (minibuf_window
)
15344 && NILP (echo_area_buffer
[0])))
15346 struct buffer
*buf
= XBUFFER (w
->contents
);
15347 whole
= BUF_ZV (buf
) - BUF_BEGV (buf
);
15348 start
= marker_position (w
->start
) - BUF_BEGV (buf
);
15349 /* I don't think this is guaranteed to be right. For the
15350 moment, we'll pretend it is. */
15351 end
= BUF_Z (buf
) - w
->window_end_pos
- BUF_BEGV (buf
);
15355 if (whole
< (end
- start
))
15356 whole
= end
- start
;
15359 start
= end
= whole
= 0;
15361 /* Indicate what this scroll bar ought to be displaying now. */
15362 if (FRAME_TERMINAL (XFRAME (w
->frame
))->set_vertical_scroll_bar_hook
)
15363 (*FRAME_TERMINAL (XFRAME (w
->frame
))->set_vertical_scroll_bar_hook
)
15364 (w
, end
- start
, whole
, start
);
15368 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
15369 selected_window is redisplayed.
15371 We can return without actually redisplaying the window if fonts has been
15372 changed on window's frame. In that case, redisplay_internal will retry. */
15375 redisplay_window (Lisp_Object window
, int just_this_one_p
)
15377 struct window
*w
= XWINDOW (window
);
15378 struct frame
*f
= XFRAME (w
->frame
);
15379 struct buffer
*buffer
= XBUFFER (w
->contents
);
15380 struct buffer
*old
= current_buffer
;
15381 struct text_pos lpoint
, opoint
, startp
;
15382 int update_mode_line
;
15385 /* Record it now because it's overwritten. */
15386 int current_matrix_up_to_date_p
= 0;
15387 int used_current_matrix_p
= 0;
15388 /* This is less strict than current_matrix_up_to_date_p.
15389 It indicates that the buffer contents and narrowing are unchanged. */
15390 int buffer_unchanged_p
= 0;
15391 int temp_scroll_step
= 0;
15392 ptrdiff_t count
= SPECPDL_INDEX ();
15394 int centering_position
= -1;
15395 int last_line_misfit
= 0;
15396 ptrdiff_t beg_unchanged
, end_unchanged
;
15397 int frame_line_height
;
15399 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
15403 *w
->desired_matrix
->method
= 0;
15406 if (!just_this_one_p
15407 && (update_mode_lines
== REDISPLAY_SOME
15408 || update_mode_lines
== 0)
15409 && (windows_or_buffers_changed
== REDISPLAY_SOME
15410 || windows_or_buffers_changed
== 0)
15413 && !buffer
->text
->redisplay
)
15416 /* Make sure that both W's markers are valid. */
15417 eassert (XMARKER (w
->start
)->buffer
== buffer
);
15418 eassert (XMARKER (w
->pointm
)->buffer
== buffer
);
15421 reconsider_clip_changes (w
);
15422 frame_line_height
= default_line_pixel_height (w
);
15424 /* Has the mode line to be updated? */
15425 update_mode_line
= (w
->update_mode_line
15426 || update_mode_lines
15427 || buffer
->clip_changed
15428 || buffer
->prevent_redisplay_optimizations_p
);
15430 if (MINI_WINDOW_P (w
))
15432 if (w
== XWINDOW (echo_area_window
)
15433 && !NILP (echo_area_buffer
[0]))
15435 if (update_mode_line
)
15436 /* We may have to update a tty frame's menu bar or a
15437 tool-bar. Example `M-x C-h C-h C-g'. */
15438 goto finish_menu_bars
;
15440 /* We've already displayed the echo area glyphs in this window. */
15441 goto finish_scroll_bars
;
15443 else if ((w
!= XWINDOW (minibuf_window
)
15444 || minibuf_level
== 0)
15445 /* When buffer is nonempty, redisplay window normally. */
15446 && BUF_Z (XBUFFER (w
->contents
)) == BUF_BEG (XBUFFER (w
->contents
))
15447 /* Quail displays non-mini buffers in minibuffer window.
15448 In that case, redisplay the window normally. */
15449 && !NILP (Fmemq (w
->contents
, Vminibuffer_list
)))
15451 /* W is a mini-buffer window, but it's not active, so clear
15453 int yb
= window_text_bottom_y (w
);
15454 struct glyph_row
*row
;
15457 for (y
= 0, row
= w
->desired_matrix
->rows
;
15459 y
+= row
->height
, ++row
)
15460 blank_row (w
, row
, y
);
15461 goto finish_scroll_bars
;
15464 clear_glyph_matrix (w
->desired_matrix
);
15467 /* Otherwise set up data on this window; select its buffer and point
15469 /* Really select the buffer, for the sake of buffer-local
15471 set_buffer_internal_1 (XBUFFER (w
->contents
));
15473 current_matrix_up_to_date_p
15474 = (w
->window_end_valid
15475 && !current_buffer
->clip_changed
15476 && !current_buffer
->prevent_redisplay_optimizations_p
15477 && !window_outdated (w
));
15479 /* Run the window-bottom-change-functions
15480 if it is possible that the text on the screen has changed
15481 (either due to modification of the text, or any other reason). */
15482 if (!current_matrix_up_to_date_p
15483 && !NILP (Vwindow_text_change_functions
))
15485 safe_run_hooks (Qwindow_text_change_functions
);
15489 beg_unchanged
= BEG_UNCHANGED
;
15490 end_unchanged
= END_UNCHANGED
;
15492 SET_TEXT_POS (opoint
, PT
, PT_BYTE
);
15494 specbind (Qinhibit_point_motion_hooks
, Qt
);
15497 = (w
->window_end_valid
15498 && !current_buffer
->clip_changed
15499 && !window_outdated (w
));
15501 /* When windows_or_buffers_changed is non-zero, we can't rely
15502 on the window end being valid, so set it to zero there. */
15503 if (windows_or_buffers_changed
)
15505 /* If window starts on a continuation line, maybe adjust the
15506 window start in case the window's width changed. */
15507 if (XMARKER (w
->start
)->buffer
== current_buffer
)
15508 compute_window_start_on_continuation_line (w
);
15510 w
->window_end_valid
= 0;
15511 /* If so, we also can't rely on current matrix
15512 and should not fool try_cursor_movement below. */
15513 current_matrix_up_to_date_p
= 0;
15516 /* Some sanity checks. */
15517 CHECK_WINDOW_END (w
);
15518 if (Z
== Z_BYTE
&& CHARPOS (opoint
) != BYTEPOS (opoint
))
15520 if (BYTEPOS (opoint
) < CHARPOS (opoint
))
15523 if (mode_line_update_needed (w
))
15524 update_mode_line
= 1;
15526 /* Point refers normally to the selected window. For any other
15527 window, set up appropriate value. */
15528 if (!EQ (window
, selected_window
))
15530 ptrdiff_t new_pt
= marker_position (w
->pointm
);
15531 ptrdiff_t new_pt_byte
= marker_byte_position (w
->pointm
);
15535 new_pt_byte
= BEGV_BYTE
;
15536 set_marker_both (w
->pointm
, Qnil
, BEGV
, BEGV_BYTE
);
15538 else if (new_pt
> (ZV
- 1))
15541 new_pt_byte
= ZV_BYTE
;
15542 set_marker_both (w
->pointm
, Qnil
, ZV
, ZV_BYTE
);
15545 /* We don't use SET_PT so that the point-motion hooks don't run. */
15546 TEMP_SET_PT_BOTH (new_pt
, new_pt_byte
);
15549 /* If any of the character widths specified in the display table
15550 have changed, invalidate the width run cache. It's true that
15551 this may be a bit late to catch such changes, but the rest of
15552 redisplay goes (non-fatally) haywire when the display table is
15553 changed, so why should we worry about doing any better? */
15554 if (current_buffer
->width_run_cache
)
15556 struct Lisp_Char_Table
*disptab
= buffer_display_table ();
15558 if (! disptab_matches_widthtab
15559 (disptab
, XVECTOR (BVAR (current_buffer
, width_table
))))
15561 invalidate_region_cache (current_buffer
,
15562 current_buffer
->width_run_cache
,
15564 recompute_width_table (current_buffer
, disptab
);
15568 /* If window-start is screwed up, choose a new one. */
15569 if (XMARKER (w
->start
)->buffer
!= current_buffer
)
15572 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
15574 /* If someone specified a new starting point but did not insist,
15575 check whether it can be used. */
15576 if (w
->optional_new_start
15577 && CHARPOS (startp
) >= BEGV
15578 && CHARPOS (startp
) <= ZV
)
15580 w
->optional_new_start
= 0;
15581 start_display (&it
, w
, startp
);
15582 move_it_to (&it
, PT
, 0, it
.last_visible_y
, -1,
15583 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
15584 if (IT_CHARPOS (it
) == PT
)
15585 w
->force_start
= 1;
15586 /* IT may overshoot PT if text at PT is invisible. */
15587 else if (IT_CHARPOS (it
) > PT
&& CHARPOS (startp
) <= PT
)
15588 w
->force_start
= 1;
15593 /* Handle case where place to start displaying has been specified,
15594 unless the specified location is outside the accessible range. */
15595 if (w
->force_start
|| window_frozen_p (w
))
15597 /* We set this later on if we have to adjust point. */
15600 w
->force_start
= 0;
15602 w
->window_end_valid
= 0;
15604 /* Forget any recorded base line for line number display. */
15605 if (!buffer_unchanged_p
)
15606 w
->base_line_number
= 0;
15608 /* Redisplay the mode line. Select the buffer properly for that.
15609 Also, run the hook window-scroll-functions
15610 because we have scrolled. */
15611 /* Note, we do this after clearing force_start because
15612 if there's an error, it is better to forget about force_start
15613 than to get into an infinite loop calling the hook functions
15614 and having them get more errors. */
15615 if (!update_mode_line
15616 || ! NILP (Vwindow_scroll_functions
))
15618 update_mode_line
= 1;
15619 w
->update_mode_line
= 1;
15620 startp
= run_window_scroll_functions (window
, startp
);
15623 if (CHARPOS (startp
) < BEGV
)
15624 SET_TEXT_POS (startp
, BEGV
, BEGV_BYTE
);
15625 else if (CHARPOS (startp
) > ZV
)
15626 SET_TEXT_POS (startp
, ZV
, ZV_BYTE
);
15628 /* Redisplay, then check if cursor has been set during the
15629 redisplay. Give up if new fonts were loaded. */
15630 /* We used to issue a CHECK_MARGINS argument to try_window here,
15631 but this causes scrolling to fail when point begins inside
15632 the scroll margin (bug#148) -- cyd */
15633 if (!try_window (window
, startp
, 0))
15635 w
->force_start
= 1;
15636 clear_glyph_matrix (w
->desired_matrix
);
15637 goto need_larger_matrices
;
15640 if (w
->cursor
.vpos
< 0 && !window_frozen_p (w
))
15642 /* If point does not appear, try to move point so it does
15643 appear. The desired matrix has been built above, so we
15644 can use it here. */
15645 new_vpos
= window_box_height (w
) / 2;
15648 if (!cursor_row_fully_visible_p (w
, 0, 0))
15650 /* Point does appear, but on a line partly visible at end of window.
15651 Move it back to a fully-visible line. */
15652 new_vpos
= window_box_height (w
);
15654 else if (w
->cursor
.vpos
>= 0)
15656 /* Some people insist on not letting point enter the scroll
15657 margin, even though this part handles windows that didn't
15659 int window_total_lines
15660 = WINDOW_TOTAL_LINES (w
) * FRAME_LINE_HEIGHT (f
) / frame_line_height
;
15661 int margin
= min (scroll_margin
, window_total_lines
/ 4);
15662 int pixel_margin
= margin
* frame_line_height
;
15663 bool header_line
= WINDOW_WANTS_HEADER_LINE_P (w
);
15665 /* Note: We add an extra FRAME_LINE_HEIGHT, because the loop
15666 below, which finds the row to move point to, advances by
15667 the Y coordinate of the _next_ row, see the definition of
15668 MATRIX_ROW_BOTTOM_Y. */
15669 if (w
->cursor
.vpos
< margin
+ header_line
)
15671 w
->cursor
.vpos
= -1;
15672 clear_glyph_matrix (w
->desired_matrix
);
15673 goto try_to_scroll
;
15677 int window_height
= window_box_height (w
);
15680 window_height
+= CURRENT_HEADER_LINE_HEIGHT (w
);
15681 if (w
->cursor
.y
>= window_height
- pixel_margin
)
15683 w
->cursor
.vpos
= -1;
15684 clear_glyph_matrix (w
->desired_matrix
);
15685 goto try_to_scroll
;
15690 /* If we need to move point for either of the above reasons,
15691 now actually do it. */
15694 struct glyph_row
*row
;
15696 row
= MATRIX_FIRST_TEXT_ROW (w
->desired_matrix
);
15697 while (MATRIX_ROW_BOTTOM_Y (row
) < new_vpos
)
15700 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row
),
15701 MATRIX_ROW_START_BYTEPOS (row
));
15703 if (w
!= XWINDOW (selected_window
))
15704 set_marker_both (w
->pointm
, Qnil
, PT
, PT_BYTE
);
15705 else if (current_buffer
== old
)
15706 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
15708 set_cursor_from_row (w
, row
, w
->desired_matrix
, 0, 0, 0, 0);
15710 /* If we are highlighting the region, then we just changed
15711 the region, so redisplay to show it. */
15712 /* FIXME: We need to (re)run pre-redisplay-function! */
15713 /* if (markpos_of_region () >= 0)
15715 clear_glyph_matrix (w->desired_matrix);
15716 if (!try_window (window, startp, 0))
15717 goto need_larger_matrices;
15723 debug_method_add (w
, "forced window start");
15728 /* Handle case where text has not changed, only point, and it has
15729 not moved off the frame, and we are not retrying after hscroll.
15730 (current_matrix_up_to_date_p is nonzero when retrying.) */
15731 if (current_matrix_up_to_date_p
15732 && (rc
= try_cursor_movement (window
, startp
, &temp_scroll_step
),
15733 rc
!= CURSOR_MOVEMENT_CANNOT_BE_USED
))
15737 case CURSOR_MOVEMENT_SUCCESS
:
15738 used_current_matrix_p
= 1;
15741 case CURSOR_MOVEMENT_MUST_SCROLL
:
15742 goto try_to_scroll
;
15748 /* If current starting point was originally the beginning of a line
15749 but no longer is, find a new starting point. */
15750 else if (w
->start_at_line_beg
15751 && !(CHARPOS (startp
) <= BEGV
15752 || FETCH_BYTE (BYTEPOS (startp
) - 1) == '\n'))
15755 debug_method_add (w
, "recenter 1");
15760 /* Try scrolling with try_window_id. Value is > 0 if update has
15761 been done, it is -1 if we know that the same window start will
15762 not work. It is 0 if unsuccessful for some other reason. */
15763 else if ((tem
= try_window_id (w
)) != 0)
15766 debug_method_add (w
, "try_window_id %d", tem
);
15769 if (f
->fonts_changed
)
15770 goto need_larger_matrices
;
15774 /* Otherwise try_window_id has returned -1 which means that we
15775 don't want the alternative below this comment to execute. */
15777 else if (CHARPOS (startp
) >= BEGV
15778 && CHARPOS (startp
) <= ZV
15779 && PT
>= CHARPOS (startp
)
15780 && (CHARPOS (startp
) < ZV
15781 /* Avoid starting at end of buffer. */
15782 || CHARPOS (startp
) == BEGV
15783 || !window_outdated (w
)))
15785 int d1
, d2
, d3
, d4
, d5
, d6
;
15787 /* If first window line is a continuation line, and window start
15788 is inside the modified region, but the first change is before
15789 current window start, we must select a new window start.
15791 However, if this is the result of a down-mouse event (e.g. by
15792 extending the mouse-drag-overlay), we don't want to select a
15793 new window start, since that would change the position under
15794 the mouse, resulting in an unwanted mouse-movement rather
15795 than a simple mouse-click. */
15796 if (!w
->start_at_line_beg
15797 && NILP (do_mouse_tracking
)
15798 && CHARPOS (startp
) > BEGV
15799 && CHARPOS (startp
) > BEG
+ beg_unchanged
15800 && CHARPOS (startp
) <= Z
- end_unchanged
15801 /* Even if w->start_at_line_beg is nil, a new window may
15802 start at a line_beg, since that's how set_buffer_window
15803 sets it. So, we need to check the return value of
15804 compute_window_start_on_continuation_line. (See also
15806 && XMARKER (w
->start
)->buffer
== current_buffer
15807 && compute_window_start_on_continuation_line (w
)
15808 /* It doesn't make sense to force the window start like we
15809 do at label force_start if it is already known that point
15810 will not be visible in the resulting window, because
15811 doing so will move point from its correct position
15812 instead of scrolling the window to bring point into view.
15814 && pos_visible_p (w
, PT
, &d1
, &d2
, &d3
, &d4
, &d5
, &d6
))
15816 w
->force_start
= 1;
15817 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
15822 debug_method_add (w
, "same window start");
15825 /* Try to redisplay starting at same place as before.
15826 If point has not moved off frame, accept the results. */
15827 if (!current_matrix_up_to_date_p
15828 /* Don't use try_window_reusing_current_matrix in this case
15829 because a window scroll function can have changed the
15831 || !NILP (Vwindow_scroll_functions
)
15832 || MINI_WINDOW_P (w
)
15833 || !(used_current_matrix_p
15834 = try_window_reusing_current_matrix (w
)))
15836 IF_DEBUG (debug_method_add (w
, "1"));
15837 if (try_window (window
, startp
, TRY_WINDOW_CHECK_MARGINS
) < 0)
15838 /* -1 means we need to scroll.
15839 0 means we need new matrices, but fonts_changed
15840 is set in that case, so we will detect it below. */
15841 goto try_to_scroll
;
15844 if (f
->fonts_changed
)
15845 goto need_larger_matrices
;
15847 if (w
->cursor
.vpos
>= 0)
15849 if (!just_this_one_p
15850 || current_buffer
->clip_changed
15851 || BEG_UNCHANGED
< CHARPOS (startp
))
15852 /* Forget any recorded base line for line number display. */
15853 w
->base_line_number
= 0;
15855 if (!cursor_row_fully_visible_p (w
, 1, 0))
15857 clear_glyph_matrix (w
->desired_matrix
);
15858 last_line_misfit
= 1;
15860 /* Drop through and scroll. */
15865 clear_glyph_matrix (w
->desired_matrix
);
15870 /* Redisplay the mode line. Select the buffer properly for that. */
15871 if (!update_mode_line
)
15873 update_mode_line
= 1;
15874 w
->update_mode_line
= 1;
15877 /* Try to scroll by specified few lines. */
15878 if ((scroll_conservatively
15879 || emacs_scroll_step
15880 || temp_scroll_step
15881 || NUMBERP (BVAR (current_buffer
, scroll_up_aggressively
))
15882 || NUMBERP (BVAR (current_buffer
, scroll_down_aggressively
)))
15883 && CHARPOS (startp
) >= BEGV
15884 && CHARPOS (startp
) <= ZV
)
15886 /* The function returns -1 if new fonts were loaded, 1 if
15887 successful, 0 if not successful. */
15888 int ss
= try_scrolling (window
, just_this_one_p
,
15889 scroll_conservatively
,
15891 temp_scroll_step
, last_line_misfit
);
15894 case SCROLLING_SUCCESS
:
15897 case SCROLLING_NEED_LARGER_MATRICES
:
15898 goto need_larger_matrices
;
15900 case SCROLLING_FAILED
:
15908 /* Finally, just choose a place to start which positions point
15909 according to user preferences. */
15914 debug_method_add (w
, "recenter");
15917 /* Forget any previously recorded base line for line number display. */
15918 if (!buffer_unchanged_p
)
15919 w
->base_line_number
= 0;
15921 /* Determine the window start relative to point. */
15922 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
15923 it
.current_y
= it
.last_visible_y
;
15924 if (centering_position
< 0)
15926 int window_total_lines
15927 = WINDOW_TOTAL_LINES (w
) * FRAME_LINE_HEIGHT (f
) / frame_line_height
;
15930 ? min (scroll_margin
, window_total_lines
/ 4)
15932 ptrdiff_t margin_pos
= CHARPOS (startp
);
15933 Lisp_Object aggressive
;
15936 /* If there is a scroll margin at the top of the window, find
15937 its character position. */
15939 /* Cannot call start_display if startp is not in the
15940 accessible region of the buffer. This can happen when we
15941 have just switched to a different buffer and/or changed
15942 its restriction. In that case, startp is initialized to
15943 the character position 1 (BEGV) because we did not yet
15944 have chance to display the buffer even once. */
15945 && BEGV
<= CHARPOS (startp
) && CHARPOS (startp
) <= ZV
)
15948 void *it1data
= NULL
;
15950 SAVE_IT (it1
, it
, it1data
);
15951 start_display (&it1
, w
, startp
);
15952 move_it_vertically (&it1
, margin
* frame_line_height
);
15953 margin_pos
= IT_CHARPOS (it1
);
15954 RESTORE_IT (&it
, &it
, it1data
);
15956 scrolling_up
= PT
> margin_pos
;
15959 ? BVAR (current_buffer
, scroll_up_aggressively
)
15960 : BVAR (current_buffer
, scroll_down_aggressively
);
15962 if (!MINI_WINDOW_P (w
)
15963 && (scroll_conservatively
> SCROLL_LIMIT
|| NUMBERP (aggressive
)))
15967 /* Setting scroll-conservatively overrides
15968 scroll-*-aggressively. */
15969 if (!scroll_conservatively
&& NUMBERP (aggressive
))
15971 double float_amount
= XFLOATINT (aggressive
);
15973 pt_offset
= float_amount
* WINDOW_BOX_TEXT_HEIGHT (w
);
15974 if (pt_offset
== 0 && float_amount
> 0)
15976 if (pt_offset
&& margin
> 0)
15979 /* Compute how much to move the window start backward from
15980 point so that point will be displayed where the user
15984 centering_position
= it
.last_visible_y
;
15986 centering_position
-= pt_offset
;
15987 centering_position
-=
15988 frame_line_height
* (1 + margin
+ (last_line_misfit
!= 0))
15989 + WINDOW_HEADER_LINE_HEIGHT (w
);
15990 /* Don't let point enter the scroll margin near top of
15992 if (centering_position
< margin
* frame_line_height
)
15993 centering_position
= margin
* frame_line_height
;
15996 centering_position
= margin
* frame_line_height
+ pt_offset
;
15999 /* Set the window start half the height of the window backward
16001 centering_position
= window_box_height (w
) / 2;
16003 move_it_vertically_backward (&it
, centering_position
);
16005 eassert (IT_CHARPOS (it
) >= BEGV
);
16007 /* The function move_it_vertically_backward may move over more
16008 than the specified y-distance. If it->w is small, e.g. a
16009 mini-buffer window, we may end up in front of the window's
16010 display area. Start displaying at the start of the line
16011 containing PT in this case. */
16012 if (it
.current_y
<= 0)
16014 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
16015 move_it_vertically_backward (&it
, 0);
16019 it
.current_x
= it
.hpos
= 0;
16021 /* Set the window start position here explicitly, to avoid an
16022 infinite loop in case the functions in window-scroll-functions
16024 set_marker_both (w
->start
, Qnil
, IT_CHARPOS (it
), IT_BYTEPOS (it
));
16026 /* Run scroll hooks. */
16027 startp
= run_window_scroll_functions (window
, it
.current
.pos
);
16029 /* Redisplay the window. */
16030 if (!current_matrix_up_to_date_p
16031 || windows_or_buffers_changed
16032 || f
->cursor_type_changed
16033 /* Don't use try_window_reusing_current_matrix in this case
16034 because it can have changed the buffer. */
16035 || !NILP (Vwindow_scroll_functions
)
16036 || !just_this_one_p
16037 || MINI_WINDOW_P (w
)
16038 || !(used_current_matrix_p
16039 = try_window_reusing_current_matrix (w
)))
16040 try_window (window
, startp
, 0);
16042 /* If new fonts have been loaded (due to fontsets), give up. We
16043 have to start a new redisplay since we need to re-adjust glyph
16045 if (f
->fonts_changed
)
16046 goto need_larger_matrices
;
16048 /* If cursor did not appear assume that the middle of the window is
16049 in the first line of the window. Do it again with the next line.
16050 (Imagine a window of height 100, displaying two lines of height
16051 60. Moving back 50 from it->last_visible_y will end in the first
16053 if (w
->cursor
.vpos
< 0)
16055 if (w
->window_end_valid
&& PT
>= Z
- w
->window_end_pos
)
16057 clear_glyph_matrix (w
->desired_matrix
);
16058 move_it_by_lines (&it
, 1);
16059 try_window (window
, it
.current
.pos
, 0);
16061 else if (PT
< IT_CHARPOS (it
))
16063 clear_glyph_matrix (w
->desired_matrix
);
16064 move_it_by_lines (&it
, -1);
16065 try_window (window
, it
.current
.pos
, 0);
16069 /* Not much we can do about it. */
16073 /* Consider the following case: Window starts at BEGV, there is
16074 invisible, intangible text at BEGV, so that display starts at
16075 some point START > BEGV. It can happen that we are called with
16076 PT somewhere between BEGV and START. Try to handle that case. */
16077 if (w
->cursor
.vpos
< 0)
16079 struct glyph_row
*row
= w
->current_matrix
->rows
;
16080 if (row
->mode_line_p
)
16082 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
16085 if (!cursor_row_fully_visible_p (w
, 0, 0))
16087 /* If vscroll is enabled, disable it and try again. */
16091 clear_glyph_matrix (w
->desired_matrix
);
16095 /* Users who set scroll-conservatively to a large number want
16096 point just above/below the scroll margin. If we ended up
16097 with point's row partially visible, move the window start to
16098 make that row fully visible and out of the margin. */
16099 if (scroll_conservatively
> SCROLL_LIMIT
)
16101 int window_total_lines
16102 = WINDOW_TOTAL_LINES (w
) * FRAME_LINE_HEIGHT (f
) * frame_line_height
;
16105 ? min (scroll_margin
, window_total_lines
/ 4)
16107 int move_down
= w
->cursor
.vpos
>= window_total_lines
/ 2;
16109 move_it_by_lines (&it
, move_down
? margin
+ 1 : -(margin
+ 1));
16110 clear_glyph_matrix (w
->desired_matrix
);
16111 if (1 == try_window (window
, it
.current
.pos
,
16112 TRY_WINDOW_CHECK_MARGINS
))
16116 /* If centering point failed to make the whole line visible,
16117 put point at the top instead. That has to make the whole line
16118 visible, if it can be done. */
16119 if (centering_position
== 0)
16122 clear_glyph_matrix (w
->desired_matrix
);
16123 centering_position
= 0;
16129 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
16130 w
->start_at_line_beg
= (CHARPOS (startp
) == BEGV
16131 || FETCH_BYTE (BYTEPOS (startp
) - 1) == '\n');
16133 /* Display the mode line, if we must. */
16134 if ((update_mode_line
16135 /* If window not full width, must redo its mode line
16136 if (a) the window to its side is being redone and
16137 (b) we do a frame-based redisplay. This is a consequence
16138 of how inverted lines are drawn in frame-based redisplay. */
16139 || (!just_this_one_p
16140 && !FRAME_WINDOW_P (f
)
16141 && !WINDOW_FULL_WIDTH_P (w
))
16142 /* Line number to display. */
16143 || w
->base_line_pos
> 0
16144 /* Column number is displayed and different from the one displayed. */
16145 || (w
->column_number_displayed
!= -1
16146 && (w
->column_number_displayed
!= current_column ())))
16147 /* This means that the window has a mode line. */
16148 && (WINDOW_WANTS_MODELINE_P (w
)
16149 || WINDOW_WANTS_HEADER_LINE_P (w
)))
16151 display_mode_lines (w
);
16153 /* If mode line height has changed, arrange for a thorough
16154 immediate redisplay using the correct mode line height. */
16155 if (WINDOW_WANTS_MODELINE_P (w
)
16156 && CURRENT_MODE_LINE_HEIGHT (w
) != DESIRED_MODE_LINE_HEIGHT (w
))
16158 f
->fonts_changed
= 1;
16159 w
->mode_line_height
= -1;
16160 MATRIX_MODE_LINE_ROW (w
->current_matrix
)->height
16161 = DESIRED_MODE_LINE_HEIGHT (w
);
16164 /* If header line height has changed, arrange for a thorough
16165 immediate redisplay using the correct header line height. */
16166 if (WINDOW_WANTS_HEADER_LINE_P (w
)
16167 && CURRENT_HEADER_LINE_HEIGHT (w
) != DESIRED_HEADER_LINE_HEIGHT (w
))
16169 f
->fonts_changed
= 1;
16170 w
->header_line_height
= -1;
16171 MATRIX_HEADER_LINE_ROW (w
->current_matrix
)->height
16172 = DESIRED_HEADER_LINE_HEIGHT (w
);
16175 if (f
->fonts_changed
)
16176 goto need_larger_matrices
;
16179 if (!line_number_displayed
&& w
->base_line_pos
!= -1)
16181 w
->base_line_pos
= 0;
16182 w
->base_line_number
= 0;
16187 /* When we reach a frame's selected window, redo the frame's menu bar. */
16188 if (update_mode_line
16189 && EQ (FRAME_SELECTED_WINDOW (f
), window
))
16191 int redisplay_menu_p
= 0;
16193 if (FRAME_WINDOW_P (f
))
16195 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
16196 || defined (HAVE_NS) || defined (USE_GTK)
16197 redisplay_menu_p
= FRAME_EXTERNAL_MENU_BAR (f
);
16199 redisplay_menu_p
= FRAME_MENU_BAR_LINES (f
) > 0;
16203 redisplay_menu_p
= FRAME_MENU_BAR_LINES (f
) > 0;
16205 if (redisplay_menu_p
)
16206 display_menu_bar (w
);
16208 #ifdef HAVE_WINDOW_SYSTEM
16209 if (FRAME_WINDOW_P (f
))
16211 #if defined (USE_GTK) || defined (HAVE_NS)
16212 if (FRAME_EXTERNAL_TOOL_BAR (f
))
16213 redisplay_tool_bar (f
);
16215 if (WINDOWP (f
->tool_bar_window
)
16216 && (FRAME_TOOL_BAR_LINES (f
) > 0
16217 || !NILP (Vauto_resize_tool_bars
))
16218 && redisplay_tool_bar (f
))
16219 ignore_mouse_drag_p
= 1;
16225 #ifdef HAVE_WINDOW_SYSTEM
16226 if (FRAME_WINDOW_P (f
)
16227 && update_window_fringes (w
, (just_this_one_p
16228 || (!used_current_matrix_p
&& !overlay_arrow_seen
)
16229 || w
->pseudo_window_p
)))
16233 if (draw_window_fringes (w
, 1))
16234 x_draw_vertical_border (w
);
16238 #endif /* HAVE_WINDOW_SYSTEM */
16240 /* We go to this label, with fonts_changed set, if it is
16241 necessary to try again using larger glyph matrices.
16242 We have to redeem the scroll bar even in this case,
16243 because the loop in redisplay_internal expects that. */
16244 need_larger_matrices
:
16246 finish_scroll_bars
:
16248 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w
))
16250 /* Set the thumb's position and size. */
16251 set_vertical_scroll_bar (w
);
16253 /* Note that we actually used the scroll bar attached to this
16254 window, so it shouldn't be deleted at the end of redisplay. */
16255 if (FRAME_TERMINAL (f
)->redeem_scroll_bar_hook
)
16256 (*FRAME_TERMINAL (f
)->redeem_scroll_bar_hook
) (w
);
16259 /* Restore current_buffer and value of point in it. The window
16260 update may have changed the buffer, so first make sure `opoint'
16261 is still valid (Bug#6177). */
16262 if (CHARPOS (opoint
) < BEGV
)
16263 TEMP_SET_PT_BOTH (BEGV
, BEGV_BYTE
);
16264 else if (CHARPOS (opoint
) > ZV
)
16265 TEMP_SET_PT_BOTH (Z
, Z_BYTE
);
16267 TEMP_SET_PT_BOTH (CHARPOS (opoint
), BYTEPOS (opoint
));
16269 set_buffer_internal_1 (old
);
16270 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
16271 shorter. This can be caused by log truncation in *Messages*. */
16272 if (CHARPOS (lpoint
) <= ZV
)
16273 TEMP_SET_PT_BOTH (CHARPOS (lpoint
), BYTEPOS (lpoint
));
16275 unbind_to (count
, Qnil
);
16279 /* Build the complete desired matrix of WINDOW with a window start
16280 buffer position POS.
16282 Value is 1 if successful. It is zero if fonts were loaded during
16283 redisplay which makes re-adjusting glyph matrices necessary, and -1
16284 if point would appear in the scroll margins.
16285 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
16286 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
16290 try_window (Lisp_Object window
, struct text_pos pos
, int flags
)
16292 struct window
*w
= XWINDOW (window
);
16294 struct glyph_row
*last_text_row
= NULL
;
16295 struct frame
*f
= XFRAME (w
->frame
);
16296 int frame_line_height
= default_line_pixel_height (w
);
16298 /* Make POS the new window start. */
16299 set_marker_both (w
->start
, Qnil
, CHARPOS (pos
), BYTEPOS (pos
));
16301 /* Mark cursor position as unknown. No overlay arrow seen. */
16302 w
->cursor
.vpos
= -1;
16303 overlay_arrow_seen
= 0;
16305 /* Initialize iterator and info to start at POS. */
16306 start_display (&it
, w
, pos
);
16308 /* Display all lines of W. */
16309 while (it
.current_y
< it
.last_visible_y
)
16311 if (display_line (&it
))
16312 last_text_row
= it
.glyph_row
- 1;
16313 if (f
->fonts_changed
&& !(flags
& TRY_WINDOW_IGNORE_FONTS_CHANGE
))
16317 /* Don't let the cursor end in the scroll margins. */
16318 if ((flags
& TRY_WINDOW_CHECK_MARGINS
)
16319 && !MINI_WINDOW_P (w
))
16321 int this_scroll_margin
;
16322 int window_total_lines
16323 = WINDOW_TOTAL_LINES (w
) * FRAME_LINE_HEIGHT (f
) / frame_line_height
;
16325 if (scroll_margin
> 0)
16327 this_scroll_margin
= min (scroll_margin
, window_total_lines
/ 4);
16328 this_scroll_margin
*= frame_line_height
;
16331 this_scroll_margin
= 0;
16333 if ((w
->cursor
.y
>= 0 /* not vscrolled */
16334 && w
->cursor
.y
< this_scroll_margin
16335 && CHARPOS (pos
) > BEGV
16336 && IT_CHARPOS (it
) < ZV
)
16337 /* rms: considering make_cursor_line_fully_visible_p here
16338 seems to give wrong results. We don't want to recenter
16339 when the last line is partly visible, we want to allow
16340 that case to be handled in the usual way. */
16341 || w
->cursor
.y
> it
.last_visible_y
- this_scroll_margin
- 1)
16343 w
->cursor
.vpos
= -1;
16344 clear_glyph_matrix (w
->desired_matrix
);
16349 /* If bottom moved off end of frame, change mode line percentage. */
16350 if (w
->window_end_pos
<= 0 && Z
!= IT_CHARPOS (it
))
16351 w
->update_mode_line
= 1;
16353 /* Set window_end_pos to the offset of the last character displayed
16354 on the window from the end of current_buffer. Set
16355 window_end_vpos to its row number. */
16358 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row
));
16359 adjust_window_ends (w
, last_text_row
, 0);
16361 (MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w
->desired_matrix
,
16362 w
->window_end_vpos
)));
16366 w
->window_end_bytepos
= Z_BYTE
- ZV_BYTE
;
16367 w
->window_end_pos
= Z
- ZV
;
16368 w
->window_end_vpos
= 0;
16371 /* But that is not valid info until redisplay finishes. */
16372 w
->window_end_valid
= 0;
16378 /************************************************************************
16379 Window redisplay reusing current matrix when buffer has not changed
16380 ************************************************************************/
16382 /* Try redisplay of window W showing an unchanged buffer with a
16383 different window start than the last time it was displayed by
16384 reusing its current matrix. Value is non-zero if successful.
16385 W->start is the new window start. */
16388 try_window_reusing_current_matrix (struct window
*w
)
16390 struct frame
*f
= XFRAME (w
->frame
);
16391 struct glyph_row
*bottom_row
;
16394 struct text_pos start
, new_start
;
16395 int nrows_scrolled
, i
;
16396 struct glyph_row
*last_text_row
;
16397 struct glyph_row
*last_reused_text_row
;
16398 struct glyph_row
*start_row
;
16399 int start_vpos
, min_y
, max_y
;
16402 if (inhibit_try_window_reusing
)
16406 if (/* This function doesn't handle terminal frames. */
16407 !FRAME_WINDOW_P (f
)
16408 /* Don't try to reuse the display if windows have been split
16410 || windows_or_buffers_changed
16411 || f
->cursor_type_changed
)
16414 /* Can't do this if showing trailing whitespace. */
16415 if (!NILP (Vshow_trailing_whitespace
))
16418 /* If top-line visibility has changed, give up. */
16419 if (WINDOW_WANTS_HEADER_LINE_P (w
)
16420 != MATRIX_HEADER_LINE_ROW (w
->current_matrix
)->mode_line_p
)
16423 /* Give up if old or new display is scrolled vertically. We could
16424 make this function handle this, but right now it doesn't. */
16425 start_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
16426 if (w
->vscroll
|| MATRIX_ROW_PARTIALLY_VISIBLE_P (w
, start_row
))
16429 /* The variable new_start now holds the new window start. The old
16430 start `start' can be determined from the current matrix. */
16431 SET_TEXT_POS_FROM_MARKER (new_start
, w
->start
);
16432 start
= start_row
->minpos
;
16433 start_vpos
= MATRIX_ROW_VPOS (start_row
, w
->current_matrix
);
16435 /* Clear the desired matrix for the display below. */
16436 clear_glyph_matrix (w
->desired_matrix
);
16438 if (CHARPOS (new_start
) <= CHARPOS (start
))
16440 /* Don't use this method if the display starts with an ellipsis
16441 displayed for invisible text. It's not easy to handle that case
16442 below, and it's certainly not worth the effort since this is
16443 not a frequent case. */
16444 if (in_ellipses_for_invisible_text_p (&start_row
->start
, w
))
16447 IF_DEBUG (debug_method_add (w
, "twu1"));
16449 /* Display up to a row that can be reused. The variable
16450 last_text_row is set to the last row displayed that displays
16451 text. Note that it.vpos == 0 if or if not there is a
16452 header-line; it's not the same as the MATRIX_ROW_VPOS! */
16453 start_display (&it
, w
, new_start
);
16454 w
->cursor
.vpos
= -1;
16455 last_text_row
= last_reused_text_row
= NULL
;
16457 while (it
.current_y
< it
.last_visible_y
&& !f
->fonts_changed
)
16459 /* If we have reached into the characters in the START row,
16460 that means the line boundaries have changed. So we
16461 can't start copying with the row START. Maybe it will
16462 work to start copying with the following row. */
16463 while (IT_CHARPOS (it
) > CHARPOS (start
))
16465 /* Advance to the next row as the "start". */
16467 start
= start_row
->minpos
;
16468 /* If there are no more rows to try, or just one, give up. */
16469 if (start_row
== MATRIX_MODE_LINE_ROW (w
->current_matrix
) - 1
16470 || w
->vscroll
|| MATRIX_ROW_PARTIALLY_VISIBLE_P (w
, start_row
)
16471 || CHARPOS (start
) == ZV
)
16473 clear_glyph_matrix (w
->desired_matrix
);
16477 start_vpos
= MATRIX_ROW_VPOS (start_row
, w
->current_matrix
);
16479 /* If we have reached alignment, we can copy the rest of the
16481 if (IT_CHARPOS (it
) == CHARPOS (start
)
16482 /* Don't accept "alignment" inside a display vector,
16483 since start_row could have started in the middle of
16484 that same display vector (thus their character
16485 positions match), and we have no way of telling if
16486 that is the case. */
16487 && it
.current
.dpvec_index
< 0)
16490 if (display_line (&it
))
16491 last_text_row
= it
.glyph_row
- 1;
16495 /* A value of current_y < last_visible_y means that we stopped
16496 at the previous window start, which in turn means that we
16497 have at least one reusable row. */
16498 if (it
.current_y
< it
.last_visible_y
)
16500 struct glyph_row
*row
;
16502 /* IT.vpos always starts from 0; it counts text lines. */
16503 nrows_scrolled
= it
.vpos
- (start_row
- MATRIX_FIRST_TEXT_ROW (w
->current_matrix
));
16505 /* Find PT if not already found in the lines displayed. */
16506 if (w
->cursor
.vpos
< 0)
16508 int dy
= it
.current_y
- start_row
->y
;
16510 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
16511 row
= row_containing_pos (w
, PT
, row
, NULL
, dy
);
16513 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0,
16514 dy
, nrows_scrolled
);
16517 clear_glyph_matrix (w
->desired_matrix
);
16522 /* Scroll the display. Do it before the current matrix is
16523 changed. The problem here is that update has not yet
16524 run, i.e. part of the current matrix is not up to date.
16525 scroll_run_hook will clear the cursor, and use the
16526 current matrix to get the height of the row the cursor is
16528 run
.current_y
= start_row
->y
;
16529 run
.desired_y
= it
.current_y
;
16530 run
.height
= it
.last_visible_y
- it
.current_y
;
16532 if (run
.height
> 0 && run
.current_y
!= run
.desired_y
)
16535 FRAME_RIF (f
)->update_window_begin_hook (w
);
16536 FRAME_RIF (f
)->clear_window_mouse_face (w
);
16537 FRAME_RIF (f
)->scroll_run_hook (w
, &run
);
16538 FRAME_RIF (f
)->update_window_end_hook (w
, 0, 0);
16542 /* Shift current matrix down by nrows_scrolled lines. */
16543 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
16544 rotate_matrix (w
->current_matrix
,
16546 MATRIX_ROW_VPOS (bottom_row
, w
->current_matrix
),
16549 /* Disable lines that must be updated. */
16550 for (i
= 0; i
< nrows_scrolled
; ++i
)
16551 (start_row
+ i
)->enabled_p
= 0;
16553 /* Re-compute Y positions. */
16554 min_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
16555 max_y
= it
.last_visible_y
;
16556 for (row
= start_row
+ nrows_scrolled
;
16560 row
->y
= it
.current_y
;
16561 row
->visible_height
= row
->height
;
16563 if (row
->y
< min_y
)
16564 row
->visible_height
-= min_y
- row
->y
;
16565 if (row
->y
+ row
->height
> max_y
)
16566 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
16567 if (row
->fringe_bitmap_periodic_p
)
16568 row
->redraw_fringe_bitmaps_p
= 1;
16570 it
.current_y
+= row
->height
;
16572 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
16573 last_reused_text_row
= row
;
16574 if (MATRIX_ROW_BOTTOM_Y (row
) >= it
.last_visible_y
)
16578 /* Disable lines in the current matrix which are now
16579 below the window. */
16580 for (++row
; row
< bottom_row
; ++row
)
16581 row
->enabled_p
= row
->mode_line_p
= 0;
16584 /* Update window_end_pos etc.; last_reused_text_row is the last
16585 reused row from the current matrix containing text, if any.
16586 The value of last_text_row is the last displayed line
16587 containing text. */
16588 if (last_reused_text_row
)
16589 adjust_window_ends (w
, last_reused_text_row
, 1);
16590 else if (last_text_row
)
16591 adjust_window_ends (w
, last_text_row
, 0);
16594 /* This window must be completely empty. */
16595 w
->window_end_bytepos
= Z_BYTE
- ZV_BYTE
;
16596 w
->window_end_pos
= Z
- ZV
;
16597 w
->window_end_vpos
= 0;
16599 w
->window_end_valid
= 0;
16601 /* Update hint: don't try scrolling again in update_window. */
16602 w
->desired_matrix
->no_scrolling_p
= 1;
16605 debug_method_add (w
, "try_window_reusing_current_matrix 1");
16609 else if (CHARPOS (new_start
) > CHARPOS (start
))
16611 struct glyph_row
*pt_row
, *row
;
16612 struct glyph_row
*first_reusable_row
;
16613 struct glyph_row
*first_row_to_display
;
16615 int yb
= window_text_bottom_y (w
);
16617 /* Find the row starting at new_start, if there is one. Don't
16618 reuse a partially visible line at the end. */
16619 first_reusable_row
= start_row
;
16620 while (first_reusable_row
->enabled_p
16621 && MATRIX_ROW_BOTTOM_Y (first_reusable_row
) < yb
16622 && (MATRIX_ROW_START_CHARPOS (first_reusable_row
)
16623 < CHARPOS (new_start
)))
16624 ++first_reusable_row
;
16626 /* Give up if there is no row to reuse. */
16627 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row
) >= yb
16628 || !first_reusable_row
->enabled_p
16629 || (MATRIX_ROW_START_CHARPOS (first_reusable_row
)
16630 != CHARPOS (new_start
)))
16633 /* We can reuse fully visible rows beginning with
16634 first_reusable_row to the end of the window. Set
16635 first_row_to_display to the first row that cannot be reused.
16636 Set pt_row to the row containing point, if there is any. */
16638 for (first_row_to_display
= first_reusable_row
;
16639 MATRIX_ROW_BOTTOM_Y (first_row_to_display
) < yb
;
16640 ++first_row_to_display
)
16642 if (PT
>= MATRIX_ROW_START_CHARPOS (first_row_to_display
)
16643 && (PT
< MATRIX_ROW_END_CHARPOS (first_row_to_display
)
16644 || (PT
== MATRIX_ROW_END_CHARPOS (first_row_to_display
)
16645 && first_row_to_display
->ends_at_zv_p
16646 && pt_row
== NULL
)))
16647 pt_row
= first_row_to_display
;
16650 /* Start displaying at the start of first_row_to_display. */
16651 eassert (first_row_to_display
->y
< yb
);
16652 init_to_row_start (&it
, w
, first_row_to_display
);
16654 nrows_scrolled
= (MATRIX_ROW_VPOS (first_reusable_row
, w
->current_matrix
)
16656 it
.vpos
= (MATRIX_ROW_VPOS (first_row_to_display
, w
->current_matrix
)
16658 it
.current_y
= (first_row_to_display
->y
- first_reusable_row
->y
16659 + WINDOW_HEADER_LINE_HEIGHT (w
));
16661 /* Display lines beginning with first_row_to_display in the
16662 desired matrix. Set last_text_row to the last row displayed
16663 that displays text. */
16664 it
.glyph_row
= MATRIX_ROW (w
->desired_matrix
, it
.vpos
);
16665 if (pt_row
== NULL
)
16666 w
->cursor
.vpos
= -1;
16667 last_text_row
= NULL
;
16668 while (it
.current_y
< it
.last_visible_y
&& !f
->fonts_changed
)
16669 if (display_line (&it
))
16670 last_text_row
= it
.glyph_row
- 1;
16672 /* If point is in a reused row, adjust y and vpos of the cursor
16676 w
->cursor
.vpos
-= nrows_scrolled
;
16677 w
->cursor
.y
-= first_reusable_row
->y
- start_row
->y
;
16680 /* Give up if point isn't in a row displayed or reused. (This
16681 also handles the case where w->cursor.vpos < nrows_scrolled
16682 after the calls to display_line, which can happen with scroll
16683 margins. See bug#1295.) */
16684 if (w
->cursor
.vpos
< 0)
16686 clear_glyph_matrix (w
->desired_matrix
);
16690 /* Scroll the display. */
16691 run
.current_y
= first_reusable_row
->y
;
16692 run
.desired_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
16693 run
.height
= it
.last_visible_y
- run
.current_y
;
16694 dy
= run
.current_y
- run
.desired_y
;
16699 FRAME_RIF (f
)->update_window_begin_hook (w
);
16700 FRAME_RIF (f
)->clear_window_mouse_face (w
);
16701 FRAME_RIF (f
)->scroll_run_hook (w
, &run
);
16702 FRAME_RIF (f
)->update_window_end_hook (w
, 0, 0);
16706 /* Adjust Y positions of reused rows. */
16707 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
16708 min_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
16709 max_y
= it
.last_visible_y
;
16710 for (row
= first_reusable_row
; row
< first_row_to_display
; ++row
)
16713 row
->visible_height
= row
->height
;
16714 if (row
->y
< min_y
)
16715 row
->visible_height
-= min_y
- row
->y
;
16716 if (row
->y
+ row
->height
> max_y
)
16717 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
16718 if (row
->fringe_bitmap_periodic_p
)
16719 row
->redraw_fringe_bitmaps_p
= 1;
16722 /* Scroll the current matrix. */
16723 eassert (nrows_scrolled
> 0);
16724 rotate_matrix (w
->current_matrix
,
16726 MATRIX_ROW_VPOS (bottom_row
, w
->current_matrix
),
16729 /* Disable rows not reused. */
16730 for (row
-= nrows_scrolled
; row
< bottom_row
; ++row
)
16731 row
->enabled_p
= 0;
16733 /* Point may have moved to a different line, so we cannot assume that
16734 the previous cursor position is valid; locate the correct row. */
16737 for (row
= MATRIX_ROW (w
->current_matrix
, w
->cursor
.vpos
);
16739 && PT
>= MATRIX_ROW_END_CHARPOS (row
)
16740 && !row
->ends_at_zv_p
;
16744 w
->cursor
.y
= row
->y
;
16746 if (row
< bottom_row
)
16748 /* Can't simply scan the row for point with
16749 bidi-reordered glyph rows. Let set_cursor_from_row
16750 figure out where to put the cursor, and if it fails,
16752 if (!NILP (BVAR (XBUFFER (w
->contents
), bidi_display_reordering
)))
16754 if (!set_cursor_from_row (w
, row
, w
->current_matrix
,
16757 clear_glyph_matrix (w
->desired_matrix
);
16763 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + w
->cursor
.hpos
;
16764 struct glyph
*end
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
];
16767 && (!BUFFERP (glyph
->object
)
16768 || glyph
->charpos
< PT
);
16772 w
->cursor
.x
+= glyph
->pixel_width
;
16778 /* Adjust window end. A null value of last_text_row means that
16779 the window end is in reused rows which in turn means that
16780 only its vpos can have changed. */
16782 adjust_window_ends (w
, last_text_row
, 0);
16784 w
->window_end_vpos
-= nrows_scrolled
;
16786 w
->window_end_valid
= 0;
16787 w
->desired_matrix
->no_scrolling_p
= 1;
16790 debug_method_add (w
, "try_window_reusing_current_matrix 2");
16800 /************************************************************************
16801 Window redisplay reusing current matrix when buffer has changed
16802 ************************************************************************/
16804 static struct glyph_row
*find_last_unchanged_at_beg_row (struct window
*);
16805 static struct glyph_row
*find_first_unchanged_at_end_row (struct window
*,
16806 ptrdiff_t *, ptrdiff_t *);
16807 static struct glyph_row
*
16808 find_last_row_displaying_text (struct glyph_matrix
*, struct it
*,
16809 struct glyph_row
*);
16812 /* Return the last row in MATRIX displaying text. If row START is
16813 non-null, start searching with that row. IT gives the dimensions
16814 of the display. Value is null if matrix is empty; otherwise it is
16815 a pointer to the row found. */
16817 static struct glyph_row
*
16818 find_last_row_displaying_text (struct glyph_matrix
*matrix
, struct it
*it
,
16819 struct glyph_row
*start
)
16821 struct glyph_row
*row
, *row_found
;
16823 /* Set row_found to the last row in IT->w's current matrix
16824 displaying text. The loop looks funny but think of partially
16827 row
= start
? start
: MATRIX_FIRST_TEXT_ROW (matrix
);
16828 while (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
16830 eassert (row
->enabled_p
);
16832 if (MATRIX_ROW_BOTTOM_Y (row
) >= it
->last_visible_y
)
16841 /* Return the last row in the current matrix of W that is not affected
16842 by changes at the start of current_buffer that occurred since W's
16843 current matrix was built. Value is null if no such row exists.
16845 BEG_UNCHANGED us the number of characters unchanged at the start of
16846 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
16847 first changed character in current_buffer. Characters at positions <
16848 BEG + BEG_UNCHANGED are at the same buffer positions as they were
16849 when the current matrix was built. */
16851 static struct glyph_row
*
16852 find_last_unchanged_at_beg_row (struct window
*w
)
16854 ptrdiff_t first_changed_pos
= BEG
+ BEG_UNCHANGED
;
16855 struct glyph_row
*row
;
16856 struct glyph_row
*row_found
= NULL
;
16857 int yb
= window_text_bottom_y (w
);
16859 /* Find the last row displaying unchanged text. */
16860 for (row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
16861 MATRIX_ROW_DISPLAYS_TEXT_P (row
)
16862 && MATRIX_ROW_START_CHARPOS (row
) < first_changed_pos
;
16865 if (/* If row ends before first_changed_pos, it is unchanged,
16866 except in some case. */
16867 MATRIX_ROW_END_CHARPOS (row
) <= first_changed_pos
16868 /* When row ends in ZV and we write at ZV it is not
16870 && !row
->ends_at_zv_p
16871 /* When first_changed_pos is the end of a continued line,
16872 row is not unchanged because it may be no longer
16874 && !(MATRIX_ROW_END_CHARPOS (row
) == first_changed_pos
16875 && (row
->continued_p
16876 || row
->exact_window_width_line_p
))
16877 /* If ROW->end is beyond ZV, then ROW->end is outdated and
16878 needs to be recomputed, so don't consider this row as
16879 unchanged. This happens when the last line was
16880 bidi-reordered and was killed immediately before this
16881 redisplay cycle. In that case, ROW->end stores the
16882 buffer position of the first visual-order character of
16883 the killed text, which is now beyond ZV. */
16884 && CHARPOS (row
->end
.pos
) <= ZV
)
16887 /* Stop if last visible row. */
16888 if (MATRIX_ROW_BOTTOM_Y (row
) >= yb
)
16896 /* Find the first glyph row in the current matrix of W that is not
16897 affected by changes at the end of current_buffer since the
16898 time W's current matrix was built.
16900 Return in *DELTA the number of chars by which buffer positions in
16901 unchanged text at the end of current_buffer must be adjusted.
16903 Return in *DELTA_BYTES the corresponding number of bytes.
16905 Value is null if no such row exists, i.e. all rows are affected by
16908 static struct glyph_row
*
16909 find_first_unchanged_at_end_row (struct window
*w
,
16910 ptrdiff_t *delta
, ptrdiff_t *delta_bytes
)
16912 struct glyph_row
*row
;
16913 struct glyph_row
*row_found
= NULL
;
16915 *delta
= *delta_bytes
= 0;
16917 /* Display must not have been paused, otherwise the current matrix
16918 is not up to date. */
16919 eassert (w
->window_end_valid
);
16921 /* A value of window_end_pos >= END_UNCHANGED means that the window
16922 end is in the range of changed text. If so, there is no
16923 unchanged row at the end of W's current matrix. */
16924 if (w
->window_end_pos
>= END_UNCHANGED
)
16927 /* Set row to the last row in W's current matrix displaying text. */
16928 row
= MATRIX_ROW (w
->current_matrix
, w
->window_end_vpos
);
16930 /* If matrix is entirely empty, no unchanged row exists. */
16931 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
16933 /* The value of row is the last glyph row in the matrix having a
16934 meaningful buffer position in it. The end position of row
16935 corresponds to window_end_pos. This allows us to translate
16936 buffer positions in the current matrix to current buffer
16937 positions for characters not in changed text. */
16939 MATRIX_ROW_END_CHARPOS (row
) + w
->window_end_pos
;
16940 ptrdiff_t Z_BYTE_old
=
16941 MATRIX_ROW_END_BYTEPOS (row
) + w
->window_end_bytepos
;
16942 ptrdiff_t last_unchanged_pos
, last_unchanged_pos_old
;
16943 struct glyph_row
*first_text_row
16944 = MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
16946 *delta
= Z
- Z_old
;
16947 *delta_bytes
= Z_BYTE
- Z_BYTE_old
;
16949 /* Set last_unchanged_pos to the buffer position of the last
16950 character in the buffer that has not been changed. Z is the
16951 index + 1 of the last character in current_buffer, i.e. by
16952 subtracting END_UNCHANGED we get the index of the last
16953 unchanged character, and we have to add BEG to get its buffer
16955 last_unchanged_pos
= Z
- END_UNCHANGED
+ BEG
;
16956 last_unchanged_pos_old
= last_unchanged_pos
- *delta
;
16958 /* Search backward from ROW for a row displaying a line that
16959 starts at a minimum position >= last_unchanged_pos_old. */
16960 for (; row
> first_text_row
; --row
)
16962 /* This used to abort, but it can happen.
16963 It is ok to just stop the search instead here. KFS. */
16964 if (!row
->enabled_p
|| !MATRIX_ROW_DISPLAYS_TEXT_P (row
))
16967 if (MATRIX_ROW_START_CHARPOS (row
) >= last_unchanged_pos_old
)
16972 eassert (!row_found
|| MATRIX_ROW_DISPLAYS_TEXT_P (row_found
));
16978 /* Make sure that glyph rows in the current matrix of window W
16979 reference the same glyph memory as corresponding rows in the
16980 frame's frame matrix. This function is called after scrolling W's
16981 current matrix on a terminal frame in try_window_id and
16982 try_window_reusing_current_matrix. */
16985 sync_frame_with_window_matrix_rows (struct window
*w
)
16987 struct frame
*f
= XFRAME (w
->frame
);
16988 struct glyph_row
*window_row
, *window_row_end
, *frame_row
;
16990 /* Preconditions: W must be a leaf window and full-width. Its frame
16991 must have a frame matrix. */
16992 eassert (BUFFERP (w
->contents
));
16993 eassert (WINDOW_FULL_WIDTH_P (w
));
16994 eassert (!FRAME_WINDOW_P (f
));
16996 /* If W is a full-width window, glyph pointers in W's current matrix
16997 have, by definition, to be the same as glyph pointers in the
16998 corresponding frame matrix. Note that frame matrices have no
16999 marginal areas (see build_frame_matrix). */
17000 window_row
= w
->current_matrix
->rows
;
17001 window_row_end
= window_row
+ w
->current_matrix
->nrows
;
17002 frame_row
= f
->current_matrix
->rows
+ WINDOW_TOP_EDGE_LINE (w
);
17003 while (window_row
< window_row_end
)
17005 struct glyph
*start
= window_row
->glyphs
[LEFT_MARGIN_AREA
];
17006 struct glyph
*end
= window_row
->glyphs
[LAST_AREA
];
17008 frame_row
->glyphs
[LEFT_MARGIN_AREA
] = start
;
17009 frame_row
->glyphs
[TEXT_AREA
] = start
;
17010 frame_row
->glyphs
[RIGHT_MARGIN_AREA
] = end
;
17011 frame_row
->glyphs
[LAST_AREA
] = end
;
17013 /* Disable frame rows whose corresponding window rows have
17014 been disabled in try_window_id. */
17015 if (!window_row
->enabled_p
)
17016 frame_row
->enabled_p
= 0;
17018 ++window_row
, ++frame_row
;
17023 /* Find the glyph row in window W containing CHARPOS. Consider all
17024 rows between START and END (not inclusive). END null means search
17025 all rows to the end of the display area of W. Value is the row
17026 containing CHARPOS or null. */
17029 row_containing_pos (struct window
*w
, ptrdiff_t charpos
,
17030 struct glyph_row
*start
, struct glyph_row
*end
, int dy
)
17032 struct glyph_row
*row
= start
;
17033 struct glyph_row
*best_row
= NULL
;
17034 ptrdiff_t mindif
= BUF_ZV (XBUFFER (w
->contents
)) + 1;
17037 /* If we happen to start on a header-line, skip that. */
17038 if (row
->mode_line_p
)
17041 if ((end
&& row
>= end
) || !row
->enabled_p
)
17044 last_y
= window_text_bottom_y (w
) - dy
;
17048 /* Give up if we have gone too far. */
17049 if (end
&& row
>= end
)
17051 /* This formerly returned if they were equal.
17052 I think that both quantities are of a "last plus one" type;
17053 if so, when they are equal, the row is within the screen. -- rms. */
17054 if (MATRIX_ROW_BOTTOM_Y (row
) > last_y
)
17057 /* If it is in this row, return this row. */
17058 if (! (MATRIX_ROW_END_CHARPOS (row
) < charpos
17059 || (MATRIX_ROW_END_CHARPOS (row
) == charpos
17060 /* The end position of a row equals the start
17061 position of the next row. If CHARPOS is there, we
17062 would rather consider it displayed in the next
17063 line, except when this line ends in ZV. */
17064 && !row_for_charpos_p (row
, charpos
)))
17065 && charpos
>= MATRIX_ROW_START_CHARPOS (row
))
17069 if (NILP (BVAR (XBUFFER (w
->contents
), bidi_display_reordering
))
17070 || (!best_row
&& !row
->continued_p
))
17072 /* In bidi-reordered rows, there could be several rows whose
17073 edges surround CHARPOS, all of these rows belonging to
17074 the same continued line. We need to find the row which
17075 fits CHARPOS the best. */
17076 for (g
= row
->glyphs
[TEXT_AREA
];
17077 g
< row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
];
17080 if (!STRINGP (g
->object
))
17082 if (g
->charpos
> 0 && eabs (g
->charpos
- charpos
) < mindif
)
17084 mindif
= eabs (g
->charpos
- charpos
);
17086 /* Exact match always wins. */
17093 else if (best_row
&& !row
->continued_p
)
17100 /* Try to redisplay window W by reusing its existing display. W's
17101 current matrix must be up to date when this function is called,
17102 i.e. window_end_valid must be nonzero.
17106 1 if display has been updated
17107 0 if otherwise unsuccessful
17108 -1 if redisplay with same window start is known not to succeed
17110 The following steps are performed:
17112 1. Find the last row in the current matrix of W that is not
17113 affected by changes at the start of current_buffer. If no such row
17116 2. Find the first row in W's current matrix that is not affected by
17117 changes at the end of current_buffer. Maybe there is no such row.
17119 3. Display lines beginning with the row + 1 found in step 1 to the
17120 row found in step 2 or, if step 2 didn't find a row, to the end of
17123 4. If cursor is not known to appear on the window, give up.
17125 5. If display stopped at the row found in step 2, scroll the
17126 display and current matrix as needed.
17128 6. Maybe display some lines at the end of W, if we must. This can
17129 happen under various circumstances, like a partially visible line
17130 becoming fully visible, or because newly displayed lines are displayed
17131 in smaller font sizes.
17133 7. Update W's window end information. */
17136 try_window_id (struct window
*w
)
17138 struct frame
*f
= XFRAME (w
->frame
);
17139 struct glyph_matrix
*current_matrix
= w
->current_matrix
;
17140 struct glyph_matrix
*desired_matrix
= w
->desired_matrix
;
17141 struct glyph_row
*last_unchanged_at_beg_row
;
17142 struct glyph_row
*first_unchanged_at_end_row
;
17143 struct glyph_row
*row
;
17144 struct glyph_row
*bottom_row
;
17147 ptrdiff_t delta
= 0, delta_bytes
= 0, stop_pos
;
17149 struct text_pos start_pos
;
17151 int first_unchanged_at_end_vpos
= 0;
17152 struct glyph_row
*last_text_row
, *last_text_row_at_end
;
17153 struct text_pos start
;
17154 ptrdiff_t first_changed_charpos
, last_changed_charpos
;
17157 if (inhibit_try_window_id
)
17161 /* This is handy for debugging. */
17163 #define GIVE_UP(X) \
17165 fprintf (stderr, "try_window_id give up %d\n", (X)); \
17169 #define GIVE_UP(X) return 0
17172 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
17174 /* Don't use this for mini-windows because these can show
17175 messages and mini-buffers, and we don't handle that here. */
17176 if (MINI_WINDOW_P (w
))
17179 /* This flag is used to prevent redisplay optimizations. */
17180 if (windows_or_buffers_changed
|| f
->cursor_type_changed
)
17183 /* Verify that narrowing has not changed.
17184 Also verify that we were not told to prevent redisplay optimizations.
17185 It would be nice to further
17186 reduce the number of cases where this prevents try_window_id. */
17187 if (current_buffer
->clip_changed
17188 || current_buffer
->prevent_redisplay_optimizations_p
)
17191 /* Window must either use window-based redisplay or be full width. */
17192 if (!FRAME_WINDOW_P (f
)
17193 && (!FRAME_LINE_INS_DEL_OK (f
)
17194 || !WINDOW_FULL_WIDTH_P (w
)))
17197 /* Give up if point is known NOT to appear in W. */
17198 if (PT
< CHARPOS (start
))
17201 /* Another way to prevent redisplay optimizations. */
17202 if (w
->last_modified
== 0)
17205 /* Verify that window is not hscrolled. */
17206 if (w
->hscroll
!= 0)
17209 /* Verify that display wasn't paused. */
17210 if (!w
->window_end_valid
)
17213 /* Likewise if highlighting trailing whitespace. */
17214 if (!NILP (Vshow_trailing_whitespace
))
17217 /* Can't use this if overlay arrow position and/or string have
17219 if (overlay_arrows_changed_p ())
17222 /* When word-wrap is on, adding a space to the first word of a
17223 wrapped line can change the wrap position, altering the line
17224 above it. It might be worthwhile to handle this more
17225 intelligently, but for now just redisplay from scratch. */
17226 if (!NILP (BVAR (XBUFFER (w
->contents
), word_wrap
)))
17229 /* Under bidi reordering, adding or deleting a character in the
17230 beginning of a paragraph, before the first strong directional
17231 character, can change the base direction of the paragraph (unless
17232 the buffer specifies a fixed paragraph direction), which will
17233 require to redisplay the whole paragraph. It might be worthwhile
17234 to find the paragraph limits and widen the range of redisplayed
17235 lines to that, but for now just give up this optimization and
17236 redisplay from scratch. */
17237 if (!NILP (BVAR (XBUFFER (w
->contents
), bidi_display_reordering
))
17238 && NILP (BVAR (XBUFFER (w
->contents
), bidi_paragraph_direction
)))
17241 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
17242 only if buffer has really changed. The reason is that the gap is
17243 initially at Z for freshly visited files. The code below would
17244 set end_unchanged to 0 in that case. */
17245 if (MODIFF
> SAVE_MODIFF
17246 /* This seems to happen sometimes after saving a buffer. */
17247 || BEG_UNCHANGED
+ END_UNCHANGED
> Z_BYTE
)
17249 if (GPT
- BEG
< BEG_UNCHANGED
)
17250 BEG_UNCHANGED
= GPT
- BEG
;
17251 if (Z
- GPT
< END_UNCHANGED
)
17252 END_UNCHANGED
= Z
- GPT
;
17255 /* The position of the first and last character that has been changed. */
17256 first_changed_charpos
= BEG
+ BEG_UNCHANGED
;
17257 last_changed_charpos
= Z
- END_UNCHANGED
;
17259 /* If window starts after a line end, and the last change is in
17260 front of that newline, then changes don't affect the display.
17261 This case happens with stealth-fontification. Note that although
17262 the display is unchanged, glyph positions in the matrix have to
17263 be adjusted, of course. */
17264 row
= MATRIX_ROW (w
->current_matrix
, w
->window_end_vpos
);
17265 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
)
17266 && ((last_changed_charpos
< CHARPOS (start
)
17267 && CHARPOS (start
) == BEGV
)
17268 || (last_changed_charpos
< CHARPOS (start
) - 1
17269 && FETCH_BYTE (BYTEPOS (start
) - 1) == '\n')))
17271 ptrdiff_t Z_old
, Z_delta
, Z_BYTE_old
, Z_delta_bytes
;
17272 struct glyph_row
*r0
;
17274 /* Compute how many chars/bytes have been added to or removed
17275 from the buffer. */
17276 Z_old
= MATRIX_ROW_END_CHARPOS (row
) + w
->window_end_pos
;
17277 Z_BYTE_old
= MATRIX_ROW_END_BYTEPOS (row
) + w
->window_end_bytepos
;
17278 Z_delta
= Z
- Z_old
;
17279 Z_delta_bytes
= Z_BYTE
- Z_BYTE_old
;
17281 /* Give up if PT is not in the window. Note that it already has
17282 been checked at the start of try_window_id that PT is not in
17283 front of the window start. */
17284 if (PT
>= MATRIX_ROW_END_CHARPOS (row
) + Z_delta
)
17287 /* If window start is unchanged, we can reuse the whole matrix
17288 as is, after adjusting glyph positions. No need to compute
17289 the window end again, since its offset from Z hasn't changed. */
17290 r0
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
17291 if (CHARPOS (start
) == MATRIX_ROW_START_CHARPOS (r0
) + Z_delta
17292 && BYTEPOS (start
) == MATRIX_ROW_START_BYTEPOS (r0
) + Z_delta_bytes
17293 /* PT must not be in a partially visible line. */
17294 && !(PT
>= MATRIX_ROW_START_CHARPOS (row
) + Z_delta
17295 && MATRIX_ROW_BOTTOM_Y (row
) > window_text_bottom_y (w
)))
17297 /* Adjust positions in the glyph matrix. */
17298 if (Z_delta
|| Z_delta_bytes
)
17300 struct glyph_row
*r1
17301 = MATRIX_BOTTOM_TEXT_ROW (current_matrix
, w
);
17302 increment_matrix_positions (w
->current_matrix
,
17303 MATRIX_ROW_VPOS (r0
, current_matrix
),
17304 MATRIX_ROW_VPOS (r1
, current_matrix
),
17305 Z_delta
, Z_delta_bytes
);
17308 /* Set the cursor. */
17309 row
= row_containing_pos (w
, PT
, r0
, NULL
, 0);
17311 set_cursor_from_row (w
, row
, current_matrix
, 0, 0, 0, 0);
17316 /* Handle the case that changes are all below what is displayed in
17317 the window, and that PT is in the window. This shortcut cannot
17318 be taken if ZV is visible in the window, and text has been added
17319 there that is visible in the window. */
17320 if (first_changed_charpos
>= MATRIX_ROW_END_CHARPOS (row
)
17321 /* ZV is not visible in the window, or there are no
17322 changes at ZV, actually. */
17323 && (current_matrix
->zv
> MATRIX_ROW_END_CHARPOS (row
)
17324 || first_changed_charpos
== last_changed_charpos
))
17326 struct glyph_row
*r0
;
17328 /* Give up if PT is not in the window. Note that it already has
17329 been checked at the start of try_window_id that PT is not in
17330 front of the window start. */
17331 if (PT
>= MATRIX_ROW_END_CHARPOS (row
))
17334 /* If window start is unchanged, we can reuse the whole matrix
17335 as is, without changing glyph positions since no text has
17336 been added/removed in front of the window end. */
17337 r0
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
17338 if (TEXT_POS_EQUAL_P (start
, r0
->minpos
)
17339 /* PT must not be in a partially visible line. */
17340 && !(PT
>= MATRIX_ROW_START_CHARPOS (row
)
17341 && MATRIX_ROW_BOTTOM_Y (row
) > window_text_bottom_y (w
)))
17343 /* We have to compute the window end anew since text
17344 could have been added/removed after it. */
17345 w
->window_end_pos
= Z
- MATRIX_ROW_END_CHARPOS (row
);
17346 w
->window_end_bytepos
= Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
17348 /* Set the cursor. */
17349 row
= row_containing_pos (w
, PT
, r0
, NULL
, 0);
17351 set_cursor_from_row (w
, row
, current_matrix
, 0, 0, 0, 0);
17356 /* Give up if window start is in the changed area.
17358 The condition used to read
17360 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
17362 but why that was tested escapes me at the moment. */
17363 if (CHARPOS (start
) >= first_changed_charpos
17364 && CHARPOS (start
) <= last_changed_charpos
)
17367 /* Check that window start agrees with the start of the first glyph
17368 row in its current matrix. Check this after we know the window
17369 start is not in changed text, otherwise positions would not be
17371 row
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
17372 if (!TEXT_POS_EQUAL_P (start
, row
->minpos
))
17375 /* Give up if the window ends in strings. Overlay strings
17376 at the end are difficult to handle, so don't try. */
17377 row
= MATRIX_ROW (current_matrix
, w
->window_end_vpos
);
17378 if (MATRIX_ROW_START_CHARPOS (row
) == MATRIX_ROW_END_CHARPOS (row
))
17381 /* Compute the position at which we have to start displaying new
17382 lines. Some of the lines at the top of the window might be
17383 reusable because they are not displaying changed text. Find the
17384 last row in W's current matrix not affected by changes at the
17385 start of current_buffer. Value is null if changes start in the
17386 first line of window. */
17387 last_unchanged_at_beg_row
= find_last_unchanged_at_beg_row (w
);
17388 if (last_unchanged_at_beg_row
)
17390 /* Avoid starting to display in the middle of a character, a TAB
17391 for instance. This is easier than to set up the iterator
17392 exactly, and it's not a frequent case, so the additional
17393 effort wouldn't really pay off. */
17394 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row
)
17395 || last_unchanged_at_beg_row
->ends_in_newline_from_string_p
)
17396 && last_unchanged_at_beg_row
> w
->current_matrix
->rows
)
17397 --last_unchanged_at_beg_row
;
17399 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row
))
17402 if (init_to_row_end (&it
, w
, last_unchanged_at_beg_row
) == 0)
17404 start_pos
= it
.current
.pos
;
17406 /* Start displaying new lines in the desired matrix at the same
17407 vpos we would use in the current matrix, i.e. below
17408 last_unchanged_at_beg_row. */
17409 it
.vpos
= 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row
,
17411 it
.glyph_row
= MATRIX_ROW (desired_matrix
, it
.vpos
);
17412 it
.current_y
= MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row
);
17414 eassert (it
.hpos
== 0 && it
.current_x
== 0);
17418 /* There are no reusable lines at the start of the window.
17419 Start displaying in the first text line. */
17420 start_display (&it
, w
, start
);
17421 it
.vpos
= it
.first_vpos
;
17422 start_pos
= it
.current
.pos
;
17425 /* Find the first row that is not affected by changes at the end of
17426 the buffer. Value will be null if there is no unchanged row, in
17427 which case we must redisplay to the end of the window. delta
17428 will be set to the value by which buffer positions beginning with
17429 first_unchanged_at_end_row have to be adjusted due to text
17431 first_unchanged_at_end_row
17432 = find_first_unchanged_at_end_row (w
, &delta
, &delta_bytes
);
17433 IF_DEBUG (debug_delta
= delta
);
17434 IF_DEBUG (debug_delta_bytes
= delta_bytes
);
17436 /* Set stop_pos to the buffer position up to which we will have to
17437 display new lines. If first_unchanged_at_end_row != NULL, this
17438 is the buffer position of the start of the line displayed in that
17439 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
17440 that we don't stop at a buffer position. */
17442 if (first_unchanged_at_end_row
)
17444 eassert (last_unchanged_at_beg_row
== NULL
17445 || first_unchanged_at_end_row
>= last_unchanged_at_beg_row
);
17447 /* If this is a continuation line, move forward to the next one
17448 that isn't. Changes in lines above affect this line.
17449 Caution: this may move first_unchanged_at_end_row to a row
17450 not displaying text. */
17451 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row
)
17452 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
)
17453 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row
)
17454 < it
.last_visible_y
))
17455 ++first_unchanged_at_end_row
;
17457 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
)
17458 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row
)
17459 >= it
.last_visible_y
))
17460 first_unchanged_at_end_row
= NULL
;
17463 stop_pos
= (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row
)
17465 first_unchanged_at_end_vpos
17466 = MATRIX_ROW_VPOS (first_unchanged_at_end_row
, current_matrix
);
17467 eassert (stop_pos
>= Z
- END_UNCHANGED
);
17470 else if (last_unchanged_at_beg_row
== NULL
)
17476 /* Either there is no unchanged row at the end, or the one we have
17477 now displays text. This is a necessary condition for the window
17478 end pos calculation at the end of this function. */
17479 eassert (first_unchanged_at_end_row
== NULL
17480 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
));
17482 debug_last_unchanged_at_beg_vpos
17483 = (last_unchanged_at_beg_row
17484 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row
, current_matrix
)
17486 debug_first_unchanged_at_end_vpos
= first_unchanged_at_end_vpos
;
17488 #endif /* GLYPH_DEBUG */
17491 /* Display new lines. Set last_text_row to the last new line
17492 displayed which has text on it, i.e. might end up as being the
17493 line where the window_end_vpos is. */
17494 w
->cursor
.vpos
= -1;
17495 last_text_row
= NULL
;
17496 overlay_arrow_seen
= 0;
17497 while (it
.current_y
< it
.last_visible_y
17498 && !f
->fonts_changed
17499 && (first_unchanged_at_end_row
== NULL
17500 || IT_CHARPOS (it
) < stop_pos
))
17502 if (display_line (&it
))
17503 last_text_row
= it
.glyph_row
- 1;
17506 if (f
->fonts_changed
)
17510 /* Compute differences in buffer positions, y-positions etc. for
17511 lines reused at the bottom of the window. Compute what we can
17513 if (first_unchanged_at_end_row
17514 /* No lines reused because we displayed everything up to the
17515 bottom of the window. */
17516 && it
.current_y
< it
.last_visible_y
)
17519 - MATRIX_ROW_VPOS (first_unchanged_at_end_row
,
17521 dy
= it
.current_y
- first_unchanged_at_end_row
->y
;
17522 run
.current_y
= first_unchanged_at_end_row
->y
;
17523 run
.desired_y
= run
.current_y
+ dy
;
17524 run
.height
= it
.last_visible_y
- max (run
.current_y
, run
.desired_y
);
17528 delta
= delta_bytes
= dvpos
= dy
17529 = run
.current_y
= run
.desired_y
= run
.height
= 0;
17530 first_unchanged_at_end_row
= NULL
;
17532 IF_DEBUG (debug_dvpos
= dvpos
; debug_dy
= dy
);
17535 /* Find the cursor if not already found. We have to decide whether
17536 PT will appear on this window (it sometimes doesn't, but this is
17537 not a very frequent case.) This decision has to be made before
17538 the current matrix is altered. A value of cursor.vpos < 0 means
17539 that PT is either in one of the lines beginning at
17540 first_unchanged_at_end_row or below the window. Don't care for
17541 lines that might be displayed later at the window end; as
17542 mentioned, this is not a frequent case. */
17543 if (w
->cursor
.vpos
< 0)
17545 /* Cursor in unchanged rows at the top? */
17546 if (PT
< CHARPOS (start_pos
)
17547 && last_unchanged_at_beg_row
)
17549 row
= row_containing_pos (w
, PT
,
17550 MATRIX_FIRST_TEXT_ROW (w
->current_matrix
),
17551 last_unchanged_at_beg_row
+ 1, 0);
17553 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
17556 /* Start from first_unchanged_at_end_row looking for PT. */
17557 else if (first_unchanged_at_end_row
)
17559 row
= row_containing_pos (w
, PT
- delta
,
17560 first_unchanged_at_end_row
, NULL
, 0);
17562 set_cursor_from_row (w
, row
, w
->current_matrix
, delta
,
17563 delta_bytes
, dy
, dvpos
);
17566 /* Give up if cursor was not found. */
17567 if (w
->cursor
.vpos
< 0)
17569 clear_glyph_matrix (w
->desired_matrix
);
17574 /* Don't let the cursor end in the scroll margins. */
17576 int this_scroll_margin
, cursor_height
;
17577 int frame_line_height
= default_line_pixel_height (w
);
17578 int window_total_lines
17579 = WINDOW_TOTAL_LINES (w
) * FRAME_LINE_HEIGHT (it
.f
) / frame_line_height
;
17581 this_scroll_margin
=
17582 max (0, min (scroll_margin
, window_total_lines
/ 4));
17583 this_scroll_margin
*= frame_line_height
;
17584 cursor_height
= MATRIX_ROW (w
->desired_matrix
, w
->cursor
.vpos
)->height
;
17586 if ((w
->cursor
.y
< this_scroll_margin
17587 && CHARPOS (start
) > BEGV
)
17588 /* Old redisplay didn't take scroll margin into account at the bottom,
17589 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
17590 || (w
->cursor
.y
+ (make_cursor_line_fully_visible_p
17591 ? cursor_height
+ this_scroll_margin
17592 : 1)) > it
.last_visible_y
)
17594 w
->cursor
.vpos
= -1;
17595 clear_glyph_matrix (w
->desired_matrix
);
17600 /* Scroll the display. Do it before changing the current matrix so
17601 that xterm.c doesn't get confused about where the cursor glyph is
17603 if (dy
&& run
.height
)
17607 if (FRAME_WINDOW_P (f
))
17609 FRAME_RIF (f
)->update_window_begin_hook (w
);
17610 FRAME_RIF (f
)->clear_window_mouse_face (w
);
17611 FRAME_RIF (f
)->scroll_run_hook (w
, &run
);
17612 FRAME_RIF (f
)->update_window_end_hook (w
, 0, 0);
17616 /* Terminal frame. In this case, dvpos gives the number of
17617 lines to scroll by; dvpos < 0 means scroll up. */
17619 = MATRIX_ROW_VPOS (first_unchanged_at_end_row
, w
->current_matrix
);
17620 int from
= WINDOW_TOP_EDGE_LINE (w
) + from_vpos
;
17621 int end
= (WINDOW_TOP_EDGE_LINE (w
)
17622 + (WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0)
17623 + window_internal_height (w
));
17625 #if defined (HAVE_GPM) || defined (MSDOS)
17626 x_clear_window_mouse_face (w
);
17628 /* Perform the operation on the screen. */
17631 /* Scroll last_unchanged_at_beg_row to the end of the
17632 window down dvpos lines. */
17633 set_terminal_window (f
, end
);
17635 /* On dumb terminals delete dvpos lines at the end
17636 before inserting dvpos empty lines. */
17637 if (!FRAME_SCROLL_REGION_OK (f
))
17638 ins_del_lines (f
, end
- dvpos
, -dvpos
);
17640 /* Insert dvpos empty lines in front of
17641 last_unchanged_at_beg_row. */
17642 ins_del_lines (f
, from
, dvpos
);
17644 else if (dvpos
< 0)
17646 /* Scroll up last_unchanged_at_beg_vpos to the end of
17647 the window to last_unchanged_at_beg_vpos - |dvpos|. */
17648 set_terminal_window (f
, end
);
17650 /* Delete dvpos lines in front of
17651 last_unchanged_at_beg_vpos. ins_del_lines will set
17652 the cursor to the given vpos and emit |dvpos| delete
17654 ins_del_lines (f
, from
+ dvpos
, dvpos
);
17656 /* On a dumb terminal insert dvpos empty lines at the
17658 if (!FRAME_SCROLL_REGION_OK (f
))
17659 ins_del_lines (f
, end
+ dvpos
, -dvpos
);
17662 set_terminal_window (f
, 0);
17668 /* Shift reused rows of the current matrix to the right position.
17669 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
17671 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (current_matrix
, w
);
17672 bottom_vpos
= MATRIX_ROW_VPOS (bottom_row
, current_matrix
);
17675 rotate_matrix (current_matrix
, first_unchanged_at_end_vpos
+ dvpos
,
17676 bottom_vpos
, dvpos
);
17677 clear_glyph_matrix_rows (current_matrix
, bottom_vpos
+ dvpos
,
17680 else if (dvpos
> 0)
17682 rotate_matrix (current_matrix
, first_unchanged_at_end_vpos
,
17683 bottom_vpos
, dvpos
);
17684 clear_glyph_matrix_rows (current_matrix
, first_unchanged_at_end_vpos
,
17685 first_unchanged_at_end_vpos
+ dvpos
);
17688 /* For frame-based redisplay, make sure that current frame and window
17689 matrix are in sync with respect to glyph memory. */
17690 if (!FRAME_WINDOW_P (f
))
17691 sync_frame_with_window_matrix_rows (w
);
17693 /* Adjust buffer positions in reused rows. */
17694 if (delta
|| delta_bytes
)
17695 increment_matrix_positions (current_matrix
,
17696 first_unchanged_at_end_vpos
+ dvpos
,
17697 bottom_vpos
, delta
, delta_bytes
);
17699 /* Adjust Y positions. */
17701 shift_glyph_matrix (w
, current_matrix
,
17702 first_unchanged_at_end_vpos
+ dvpos
,
17705 if (first_unchanged_at_end_row
)
17707 first_unchanged_at_end_row
+= dvpos
;
17708 if (first_unchanged_at_end_row
->y
>= it
.last_visible_y
17709 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
))
17710 first_unchanged_at_end_row
= NULL
;
17713 /* If scrolling up, there may be some lines to display at the end of
17715 last_text_row_at_end
= NULL
;
17718 /* Scrolling up can leave for example a partially visible line
17719 at the end of the window to be redisplayed. */
17720 /* Set last_row to the glyph row in the current matrix where the
17721 window end line is found. It has been moved up or down in
17722 the matrix by dvpos. */
17723 int last_vpos
= w
->window_end_vpos
+ dvpos
;
17724 struct glyph_row
*last_row
= MATRIX_ROW (current_matrix
, last_vpos
);
17726 /* If last_row is the window end line, it should display text. */
17727 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_row
));
17729 /* If window end line was partially visible before, begin
17730 displaying at that line. Otherwise begin displaying with the
17731 line following it. */
17732 if (MATRIX_ROW_BOTTOM_Y (last_row
) - dy
>= it
.last_visible_y
)
17734 init_to_row_start (&it
, w
, last_row
);
17735 it
.vpos
= last_vpos
;
17736 it
.current_y
= last_row
->y
;
17740 init_to_row_end (&it
, w
, last_row
);
17741 it
.vpos
= 1 + last_vpos
;
17742 it
.current_y
= MATRIX_ROW_BOTTOM_Y (last_row
);
17746 /* We may start in a continuation line. If so, we have to
17747 get the right continuation_lines_width and current_x. */
17748 it
.continuation_lines_width
= last_row
->continuation_lines_width
;
17749 it
.hpos
= it
.current_x
= 0;
17751 /* Display the rest of the lines at the window end. */
17752 it
.glyph_row
= MATRIX_ROW (desired_matrix
, it
.vpos
);
17753 while (it
.current_y
< it
.last_visible_y
&& !f
->fonts_changed
)
17755 /* Is it always sure that the display agrees with lines in
17756 the current matrix? I don't think so, so we mark rows
17757 displayed invalid in the current matrix by setting their
17758 enabled_p flag to zero. */
17759 MATRIX_ROW (w
->current_matrix
, it
.vpos
)->enabled_p
= 0;
17760 if (display_line (&it
))
17761 last_text_row_at_end
= it
.glyph_row
- 1;
17765 /* Update window_end_pos and window_end_vpos. */
17766 if (first_unchanged_at_end_row
&& !last_text_row_at_end
)
17768 /* Window end line if one of the preserved rows from the current
17769 matrix. Set row to the last row displaying text in current
17770 matrix starting at first_unchanged_at_end_row, after
17772 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
));
17773 row
= find_last_row_displaying_text (w
->current_matrix
, &it
,
17774 first_unchanged_at_end_row
);
17775 eassert (row
&& MATRIX_ROW_DISPLAYS_TEXT_P (row
));
17776 adjust_window_ends (w
, row
, 1);
17777 eassert (w
->window_end_bytepos
>= 0);
17778 IF_DEBUG (debug_method_add (w
, "A"));
17780 else if (last_text_row_at_end
)
17782 adjust_window_ends (w
, last_text_row_at_end
, 0);
17783 eassert (w
->window_end_bytepos
>= 0);
17784 IF_DEBUG (debug_method_add (w
, "B"));
17786 else if (last_text_row
)
17788 /* We have displayed either to the end of the window or at the
17789 end of the window, i.e. the last row with text is to be found
17790 in the desired matrix. */
17791 adjust_window_ends (w
, last_text_row
, 0);
17792 eassert (w
->window_end_bytepos
>= 0);
17794 else if (first_unchanged_at_end_row
== NULL
17795 && last_text_row
== NULL
17796 && last_text_row_at_end
== NULL
)
17798 /* Displayed to end of window, but no line containing text was
17799 displayed. Lines were deleted at the end of the window. */
17800 int first_vpos
= WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0;
17801 int vpos
= w
->window_end_vpos
;
17802 struct glyph_row
*current_row
= current_matrix
->rows
+ vpos
;
17803 struct glyph_row
*desired_row
= desired_matrix
->rows
+ vpos
;
17806 row
== NULL
&& vpos
>= first_vpos
;
17807 --vpos
, --current_row
, --desired_row
)
17809 if (desired_row
->enabled_p
)
17811 if (MATRIX_ROW_DISPLAYS_TEXT_P (desired_row
))
17814 else if (MATRIX_ROW_DISPLAYS_TEXT_P (current_row
))
17818 eassert (row
!= NULL
);
17819 w
->window_end_vpos
= vpos
+ 1;
17820 w
->window_end_pos
= Z
- MATRIX_ROW_END_CHARPOS (row
);
17821 w
->window_end_bytepos
= Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
17822 eassert (w
->window_end_bytepos
>= 0);
17823 IF_DEBUG (debug_method_add (w
, "C"));
17828 IF_DEBUG (debug_end_pos
= w
->window_end_pos
;
17829 debug_end_vpos
= w
->window_end_vpos
);
17831 /* Record that display has not been completed. */
17832 w
->window_end_valid
= 0;
17833 w
->desired_matrix
->no_scrolling_p
= 1;
17841 /***********************************************************************
17842 More debugging support
17843 ***********************************************************************/
17847 void dump_glyph_row (struct glyph_row
*, int, int) EXTERNALLY_VISIBLE
;
17848 void dump_glyph_matrix (struct glyph_matrix
*, int) EXTERNALLY_VISIBLE
;
17849 void dump_glyph (struct glyph_row
*, struct glyph
*, int) EXTERNALLY_VISIBLE
;
17852 /* Dump the contents of glyph matrix MATRIX on stderr.
17854 GLYPHS 0 means don't show glyph contents.
17855 GLYPHS 1 means show glyphs in short form
17856 GLYPHS > 1 means show glyphs in long form. */
17859 dump_glyph_matrix (struct glyph_matrix
*matrix
, int glyphs
)
17862 for (i
= 0; i
< matrix
->nrows
; ++i
)
17863 dump_glyph_row (MATRIX_ROW (matrix
, i
), i
, glyphs
);
17867 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
17868 the glyph row and area where the glyph comes from. */
17871 dump_glyph (struct glyph_row
*row
, struct glyph
*glyph
, int area
)
17873 if (glyph
->type
== CHAR_GLYPH
17874 || glyph
->type
== GLYPHLESS_GLYPH
)
17877 " %5"pD
"d %c %9"pI
"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
17878 glyph
- row
->glyphs
[TEXT_AREA
],
17879 (glyph
->type
== CHAR_GLYPH
17883 (BUFFERP (glyph
->object
)
17885 : (STRINGP (glyph
->object
)
17887 : (INTEGERP (glyph
->object
)
17890 glyph
->pixel_width
,
17892 (glyph
->u
.ch
< 0x80 && glyph
->u
.ch
>= ' '
17896 glyph
->left_box_line_p
,
17897 glyph
->right_box_line_p
);
17899 else if (glyph
->type
== STRETCH_GLYPH
)
17902 " %5"pD
"d %c %9"pI
"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
17903 glyph
- row
->glyphs
[TEXT_AREA
],
17906 (BUFFERP (glyph
->object
)
17908 : (STRINGP (glyph
->object
)
17910 : (INTEGERP (glyph
->object
)
17913 glyph
->pixel_width
,
17917 glyph
->left_box_line_p
,
17918 glyph
->right_box_line_p
);
17920 else if (glyph
->type
== IMAGE_GLYPH
)
17923 " %5"pD
"d %c %9"pI
"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
17924 glyph
- row
->glyphs
[TEXT_AREA
],
17927 (BUFFERP (glyph
->object
)
17929 : (STRINGP (glyph
->object
)
17931 : (INTEGERP (glyph
->object
)
17934 glyph
->pixel_width
,
17938 glyph
->left_box_line_p
,
17939 glyph
->right_box_line_p
);
17941 else if (glyph
->type
== COMPOSITE_GLYPH
)
17944 " %5"pD
"d %c %9"pI
"d %c %3d 0x%06x",
17945 glyph
- row
->glyphs
[TEXT_AREA
],
17948 (BUFFERP (glyph
->object
)
17950 : (STRINGP (glyph
->object
)
17952 : (INTEGERP (glyph
->object
)
17955 glyph
->pixel_width
,
17957 if (glyph
->u
.cmp
.automatic
)
17960 glyph
->slice
.cmp
.from
, glyph
->slice
.cmp
.to
);
17961 fprintf (stderr
, " . %4d %1.1d%1.1d\n",
17963 glyph
->left_box_line_p
,
17964 glyph
->right_box_line_p
);
17969 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
17970 GLYPHS 0 means don't show glyph contents.
17971 GLYPHS 1 means show glyphs in short form
17972 GLYPHS > 1 means show glyphs in long form. */
17975 dump_glyph_row (struct glyph_row
*row
, int vpos
, int glyphs
)
17979 fprintf (stderr
, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
17980 fprintf (stderr
, "==============================================================================\n");
17982 fprintf (stderr
, "%3d %9"pI
"d %9"pI
"d %4d %1.1d%1.1d%1.1d%1.1d\
17983 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
17985 MATRIX_ROW_START_CHARPOS (row
),
17986 MATRIX_ROW_END_CHARPOS (row
),
17987 row
->used
[TEXT_AREA
],
17988 row
->contains_overlapping_glyphs_p
,
17990 row
->truncated_on_left_p
,
17991 row
->truncated_on_right_p
,
17993 MATRIX_ROW_CONTINUATION_LINE_P (row
),
17994 MATRIX_ROW_DISPLAYS_TEXT_P (row
),
17997 row
->ends_in_middle_of_char_p
,
17998 row
->starts_in_middle_of_char_p
,
18004 row
->visible_height
,
18007 /* The next 3 lines should align to "Start" in the header. */
18008 fprintf (stderr
, " %9"pD
"d %9"pD
"d\t%5d\n", row
->start
.overlay_string_index
,
18009 row
->end
.overlay_string_index
,
18010 row
->continuation_lines_width
);
18011 fprintf (stderr
, " %9"pI
"d %9"pI
"d\n",
18012 CHARPOS (row
->start
.string_pos
),
18013 CHARPOS (row
->end
.string_pos
));
18014 fprintf (stderr
, " %9d %9d\n", row
->start
.dpvec_index
,
18015 row
->end
.dpvec_index
);
18022 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
18024 struct glyph
*glyph
= row
->glyphs
[area
];
18025 struct glyph
*glyph_end
= glyph
+ row
->used
[area
];
18027 /* Glyph for a line end in text. */
18028 if (area
== TEXT_AREA
&& glyph
== glyph_end
&& glyph
->charpos
> 0)
18031 if (glyph
< glyph_end
)
18032 fprintf (stderr
, " Glyph# Type Pos O W Code C Face LR\n");
18034 for (; glyph
< glyph_end
; ++glyph
)
18035 dump_glyph (row
, glyph
, area
);
18038 else if (glyphs
== 1)
18042 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
18044 char *s
= alloca (row
->used
[area
] + 4);
18047 for (i
= 0; i
< row
->used
[area
]; ++i
)
18049 struct glyph
*glyph
= row
->glyphs
[area
] + i
;
18050 if (i
== row
->used
[area
] - 1
18051 && area
== TEXT_AREA
18052 && INTEGERP (glyph
->object
)
18053 && glyph
->type
== CHAR_GLYPH
18054 && glyph
->u
.ch
== ' ')
18056 strcpy (&s
[i
], "[\\n]");
18059 else if (glyph
->type
== CHAR_GLYPH
18060 && glyph
->u
.ch
< 0x80
18061 && glyph
->u
.ch
>= ' ')
18062 s
[i
] = glyph
->u
.ch
;
18068 fprintf (stderr
, "%3d: (%d) '%s'\n", vpos
, row
->enabled_p
, s
);
18074 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix
,
18075 Sdump_glyph_matrix
, 0, 1, "p",
18076 doc
: /* Dump the current matrix of the selected window to stderr.
18077 Shows contents of glyph row structures. With non-nil
18078 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
18079 glyphs in short form, otherwise show glyphs in long form. */)
18080 (Lisp_Object glyphs
)
18082 struct window
*w
= XWINDOW (selected_window
);
18083 struct buffer
*buffer
= XBUFFER (w
->contents
);
18085 fprintf (stderr
, "PT = %"pI
"d, BEGV = %"pI
"d. ZV = %"pI
"d\n",
18086 BUF_PT (buffer
), BUF_BEGV (buffer
), BUF_ZV (buffer
));
18087 fprintf (stderr
, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
18088 w
->cursor
.x
, w
->cursor
.y
, w
->cursor
.hpos
, w
->cursor
.vpos
);
18089 fprintf (stderr
, "=============================================\n");
18090 dump_glyph_matrix (w
->current_matrix
,
18091 TYPE_RANGED_INTEGERP (int, glyphs
) ? XINT (glyphs
) : 0);
18096 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix
,
18097 Sdump_frame_glyph_matrix
, 0, 0, "", doc
: /* */)
18100 struct frame
*f
= XFRAME (selected_frame
);
18101 dump_glyph_matrix (f
->current_matrix
, 1);
18106 DEFUN ("dump-glyph-row", Fdump_glyph_row
, Sdump_glyph_row
, 1, 2, "",
18107 doc
: /* Dump glyph row ROW to stderr.
18108 GLYPH 0 means don't dump glyphs.
18109 GLYPH 1 means dump glyphs in short form.
18110 GLYPH > 1 or omitted means dump glyphs in long form. */)
18111 (Lisp_Object row
, Lisp_Object glyphs
)
18113 struct glyph_matrix
*matrix
;
18116 CHECK_NUMBER (row
);
18117 matrix
= XWINDOW (selected_window
)->current_matrix
;
18119 if (vpos
>= 0 && vpos
< matrix
->nrows
)
18120 dump_glyph_row (MATRIX_ROW (matrix
, vpos
),
18122 TYPE_RANGED_INTEGERP (int, glyphs
) ? XINT (glyphs
) : 2);
18127 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row
, Sdump_tool_bar_row
, 1, 2, "",
18128 doc
: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
18129 GLYPH 0 means don't dump glyphs.
18130 GLYPH 1 means dump glyphs in short form.
18131 GLYPH > 1 or omitted means dump glyphs in long form.
18133 If there's no tool-bar, or if the tool-bar is not drawn by Emacs,
18135 (Lisp_Object row
, Lisp_Object glyphs
)
18137 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
18138 struct frame
*sf
= SELECTED_FRAME ();
18139 struct glyph_matrix
*m
= XWINDOW (sf
->tool_bar_window
)->current_matrix
;
18142 CHECK_NUMBER (row
);
18144 if (vpos
>= 0 && vpos
< m
->nrows
)
18145 dump_glyph_row (MATRIX_ROW (m
, vpos
), vpos
,
18146 TYPE_RANGED_INTEGERP (int, glyphs
) ? XINT (glyphs
) : 2);
18152 DEFUN ("trace-redisplay", Ftrace_redisplay
, Strace_redisplay
, 0, 1, "P",
18153 doc
: /* Toggle tracing of redisplay.
18154 With ARG, turn tracing on if and only if ARG is positive. */)
18158 trace_redisplay_p
= !trace_redisplay_p
;
18161 arg
= Fprefix_numeric_value (arg
);
18162 trace_redisplay_p
= XINT (arg
) > 0;
18169 DEFUN ("trace-to-stderr", Ftrace_to_stderr
, Strace_to_stderr
, 1, MANY
, "",
18170 doc
: /* Like `format', but print result to stderr.
18171 usage: (trace-to-stderr STRING &rest OBJECTS) */)
18172 (ptrdiff_t nargs
, Lisp_Object
*args
)
18174 Lisp_Object s
= Fformat (nargs
, args
);
18175 fprintf (stderr
, "%s", SDATA (s
));
18179 #endif /* GLYPH_DEBUG */
18183 /***********************************************************************
18184 Building Desired Matrix Rows
18185 ***********************************************************************/
18187 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
18188 Used for non-window-redisplay windows, and for windows w/o left fringe. */
18190 static struct glyph_row
*
18191 get_overlay_arrow_glyph_row (struct window
*w
, Lisp_Object overlay_arrow_string
)
18193 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
18194 struct buffer
*buffer
= XBUFFER (w
->contents
);
18195 struct buffer
*old
= current_buffer
;
18196 const unsigned char *arrow_string
= SDATA (overlay_arrow_string
);
18197 int arrow_len
= SCHARS (overlay_arrow_string
);
18198 const unsigned char *arrow_end
= arrow_string
+ arrow_len
;
18199 const unsigned char *p
;
18202 int n_glyphs_before
;
18204 set_buffer_temp (buffer
);
18205 init_iterator (&it
, w
, -1, -1, &scratch_glyph_row
, DEFAULT_FACE_ID
);
18206 it
.glyph_row
->used
[TEXT_AREA
] = 0;
18207 SET_TEXT_POS (it
.position
, 0, 0);
18209 multibyte_p
= !NILP (BVAR (buffer
, enable_multibyte_characters
));
18211 while (p
< arrow_end
)
18213 Lisp_Object face
, ilisp
;
18215 /* Get the next character. */
18217 it
.c
= it
.char_to_display
= string_char_and_length (p
, &it
.len
);
18220 it
.c
= it
.char_to_display
= *p
, it
.len
= 1;
18221 if (! ASCII_CHAR_P (it
.c
))
18222 it
.char_to_display
= BYTE8_TO_CHAR (it
.c
);
18226 /* Get its face. */
18227 ilisp
= make_number (p
- arrow_string
);
18228 face
= Fget_text_property (ilisp
, Qface
, overlay_arrow_string
);
18229 it
.face_id
= compute_char_face (f
, it
.char_to_display
, face
);
18231 /* Compute its width, get its glyphs. */
18232 n_glyphs_before
= it
.glyph_row
->used
[TEXT_AREA
];
18233 SET_TEXT_POS (it
.position
, -1, -1);
18234 PRODUCE_GLYPHS (&it
);
18236 /* If this character doesn't fit any more in the line, we have
18237 to remove some glyphs. */
18238 if (it
.current_x
> it
.last_visible_x
)
18240 it
.glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
;
18245 set_buffer_temp (old
);
18246 return it
.glyph_row
;
18250 /* Insert truncation glyphs at the start of IT->glyph_row. Which
18251 glyphs to insert is determined by produce_special_glyphs. */
18254 insert_left_trunc_glyphs (struct it
*it
)
18256 struct it truncate_it
;
18257 struct glyph
*from
, *end
, *to
, *toend
;
18259 eassert (!FRAME_WINDOW_P (it
->f
)
18260 || (!it
->glyph_row
->reversed_p
18261 && WINDOW_LEFT_FRINGE_WIDTH (it
->w
) == 0)
18262 || (it
->glyph_row
->reversed_p
18263 && WINDOW_RIGHT_FRINGE_WIDTH (it
->w
) == 0));
18265 /* Get the truncation glyphs. */
18267 truncate_it
.current_x
= 0;
18268 truncate_it
.face_id
= DEFAULT_FACE_ID
;
18269 truncate_it
.glyph_row
= &scratch_glyph_row
;
18270 truncate_it
.glyph_row
->used
[TEXT_AREA
] = 0;
18271 CHARPOS (truncate_it
.position
) = BYTEPOS (truncate_it
.position
) = -1;
18272 truncate_it
.object
= make_number (0);
18273 produce_special_glyphs (&truncate_it
, IT_TRUNCATION
);
18275 /* Overwrite glyphs from IT with truncation glyphs. */
18276 if (!it
->glyph_row
->reversed_p
)
18278 short tused
= truncate_it
.glyph_row
->used
[TEXT_AREA
];
18280 from
= truncate_it
.glyph_row
->glyphs
[TEXT_AREA
];
18281 end
= from
+ tused
;
18282 to
= it
->glyph_row
->glyphs
[TEXT_AREA
];
18283 toend
= to
+ it
->glyph_row
->used
[TEXT_AREA
];
18284 if (FRAME_WINDOW_P (it
->f
))
18286 /* On GUI frames, when variable-size fonts are displayed,
18287 the truncation glyphs may need more pixels than the row's
18288 glyphs they overwrite. We overwrite more glyphs to free
18289 enough screen real estate, and enlarge the stretch glyph
18290 on the right (see display_line), if there is one, to
18291 preserve the screen position of the truncation glyphs on
18294 struct glyph
*g
= to
;
18297 /* The first glyph could be partially visible, in which case
18298 it->glyph_row->x will be negative. But we want the left
18299 truncation glyphs to be aligned at the left margin of the
18300 window, so we override the x coordinate at which the row
18302 it
->glyph_row
->x
= 0;
18303 while (g
< toend
&& w
< it
->truncation_pixel_width
)
18305 w
+= g
->pixel_width
;
18308 if (g
- to
- tused
> 0)
18310 memmove (to
+ tused
, g
, (toend
- g
) * sizeof(*g
));
18311 it
->glyph_row
->used
[TEXT_AREA
] -= g
- to
- tused
;
18313 used
= it
->glyph_row
->used
[TEXT_AREA
];
18314 if (it
->glyph_row
->truncated_on_right_p
18315 && WINDOW_RIGHT_FRINGE_WIDTH (it
->w
) == 0
18316 && it
->glyph_row
->glyphs
[TEXT_AREA
][used
- 2].type
18319 int extra
= w
- it
->truncation_pixel_width
;
18321 it
->glyph_row
->glyphs
[TEXT_AREA
][used
- 2].pixel_width
+= extra
;
18328 /* There may be padding glyphs left over. Overwrite them too. */
18329 if (!FRAME_WINDOW_P (it
->f
))
18331 while (to
< toend
&& CHAR_GLYPH_PADDING_P (*to
))
18333 from
= truncate_it
.glyph_row
->glyphs
[TEXT_AREA
];
18340 it
->glyph_row
->used
[TEXT_AREA
] = to
- it
->glyph_row
->glyphs
[TEXT_AREA
];
18344 short tused
= truncate_it
.glyph_row
->used
[TEXT_AREA
];
18346 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
18347 that back to front. */
18348 end
= truncate_it
.glyph_row
->glyphs
[TEXT_AREA
];
18349 from
= end
+ truncate_it
.glyph_row
->used
[TEXT_AREA
] - 1;
18350 toend
= it
->glyph_row
->glyphs
[TEXT_AREA
];
18351 to
= toend
+ it
->glyph_row
->used
[TEXT_AREA
] - 1;
18352 if (FRAME_WINDOW_P (it
->f
))
18355 struct glyph
*g
= to
;
18357 while (g
>= toend
&& w
< it
->truncation_pixel_width
)
18359 w
+= g
->pixel_width
;
18362 if (to
- g
- tused
> 0)
18364 if (it
->glyph_row
->truncated_on_right_p
18365 && WINDOW_LEFT_FRINGE_WIDTH (it
->w
) == 0
18366 && it
->glyph_row
->glyphs
[TEXT_AREA
][1].type
== STRETCH_GLYPH
)
18368 int extra
= w
- it
->truncation_pixel_width
;
18370 it
->glyph_row
->glyphs
[TEXT_AREA
][1].pixel_width
+= extra
;
18374 while (from
>= end
&& to
>= toend
)
18376 if (!FRAME_WINDOW_P (it
->f
))
18378 while (to
>= toend
&& CHAR_GLYPH_PADDING_P (*to
))
18381 truncate_it
.glyph_row
->glyphs
[TEXT_AREA
]
18382 + truncate_it
.glyph_row
->used
[TEXT_AREA
] - 1;
18383 while (from
>= end
&& to
>= toend
)
18389 /* Need to free some room before prepending additional
18391 int move_by
= from
- end
+ 1;
18392 struct glyph
*g0
= it
->glyph_row
->glyphs
[TEXT_AREA
];
18393 struct glyph
*g
= g0
+ it
->glyph_row
->used
[TEXT_AREA
] - 1;
18395 for ( ; g
>= g0
; g
--)
18397 while (from
>= end
)
18399 it
->glyph_row
->used
[TEXT_AREA
] += move_by
;
18404 /* Compute the hash code for ROW. */
18406 row_hash (struct glyph_row
*row
)
18409 unsigned hashval
= 0;
18411 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
18412 for (k
= 0; k
< row
->used
[area
]; ++k
)
18413 hashval
= ((((hashval
<< 4) + (hashval
>> 24)) & 0x0fffffff)
18414 + row
->glyphs
[area
][k
].u
.val
18415 + row
->glyphs
[area
][k
].face_id
18416 + row
->glyphs
[area
][k
].padding_p
18417 + (row
->glyphs
[area
][k
].type
<< 2));
18422 /* Compute the pixel height and width of IT->glyph_row.
18424 Most of the time, ascent and height of a display line will be equal
18425 to the max_ascent and max_height values of the display iterator
18426 structure. This is not the case if
18428 1. We hit ZV without displaying anything. In this case, max_ascent
18429 and max_height will be zero.
18431 2. We have some glyphs that don't contribute to the line height.
18432 (The glyph row flag contributes_to_line_height_p is for future
18433 pixmap extensions).
18435 The first case is easily covered by using default values because in
18436 these cases, the line height does not really matter, except that it
18437 must not be zero. */
18440 compute_line_metrics (struct it
*it
)
18442 struct glyph_row
*row
= it
->glyph_row
;
18444 if (FRAME_WINDOW_P (it
->f
))
18446 int i
, min_y
, max_y
;
18448 /* The line may consist of one space only, that was added to
18449 place the cursor on it. If so, the row's height hasn't been
18451 if (row
->height
== 0)
18453 if (it
->max_ascent
+ it
->max_descent
== 0)
18454 it
->max_descent
= it
->max_phys_descent
= FRAME_LINE_HEIGHT (it
->f
);
18455 row
->ascent
= it
->max_ascent
;
18456 row
->height
= it
->max_ascent
+ it
->max_descent
;
18457 row
->phys_ascent
= it
->max_phys_ascent
;
18458 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
18459 row
->extra_line_spacing
= it
->max_extra_line_spacing
;
18462 /* Compute the width of this line. */
18463 row
->pixel_width
= row
->x
;
18464 for (i
= 0; i
< row
->used
[TEXT_AREA
]; ++i
)
18465 row
->pixel_width
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
18467 eassert (row
->pixel_width
>= 0);
18468 eassert (row
->ascent
>= 0 && row
->height
> 0);
18470 row
->overlapping_p
= (MATRIX_ROW_OVERLAPS_SUCC_P (row
)
18471 || MATRIX_ROW_OVERLAPS_PRED_P (row
));
18473 /* If first line's physical ascent is larger than its logical
18474 ascent, use the physical ascent, and make the row taller.
18475 This makes accented characters fully visible. */
18476 if (row
== MATRIX_FIRST_TEXT_ROW (it
->w
->desired_matrix
)
18477 && row
->phys_ascent
> row
->ascent
)
18479 row
->height
+= row
->phys_ascent
- row
->ascent
;
18480 row
->ascent
= row
->phys_ascent
;
18483 /* Compute how much of the line is visible. */
18484 row
->visible_height
= row
->height
;
18486 min_y
= WINDOW_HEADER_LINE_HEIGHT (it
->w
);
18487 max_y
= WINDOW_BOX_HEIGHT_NO_MODE_LINE (it
->w
);
18489 if (row
->y
< min_y
)
18490 row
->visible_height
-= min_y
- row
->y
;
18491 if (row
->y
+ row
->height
> max_y
)
18492 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
18496 row
->pixel_width
= row
->used
[TEXT_AREA
];
18497 if (row
->continued_p
)
18498 row
->pixel_width
-= it
->continuation_pixel_width
;
18499 else if (row
->truncated_on_right_p
)
18500 row
->pixel_width
-= it
->truncation_pixel_width
;
18501 row
->ascent
= row
->phys_ascent
= 0;
18502 row
->height
= row
->phys_height
= row
->visible_height
= 1;
18503 row
->extra_line_spacing
= 0;
18506 /* Compute a hash code for this row. */
18507 row
->hash
= row_hash (row
);
18509 it
->max_ascent
= it
->max_descent
= 0;
18510 it
->max_phys_ascent
= it
->max_phys_descent
= 0;
18514 /* Append one space to the glyph row of iterator IT if doing a
18515 window-based redisplay. The space has the same face as
18516 IT->face_id. Value is non-zero if a space was added.
18518 This function is called to make sure that there is always one glyph
18519 at the end of a glyph row that the cursor can be set on under
18520 window-systems. (If there weren't such a glyph we would not know
18521 how wide and tall a box cursor should be displayed).
18523 At the same time this space let's a nicely handle clearing to the
18524 end of the line if the row ends in italic text. */
18527 append_space_for_newline (struct it
*it
, int default_face_p
)
18529 if (FRAME_WINDOW_P (it
->f
))
18531 int n
= it
->glyph_row
->used
[TEXT_AREA
];
18533 if (it
->glyph_row
->glyphs
[TEXT_AREA
] + n
18534 < it
->glyph_row
->glyphs
[1 + TEXT_AREA
])
18536 /* Save some values that must not be changed.
18537 Must save IT->c and IT->len because otherwise
18538 ITERATOR_AT_END_P wouldn't work anymore after
18539 append_space_for_newline has been called. */
18540 enum display_element_type saved_what
= it
->what
;
18541 int saved_c
= it
->c
, saved_len
= it
->len
;
18542 int saved_char_to_display
= it
->char_to_display
;
18543 int saved_x
= it
->current_x
;
18544 int saved_face_id
= it
->face_id
;
18545 int saved_box_end
= it
->end_of_box_run_p
;
18546 struct text_pos saved_pos
;
18547 Lisp_Object saved_object
;
18550 saved_object
= it
->object
;
18551 saved_pos
= it
->position
;
18553 it
->what
= IT_CHARACTER
;
18554 memset (&it
->position
, 0, sizeof it
->position
);
18555 it
->object
= make_number (0);
18556 it
->c
= it
->char_to_display
= ' ';
18559 /* If the default face was remapped, be sure to use the
18560 remapped face for the appended newline. */
18561 if (default_face_p
)
18562 it
->face_id
= lookup_basic_face (it
->f
, DEFAULT_FACE_ID
);
18563 else if (it
->face_before_selective_p
)
18564 it
->face_id
= it
->saved_face_id
;
18565 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
18566 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, 0, -1, Qnil
);
18567 /* In R2L rows, we will prepend a stretch glyph that will
18568 have the end_of_box_run_p flag set for it, so there's no
18569 need for the appended newline glyph to have that flag
18571 if (it
->glyph_row
->reversed_p
18572 /* But if the appended newline glyph goes all the way to
18573 the end of the row, there will be no stretch glyph,
18574 so leave the box flag set. */
18575 && saved_x
+ FRAME_COLUMN_WIDTH (it
->f
) < it
->last_visible_x
)
18576 it
->end_of_box_run_p
= 0;
18578 PRODUCE_GLYPHS (it
);
18580 it
->override_ascent
= -1;
18581 it
->constrain_row_ascent_descent_p
= 0;
18582 it
->current_x
= saved_x
;
18583 it
->object
= saved_object
;
18584 it
->position
= saved_pos
;
18585 it
->what
= saved_what
;
18586 it
->face_id
= saved_face_id
;
18587 it
->len
= saved_len
;
18589 it
->char_to_display
= saved_char_to_display
;
18590 it
->end_of_box_run_p
= saved_box_end
;
18599 /* Extend the face of the last glyph in the text area of IT->glyph_row
18600 to the end of the display line. Called from display_line. If the
18601 glyph row is empty, add a space glyph to it so that we know the
18602 face to draw. Set the glyph row flag fill_line_p. If the glyph
18603 row is R2L, prepend a stretch glyph to cover the empty space to the
18604 left of the leftmost glyph. */
18607 extend_face_to_end_of_line (struct it
*it
)
18609 struct face
*face
, *default_face
;
18610 struct frame
*f
= it
->f
;
18612 /* If line is already filled, do nothing. Non window-system frames
18613 get a grace of one more ``pixel'' because their characters are
18614 1-``pixel'' wide, so they hit the equality too early. This grace
18615 is needed only for R2L rows that are not continued, to produce
18616 one extra blank where we could display the cursor. */
18617 if (it
->current_x
>= it
->last_visible_x
18618 + (!FRAME_WINDOW_P (f
)
18619 && it
->glyph_row
->reversed_p
18620 && !it
->glyph_row
->continued_p
))
18623 /* The default face, possibly remapped. */
18624 default_face
= FACE_FROM_ID (f
, lookup_basic_face (f
, DEFAULT_FACE_ID
));
18626 /* Face extension extends the background and box of IT->face_id
18627 to the end of the line. If the background equals the background
18628 of the frame, we don't have to do anything. */
18629 if (it
->face_before_selective_p
)
18630 face
= FACE_FROM_ID (f
, it
->saved_face_id
);
18632 face
= FACE_FROM_ID (f
, it
->face_id
);
18634 if (FRAME_WINDOW_P (f
)
18635 && MATRIX_ROW_DISPLAYS_TEXT_P (it
->glyph_row
)
18636 && face
->box
== FACE_NO_BOX
18637 && face
->background
== FRAME_BACKGROUND_PIXEL (f
)
18638 #ifdef HAVE_WINDOW_SYSTEM
18641 && !it
->glyph_row
->reversed_p
)
18644 /* Set the glyph row flag indicating that the face of the last glyph
18645 in the text area has to be drawn to the end of the text area. */
18646 it
->glyph_row
->fill_line_p
= 1;
18648 /* If current character of IT is not ASCII, make sure we have the
18649 ASCII face. This will be automatically undone the next time
18650 get_next_display_element returns a multibyte character. Note
18651 that the character will always be single byte in unibyte
18653 if (!ASCII_CHAR_P (it
->c
))
18655 it
->face_id
= FACE_FOR_CHAR (f
, face
, 0, -1, Qnil
);
18658 if (FRAME_WINDOW_P (f
))
18660 /* If the row is empty, add a space with the current face of IT,
18661 so that we know which face to draw. */
18662 if (it
->glyph_row
->used
[TEXT_AREA
] == 0)
18664 it
->glyph_row
->glyphs
[TEXT_AREA
][0] = space_glyph
;
18665 it
->glyph_row
->glyphs
[TEXT_AREA
][0].face_id
= face
->id
;
18666 it
->glyph_row
->used
[TEXT_AREA
] = 1;
18668 #ifdef HAVE_WINDOW_SYSTEM
18669 if (it
->glyph_row
->reversed_p
)
18671 /* Prepend a stretch glyph to the row, such that the
18672 rightmost glyph will be drawn flushed all the way to the
18673 right margin of the window. The stretch glyph that will
18674 occupy the empty space, if any, to the left of the
18676 struct font
*font
= face
->font
? face
->font
: FRAME_FONT (f
);
18677 struct glyph
*row_start
= it
->glyph_row
->glyphs
[TEXT_AREA
];
18678 struct glyph
*row_end
= row_start
+ it
->glyph_row
->used
[TEXT_AREA
];
18680 int row_width
, stretch_ascent
, stretch_width
;
18681 struct text_pos saved_pos
;
18682 int saved_face_id
, saved_avoid_cursor
, saved_box_start
;
18684 for (row_width
= 0, g
= row_start
; g
< row_end
; g
++)
18685 row_width
+= g
->pixel_width
;
18686 stretch_width
= window_box_width (it
->w
, TEXT_AREA
) - row_width
;
18687 if (stretch_width
> 0)
18690 (((it
->ascent
+ it
->descent
)
18691 * FONT_BASE (font
)) / FONT_HEIGHT (font
));
18692 saved_pos
= it
->position
;
18693 memset (&it
->position
, 0, sizeof it
->position
);
18694 saved_avoid_cursor
= it
->avoid_cursor_p
;
18695 it
->avoid_cursor_p
= 1;
18696 saved_face_id
= it
->face_id
;
18697 saved_box_start
= it
->start_of_box_run_p
;
18698 /* The last row's stretch glyph should get the default
18699 face, to avoid painting the rest of the window with
18700 the region face, if the region ends at ZV. */
18701 if (it
->glyph_row
->ends_at_zv_p
)
18702 it
->face_id
= default_face
->id
;
18704 it
->face_id
= face
->id
;
18705 it
->start_of_box_run_p
= 0;
18706 append_stretch_glyph (it
, make_number (0), stretch_width
,
18707 it
->ascent
+ it
->descent
, stretch_ascent
);
18708 it
->position
= saved_pos
;
18709 it
->avoid_cursor_p
= saved_avoid_cursor
;
18710 it
->face_id
= saved_face_id
;
18711 it
->start_of_box_run_p
= saved_box_start
;
18714 #endif /* HAVE_WINDOW_SYSTEM */
18718 /* Save some values that must not be changed. */
18719 int saved_x
= it
->current_x
;
18720 struct text_pos saved_pos
;
18721 Lisp_Object saved_object
;
18722 enum display_element_type saved_what
= it
->what
;
18723 int saved_face_id
= it
->face_id
;
18725 saved_object
= it
->object
;
18726 saved_pos
= it
->position
;
18728 it
->what
= IT_CHARACTER
;
18729 memset (&it
->position
, 0, sizeof it
->position
);
18730 it
->object
= make_number (0);
18731 it
->c
= it
->char_to_display
= ' ';
18733 /* The last row's blank glyphs should get the default face, to
18734 avoid painting the rest of the window with the region face,
18735 if the region ends at ZV. */
18736 if (it
->glyph_row
->ends_at_zv_p
)
18737 it
->face_id
= default_face
->id
;
18739 it
->face_id
= face
->id
;
18741 PRODUCE_GLYPHS (it
);
18743 while (it
->current_x
<= it
->last_visible_x
)
18744 PRODUCE_GLYPHS (it
);
18746 /* Don't count these blanks really. It would let us insert a left
18747 truncation glyph below and make us set the cursor on them, maybe. */
18748 it
->current_x
= saved_x
;
18749 it
->object
= saved_object
;
18750 it
->position
= saved_pos
;
18751 it
->what
= saved_what
;
18752 it
->face_id
= saved_face_id
;
18757 /* Value is non-zero if text starting at CHARPOS in current_buffer is
18758 trailing whitespace. */
18761 trailing_whitespace_p (ptrdiff_t charpos
)
18763 ptrdiff_t bytepos
= CHAR_TO_BYTE (charpos
);
18766 while (bytepos
< ZV_BYTE
18767 && (c
= FETCH_CHAR (bytepos
),
18768 c
== ' ' || c
== '\t'))
18771 if (bytepos
>= ZV_BYTE
|| c
== '\n' || c
== '\r')
18773 if (bytepos
!= PT_BYTE
)
18780 /* Highlight trailing whitespace, if any, in ROW. */
18783 highlight_trailing_whitespace (struct frame
*f
, struct glyph_row
*row
)
18785 int used
= row
->used
[TEXT_AREA
];
18789 struct glyph
*start
= row
->glyphs
[TEXT_AREA
];
18790 struct glyph
*glyph
= start
+ used
- 1;
18792 if (row
->reversed_p
)
18794 /* Right-to-left rows need to be processed in the opposite
18795 direction, so swap the edge pointers. */
18797 start
= row
->glyphs
[TEXT_AREA
] + used
- 1;
18800 /* Skip over glyphs inserted to display the cursor at the
18801 end of a line, for extending the face of the last glyph
18802 to the end of the line on terminals, and for truncation
18803 and continuation glyphs. */
18804 if (!row
->reversed_p
)
18806 while (glyph
>= start
18807 && glyph
->type
== CHAR_GLYPH
18808 && INTEGERP (glyph
->object
))
18813 while (glyph
<= start
18814 && glyph
->type
== CHAR_GLYPH
18815 && INTEGERP (glyph
->object
))
18819 /* If last glyph is a space or stretch, and it's trailing
18820 whitespace, set the face of all trailing whitespace glyphs in
18821 IT->glyph_row to `trailing-whitespace'. */
18822 if ((row
->reversed_p
? glyph
<= start
: glyph
>= start
)
18823 && BUFFERP (glyph
->object
)
18824 && (glyph
->type
== STRETCH_GLYPH
18825 || (glyph
->type
== CHAR_GLYPH
18826 && glyph
->u
.ch
== ' '))
18827 && trailing_whitespace_p (glyph
->charpos
))
18829 int face_id
= lookup_named_face (f
, Qtrailing_whitespace
, 0);
18833 if (!row
->reversed_p
)
18835 while (glyph
>= start
18836 && BUFFERP (glyph
->object
)
18837 && (glyph
->type
== STRETCH_GLYPH
18838 || (glyph
->type
== CHAR_GLYPH
18839 && glyph
->u
.ch
== ' ')))
18840 (glyph
--)->face_id
= face_id
;
18844 while (glyph
<= start
18845 && BUFFERP (glyph
->object
)
18846 && (glyph
->type
== STRETCH_GLYPH
18847 || (glyph
->type
== CHAR_GLYPH
18848 && glyph
->u
.ch
== ' ')))
18849 (glyph
++)->face_id
= face_id
;
18856 /* Value is non-zero if glyph row ROW should be
18857 considered to hold the buffer position CHARPOS. */
18860 row_for_charpos_p (struct glyph_row
*row
, ptrdiff_t charpos
)
18864 if (charpos
== CHARPOS (row
->end
.pos
)
18865 || charpos
== MATRIX_ROW_END_CHARPOS (row
))
18867 /* Suppose the row ends on a string.
18868 Unless the row is continued, that means it ends on a newline
18869 in the string. If it's anything other than a display string
18870 (e.g., a before-string from an overlay), we don't want the
18871 cursor there. (This heuristic seems to give the optimal
18872 behavior for the various types of multi-line strings.)
18873 One exception: if the string has `cursor' property on one of
18874 its characters, we _do_ want the cursor there. */
18875 if (CHARPOS (row
->end
.string_pos
) >= 0)
18877 if (row
->continued_p
)
18881 /* Check for `display' property. */
18882 struct glyph
*beg
= row
->glyphs
[TEXT_AREA
];
18883 struct glyph
*end
= beg
+ row
->used
[TEXT_AREA
] - 1;
18884 struct glyph
*glyph
;
18887 for (glyph
= end
; glyph
>= beg
; --glyph
)
18888 if (STRINGP (glyph
->object
))
18891 = Fget_char_property (make_number (charpos
),
18895 && display_prop_string_p (prop
, glyph
->object
));
18896 /* If there's a `cursor' property on one of the
18897 string's characters, this row is a cursor row,
18898 even though this is not a display string. */
18901 Lisp_Object s
= glyph
->object
;
18903 for ( ; glyph
>= beg
&& EQ (glyph
->object
, s
); --glyph
)
18905 ptrdiff_t gpos
= glyph
->charpos
;
18907 if (!NILP (Fget_char_property (make_number (gpos
),
18919 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
))
18921 /* If the row ends in middle of a real character,
18922 and the line is continued, we want the cursor here.
18923 That's because CHARPOS (ROW->end.pos) would equal
18924 PT if PT is before the character. */
18925 if (!row
->ends_in_ellipsis_p
)
18926 result
= row
->continued_p
;
18928 /* If the row ends in an ellipsis, then
18929 CHARPOS (ROW->end.pos) will equal point after the
18930 invisible text. We want that position to be displayed
18931 after the ellipsis. */
18934 /* If the row ends at ZV, display the cursor at the end of that
18935 row instead of at the start of the row below. */
18936 else if (row
->ends_at_zv_p
)
18945 /* Value is non-zero if glyph row ROW should be
18946 used to hold the cursor. */
18949 cursor_row_p (struct glyph_row
*row
)
18951 return row_for_charpos_p (row
, PT
);
18956 /* Push the property PROP so that it will be rendered at the current
18957 position in IT. Return 1 if PROP was successfully pushed, 0
18958 otherwise. Called from handle_line_prefix to handle the
18959 `line-prefix' and `wrap-prefix' properties. */
18962 push_prefix_prop (struct it
*it
, Lisp_Object prop
)
18964 struct text_pos pos
=
18965 STRINGP (it
->string
) ? it
->current
.string_pos
: it
->current
.pos
;
18967 eassert (it
->method
== GET_FROM_BUFFER
18968 || it
->method
== GET_FROM_DISPLAY_VECTOR
18969 || it
->method
== GET_FROM_STRING
);
18971 /* We need to save the current buffer/string position, so it will be
18972 restored by pop_it, because iterate_out_of_display_property
18973 depends on that being set correctly, but some situations leave
18974 it->position not yet set when this function is called. */
18975 push_it (it
, &pos
);
18977 if (STRINGP (prop
))
18979 if (SCHARS (prop
) == 0)
18986 it
->string_from_prefix_prop_p
= 1;
18987 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
18988 it
->current
.overlay_string_index
= -1;
18989 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = 0;
18990 it
->end_charpos
= it
->string_nchars
= SCHARS (it
->string
);
18991 it
->method
= GET_FROM_STRING
;
18992 it
->stop_charpos
= 0;
18994 it
->base_level_stop
= 0;
18996 /* Force paragraph direction to be that of the parent
18998 if (it
->bidi_p
&& it
->bidi_it
.paragraph_dir
== R2L
)
18999 it
->paragraph_embedding
= it
->bidi_it
.paragraph_dir
;
19001 it
->paragraph_embedding
= L2R
;
19003 /* Set up the bidi iterator for this display string. */
19006 it
->bidi_it
.string
.lstring
= it
->string
;
19007 it
->bidi_it
.string
.s
= NULL
;
19008 it
->bidi_it
.string
.schars
= it
->end_charpos
;
19009 it
->bidi_it
.string
.bufpos
= IT_CHARPOS (*it
);
19010 it
->bidi_it
.string
.from_disp_str
= it
->string_from_display_prop_p
;
19011 it
->bidi_it
.string
.unibyte
= !it
->multibyte_p
;
19012 it
->bidi_it
.w
= it
->w
;
19013 bidi_init_it (0, 0, FRAME_WINDOW_P (it
->f
), &it
->bidi_it
);
19016 else if (CONSP (prop
) && EQ (XCAR (prop
), Qspace
))
19018 it
->method
= GET_FROM_STRETCH
;
19021 #ifdef HAVE_WINDOW_SYSTEM
19022 else if (IMAGEP (prop
))
19024 it
->what
= IT_IMAGE
;
19025 it
->image_id
= lookup_image (it
->f
, prop
);
19026 it
->method
= GET_FROM_IMAGE
;
19028 #endif /* HAVE_WINDOW_SYSTEM */
19031 pop_it (it
); /* bogus display property, give up */
19038 /* Return the character-property PROP at the current position in IT. */
19041 get_it_property (struct it
*it
, Lisp_Object prop
)
19043 Lisp_Object position
, object
= it
->object
;
19045 if (STRINGP (object
))
19046 position
= make_number (IT_STRING_CHARPOS (*it
));
19047 else if (BUFFERP (object
))
19049 position
= make_number (IT_CHARPOS (*it
));
19050 object
= it
->window
;
19055 return Fget_char_property (position
, prop
, object
);
19058 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
19061 handle_line_prefix (struct it
*it
)
19063 Lisp_Object prefix
;
19065 if (it
->continuation_lines_width
> 0)
19067 prefix
= get_it_property (it
, Qwrap_prefix
);
19069 prefix
= Vwrap_prefix
;
19073 prefix
= get_it_property (it
, Qline_prefix
);
19075 prefix
= Vline_prefix
;
19077 if (! NILP (prefix
) && push_prefix_prop (it
, prefix
))
19079 /* If the prefix is wider than the window, and we try to wrap
19080 it, it would acquire its own wrap prefix, and so on till the
19081 iterator stack overflows. So, don't wrap the prefix. */
19082 it
->line_wrap
= TRUNCATE
;
19083 it
->avoid_cursor_p
= 1;
19089 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
19090 only for R2L lines from display_line and display_string, when they
19091 decide that too many glyphs were produced by PRODUCE_GLYPHS, and
19092 the line/string needs to be continued on the next glyph row. */
19094 unproduce_glyphs (struct it
*it
, int n
)
19096 struct glyph
*glyph
, *end
;
19098 eassert (it
->glyph_row
);
19099 eassert (it
->glyph_row
->reversed_p
);
19100 eassert (it
->area
== TEXT_AREA
);
19101 eassert (n
<= it
->glyph_row
->used
[TEXT_AREA
]);
19103 if (n
> it
->glyph_row
->used
[TEXT_AREA
])
19104 n
= it
->glyph_row
->used
[TEXT_AREA
];
19105 glyph
= it
->glyph_row
->glyphs
[TEXT_AREA
] + n
;
19106 end
= it
->glyph_row
->glyphs
[TEXT_AREA
] + it
->glyph_row
->used
[TEXT_AREA
];
19107 for ( ; glyph
< end
; glyph
++)
19108 glyph
[-n
] = *glyph
;
19111 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
19112 and ROW->maxpos. */
19114 find_row_edges (struct it
*it
, struct glyph_row
*row
,
19115 ptrdiff_t min_pos
, ptrdiff_t min_bpos
,
19116 ptrdiff_t max_pos
, ptrdiff_t max_bpos
)
19118 /* FIXME: Revisit this when glyph ``spilling'' in continuation
19119 lines' rows is implemented for bidi-reordered rows. */
19121 /* ROW->minpos is the value of min_pos, the minimal buffer position
19122 we have in ROW, or ROW->start.pos if that is smaller. */
19123 if (min_pos
<= ZV
&& min_pos
< row
->start
.pos
.charpos
)
19124 SET_TEXT_POS (row
->minpos
, min_pos
, min_bpos
);
19126 /* We didn't find buffer positions smaller than ROW->start, or
19127 didn't find _any_ valid buffer positions in any of the glyphs,
19128 so we must trust the iterator's computed positions. */
19129 row
->minpos
= row
->start
.pos
;
19132 max_pos
= CHARPOS (it
->current
.pos
);
19133 max_bpos
= BYTEPOS (it
->current
.pos
);
19136 /* Here are the various use-cases for ending the row, and the
19137 corresponding values for ROW->maxpos:
19139 Line ends in a newline from buffer eol_pos + 1
19140 Line is continued from buffer max_pos + 1
19141 Line is truncated on right it->current.pos
19142 Line ends in a newline from string max_pos + 1(*)
19143 (*) + 1 only when line ends in a forward scan
19144 Line is continued from string max_pos
19145 Line is continued from display vector max_pos
19146 Line is entirely from a string min_pos == max_pos
19147 Line is entirely from a display vector min_pos == max_pos
19148 Line that ends at ZV ZV
19150 If you discover other use-cases, please add them here as
19152 if (row
->ends_at_zv_p
)
19153 row
->maxpos
= it
->current
.pos
;
19154 else if (row
->used
[TEXT_AREA
])
19156 int seen_this_string
= 0;
19157 struct glyph_row
*r1
= row
- 1;
19159 /* Did we see the same display string on the previous row? */
19160 if (STRINGP (it
->object
)
19161 /* this is not the first row */
19162 && row
> it
->w
->desired_matrix
->rows
19163 /* previous row is not the header line */
19164 && !r1
->mode_line_p
19165 /* previous row also ends in a newline from a string */
19166 && r1
->ends_in_newline_from_string_p
)
19168 struct glyph
*start
, *end
;
19170 /* Search for the last glyph of the previous row that came
19171 from buffer or string. Depending on whether the row is
19172 L2R or R2L, we need to process it front to back or the
19173 other way round. */
19174 if (!r1
->reversed_p
)
19176 start
= r1
->glyphs
[TEXT_AREA
];
19177 end
= start
+ r1
->used
[TEXT_AREA
];
19178 /* Glyphs inserted by redisplay have an integer (zero)
19179 as their object. */
19181 && INTEGERP ((end
- 1)->object
)
19182 && (end
- 1)->charpos
<= 0)
19186 if (EQ ((end
- 1)->object
, it
->object
))
19187 seen_this_string
= 1;
19190 /* If all the glyphs of the previous row were inserted
19191 by redisplay, it means the previous row was
19192 produced from a single newline, which is only
19193 possible if that newline came from the same string
19194 as the one which produced this ROW. */
19195 seen_this_string
= 1;
19199 end
= r1
->glyphs
[TEXT_AREA
] - 1;
19200 start
= end
+ r1
->used
[TEXT_AREA
];
19202 && INTEGERP ((end
+ 1)->object
)
19203 && (end
+ 1)->charpos
<= 0)
19207 if (EQ ((end
+ 1)->object
, it
->object
))
19208 seen_this_string
= 1;
19211 seen_this_string
= 1;
19214 /* Take note of each display string that covers a newline only
19215 once, the first time we see it. This is for when a display
19216 string includes more than one newline in it. */
19217 if (row
->ends_in_newline_from_string_p
&& !seen_this_string
)
19219 /* If we were scanning the buffer forward when we displayed
19220 the string, we want to account for at least one buffer
19221 position that belongs to this row (position covered by
19222 the display string), so that cursor positioning will
19223 consider this row as a candidate when point is at the end
19224 of the visual line represented by this row. This is not
19225 required when scanning back, because max_pos will already
19226 have a much larger value. */
19227 if (CHARPOS (row
->end
.pos
) > max_pos
)
19228 INC_BOTH (max_pos
, max_bpos
);
19229 SET_TEXT_POS (row
->maxpos
, max_pos
, max_bpos
);
19231 else if (CHARPOS (it
->eol_pos
) > 0)
19232 SET_TEXT_POS (row
->maxpos
,
19233 CHARPOS (it
->eol_pos
) + 1, BYTEPOS (it
->eol_pos
) + 1);
19234 else if (row
->continued_p
)
19236 /* If max_pos is different from IT's current position, it
19237 means IT->method does not belong to the display element
19238 at max_pos. However, it also means that the display
19239 element at max_pos was displayed in its entirety on this
19240 line, which is equivalent to saying that the next line
19241 starts at the next buffer position. */
19242 if (IT_CHARPOS (*it
) == max_pos
&& it
->method
!= GET_FROM_BUFFER
)
19243 SET_TEXT_POS (row
->maxpos
, max_pos
, max_bpos
);
19246 INC_BOTH (max_pos
, max_bpos
);
19247 SET_TEXT_POS (row
->maxpos
, max_pos
, max_bpos
);
19250 else if (row
->truncated_on_right_p
)
19251 /* display_line already called reseat_at_next_visible_line_start,
19252 which puts the iterator at the beginning of the next line, in
19253 the logical order. */
19254 row
->maxpos
= it
->current
.pos
;
19255 else if (max_pos
== min_pos
&& it
->method
!= GET_FROM_BUFFER
)
19256 /* A line that is entirely from a string/image/stretch... */
19257 row
->maxpos
= row
->minpos
;
19262 row
->maxpos
= it
->current
.pos
;
19265 /* Construct the glyph row IT->glyph_row in the desired matrix of
19266 IT->w from text at the current position of IT. See dispextern.h
19267 for an overview of struct it. Value is non-zero if
19268 IT->glyph_row displays text, as opposed to a line displaying ZV
19272 display_line (struct it
*it
)
19274 struct glyph_row
*row
= it
->glyph_row
;
19275 Lisp_Object overlay_arrow_string
;
19277 void *wrap_data
= NULL
;
19278 int may_wrap
= 0, wrap_x
IF_LINT (= 0);
19279 int wrap_row_used
= -1;
19280 int wrap_row_ascent
IF_LINT (= 0), wrap_row_height
IF_LINT (= 0);
19281 int wrap_row_phys_ascent
IF_LINT (= 0), wrap_row_phys_height
IF_LINT (= 0);
19282 int wrap_row_extra_line_spacing
IF_LINT (= 0);
19283 ptrdiff_t wrap_row_min_pos
IF_LINT (= 0), wrap_row_min_bpos
IF_LINT (= 0);
19284 ptrdiff_t wrap_row_max_pos
IF_LINT (= 0), wrap_row_max_bpos
IF_LINT (= 0);
19286 ptrdiff_t min_pos
= ZV
+ 1, max_pos
= 0;
19287 ptrdiff_t min_bpos
IF_LINT (= 0), max_bpos
IF_LINT (= 0);
19289 /* We always start displaying at hpos zero even if hscrolled. */
19290 eassert (it
->hpos
== 0 && it
->current_x
== 0);
19292 if (MATRIX_ROW_VPOS (row
, it
->w
->desired_matrix
)
19293 >= it
->w
->desired_matrix
->nrows
)
19295 it
->w
->nrows_scale_factor
++;
19296 it
->f
->fonts_changed
= 1;
19300 /* Clear the result glyph row and enable it. */
19301 prepare_desired_row (row
);
19303 row
->y
= it
->current_y
;
19304 row
->start
= it
->start
;
19305 row
->continuation_lines_width
= it
->continuation_lines_width
;
19306 row
->displays_text_p
= 1;
19307 row
->starts_in_middle_of_char_p
= it
->starts_in_middle_of_char_p
;
19308 it
->starts_in_middle_of_char_p
= 0;
19310 /* Arrange the overlays nicely for our purposes. Usually, we call
19311 display_line on only one line at a time, in which case this
19312 can't really hurt too much, or we call it on lines which appear
19313 one after another in the buffer, in which case all calls to
19314 recenter_overlay_lists but the first will be pretty cheap. */
19315 recenter_overlay_lists (current_buffer
, IT_CHARPOS (*it
));
19317 /* Move over display elements that are not visible because we are
19318 hscrolled. This may stop at an x-position < IT->first_visible_x
19319 if the first glyph is partially visible or if we hit a line end. */
19320 if (it
->current_x
< it
->first_visible_x
)
19322 enum move_it_result move_result
;
19324 this_line_min_pos
= row
->start
.pos
;
19325 move_result
= move_it_in_display_line_to (it
, ZV
, it
->first_visible_x
,
19326 MOVE_TO_POS
| MOVE_TO_X
);
19327 /* If we are under a large hscroll, move_it_in_display_line_to
19328 could hit the end of the line without reaching
19329 it->first_visible_x. Pretend that we did reach it. This is
19330 especially important on a TTY, where we will call
19331 extend_face_to_end_of_line, which needs to know how many
19332 blank glyphs to produce. */
19333 if (it
->current_x
< it
->first_visible_x
19334 && (move_result
== MOVE_NEWLINE_OR_CR
19335 || move_result
== MOVE_POS_MATCH_OR_ZV
))
19336 it
->current_x
= it
->first_visible_x
;
19338 /* Record the smallest positions seen while we moved over
19339 display elements that are not visible. This is needed by
19340 redisplay_internal for optimizing the case where the cursor
19341 stays inside the same line. The rest of this function only
19342 considers positions that are actually displayed, so
19343 RECORD_MAX_MIN_POS will not otherwise record positions that
19344 are hscrolled to the left of the left edge of the window. */
19345 min_pos
= CHARPOS (this_line_min_pos
);
19346 min_bpos
= BYTEPOS (this_line_min_pos
);
19350 /* We only do this when not calling `move_it_in_display_line_to'
19351 above, because move_it_in_display_line_to calls
19352 handle_line_prefix itself. */
19353 handle_line_prefix (it
);
19356 /* Get the initial row height. This is either the height of the
19357 text hscrolled, if there is any, or zero. */
19358 row
->ascent
= it
->max_ascent
;
19359 row
->height
= it
->max_ascent
+ it
->max_descent
;
19360 row
->phys_ascent
= it
->max_phys_ascent
;
19361 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
19362 row
->extra_line_spacing
= it
->max_extra_line_spacing
;
19364 /* Utility macro to record max and min buffer positions seen until now. */
19365 #define RECORD_MAX_MIN_POS(IT) \
19368 int composition_p = !STRINGP ((IT)->string) \
19369 && ((IT)->what == IT_COMPOSITION); \
19370 ptrdiff_t current_pos = \
19371 composition_p ? (IT)->cmp_it.charpos \
19372 : IT_CHARPOS (*(IT)); \
19373 ptrdiff_t current_bpos = \
19374 composition_p ? CHAR_TO_BYTE (current_pos) \
19375 : IT_BYTEPOS (*(IT)); \
19376 if (current_pos < min_pos) \
19378 min_pos = current_pos; \
19379 min_bpos = current_bpos; \
19381 if (IT_CHARPOS (*it) > max_pos) \
19383 max_pos = IT_CHARPOS (*it); \
19384 max_bpos = IT_BYTEPOS (*it); \
19389 /* Loop generating characters. The loop is left with IT on the next
19390 character to display. */
19393 int n_glyphs_before
, hpos_before
, x_before
;
19395 int ascent
= 0, descent
= 0, phys_ascent
= 0, phys_descent
= 0;
19397 /* Retrieve the next thing to display. Value is zero if end of
19399 if (!get_next_display_element (it
))
19401 /* Maybe add a space at the end of this line that is used to
19402 display the cursor there under X. Set the charpos of the
19403 first glyph of blank lines not corresponding to any text
19405 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
19406 row
->exact_window_width_line_p
= 1;
19407 else if ((append_space_for_newline (it
, 1) && row
->used
[TEXT_AREA
] == 1)
19408 || row
->used
[TEXT_AREA
] == 0)
19410 row
->glyphs
[TEXT_AREA
]->charpos
= -1;
19411 row
->displays_text_p
= 0;
19413 if (!NILP (BVAR (XBUFFER (it
->w
->contents
), indicate_empty_lines
))
19414 && (!MINI_WINDOW_P (it
->w
)
19415 || (minibuf_level
&& EQ (it
->window
, minibuf_window
))))
19416 row
->indicate_empty_line_p
= 1;
19419 it
->continuation_lines_width
= 0;
19420 row
->ends_at_zv_p
= 1;
19421 /* A row that displays right-to-left text must always have
19422 its last face extended all the way to the end of line,
19423 even if this row ends in ZV, because we still write to
19424 the screen left to right. We also need to extend the
19425 last face if the default face is remapped to some
19426 different face, otherwise the functions that clear
19427 portions of the screen will clear with the default face's
19428 background color. */
19429 if (row
->reversed_p
19430 || lookup_basic_face (it
->f
, DEFAULT_FACE_ID
) != DEFAULT_FACE_ID
)
19431 extend_face_to_end_of_line (it
);
19435 /* Now, get the metrics of what we want to display. This also
19436 generates glyphs in `row' (which is IT->glyph_row). */
19437 n_glyphs_before
= row
->used
[TEXT_AREA
];
19440 /* Remember the line height so far in case the next element doesn't
19441 fit on the line. */
19442 if (it
->line_wrap
!= TRUNCATE
)
19444 ascent
= it
->max_ascent
;
19445 descent
= it
->max_descent
;
19446 phys_ascent
= it
->max_phys_ascent
;
19447 phys_descent
= it
->max_phys_descent
;
19449 if (it
->line_wrap
== WORD_WRAP
&& it
->area
== TEXT_AREA
)
19451 if (IT_DISPLAYING_WHITESPACE (it
))
19455 SAVE_IT (wrap_it
, *it
, wrap_data
);
19457 wrap_row_used
= row
->used
[TEXT_AREA
];
19458 wrap_row_ascent
= row
->ascent
;
19459 wrap_row_height
= row
->height
;
19460 wrap_row_phys_ascent
= row
->phys_ascent
;
19461 wrap_row_phys_height
= row
->phys_height
;
19462 wrap_row_extra_line_spacing
= row
->extra_line_spacing
;
19463 wrap_row_min_pos
= min_pos
;
19464 wrap_row_min_bpos
= min_bpos
;
19465 wrap_row_max_pos
= max_pos
;
19466 wrap_row_max_bpos
= max_bpos
;
19472 PRODUCE_GLYPHS (it
);
19474 /* If this display element was in marginal areas, continue with
19476 if (it
->area
!= TEXT_AREA
)
19478 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
19479 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
19480 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
19481 row
->phys_height
= max (row
->phys_height
,
19482 it
->max_phys_ascent
+ it
->max_phys_descent
);
19483 row
->extra_line_spacing
= max (row
->extra_line_spacing
,
19484 it
->max_extra_line_spacing
);
19485 set_iterator_to_next (it
, 1);
19489 /* Does the display element fit on the line? If we truncate
19490 lines, we should draw past the right edge of the window. If
19491 we don't truncate, we want to stop so that we can display the
19492 continuation glyph before the right margin. If lines are
19493 continued, there are two possible strategies for characters
19494 resulting in more than 1 glyph (e.g. tabs): Display as many
19495 glyphs as possible in this line and leave the rest for the
19496 continuation line, or display the whole element in the next
19497 line. Original redisplay did the former, so we do it also. */
19498 nglyphs
= row
->used
[TEXT_AREA
] - n_glyphs_before
;
19499 hpos_before
= it
->hpos
;
19502 if (/* Not a newline. */
19504 /* Glyphs produced fit entirely in the line. */
19505 && it
->current_x
< it
->last_visible_x
)
19507 it
->hpos
+= nglyphs
;
19508 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
19509 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
19510 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
19511 row
->phys_height
= max (row
->phys_height
,
19512 it
->max_phys_ascent
+ it
->max_phys_descent
);
19513 row
->extra_line_spacing
= max (row
->extra_line_spacing
,
19514 it
->max_extra_line_spacing
);
19515 if (it
->current_x
- it
->pixel_width
< it
->first_visible_x
)
19516 row
->x
= x
- it
->first_visible_x
;
19517 /* Record the maximum and minimum buffer positions seen so
19518 far in glyphs that will be displayed by this row. */
19520 RECORD_MAX_MIN_POS (it
);
19525 struct glyph
*glyph
;
19527 for (i
= 0; i
< nglyphs
; ++i
, x
= new_x
)
19529 glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
19530 new_x
= x
+ glyph
->pixel_width
;
19532 if (/* Lines are continued. */
19533 it
->line_wrap
!= TRUNCATE
19534 && (/* Glyph doesn't fit on the line. */
19535 new_x
> it
->last_visible_x
19536 /* Or it fits exactly on a window system frame. */
19537 || (new_x
== it
->last_visible_x
19538 && FRAME_WINDOW_P (it
->f
)
19539 && (row
->reversed_p
19540 ? WINDOW_LEFT_FRINGE_WIDTH (it
->w
)
19541 : WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)))))
19543 /* End of a continued line. */
19546 || (new_x
== it
->last_visible_x
19547 && FRAME_WINDOW_P (it
->f
)
19548 && (row
->reversed_p
19549 ? WINDOW_LEFT_FRINGE_WIDTH (it
->w
)
19550 : WINDOW_RIGHT_FRINGE_WIDTH (it
->w
))))
19552 /* Current glyph is the only one on the line or
19553 fits exactly on the line. We must continue
19554 the line because we can't draw the cursor
19555 after the glyph. */
19556 row
->continued_p
= 1;
19557 it
->current_x
= new_x
;
19558 it
->continuation_lines_width
+= new_x
;
19560 if (i
== nglyphs
- 1)
19562 /* If line-wrap is on, check if a previous
19563 wrap point was found. */
19564 if (wrap_row_used
> 0
19565 /* Even if there is a previous wrap
19566 point, continue the line here as
19567 usual, if (i) the previous character
19568 was a space or tab AND (ii) the
19569 current character is not. */
19571 || IT_DISPLAYING_WHITESPACE (it
)))
19574 /* Record the maximum and minimum buffer
19575 positions seen so far in glyphs that will be
19576 displayed by this row. */
19578 RECORD_MAX_MIN_POS (it
);
19579 set_iterator_to_next (it
, 1);
19580 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
19582 if (!get_next_display_element (it
))
19584 row
->exact_window_width_line_p
= 1;
19585 it
->continuation_lines_width
= 0;
19586 row
->continued_p
= 0;
19587 row
->ends_at_zv_p
= 1;
19589 else if (ITERATOR_AT_END_OF_LINE_P (it
))
19591 row
->continued_p
= 0;
19592 row
->exact_window_width_line_p
= 1;
19596 else if (it
->bidi_p
)
19597 RECORD_MAX_MIN_POS (it
);
19599 else if (CHAR_GLYPH_PADDING_P (*glyph
)
19600 && !FRAME_WINDOW_P (it
->f
))
19602 /* A padding glyph that doesn't fit on this line.
19603 This means the whole character doesn't fit
19605 if (row
->reversed_p
)
19606 unproduce_glyphs (it
, row
->used
[TEXT_AREA
]
19607 - n_glyphs_before
);
19608 row
->used
[TEXT_AREA
] = n_glyphs_before
;
19610 /* Fill the rest of the row with continuation
19611 glyphs like in 20.x. */
19612 while (row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
]
19613 < row
->glyphs
[1 + TEXT_AREA
])
19614 produce_special_glyphs (it
, IT_CONTINUATION
);
19616 row
->continued_p
= 1;
19617 it
->current_x
= x_before
;
19618 it
->continuation_lines_width
+= x_before
;
19620 /* Restore the height to what it was before the
19621 element not fitting on the line. */
19622 it
->max_ascent
= ascent
;
19623 it
->max_descent
= descent
;
19624 it
->max_phys_ascent
= phys_ascent
;
19625 it
->max_phys_descent
= phys_descent
;
19627 else if (wrap_row_used
> 0)
19630 if (row
->reversed_p
)
19631 unproduce_glyphs (it
,
19632 row
->used
[TEXT_AREA
] - wrap_row_used
);
19633 RESTORE_IT (it
, &wrap_it
, wrap_data
);
19634 it
->continuation_lines_width
+= wrap_x
;
19635 row
->used
[TEXT_AREA
] = wrap_row_used
;
19636 row
->ascent
= wrap_row_ascent
;
19637 row
->height
= wrap_row_height
;
19638 row
->phys_ascent
= wrap_row_phys_ascent
;
19639 row
->phys_height
= wrap_row_phys_height
;
19640 row
->extra_line_spacing
= wrap_row_extra_line_spacing
;
19641 min_pos
= wrap_row_min_pos
;
19642 min_bpos
= wrap_row_min_bpos
;
19643 max_pos
= wrap_row_max_pos
;
19644 max_bpos
= wrap_row_max_bpos
;
19645 row
->continued_p
= 1;
19646 row
->ends_at_zv_p
= 0;
19647 row
->exact_window_width_line_p
= 0;
19648 it
->continuation_lines_width
+= x
;
19650 /* Make sure that a non-default face is extended
19651 up to the right margin of the window. */
19652 extend_face_to_end_of_line (it
);
19654 else if (it
->c
== '\t' && FRAME_WINDOW_P (it
->f
))
19656 /* A TAB that extends past the right edge of the
19657 window. This produces a single glyph on
19658 window system frames. We leave the glyph in
19659 this row and let it fill the row, but don't
19660 consume the TAB. */
19661 if ((row
->reversed_p
19662 ? WINDOW_LEFT_FRINGE_WIDTH (it
->w
)
19663 : WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)) == 0)
19664 produce_special_glyphs (it
, IT_CONTINUATION
);
19665 it
->continuation_lines_width
+= it
->last_visible_x
;
19666 row
->ends_in_middle_of_char_p
= 1;
19667 row
->continued_p
= 1;
19668 glyph
->pixel_width
= it
->last_visible_x
- x
;
19669 it
->starts_in_middle_of_char_p
= 1;
19673 /* Something other than a TAB that draws past
19674 the right edge of the window. Restore
19675 positions to values before the element. */
19676 if (row
->reversed_p
)
19677 unproduce_glyphs (it
, row
->used
[TEXT_AREA
]
19678 - (n_glyphs_before
+ i
));
19679 row
->used
[TEXT_AREA
] = n_glyphs_before
+ i
;
19681 /* Display continuation glyphs. */
19682 it
->current_x
= x_before
;
19683 it
->continuation_lines_width
+= x
;
19684 if (!FRAME_WINDOW_P (it
->f
)
19685 || (row
->reversed_p
19686 ? WINDOW_LEFT_FRINGE_WIDTH (it
->w
)
19687 : WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)) == 0)
19688 produce_special_glyphs (it
, IT_CONTINUATION
);
19689 row
->continued_p
= 1;
19691 extend_face_to_end_of_line (it
);
19693 if (nglyphs
> 1 && i
> 0)
19695 row
->ends_in_middle_of_char_p
= 1;
19696 it
->starts_in_middle_of_char_p
= 1;
19699 /* Restore the height to what it was before the
19700 element not fitting on the line. */
19701 it
->max_ascent
= ascent
;
19702 it
->max_descent
= descent
;
19703 it
->max_phys_ascent
= phys_ascent
;
19704 it
->max_phys_descent
= phys_descent
;
19709 else if (new_x
> it
->first_visible_x
)
19711 /* Increment number of glyphs actually displayed. */
19714 /* Record the maximum and minimum buffer positions
19715 seen so far in glyphs that will be displayed by
19718 RECORD_MAX_MIN_POS (it
);
19720 if (x
< it
->first_visible_x
)
19721 /* Glyph is partially visible, i.e. row starts at
19722 negative X position. */
19723 row
->x
= x
- it
->first_visible_x
;
19727 /* Glyph is completely off the left margin of the
19728 window. This should not happen because of the
19729 move_it_in_display_line at the start of this
19730 function, unless the text display area of the
19731 window is empty. */
19732 eassert (it
->first_visible_x
<= it
->last_visible_x
);
19735 /* Even if this display element produced no glyphs at all,
19736 we want to record its position. */
19737 if (it
->bidi_p
&& nglyphs
== 0)
19738 RECORD_MAX_MIN_POS (it
);
19740 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
19741 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
19742 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
19743 row
->phys_height
= max (row
->phys_height
,
19744 it
->max_phys_ascent
+ it
->max_phys_descent
);
19745 row
->extra_line_spacing
= max (row
->extra_line_spacing
,
19746 it
->max_extra_line_spacing
);
19748 /* End of this display line if row is continued. */
19749 if (row
->continued_p
|| row
->ends_at_zv_p
)
19754 /* Is this a line end? If yes, we're also done, after making
19755 sure that a non-default face is extended up to the right
19756 margin of the window. */
19757 if (ITERATOR_AT_END_OF_LINE_P (it
))
19759 int used_before
= row
->used
[TEXT_AREA
];
19761 row
->ends_in_newline_from_string_p
= STRINGP (it
->object
);
19763 /* Add a space at the end of the line that is used to
19764 display the cursor there. */
19765 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
19766 append_space_for_newline (it
, 0);
19768 /* Extend the face to the end of the line. */
19769 extend_face_to_end_of_line (it
);
19771 /* Make sure we have the position. */
19772 if (used_before
== 0)
19773 row
->glyphs
[TEXT_AREA
]->charpos
= CHARPOS (it
->position
);
19775 /* Record the position of the newline, for use in
19777 it
->eol_pos
= it
->current
.pos
;
19779 /* Consume the line end. This skips over invisible lines. */
19780 set_iterator_to_next (it
, 1);
19781 it
->continuation_lines_width
= 0;
19785 /* Proceed with next display element. Note that this skips
19786 over lines invisible because of selective display. */
19787 set_iterator_to_next (it
, 1);
19789 /* If we truncate lines, we are done when the last displayed
19790 glyphs reach past the right margin of the window. */
19791 if (it
->line_wrap
== TRUNCATE
19792 && (FRAME_WINDOW_P (it
->f
) && WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)
19793 ? (it
->current_x
>= it
->last_visible_x
)
19794 : (it
->current_x
> it
->last_visible_x
)))
19796 /* Maybe add truncation glyphs. */
19797 if (!FRAME_WINDOW_P (it
->f
)
19798 || (row
->reversed_p
19799 ? WINDOW_LEFT_FRINGE_WIDTH (it
->w
)
19800 : WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)) == 0)
19804 if (!row
->reversed_p
)
19806 for (i
= row
->used
[TEXT_AREA
] - 1; i
> 0; --i
)
19807 if (!CHAR_GLYPH_PADDING_P (row
->glyphs
[TEXT_AREA
][i
]))
19812 for (i
= 0; i
< row
->used
[TEXT_AREA
]; i
++)
19813 if (!CHAR_GLYPH_PADDING_P (row
->glyphs
[TEXT_AREA
][i
]))
19815 /* Remove any padding glyphs at the front of ROW, to
19816 make room for the truncation glyphs we will be
19817 adding below. The loop below always inserts at
19818 least one truncation glyph, so also remove the
19819 last glyph added to ROW. */
19820 unproduce_glyphs (it
, i
+ 1);
19821 /* Adjust i for the loop below. */
19822 i
= row
->used
[TEXT_AREA
] - (i
+ 1);
19825 it
->current_x
= x_before
;
19826 if (!FRAME_WINDOW_P (it
->f
))
19828 for (n
= row
->used
[TEXT_AREA
]; i
< n
; ++i
)
19830 row
->used
[TEXT_AREA
] = i
;
19831 produce_special_glyphs (it
, IT_TRUNCATION
);
19836 row
->used
[TEXT_AREA
] = i
;
19837 produce_special_glyphs (it
, IT_TRUNCATION
);
19840 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
19842 /* Don't truncate if we can overflow newline into fringe. */
19843 if (!get_next_display_element (it
))
19845 it
->continuation_lines_width
= 0;
19846 row
->ends_at_zv_p
= 1;
19847 row
->exact_window_width_line_p
= 1;
19850 if (ITERATOR_AT_END_OF_LINE_P (it
))
19852 row
->exact_window_width_line_p
= 1;
19853 goto at_end_of_line
;
19855 it
->current_x
= x_before
;
19858 row
->truncated_on_right_p
= 1;
19859 it
->continuation_lines_width
= 0;
19860 reseat_at_next_visible_line_start (it
, 0);
19861 row
->ends_at_zv_p
= FETCH_BYTE (IT_BYTEPOS (*it
) - 1) != '\n';
19862 it
->hpos
= hpos_before
;
19868 bidi_unshelve_cache (wrap_data
, 1);
19870 /* If line is not empty and hscrolled, maybe insert truncation glyphs
19871 at the left window margin. */
19872 if (it
->first_visible_x
19873 && IT_CHARPOS (*it
) != CHARPOS (row
->start
.pos
))
19875 if (!FRAME_WINDOW_P (it
->f
)
19876 || (row
->reversed_p
19877 ? WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)
19878 : WINDOW_LEFT_FRINGE_WIDTH (it
->w
)) == 0)
19879 insert_left_trunc_glyphs (it
);
19880 row
->truncated_on_left_p
= 1;
19883 /* Remember the position at which this line ends.
19885 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
19886 cannot be before the call to find_row_edges below, since that is
19887 where these positions are determined. */
19888 row
->end
= it
->current
;
19891 row
->minpos
= row
->start
.pos
;
19892 row
->maxpos
= row
->end
.pos
;
19896 /* ROW->minpos and ROW->maxpos must be the smallest and
19897 `1 + the largest' buffer positions in ROW. But if ROW was
19898 bidi-reordered, these two positions can be anywhere in the
19899 row, so we must determine them now. */
19900 find_row_edges (it
, row
, min_pos
, min_bpos
, max_pos
, max_bpos
);
19903 /* If the start of this line is the overlay arrow-position, then
19904 mark this glyph row as the one containing the overlay arrow.
19905 This is clearly a mess with variable size fonts. It would be
19906 better to let it be displayed like cursors under X. */
19907 if ((MATRIX_ROW_DISPLAYS_TEXT_P (row
) || !overlay_arrow_seen
)
19908 && (overlay_arrow_string
= overlay_arrow_at_row (it
, row
),
19909 !NILP (overlay_arrow_string
)))
19911 /* Overlay arrow in window redisplay is a fringe bitmap. */
19912 if (STRINGP (overlay_arrow_string
))
19914 struct glyph_row
*arrow_row
19915 = get_overlay_arrow_glyph_row (it
->w
, overlay_arrow_string
);
19916 struct glyph
*glyph
= arrow_row
->glyphs
[TEXT_AREA
];
19917 struct glyph
*arrow_end
= glyph
+ arrow_row
->used
[TEXT_AREA
];
19918 struct glyph
*p
= row
->glyphs
[TEXT_AREA
];
19919 struct glyph
*p2
, *end
;
19921 /* Copy the arrow glyphs. */
19922 while (glyph
< arrow_end
)
19925 /* Throw away padding glyphs. */
19927 end
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
];
19928 while (p2
< end
&& CHAR_GLYPH_PADDING_P (*p2
))
19934 row
->used
[TEXT_AREA
] = p2
- row
->glyphs
[TEXT_AREA
];
19939 eassert (INTEGERP (overlay_arrow_string
));
19940 row
->overlay_arrow_bitmap
= XINT (overlay_arrow_string
);
19942 overlay_arrow_seen
= 1;
19945 /* Highlight trailing whitespace. */
19946 if (!NILP (Vshow_trailing_whitespace
))
19947 highlight_trailing_whitespace (it
->f
, it
->glyph_row
);
19949 /* Compute pixel dimensions of this line. */
19950 compute_line_metrics (it
);
19952 /* Implementation note: No changes in the glyphs of ROW or in their
19953 faces can be done past this point, because compute_line_metrics
19954 computes ROW's hash value and stores it within the glyph_row
19957 /* Record whether this row ends inside an ellipsis. */
19958 row
->ends_in_ellipsis_p
19959 = (it
->method
== GET_FROM_DISPLAY_VECTOR
19960 && it
->ellipsis_p
);
19962 /* Save fringe bitmaps in this row. */
19963 row
->left_user_fringe_bitmap
= it
->left_user_fringe_bitmap
;
19964 row
->left_user_fringe_face_id
= it
->left_user_fringe_face_id
;
19965 row
->right_user_fringe_bitmap
= it
->right_user_fringe_bitmap
;
19966 row
->right_user_fringe_face_id
= it
->right_user_fringe_face_id
;
19968 it
->left_user_fringe_bitmap
= 0;
19969 it
->left_user_fringe_face_id
= 0;
19970 it
->right_user_fringe_bitmap
= 0;
19971 it
->right_user_fringe_face_id
= 0;
19973 /* Maybe set the cursor. */
19974 cvpos
= it
->w
->cursor
.vpos
;
19976 /* In bidi-reordered rows, keep checking for proper cursor
19977 position even if one has been found already, because buffer
19978 positions in such rows change non-linearly with ROW->VPOS,
19979 when a line is continued. One exception: when we are at ZV,
19980 display cursor on the first suitable glyph row, since all
19981 the empty rows after that also have their position set to ZV. */
19982 /* FIXME: Revisit this when glyph ``spilling'' in continuation
19983 lines' rows is implemented for bidi-reordered rows. */
19985 && !MATRIX_ROW (it
->w
->desired_matrix
, cvpos
)->ends_at_zv_p
))
19986 && PT
>= MATRIX_ROW_START_CHARPOS (row
)
19987 && PT
<= MATRIX_ROW_END_CHARPOS (row
)
19988 && cursor_row_p (row
))
19989 set_cursor_from_row (it
->w
, row
, it
->w
->desired_matrix
, 0, 0, 0, 0);
19991 /* Prepare for the next line. This line starts horizontally at (X
19992 HPOS) = (0 0). Vertical positions are incremented. As a
19993 convenience for the caller, IT->glyph_row is set to the next
19995 it
->current_x
= it
->hpos
= 0;
19996 it
->current_y
+= row
->height
;
19997 SET_TEXT_POS (it
->eol_pos
, 0, 0);
20000 /* The next row should by default use the same value of the
20001 reversed_p flag as this one. set_iterator_to_next decides when
20002 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
20003 the flag accordingly. */
20004 if (it
->glyph_row
< MATRIX_BOTTOM_TEXT_ROW (it
->w
->desired_matrix
, it
->w
))
20005 it
->glyph_row
->reversed_p
= row
->reversed_p
;
20006 it
->start
= row
->end
;
20007 return MATRIX_ROW_DISPLAYS_TEXT_P (row
);
20009 #undef RECORD_MAX_MIN_POS
20012 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction
,
20013 Scurrent_bidi_paragraph_direction
, 0, 1, 0,
20014 doc
: /* Return paragraph direction at point in BUFFER.
20015 Value is either `left-to-right' or `right-to-left'.
20016 If BUFFER is omitted or nil, it defaults to the current buffer.
20018 Paragraph direction determines how the text in the paragraph is displayed.
20019 In left-to-right paragraphs, text begins at the left margin of the window
20020 and the reading direction is generally left to right. In right-to-left
20021 paragraphs, text begins at the right margin and is read from right to left.
20023 See also `bidi-paragraph-direction'. */)
20024 (Lisp_Object buffer
)
20026 struct buffer
*buf
= current_buffer
;
20027 struct buffer
*old
= buf
;
20029 if (! NILP (buffer
))
20031 CHECK_BUFFER (buffer
);
20032 buf
= XBUFFER (buffer
);
20035 if (NILP (BVAR (buf
, bidi_display_reordering
))
20036 || NILP (BVAR (buf
, enable_multibyte_characters
))
20037 /* When we are loading loadup.el, the character property tables
20038 needed for bidi iteration are not yet available. */
20039 || !NILP (Vpurify_flag
))
20040 return Qleft_to_right
;
20041 else if (!NILP (BVAR (buf
, bidi_paragraph_direction
)))
20042 return BVAR (buf
, bidi_paragraph_direction
);
20045 /* Determine the direction from buffer text. We could try to
20046 use current_matrix if it is up to date, but this seems fast
20047 enough as it is. */
20048 struct bidi_it itb
;
20049 ptrdiff_t pos
= BUF_PT (buf
);
20050 ptrdiff_t bytepos
= BUF_PT_BYTE (buf
);
20052 void *itb_data
= bidi_shelve_cache ();
20054 set_buffer_temp (buf
);
20055 /* bidi_paragraph_init finds the base direction of the paragraph
20056 by searching forward from paragraph start. We need the base
20057 direction of the current or _previous_ paragraph, so we need
20058 to make sure we are within that paragraph. To that end, find
20059 the previous non-empty line. */
20060 if (pos
>= ZV
&& pos
> BEGV
)
20061 DEC_BOTH (pos
, bytepos
);
20062 if (fast_looking_at (build_string ("[\f\t ]*\n"),
20063 pos
, bytepos
, ZV
, ZV_BYTE
, Qnil
) > 0)
20065 while ((c
= FETCH_BYTE (bytepos
)) == '\n'
20066 || c
== ' ' || c
== '\t' || c
== '\f')
20068 if (bytepos
<= BEGV_BYTE
)
20073 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos
)))
20076 bidi_init_it (pos
, bytepos
, FRAME_WINDOW_P (SELECTED_FRAME ()), &itb
);
20077 itb
.paragraph_dir
= NEUTRAL_DIR
;
20078 itb
.string
.s
= NULL
;
20079 itb
.string
.lstring
= Qnil
;
20080 itb
.string
.bufpos
= 0;
20081 itb
.string
.unibyte
= 0;
20082 /* We have no window to use here for ignoring window-specific
20083 overlays. Using NULL for window pointer will cause
20084 compute_display_string_pos to use the current buffer. */
20086 bidi_paragraph_init (NEUTRAL_DIR
, &itb
, 1);
20087 bidi_unshelve_cache (itb_data
, 0);
20088 set_buffer_temp (old
);
20089 switch (itb
.paragraph_dir
)
20092 return Qleft_to_right
;
20095 return Qright_to_left
;
20103 DEFUN ("move-point-visually", Fmove_point_visually
,
20104 Smove_point_visually
, 1, 1, 0,
20105 doc
: /* Move point in the visual order in the specified DIRECTION.
20106 DIRECTION can be 1, meaning move to the right, or -1, which moves to the
20109 Value is the new character position of point. */)
20110 (Lisp_Object direction
)
20112 struct window
*w
= XWINDOW (selected_window
);
20113 struct buffer
*b
= XBUFFER (w
->contents
);
20114 struct glyph_row
*row
;
20116 Lisp_Object paragraph_dir
;
20118 #define ROW_GLYPH_NEWLINE_P(ROW,GLYPH) \
20119 (!(ROW)->continued_p \
20120 && INTEGERP ((GLYPH)->object) \
20121 && (GLYPH)->type == CHAR_GLYPH \
20122 && (GLYPH)->u.ch == ' ' \
20123 && (GLYPH)->charpos >= 0 \
20124 && !(GLYPH)->avoid_cursor_p)
20126 CHECK_NUMBER (direction
);
20127 dir
= XINT (direction
);
20133 /* If current matrix is up-to-date, we can use the information
20134 recorded in the glyphs, at least as long as the goal is on the
20136 if (w
->window_end_valid
20137 && !windows_or_buffers_changed
20139 && !b
->clip_changed
20140 && !b
->prevent_redisplay_optimizations_p
20141 && !window_outdated (w
)
20142 && w
->cursor
.vpos
>= 0
20143 && w
->cursor
.vpos
< w
->current_matrix
->nrows
20144 && (row
= MATRIX_ROW (w
->current_matrix
, w
->cursor
.vpos
))->enabled_p
)
20146 struct glyph
*g
= row
->glyphs
[TEXT_AREA
];
20147 struct glyph
*e
= dir
> 0 ? g
+ row
->used
[TEXT_AREA
] : g
- 1;
20148 struct glyph
*gpt
= g
+ w
->cursor
.hpos
;
20150 for (g
= gpt
+ dir
; (dir
> 0 ? g
< e
: g
> e
); g
+= dir
)
20152 if (BUFFERP (g
->object
) && g
->charpos
!= PT
)
20154 SET_PT (g
->charpos
);
20155 w
->cursor
.vpos
= -1;
20156 return make_number (PT
);
20158 else if (!INTEGERP (g
->object
) && !EQ (g
->object
, gpt
->object
))
20162 if (BUFFERP (gpt
->object
))
20165 if ((gpt
->resolved_level
- row
->reversed_p
) % 2 == 0)
20166 new_pos
+= (row
->reversed_p
? -dir
: dir
);
20168 new_pos
-= (row
->reversed_p
? -dir
: dir
);;
20170 else if (BUFFERP (g
->object
))
20171 new_pos
= g
->charpos
;
20175 w
->cursor
.vpos
= -1;
20176 return make_number (PT
);
20178 else if (ROW_GLYPH_NEWLINE_P (row
, g
))
20180 /* Glyphs inserted at the end of a non-empty line for
20181 positioning the cursor have zero charpos, so we must
20182 deduce the value of point by other means. */
20183 if (g
->charpos
> 0)
20184 SET_PT (g
->charpos
);
20185 else if (row
->ends_at_zv_p
&& PT
!= ZV
)
20187 else if (PT
!= MATRIX_ROW_END_CHARPOS (row
) - 1)
20188 SET_PT (MATRIX_ROW_END_CHARPOS (row
) - 1);
20191 w
->cursor
.vpos
= -1;
20192 return make_number (PT
);
20195 if (g
== e
|| INTEGERP (g
->object
))
20197 if (row
->truncated_on_left_p
|| row
->truncated_on_right_p
)
20198 goto simulate_display
;
20199 if (!row
->reversed_p
)
20203 if (row
< MATRIX_FIRST_TEXT_ROW (w
->current_matrix
)
20204 || row
> MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
))
20205 goto simulate_display
;
20209 if (row
->reversed_p
&& !row
->continued_p
)
20211 SET_PT (MATRIX_ROW_END_CHARPOS (row
) - 1);
20212 w
->cursor
.vpos
= -1;
20213 return make_number (PT
);
20215 g
= row
->glyphs
[TEXT_AREA
];
20216 e
= g
+ row
->used
[TEXT_AREA
];
20217 for ( ; g
< e
; g
++)
20219 if (BUFFERP (g
->object
)
20220 /* Empty lines have only one glyph, which stands
20221 for the newline, and whose charpos is the
20222 buffer position of the newline. */
20223 || ROW_GLYPH_NEWLINE_P (row
, g
)
20224 /* When the buffer ends in a newline, the line at
20225 EOB also has one glyph, but its charpos is -1. */
20226 || (row
->ends_at_zv_p
20227 && !row
->reversed_p
20228 && INTEGERP (g
->object
)
20229 && g
->type
== CHAR_GLYPH
20230 && g
->u
.ch
== ' '))
20232 if (g
->charpos
> 0)
20233 SET_PT (g
->charpos
);
20234 else if (!row
->reversed_p
20235 && row
->ends_at_zv_p
20240 w
->cursor
.vpos
= -1;
20241 return make_number (PT
);
20247 if (!row
->reversed_p
&& !row
->continued_p
)
20249 SET_PT (MATRIX_ROW_END_CHARPOS (row
) - 1);
20250 w
->cursor
.vpos
= -1;
20251 return make_number (PT
);
20253 e
= row
->glyphs
[TEXT_AREA
];
20254 g
= e
+ row
->used
[TEXT_AREA
] - 1;
20255 for ( ; g
>= e
; g
--)
20257 if (BUFFERP (g
->object
)
20258 || (ROW_GLYPH_NEWLINE_P (row
, g
)
20260 /* Empty R2L lines on GUI frames have the buffer
20261 position of the newline stored in the stretch
20263 || g
->type
== STRETCH_GLYPH
20264 || (row
->ends_at_zv_p
20266 && INTEGERP (g
->object
)
20267 && g
->type
== CHAR_GLYPH
20268 && g
->u
.ch
== ' '))
20270 if (g
->charpos
> 0)
20271 SET_PT (g
->charpos
);
20272 else if (row
->reversed_p
20273 && row
->ends_at_zv_p
20278 w
->cursor
.vpos
= -1;
20279 return make_number (PT
);
20288 /* If we wind up here, we failed to move by using the glyphs, so we
20289 need to simulate display instead. */
20292 paragraph_dir
= Fcurrent_bidi_paragraph_direction (w
->contents
);
20294 paragraph_dir
= Qleft_to_right
;
20295 if (EQ (paragraph_dir
, Qright_to_left
))
20297 if (PT
<= BEGV
&& dir
< 0)
20298 xsignal0 (Qbeginning_of_buffer
);
20299 else if (PT
>= ZV
&& dir
> 0)
20300 xsignal0 (Qend_of_buffer
);
20303 struct text_pos pt
;
20305 int pt_x
, target_x
, pixel_width
, pt_vpos
;
20307 bool overshoot_expected
= false;
20308 bool target_is_eol_p
= false;
20310 /* Setup the arena. */
20311 SET_TEXT_POS (pt
, PT
, PT_BYTE
);
20312 start_display (&it
, w
, pt
);
20314 if (it
.cmp_it
.id
< 0
20315 && it
.method
== GET_FROM_STRING
20316 && it
.area
== TEXT_AREA
20317 && it
.string_from_display_prop_p
20318 && (it
.sp
> 0 && it
.stack
[it
.sp
- 1].method
== GET_FROM_BUFFER
))
20319 overshoot_expected
= true;
20321 /* Find the X coordinate of point. We start from the beginning
20322 of this or previous line to make sure we are before point in
20323 the logical order (since the move_it_* functions can only
20325 reseat_at_previous_visible_line_start (&it
);
20326 it
.current_x
= it
.hpos
= it
.current_y
= it
.vpos
= 0;
20327 if (IT_CHARPOS (it
) != PT
)
20328 move_it_to (&it
, overshoot_expected
? PT
- 1 : PT
,
20329 -1, -1, -1, MOVE_TO_POS
);
20330 pt_x
= it
.current_x
;
20332 if (dir
> 0 || overshoot_expected
)
20334 struct glyph_row
*row
= it
.glyph_row
;
20336 /* When point is at beginning of line, we don't have
20337 information about the glyph there loaded into struct
20338 it. Calling get_next_display_element fixes that. */
20340 get_next_display_element (&it
);
20341 at_eol_p
= ITERATOR_AT_END_OF_LINE_P (&it
);
20342 it
.glyph_row
= NULL
;
20343 PRODUCE_GLYPHS (&it
); /* compute it.pixel_width */
20344 it
.glyph_row
= row
;
20345 /* PRODUCE_GLYPHS advances it.current_x, so we must restore
20346 it, lest it will become out of sync with it's buffer
20348 it
.current_x
= pt_x
;
20351 at_eol_p
= ITERATOR_AT_END_OF_LINE_P (&it
);
20352 pixel_width
= it
.pixel_width
;
20353 if (overshoot_expected
&& at_eol_p
)
20355 else if (pixel_width
<= 0)
20358 /* If there's a display string at point, we are actually at the
20359 glyph to the left of point, so we need to correct the X
20361 if (overshoot_expected
)
20362 pt_x
+= pixel_width
;
20364 /* Compute target X coordinate, either to the left or to the
20365 right of point. On TTY frames, all characters have the same
20366 pixel width of 1, so we can use that. On GUI frames we don't
20367 have an easy way of getting at the pixel width of the
20368 character to the left of point, so we use a different method
20369 of getting to that place. */
20371 target_x
= pt_x
+ pixel_width
;
20373 target_x
= pt_x
- (!FRAME_WINDOW_P (it
.f
)) * pixel_width
;
20375 /* Target X coordinate could be one line above or below the line
20376 of point, in which case we need to adjust the target X
20377 coordinate. Also, if moving to the left, we need to begin at
20378 the left edge of the point's screen line. */
20383 start_display (&it
, w
, pt
);
20384 reseat_at_previous_visible_line_start (&it
);
20385 it
.current_x
= it
.current_y
= it
.hpos
= 0;
20387 move_it_by_lines (&it
, pt_vpos
);
20391 move_it_by_lines (&it
, -1);
20392 target_x
= it
.last_visible_x
- !FRAME_WINDOW_P (it
.f
);
20393 target_is_eol_p
= true;
20399 || (target_x
>= it
.last_visible_x
20400 && it
.line_wrap
!= TRUNCATE
))
20403 move_it_by_lines (&it
, 0);
20404 move_it_by_lines (&it
, 1);
20409 /* Move to the target X coordinate. */
20410 #ifdef HAVE_WINDOW_SYSTEM
20411 /* On GUI frames, as we don't know the X coordinate of the
20412 character to the left of point, moving point to the left
20413 requires walking, one grapheme cluster at a time, until we
20414 find ourself at a place immediately to the left of the
20415 character at point. */
20416 if (FRAME_WINDOW_P (it
.f
) && dir
< 0)
20418 struct text_pos new_pos
= it
.current
.pos
;
20419 enum move_it_result rc
= MOVE_X_REACHED
;
20421 while (it
.current_x
+ it
.pixel_width
<= target_x
20422 && rc
== MOVE_X_REACHED
)
20424 int new_x
= it
.current_x
+ it
.pixel_width
;
20426 new_pos
= it
.current
.pos
;
20427 if (new_x
== it
.current_x
)
20429 rc
= move_it_in_display_line_to (&it
, ZV
, new_x
,
20430 MOVE_TO_POS
| MOVE_TO_X
);
20431 if (ITERATOR_AT_END_OF_LINE_P (&it
) && !target_is_eol_p
)
20434 /* If we ended up on a composed character inside
20435 bidi-reordered text (e.g., Hebrew text with diacritics),
20436 the iterator gives us the buffer position of the last (in
20437 logical order) character of the composed grapheme cluster,
20438 which is not what we want. So we cheat: we compute the
20439 character position of the character that follows (in the
20440 logical order) the one where the above loop stopped. That
20441 character will appear on display to the left of point. */
20443 && it
.bidi_it
.scan_dir
== -1
20444 && new_pos
.charpos
- IT_CHARPOS (it
) > 1)
20446 new_pos
.charpos
= IT_CHARPOS (it
) + 1;
20447 new_pos
.bytepos
= CHAR_TO_BYTE (new_pos
.charpos
);
20449 it
.current
.pos
= new_pos
;
20453 if (it
.current_x
!= target_x
)
20454 move_it_in_display_line_to (&it
, ZV
, target_x
, MOVE_TO_POS
| MOVE_TO_X
);
20456 /* When lines are truncated, the above loop will stop at the
20457 window edge. But we want to get to the end of line, even if
20458 it is beyond the window edge; automatic hscroll will then
20459 scroll the window to show point as appropriate. */
20460 if (target_is_eol_p
&& it
.line_wrap
== TRUNCATE
20461 && get_next_display_element (&it
))
20463 struct text_pos new_pos
= it
.current
.pos
;
20465 while (!ITERATOR_AT_END_OF_LINE_P (&it
))
20467 set_iterator_to_next (&it
, 0);
20468 if (it
.method
== GET_FROM_BUFFER
)
20469 new_pos
= it
.current
.pos
;
20470 if (!get_next_display_element (&it
))
20474 it
.current
.pos
= new_pos
;
20477 /* If we ended up in a display string that covers point, move to
20478 buffer position to the right in the visual order. */
20481 while (IT_CHARPOS (it
) == PT
)
20483 set_iterator_to_next (&it
, 0);
20484 if (!get_next_display_element (&it
))
20489 /* Move point to that position. */
20490 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
20493 return make_number (PT
);
20495 #undef ROW_GLYPH_NEWLINE_P
20499 /***********************************************************************
20501 ***********************************************************************/
20503 /* Redisplay the menu bar in the frame for window W.
20505 The menu bar of X frames that don't have X toolkit support is
20506 displayed in a special window W->frame->menu_bar_window.
20508 The menu bar of terminal frames is treated specially as far as
20509 glyph matrices are concerned. Menu bar lines are not part of
20510 windows, so the update is done directly on the frame matrix rows
20511 for the menu bar. */
20514 display_menu_bar (struct window
*w
)
20516 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
20521 /* Don't do all this for graphical frames. */
20523 if (FRAME_W32_P (f
))
20526 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
20532 if (FRAME_NS_P (f
))
20534 #endif /* HAVE_NS */
20536 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
20537 eassert (!FRAME_WINDOW_P (f
));
20538 init_iterator (&it
, w
, -1, -1, f
->desired_matrix
->rows
, MENU_FACE_ID
);
20539 it
.first_visible_x
= 0;
20540 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
20541 #elif defined (HAVE_X_WINDOWS) /* X without toolkit. */
20542 if (FRAME_WINDOW_P (f
))
20544 /* Menu bar lines are displayed in the desired matrix of the
20545 dummy window menu_bar_window. */
20546 struct window
*menu_w
;
20547 menu_w
= XWINDOW (f
->menu_bar_window
);
20548 init_iterator (&it
, menu_w
, -1, -1, menu_w
->desired_matrix
->rows
,
20550 it
.first_visible_x
= 0;
20551 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
20554 #endif /* not USE_X_TOOLKIT and not USE_GTK */
20556 /* This is a TTY frame, i.e. character hpos/vpos are used as
20558 init_iterator (&it
, w
, -1, -1, f
->desired_matrix
->rows
,
20560 it
.first_visible_x
= 0;
20561 it
.last_visible_x
= FRAME_COLS (f
);
20564 /* FIXME: This should be controlled by a user option. See the
20565 comments in redisplay_tool_bar and display_mode_line about
20567 it
.paragraph_embedding
= L2R
;
20569 /* Clear all rows of the menu bar. */
20570 for (i
= 0; i
< FRAME_MENU_BAR_LINES (f
); ++i
)
20572 struct glyph_row
*row
= it
.glyph_row
+ i
;
20573 clear_glyph_row (row
);
20574 row
->enabled_p
= 1;
20575 row
->full_width_p
= 1;
20578 /* Display all items of the menu bar. */
20579 items
= FRAME_MENU_BAR_ITEMS (it
.f
);
20580 for (i
= 0; i
< ASIZE (items
); i
+= 4)
20582 Lisp_Object string
;
20584 /* Stop at nil string. */
20585 string
= AREF (items
, i
+ 1);
20589 /* Remember where item was displayed. */
20590 ASET (items
, i
+ 3, make_number (it
.hpos
));
20592 /* Display the item, pad with one space. */
20593 if (it
.current_x
< it
.last_visible_x
)
20594 display_string (NULL
, string
, Qnil
, 0, 0, &it
,
20595 SCHARS (string
) + 1, 0, 0, -1);
20598 /* Fill out the line with spaces. */
20599 if (it
.current_x
< it
.last_visible_x
)
20600 display_string ("", Qnil
, Qnil
, 0, 0, &it
, -1, 0, 0, -1);
20602 /* Compute the total height of the lines. */
20603 compute_line_metrics (&it
);
20607 /* Deep copy of a glyph row, including the glyphs. */
20609 deep_copy_glyph_row (struct glyph_row
*to
, struct glyph_row
*from
)
20611 struct glyph
*pointers
[1 + LAST_AREA
];
20612 int to_used
= to
->used
[TEXT_AREA
];
20614 /* Save glyph pointers of TO. */
20615 memcpy (pointers
, to
->glyphs
, sizeof to
->glyphs
);
20617 /* Do a structure assignment. */
20620 /* Restore original glyph pointers of TO. */
20621 memcpy (to
->glyphs
, pointers
, sizeof to
->glyphs
);
20623 /* Copy the glyphs. */
20624 memcpy (to
->glyphs
[TEXT_AREA
], from
->glyphs
[TEXT_AREA
],
20625 min (from
->used
[TEXT_AREA
], to_used
) * sizeof (struct glyph
));
20627 /* If we filled only part of the TO row, fill the rest with
20628 space_glyph (which will display as empty space). */
20629 if (to_used
> from
->used
[TEXT_AREA
])
20630 fill_up_frame_row_with_spaces (to
, to_used
);
20633 /* Display one menu item on a TTY, by overwriting the glyphs in the
20634 frame F's desired glyph matrix with glyphs produced from the menu
20635 item text. Called from term.c to display TTY drop-down menus one
20638 ITEM_TEXT is the menu item text as a C string.
20640 FACE_ID is the face ID to be used for this menu item. FACE_ID
20641 could specify one of 3 faces: a face for an enabled item, a face
20642 for a disabled item, or a face for a selected item.
20644 X and Y are coordinates of the first glyph in the frame's desired
20645 matrix to be overwritten by the menu item. Since this is a TTY, Y
20646 is the zero-based number of the glyph row and X is the zero-based
20647 glyph number in the row, starting from left, where to start
20648 displaying the item.
20650 SUBMENU non-zero means this menu item drops down a submenu, which
20651 should be indicated by displaying a proper visual cue after the
20655 display_tty_menu_item (const char *item_text
, int width
, int face_id
,
20656 int x
, int y
, int submenu
)
20659 struct frame
*f
= SELECTED_FRAME ();
20660 struct window
*w
= XWINDOW (f
->selected_window
);
20661 int saved_used
, saved_truncated
, saved_width
, saved_reversed
;
20662 struct glyph_row
*row
;
20663 size_t item_len
= strlen (item_text
);
20665 eassert (FRAME_TERMCAP_P (f
));
20667 /* Don't write beyond the matrix's last row. This can happen for
20668 TTY screens that are not high enough to show the entire menu.
20669 (This is actually a bit of defensive programming, as
20670 tty_menu_display already limits the number of menu items to one
20671 less than the number of screen lines.) */
20672 if (y
>= f
->desired_matrix
->nrows
)
20675 init_iterator (&it
, w
, -1, -1, f
->desired_matrix
->rows
+ y
, MENU_FACE_ID
);
20676 it
.first_visible_x
= 0;
20677 it
.last_visible_x
= FRAME_COLS (f
) - 1;
20678 row
= it
.glyph_row
;
20679 /* Start with the row contents from the current matrix. */
20680 deep_copy_glyph_row (row
, f
->current_matrix
->rows
+ y
);
20681 saved_width
= row
->full_width_p
;
20682 row
->full_width_p
= 1;
20683 saved_reversed
= row
->reversed_p
;
20684 row
->reversed_p
= 0;
20685 row
->enabled_p
= 1;
20687 /* Arrange for the menu item glyphs to start at (X,Y) and have the
20689 eassert (x
< f
->desired_matrix
->matrix_w
);
20690 it
.current_x
= it
.hpos
= x
;
20691 it
.current_y
= it
.vpos
= y
;
20692 saved_used
= row
->used
[TEXT_AREA
];
20693 saved_truncated
= row
->truncated_on_right_p
;
20694 row
->used
[TEXT_AREA
] = x
;
20695 it
.face_id
= face_id
;
20696 it
.line_wrap
= TRUNCATE
;
20698 /* FIXME: This should be controlled by a user option. See the
20699 comments in redisplay_tool_bar and display_mode_line about this.
20700 Also, if paragraph_embedding could ever be R2L, changes will be
20701 needed to avoid shifting to the right the row characters in
20702 term.c:append_glyph. */
20703 it
.paragraph_embedding
= L2R
;
20705 /* Pad with a space on the left. */
20706 display_string (" ", Qnil
, Qnil
, 0, 0, &it
, 1, 0, FRAME_COLS (f
) - 1, -1);
20708 /* Display the menu item, pad with spaces to WIDTH. */
20711 display_string (item_text
, Qnil
, Qnil
, 0, 0, &it
,
20712 item_len
, 0, FRAME_COLS (f
) - 1, -1);
20714 /* Indicate with " >" that there's a submenu. */
20715 display_string (" >", Qnil
, Qnil
, 0, 0, &it
, width
, 0,
20716 FRAME_COLS (f
) - 1, -1);
20719 display_string (item_text
, Qnil
, Qnil
, 0, 0, &it
,
20720 width
, 0, FRAME_COLS (f
) - 1, -1);
20722 row
->used
[TEXT_AREA
] = max (saved_used
, row
->used
[TEXT_AREA
]);
20723 row
->truncated_on_right_p
= saved_truncated
;
20724 row
->hash
= row_hash (row
);
20725 row
->full_width_p
= saved_width
;
20726 row
->reversed_p
= saved_reversed
;
20728 #endif /* HAVE_MENUS */
20730 /***********************************************************************
20732 ***********************************************************************/
20734 /* Redisplay mode lines in the window tree whose root is WINDOW. If
20735 FORCE is non-zero, redisplay mode lines unconditionally.
20736 Otherwise, redisplay only mode lines that are garbaged. Value is
20737 the number of windows whose mode lines were redisplayed. */
20740 redisplay_mode_lines (Lisp_Object window
, int force
)
20744 while (!NILP (window
))
20746 struct window
*w
= XWINDOW (window
);
20748 if (WINDOWP (w
->contents
))
20749 nwindows
+= redisplay_mode_lines (w
->contents
, force
);
20751 || FRAME_GARBAGED_P (XFRAME (w
->frame
))
20752 || !MATRIX_MODE_LINE_ROW (w
->current_matrix
)->enabled_p
)
20754 struct text_pos lpoint
;
20755 struct buffer
*old
= current_buffer
;
20757 /* Set the window's buffer for the mode line display. */
20758 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
20759 set_buffer_internal_1 (XBUFFER (w
->contents
));
20761 /* Point refers normally to the selected window. For any
20762 other window, set up appropriate value. */
20763 if (!EQ (window
, selected_window
))
20765 struct text_pos pt
;
20767 CLIP_TEXT_POS_FROM_MARKER (pt
, w
->pointm
);
20768 TEMP_SET_PT_BOTH (CHARPOS (pt
), BYTEPOS (pt
));
20771 /* Display mode lines. */
20772 clear_glyph_matrix (w
->desired_matrix
);
20773 if (display_mode_lines (w
))
20776 w
->must_be_updated_p
= 1;
20779 /* Restore old settings. */
20780 set_buffer_internal_1 (old
);
20781 TEMP_SET_PT_BOTH (CHARPOS (lpoint
), BYTEPOS (lpoint
));
20791 /* Display the mode and/or header line of window W. Value is the
20792 sum number of mode lines and header lines displayed. */
20795 display_mode_lines (struct window
*w
)
20797 Lisp_Object old_selected_window
= selected_window
;
20798 Lisp_Object old_selected_frame
= selected_frame
;
20799 Lisp_Object new_frame
= w
->frame
;
20800 Lisp_Object old_frame_selected_window
= XFRAME (new_frame
)->selected_window
;
20803 selected_frame
= new_frame
;
20804 /* FIXME: If we were to allow the mode-line's computation changing the buffer
20805 or window's point, then we'd need select_window_1 here as well. */
20806 XSETWINDOW (selected_window
, w
);
20807 XFRAME (new_frame
)->selected_window
= selected_window
;
20809 /* These will be set while the mode line specs are processed. */
20810 line_number_displayed
= 0;
20811 w
->column_number_displayed
= -1;
20813 if (WINDOW_WANTS_MODELINE_P (w
))
20815 struct window
*sel_w
= XWINDOW (old_selected_window
);
20817 /* Select mode line face based on the real selected window. */
20818 display_mode_line (w
, CURRENT_MODE_LINE_FACE_ID_3 (sel_w
, sel_w
, w
),
20819 BVAR (current_buffer
, mode_line_format
));
20823 if (WINDOW_WANTS_HEADER_LINE_P (w
))
20825 display_mode_line (w
, HEADER_LINE_FACE_ID
,
20826 BVAR (current_buffer
, header_line_format
));
20830 XFRAME (new_frame
)->selected_window
= old_frame_selected_window
;
20831 selected_frame
= old_selected_frame
;
20832 selected_window
= old_selected_window
;
20837 /* Display mode or header line of window W. FACE_ID specifies which
20838 line to display; it is either MODE_LINE_FACE_ID or
20839 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
20840 display. Value is the pixel height of the mode/header line
20844 display_mode_line (struct window
*w
, enum face_id face_id
, Lisp_Object format
)
20848 ptrdiff_t count
= SPECPDL_INDEX ();
20850 init_iterator (&it
, w
, -1, -1, NULL
, face_id
);
20851 /* Don't extend on a previously drawn mode-line.
20852 This may happen if called from pos_visible_p. */
20853 it
.glyph_row
->enabled_p
= 0;
20854 prepare_desired_row (it
.glyph_row
);
20856 it
.glyph_row
->mode_line_p
= 1;
20858 /* FIXME: This should be controlled by a user option. But
20859 supporting such an option is not trivial, since the mode line is
20860 made up of many separate strings. */
20861 it
.paragraph_embedding
= L2R
;
20863 record_unwind_protect (unwind_format_mode_line
,
20864 format_mode_line_unwind_data (NULL
, NULL
, Qnil
, 0));
20866 mode_line_target
= MODE_LINE_DISPLAY
;
20868 /* Temporarily make frame's keyboard the current kboard so that
20869 kboard-local variables in the mode_line_format will get the right
20871 push_kboard (FRAME_KBOARD (it
.f
));
20872 record_unwind_save_match_data ();
20873 display_mode_element (&it
, 0, 0, 0, format
, Qnil
, 0);
20876 unbind_to (count
, Qnil
);
20878 /* Fill up with spaces. */
20879 display_string (" ", Qnil
, Qnil
, 0, 0, &it
, 10000, -1, -1, 0);
20881 compute_line_metrics (&it
);
20882 it
.glyph_row
->full_width_p
= 1;
20883 it
.glyph_row
->continued_p
= 0;
20884 it
.glyph_row
->truncated_on_left_p
= 0;
20885 it
.glyph_row
->truncated_on_right_p
= 0;
20887 /* Make a 3D mode-line have a shadow at its right end. */
20888 face
= FACE_FROM_ID (it
.f
, face_id
);
20889 extend_face_to_end_of_line (&it
);
20890 if (face
->box
!= FACE_NO_BOX
)
20892 struct glyph
*last
= (it
.glyph_row
->glyphs
[TEXT_AREA
]
20893 + it
.glyph_row
->used
[TEXT_AREA
] - 1);
20894 last
->right_box_line_p
= 1;
20897 return it
.glyph_row
->height
;
20900 /* Move element ELT in LIST to the front of LIST.
20901 Return the updated list. */
20904 move_elt_to_front (Lisp_Object elt
, Lisp_Object list
)
20906 register Lisp_Object tail
, prev
;
20907 register Lisp_Object tem
;
20911 while (CONSP (tail
))
20917 /* Splice out the link TAIL. */
20919 list
= XCDR (tail
);
20921 Fsetcdr (prev
, XCDR (tail
));
20923 /* Now make it the first. */
20924 Fsetcdr (tail
, list
);
20929 tail
= XCDR (tail
);
20933 /* Not found--return unchanged LIST. */
20937 /* Contribute ELT to the mode line for window IT->w. How it
20938 translates into text depends on its data type.
20940 IT describes the display environment in which we display, as usual.
20942 DEPTH is the depth in recursion. It is used to prevent
20943 infinite recursion here.
20945 FIELD_WIDTH is the number of characters the display of ELT should
20946 occupy in the mode line, and PRECISION is the maximum number of
20947 characters to display from ELT's representation. See
20948 display_string for details.
20950 Returns the hpos of the end of the text generated by ELT.
20952 PROPS is a property list to add to any string we encounter.
20954 If RISKY is nonzero, remove (disregard) any properties in any string
20955 we encounter, and ignore :eval and :propertize.
20957 The global variable `mode_line_target' determines whether the
20958 output is passed to `store_mode_line_noprop',
20959 `store_mode_line_string', or `display_string'. */
20962 display_mode_element (struct it
*it
, int depth
, int field_width
, int precision
,
20963 Lisp_Object elt
, Lisp_Object props
, int risky
)
20965 int n
= 0, field
, prec
;
20970 elt
= build_string ("*too-deep*");
20974 switch (XTYPE (elt
))
20978 /* A string: output it and check for %-constructs within it. */
20980 ptrdiff_t offset
= 0;
20982 if (SCHARS (elt
) > 0
20983 && (!NILP (props
) || risky
))
20985 Lisp_Object oprops
, aelt
;
20986 oprops
= Ftext_properties_at (make_number (0), elt
);
20988 /* If the starting string's properties are not what
20989 we want, translate the string. Also, if the string
20990 is risky, do that anyway. */
20992 if (NILP (Fequal (props
, oprops
)) || risky
)
20994 /* If the starting string has properties,
20995 merge the specified ones onto the existing ones. */
20996 if (! NILP (oprops
) && !risky
)
21000 oprops
= Fcopy_sequence (oprops
);
21002 while (CONSP (tem
))
21004 oprops
= Fplist_put (oprops
, XCAR (tem
),
21005 XCAR (XCDR (tem
)));
21006 tem
= XCDR (XCDR (tem
));
21011 aelt
= Fassoc (elt
, mode_line_proptrans_alist
);
21012 if (! NILP (aelt
) && !NILP (Fequal (props
, XCDR (aelt
))))
21014 /* AELT is what we want. Move it to the front
21015 without consing. */
21017 mode_line_proptrans_alist
21018 = move_elt_to_front (aelt
, mode_line_proptrans_alist
);
21024 /* If AELT has the wrong props, it is useless.
21025 so get rid of it. */
21027 mode_line_proptrans_alist
21028 = Fdelq (aelt
, mode_line_proptrans_alist
);
21030 elt
= Fcopy_sequence (elt
);
21031 Fset_text_properties (make_number (0), Flength (elt
),
21033 /* Add this item to mode_line_proptrans_alist. */
21034 mode_line_proptrans_alist
21035 = Fcons (Fcons (elt
, props
),
21036 mode_line_proptrans_alist
);
21037 /* Truncate mode_line_proptrans_alist
21038 to at most 50 elements. */
21039 tem
= Fnthcdr (make_number (50),
21040 mode_line_proptrans_alist
);
21042 XSETCDR (tem
, Qnil
);
21051 prec
= precision
- n
;
21052 switch (mode_line_target
)
21054 case MODE_LINE_NOPROP
:
21055 case MODE_LINE_TITLE
:
21056 n
+= store_mode_line_noprop (SSDATA (elt
), -1, prec
);
21058 case MODE_LINE_STRING
:
21059 n
+= store_mode_line_string (NULL
, elt
, 1, 0, prec
, Qnil
);
21061 case MODE_LINE_DISPLAY
:
21062 n
+= display_string (NULL
, elt
, Qnil
, 0, 0, it
,
21063 0, prec
, 0, STRING_MULTIBYTE (elt
));
21070 /* Handle the non-literal case. */
21072 while ((precision
<= 0 || n
< precision
)
21073 && SREF (elt
, offset
) != 0
21074 && (mode_line_target
!= MODE_LINE_DISPLAY
21075 || it
->current_x
< it
->last_visible_x
))
21077 ptrdiff_t last_offset
= offset
;
21079 /* Advance to end of string or next format specifier. */
21080 while ((c
= SREF (elt
, offset
++)) != '\0' && c
!= '%')
21083 if (offset
- 1 != last_offset
)
21085 ptrdiff_t nchars
, nbytes
;
21087 /* Output to end of string or up to '%'. Field width
21088 is length of string. Don't output more than
21089 PRECISION allows us. */
21092 prec
= c_string_width (SDATA (elt
) + last_offset
,
21093 offset
- last_offset
, precision
- n
,
21096 switch (mode_line_target
)
21098 case MODE_LINE_NOPROP
:
21099 case MODE_LINE_TITLE
:
21100 n
+= store_mode_line_noprop (SSDATA (elt
) + last_offset
, 0, prec
);
21102 case MODE_LINE_STRING
:
21104 ptrdiff_t bytepos
= last_offset
;
21105 ptrdiff_t charpos
= string_byte_to_char (elt
, bytepos
);
21106 ptrdiff_t endpos
= (precision
<= 0
21107 ? string_byte_to_char (elt
, offset
)
21108 : charpos
+ nchars
);
21110 n
+= store_mode_line_string (NULL
,
21111 Fsubstring (elt
, make_number (charpos
),
21112 make_number (endpos
)),
21116 case MODE_LINE_DISPLAY
:
21118 ptrdiff_t bytepos
= last_offset
;
21119 ptrdiff_t charpos
= string_byte_to_char (elt
, bytepos
);
21121 if (precision
<= 0)
21122 nchars
= string_byte_to_char (elt
, offset
) - charpos
;
21123 n
+= display_string (NULL
, elt
, Qnil
, 0, charpos
,
21125 STRING_MULTIBYTE (elt
));
21130 else /* c == '%' */
21132 ptrdiff_t percent_position
= offset
;
21134 /* Get the specified minimum width. Zero means
21137 while ((c
= SREF (elt
, offset
++)) >= '0' && c
<= '9')
21138 field
= field
* 10 + c
- '0';
21140 /* Don't pad beyond the total padding allowed. */
21141 if (field_width
- n
> 0 && field
> field_width
- n
)
21142 field
= field_width
- n
;
21144 /* Note that either PRECISION <= 0 or N < PRECISION. */
21145 prec
= precision
- n
;
21148 n
+= display_mode_element (it
, depth
, field
, prec
,
21149 Vglobal_mode_string
, props
,
21154 ptrdiff_t bytepos
, charpos
;
21156 Lisp_Object string
;
21158 bytepos
= percent_position
;
21159 charpos
= (STRING_MULTIBYTE (elt
)
21160 ? string_byte_to_char (elt
, bytepos
)
21162 spec
= decode_mode_spec (it
->w
, c
, field
, &string
);
21163 multibyte
= STRINGP (string
) && STRING_MULTIBYTE (string
);
21165 switch (mode_line_target
)
21167 case MODE_LINE_NOPROP
:
21168 case MODE_LINE_TITLE
:
21169 n
+= store_mode_line_noprop (spec
, field
, prec
);
21171 case MODE_LINE_STRING
:
21173 Lisp_Object tem
= build_string (spec
);
21174 props
= Ftext_properties_at (make_number (charpos
), elt
);
21175 /* Should only keep face property in props */
21176 n
+= store_mode_line_string (NULL
, tem
, 0, field
, prec
, props
);
21179 case MODE_LINE_DISPLAY
:
21181 int nglyphs_before
, nwritten
;
21183 nglyphs_before
= it
->glyph_row
->used
[TEXT_AREA
];
21184 nwritten
= display_string (spec
, string
, elt
,
21189 /* Assign to the glyphs written above the
21190 string where the `%x' came from, position
21194 struct glyph
*glyph
21195 = (it
->glyph_row
->glyphs
[TEXT_AREA
]
21199 for (i
= 0; i
< nwritten
; ++i
)
21201 glyph
[i
].object
= elt
;
21202 glyph
[i
].charpos
= charpos
;
21219 /* A symbol: process the value of the symbol recursively
21220 as if it appeared here directly. Avoid error if symbol void.
21221 Special case: if value of symbol is a string, output the string
21224 register Lisp_Object tem
;
21226 /* If the variable is not marked as risky to set
21227 then its contents are risky to use. */
21228 if (NILP (Fget (elt
, Qrisky_local_variable
)))
21231 tem
= Fboundp (elt
);
21234 tem
= Fsymbol_value (elt
);
21235 /* If value is a string, output that string literally:
21236 don't check for % within it. */
21240 if (!EQ (tem
, elt
))
21242 /* Give up right away for nil or t. */
21252 register Lisp_Object car
, tem
;
21254 /* A cons cell: five distinct cases.
21255 If first element is :eval or :propertize, do something special.
21256 If first element is a string or a cons, process all the elements
21257 and effectively concatenate them.
21258 If first element is a negative number, truncate displaying cdr to
21259 at most that many characters. If positive, pad (with spaces)
21260 to at least that many characters.
21261 If first element is a symbol, process the cadr or caddr recursively
21262 according to whether the symbol's value is non-nil or nil. */
21264 if (EQ (car
, QCeval
))
21266 /* An element of the form (:eval FORM) means evaluate FORM
21267 and use the result as mode line elements. */
21272 if (CONSP (XCDR (elt
)))
21275 spec
= safe_eval (XCAR (XCDR (elt
)));
21276 n
+= display_mode_element (it
, depth
, field_width
- n
,
21277 precision
- n
, spec
, props
,
21281 else if (EQ (car
, QCpropertize
))
21283 /* An element of the form (:propertize ELT PROPS...)
21284 means display ELT but applying properties PROPS. */
21289 if (CONSP (XCDR (elt
)))
21290 n
+= display_mode_element (it
, depth
, field_width
- n
,
21291 precision
- n
, XCAR (XCDR (elt
)),
21292 XCDR (XCDR (elt
)), risky
);
21294 else if (SYMBOLP (car
))
21296 tem
= Fboundp (car
);
21300 /* elt is now the cdr, and we know it is a cons cell.
21301 Use its car if CAR has a non-nil value. */
21304 tem
= Fsymbol_value (car
);
21311 /* Symbol's value is nil (or symbol is unbound)
21312 Get the cddr of the original list
21313 and if possible find the caddr and use that. */
21317 else if (!CONSP (elt
))
21322 else if (INTEGERP (car
))
21324 register int lim
= XINT (car
);
21328 /* Negative int means reduce maximum width. */
21329 if (precision
<= 0)
21332 precision
= min (precision
, -lim
);
21336 /* Padding specified. Don't let it be more than
21337 current maximum. */
21339 lim
= min (precision
, lim
);
21341 /* If that's more padding than already wanted, queue it.
21342 But don't reduce padding already specified even if
21343 that is beyond the current truncation point. */
21344 field_width
= max (lim
, field_width
);
21348 else if (STRINGP (car
) || CONSP (car
))
21350 Lisp_Object halftail
= elt
;
21354 && (precision
<= 0 || n
< precision
))
21356 n
+= display_mode_element (it
, depth
,
21357 /* Do padding only after the last
21358 element in the list. */
21359 (! CONSP (XCDR (elt
))
21362 precision
- n
, XCAR (elt
),
21366 if ((len
& 1) == 0)
21367 halftail
= XCDR (halftail
);
21368 /* Check for cycle. */
21369 if (EQ (halftail
, elt
))
21378 elt
= build_string ("*invalid*");
21382 /* Pad to FIELD_WIDTH. */
21383 if (field_width
> 0 && n
< field_width
)
21385 switch (mode_line_target
)
21387 case MODE_LINE_NOPROP
:
21388 case MODE_LINE_TITLE
:
21389 n
+= store_mode_line_noprop ("", field_width
- n
, 0);
21391 case MODE_LINE_STRING
:
21392 n
+= store_mode_line_string ("", Qnil
, 0, field_width
- n
, 0, Qnil
);
21394 case MODE_LINE_DISPLAY
:
21395 n
+= display_string ("", Qnil
, Qnil
, 0, 0, it
, field_width
- n
,
21404 /* Store a mode-line string element in mode_line_string_list.
21406 If STRING is non-null, display that C string. Otherwise, the Lisp
21407 string LISP_STRING is displayed.
21409 FIELD_WIDTH is the minimum number of output glyphs to produce.
21410 If STRING has fewer characters than FIELD_WIDTH, pad to the right
21411 with spaces. FIELD_WIDTH <= 0 means don't pad.
21413 PRECISION is the maximum number of characters to output from
21414 STRING. PRECISION <= 0 means don't truncate the string.
21416 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
21417 properties to the string.
21419 PROPS are the properties to add to the string.
21420 The mode_line_string_face face property is always added to the string.
21424 store_mode_line_string (const char *string
, Lisp_Object lisp_string
, int copy_string
,
21425 int field_width
, int precision
, Lisp_Object props
)
21430 if (string
!= NULL
)
21432 len
= strlen (string
);
21433 if (precision
> 0 && len
> precision
)
21435 lisp_string
= make_string (string
, len
);
21437 props
= mode_line_string_face_prop
;
21438 else if (!NILP (mode_line_string_face
))
21440 Lisp_Object face
= Fplist_get (props
, Qface
);
21441 props
= Fcopy_sequence (props
);
21443 face
= mode_line_string_face
;
21445 face
= list2 (face
, mode_line_string_face
);
21446 props
= Fplist_put (props
, Qface
, face
);
21448 Fadd_text_properties (make_number (0), make_number (len
),
21449 props
, lisp_string
);
21453 len
= XFASTINT (Flength (lisp_string
));
21454 if (precision
> 0 && len
> precision
)
21457 lisp_string
= Fsubstring (lisp_string
, make_number (0), make_number (len
));
21460 if (!NILP (mode_line_string_face
))
21464 props
= Ftext_properties_at (make_number (0), lisp_string
);
21465 face
= Fplist_get (props
, Qface
);
21467 face
= mode_line_string_face
;
21469 face
= list2 (face
, mode_line_string_face
);
21470 props
= list2 (Qface
, face
);
21472 lisp_string
= Fcopy_sequence (lisp_string
);
21475 Fadd_text_properties (make_number (0), make_number (len
),
21476 props
, lisp_string
);
21481 mode_line_string_list
= Fcons (lisp_string
, mode_line_string_list
);
21485 if (field_width
> len
)
21487 field_width
-= len
;
21488 lisp_string
= Fmake_string (make_number (field_width
), make_number (' '));
21490 Fadd_text_properties (make_number (0), make_number (field_width
),
21491 props
, lisp_string
);
21492 mode_line_string_list
= Fcons (lisp_string
, mode_line_string_list
);
21500 DEFUN ("format-mode-line", Fformat_mode_line
, Sformat_mode_line
,
21502 doc
: /* Format a string out of a mode line format specification.
21503 First arg FORMAT specifies the mode line format (see `mode-line-format'
21504 for details) to use.
21506 By default, the format is evaluated for the currently selected window.
21508 Optional second arg FACE specifies the face property to put on all
21509 characters for which no face is specified. The value nil means the
21510 default face. The value t means whatever face the window's mode line
21511 currently uses (either `mode-line' or `mode-line-inactive',
21512 depending on whether the window is the selected window or not).
21513 An integer value means the value string has no text
21516 Optional third and fourth args WINDOW and BUFFER specify the window
21517 and buffer to use as the context for the formatting (defaults
21518 are the selected window and the WINDOW's buffer). */)
21519 (Lisp_Object format
, Lisp_Object face
,
21520 Lisp_Object window
, Lisp_Object buffer
)
21525 struct buffer
*old_buffer
= NULL
;
21527 int no_props
= INTEGERP (face
);
21528 ptrdiff_t count
= SPECPDL_INDEX ();
21530 int string_start
= 0;
21532 w
= decode_any_window (window
);
21533 XSETWINDOW (window
, w
);
21536 buffer
= w
->contents
;
21537 CHECK_BUFFER (buffer
);
21539 /* Make formatting the modeline a non-op when noninteractive, otherwise
21540 there will be problems later caused by a partially initialized frame. */
21541 if (NILP (format
) || noninteractive
)
21542 return empty_unibyte_string
;
21547 face_id
= (NILP (face
) || EQ (face
, Qdefault
)) ? DEFAULT_FACE_ID
21548 : EQ (face
, Qt
) ? (EQ (window
, selected_window
)
21549 ? MODE_LINE_FACE_ID
: MODE_LINE_INACTIVE_FACE_ID
)
21550 : EQ (face
, Qmode_line
) ? MODE_LINE_FACE_ID
21551 : EQ (face
, Qmode_line_inactive
) ? MODE_LINE_INACTIVE_FACE_ID
21552 : EQ (face
, Qheader_line
) ? HEADER_LINE_FACE_ID
21553 : EQ (face
, Qtool_bar
) ? TOOL_BAR_FACE_ID
21556 old_buffer
= current_buffer
;
21558 /* Save things including mode_line_proptrans_alist,
21559 and set that to nil so that we don't alter the outer value. */
21560 record_unwind_protect (unwind_format_mode_line
,
21561 format_mode_line_unwind_data
21562 (XFRAME (WINDOW_FRAME (w
)),
21563 old_buffer
, selected_window
, 1));
21564 mode_line_proptrans_alist
= Qnil
;
21566 Fselect_window (window
, Qt
);
21567 set_buffer_internal_1 (XBUFFER (buffer
));
21569 init_iterator (&it
, w
, -1, -1, NULL
, face_id
);
21573 mode_line_target
= MODE_LINE_NOPROP
;
21574 mode_line_string_face_prop
= Qnil
;
21575 mode_line_string_list
= Qnil
;
21576 string_start
= MODE_LINE_NOPROP_LEN (0);
21580 mode_line_target
= MODE_LINE_STRING
;
21581 mode_line_string_list
= Qnil
;
21582 mode_line_string_face
= face
;
21583 mode_line_string_face_prop
21584 = NILP (face
) ? Qnil
: list2 (Qface
, face
);
21587 push_kboard (FRAME_KBOARD (it
.f
));
21588 display_mode_element (&it
, 0, 0, 0, format
, Qnil
, 0);
21593 len
= MODE_LINE_NOPROP_LEN (string_start
);
21594 str
= make_string (mode_line_noprop_buf
+ string_start
, len
);
21598 mode_line_string_list
= Fnreverse (mode_line_string_list
);
21599 str
= Fmapconcat (intern ("identity"), mode_line_string_list
,
21600 empty_unibyte_string
);
21603 unbind_to (count
, Qnil
);
21607 /* Write a null-terminated, right justified decimal representation of
21608 the positive integer D to BUF using a minimal field width WIDTH. */
21611 pint2str (register char *buf
, register int width
, register ptrdiff_t d
)
21613 register char *p
= buf
;
21621 *p
++ = d
% 10 + '0';
21626 for (width
-= (int) (p
- buf
); width
> 0; --width
)
21637 /* Write a null-terminated, right justified decimal and "human
21638 readable" representation of the nonnegative integer D to BUF using
21639 a minimal field width WIDTH. D should be smaller than 999.5e24. */
21641 static const char power_letter
[] =
21655 pint2hrstr (char *buf
, int width
, ptrdiff_t d
)
21657 /* We aim to represent the nonnegative integer D as
21658 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
21659 ptrdiff_t quotient
= d
;
21661 /* -1 means: do not use TENTHS. */
21665 /* Length of QUOTIENT.TENTHS as a string. */
21671 if (quotient
>= 1000)
21673 /* Scale to the appropriate EXPONENT. */
21676 remainder
= quotient
% 1000;
21680 while (quotient
>= 1000);
21682 /* Round to nearest and decide whether to use TENTHS or not. */
21685 tenths
= remainder
/ 100;
21686 if (remainder
% 100 >= 50)
21693 if (quotient
== 10)
21701 if (remainder
>= 500)
21703 if (quotient
< 999)
21714 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
21715 if (tenths
== -1 && quotient
<= 99)
21722 p
= psuffix
= buf
+ max (width
, length
);
21724 /* Print EXPONENT. */
21725 *psuffix
++ = power_letter
[exponent
];
21728 /* Print TENTHS. */
21731 *--p
= '0' + tenths
;
21735 /* Print QUOTIENT. */
21738 int digit
= quotient
% 10;
21739 *--p
= '0' + digit
;
21741 while ((quotient
/= 10) != 0);
21743 /* Print leading spaces. */
21748 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
21749 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
21750 type of CODING_SYSTEM. Return updated pointer into BUF. */
21752 static unsigned char invalid_eol_type
[] = "(*invalid*)";
21755 decode_mode_spec_coding (Lisp_Object coding_system
, register char *buf
, int eol_flag
)
21758 bool multibyte
= !NILP (BVAR (current_buffer
, enable_multibyte_characters
));
21759 const unsigned char *eol_str
;
21761 /* The EOL conversion we are using. */
21762 Lisp_Object eoltype
;
21764 val
= CODING_SYSTEM_SPEC (coding_system
);
21767 if (!VECTORP (val
)) /* Not yet decided. */
21769 *buf
++ = multibyte
? '-' : ' ';
21771 eoltype
= eol_mnemonic_undecided
;
21772 /* Don't mention EOL conversion if it isn't decided. */
21777 Lisp_Object eolvalue
;
21779 attrs
= AREF (val
, 0);
21780 eolvalue
= AREF (val
, 2);
21783 ? XFASTINT (CODING_ATTR_MNEMONIC (attrs
))
21788 /* The EOL conversion that is normal on this system. */
21790 if (NILP (eolvalue
)) /* Not yet decided. */
21791 eoltype
= eol_mnemonic_undecided
;
21792 else if (VECTORP (eolvalue
)) /* Not yet decided. */
21793 eoltype
= eol_mnemonic_undecided
;
21794 else /* eolvalue is Qunix, Qdos, or Qmac. */
21795 eoltype
= (EQ (eolvalue
, Qunix
)
21796 ? eol_mnemonic_unix
21797 : (EQ (eolvalue
, Qdos
) == 1
21798 ? eol_mnemonic_dos
: eol_mnemonic_mac
));
21804 /* Mention the EOL conversion if it is not the usual one. */
21805 if (STRINGP (eoltype
))
21807 eol_str
= SDATA (eoltype
);
21808 eol_str_len
= SBYTES (eoltype
);
21810 else if (CHARACTERP (eoltype
))
21812 unsigned char *tmp
= alloca (MAX_MULTIBYTE_LENGTH
);
21813 int c
= XFASTINT (eoltype
);
21814 eol_str_len
= CHAR_STRING (c
, tmp
);
21819 eol_str
= invalid_eol_type
;
21820 eol_str_len
= sizeof (invalid_eol_type
) - 1;
21822 memcpy (buf
, eol_str
, eol_str_len
);
21823 buf
+= eol_str_len
;
21829 /* Return a string for the output of a mode line %-spec for window W,
21830 generated by character C. FIELD_WIDTH > 0 means pad the string
21831 returned with spaces to that value. Return a Lisp string in
21832 *STRING if the resulting string is taken from that Lisp string.
21834 Note we operate on the current buffer for most purposes. */
21836 static char lots_of_dashes
[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
21838 static const char *
21839 decode_mode_spec (struct window
*w
, register int c
, int field_width
,
21840 Lisp_Object
*string
)
21843 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
21844 char *decode_mode_spec_buf
= f
->decode_mode_spec_buffer
;
21845 /* We are going to use f->decode_mode_spec_buffer as the buffer to
21846 produce strings from numerical values, so limit preposterously
21847 large values of FIELD_WIDTH to avoid overrunning the buffer's
21848 end. The size of the buffer is enough for FRAME_MESSAGE_BUF_SIZE
21849 bytes plus the terminating null. */
21850 int width
= min (field_width
, FRAME_MESSAGE_BUF_SIZE (f
));
21851 struct buffer
*b
= current_buffer
;
21859 if (!NILP (BVAR (b
, read_only
)))
21861 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
21866 /* This differs from %* only for a modified read-only buffer. */
21867 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
21869 if (!NILP (BVAR (b
, read_only
)))
21874 /* This differs from %* in ignoring read-only-ness. */
21875 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
21887 if (command_loop_level
> 5)
21889 p
= decode_mode_spec_buf
;
21890 for (i
= 0; i
< command_loop_level
; i
++)
21893 return decode_mode_spec_buf
;
21901 if (command_loop_level
> 5)
21903 p
= decode_mode_spec_buf
;
21904 for (i
= 0; i
< command_loop_level
; i
++)
21907 return decode_mode_spec_buf
;
21914 /* Let lots_of_dashes be a string of infinite length. */
21915 if (mode_line_target
== MODE_LINE_NOPROP
21916 || mode_line_target
== MODE_LINE_STRING
)
21918 if (field_width
<= 0
21919 || field_width
> sizeof (lots_of_dashes
))
21921 for (i
= 0; i
< FRAME_MESSAGE_BUF_SIZE (f
) - 1; ++i
)
21922 decode_mode_spec_buf
[i
] = '-';
21923 decode_mode_spec_buf
[i
] = '\0';
21924 return decode_mode_spec_buf
;
21927 return lots_of_dashes
;
21931 obj
= BVAR (b
, name
);
21935 /* %c and %l are ignored in `frame-title-format'.
21936 (In redisplay_internal, the frame title is drawn _before_ the
21937 windows are updated, so the stuff which depends on actual
21938 window contents (such as %l) may fail to render properly, or
21939 even crash emacs.) */
21940 if (mode_line_target
== MODE_LINE_TITLE
)
21944 ptrdiff_t col
= current_column ();
21945 w
->column_number_displayed
= col
;
21946 pint2str (decode_mode_spec_buf
, width
, col
);
21947 return decode_mode_spec_buf
;
21951 #ifndef SYSTEM_MALLOC
21953 if (NILP (Vmemory_full
))
21956 return "!MEM FULL! ";
21963 /* %F displays the frame name. */
21964 if (!NILP (f
->title
))
21965 return SSDATA (f
->title
);
21966 if (f
->explicit_name
|| ! FRAME_WINDOW_P (f
))
21967 return SSDATA (f
->name
);
21971 obj
= BVAR (b
, filename
);
21976 ptrdiff_t size
= ZV
- BEGV
;
21977 pint2str (decode_mode_spec_buf
, width
, size
);
21978 return decode_mode_spec_buf
;
21983 ptrdiff_t size
= ZV
- BEGV
;
21984 pint2hrstr (decode_mode_spec_buf
, width
, size
);
21985 return decode_mode_spec_buf
;
21990 ptrdiff_t startpos
, startpos_byte
, line
, linepos
, linepos_byte
;
21991 ptrdiff_t topline
, nlines
, height
;
21994 /* %c and %l are ignored in `frame-title-format'. */
21995 if (mode_line_target
== MODE_LINE_TITLE
)
21998 startpos
= marker_position (w
->start
);
21999 startpos_byte
= marker_byte_position (w
->start
);
22000 height
= WINDOW_TOTAL_LINES (w
);
22002 /* If we decided that this buffer isn't suitable for line numbers,
22003 don't forget that too fast. */
22004 if (w
->base_line_pos
== -1)
22007 /* If the buffer is very big, don't waste time. */
22008 if (INTEGERP (Vline_number_display_limit
)
22009 && BUF_ZV (b
) - BUF_BEGV (b
) > XINT (Vline_number_display_limit
))
22011 w
->base_line_pos
= 0;
22012 w
->base_line_number
= 0;
22016 if (w
->base_line_number
> 0
22017 && w
->base_line_pos
> 0
22018 && w
->base_line_pos
<= startpos
)
22020 line
= w
->base_line_number
;
22021 linepos
= w
->base_line_pos
;
22022 linepos_byte
= buf_charpos_to_bytepos (b
, linepos
);
22027 linepos
= BUF_BEGV (b
);
22028 linepos_byte
= BUF_BEGV_BYTE (b
);
22031 /* Count lines from base line to window start position. */
22032 nlines
= display_count_lines (linepos_byte
,
22036 topline
= nlines
+ line
;
22038 /* Determine a new base line, if the old one is too close
22039 or too far away, or if we did not have one.
22040 "Too close" means it's plausible a scroll-down would
22041 go back past it. */
22042 if (startpos
== BUF_BEGV (b
))
22044 w
->base_line_number
= topline
;
22045 w
->base_line_pos
= BUF_BEGV (b
);
22047 else if (nlines
< height
+ 25 || nlines
> height
* 3 + 50
22048 || linepos
== BUF_BEGV (b
))
22050 ptrdiff_t limit
= BUF_BEGV (b
);
22051 ptrdiff_t limit_byte
= BUF_BEGV_BYTE (b
);
22052 ptrdiff_t position
;
22053 ptrdiff_t distance
=
22054 (height
* 2 + 30) * line_number_display_limit_width
;
22056 if (startpos
- distance
> limit
)
22058 limit
= startpos
- distance
;
22059 limit_byte
= CHAR_TO_BYTE (limit
);
22062 nlines
= display_count_lines (startpos_byte
,
22064 - (height
* 2 + 30),
22066 /* If we couldn't find the lines we wanted within
22067 line_number_display_limit_width chars per line,
22068 give up on line numbers for this window. */
22069 if (position
== limit_byte
&& limit
== startpos
- distance
)
22071 w
->base_line_pos
= -1;
22072 w
->base_line_number
= 0;
22076 w
->base_line_number
= topline
- nlines
;
22077 w
->base_line_pos
= BYTE_TO_CHAR (position
);
22080 /* Now count lines from the start pos to point. */
22081 nlines
= display_count_lines (startpos_byte
,
22082 PT_BYTE
, PT
, &junk
);
22084 /* Record that we did display the line number. */
22085 line_number_displayed
= 1;
22087 /* Make the string to show. */
22088 pint2str (decode_mode_spec_buf
, width
, topline
+ nlines
);
22089 return decode_mode_spec_buf
;
22092 char* p
= decode_mode_spec_buf
;
22093 int pad
= width
- 2;
22099 return decode_mode_spec_buf
;
22105 obj
= BVAR (b
, mode_name
);
22109 if (BUF_BEGV (b
) > BUF_BEG (b
) || BUF_ZV (b
) < BUF_Z (b
))
22115 ptrdiff_t pos
= marker_position (w
->start
);
22116 ptrdiff_t total
= BUF_ZV (b
) - BUF_BEGV (b
);
22118 if (w
->window_end_pos
<= BUF_Z (b
) - BUF_ZV (b
))
22120 if (pos
<= BUF_BEGV (b
))
22125 else if (pos
<= BUF_BEGV (b
))
22129 if (total
> 1000000)
22130 /* Do it differently for a large value, to avoid overflow. */
22131 total
= ((pos
- BUF_BEGV (b
)) + (total
/ 100) - 1) / (total
/ 100);
22133 total
= ((pos
- BUF_BEGV (b
)) * 100 + total
- 1) / total
;
22134 /* We can't normally display a 3-digit number,
22135 so get us a 2-digit number that is close. */
22138 sprintf (decode_mode_spec_buf
, "%2"pD
"d%%", total
);
22139 return decode_mode_spec_buf
;
22143 /* Display percentage of size above the bottom of the screen. */
22146 ptrdiff_t toppos
= marker_position (w
->start
);
22147 ptrdiff_t botpos
= BUF_Z (b
) - w
->window_end_pos
;
22148 ptrdiff_t total
= BUF_ZV (b
) - BUF_BEGV (b
);
22150 if (botpos
>= BUF_ZV (b
))
22152 if (toppos
<= BUF_BEGV (b
))
22159 if (total
> 1000000)
22160 /* Do it differently for a large value, to avoid overflow. */
22161 total
= ((botpos
- BUF_BEGV (b
)) + (total
/ 100) - 1) / (total
/ 100);
22163 total
= ((botpos
- BUF_BEGV (b
)) * 100 + total
- 1) / total
;
22164 /* We can't normally display a 3-digit number,
22165 so get us a 2-digit number that is close. */
22168 if (toppos
<= BUF_BEGV (b
))
22169 sprintf (decode_mode_spec_buf
, "Top%2"pD
"d%%", total
);
22171 sprintf (decode_mode_spec_buf
, "%2"pD
"d%%", total
);
22172 return decode_mode_spec_buf
;
22177 /* status of process */
22178 obj
= Fget_buffer_process (Fcurrent_buffer ());
22180 return "no process";
22182 obj
= Fsymbol_name (Fprocess_status (obj
));
22188 ptrdiff_t count
= inhibit_garbage_collection ();
22189 Lisp_Object val
= call1 (intern ("file-remote-p"),
22190 BVAR (current_buffer
, directory
));
22191 unbind_to (count
, Qnil
);
22200 /* coding-system (not including end-of-line format) */
22202 /* coding-system (including end-of-line type) */
22204 int eol_flag
= (c
== 'Z');
22205 char *p
= decode_mode_spec_buf
;
22207 if (! FRAME_WINDOW_P (f
))
22209 /* No need to mention EOL here--the terminal never needs
22210 to do EOL conversion. */
22211 p
= decode_mode_spec_coding (CODING_ID_NAME
22212 (FRAME_KEYBOARD_CODING (f
)->id
),
22214 p
= decode_mode_spec_coding (CODING_ID_NAME
22215 (FRAME_TERMINAL_CODING (f
)->id
),
22218 p
= decode_mode_spec_coding (BVAR (b
, buffer_file_coding_system
),
22221 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
22222 #ifdef subprocesses
22223 obj
= Fget_buffer_process (Fcurrent_buffer ());
22224 if (PROCESSP (obj
))
22226 p
= decode_mode_spec_coding
22227 (XPROCESS (obj
)->decode_coding_system
, p
, eol_flag
);
22228 p
= decode_mode_spec_coding
22229 (XPROCESS (obj
)->encode_coding_system
, p
, eol_flag
);
22231 #endif /* subprocesses */
22234 return decode_mode_spec_buf
;
22241 return SSDATA (obj
);
22248 /* Count up to COUNT lines starting from START_BYTE. COUNT negative
22249 means count lines back from START_BYTE. But don't go beyond
22250 LIMIT_BYTE. Return the number of lines thus found (always
22253 Set *BYTE_POS_PTR to the byte position where we stopped. This is
22254 either the position COUNT lines after/before START_BYTE, if we
22255 found COUNT lines, or LIMIT_BYTE if we hit the limit before finding
22259 display_count_lines (ptrdiff_t start_byte
,
22260 ptrdiff_t limit_byte
, ptrdiff_t count
,
22261 ptrdiff_t *byte_pos_ptr
)
22263 register unsigned char *cursor
;
22264 unsigned char *base
;
22266 register ptrdiff_t ceiling
;
22267 register unsigned char *ceiling_addr
;
22268 ptrdiff_t orig_count
= count
;
22270 /* If we are not in selective display mode,
22271 check only for newlines. */
22272 int selective_display
= (!NILP (BVAR (current_buffer
, selective_display
))
22273 && !INTEGERP (BVAR (current_buffer
, selective_display
)));
22277 while (start_byte
< limit_byte
)
22279 ceiling
= BUFFER_CEILING_OF (start_byte
);
22280 ceiling
= min (limit_byte
- 1, ceiling
);
22281 ceiling_addr
= BYTE_POS_ADDR (ceiling
) + 1;
22282 base
= (cursor
= BYTE_POS_ADDR (start_byte
));
22286 if (selective_display
)
22288 while (*cursor
!= '\n' && *cursor
!= 015
22289 && ++cursor
!= ceiling_addr
)
22291 if (cursor
== ceiling_addr
)
22296 cursor
= memchr (cursor
, '\n', ceiling_addr
- cursor
);
22305 start_byte
+= cursor
- base
;
22306 *byte_pos_ptr
= start_byte
;
22310 while (cursor
< ceiling_addr
);
22312 start_byte
+= ceiling_addr
- base
;
22317 while (start_byte
> limit_byte
)
22319 ceiling
= BUFFER_FLOOR_OF (start_byte
- 1);
22320 ceiling
= max (limit_byte
, ceiling
);
22321 ceiling_addr
= BYTE_POS_ADDR (ceiling
);
22322 base
= (cursor
= BYTE_POS_ADDR (start_byte
- 1) + 1);
22325 if (selective_display
)
22327 while (--cursor
>= ceiling_addr
22328 && *cursor
!= '\n' && *cursor
!= 015)
22330 if (cursor
< ceiling_addr
)
22335 cursor
= memrchr (ceiling_addr
, '\n', cursor
- ceiling_addr
);
22342 start_byte
+= cursor
- base
+ 1;
22343 *byte_pos_ptr
= start_byte
;
22344 /* When scanning backwards, we should
22345 not count the newline posterior to which we stop. */
22346 return - orig_count
- 1;
22349 start_byte
+= ceiling_addr
- base
;
22353 *byte_pos_ptr
= limit_byte
;
22356 return - orig_count
+ count
;
22357 return orig_count
- count
;
22363 /***********************************************************************
22365 ***********************************************************************/
22367 /* Display a NUL-terminated string, starting with index START.
22369 If STRING is non-null, display that C string. Otherwise, the Lisp
22370 string LISP_STRING is displayed. There's a case that STRING is
22371 non-null and LISP_STRING is not nil. It means STRING is a string
22372 data of LISP_STRING. In that case, we display LISP_STRING while
22373 ignoring its text properties.
22375 If FACE_STRING is not nil, FACE_STRING_POS is a position in
22376 FACE_STRING. Display STRING or LISP_STRING with the face at
22377 FACE_STRING_POS in FACE_STRING:
22379 Display the string in the environment given by IT, but use the
22380 standard display table, temporarily.
22382 FIELD_WIDTH is the minimum number of output glyphs to produce.
22383 If STRING has fewer characters than FIELD_WIDTH, pad to the right
22384 with spaces. If STRING has more characters, more than FIELD_WIDTH
22385 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
22387 PRECISION is the maximum number of characters to output from
22388 STRING. PRECISION < 0 means don't truncate the string.
22390 This is roughly equivalent to printf format specifiers:
22392 FIELD_WIDTH PRECISION PRINTF
22393 ----------------------------------------
22399 MULTIBYTE zero means do not display multibyte chars, > 0 means do
22400 display them, and < 0 means obey the current buffer's value of
22401 enable_multibyte_characters.
22403 Value is the number of columns displayed. */
22406 display_string (const char *string
, Lisp_Object lisp_string
, Lisp_Object face_string
,
22407 ptrdiff_t face_string_pos
, ptrdiff_t start
, struct it
*it
,
22408 int field_width
, int precision
, int max_x
, int multibyte
)
22410 int hpos_at_start
= it
->hpos
;
22411 int saved_face_id
= it
->face_id
;
22412 struct glyph_row
*row
= it
->glyph_row
;
22413 ptrdiff_t it_charpos
;
22415 /* Initialize the iterator IT for iteration over STRING beginning
22416 with index START. */
22417 reseat_to_string (it
, NILP (lisp_string
) ? string
: NULL
, lisp_string
, start
,
22418 precision
, field_width
, multibyte
);
22419 if (string
&& STRINGP (lisp_string
))
22420 /* LISP_STRING is the one returned by decode_mode_spec. We should
22421 ignore its text properties. */
22422 it
->stop_charpos
= it
->end_charpos
;
22424 /* If displaying STRING, set up the face of the iterator from
22425 FACE_STRING, if that's given. */
22426 if (STRINGP (face_string
))
22432 = face_at_string_position (it
->w
, face_string
, face_string_pos
,
22433 0, &endptr
, it
->base_face_id
, 0);
22434 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
22435 it
->face_box_p
= face
->box
!= FACE_NO_BOX
;
22438 /* Set max_x to the maximum allowed X position. Don't let it go
22439 beyond the right edge of the window. */
22441 max_x
= it
->last_visible_x
;
22443 max_x
= min (max_x
, it
->last_visible_x
);
22445 /* Skip over display elements that are not visible. because IT->w is
22447 if (it
->current_x
< it
->first_visible_x
)
22448 move_it_in_display_line_to (it
, 100000, it
->first_visible_x
,
22449 MOVE_TO_POS
| MOVE_TO_X
);
22451 row
->ascent
= it
->max_ascent
;
22452 row
->height
= it
->max_ascent
+ it
->max_descent
;
22453 row
->phys_ascent
= it
->max_phys_ascent
;
22454 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
22455 row
->extra_line_spacing
= it
->max_extra_line_spacing
;
22457 if (STRINGP (it
->string
))
22458 it_charpos
= IT_STRING_CHARPOS (*it
);
22460 it_charpos
= IT_CHARPOS (*it
);
22462 /* This condition is for the case that we are called with current_x
22463 past last_visible_x. */
22464 while (it
->current_x
< max_x
)
22466 int x_before
, x
, n_glyphs_before
, i
, nglyphs
;
22468 /* Get the next display element. */
22469 if (!get_next_display_element (it
))
22472 /* Produce glyphs. */
22473 x_before
= it
->current_x
;
22474 n_glyphs_before
= row
->used
[TEXT_AREA
];
22475 PRODUCE_GLYPHS (it
);
22477 nglyphs
= row
->used
[TEXT_AREA
] - n_glyphs_before
;
22480 while (i
< nglyphs
)
22482 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
22484 if (it
->line_wrap
!= TRUNCATE
22485 && x
+ glyph
->pixel_width
> max_x
)
22487 /* End of continued line or max_x reached. */
22488 if (CHAR_GLYPH_PADDING_P (*glyph
))
22490 /* A wide character is unbreakable. */
22491 if (row
->reversed_p
)
22492 unproduce_glyphs (it
, row
->used
[TEXT_AREA
]
22493 - n_glyphs_before
);
22494 row
->used
[TEXT_AREA
] = n_glyphs_before
;
22495 it
->current_x
= x_before
;
22499 if (row
->reversed_p
)
22500 unproduce_glyphs (it
, row
->used
[TEXT_AREA
]
22501 - (n_glyphs_before
+ i
));
22502 row
->used
[TEXT_AREA
] = n_glyphs_before
+ i
;
22507 else if (x
+ glyph
->pixel_width
>= it
->first_visible_x
)
22509 /* Glyph is at least partially visible. */
22511 if (x
< it
->first_visible_x
)
22512 row
->x
= x
- it
->first_visible_x
;
22516 /* Glyph is off the left margin of the display area.
22517 Should not happen. */
22521 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
22522 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
22523 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
22524 row
->phys_height
= max (row
->phys_height
,
22525 it
->max_phys_ascent
+ it
->max_phys_descent
);
22526 row
->extra_line_spacing
= max (row
->extra_line_spacing
,
22527 it
->max_extra_line_spacing
);
22528 x
+= glyph
->pixel_width
;
22532 /* Stop if max_x reached. */
22536 /* Stop at line ends. */
22537 if (ITERATOR_AT_END_OF_LINE_P (it
))
22539 it
->continuation_lines_width
= 0;
22543 set_iterator_to_next (it
, 1);
22544 if (STRINGP (it
->string
))
22545 it_charpos
= IT_STRING_CHARPOS (*it
);
22547 it_charpos
= IT_CHARPOS (*it
);
22549 /* Stop if truncating at the right edge. */
22550 if (it
->line_wrap
== TRUNCATE
22551 && it
->current_x
>= it
->last_visible_x
)
22553 /* Add truncation mark, but don't do it if the line is
22554 truncated at a padding space. */
22555 if (it_charpos
< it
->string_nchars
)
22557 if (!FRAME_WINDOW_P (it
->f
))
22561 if (it
->current_x
> it
->last_visible_x
)
22563 if (!row
->reversed_p
)
22565 for (ii
= row
->used
[TEXT_AREA
] - 1; ii
> 0; --ii
)
22566 if (!CHAR_GLYPH_PADDING_P (row
->glyphs
[TEXT_AREA
][ii
]))
22571 for (ii
= 0; ii
< row
->used
[TEXT_AREA
]; ii
++)
22572 if (!CHAR_GLYPH_PADDING_P (row
->glyphs
[TEXT_AREA
][ii
]))
22574 unproduce_glyphs (it
, ii
+ 1);
22575 ii
= row
->used
[TEXT_AREA
] - (ii
+ 1);
22577 for (n
= row
->used
[TEXT_AREA
]; ii
< n
; ++ii
)
22579 row
->used
[TEXT_AREA
] = ii
;
22580 produce_special_glyphs (it
, IT_TRUNCATION
);
22583 produce_special_glyphs (it
, IT_TRUNCATION
);
22585 row
->truncated_on_right_p
= 1;
22591 /* Maybe insert a truncation at the left. */
22592 if (it
->first_visible_x
22595 if (!FRAME_WINDOW_P (it
->f
)
22596 || (row
->reversed_p
22597 ? WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)
22598 : WINDOW_LEFT_FRINGE_WIDTH (it
->w
)) == 0)
22599 insert_left_trunc_glyphs (it
);
22600 row
->truncated_on_left_p
= 1;
22603 it
->face_id
= saved_face_id
;
22605 /* Value is number of columns displayed. */
22606 return it
->hpos
- hpos_at_start
;
22611 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
22612 appears as an element of LIST or as the car of an element of LIST.
22613 If PROPVAL is a list, compare each element against LIST in that
22614 way, and return 1/2 if any element of PROPVAL is found in LIST.
22615 Otherwise return 0. This function cannot quit.
22616 The return value is 2 if the text is invisible but with an ellipsis
22617 and 1 if it's invisible and without an ellipsis. */
22620 invisible_p (register Lisp_Object propval
, Lisp_Object list
)
22622 register Lisp_Object tail
, proptail
;
22624 for (tail
= list
; CONSP (tail
); tail
= XCDR (tail
))
22626 register Lisp_Object tem
;
22628 if (EQ (propval
, tem
))
22630 if (CONSP (tem
) && EQ (propval
, XCAR (tem
)))
22631 return NILP (XCDR (tem
)) ? 1 : 2;
22634 if (CONSP (propval
))
22636 for (proptail
= propval
; CONSP (proptail
); proptail
= XCDR (proptail
))
22638 Lisp_Object propelt
;
22639 propelt
= XCAR (proptail
);
22640 for (tail
= list
; CONSP (tail
); tail
= XCDR (tail
))
22642 register Lisp_Object tem
;
22644 if (EQ (propelt
, tem
))
22646 if (CONSP (tem
) && EQ (propelt
, XCAR (tem
)))
22647 return NILP (XCDR (tem
)) ? 1 : 2;
22655 DEFUN ("invisible-p", Finvisible_p
, Sinvisible_p
, 1, 1, 0,
22656 doc
: /* Non-nil if the property makes the text invisible.
22657 POS-OR-PROP can be a marker or number, in which case it is taken to be
22658 a position in the current buffer and the value of the `invisible' property
22659 is checked; or it can be some other value, which is then presumed to be the
22660 value of the `invisible' property of the text of interest.
22661 The non-nil value returned can be t for truly invisible text or something
22662 else if the text is replaced by an ellipsis. */)
22663 (Lisp_Object pos_or_prop
)
22666 = (NATNUMP (pos_or_prop
) || MARKERP (pos_or_prop
)
22667 ? Fget_char_property (pos_or_prop
, Qinvisible
, Qnil
)
22669 int invis
= TEXT_PROP_MEANS_INVISIBLE (prop
);
22670 return (invis
== 0 ? Qnil
22672 : make_number (invis
));
22675 /* Calculate a width or height in pixels from a specification using
22676 the following elements:
22679 NUM - a (fractional) multiple of the default font width/height
22680 (NUM) - specifies exactly NUM pixels
22681 UNIT - a fixed number of pixels, see below.
22682 ELEMENT - size of a display element in pixels, see below.
22683 (NUM . SPEC) - equals NUM * SPEC
22684 (+ SPEC SPEC ...) - add pixel values
22685 (- SPEC SPEC ...) - subtract pixel values
22686 (- SPEC) - negate pixel value
22689 INT or FLOAT - a number constant
22690 SYMBOL - use symbol's (buffer local) variable binding.
22693 in - pixels per inch *)
22694 mm - pixels per 1/1000 meter *)
22695 cm - pixels per 1/100 meter *)
22696 width - width of current font in pixels.
22697 height - height of current font in pixels.
22699 *) using the ratio(s) defined in display-pixels-per-inch.
22703 left-fringe - left fringe width in pixels
22704 right-fringe - right fringe width in pixels
22706 left-margin - left margin width in pixels
22707 right-margin - right margin width in pixels
22709 scroll-bar - scroll-bar area width in pixels
22713 Pixels corresponding to 5 inches:
22716 Total width of non-text areas on left side of window (if scroll-bar is on left):
22717 '(space :width (+ left-fringe left-margin scroll-bar))
22719 Align to first text column (in header line):
22720 '(space :align-to 0)
22722 Align to middle of text area minus half the width of variable `my-image'
22723 containing a loaded image:
22724 '(space :align-to (0.5 . (- text my-image)))
22726 Width of left margin minus width of 1 character in the default font:
22727 '(space :width (- left-margin 1))
22729 Width of left margin minus width of 2 characters in the current font:
22730 '(space :width (- left-margin (2 . width)))
22732 Center 1 character over left-margin (in header line):
22733 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
22735 Different ways to express width of left fringe plus left margin minus one pixel:
22736 '(space :width (- (+ left-fringe left-margin) (1)))
22737 '(space :width (+ left-fringe left-margin (- (1))))
22738 '(space :width (+ left-fringe left-margin (-1)))
22743 calc_pixel_width_or_height (double *res
, struct it
*it
, Lisp_Object prop
,
22744 struct font
*font
, int width_p
, int *align_to
)
22748 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
22749 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
22752 return OK_PIXELS (0);
22754 eassert (FRAME_LIVE_P (it
->f
));
22756 if (SYMBOLP (prop
))
22758 if (SCHARS (SYMBOL_NAME (prop
)) == 2)
22760 char *unit
= SSDATA (SYMBOL_NAME (prop
));
22762 if (unit
[0] == 'i' && unit
[1] == 'n')
22764 else if (unit
[0] == 'm' && unit
[1] == 'm')
22766 else if (unit
[0] == 'c' && unit
[1] == 'm')
22772 double ppi
= (width_p
? FRAME_RES_X (it
->f
)
22773 : FRAME_RES_Y (it
->f
));
22776 return OK_PIXELS (ppi
/ pixels
);
22781 #ifdef HAVE_WINDOW_SYSTEM
22782 if (EQ (prop
, Qheight
))
22783 return OK_PIXELS (font
? FONT_HEIGHT (font
) : FRAME_LINE_HEIGHT (it
->f
));
22784 if (EQ (prop
, Qwidth
))
22785 return OK_PIXELS (font
? FONT_WIDTH (font
) : FRAME_COLUMN_WIDTH (it
->f
));
22787 if (EQ (prop
, Qheight
) || EQ (prop
, Qwidth
))
22788 return OK_PIXELS (1);
22791 if (EQ (prop
, Qtext
))
22792 return OK_PIXELS (width_p
22793 ? window_box_width (it
->w
, TEXT_AREA
)
22794 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it
->w
));
22796 if (align_to
&& *align_to
< 0)
22799 if (EQ (prop
, Qleft
))
22800 return OK_ALIGN_TO (window_box_left_offset (it
->w
, TEXT_AREA
));
22801 if (EQ (prop
, Qright
))
22802 return OK_ALIGN_TO (window_box_right_offset (it
->w
, TEXT_AREA
));
22803 if (EQ (prop
, Qcenter
))
22804 return OK_ALIGN_TO (window_box_left_offset (it
->w
, TEXT_AREA
)
22805 + window_box_width (it
->w
, TEXT_AREA
) / 2);
22806 if (EQ (prop
, Qleft_fringe
))
22807 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it
->w
)
22808 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it
->w
)
22809 : window_box_right_offset (it
->w
, LEFT_MARGIN_AREA
));
22810 if (EQ (prop
, Qright_fringe
))
22811 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it
->w
)
22812 ? window_box_right_offset (it
->w
, RIGHT_MARGIN_AREA
)
22813 : window_box_right_offset (it
->w
, TEXT_AREA
));
22814 if (EQ (prop
, Qleft_margin
))
22815 return OK_ALIGN_TO (window_box_left_offset (it
->w
, LEFT_MARGIN_AREA
));
22816 if (EQ (prop
, Qright_margin
))
22817 return OK_ALIGN_TO (window_box_left_offset (it
->w
, RIGHT_MARGIN_AREA
));
22818 if (EQ (prop
, Qscroll_bar
))
22819 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it
->w
)
22821 : (window_box_right_offset (it
->w
, RIGHT_MARGIN_AREA
)
22822 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it
->w
)
22823 ? WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)
22828 if (EQ (prop
, Qleft_fringe
))
22829 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it
->w
));
22830 if (EQ (prop
, Qright_fringe
))
22831 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it
->w
));
22832 if (EQ (prop
, Qleft_margin
))
22833 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it
->w
));
22834 if (EQ (prop
, Qright_margin
))
22835 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it
->w
));
22836 if (EQ (prop
, Qscroll_bar
))
22837 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it
->w
));
22840 prop
= buffer_local_value_1 (prop
, it
->w
->contents
);
22841 if (EQ (prop
, Qunbound
))
22845 if (INTEGERP (prop
) || FLOATP (prop
))
22847 int base_unit
= (width_p
22848 ? FRAME_COLUMN_WIDTH (it
->f
)
22849 : FRAME_LINE_HEIGHT (it
->f
));
22850 return OK_PIXELS (XFLOATINT (prop
) * base_unit
);
22855 Lisp_Object car
= XCAR (prop
);
22856 Lisp_Object cdr
= XCDR (prop
);
22860 #ifdef HAVE_WINDOW_SYSTEM
22861 if (FRAME_WINDOW_P (it
->f
)
22862 && valid_image_p (prop
))
22864 ptrdiff_t id
= lookup_image (it
->f
, prop
);
22865 struct image
*img
= IMAGE_FROM_ID (it
->f
, id
);
22867 return OK_PIXELS (width_p
? img
->width
: img
->height
);
22870 if (EQ (car
, Qplus
) || EQ (car
, Qminus
))
22876 while (CONSP (cdr
))
22878 if (!calc_pixel_width_or_height (&px
, it
, XCAR (cdr
),
22879 font
, width_p
, align_to
))
22882 pixels
= (EQ (car
, Qplus
) ? px
: -px
), first
= 0;
22887 if (EQ (car
, Qminus
))
22889 return OK_PIXELS (pixels
);
22892 car
= buffer_local_value_1 (car
, it
->w
->contents
);
22893 if (EQ (car
, Qunbound
))
22897 if (INTEGERP (car
) || FLOATP (car
))
22900 pixels
= XFLOATINT (car
);
22902 return OK_PIXELS (pixels
);
22903 if (calc_pixel_width_or_height (&fact
, it
, cdr
,
22904 font
, width_p
, align_to
))
22905 return OK_PIXELS (pixels
* fact
);
22916 /***********************************************************************
22918 ***********************************************************************/
22920 #ifdef HAVE_WINDOW_SYSTEM
22925 dump_glyph_string (struct glyph_string
*s
)
22927 fprintf (stderr
, "glyph string\n");
22928 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
22929 s
->x
, s
->y
, s
->width
, s
->height
);
22930 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
22931 fprintf (stderr
, " hl = %d\n", s
->hl
);
22932 fprintf (stderr
, " left overhang = %d, right = %d\n",
22933 s
->left_overhang
, s
->right_overhang
);
22934 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
22935 fprintf (stderr
, " extends to end of line = %d\n",
22936 s
->extends_to_end_of_line_p
);
22937 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
22938 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
22941 #endif /* GLYPH_DEBUG */
22943 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
22944 of XChar2b structures for S; it can't be allocated in
22945 init_glyph_string because it must be allocated via `alloca'. W
22946 is the window on which S is drawn. ROW and AREA are the glyph row
22947 and area within the row from which S is constructed. START is the
22948 index of the first glyph structure covered by S. HL is a
22949 face-override for drawing S. */
22952 #define OPTIONAL_HDC(hdc) HDC hdc,
22953 #define DECLARE_HDC(hdc) HDC hdc;
22954 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
22955 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
22958 #ifndef OPTIONAL_HDC
22959 #define OPTIONAL_HDC(hdc)
22960 #define DECLARE_HDC(hdc)
22961 #define ALLOCATE_HDC(hdc, f)
22962 #define RELEASE_HDC(hdc, f)
22966 init_glyph_string (struct glyph_string
*s
,
22968 XChar2b
*char2b
, struct window
*w
, struct glyph_row
*row
,
22969 enum glyph_row_area area
, int start
, enum draw_glyphs_face hl
)
22971 memset (s
, 0, sizeof *s
);
22973 s
->f
= XFRAME (w
->frame
);
22977 s
->display
= FRAME_X_DISPLAY (s
->f
);
22978 s
->window
= FRAME_X_WINDOW (s
->f
);
22979 s
->char2b
= char2b
;
22983 s
->first_glyph
= row
->glyphs
[area
] + start
;
22984 s
->height
= row
->height
;
22985 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
22986 s
->ybase
= s
->y
+ row
->ascent
;
22990 /* Append the list of glyph strings with head H and tail T to the list
22991 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
22994 append_glyph_string_lists (struct glyph_string
**head
, struct glyph_string
**tail
,
22995 struct glyph_string
*h
, struct glyph_string
*t
)
23009 /* Prepend the list of glyph strings with head H and tail T to the
23010 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
23014 prepend_glyph_string_lists (struct glyph_string
**head
, struct glyph_string
**tail
,
23015 struct glyph_string
*h
, struct glyph_string
*t
)
23029 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
23030 Set *HEAD and *TAIL to the resulting list. */
23033 append_glyph_string (struct glyph_string
**head
, struct glyph_string
**tail
,
23034 struct glyph_string
*s
)
23036 s
->next
= s
->prev
= NULL
;
23037 append_glyph_string_lists (head
, tail
, s
, s
);
23041 /* Get face and two-byte form of character C in face FACE_ID on frame F.
23042 The encoding of C is returned in *CHAR2B. DISPLAY_P non-zero means
23043 make sure that X resources for the face returned are allocated.
23044 Value is a pointer to a realized face that is ready for display if
23045 DISPLAY_P is non-zero. */
23047 static struct face
*
23048 get_char_face_and_encoding (struct frame
*f
, int c
, int face_id
,
23049 XChar2b
*char2b
, int display_p
)
23051 struct face
*face
= FACE_FROM_ID (f
, face_id
);
23056 code
= face
->font
->driver
->encode_char (face
->font
, c
);
23058 if (code
== FONT_INVALID_CODE
)
23061 STORE_XCHAR2B (char2b
, (code
>> 8), (code
& 0xFF));
23063 /* Make sure X resources of the face are allocated. */
23064 #ifdef HAVE_X_WINDOWS
23068 eassert (face
!= NULL
);
23069 PREPARE_FACE_FOR_DISPLAY (f
, face
);
23076 /* Get face and two-byte form of character glyph GLYPH on frame F.
23077 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
23078 a pointer to a realized face that is ready for display. */
23080 static struct face
*
23081 get_glyph_face_and_encoding (struct frame
*f
, struct glyph
*glyph
,
23082 XChar2b
*char2b
, int *two_byte_p
)
23087 eassert (glyph
->type
== CHAR_GLYPH
);
23088 face
= FACE_FROM_ID (f
, glyph
->face_id
);
23090 /* Make sure X resources of the face are allocated. */
23091 eassert (face
!= NULL
);
23092 PREPARE_FACE_FOR_DISPLAY (f
, face
);
23099 if (CHAR_BYTE8_P (glyph
->u
.ch
))
23100 code
= CHAR_TO_BYTE8 (glyph
->u
.ch
);
23102 code
= face
->font
->driver
->encode_char (face
->font
, glyph
->u
.ch
);
23104 if (code
== FONT_INVALID_CODE
)
23108 STORE_XCHAR2B (char2b
, (code
>> 8), (code
& 0xFF));
23113 /* Get glyph code of character C in FONT in the two-byte form CHAR2B.
23114 Return 1 if FONT has a glyph for C, otherwise return 0. */
23117 get_char_glyph_code (int c
, struct font
*font
, XChar2b
*char2b
)
23121 if (CHAR_BYTE8_P (c
))
23122 code
= CHAR_TO_BYTE8 (c
);
23124 code
= font
->driver
->encode_char (font
, c
);
23126 if (code
== FONT_INVALID_CODE
)
23128 STORE_XCHAR2B (char2b
, (code
>> 8), (code
& 0xFF));
23133 /* Fill glyph string S with composition components specified by S->cmp.
23135 BASE_FACE is the base face of the composition.
23136 S->cmp_from is the index of the first component for S.
23138 OVERLAPS non-zero means S should draw the foreground only, and use
23139 its physical height for clipping. See also draw_glyphs.
23141 Value is the index of a component not in S. */
23144 fill_composite_glyph_string (struct glyph_string
*s
, struct face
*base_face
,
23148 /* For all glyphs of this composition, starting at the offset
23149 S->cmp_from, until we reach the end of the definition or encounter a
23150 glyph that requires the different face, add it to S. */
23155 s
->for_overlaps
= overlaps
;
23158 for (i
= s
->cmp_from
; i
< s
->cmp
->glyph_len
; i
++)
23160 int c
= COMPOSITION_GLYPH (s
->cmp
, i
);
23162 /* TAB in a composition means display glyphs with padding space
23163 on the left or right. */
23166 int face_id
= FACE_FOR_CHAR (s
->f
, base_face
->ascii_face
, c
,
23169 face
= get_char_face_and_encoding (s
->f
, c
, face_id
,
23176 s
->font
= s
->face
->font
;
23178 else if (s
->face
!= face
)
23186 if (s
->face
== NULL
)
23188 s
->face
= base_face
->ascii_face
;
23189 s
->font
= s
->face
->font
;
23192 /* All glyph strings for the same composition has the same width,
23193 i.e. the width set for the first component of the composition. */
23194 s
->width
= s
->first_glyph
->pixel_width
;
23196 /* If the specified font could not be loaded, use the frame's
23197 default font, but record the fact that we couldn't load it in
23198 the glyph string so that we can draw rectangles for the
23199 characters of the glyph string. */
23200 if (s
->font
== NULL
)
23202 s
->font_not_found_p
= 1;
23203 s
->font
= FRAME_FONT (s
->f
);
23206 /* Adjust base line for subscript/superscript text. */
23207 s
->ybase
+= s
->first_glyph
->voffset
;
23209 /* This glyph string must always be drawn with 16-bit functions. */
23216 fill_gstring_glyph_string (struct glyph_string
*s
, int face_id
,
23217 int start
, int end
, int overlaps
)
23219 struct glyph
*glyph
, *last
;
23220 Lisp_Object lgstring
;
23223 s
->for_overlaps
= overlaps
;
23224 glyph
= s
->row
->glyphs
[s
->area
] + start
;
23225 last
= s
->row
->glyphs
[s
->area
] + end
;
23226 s
->cmp_id
= glyph
->u
.cmp
.id
;
23227 s
->cmp_from
= glyph
->slice
.cmp
.from
;
23228 s
->cmp_to
= glyph
->slice
.cmp
.to
+ 1;
23229 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
23230 lgstring
= composition_gstring_from_id (s
->cmp_id
);
23231 s
->font
= XFONT_OBJECT (LGSTRING_FONT (lgstring
));
23233 while (glyph
< last
23234 && glyph
->u
.cmp
.automatic
23235 && glyph
->u
.cmp
.id
== s
->cmp_id
23236 && s
->cmp_to
== glyph
->slice
.cmp
.from
)
23237 s
->cmp_to
= (glyph
++)->slice
.cmp
.to
+ 1;
23239 for (i
= s
->cmp_from
; i
< s
->cmp_to
; i
++)
23241 Lisp_Object lglyph
= LGSTRING_GLYPH (lgstring
, i
);
23242 unsigned code
= LGLYPH_CODE (lglyph
);
23244 STORE_XCHAR2B ((s
->char2b
+ i
), code
>> 8, code
& 0xFF);
23246 s
->width
= composition_gstring_width (lgstring
, s
->cmp_from
, s
->cmp_to
, NULL
);
23247 return glyph
- s
->row
->glyphs
[s
->area
];
23251 /* Fill glyph string S from a sequence glyphs for glyphless characters.
23252 See the comment of fill_glyph_string for arguments.
23253 Value is the index of the first glyph not in S. */
23257 fill_glyphless_glyph_string (struct glyph_string
*s
, int face_id
,
23258 int start
, int end
, int overlaps
)
23260 struct glyph
*glyph
, *last
;
23263 eassert (s
->first_glyph
->type
== GLYPHLESS_GLYPH
);
23264 s
->for_overlaps
= overlaps
;
23265 glyph
= s
->row
->glyphs
[s
->area
] + start
;
23266 last
= s
->row
->glyphs
[s
->area
] + end
;
23267 voffset
= glyph
->voffset
;
23268 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
23269 s
->font
= s
->face
->font
? s
->face
->font
: FRAME_FONT (s
->f
);
23271 s
->width
= glyph
->pixel_width
;
23273 while (glyph
< last
23274 && glyph
->type
== GLYPHLESS_GLYPH
23275 && glyph
->voffset
== voffset
23276 && glyph
->face_id
== face_id
)
23279 s
->width
+= glyph
->pixel_width
;
23282 s
->ybase
+= voffset
;
23283 return glyph
- s
->row
->glyphs
[s
->area
];
23287 /* Fill glyph string S from a sequence of character glyphs.
23289 FACE_ID is the face id of the string. START is the index of the
23290 first glyph to consider, END is the index of the last + 1.
23291 OVERLAPS non-zero means S should draw the foreground only, and use
23292 its physical height for clipping. See also draw_glyphs.
23294 Value is the index of the first glyph not in S. */
23297 fill_glyph_string (struct glyph_string
*s
, int face_id
,
23298 int start
, int end
, int overlaps
)
23300 struct glyph
*glyph
, *last
;
23302 int glyph_not_available_p
;
23304 eassert (s
->f
== XFRAME (s
->w
->frame
));
23305 eassert (s
->nchars
== 0);
23306 eassert (start
>= 0 && end
> start
);
23308 s
->for_overlaps
= overlaps
;
23309 glyph
= s
->row
->glyphs
[s
->area
] + start
;
23310 last
= s
->row
->glyphs
[s
->area
] + end
;
23311 voffset
= glyph
->voffset
;
23312 s
->padding_p
= glyph
->padding_p
;
23313 glyph_not_available_p
= glyph
->glyph_not_available_p
;
23315 while (glyph
< last
23316 && glyph
->type
== CHAR_GLYPH
23317 && glyph
->voffset
== voffset
23318 /* Same face id implies same font, nowadays. */
23319 && glyph
->face_id
== face_id
23320 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
23324 s
->face
= get_glyph_face_and_encoding (s
->f
, glyph
,
23325 s
->char2b
+ s
->nchars
,
23327 s
->two_byte_p
= two_byte_p
;
23329 eassert (s
->nchars
<= end
- start
);
23330 s
->width
+= glyph
->pixel_width
;
23331 if (glyph
++->padding_p
!= s
->padding_p
)
23335 s
->font
= s
->face
->font
;
23337 /* If the specified font could not be loaded, use the frame's font,
23338 but record the fact that we couldn't load it in
23339 S->font_not_found_p so that we can draw rectangles for the
23340 characters of the glyph string. */
23341 if (s
->font
== NULL
|| glyph_not_available_p
)
23343 s
->font_not_found_p
= 1;
23344 s
->font
= FRAME_FONT (s
->f
);
23347 /* Adjust base line for subscript/superscript text. */
23348 s
->ybase
+= voffset
;
23350 eassert (s
->face
&& s
->face
->gc
);
23351 return glyph
- s
->row
->glyphs
[s
->area
];
23355 /* Fill glyph string S from image glyph S->first_glyph. */
23358 fill_image_glyph_string (struct glyph_string
*s
)
23360 eassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
23361 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
23363 s
->slice
= s
->first_glyph
->slice
.img
;
23364 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
23365 s
->font
= s
->face
->font
;
23366 s
->width
= s
->first_glyph
->pixel_width
;
23368 /* Adjust base line for subscript/superscript text. */
23369 s
->ybase
+= s
->first_glyph
->voffset
;
23373 /* Fill glyph string S from a sequence of stretch glyphs.
23375 START is the index of the first glyph to consider,
23376 END is the index of the last + 1.
23378 Value is the index of the first glyph not in S. */
23381 fill_stretch_glyph_string (struct glyph_string
*s
, int start
, int end
)
23383 struct glyph
*glyph
, *last
;
23384 int voffset
, face_id
;
23386 eassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
23388 glyph
= s
->row
->glyphs
[s
->area
] + start
;
23389 last
= s
->row
->glyphs
[s
->area
] + end
;
23390 face_id
= glyph
->face_id
;
23391 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
23392 s
->font
= s
->face
->font
;
23393 s
->width
= glyph
->pixel_width
;
23395 voffset
= glyph
->voffset
;
23399 && glyph
->type
== STRETCH_GLYPH
23400 && glyph
->voffset
== voffset
23401 && glyph
->face_id
== face_id
);
23403 s
->width
+= glyph
->pixel_width
;
23405 /* Adjust base line for subscript/superscript text. */
23406 s
->ybase
+= voffset
;
23408 /* The case that face->gc == 0 is handled when drawing the glyph
23409 string by calling PREPARE_FACE_FOR_DISPLAY. */
23411 return glyph
- s
->row
->glyphs
[s
->area
];
23414 static struct font_metrics
*
23415 get_per_char_metric (struct font
*font
, XChar2b
*char2b
)
23417 static struct font_metrics metrics
;
23422 code
= (XCHAR2B_BYTE1 (char2b
) << 8) | XCHAR2B_BYTE2 (char2b
);
23423 if (code
== FONT_INVALID_CODE
)
23425 font
->driver
->text_extents (font
, &code
, 1, &metrics
);
23430 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
23431 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
23432 assumed to be zero. */
23435 x_get_glyph_overhangs (struct glyph
*glyph
, struct frame
*f
, int *left
, int *right
)
23437 *left
= *right
= 0;
23439 if (glyph
->type
== CHAR_GLYPH
)
23443 struct font_metrics
*pcm
;
23445 face
= get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
23446 if (face
->font
&& (pcm
= get_per_char_metric (face
->font
, &char2b
)))
23448 if (pcm
->rbearing
> pcm
->width
)
23449 *right
= pcm
->rbearing
- pcm
->width
;
23450 if (pcm
->lbearing
< 0)
23451 *left
= -pcm
->lbearing
;
23454 else if (glyph
->type
== COMPOSITE_GLYPH
)
23456 if (! glyph
->u
.cmp
.automatic
)
23458 struct composition
*cmp
= composition_table
[glyph
->u
.cmp
.id
];
23460 if (cmp
->rbearing
> cmp
->pixel_width
)
23461 *right
= cmp
->rbearing
- cmp
->pixel_width
;
23462 if (cmp
->lbearing
< 0)
23463 *left
= - cmp
->lbearing
;
23467 Lisp_Object gstring
= composition_gstring_from_id (glyph
->u
.cmp
.id
);
23468 struct font_metrics metrics
;
23470 composition_gstring_width (gstring
, glyph
->slice
.cmp
.from
,
23471 glyph
->slice
.cmp
.to
+ 1, &metrics
);
23472 if (metrics
.rbearing
> metrics
.width
)
23473 *right
= metrics
.rbearing
- metrics
.width
;
23474 if (metrics
.lbearing
< 0)
23475 *left
= - metrics
.lbearing
;
23481 /* Return the index of the first glyph preceding glyph string S that
23482 is overwritten by S because of S's left overhang. Value is -1
23483 if no glyphs are overwritten. */
23486 left_overwritten (struct glyph_string
*s
)
23490 if (s
->left_overhang
)
23493 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
23494 int first
= s
->first_glyph
- glyphs
;
23496 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
23497 x
-= glyphs
[i
].pixel_width
;
23508 /* Return the index of the first glyph preceding glyph string S that
23509 is overwriting S because of its right overhang. Value is -1 if no
23510 glyph in front of S overwrites S. */
23513 left_overwriting (struct glyph_string
*s
)
23516 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
23517 int first
= s
->first_glyph
- glyphs
;
23521 for (i
= first
- 1; i
>= 0; --i
)
23524 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
23527 x
-= glyphs
[i
].pixel_width
;
23534 /* Return the index of the last glyph following glyph string S that is
23535 overwritten by S because of S's right overhang. Value is -1 if
23536 no such glyph is found. */
23539 right_overwritten (struct glyph_string
*s
)
23543 if (s
->right_overhang
)
23546 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
23547 int first
= (s
->first_glyph
- glyphs
23548 + (s
->first_glyph
->type
== COMPOSITE_GLYPH
? 1 : s
->nchars
));
23549 int end
= s
->row
->used
[s
->area
];
23551 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
23552 x
+= glyphs
[i
].pixel_width
;
23561 /* Return the index of the last glyph following glyph string S that
23562 overwrites S because of its left overhang. Value is negative
23563 if no such glyph is found. */
23566 right_overwriting (struct glyph_string
*s
)
23569 int end
= s
->row
->used
[s
->area
];
23570 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
23571 int first
= (s
->first_glyph
- glyphs
23572 + (s
->first_glyph
->type
== COMPOSITE_GLYPH
? 1 : s
->nchars
));
23576 for (i
= first
; i
< end
; ++i
)
23579 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
23582 x
+= glyphs
[i
].pixel_width
;
23589 /* Set background width of glyph string S. START is the index of the
23590 first glyph following S. LAST_X is the right-most x-position + 1
23591 in the drawing area. */
23594 set_glyph_string_background_width (struct glyph_string
*s
, int start
, int last_x
)
23596 /* If the face of this glyph string has to be drawn to the end of
23597 the drawing area, set S->extends_to_end_of_line_p. */
23599 if (start
== s
->row
->used
[s
->area
]
23600 && s
->area
== TEXT_AREA
23601 && ((s
->row
->fill_line_p
23602 && (s
->hl
== DRAW_NORMAL_TEXT
23603 || s
->hl
== DRAW_IMAGE_RAISED
23604 || s
->hl
== DRAW_IMAGE_SUNKEN
))
23605 || s
->hl
== DRAW_MOUSE_FACE
))
23606 s
->extends_to_end_of_line_p
= 1;
23608 /* If S extends its face to the end of the line, set its
23609 background_width to the distance to the right edge of the drawing
23611 if (s
->extends_to_end_of_line_p
)
23612 s
->background_width
= last_x
- s
->x
+ 1;
23614 s
->background_width
= s
->width
;
23618 /* Compute overhangs and x-positions for glyph string S and its
23619 predecessors, or successors. X is the starting x-position for S.
23620 BACKWARD_P non-zero means process predecessors. */
23623 compute_overhangs_and_x (struct glyph_string
*s
, int x
, int backward_p
)
23629 if (FRAME_RIF (s
->f
)->compute_glyph_string_overhangs
)
23630 FRAME_RIF (s
->f
)->compute_glyph_string_overhangs (s
);
23640 if (FRAME_RIF (s
->f
)->compute_glyph_string_overhangs
)
23641 FRAME_RIF (s
->f
)->compute_glyph_string_overhangs (s
);
23651 /* The following macros are only called from draw_glyphs below.
23652 They reference the following parameters of that function directly:
23653 `w', `row', `area', and `overlap_p'
23654 as well as the following local variables:
23655 `s', `f', and `hdc' (in W32) */
23658 /* On W32, silently add local `hdc' variable to argument list of
23659 init_glyph_string. */
23660 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
23661 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
23663 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
23664 init_glyph_string (s, char2b, w, row, area, start, hl)
23667 /* Add a glyph string for a stretch glyph to the list of strings
23668 between HEAD and TAIL. START is the index of the stretch glyph in
23669 row area AREA of glyph row ROW. END is the index of the last glyph
23670 in that glyph row area. X is the current output position assigned
23671 to the new glyph string constructed. HL overrides that face of the
23672 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
23673 is the right-most x-position of the drawing area. */
23675 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
23676 and below -- keep them on one line. */
23677 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23680 s = alloca (sizeof *s); \
23681 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23682 START = fill_stretch_glyph_string (s, START, END); \
23683 append_glyph_string (&HEAD, &TAIL, s); \
23689 /* Add a glyph string for an image glyph to the list of strings
23690 between HEAD and TAIL. START is the index of the image glyph in
23691 row area AREA of glyph row ROW. END is the index of the last glyph
23692 in that glyph row area. X is the current output position assigned
23693 to the new glyph string constructed. HL overrides that face of the
23694 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
23695 is the right-most x-position of the drawing area. */
23697 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23700 s = alloca (sizeof *s); \
23701 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23702 fill_image_glyph_string (s); \
23703 append_glyph_string (&HEAD, &TAIL, s); \
23710 /* Add a glyph string for a sequence of character glyphs to the list
23711 of strings between HEAD and TAIL. START is the index of the first
23712 glyph in row area AREA of glyph row ROW that is part of the new
23713 glyph string. END is the index of the last glyph in that glyph row
23714 area. X is the current output position assigned to the new glyph
23715 string constructed. HL overrides that face of the glyph; e.g. it
23716 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
23717 right-most x-position of the drawing area. */
23719 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
23725 face_id = (row)->glyphs[area][START].face_id; \
23727 s = alloca (sizeof *s); \
23728 char2b = alloca ((END - START) * sizeof *char2b); \
23729 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23730 append_glyph_string (&HEAD, &TAIL, s); \
23732 START = fill_glyph_string (s, face_id, START, END, overlaps); \
23737 /* Add a glyph string for a composite sequence to the list of strings
23738 between HEAD and TAIL. START is the index of the first glyph in
23739 row area AREA of glyph row ROW that is part of the new glyph
23740 string. END is the index of the last glyph in that glyph row area.
23741 X is the current output position assigned to the new glyph string
23742 constructed. HL overrides that face of the glyph; e.g. it is
23743 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
23744 x-position of the drawing area. */
23746 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23748 int face_id = (row)->glyphs[area][START].face_id; \
23749 struct face *base_face = FACE_FROM_ID (f, face_id); \
23750 ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \
23751 struct composition *cmp = composition_table[cmp_id]; \
23753 struct glyph_string *first_s = NULL; \
23756 char2b = alloca (cmp->glyph_len * sizeof *char2b); \
23758 /* Make glyph_strings for each glyph sequence that is drawable by \
23759 the same face, and append them to HEAD/TAIL. */ \
23760 for (n = 0; n < cmp->glyph_len;) \
23762 s = alloca (sizeof *s); \
23763 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23764 append_glyph_string (&(HEAD), &(TAIL), s); \
23770 n = fill_composite_glyph_string (s, base_face, overlaps); \
23778 /* Add a glyph string for a glyph-string sequence to the list of strings
23779 between HEAD and TAIL. */
23781 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23785 Lisp_Object gstring; \
23787 face_id = (row)->glyphs[area][START].face_id; \
23788 gstring = (composition_gstring_from_id \
23789 ((row)->glyphs[area][START].u.cmp.id)); \
23790 s = alloca (sizeof *s); \
23791 char2b = alloca (LGSTRING_GLYPH_LEN (gstring) * sizeof *char2b); \
23792 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23793 append_glyph_string (&(HEAD), &(TAIL), s); \
23795 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
23799 /* Add a glyph string for a sequence of glyphless character's glyphs
23800 to the list of strings between HEAD and TAIL. The meanings of
23801 arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */
23803 #define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23808 face_id = (row)->glyphs[area][START].face_id; \
23810 s = alloca (sizeof *s); \
23811 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23812 append_glyph_string (&HEAD, &TAIL, s); \
23814 START = fill_glyphless_glyph_string (s, face_id, START, END, \
23820 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
23821 of AREA of glyph row ROW on window W between indices START and END.
23822 HL overrides the face for drawing glyph strings, e.g. it is
23823 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
23824 x-positions of the drawing area.
23826 This is an ugly monster macro construct because we must use alloca
23827 to allocate glyph strings (because draw_glyphs can be called
23828 asynchronously). */
23830 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
23833 HEAD = TAIL = NULL; \
23834 while (START < END) \
23836 struct glyph *first_glyph = (row)->glyphs[area] + START; \
23837 switch (first_glyph->type) \
23840 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
23844 case COMPOSITE_GLYPH: \
23845 if (first_glyph->u.cmp.automatic) \
23846 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
23849 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
23853 case STRETCH_GLYPH: \
23854 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
23858 case IMAGE_GLYPH: \
23859 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
23863 case GLYPHLESS_GLYPH: \
23864 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
23874 set_glyph_string_background_width (s, START, LAST_X); \
23881 /* Draw glyphs between START and END in AREA of ROW on window W,
23882 starting at x-position X. X is relative to AREA in W. HL is a
23883 face-override with the following meaning:
23885 DRAW_NORMAL_TEXT draw normally
23886 DRAW_CURSOR draw in cursor face
23887 DRAW_MOUSE_FACE draw in mouse face.
23888 DRAW_INVERSE_VIDEO draw in mode line face
23889 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
23890 DRAW_IMAGE_RAISED draw an image with a raised relief around it
23892 If OVERLAPS is non-zero, draw only the foreground of characters and
23893 clip to the physical height of ROW. Non-zero value also defines
23894 the overlapping part to be drawn:
23896 OVERLAPS_PRED overlap with preceding rows
23897 OVERLAPS_SUCC overlap with succeeding rows
23898 OVERLAPS_BOTH overlap with both preceding/succeeding rows
23899 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
23901 Value is the x-position reached, relative to AREA of W. */
23904 draw_glyphs (struct window
*w
, int x
, struct glyph_row
*row
,
23905 enum glyph_row_area area
, ptrdiff_t start
, ptrdiff_t end
,
23906 enum draw_glyphs_face hl
, int overlaps
)
23908 struct glyph_string
*head
, *tail
;
23909 struct glyph_string
*s
;
23910 struct glyph_string
*clip_head
= NULL
, *clip_tail
= NULL
;
23911 int i
, j
, x_reached
, last_x
, area_left
= 0;
23912 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
23915 ALLOCATE_HDC (hdc
, f
);
23917 /* Let's rather be paranoid than getting a SEGV. */
23918 end
= min (end
, row
->used
[area
]);
23919 start
= clip_to_bounds (0, start
, end
);
23921 /* Translate X to frame coordinates. Set last_x to the right
23922 end of the drawing area. */
23923 if (row
->full_width_p
)
23925 /* X is relative to the left edge of W, without scroll bars
23927 area_left
= WINDOW_LEFT_EDGE_X (w
);
23928 last_x
= WINDOW_LEFT_EDGE_X (w
) + WINDOW_TOTAL_WIDTH (w
);
23932 area_left
= window_box_left (w
, area
);
23933 last_x
= area_left
+ window_box_width (w
, area
);
23937 /* Build a doubly-linked list of glyph_string structures between
23938 head and tail from what we have to draw. Note that the macro
23939 BUILD_GLYPH_STRINGS will modify its start parameter. That's
23940 the reason we use a separate variable `i'. */
23942 BUILD_GLYPH_STRINGS (i
, end
, head
, tail
, hl
, x
, last_x
);
23944 x_reached
= tail
->x
+ tail
->background_width
;
23948 /* If there are any glyphs with lbearing < 0 or rbearing > width in
23949 the row, redraw some glyphs in front or following the glyph
23950 strings built above. */
23951 if (head
&& !overlaps
&& row
->contains_overlapping_glyphs_p
)
23953 struct glyph_string
*h
, *t
;
23954 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
23955 int mouse_beg_col
IF_LINT (= 0), mouse_end_col
IF_LINT (= 0);
23956 int check_mouse_face
= 0;
23959 /* If mouse highlighting is on, we may need to draw adjacent
23960 glyphs using mouse-face highlighting. */
23961 if (area
== TEXT_AREA
&& row
->mouse_face_p
23962 && hlinfo
->mouse_face_beg_row
>= 0
23963 && hlinfo
->mouse_face_end_row
>= 0)
23965 ptrdiff_t row_vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
23967 if (row_vpos
>= hlinfo
->mouse_face_beg_row
23968 && row_vpos
<= hlinfo
->mouse_face_end_row
)
23970 check_mouse_face
= 1;
23971 mouse_beg_col
= (row_vpos
== hlinfo
->mouse_face_beg_row
)
23972 ? hlinfo
->mouse_face_beg_col
: 0;
23973 mouse_end_col
= (row_vpos
== hlinfo
->mouse_face_end_row
)
23974 ? hlinfo
->mouse_face_end_col
23975 : row
->used
[TEXT_AREA
];
23979 /* Compute overhangs for all glyph strings. */
23980 if (FRAME_RIF (f
)->compute_glyph_string_overhangs
)
23981 for (s
= head
; s
; s
= s
->next
)
23982 FRAME_RIF (f
)->compute_glyph_string_overhangs (s
);
23984 /* Prepend glyph strings for glyphs in front of the first glyph
23985 string that are overwritten because of the first glyph
23986 string's left overhang. The background of all strings
23987 prepended must be drawn because the first glyph string
23989 i
= left_overwritten (head
);
23992 enum draw_glyphs_face overlap_hl
;
23994 /* If this row contains mouse highlighting, attempt to draw
23995 the overlapped glyphs with the correct highlight. This
23996 code fails if the overlap encompasses more than one glyph
23997 and mouse-highlight spans only some of these glyphs.
23998 However, making it work perfectly involves a lot more
23999 code, and I don't know if the pathological case occurs in
24000 practice, so we'll stick to this for now. --- cyd */
24001 if (check_mouse_face
24002 && mouse_beg_col
< start
&& mouse_end_col
> i
)
24003 overlap_hl
= DRAW_MOUSE_FACE
;
24005 overlap_hl
= DRAW_NORMAL_TEXT
;
24008 BUILD_GLYPH_STRINGS (j
, start
, h
, t
,
24009 overlap_hl
, dummy_x
, last_x
);
24011 compute_overhangs_and_x (t
, head
->x
, 1);
24012 prepend_glyph_string_lists (&head
, &tail
, h
, t
);
24016 /* Prepend glyph strings for glyphs in front of the first glyph
24017 string that overwrite that glyph string because of their
24018 right overhang. For these strings, only the foreground must
24019 be drawn, because it draws over the glyph string at `head'.
24020 The background must not be drawn because this would overwrite
24021 right overhangs of preceding glyphs for which no glyph
24023 i
= left_overwriting (head
);
24026 enum draw_glyphs_face overlap_hl
;
24028 if (check_mouse_face
24029 && mouse_beg_col
< start
&& mouse_end_col
> i
)
24030 overlap_hl
= DRAW_MOUSE_FACE
;
24032 overlap_hl
= DRAW_NORMAL_TEXT
;
24035 BUILD_GLYPH_STRINGS (i
, start
, h
, t
,
24036 overlap_hl
, dummy_x
, last_x
);
24037 for (s
= h
; s
; s
= s
->next
)
24038 s
->background_filled_p
= 1;
24039 compute_overhangs_and_x (t
, head
->x
, 1);
24040 prepend_glyph_string_lists (&head
, &tail
, h
, t
);
24043 /* Append glyphs strings for glyphs following the last glyph
24044 string tail that are overwritten by tail. The background of
24045 these strings has to be drawn because tail's foreground draws
24047 i
= right_overwritten (tail
);
24050 enum draw_glyphs_face overlap_hl
;
24052 if (check_mouse_face
24053 && mouse_beg_col
< i
&& mouse_end_col
> end
)
24054 overlap_hl
= DRAW_MOUSE_FACE
;
24056 overlap_hl
= DRAW_NORMAL_TEXT
;
24058 BUILD_GLYPH_STRINGS (end
, i
, h
, t
,
24059 overlap_hl
, x
, last_x
);
24060 /* Because BUILD_GLYPH_STRINGS updates the first argument,
24061 we don't have `end = i;' here. */
24062 compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
24063 append_glyph_string_lists (&head
, &tail
, h
, t
);
24067 /* Append glyph strings for glyphs following the last glyph
24068 string tail that overwrite tail. The foreground of such
24069 glyphs has to be drawn because it writes into the background
24070 of tail. The background must not be drawn because it could
24071 paint over the foreground of following glyphs. */
24072 i
= right_overwriting (tail
);
24075 enum draw_glyphs_face overlap_hl
;
24076 if (check_mouse_face
24077 && mouse_beg_col
< i
&& mouse_end_col
> end
)
24078 overlap_hl
= DRAW_MOUSE_FACE
;
24080 overlap_hl
= DRAW_NORMAL_TEXT
;
24083 i
++; /* We must include the Ith glyph. */
24084 BUILD_GLYPH_STRINGS (end
, i
, h
, t
,
24085 overlap_hl
, x
, last_x
);
24086 for (s
= h
; s
; s
= s
->next
)
24087 s
->background_filled_p
= 1;
24088 compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
24089 append_glyph_string_lists (&head
, &tail
, h
, t
);
24091 if (clip_head
|| clip_tail
)
24092 for (s
= head
; s
; s
= s
->next
)
24094 s
->clip_head
= clip_head
;
24095 s
->clip_tail
= clip_tail
;
24099 /* Draw all strings. */
24100 for (s
= head
; s
; s
= s
->next
)
24101 FRAME_RIF (f
)->draw_glyph_string (s
);
24104 /* When focus a sole frame and move horizontally, this sets on_p to 0
24105 causing a failure to erase prev cursor position. */
24106 if (area
== TEXT_AREA
24107 && !row
->full_width_p
24108 /* When drawing overlapping rows, only the glyph strings'
24109 foreground is drawn, which doesn't erase a cursor
24113 int x0
= clip_head
? clip_head
->x
: (head
? head
->x
: x
);
24114 int x1
= (clip_tail
? clip_tail
->x
+ clip_tail
->background_width
24115 : (tail
? tail
->x
+ tail
->background_width
: x
));
24119 notice_overwritten_cursor (w
, TEXT_AREA
, x0
, x1
,
24120 row
->y
, MATRIX_ROW_BOTTOM_Y (row
));
24124 /* Value is the x-position up to which drawn, relative to AREA of W.
24125 This doesn't include parts drawn because of overhangs. */
24126 if (row
->full_width_p
)
24127 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
24129 x_reached
-= area_left
;
24131 RELEASE_HDC (hdc
, f
);
24136 /* Expand row matrix if too narrow. Don't expand if area
24139 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
24141 if (!it->f->fonts_changed \
24142 && (it->glyph_row->glyphs[area] \
24143 < it->glyph_row->glyphs[area + 1])) \
24145 it->w->ncols_scale_factor++; \
24146 it->f->fonts_changed = 1; \
24150 /* Store one glyph for IT->char_to_display in IT->glyph_row.
24151 Called from x_produce_glyphs when IT->glyph_row is non-null. */
24154 append_glyph (struct it
*it
)
24156 struct glyph
*glyph
;
24157 enum glyph_row_area area
= it
->area
;
24159 eassert (it
->glyph_row
);
24160 eassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
24162 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
24163 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
24165 /* If the glyph row is reversed, we need to prepend the glyph
24166 rather than append it. */
24167 if (it
->glyph_row
->reversed_p
&& area
== TEXT_AREA
)
24171 /* Make room for the additional glyph. */
24172 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[area
]; g
--)
24174 glyph
= it
->glyph_row
->glyphs
[area
];
24176 glyph
->charpos
= CHARPOS (it
->position
);
24177 glyph
->object
= it
->object
;
24178 if (it
->pixel_width
> 0)
24180 glyph
->pixel_width
= it
->pixel_width
;
24181 glyph
->padding_p
= 0;
24185 /* Assure at least 1-pixel width. Otherwise, cursor can't
24186 be displayed correctly. */
24187 glyph
->pixel_width
= 1;
24188 glyph
->padding_p
= 1;
24190 glyph
->ascent
= it
->ascent
;
24191 glyph
->descent
= it
->descent
;
24192 glyph
->voffset
= it
->voffset
;
24193 glyph
->type
= CHAR_GLYPH
;
24194 glyph
->avoid_cursor_p
= it
->avoid_cursor_p
;
24195 glyph
->multibyte_p
= it
->multibyte_p
;
24196 if (it
->glyph_row
->reversed_p
&& area
== TEXT_AREA
)
24198 /* In R2L rows, the left and the right box edges need to be
24199 drawn in reverse direction. */
24200 glyph
->right_box_line_p
= it
->start_of_box_run_p
;
24201 glyph
->left_box_line_p
= it
->end_of_box_run_p
;
24205 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
24206 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
24208 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
24209 || it
->phys_descent
> it
->descent
);
24210 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
24211 glyph
->face_id
= it
->face_id
;
24212 glyph
->u
.ch
= it
->char_to_display
;
24213 glyph
->slice
.img
= null_glyph_slice
;
24214 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
24217 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
24218 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
24220 glyph
->bidi_type
= it
->bidi_it
.type
;
24224 glyph
->resolved_level
= 0;
24225 glyph
->bidi_type
= UNKNOWN_BT
;
24227 ++it
->glyph_row
->used
[area
];
24230 IT_EXPAND_MATRIX_WIDTH (it
, area
);
24233 /* Store one glyph for the composition IT->cmp_it.id in
24234 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
24238 append_composite_glyph (struct it
*it
)
24240 struct glyph
*glyph
;
24241 enum glyph_row_area area
= it
->area
;
24243 eassert (it
->glyph_row
);
24245 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
24246 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
24248 /* If the glyph row is reversed, we need to prepend the glyph
24249 rather than append it. */
24250 if (it
->glyph_row
->reversed_p
&& it
->area
== TEXT_AREA
)
24254 /* Make room for the new glyph. */
24255 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[it
->area
]; g
--)
24257 glyph
= it
->glyph_row
->glyphs
[it
->area
];
24259 glyph
->charpos
= it
->cmp_it
.charpos
;
24260 glyph
->object
= it
->object
;
24261 glyph
->pixel_width
= it
->pixel_width
;
24262 glyph
->ascent
= it
->ascent
;
24263 glyph
->descent
= it
->descent
;
24264 glyph
->voffset
= it
->voffset
;
24265 glyph
->type
= COMPOSITE_GLYPH
;
24266 if (it
->cmp_it
.ch
< 0)
24268 glyph
->u
.cmp
.automatic
= 0;
24269 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
24270 glyph
->slice
.cmp
.from
= glyph
->slice
.cmp
.to
= 0;
24274 glyph
->u
.cmp
.automatic
= 1;
24275 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
24276 glyph
->slice
.cmp
.from
= it
->cmp_it
.from
;
24277 glyph
->slice
.cmp
.to
= it
->cmp_it
.to
- 1;
24279 glyph
->avoid_cursor_p
= it
->avoid_cursor_p
;
24280 glyph
->multibyte_p
= it
->multibyte_p
;
24281 if (it
->glyph_row
->reversed_p
&& area
== TEXT_AREA
)
24283 /* In R2L rows, the left and the right box edges need to be
24284 drawn in reverse direction. */
24285 glyph
->right_box_line_p
= it
->start_of_box_run_p
;
24286 glyph
->left_box_line_p
= it
->end_of_box_run_p
;
24290 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
24291 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
24293 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
24294 || it
->phys_descent
> it
->descent
);
24295 glyph
->padding_p
= 0;
24296 glyph
->glyph_not_available_p
= 0;
24297 glyph
->face_id
= it
->face_id
;
24298 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
24301 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
24302 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
24304 glyph
->bidi_type
= it
->bidi_it
.type
;
24306 ++it
->glyph_row
->used
[area
];
24309 IT_EXPAND_MATRIX_WIDTH (it
, area
);
24313 /* Change IT->ascent and IT->height according to the setting of
24317 take_vertical_position_into_account (struct it
*it
)
24321 if (it
->voffset
< 0)
24322 /* Increase the ascent so that we can display the text higher
24324 it
->ascent
-= it
->voffset
;
24326 /* Increase the descent so that we can display the text lower
24328 it
->descent
+= it
->voffset
;
24333 /* Produce glyphs/get display metrics for the image IT is loaded with.
24334 See the description of struct display_iterator in dispextern.h for
24335 an overview of struct display_iterator. */
24338 produce_image_glyph (struct it
*it
)
24342 int glyph_ascent
, crop
;
24343 struct glyph_slice slice
;
24345 eassert (it
->what
== IT_IMAGE
);
24347 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
24349 /* Make sure X resources of the face is loaded. */
24350 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
24352 if (it
->image_id
< 0)
24354 /* Fringe bitmap. */
24355 it
->ascent
= it
->phys_ascent
= 0;
24356 it
->descent
= it
->phys_descent
= 0;
24357 it
->pixel_width
= 0;
24362 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
24364 /* Make sure X resources of the image is loaded. */
24365 prepare_image_for_display (it
->f
, img
);
24367 slice
.x
= slice
.y
= 0;
24368 slice
.width
= img
->width
;
24369 slice
.height
= img
->height
;
24371 if (INTEGERP (it
->slice
.x
))
24372 slice
.x
= XINT (it
->slice
.x
);
24373 else if (FLOATP (it
->slice
.x
))
24374 slice
.x
= XFLOAT_DATA (it
->slice
.x
) * img
->width
;
24376 if (INTEGERP (it
->slice
.y
))
24377 slice
.y
= XINT (it
->slice
.y
);
24378 else if (FLOATP (it
->slice
.y
))
24379 slice
.y
= XFLOAT_DATA (it
->slice
.y
) * img
->height
;
24381 if (INTEGERP (it
->slice
.width
))
24382 slice
.width
= XINT (it
->slice
.width
);
24383 else if (FLOATP (it
->slice
.width
))
24384 slice
.width
= XFLOAT_DATA (it
->slice
.width
) * img
->width
;
24386 if (INTEGERP (it
->slice
.height
))
24387 slice
.height
= XINT (it
->slice
.height
);
24388 else if (FLOATP (it
->slice
.height
))
24389 slice
.height
= XFLOAT_DATA (it
->slice
.height
) * img
->height
;
24391 if (slice
.x
>= img
->width
)
24392 slice
.x
= img
->width
;
24393 if (slice
.y
>= img
->height
)
24394 slice
.y
= img
->height
;
24395 if (slice
.x
+ slice
.width
>= img
->width
)
24396 slice
.width
= img
->width
- slice
.x
;
24397 if (slice
.y
+ slice
.height
> img
->height
)
24398 slice
.height
= img
->height
- slice
.y
;
24400 if (slice
.width
== 0 || slice
.height
== 0)
24403 it
->ascent
= it
->phys_ascent
= glyph_ascent
= image_ascent (img
, face
, &slice
);
24405 it
->descent
= slice
.height
- glyph_ascent
;
24407 it
->descent
+= img
->vmargin
;
24408 if (slice
.y
+ slice
.height
== img
->height
)
24409 it
->descent
+= img
->vmargin
;
24410 it
->phys_descent
= it
->descent
;
24412 it
->pixel_width
= slice
.width
;
24414 it
->pixel_width
+= img
->hmargin
;
24415 if (slice
.x
+ slice
.width
== img
->width
)
24416 it
->pixel_width
+= img
->hmargin
;
24418 /* It's quite possible for images to have an ascent greater than
24419 their height, so don't get confused in that case. */
24420 if (it
->descent
< 0)
24425 if (face
->box
!= FACE_NO_BOX
)
24427 if (face
->box_line_width
> 0)
24430 it
->ascent
+= face
->box_line_width
;
24431 if (slice
.y
+ slice
.height
== img
->height
)
24432 it
->descent
+= face
->box_line_width
;
24435 if (it
->start_of_box_run_p
&& slice
.x
== 0)
24436 it
->pixel_width
+= eabs (face
->box_line_width
);
24437 if (it
->end_of_box_run_p
&& slice
.x
+ slice
.width
== img
->width
)
24438 it
->pixel_width
+= eabs (face
->box_line_width
);
24441 take_vertical_position_into_account (it
);
24443 /* Automatically crop wide image glyphs at right edge so we can
24444 draw the cursor on same display row. */
24445 if ((crop
= it
->pixel_width
- (it
->last_visible_x
- it
->current_x
), crop
> 0)
24446 && (it
->hpos
== 0 || it
->pixel_width
> it
->last_visible_x
/ 4))
24448 it
->pixel_width
-= crop
;
24449 slice
.width
-= crop
;
24454 struct glyph
*glyph
;
24455 enum glyph_row_area area
= it
->area
;
24457 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
24458 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
24460 glyph
->charpos
= CHARPOS (it
->position
);
24461 glyph
->object
= it
->object
;
24462 glyph
->pixel_width
= it
->pixel_width
;
24463 glyph
->ascent
= glyph_ascent
;
24464 glyph
->descent
= it
->descent
;
24465 glyph
->voffset
= it
->voffset
;
24466 glyph
->type
= IMAGE_GLYPH
;
24467 glyph
->avoid_cursor_p
= it
->avoid_cursor_p
;
24468 glyph
->multibyte_p
= it
->multibyte_p
;
24469 if (it
->glyph_row
->reversed_p
&& area
== TEXT_AREA
)
24471 /* In R2L rows, the left and the right box edges need to be
24472 drawn in reverse direction. */
24473 glyph
->right_box_line_p
= it
->start_of_box_run_p
;
24474 glyph
->left_box_line_p
= it
->end_of_box_run_p
;
24478 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
24479 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
24481 glyph
->overlaps_vertically_p
= 0;
24482 glyph
->padding_p
= 0;
24483 glyph
->glyph_not_available_p
= 0;
24484 glyph
->face_id
= it
->face_id
;
24485 glyph
->u
.img_id
= img
->id
;
24486 glyph
->slice
.img
= slice
;
24487 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
24490 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
24491 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
24493 glyph
->bidi_type
= it
->bidi_it
.type
;
24495 ++it
->glyph_row
->used
[area
];
24498 IT_EXPAND_MATRIX_WIDTH (it
, area
);
24503 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
24504 of the glyph, WIDTH and HEIGHT are the width and height of the
24505 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
24508 append_stretch_glyph (struct it
*it
, Lisp_Object object
,
24509 int width
, int height
, int ascent
)
24511 struct glyph
*glyph
;
24512 enum glyph_row_area area
= it
->area
;
24514 eassert (ascent
>= 0 && ascent
<= height
);
24516 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
24517 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
24519 /* If the glyph row is reversed, we need to prepend the glyph
24520 rather than append it. */
24521 if (it
->glyph_row
->reversed_p
&& area
== TEXT_AREA
)
24525 /* Make room for the additional glyph. */
24526 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[area
]; g
--)
24528 glyph
= it
->glyph_row
->glyphs
[area
];
24530 glyph
->charpos
= CHARPOS (it
->position
);
24531 glyph
->object
= object
;
24532 glyph
->pixel_width
= width
;
24533 glyph
->ascent
= ascent
;
24534 glyph
->descent
= height
- ascent
;
24535 glyph
->voffset
= it
->voffset
;
24536 glyph
->type
= STRETCH_GLYPH
;
24537 glyph
->avoid_cursor_p
= it
->avoid_cursor_p
;
24538 glyph
->multibyte_p
= it
->multibyte_p
;
24539 if (it
->glyph_row
->reversed_p
&& area
== TEXT_AREA
)
24541 /* In R2L rows, the left and the right box edges need to be
24542 drawn in reverse direction. */
24543 glyph
->right_box_line_p
= it
->start_of_box_run_p
;
24544 glyph
->left_box_line_p
= it
->end_of_box_run_p
;
24548 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
24549 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
24551 glyph
->overlaps_vertically_p
= 0;
24552 glyph
->padding_p
= 0;
24553 glyph
->glyph_not_available_p
= 0;
24554 glyph
->face_id
= it
->face_id
;
24555 glyph
->u
.stretch
.ascent
= ascent
;
24556 glyph
->u
.stretch
.height
= height
;
24557 glyph
->slice
.img
= null_glyph_slice
;
24558 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
24561 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
24562 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
24564 glyph
->bidi_type
= it
->bidi_it
.type
;
24568 glyph
->resolved_level
= 0;
24569 glyph
->bidi_type
= UNKNOWN_BT
;
24571 ++it
->glyph_row
->used
[area
];
24574 IT_EXPAND_MATRIX_WIDTH (it
, area
);
24577 #endif /* HAVE_WINDOW_SYSTEM */
24579 /* Produce a stretch glyph for iterator IT. IT->object is the value
24580 of the glyph property displayed. The value must be a list
24581 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
24584 1. `:width WIDTH' specifies that the space should be WIDTH *
24585 canonical char width wide. WIDTH may be an integer or floating
24588 2. `:relative-width FACTOR' specifies that the width of the stretch
24589 should be computed from the width of the first character having the
24590 `glyph' property, and should be FACTOR times that width.
24592 3. `:align-to HPOS' specifies that the space should be wide enough
24593 to reach HPOS, a value in canonical character units.
24595 Exactly one of the above pairs must be present.
24597 4. `:height HEIGHT' specifies that the height of the stretch produced
24598 should be HEIGHT, measured in canonical character units.
24600 5. `:relative-height FACTOR' specifies that the height of the
24601 stretch should be FACTOR times the height of the characters having
24602 the glyph property.
24604 Either none or exactly one of 4 or 5 must be present.
24606 6. `:ascent ASCENT' specifies that ASCENT percent of the height
24607 of the stretch should be used for the ascent of the stretch.
24608 ASCENT must be in the range 0 <= ASCENT <= 100. */
24611 produce_stretch_glyph (struct it
*it
)
24613 /* (space :width WIDTH :height HEIGHT ...) */
24614 Lisp_Object prop
, plist
;
24615 int width
= 0, height
= 0, align_to
= -1;
24616 int zero_width_ok_p
= 0;
24618 struct font
*font
= NULL
;
24620 #ifdef HAVE_WINDOW_SYSTEM
24622 int zero_height_ok_p
= 0;
24624 if (FRAME_WINDOW_P (it
->f
))
24626 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
24627 font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
24628 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
24632 /* List should start with `space'. */
24633 eassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
24634 plist
= XCDR (it
->object
);
24636 /* Compute the width of the stretch. */
24637 if ((prop
= Fplist_get (plist
, QCwidth
), !NILP (prop
))
24638 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 1, 0))
24640 /* Absolute width `:width WIDTH' specified and valid. */
24641 zero_width_ok_p
= 1;
24644 #ifdef HAVE_WINDOW_SYSTEM
24645 else if (FRAME_WINDOW_P (it
->f
)
24646 && (prop
= Fplist_get (plist
, QCrelative_width
), NUMVAL (prop
) > 0))
24648 /* Relative width `:relative-width FACTOR' specified and valid.
24649 Compute the width of the characters having the `glyph'
24652 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
24655 if (it
->multibyte_p
)
24656 it2
.c
= it2
.char_to_display
= STRING_CHAR_AND_LENGTH (p
, it2
.len
);
24659 it2
.c
= it2
.char_to_display
= *p
, it2
.len
= 1;
24660 if (! ASCII_CHAR_P (it2
.c
))
24661 it2
.char_to_display
= BYTE8_TO_CHAR (it2
.c
);
24664 it2
.glyph_row
= NULL
;
24665 it2
.what
= IT_CHARACTER
;
24666 x_produce_glyphs (&it2
);
24667 width
= NUMVAL (prop
) * it2
.pixel_width
;
24669 #endif /* HAVE_WINDOW_SYSTEM */
24670 else if ((prop
= Fplist_get (plist
, QCalign_to
), !NILP (prop
))
24671 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 1, &align_to
))
24673 if (it
->glyph_row
== NULL
|| !it
->glyph_row
->mode_line_p
)
24674 align_to
= (align_to
< 0
24676 : align_to
- window_box_left_offset (it
->w
, TEXT_AREA
));
24677 else if (align_to
< 0)
24678 align_to
= window_box_left_offset (it
->w
, TEXT_AREA
);
24679 width
= max (0, (int)tem
+ align_to
- it
->current_x
);
24680 zero_width_ok_p
= 1;
24683 /* Nothing specified -> width defaults to canonical char width. */
24684 width
= FRAME_COLUMN_WIDTH (it
->f
);
24686 if (width
<= 0 && (width
< 0 || !zero_width_ok_p
))
24689 #ifdef HAVE_WINDOW_SYSTEM
24690 /* Compute height. */
24691 if (FRAME_WINDOW_P (it
->f
))
24693 if ((prop
= Fplist_get (plist
, QCheight
), !NILP (prop
))
24694 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 0, 0))
24697 zero_height_ok_p
= 1;
24699 else if (prop
= Fplist_get (plist
, QCrelative_height
),
24701 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
24703 height
= FONT_HEIGHT (font
);
24705 if (height
<= 0 && (height
< 0 || !zero_height_ok_p
))
24708 /* Compute percentage of height used for ascent. If
24709 `:ascent ASCENT' is present and valid, use that. Otherwise,
24710 derive the ascent from the font in use. */
24711 if (prop
= Fplist_get (plist
, QCascent
),
24712 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
24713 ascent
= height
* NUMVAL (prop
) / 100.0;
24714 else if (!NILP (prop
)
24715 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 0, 0))
24716 ascent
= min (max (0, (int)tem
), height
);
24718 ascent
= (height
* FONT_BASE (font
)) / FONT_HEIGHT (font
);
24721 #endif /* HAVE_WINDOW_SYSTEM */
24724 if (width
> 0 && it
->line_wrap
!= TRUNCATE
24725 && it
->current_x
+ width
> it
->last_visible_x
)
24727 width
= it
->last_visible_x
- it
->current_x
;
24728 #ifdef HAVE_WINDOW_SYSTEM
24729 /* Subtract one more pixel from the stretch width, but only on
24730 GUI frames, since on a TTY each glyph is one "pixel" wide. */
24731 width
-= FRAME_WINDOW_P (it
->f
);
24735 if (width
> 0 && height
> 0 && it
->glyph_row
)
24737 Lisp_Object o_object
= it
->object
;
24738 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
24741 if (!STRINGP (object
))
24742 object
= it
->w
->contents
;
24743 #ifdef HAVE_WINDOW_SYSTEM
24744 if (FRAME_WINDOW_P (it
->f
))
24745 append_stretch_glyph (it
, object
, width
, height
, ascent
);
24749 it
->object
= object
;
24750 it
->char_to_display
= ' ';
24751 it
->pixel_width
= it
->len
= 1;
24753 tty_append_glyph (it
);
24754 it
->object
= o_object
;
24758 it
->pixel_width
= width
;
24759 #ifdef HAVE_WINDOW_SYSTEM
24760 if (FRAME_WINDOW_P (it
->f
))
24762 it
->ascent
= it
->phys_ascent
= ascent
;
24763 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
24764 it
->nglyphs
= width
> 0 && height
> 0 ? 1 : 0;
24765 take_vertical_position_into_account (it
);
24769 it
->nglyphs
= width
;
24772 /* Get information about special display element WHAT in an
24773 environment described by IT. WHAT is one of IT_TRUNCATION or
24774 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
24775 non-null glyph_row member. This function ensures that fields like
24776 face_id, c, len of IT are left untouched. */
24779 produce_special_glyphs (struct it
*it
, enum display_element_type what
)
24786 temp_it
.object
= make_number (0);
24787 memset (&temp_it
.current
, 0, sizeof temp_it
.current
);
24789 if (what
== IT_CONTINUATION
)
24791 /* Continuation glyph. For R2L lines, we mirror it by hand. */
24792 if (it
->bidi_it
.paragraph_dir
== R2L
)
24793 SET_GLYPH_FROM_CHAR (glyph
, '/');
24795 SET_GLYPH_FROM_CHAR (glyph
, '\\');
24797 && (gc
= DISP_CONTINUE_GLYPH (it
->dp
), GLYPH_CODE_P (gc
)))
24799 /* FIXME: Should we mirror GC for R2L lines? */
24800 SET_GLYPH_FROM_GLYPH_CODE (glyph
, gc
);
24801 spec_glyph_lookup_face (XWINDOW (it
->window
), &glyph
);
24804 else if (what
== IT_TRUNCATION
)
24806 /* Truncation glyph. */
24807 SET_GLYPH_FROM_CHAR (glyph
, '$');
24809 && (gc
= DISP_TRUNC_GLYPH (it
->dp
), GLYPH_CODE_P (gc
)))
24811 /* FIXME: Should we mirror GC for R2L lines? */
24812 SET_GLYPH_FROM_GLYPH_CODE (glyph
, gc
);
24813 spec_glyph_lookup_face (XWINDOW (it
->window
), &glyph
);
24819 #ifdef HAVE_WINDOW_SYSTEM
24820 /* On a GUI frame, when the right fringe (left fringe for R2L rows)
24821 is turned off, we precede the truncation/continuation glyphs by a
24822 stretch glyph whose width is computed such that these special
24823 glyphs are aligned at the window margin, even when very different
24824 fonts are used in different glyph rows. */
24825 if (FRAME_WINDOW_P (temp_it
.f
)
24826 /* init_iterator calls this with it->glyph_row == NULL, and it
24827 wants only the pixel width of the truncation/continuation
24829 && temp_it
.glyph_row
24830 /* insert_left_trunc_glyphs calls us at the beginning of the
24831 row, and it has its own calculation of the stretch glyph
24833 && temp_it
.glyph_row
->used
[TEXT_AREA
] > 0
24834 && (temp_it
.glyph_row
->reversed_p
24835 ? WINDOW_LEFT_FRINGE_WIDTH (temp_it
.w
)
24836 : WINDOW_RIGHT_FRINGE_WIDTH (temp_it
.w
)) == 0)
24838 int stretch_width
= temp_it
.last_visible_x
- temp_it
.current_x
;
24840 if (stretch_width
> 0)
24842 struct face
*face
= FACE_FROM_ID (temp_it
.f
, temp_it
.face_id
);
24843 struct font
*font
=
24844 face
->font
? face
->font
: FRAME_FONT (temp_it
.f
);
24845 int stretch_ascent
=
24846 (((temp_it
.ascent
+ temp_it
.descent
)
24847 * FONT_BASE (font
)) / FONT_HEIGHT (font
));
24849 append_stretch_glyph (&temp_it
, make_number (0), stretch_width
,
24850 temp_it
.ascent
+ temp_it
.descent
,
24857 temp_it
.what
= IT_CHARACTER
;
24859 temp_it
.c
= temp_it
.char_to_display
= GLYPH_CHAR (glyph
);
24860 temp_it
.face_id
= GLYPH_FACE (glyph
);
24861 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
24863 PRODUCE_GLYPHS (&temp_it
);
24864 it
->pixel_width
= temp_it
.pixel_width
;
24865 it
->nglyphs
= temp_it
.pixel_width
;
24868 #ifdef HAVE_WINDOW_SYSTEM
24870 /* Calculate line-height and line-spacing properties.
24871 An integer value specifies explicit pixel value.
24872 A float value specifies relative value to current face height.
24873 A cons (float . face-name) specifies relative value to
24874 height of specified face font.
24876 Returns height in pixels, or nil. */
24880 calc_line_height_property (struct it
*it
, Lisp_Object val
, struct font
*font
,
24881 int boff
, int override
)
24883 Lisp_Object face_name
= Qnil
;
24884 int ascent
, descent
, height
;
24886 if (NILP (val
) || INTEGERP (val
) || (override
&& EQ (val
, Qt
)))
24891 face_name
= XCAR (val
);
24893 if (!NUMBERP (val
))
24894 val
= make_number (1);
24895 if (NILP (face_name
))
24897 height
= it
->ascent
+ it
->descent
;
24902 if (NILP (face_name
))
24904 font
= FRAME_FONT (it
->f
);
24905 boff
= FRAME_BASELINE_OFFSET (it
->f
);
24907 else if (EQ (face_name
, Qt
))
24916 face_id
= lookup_named_face (it
->f
, face_name
, 0);
24918 return make_number (-1);
24920 face
= FACE_FROM_ID (it
->f
, face_id
);
24923 return make_number (-1);
24924 boff
= font
->baseline_offset
;
24925 if (font
->vertical_centering
)
24926 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
24929 ascent
= FONT_BASE (font
) + boff
;
24930 descent
= FONT_DESCENT (font
) - boff
;
24934 it
->override_ascent
= ascent
;
24935 it
->override_descent
= descent
;
24936 it
->override_boff
= boff
;
24939 height
= ascent
+ descent
;
24943 height
= (int)(XFLOAT_DATA (val
) * height
);
24944 else if (INTEGERP (val
))
24945 height
*= XINT (val
);
24947 return make_number (height
);
24951 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
24952 is a face ID to be used for the glyph. FOR_NO_FONT is nonzero if
24953 and only if this is for a character for which no font was found.
24955 If the display method (it->glyphless_method) is
24956 GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
24957 length of the acronym or the hexadecimal string, UPPER_XOFF and
24958 UPPER_YOFF are pixel offsets for the upper part of the string,
24959 LOWER_XOFF and LOWER_YOFF are for the lower part.
24961 For the other display methods, LEN through LOWER_YOFF are zero. */
24964 append_glyphless_glyph (struct it
*it
, int face_id
, int for_no_font
, int len
,
24965 short upper_xoff
, short upper_yoff
,
24966 short lower_xoff
, short lower_yoff
)
24968 struct glyph
*glyph
;
24969 enum glyph_row_area area
= it
->area
;
24971 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
24972 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
24974 /* If the glyph row is reversed, we need to prepend the glyph
24975 rather than append it. */
24976 if (it
->glyph_row
->reversed_p
&& area
== TEXT_AREA
)
24980 /* Make room for the additional glyph. */
24981 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[area
]; g
--)
24983 glyph
= it
->glyph_row
->glyphs
[area
];
24985 glyph
->charpos
= CHARPOS (it
->position
);
24986 glyph
->object
= it
->object
;
24987 glyph
->pixel_width
= it
->pixel_width
;
24988 glyph
->ascent
= it
->ascent
;
24989 glyph
->descent
= it
->descent
;
24990 glyph
->voffset
= it
->voffset
;
24991 glyph
->type
= GLYPHLESS_GLYPH
;
24992 glyph
->u
.glyphless
.method
= it
->glyphless_method
;
24993 glyph
->u
.glyphless
.for_no_font
= for_no_font
;
24994 glyph
->u
.glyphless
.len
= len
;
24995 glyph
->u
.glyphless
.ch
= it
->c
;
24996 glyph
->slice
.glyphless
.upper_xoff
= upper_xoff
;
24997 glyph
->slice
.glyphless
.upper_yoff
= upper_yoff
;
24998 glyph
->slice
.glyphless
.lower_xoff
= lower_xoff
;
24999 glyph
->slice
.glyphless
.lower_yoff
= lower_yoff
;
25000 glyph
->avoid_cursor_p
= it
->avoid_cursor_p
;
25001 glyph
->multibyte_p
= it
->multibyte_p
;
25002 if (it
->glyph_row
->reversed_p
&& area
== TEXT_AREA
)
25004 /* In R2L rows, the left and the right box edges need to be
25005 drawn in reverse direction. */
25006 glyph
->right_box_line_p
= it
->start_of_box_run_p
;
25007 glyph
->left_box_line_p
= it
->end_of_box_run_p
;
25011 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
25012 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
25014 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
25015 || it
->phys_descent
> it
->descent
);
25016 glyph
->padding_p
= 0;
25017 glyph
->glyph_not_available_p
= 0;
25018 glyph
->face_id
= face_id
;
25019 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
25022 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
25023 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
25025 glyph
->bidi_type
= it
->bidi_it
.type
;
25027 ++it
->glyph_row
->used
[area
];
25030 IT_EXPAND_MATRIX_WIDTH (it
, area
);
25034 /* Produce a glyph for a glyphless character for iterator IT.
25035 IT->glyphless_method specifies which method to use for displaying
25036 the character. See the description of enum
25037 glyphless_display_method in dispextern.h for the detail.
25039 FOR_NO_FONT is nonzero if and only if this is for a character for
25040 which no font was found. ACRONYM, if non-nil, is an acronym string
25041 for the character. */
25044 produce_glyphless_glyph (struct it
*it
, int for_no_font
, Lisp_Object acronym
)
25049 int base_width
, base_height
, width
, height
;
25050 short upper_xoff
, upper_yoff
, lower_xoff
, lower_yoff
;
25053 /* Get the metrics of the base font. We always refer to the current
25055 face
= FACE_FROM_ID (it
->f
, it
->face_id
)->ascii_face
;
25056 font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
25057 it
->ascent
= FONT_BASE (font
) + font
->baseline_offset
;
25058 it
->descent
= FONT_DESCENT (font
) - font
->baseline_offset
;
25059 base_height
= it
->ascent
+ it
->descent
;
25060 base_width
= font
->average_width
;
25062 face_id
= merge_glyphless_glyph_face (it
);
25064 if (it
->glyphless_method
== GLYPHLESS_DISPLAY_THIN_SPACE
)
25066 it
->pixel_width
= THIN_SPACE_WIDTH
;
25068 upper_xoff
= upper_yoff
= lower_xoff
= lower_yoff
= 0;
25070 else if (it
->glyphless_method
== GLYPHLESS_DISPLAY_EMPTY_BOX
)
25072 width
= CHAR_WIDTH (it
->c
);
25075 else if (width
> 4)
25077 it
->pixel_width
= base_width
* width
;
25079 upper_xoff
= upper_yoff
= lower_xoff
= lower_yoff
= 0;
25085 unsigned int code
[6];
25087 int ascent
, descent
;
25088 struct font_metrics metrics_upper
, metrics_lower
;
25090 face
= FACE_FROM_ID (it
->f
, face_id
);
25091 font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
25092 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
25094 if (it
->glyphless_method
== GLYPHLESS_DISPLAY_ACRONYM
)
25096 if (! STRINGP (acronym
) && CHAR_TABLE_P (Vglyphless_char_display
))
25097 acronym
= CHAR_TABLE_REF (Vglyphless_char_display
, it
->c
);
25098 if (CONSP (acronym
))
25099 acronym
= XCAR (acronym
);
25100 str
= STRINGP (acronym
) ? SSDATA (acronym
) : "";
25104 eassert (it
->glyphless_method
== GLYPHLESS_DISPLAY_HEX_CODE
);
25105 sprintf (buf
, "%0*X", it
->c
< 0x10000 ? 4 : 6, it
->c
);
25108 for (len
= 0; str
[len
] && ASCII_BYTE_P (str
[len
]) && len
< 6; len
++)
25109 code
[len
] = font
->driver
->encode_char (font
, str
[len
]);
25110 upper_len
= (len
+ 1) / 2;
25111 font
->driver
->text_extents (font
, code
, upper_len
,
25113 font
->driver
->text_extents (font
, code
+ upper_len
, len
- upper_len
,
25118 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
25119 width
= max (metrics_upper
.width
, metrics_lower
.width
) + 4;
25120 upper_xoff
= upper_yoff
= 2; /* the typical case */
25121 if (base_width
>= width
)
25123 /* Align the upper to the left, the lower to the right. */
25124 it
->pixel_width
= base_width
;
25125 lower_xoff
= base_width
- 2 - metrics_lower
.width
;
25129 /* Center the shorter one. */
25130 it
->pixel_width
= width
;
25131 if (metrics_upper
.width
>= metrics_lower
.width
)
25132 lower_xoff
= (width
- metrics_lower
.width
) / 2;
25135 /* FIXME: This code doesn't look right. It formerly was
25136 missing the "lower_xoff = 0;", which couldn't have
25137 been right since it left lower_xoff uninitialized. */
25139 upper_xoff
= (width
- metrics_upper
.width
) / 2;
25143 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
25144 top, bottom, and between upper and lower strings. */
25145 height
= (metrics_upper
.ascent
+ metrics_upper
.descent
25146 + metrics_lower
.ascent
+ metrics_lower
.descent
) + 5;
25147 /* Center vertically.
25148 H:base_height, D:base_descent
25149 h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent
25151 ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up
25152 descent = D - H/2 + h/2;
25153 lower_yoff = descent - 2 - ld;
25154 upper_yoff = lower_yoff - la - 1 - ud; */
25155 ascent
= - (it
->descent
- (base_height
+ height
+ 1) / 2);
25156 descent
= it
->descent
- (base_height
- height
) / 2;
25157 lower_yoff
= descent
- 2 - metrics_lower
.descent
;
25158 upper_yoff
= (lower_yoff
- metrics_lower
.ascent
- 1
25159 - metrics_upper
.descent
);
25160 /* Don't make the height shorter than the base height. */
25161 if (height
> base_height
)
25163 it
->ascent
= ascent
;
25164 it
->descent
= descent
;
25168 it
->phys_ascent
= it
->ascent
;
25169 it
->phys_descent
= it
->descent
;
25171 append_glyphless_glyph (it
, face_id
, for_no_font
, len
,
25172 upper_xoff
, upper_yoff
,
25173 lower_xoff
, lower_yoff
);
25175 take_vertical_position_into_account (it
);
25180 Produce glyphs/get display metrics for the display element IT is
25181 loaded with. See the description of struct it in dispextern.h
25182 for an overview of struct it. */
25185 x_produce_glyphs (struct it
*it
)
25187 int extra_line_spacing
= it
->extra_line_spacing
;
25189 it
->glyph_not_available_p
= 0;
25191 if (it
->what
== IT_CHARACTER
)
25194 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
25195 struct font
*font
= face
->font
;
25196 struct font_metrics
*pcm
= NULL
;
25197 int boff
; /* Baseline offset. */
25201 /* When no suitable font is found, display this character by
25202 the method specified in the first extra slot of
25203 Vglyphless_char_display. */
25204 Lisp_Object acronym
= lookup_glyphless_char_display (-1, it
);
25206 eassert (it
->what
== IT_GLYPHLESS
);
25207 produce_glyphless_glyph (it
, 1, STRINGP (acronym
) ? acronym
: Qnil
);
25211 boff
= font
->baseline_offset
;
25212 if (font
->vertical_centering
)
25213 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
25215 if (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t')
25221 if (it
->override_ascent
>= 0)
25223 it
->ascent
= it
->override_ascent
;
25224 it
->descent
= it
->override_descent
;
25225 boff
= it
->override_boff
;
25229 it
->ascent
= FONT_BASE (font
) + boff
;
25230 it
->descent
= FONT_DESCENT (font
) - boff
;
25233 if (get_char_glyph_code (it
->char_to_display
, font
, &char2b
))
25235 pcm
= get_per_char_metric (font
, &char2b
);
25236 if (pcm
->width
== 0
25237 && pcm
->rbearing
== 0 && pcm
->lbearing
== 0)
25243 it
->phys_ascent
= pcm
->ascent
+ boff
;
25244 it
->phys_descent
= pcm
->descent
- boff
;
25245 it
->pixel_width
= pcm
->width
;
25249 it
->glyph_not_available_p
= 1;
25250 it
->phys_ascent
= it
->ascent
;
25251 it
->phys_descent
= it
->descent
;
25252 it
->pixel_width
= font
->space_width
;
25255 if (it
->constrain_row_ascent_descent_p
)
25257 if (it
->descent
> it
->max_descent
)
25259 it
->ascent
+= it
->descent
- it
->max_descent
;
25260 it
->descent
= it
->max_descent
;
25262 if (it
->ascent
> it
->max_ascent
)
25264 it
->descent
= min (it
->max_descent
, it
->descent
+ it
->ascent
- it
->max_ascent
);
25265 it
->ascent
= it
->max_ascent
;
25267 it
->phys_ascent
= min (it
->phys_ascent
, it
->ascent
);
25268 it
->phys_descent
= min (it
->phys_descent
, it
->descent
);
25269 extra_line_spacing
= 0;
25272 /* If this is a space inside a region of text with
25273 `space-width' property, change its width. */
25274 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
25276 it
->pixel_width
*= XFLOATINT (it
->space_width
);
25278 /* If face has a box, add the box thickness to the character
25279 height. If character has a box line to the left and/or
25280 right, add the box line width to the character's width. */
25281 if (face
->box
!= FACE_NO_BOX
)
25283 int thick
= face
->box_line_width
;
25287 it
->ascent
+= thick
;
25288 it
->descent
+= thick
;
25293 if (it
->start_of_box_run_p
)
25294 it
->pixel_width
+= thick
;
25295 if (it
->end_of_box_run_p
)
25296 it
->pixel_width
+= thick
;
25299 /* If face has an overline, add the height of the overline
25300 (1 pixel) and a 1 pixel margin to the character height. */
25301 if (face
->overline_p
)
25302 it
->ascent
+= overline_margin
;
25304 if (it
->constrain_row_ascent_descent_p
)
25306 if (it
->ascent
> it
->max_ascent
)
25307 it
->ascent
= it
->max_ascent
;
25308 if (it
->descent
> it
->max_descent
)
25309 it
->descent
= it
->max_descent
;
25312 take_vertical_position_into_account (it
);
25314 /* If we have to actually produce glyphs, do it. */
25319 /* Translate a space with a `space-width' property
25320 into a stretch glyph. */
25321 int ascent
= (((it
->ascent
+ it
->descent
) * FONT_BASE (font
))
25322 / FONT_HEIGHT (font
));
25323 append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
25324 it
->ascent
+ it
->descent
, ascent
);
25329 /* If characters with lbearing or rbearing are displayed
25330 in this line, record that fact in a flag of the
25331 glyph row. This is used to optimize X output code. */
25332 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
25333 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
25335 if (! stretched_p
&& it
->pixel_width
== 0)
25336 /* We assure that all visible glyphs have at least 1-pixel
25338 it
->pixel_width
= 1;
25340 else if (it
->char_to_display
== '\n')
25342 /* A newline has no width, but we need the height of the
25343 line. But if previous part of the line sets a height,
25344 don't increase that height. */
25346 Lisp_Object height
;
25347 Lisp_Object total_height
= Qnil
;
25349 it
->override_ascent
= -1;
25350 it
->pixel_width
= 0;
25353 height
= get_it_property (it
, Qline_height
);
25354 /* Split (line-height total-height) list. */
25356 && CONSP (XCDR (height
))
25357 && NILP (XCDR (XCDR (height
))))
25359 total_height
= XCAR (XCDR (height
));
25360 height
= XCAR (height
);
25362 height
= calc_line_height_property (it
, height
, font
, boff
, 1);
25364 if (it
->override_ascent
>= 0)
25366 it
->ascent
= it
->override_ascent
;
25367 it
->descent
= it
->override_descent
;
25368 boff
= it
->override_boff
;
25372 it
->ascent
= FONT_BASE (font
) + boff
;
25373 it
->descent
= FONT_DESCENT (font
) - boff
;
25376 if (EQ (height
, Qt
))
25378 if (it
->descent
> it
->max_descent
)
25380 it
->ascent
+= it
->descent
- it
->max_descent
;
25381 it
->descent
= it
->max_descent
;
25383 if (it
->ascent
> it
->max_ascent
)
25385 it
->descent
= min (it
->max_descent
, it
->descent
+ it
->ascent
- it
->max_ascent
);
25386 it
->ascent
= it
->max_ascent
;
25388 it
->phys_ascent
= min (it
->phys_ascent
, it
->ascent
);
25389 it
->phys_descent
= min (it
->phys_descent
, it
->descent
);
25390 it
->constrain_row_ascent_descent_p
= 1;
25391 extra_line_spacing
= 0;
25395 Lisp_Object spacing
;
25397 it
->phys_ascent
= it
->ascent
;
25398 it
->phys_descent
= it
->descent
;
25400 if ((it
->max_ascent
> 0 || it
->max_descent
> 0)
25401 && face
->box
!= FACE_NO_BOX
25402 && face
->box_line_width
> 0)
25404 it
->ascent
+= face
->box_line_width
;
25405 it
->descent
+= face
->box_line_width
;
25408 && XINT (height
) > it
->ascent
+ it
->descent
)
25409 it
->ascent
= XINT (height
) - it
->descent
;
25411 if (!NILP (total_height
))
25412 spacing
= calc_line_height_property (it
, total_height
, font
, boff
, 0);
25415 spacing
= get_it_property (it
, Qline_spacing
);
25416 spacing
= calc_line_height_property (it
, spacing
, font
, boff
, 0);
25418 if (INTEGERP (spacing
))
25420 extra_line_spacing
= XINT (spacing
);
25421 if (!NILP (total_height
))
25422 extra_line_spacing
-= (it
->phys_ascent
+ it
->phys_descent
);
25426 else /* i.e. (it->char_to_display == '\t') */
25428 if (font
->space_width
> 0)
25430 int tab_width
= it
->tab_width
* font
->space_width
;
25431 int x
= it
->current_x
+ it
->continuation_lines_width
;
25432 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
25434 /* If the distance from the current position to the next tab
25435 stop is less than a space character width, use the
25436 tab stop after that. */
25437 if (next_tab_x
- x
< font
->space_width
)
25438 next_tab_x
+= tab_width
;
25440 it
->pixel_width
= next_tab_x
- x
;
25442 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
25443 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
25447 append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
25448 it
->ascent
+ it
->descent
, it
->ascent
);
25453 it
->pixel_width
= 0;
25458 else if (it
->what
== IT_COMPOSITION
&& it
->cmp_it
.ch
< 0)
25460 /* A static composition.
25462 Note: A composition is represented as one glyph in the
25463 glyph matrix. There are no padding glyphs.
25465 Important note: pixel_width, ascent, and descent are the
25466 values of what is drawn by draw_glyphs (i.e. the values of
25467 the overall glyphs composed). */
25468 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
25469 int boff
; /* baseline offset */
25470 struct composition
*cmp
= composition_table
[it
->cmp_it
.id
];
25471 int glyph_len
= cmp
->glyph_len
;
25472 struct font
*font
= face
->font
;
25476 /* If we have not yet calculated pixel size data of glyphs of
25477 the composition for the current face font, calculate them
25478 now. Theoretically, we have to check all fonts for the
25479 glyphs, but that requires much time and memory space. So,
25480 here we check only the font of the first glyph. This may
25481 lead to incorrect display, but it's very rare, and C-l
25482 (recenter-top-bottom) can correct the display anyway. */
25483 if (! cmp
->font
|| cmp
->font
!= font
)
25485 /* Ascent and descent of the font of the first character
25486 of this composition (adjusted by baseline offset).
25487 Ascent and descent of overall glyphs should not be less
25488 than these, respectively. */
25489 int font_ascent
, font_descent
, font_height
;
25490 /* Bounding box of the overall glyphs. */
25491 int leftmost
, rightmost
, lowest
, highest
;
25492 int lbearing
, rbearing
;
25493 int i
, width
, ascent
, descent
;
25494 int left_padded
= 0, right_padded
= 0;
25495 int c
IF_LINT (= 0); /* cmp->glyph_len can't be zero; see Bug#8512 */
25497 struct font_metrics
*pcm
;
25498 int font_not_found_p
;
25501 for (glyph_len
= cmp
->glyph_len
; glyph_len
> 0; glyph_len
--)
25502 if ((c
= COMPOSITION_GLYPH (cmp
, glyph_len
- 1)) != '\t')
25504 if (glyph_len
< cmp
->glyph_len
)
25506 for (i
= 0; i
< glyph_len
; i
++)
25508 if ((c
= COMPOSITION_GLYPH (cmp
, i
)) != '\t')
25510 cmp
->offsets
[i
* 2] = cmp
->offsets
[i
* 2 + 1] = 0;
25515 pos
= (STRINGP (it
->string
) ? IT_STRING_CHARPOS (*it
)
25516 : IT_CHARPOS (*it
));
25517 /* If no suitable font is found, use the default font. */
25518 font_not_found_p
= font
== NULL
;
25519 if (font_not_found_p
)
25521 face
= face
->ascii_face
;
25524 boff
= font
->baseline_offset
;
25525 if (font
->vertical_centering
)
25526 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
25527 font_ascent
= FONT_BASE (font
) + boff
;
25528 font_descent
= FONT_DESCENT (font
) - boff
;
25529 font_height
= FONT_HEIGHT (font
);
25534 if (! font_not_found_p
)
25536 get_char_face_and_encoding (it
->f
, c
, it
->face_id
,
25538 pcm
= get_per_char_metric (font
, &char2b
);
25541 /* Initialize the bounding box. */
25544 width
= cmp
->glyph_len
> 0 ? pcm
->width
: 0;
25545 ascent
= pcm
->ascent
;
25546 descent
= pcm
->descent
;
25547 lbearing
= pcm
->lbearing
;
25548 rbearing
= pcm
->rbearing
;
25552 width
= cmp
->glyph_len
> 0 ? font
->space_width
: 0;
25553 ascent
= FONT_BASE (font
);
25554 descent
= FONT_DESCENT (font
);
25561 lowest
= - descent
+ boff
;
25562 highest
= ascent
+ boff
;
25564 if (! font_not_found_p
25565 && font
->default_ascent
25566 && CHAR_TABLE_P (Vuse_default_ascent
)
25567 && !NILP (Faref (Vuse_default_ascent
,
25568 make_number (it
->char_to_display
))))
25569 highest
= font
->default_ascent
+ boff
;
25571 /* Draw the first glyph at the normal position. It may be
25572 shifted to right later if some other glyphs are drawn
25574 cmp
->offsets
[i
* 2] = 0;
25575 cmp
->offsets
[i
* 2 + 1] = boff
;
25576 cmp
->lbearing
= lbearing
;
25577 cmp
->rbearing
= rbearing
;
25579 /* Set cmp->offsets for the remaining glyphs. */
25580 for (i
++; i
< glyph_len
; i
++)
25582 int left
, right
, btm
, top
;
25583 int ch
= COMPOSITION_GLYPH (cmp
, i
);
25585 struct face
*this_face
;
25589 face_id
= FACE_FOR_CHAR (it
->f
, face
, ch
, pos
, it
->string
);
25590 this_face
= FACE_FROM_ID (it
->f
, face_id
);
25591 font
= this_face
->font
;
25597 get_char_face_and_encoding (it
->f
, ch
, face_id
,
25599 pcm
= get_per_char_metric (font
, &char2b
);
25602 cmp
->offsets
[i
* 2] = cmp
->offsets
[i
* 2 + 1] = 0;
25605 width
= pcm
->width
;
25606 ascent
= pcm
->ascent
;
25607 descent
= pcm
->descent
;
25608 lbearing
= pcm
->lbearing
;
25609 rbearing
= pcm
->rbearing
;
25610 if (cmp
->method
!= COMPOSITION_WITH_RULE_ALTCHARS
)
25612 /* Relative composition with or without
25613 alternate chars. */
25614 left
= (leftmost
+ rightmost
- width
) / 2;
25615 btm
= - descent
+ boff
;
25616 if (font
->relative_compose
25617 && (! CHAR_TABLE_P (Vignore_relative_composition
)
25618 || NILP (Faref (Vignore_relative_composition
,
25619 make_number (ch
)))))
25622 if (- descent
>= font
->relative_compose
)
25623 /* One extra pixel between two glyphs. */
25625 else if (ascent
<= 0)
25626 /* One extra pixel between two glyphs. */
25627 btm
= lowest
- 1 - ascent
- descent
;
25632 /* A composition rule is specified by an integer
25633 value that encodes global and new reference
25634 points (GREF and NREF). GREF and NREF are
25635 specified by numbers as below:
25637 0---1---2 -- ascent
25641 9--10--11 -- center
25643 ---3---4---5--- baseline
25645 6---7---8 -- descent
25647 int rule
= COMPOSITION_RULE (cmp
, i
);
25648 int gref
, nref
, grefx
, grefy
, nrefx
, nrefy
, xoff
, yoff
;
25650 COMPOSITION_DECODE_RULE (rule
, gref
, nref
, xoff
, yoff
);
25651 grefx
= gref
% 3, nrefx
= nref
% 3;
25652 grefy
= gref
/ 3, nrefy
= nref
/ 3;
25654 xoff
= font_height
* (xoff
- 128) / 256;
25656 yoff
= font_height
* (yoff
- 128) / 256;
25659 + grefx
* (rightmost
- leftmost
) / 2
25660 - nrefx
* width
/ 2
25663 btm
= ((grefy
== 0 ? highest
25665 : grefy
== 2 ? lowest
25666 : (highest
+ lowest
) / 2)
25667 - (nrefy
== 0 ? ascent
+ descent
25668 : nrefy
== 1 ? descent
- boff
25670 : (ascent
+ descent
) / 2)
25674 cmp
->offsets
[i
* 2] = left
;
25675 cmp
->offsets
[i
* 2 + 1] = btm
+ descent
;
25677 /* Update the bounding box of the overall glyphs. */
25680 right
= left
+ width
;
25681 if (left
< leftmost
)
25683 if (right
> rightmost
)
25686 top
= btm
+ descent
+ ascent
;
25692 if (cmp
->lbearing
> left
+ lbearing
)
25693 cmp
->lbearing
= left
+ lbearing
;
25694 if (cmp
->rbearing
< left
+ rbearing
)
25695 cmp
->rbearing
= left
+ rbearing
;
25699 /* If there are glyphs whose x-offsets are negative,
25700 shift all glyphs to the right and make all x-offsets
25704 for (i
= 0; i
< cmp
->glyph_len
; i
++)
25705 cmp
->offsets
[i
* 2] -= leftmost
;
25706 rightmost
-= leftmost
;
25707 cmp
->lbearing
-= leftmost
;
25708 cmp
->rbearing
-= leftmost
;
25711 if (left_padded
&& cmp
->lbearing
< 0)
25713 for (i
= 0; i
< cmp
->glyph_len
; i
++)
25714 cmp
->offsets
[i
* 2] -= cmp
->lbearing
;
25715 rightmost
-= cmp
->lbearing
;
25716 cmp
->rbearing
-= cmp
->lbearing
;
25719 if (right_padded
&& rightmost
< cmp
->rbearing
)
25721 rightmost
= cmp
->rbearing
;
25724 cmp
->pixel_width
= rightmost
;
25725 cmp
->ascent
= highest
;
25726 cmp
->descent
= - lowest
;
25727 if (cmp
->ascent
< font_ascent
)
25728 cmp
->ascent
= font_ascent
;
25729 if (cmp
->descent
< font_descent
)
25730 cmp
->descent
= font_descent
;
25734 && (cmp
->lbearing
< 0
25735 || cmp
->rbearing
> cmp
->pixel_width
))
25736 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
25738 it
->pixel_width
= cmp
->pixel_width
;
25739 it
->ascent
= it
->phys_ascent
= cmp
->ascent
;
25740 it
->descent
= it
->phys_descent
= cmp
->descent
;
25741 if (face
->box
!= FACE_NO_BOX
)
25743 int thick
= face
->box_line_width
;
25747 it
->ascent
+= thick
;
25748 it
->descent
+= thick
;
25753 if (it
->start_of_box_run_p
)
25754 it
->pixel_width
+= thick
;
25755 if (it
->end_of_box_run_p
)
25756 it
->pixel_width
+= thick
;
25759 /* If face has an overline, add the height of the overline
25760 (1 pixel) and a 1 pixel margin to the character height. */
25761 if (face
->overline_p
)
25762 it
->ascent
+= overline_margin
;
25764 take_vertical_position_into_account (it
);
25765 if (it
->ascent
< 0)
25767 if (it
->descent
< 0)
25770 if (it
->glyph_row
&& cmp
->glyph_len
> 0)
25771 append_composite_glyph (it
);
25773 else if (it
->what
== IT_COMPOSITION
)
25775 /* A dynamic (automatic) composition. */
25776 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
25777 Lisp_Object gstring
;
25778 struct font_metrics metrics
;
25782 gstring
= composition_gstring_from_id (it
->cmp_it
.id
);
25784 = composition_gstring_width (gstring
, it
->cmp_it
.from
, it
->cmp_it
.to
,
25787 && (metrics
.lbearing
< 0 || metrics
.rbearing
> metrics
.width
))
25788 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
25789 it
->ascent
= it
->phys_ascent
= metrics
.ascent
;
25790 it
->descent
= it
->phys_descent
= metrics
.descent
;
25791 if (face
->box
!= FACE_NO_BOX
)
25793 int thick
= face
->box_line_width
;
25797 it
->ascent
+= thick
;
25798 it
->descent
+= thick
;
25803 if (it
->start_of_box_run_p
)
25804 it
->pixel_width
+= thick
;
25805 if (it
->end_of_box_run_p
)
25806 it
->pixel_width
+= thick
;
25808 /* If face has an overline, add the height of the overline
25809 (1 pixel) and a 1 pixel margin to the character height. */
25810 if (face
->overline_p
)
25811 it
->ascent
+= overline_margin
;
25812 take_vertical_position_into_account (it
);
25813 if (it
->ascent
< 0)
25815 if (it
->descent
< 0)
25819 append_composite_glyph (it
);
25821 else if (it
->what
== IT_GLYPHLESS
)
25822 produce_glyphless_glyph (it
, 0, Qnil
);
25823 else if (it
->what
== IT_IMAGE
)
25824 produce_image_glyph (it
);
25825 else if (it
->what
== IT_STRETCH
)
25826 produce_stretch_glyph (it
);
25829 /* Accumulate dimensions. Note: can't assume that it->descent > 0
25830 because this isn't true for images with `:ascent 100'. */
25831 eassert (it
->ascent
>= 0 && it
->descent
>= 0);
25832 if (it
->area
== TEXT_AREA
)
25833 it
->current_x
+= it
->pixel_width
;
25835 if (extra_line_spacing
> 0)
25837 it
->descent
+= extra_line_spacing
;
25838 if (extra_line_spacing
> it
->max_extra_line_spacing
)
25839 it
->max_extra_line_spacing
= extra_line_spacing
;
25842 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
25843 it
->max_descent
= max (it
->max_descent
, it
->descent
);
25844 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
25845 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
25849 Output LEN glyphs starting at START at the nominal cursor position.
25850 Advance the nominal cursor over the text. UPDATED_ROW is the glyph row
25851 being updated, and UPDATED_AREA is the area of that row being updated. */
25854 x_write_glyphs (struct window
*w
, struct glyph_row
*updated_row
,
25855 struct glyph
*start
, enum glyph_row_area updated_area
, int len
)
25857 int x
, hpos
, chpos
= w
->phys_cursor
.hpos
;
25859 eassert (updated_row
);
25860 /* When the window is hscrolled, cursor hpos can legitimately be out
25861 of bounds, but we draw the cursor at the corresponding window
25862 margin in that case. */
25863 if (!updated_row
->reversed_p
&& chpos
< 0)
25865 if (updated_row
->reversed_p
&& chpos
>= updated_row
->used
[TEXT_AREA
])
25866 chpos
= updated_row
->used
[TEXT_AREA
] - 1;
25870 /* Write glyphs. */
25872 hpos
= start
- updated_row
->glyphs
[updated_area
];
25873 x
= draw_glyphs (w
, w
->output_cursor
.x
,
25874 updated_row
, updated_area
,
25876 DRAW_NORMAL_TEXT
, 0);
25878 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
25879 if (updated_area
== TEXT_AREA
25880 && w
->phys_cursor_on_p
25881 && w
->phys_cursor
.vpos
== w
->output_cursor
.vpos
25883 && chpos
< hpos
+ len
)
25884 w
->phys_cursor_on_p
= 0;
25888 /* Advance the output cursor. */
25889 w
->output_cursor
.hpos
+= len
;
25890 w
->output_cursor
.x
= x
;
25895 Insert LEN glyphs from START at the nominal cursor position. */
25898 x_insert_glyphs (struct window
*w
, struct glyph_row
*updated_row
,
25899 struct glyph
*start
, enum glyph_row_area updated_area
, int len
)
25902 int line_height
, shift_by_width
, shifted_region_width
;
25903 struct glyph_row
*row
;
25904 struct glyph
*glyph
;
25905 int frame_x
, frame_y
;
25908 eassert (updated_row
);
25910 f
= XFRAME (WINDOW_FRAME (w
));
25912 /* Get the height of the line we are in. */
25914 line_height
= row
->height
;
25916 /* Get the width of the glyphs to insert. */
25917 shift_by_width
= 0;
25918 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
25919 shift_by_width
+= glyph
->pixel_width
;
25921 /* Get the width of the region to shift right. */
25922 shifted_region_width
= (window_box_width (w
, updated_area
)
25923 - w
->output_cursor
.x
25927 frame_x
= window_box_left (w
, updated_area
) + w
->output_cursor
.x
;
25928 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, w
->output_cursor
.y
);
25930 FRAME_RIF (f
)->shift_glyphs_for_insert (f
, frame_x
, frame_y
, shifted_region_width
,
25931 line_height
, shift_by_width
);
25933 /* Write the glyphs. */
25934 hpos
= start
- row
->glyphs
[updated_area
];
25935 draw_glyphs (w
, w
->output_cursor
.x
, row
, updated_area
,
25937 DRAW_NORMAL_TEXT
, 0);
25939 /* Advance the output cursor. */
25940 w
->output_cursor
.hpos
+= len
;
25941 w
->output_cursor
.x
+= shift_by_width
;
25947 Erase the current text line from the nominal cursor position
25948 (inclusive) to pixel column TO_X (exclusive). The idea is that
25949 everything from TO_X onward is already erased.
25951 TO_X is a pixel position relative to UPDATED_AREA of currently
25952 updated window W. TO_X == -1 means clear to the end of this area. */
25955 x_clear_end_of_line (struct window
*w
, struct glyph_row
*updated_row
,
25956 enum glyph_row_area updated_area
, int to_x
)
25959 int max_x
, min_y
, max_y
;
25960 int from_x
, from_y
, to_y
;
25962 eassert (updated_row
);
25963 f
= XFRAME (w
->frame
);
25965 if (updated_row
->full_width_p
)
25966 max_x
= WINDOW_TOTAL_WIDTH (w
);
25968 max_x
= window_box_width (w
, updated_area
);
25969 max_y
= window_text_bottom_y (w
);
25971 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
25972 of window. For TO_X > 0, truncate to end of drawing area. */
25978 to_x
= min (to_x
, max_x
);
25980 to_y
= min (max_y
, w
->output_cursor
.y
+ updated_row
->height
);
25982 /* Notice if the cursor will be cleared by this operation. */
25983 if (!updated_row
->full_width_p
)
25984 notice_overwritten_cursor (w
, updated_area
,
25985 w
->output_cursor
.x
, -1,
25987 MATRIX_ROW_BOTTOM_Y (updated_row
));
25989 from_x
= w
->output_cursor
.x
;
25991 /* Translate to frame coordinates. */
25992 if (updated_row
->full_width_p
)
25994 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
25995 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
25999 int area_left
= window_box_left (w
, updated_area
);
26000 from_x
+= area_left
;
26004 min_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
26005 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, w
->output_cursor
.y
));
26006 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
26008 /* Prevent inadvertently clearing to end of the X window. */
26009 if (to_x
> from_x
&& to_y
> from_y
)
26012 FRAME_RIF (f
)->clear_frame_area (f
, from_x
, from_y
,
26013 to_x
- from_x
, to_y
- from_y
);
26018 #endif /* HAVE_WINDOW_SYSTEM */
26022 /***********************************************************************
26024 ***********************************************************************/
26026 /* Value is the internal representation of the specified cursor type
26027 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
26028 of the bar cursor. */
26030 static enum text_cursor_kinds
26031 get_specified_cursor_type (Lisp_Object arg
, int *width
)
26033 enum text_cursor_kinds type
;
26038 if (EQ (arg
, Qbox
))
26039 return FILLED_BOX_CURSOR
;
26041 if (EQ (arg
, Qhollow
))
26042 return HOLLOW_BOX_CURSOR
;
26044 if (EQ (arg
, Qbar
))
26051 && EQ (XCAR (arg
), Qbar
)
26052 && RANGED_INTEGERP (0, XCDR (arg
), INT_MAX
))
26054 *width
= XINT (XCDR (arg
));
26058 if (EQ (arg
, Qhbar
))
26061 return HBAR_CURSOR
;
26065 && EQ (XCAR (arg
), Qhbar
)
26066 && RANGED_INTEGERP (0, XCDR (arg
), INT_MAX
))
26068 *width
= XINT (XCDR (arg
));
26069 return HBAR_CURSOR
;
26072 /* Treat anything unknown as "hollow box cursor".
26073 It was bad to signal an error; people have trouble fixing
26074 .Xdefaults with Emacs, when it has something bad in it. */
26075 type
= HOLLOW_BOX_CURSOR
;
26080 /* Set the default cursor types for specified frame. */
26082 set_frame_cursor_types (struct frame
*f
, Lisp_Object arg
)
26087 FRAME_DESIRED_CURSOR (f
) = get_specified_cursor_type (arg
, &width
);
26088 FRAME_CURSOR_WIDTH (f
) = width
;
26090 /* By default, set up the blink-off state depending on the on-state. */
26092 tem
= Fassoc (arg
, Vblink_cursor_alist
);
26095 FRAME_BLINK_OFF_CURSOR (f
)
26096 = get_specified_cursor_type (XCDR (tem
), &width
);
26097 FRAME_BLINK_OFF_CURSOR_WIDTH (f
) = width
;
26100 FRAME_BLINK_OFF_CURSOR (f
) = DEFAULT_CURSOR
;
26102 /* Make sure the cursor gets redrawn. */
26103 f
->cursor_type_changed
= 1;
26107 #ifdef HAVE_WINDOW_SYSTEM
26109 /* Return the cursor we want to be displayed in window W. Return
26110 width of bar/hbar cursor through WIDTH arg. Return with
26111 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
26112 (i.e. if the `system caret' should track this cursor).
26114 In a mini-buffer window, we want the cursor only to appear if we
26115 are reading input from this window. For the selected window, we
26116 want the cursor type given by the frame parameter or buffer local
26117 setting of cursor-type. If explicitly marked off, draw no cursor.
26118 In all other cases, we want a hollow box cursor. */
26120 static enum text_cursor_kinds
26121 get_window_cursor_type (struct window
*w
, struct glyph
*glyph
, int *width
,
26122 int *active_cursor
)
26124 struct frame
*f
= XFRAME (w
->frame
);
26125 struct buffer
*b
= XBUFFER (w
->contents
);
26126 int cursor_type
= DEFAULT_CURSOR
;
26127 Lisp_Object alt_cursor
;
26128 int non_selected
= 0;
26130 *active_cursor
= 1;
26133 if (cursor_in_echo_area
26134 && FRAME_HAS_MINIBUF_P (f
)
26135 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
26137 if (w
== XWINDOW (echo_area_window
))
26139 if (EQ (BVAR (b
, cursor_type
), Qt
) || NILP (BVAR (b
, cursor_type
)))
26141 *width
= FRAME_CURSOR_WIDTH (f
);
26142 return FRAME_DESIRED_CURSOR (f
);
26145 return get_specified_cursor_type (BVAR (b
, cursor_type
), width
);
26148 *active_cursor
= 0;
26152 /* Detect a nonselected window or nonselected frame. */
26153 else if (w
!= XWINDOW (f
->selected_window
)
26154 || f
!= FRAME_DISPLAY_INFO (f
)->x_highlight_frame
)
26156 *active_cursor
= 0;
26158 if (MINI_WINDOW_P (w
) && minibuf_level
== 0)
26164 /* Never display a cursor in a window in which cursor-type is nil. */
26165 if (NILP (BVAR (b
, cursor_type
)))
26168 /* Get the normal cursor type for this window. */
26169 if (EQ (BVAR (b
, cursor_type
), Qt
))
26171 cursor_type
= FRAME_DESIRED_CURSOR (f
);
26172 *width
= FRAME_CURSOR_WIDTH (f
);
26175 cursor_type
= get_specified_cursor_type (BVAR (b
, cursor_type
), width
);
26177 /* Use cursor-in-non-selected-windows instead
26178 for non-selected window or frame. */
26181 alt_cursor
= BVAR (b
, cursor_in_non_selected_windows
);
26182 if (!EQ (Qt
, alt_cursor
))
26183 return get_specified_cursor_type (alt_cursor
, width
);
26184 /* t means modify the normal cursor type. */
26185 if (cursor_type
== FILLED_BOX_CURSOR
)
26186 cursor_type
= HOLLOW_BOX_CURSOR
;
26187 else if (cursor_type
== BAR_CURSOR
&& *width
> 1)
26189 return cursor_type
;
26192 /* Use normal cursor if not blinked off. */
26193 if (!w
->cursor_off_p
)
26195 if (glyph
!= NULL
&& glyph
->type
== IMAGE_GLYPH
)
26197 if (cursor_type
== FILLED_BOX_CURSOR
)
26199 /* Using a block cursor on large images can be very annoying.
26200 So use a hollow cursor for "large" images.
26201 If image is not transparent (no mask), also use hollow cursor. */
26202 struct image
*img
= IMAGE_FROM_ID (f
, glyph
->u
.img_id
);
26203 if (img
!= NULL
&& IMAGEP (img
->spec
))
26205 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
26206 where N = size of default frame font size.
26207 This should cover most of the "tiny" icons people may use. */
26209 || img
->width
> max (32, WINDOW_FRAME_COLUMN_WIDTH (w
))
26210 || img
->height
> max (32, WINDOW_FRAME_LINE_HEIGHT (w
)))
26211 cursor_type
= HOLLOW_BOX_CURSOR
;
26214 else if (cursor_type
!= NO_CURSOR
)
26216 /* Display current only supports BOX and HOLLOW cursors for images.
26217 So for now, unconditionally use a HOLLOW cursor when cursor is
26218 not a solid box cursor. */
26219 cursor_type
= HOLLOW_BOX_CURSOR
;
26222 return cursor_type
;
26225 /* Cursor is blinked off, so determine how to "toggle" it. */
26227 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
26228 if ((alt_cursor
= Fassoc (BVAR (b
, cursor_type
), Vblink_cursor_alist
), !NILP (alt_cursor
)))
26229 return get_specified_cursor_type (XCDR (alt_cursor
), width
);
26231 /* Then see if frame has specified a specific blink off cursor type. */
26232 if (FRAME_BLINK_OFF_CURSOR (f
) != DEFAULT_CURSOR
)
26234 *width
= FRAME_BLINK_OFF_CURSOR_WIDTH (f
);
26235 return FRAME_BLINK_OFF_CURSOR (f
);
26239 /* Some people liked having a permanently visible blinking cursor,
26240 while others had very strong opinions against it. So it was
26241 decided to remove it. KFS 2003-09-03 */
26243 /* Finally perform built-in cursor blinking:
26244 filled box <-> hollow box
26245 wide [h]bar <-> narrow [h]bar
26246 narrow [h]bar <-> no cursor
26247 other type <-> no cursor */
26249 if (cursor_type
== FILLED_BOX_CURSOR
)
26250 return HOLLOW_BOX_CURSOR
;
26252 if ((cursor_type
== BAR_CURSOR
|| cursor_type
== HBAR_CURSOR
) && *width
> 1)
26255 return cursor_type
;
26263 /* Notice when the text cursor of window W has been completely
26264 overwritten by a drawing operation that outputs glyphs in AREA
26265 starting at X0 and ending at X1 in the line starting at Y0 and
26266 ending at Y1. X coordinates are area-relative. X1 < 0 means all
26267 the rest of the line after X0 has been written. Y coordinates
26268 are window-relative. */
26271 notice_overwritten_cursor (struct window
*w
, enum glyph_row_area area
,
26272 int x0
, int x1
, int y0
, int y1
)
26274 int cx0
, cx1
, cy0
, cy1
;
26275 struct glyph_row
*row
;
26277 if (!w
->phys_cursor_on_p
)
26279 if (area
!= TEXT_AREA
)
26282 if (w
->phys_cursor
.vpos
< 0
26283 || w
->phys_cursor
.vpos
>= w
->current_matrix
->nrows
26284 || (row
= w
->current_matrix
->rows
+ w
->phys_cursor
.vpos
,
26285 !(row
->enabled_p
&& MATRIX_ROW_DISPLAYS_TEXT_P (row
))))
26288 if (row
->cursor_in_fringe_p
)
26290 row
->cursor_in_fringe_p
= 0;
26291 draw_fringe_bitmap (w
, row
, row
->reversed_p
);
26292 w
->phys_cursor_on_p
= 0;
26296 cx0
= w
->phys_cursor
.x
;
26297 cx1
= cx0
+ w
->phys_cursor_width
;
26298 if (x0
> cx0
|| (x1
>= 0 && x1
< cx1
))
26301 /* The cursor image will be completely removed from the
26302 screen if the output area intersects the cursor area in
26303 y-direction. When we draw in [y0 y1[, and some part of
26304 the cursor is at y < y0, that part must have been drawn
26305 before. When scrolling, the cursor is erased before
26306 actually scrolling, so we don't come here. When not
26307 scrolling, the rows above the old cursor row must have
26308 changed, and in this case these rows must have written
26309 over the cursor image.
26311 Likewise if part of the cursor is below y1, with the
26312 exception of the cursor being in the first blank row at
26313 the buffer and window end because update_text_area
26314 doesn't draw that row. (Except when it does, but
26315 that's handled in update_text_area.) */
26317 cy0
= w
->phys_cursor
.y
;
26318 cy1
= cy0
+ w
->phys_cursor_height
;
26319 if ((y0
< cy0
|| y0
>= cy1
) && (y1
<= cy0
|| y1
>= cy1
))
26322 w
->phys_cursor_on_p
= 0;
26325 #endif /* HAVE_WINDOW_SYSTEM */
26328 /************************************************************************
26330 ************************************************************************/
26332 #ifdef HAVE_WINDOW_SYSTEM
26335 Fix the display of area AREA of overlapping row ROW in window W
26336 with respect to the overlapping part OVERLAPS. */
26339 x_fix_overlapping_area (struct window
*w
, struct glyph_row
*row
,
26340 enum glyph_row_area area
, int overlaps
)
26347 for (i
= 0; i
< row
->used
[area
];)
26349 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
26351 int start
= i
, start_x
= x
;
26355 x
+= row
->glyphs
[area
][i
].pixel_width
;
26358 while (i
< row
->used
[area
]
26359 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
26361 draw_glyphs (w
, start_x
, row
, area
,
26363 DRAW_NORMAL_TEXT
, overlaps
);
26367 x
+= row
->glyphs
[area
][i
].pixel_width
;
26377 Draw the cursor glyph of window W in glyph row ROW. See the
26378 comment of draw_glyphs for the meaning of HL. */
26381 draw_phys_cursor_glyph (struct window
*w
, struct glyph_row
*row
,
26382 enum draw_glyphs_face hl
)
26384 /* If cursor hpos is out of bounds, don't draw garbage. This can
26385 happen in mini-buffer windows when switching between echo area
26386 glyphs and mini-buffer. */
26387 if ((row
->reversed_p
26388 ? (w
->phys_cursor
.hpos
>= 0)
26389 : (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])))
26391 int on_p
= w
->phys_cursor_on_p
;
26393 int hpos
= w
->phys_cursor
.hpos
;
26395 /* When the window is hscrolled, cursor hpos can legitimately be
26396 out of bounds, but we draw the cursor at the corresponding
26397 window margin in that case. */
26398 if (!row
->reversed_p
&& hpos
< 0)
26400 if (row
->reversed_p
&& hpos
>= row
->used
[TEXT_AREA
])
26401 hpos
= row
->used
[TEXT_AREA
] - 1;
26403 x1
= draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
, hpos
, hpos
+ 1,
26405 w
->phys_cursor_on_p
= on_p
;
26407 if (hl
== DRAW_CURSOR
)
26408 w
->phys_cursor_width
= x1
- w
->phys_cursor
.x
;
26409 /* When we erase the cursor, and ROW is overlapped by other
26410 rows, make sure that these overlapping parts of other rows
26412 else if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
26414 w
->phys_cursor_width
= x1
- w
->phys_cursor
.x
;
26416 if (row
> w
->current_matrix
->rows
26417 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
26418 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
,
26419 OVERLAPS_ERASED_CURSOR
);
26421 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
26422 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
26423 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
,
26424 OVERLAPS_ERASED_CURSOR
);
26430 /* Erase the image of a cursor of window W from the screen. */
26436 erase_phys_cursor (struct window
*w
)
26438 struct frame
*f
= XFRAME (w
->frame
);
26439 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
26440 int hpos
= w
->phys_cursor
.hpos
;
26441 int vpos
= w
->phys_cursor
.vpos
;
26442 int mouse_face_here_p
= 0;
26443 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
26444 struct glyph_row
*cursor_row
;
26445 struct glyph
*cursor_glyph
;
26446 enum draw_glyphs_face hl
;
26448 /* No cursor displayed or row invalidated => nothing to do on the
26450 if (w
->phys_cursor_type
== NO_CURSOR
)
26451 goto mark_cursor_off
;
26453 /* VPOS >= active_glyphs->nrows means that window has been resized.
26454 Don't bother to erase the cursor. */
26455 if (vpos
>= active_glyphs
->nrows
)
26456 goto mark_cursor_off
;
26458 /* If row containing cursor is marked invalid, there is nothing we
26460 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
26461 if (!cursor_row
->enabled_p
)
26462 goto mark_cursor_off
;
26464 /* If line spacing is > 0, old cursor may only be partially visible in
26465 window after split-window. So adjust visible height. */
26466 cursor_row
->visible_height
= min (cursor_row
->visible_height
,
26467 window_text_bottom_y (w
) - cursor_row
->y
);
26469 /* If row is completely invisible, don't attempt to delete a cursor which
26470 isn't there. This can happen if cursor is at top of a window, and
26471 we switch to a buffer with a header line in that window. */
26472 if (cursor_row
->visible_height
<= 0)
26473 goto mark_cursor_off
;
26475 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
26476 if (cursor_row
->cursor_in_fringe_p
)
26478 cursor_row
->cursor_in_fringe_p
= 0;
26479 draw_fringe_bitmap (w
, cursor_row
, cursor_row
->reversed_p
);
26480 goto mark_cursor_off
;
26483 /* This can happen when the new row is shorter than the old one.
26484 In this case, either draw_glyphs or clear_end_of_line
26485 should have cleared the cursor. Note that we wouldn't be
26486 able to erase the cursor in this case because we don't have a
26487 cursor glyph at hand. */
26488 if ((cursor_row
->reversed_p
26489 ? (w
->phys_cursor
.hpos
< 0)
26490 : (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])))
26491 goto mark_cursor_off
;
26493 /* When the window is hscrolled, cursor hpos can legitimately be out
26494 of bounds, but we draw the cursor at the corresponding window
26495 margin in that case. */
26496 if (!cursor_row
->reversed_p
&& hpos
< 0)
26498 if (cursor_row
->reversed_p
&& hpos
>= cursor_row
->used
[TEXT_AREA
])
26499 hpos
= cursor_row
->used
[TEXT_AREA
] - 1;
26501 /* If the cursor is in the mouse face area, redisplay that when
26502 we clear the cursor. */
26503 if (! NILP (hlinfo
->mouse_face_window
)
26504 && coords_in_mouse_face_p (w
, hpos
, vpos
)
26505 /* Don't redraw the cursor's spot in mouse face if it is at the
26506 end of a line (on a newline). The cursor appears there, but
26507 mouse highlighting does not. */
26508 && cursor_row
->used
[TEXT_AREA
] > hpos
&& hpos
>= 0)
26509 mouse_face_here_p
= 1;
26511 /* Maybe clear the display under the cursor. */
26512 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
26515 int header_line_height
= WINDOW_HEADER_LINE_HEIGHT (w
);
26518 cursor_glyph
= get_phys_cursor_glyph (w
);
26519 if (cursor_glyph
== NULL
)
26520 goto mark_cursor_off
;
26522 width
= cursor_glyph
->pixel_width
;
26523 left_x
= window_box_left_offset (w
, TEXT_AREA
);
26524 x
= w
->phys_cursor
.x
;
26526 width
-= left_x
- x
;
26527 width
= min (width
, window_box_width (w
, TEXT_AREA
) - x
);
26528 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
, cursor_row
->y
));
26529 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, max (x
, left_x
));
26532 FRAME_RIF (f
)->clear_frame_area (f
, x
, y
, width
, cursor_row
->visible_height
);
26535 /* Erase the cursor by redrawing the character underneath it. */
26536 if (mouse_face_here_p
)
26537 hl
= DRAW_MOUSE_FACE
;
26539 hl
= DRAW_NORMAL_TEXT
;
26540 draw_phys_cursor_glyph (w
, cursor_row
, hl
);
26543 w
->phys_cursor_on_p
= 0;
26544 w
->phys_cursor_type
= NO_CURSOR
;
26549 Display or clear cursor of window W. If ON is zero, clear the
26550 cursor. If it is non-zero, display the cursor. If ON is nonzero,
26551 where to put the cursor is specified by HPOS, VPOS, X and Y. */
26554 display_and_set_cursor (struct window
*w
, bool on
,
26555 int hpos
, int vpos
, int x
, int y
)
26557 struct frame
*f
= XFRAME (w
->frame
);
26558 int new_cursor_type
;
26559 int new_cursor_width
;
26561 struct glyph_row
*glyph_row
;
26562 struct glyph
*glyph
;
26564 /* This is pointless on invisible frames, and dangerous on garbaged
26565 windows and frames; in the latter case, the frame or window may
26566 be in the midst of changing its size, and x and y may be off the
26568 if (! FRAME_VISIBLE_P (f
)
26569 || FRAME_GARBAGED_P (f
)
26570 || vpos
>= w
->current_matrix
->nrows
26571 || hpos
>= w
->current_matrix
->matrix_w
)
26574 /* If cursor is off and we want it off, return quickly. */
26575 if (!on
&& !w
->phys_cursor_on_p
)
26578 glyph_row
= MATRIX_ROW (w
->current_matrix
, vpos
);
26579 /* If cursor row is not enabled, we don't really know where to
26580 display the cursor. */
26581 if (!glyph_row
->enabled_p
)
26583 w
->phys_cursor_on_p
= 0;
26588 if (!glyph_row
->exact_window_width_line_p
26589 || (0 <= hpos
&& hpos
< glyph_row
->used
[TEXT_AREA
]))
26590 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
26592 eassert (input_blocked_p ());
26594 /* Set new_cursor_type to the cursor we want to be displayed. */
26595 new_cursor_type
= get_window_cursor_type (w
, glyph
,
26596 &new_cursor_width
, &active_cursor
);
26598 /* If cursor is currently being shown and we don't want it to be or
26599 it is in the wrong place, or the cursor type is not what we want,
26601 if (w
->phys_cursor_on_p
26603 || w
->phys_cursor
.x
!= x
26604 || w
->phys_cursor
.y
!= y
26605 || new_cursor_type
!= w
->phys_cursor_type
26606 || ((new_cursor_type
== BAR_CURSOR
|| new_cursor_type
== HBAR_CURSOR
)
26607 && new_cursor_width
!= w
->phys_cursor_width
)))
26608 erase_phys_cursor (w
);
26610 /* Don't check phys_cursor_on_p here because that flag is only set
26611 to zero in some cases where we know that the cursor has been
26612 completely erased, to avoid the extra work of erasing the cursor
26613 twice. In other words, phys_cursor_on_p can be 1 and the cursor
26614 still not be visible, or it has only been partly erased. */
26617 w
->phys_cursor_ascent
= glyph_row
->ascent
;
26618 w
->phys_cursor_height
= glyph_row
->height
;
26620 /* Set phys_cursor_.* before x_draw_.* is called because some
26621 of them may need the information. */
26622 w
->phys_cursor
.x
= x
;
26623 w
->phys_cursor
.y
= glyph_row
->y
;
26624 w
->phys_cursor
.hpos
= hpos
;
26625 w
->phys_cursor
.vpos
= vpos
;
26628 FRAME_RIF (f
)->draw_window_cursor (w
, glyph_row
, x
, y
,
26629 new_cursor_type
, new_cursor_width
,
26630 on
, active_cursor
);
26634 /* Switch the display of W's cursor on or off, according to the value
26638 update_window_cursor (struct window
*w
, bool on
)
26640 /* Don't update cursor in windows whose frame is in the process
26641 of being deleted. */
26642 if (w
->current_matrix
)
26644 int hpos
= w
->phys_cursor
.hpos
;
26645 int vpos
= w
->phys_cursor
.vpos
;
26646 struct glyph_row
*row
;
26648 if (vpos
>= w
->current_matrix
->nrows
26649 || hpos
>= w
->current_matrix
->matrix_w
)
26652 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
26654 /* When the window is hscrolled, cursor hpos can legitimately be
26655 out of bounds, but we draw the cursor at the corresponding
26656 window margin in that case. */
26657 if (!row
->reversed_p
&& hpos
< 0)
26659 if (row
->reversed_p
&& hpos
>= row
->used
[TEXT_AREA
])
26660 hpos
= row
->used
[TEXT_AREA
] - 1;
26663 display_and_set_cursor (w
, on
, hpos
, vpos
,
26664 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
26670 /* Call update_window_cursor with parameter ON_P on all leaf windows
26671 in the window tree rooted at W. */
26674 update_cursor_in_window_tree (struct window
*w
, bool on_p
)
26678 if (WINDOWP (w
->contents
))
26679 update_cursor_in_window_tree (XWINDOW (w
->contents
), on_p
);
26681 update_window_cursor (w
, on_p
);
26683 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
26689 Display the cursor on window W, or clear it, according to ON_P.
26690 Don't change the cursor's position. */
26693 x_update_cursor (struct frame
*f
, bool on_p
)
26695 update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
26700 Clear the cursor of window W to background color, and mark the
26701 cursor as not shown. This is used when the text where the cursor
26702 is about to be rewritten. */
26705 x_clear_cursor (struct window
*w
)
26707 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
26708 update_window_cursor (w
, 0);
26711 #endif /* HAVE_WINDOW_SYSTEM */
26713 /* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
26716 draw_row_with_mouse_face (struct window
*w
, int start_x
, struct glyph_row
*row
,
26717 int start_hpos
, int end_hpos
,
26718 enum draw_glyphs_face draw
)
26720 #ifdef HAVE_WINDOW_SYSTEM
26721 if (FRAME_WINDOW_P (XFRAME (w
->frame
)))
26723 draw_glyphs (w
, start_x
, row
, TEXT_AREA
, start_hpos
, end_hpos
, draw
, 0);
26727 #if defined (HAVE_GPM) || defined (MSDOS) || defined (WINDOWSNT)
26728 tty_draw_row_with_mouse_face (w
, row
, start_hpos
, end_hpos
, draw
);
26732 /* Display the active region described by mouse_face_* according to DRAW. */
26735 show_mouse_face (Mouse_HLInfo
*hlinfo
, enum draw_glyphs_face draw
)
26737 struct window
*w
= XWINDOW (hlinfo
->mouse_face_window
);
26738 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
26740 if (/* If window is in the process of being destroyed, don't bother
26742 w
->current_matrix
!= NULL
26743 /* Don't update mouse highlight if hidden */
26744 && (draw
!= DRAW_MOUSE_FACE
|| !hlinfo
->mouse_face_hidden
)
26745 /* Recognize when we are called to operate on rows that don't exist
26746 anymore. This can happen when a window is split. */
26747 && hlinfo
->mouse_face_end_row
< w
->current_matrix
->nrows
)
26749 int phys_cursor_on_p
= w
->phys_cursor_on_p
;
26750 struct glyph_row
*row
, *first
, *last
;
26752 first
= MATRIX_ROW (w
->current_matrix
, hlinfo
->mouse_face_beg_row
);
26753 last
= MATRIX_ROW (w
->current_matrix
, hlinfo
->mouse_face_end_row
);
26755 for (row
= first
; row
<= last
&& row
->enabled_p
; ++row
)
26757 int start_hpos
, end_hpos
, start_x
;
26759 /* For all but the first row, the highlight starts at column 0. */
26762 /* R2L rows have BEG and END in reversed order, but the
26763 screen drawing geometry is always left to right. So
26764 we need to mirror the beginning and end of the
26765 highlighted area in R2L rows. */
26766 if (!row
->reversed_p
)
26768 start_hpos
= hlinfo
->mouse_face_beg_col
;
26769 start_x
= hlinfo
->mouse_face_beg_x
;
26771 else if (row
== last
)
26773 start_hpos
= hlinfo
->mouse_face_end_col
;
26774 start_x
= hlinfo
->mouse_face_end_x
;
26782 else if (row
->reversed_p
&& row
== last
)
26784 start_hpos
= hlinfo
->mouse_face_end_col
;
26785 start_x
= hlinfo
->mouse_face_end_x
;
26795 if (!row
->reversed_p
)
26796 end_hpos
= hlinfo
->mouse_face_end_col
;
26797 else if (row
== first
)
26798 end_hpos
= hlinfo
->mouse_face_beg_col
;
26801 end_hpos
= row
->used
[TEXT_AREA
];
26802 if (draw
== DRAW_NORMAL_TEXT
)
26803 row
->fill_line_p
= 1; /* Clear to end of line */
26806 else if (row
->reversed_p
&& row
== first
)
26807 end_hpos
= hlinfo
->mouse_face_beg_col
;
26810 end_hpos
= row
->used
[TEXT_AREA
];
26811 if (draw
== DRAW_NORMAL_TEXT
)
26812 row
->fill_line_p
= 1; /* Clear to end of line */
26815 if (end_hpos
> start_hpos
)
26817 draw_row_with_mouse_face (w
, start_x
, row
,
26818 start_hpos
, end_hpos
, draw
);
26821 = draw
== DRAW_MOUSE_FACE
|| draw
== DRAW_IMAGE_RAISED
;
26825 #ifdef HAVE_WINDOW_SYSTEM
26826 /* When we've written over the cursor, arrange for it to
26827 be displayed again. */
26828 if (FRAME_WINDOW_P (f
)
26829 && phys_cursor_on_p
&& !w
->phys_cursor_on_p
)
26831 int hpos
= w
->phys_cursor
.hpos
;
26833 /* When the window is hscrolled, cursor hpos can legitimately be
26834 out of bounds, but we draw the cursor at the corresponding
26835 window margin in that case. */
26836 if (!row
->reversed_p
&& hpos
< 0)
26838 if (row
->reversed_p
&& hpos
>= row
->used
[TEXT_AREA
])
26839 hpos
= row
->used
[TEXT_AREA
] - 1;
26842 display_and_set_cursor (w
, 1, hpos
, w
->phys_cursor
.vpos
,
26843 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
26846 #endif /* HAVE_WINDOW_SYSTEM */
26849 #ifdef HAVE_WINDOW_SYSTEM
26850 /* Change the mouse cursor. */
26851 if (FRAME_WINDOW_P (f
))
26853 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
26854 if (draw
== DRAW_NORMAL_TEXT
26855 && !EQ (hlinfo
->mouse_face_window
, f
->tool_bar_window
))
26856 FRAME_RIF (f
)->define_frame_cursor (f
, FRAME_X_OUTPUT (f
)->text_cursor
);
26859 if (draw
== DRAW_MOUSE_FACE
)
26860 FRAME_RIF (f
)->define_frame_cursor (f
, FRAME_X_OUTPUT (f
)->hand_cursor
);
26862 FRAME_RIF (f
)->define_frame_cursor (f
, FRAME_X_OUTPUT (f
)->nontext_cursor
);
26864 #endif /* HAVE_WINDOW_SYSTEM */
26868 Clear out the mouse-highlighted active region.
26869 Redraw it un-highlighted first. Value is non-zero if mouse
26870 face was actually drawn unhighlighted. */
26873 clear_mouse_face (Mouse_HLInfo
*hlinfo
)
26877 if (!hlinfo
->mouse_face_hidden
&& !NILP (hlinfo
->mouse_face_window
))
26879 show_mouse_face (hlinfo
, DRAW_NORMAL_TEXT
);
26883 reset_mouse_highlight (hlinfo
);
26887 /* Return non-zero if the coordinates HPOS and VPOS on windows W are
26888 within the mouse face on that window. */
26890 coords_in_mouse_face_p (struct window
*w
, int hpos
, int vpos
)
26892 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (XFRAME (w
->frame
));
26894 /* Quickly resolve the easy cases. */
26895 if (!(WINDOWP (hlinfo
->mouse_face_window
)
26896 && XWINDOW (hlinfo
->mouse_face_window
) == w
))
26898 if (vpos
< hlinfo
->mouse_face_beg_row
26899 || vpos
> hlinfo
->mouse_face_end_row
)
26901 if (vpos
> hlinfo
->mouse_face_beg_row
26902 && vpos
< hlinfo
->mouse_face_end_row
)
26905 if (!MATRIX_ROW (w
->current_matrix
, vpos
)->reversed_p
)
26907 if (hlinfo
->mouse_face_beg_row
== hlinfo
->mouse_face_end_row
)
26909 if (hlinfo
->mouse_face_beg_col
<= hpos
&& hpos
< hlinfo
->mouse_face_end_col
)
26912 else if ((vpos
== hlinfo
->mouse_face_beg_row
26913 && hpos
>= hlinfo
->mouse_face_beg_col
)
26914 || (vpos
== hlinfo
->mouse_face_end_row
26915 && hpos
< hlinfo
->mouse_face_end_col
))
26920 if (hlinfo
->mouse_face_beg_row
== hlinfo
->mouse_face_end_row
)
26922 if (hlinfo
->mouse_face_end_col
< hpos
&& hpos
<= hlinfo
->mouse_face_beg_col
)
26925 else if ((vpos
== hlinfo
->mouse_face_beg_row
26926 && hpos
<= hlinfo
->mouse_face_beg_col
)
26927 || (vpos
== hlinfo
->mouse_face_end_row
26928 && hpos
> hlinfo
->mouse_face_end_col
))
26936 Non-zero if physical cursor of window W is within mouse face. */
26939 cursor_in_mouse_face_p (struct window
*w
)
26941 int hpos
= w
->phys_cursor
.hpos
;
26942 int vpos
= w
->phys_cursor
.vpos
;
26943 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
26945 /* When the window is hscrolled, cursor hpos can legitimately be out
26946 of bounds, but we draw the cursor at the corresponding window
26947 margin in that case. */
26948 if (!row
->reversed_p
&& hpos
< 0)
26950 if (row
->reversed_p
&& hpos
>= row
->used
[TEXT_AREA
])
26951 hpos
= row
->used
[TEXT_AREA
] - 1;
26953 return coords_in_mouse_face_p (w
, hpos
, vpos
);
26958 /* Find the glyph rows START_ROW and END_ROW of window W that display
26959 characters between buffer positions START_CHARPOS and END_CHARPOS
26960 (excluding END_CHARPOS). DISP_STRING is a display string that
26961 covers these buffer positions. This is similar to
26962 row_containing_pos, but is more accurate when bidi reordering makes
26963 buffer positions change non-linearly with glyph rows. */
26965 rows_from_pos_range (struct window
*w
,
26966 ptrdiff_t start_charpos
, ptrdiff_t end_charpos
,
26967 Lisp_Object disp_string
,
26968 struct glyph_row
**start
, struct glyph_row
**end
)
26970 struct glyph_row
*first
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
26971 int last_y
= window_text_bottom_y (w
);
26972 struct glyph_row
*row
;
26977 while (!first
->enabled_p
26978 && first
< MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
))
26981 /* Find the START row. */
26983 row
->enabled_p
&& MATRIX_ROW_BOTTOM_Y (row
) <= last_y
;
26986 /* A row can potentially be the START row if the range of the
26987 characters it displays intersects the range
26988 [START_CHARPOS..END_CHARPOS). */
26989 if (! ((start_charpos
< MATRIX_ROW_START_CHARPOS (row
)
26990 && end_charpos
< MATRIX_ROW_START_CHARPOS (row
))
26991 /* See the commentary in row_containing_pos, for the
26992 explanation of the complicated way to check whether
26993 some position is beyond the end of the characters
26994 displayed by a row. */
26995 || ((start_charpos
> MATRIX_ROW_END_CHARPOS (row
)
26996 || (start_charpos
== MATRIX_ROW_END_CHARPOS (row
)
26997 && !row
->ends_at_zv_p
26998 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
)))
26999 && (end_charpos
> MATRIX_ROW_END_CHARPOS (row
)
27000 || (end_charpos
== MATRIX_ROW_END_CHARPOS (row
)
27001 && !row
->ends_at_zv_p
27002 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
))))))
27004 /* Found a candidate row. Now make sure at least one of the
27005 glyphs it displays has a charpos from the range
27006 [START_CHARPOS..END_CHARPOS).
27008 This is not obvious because bidi reordering could make
27009 buffer positions of a row be 1,2,3,102,101,100, and if we
27010 want to highlight characters in [50..60), we don't want
27011 this row, even though [50..60) does intersect [1..103),
27012 the range of character positions given by the row's start
27013 and end positions. */
27014 struct glyph
*g
= row
->glyphs
[TEXT_AREA
];
27015 struct glyph
*e
= g
+ row
->used
[TEXT_AREA
];
27019 if (((BUFFERP (g
->object
) || INTEGERP (g
->object
))
27020 && start_charpos
<= g
->charpos
&& g
->charpos
< end_charpos
)
27021 /* A glyph that comes from DISP_STRING is by
27022 definition to be highlighted. */
27023 || EQ (g
->object
, disp_string
))
27032 /* Find the END row. */
27034 /* If the last row is partially visible, start looking for END
27035 from that row, instead of starting from FIRST. */
27036 && !(row
->enabled_p
27037 && row
->y
< last_y
&& MATRIX_ROW_BOTTOM_Y (row
) > last_y
))
27039 for ( ; row
->enabled_p
&& MATRIX_ROW_BOTTOM_Y (row
) <= last_y
; row
++)
27041 struct glyph_row
*next
= row
+ 1;
27042 ptrdiff_t next_start
= MATRIX_ROW_START_CHARPOS (next
);
27044 if (!next
->enabled_p
27045 || next
>= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
)
27046 /* The first row >= START whose range of displayed characters
27047 does NOT intersect the range [START_CHARPOS..END_CHARPOS]
27048 is the row END + 1. */
27049 || (start_charpos
< next_start
27050 && end_charpos
< next_start
)
27051 || ((start_charpos
> MATRIX_ROW_END_CHARPOS (next
)
27052 || (start_charpos
== MATRIX_ROW_END_CHARPOS (next
)
27053 && !next
->ends_at_zv_p
27054 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next
)))
27055 && (end_charpos
> MATRIX_ROW_END_CHARPOS (next
)
27056 || (end_charpos
== MATRIX_ROW_END_CHARPOS (next
)
27057 && !next
->ends_at_zv_p
27058 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next
)))))
27065 /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
27066 but none of the characters it displays are in the range, it is
27068 struct glyph
*g
= next
->glyphs
[TEXT_AREA
];
27069 struct glyph
*s
= g
;
27070 struct glyph
*e
= g
+ next
->used
[TEXT_AREA
];
27074 if (((BUFFERP (g
->object
) || INTEGERP (g
->object
))
27075 && ((start_charpos
<= g
->charpos
&& g
->charpos
< end_charpos
)
27076 /* If the buffer position of the first glyph in
27077 the row is equal to END_CHARPOS, it means
27078 the last character to be highlighted is the
27079 newline of ROW, and we must consider NEXT as
27081 || (((!next
->reversed_p
&& g
== s
)
27082 || (next
->reversed_p
&& g
== e
- 1))
27083 && (g
->charpos
== end_charpos
27084 /* Special case for when NEXT is an
27085 empty line at ZV. */
27086 || (g
->charpos
== -1
27087 && !row
->ends_at_zv_p
27088 && next_start
== end_charpos
)))))
27089 /* A glyph that comes from DISP_STRING is by
27090 definition to be highlighted. */
27091 || EQ (g
->object
, disp_string
))
27100 /* The first row that ends at ZV must be the last to be
27102 else if (next
->ends_at_zv_p
)
27111 /* This function sets the mouse_face_* elements of HLINFO, assuming
27112 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
27113 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
27114 for the overlay or run of text properties specifying the mouse
27115 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
27116 before-string and after-string that must also be highlighted.
27117 DISP_STRING, if non-nil, is a display string that may cover some
27118 or all of the highlighted text. */
27121 mouse_face_from_buffer_pos (Lisp_Object window
,
27122 Mouse_HLInfo
*hlinfo
,
27123 ptrdiff_t mouse_charpos
,
27124 ptrdiff_t start_charpos
,
27125 ptrdiff_t end_charpos
,
27126 Lisp_Object before_string
,
27127 Lisp_Object after_string
,
27128 Lisp_Object disp_string
)
27130 struct window
*w
= XWINDOW (window
);
27131 struct glyph_row
*first
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
27132 struct glyph_row
*r1
, *r2
;
27133 struct glyph
*glyph
, *end
;
27134 ptrdiff_t ignore
, pos
;
27137 eassert (NILP (disp_string
) || STRINGP (disp_string
));
27138 eassert (NILP (before_string
) || STRINGP (before_string
));
27139 eassert (NILP (after_string
) || STRINGP (after_string
));
27141 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
27142 rows_from_pos_range (w
, start_charpos
, end_charpos
, disp_string
, &r1
, &r2
);
27144 r1
= MATRIX_ROW (w
->current_matrix
, w
->window_end_vpos
);
27145 /* If the before-string or display-string contains newlines,
27146 rows_from_pos_range skips to its last row. Move back. */
27147 if (!NILP (before_string
) || !NILP (disp_string
))
27149 struct glyph_row
*prev
;
27150 while ((prev
= r1
- 1, prev
>= first
)
27151 && MATRIX_ROW_END_CHARPOS (prev
) == start_charpos
27152 && prev
->used
[TEXT_AREA
] > 0)
27154 struct glyph
*beg
= prev
->glyphs
[TEXT_AREA
];
27155 glyph
= beg
+ prev
->used
[TEXT_AREA
];
27156 while (--glyph
>= beg
&& INTEGERP (glyph
->object
));
27158 || !(EQ (glyph
->object
, before_string
)
27159 || EQ (glyph
->object
, disp_string
)))
27166 r2
= MATRIX_ROW (w
->current_matrix
, w
->window_end_vpos
);
27167 hlinfo
->mouse_face_past_end
= 1;
27169 else if (!NILP (after_string
))
27171 /* If the after-string has newlines, advance to its last row. */
27172 struct glyph_row
*next
;
27173 struct glyph_row
*last
27174 = MATRIX_ROW (w
->current_matrix
, w
->window_end_vpos
);
27176 for (next
= r2
+ 1;
27178 && next
->used
[TEXT_AREA
] > 0
27179 && EQ (next
->glyphs
[TEXT_AREA
]->object
, after_string
);
27183 /* The rest of the display engine assumes that mouse_face_beg_row is
27184 either above mouse_face_end_row or identical to it. But with
27185 bidi-reordered continued lines, the row for START_CHARPOS could
27186 be below the row for END_CHARPOS. If so, swap the rows and store
27187 them in correct order. */
27190 struct glyph_row
*tem
= r2
;
27196 hlinfo
->mouse_face_beg_row
= MATRIX_ROW_VPOS (r1
, w
->current_matrix
);
27197 hlinfo
->mouse_face_end_row
= MATRIX_ROW_VPOS (r2
, w
->current_matrix
);
27199 /* For a bidi-reordered row, the positions of BEFORE_STRING,
27200 AFTER_STRING, DISP_STRING, START_CHARPOS, and END_CHARPOS
27201 could be anywhere in the row and in any order. The strategy
27202 below is to find the leftmost and the rightmost glyph that
27203 belongs to either of these 3 strings, or whose position is
27204 between START_CHARPOS and END_CHARPOS, and highlight all the
27205 glyphs between those two. This may cover more than just the text
27206 between START_CHARPOS and END_CHARPOS if the range of characters
27207 strides the bidi level boundary, e.g. if the beginning is in R2L
27208 text while the end is in L2R text or vice versa. */
27209 if (!r1
->reversed_p
)
27211 /* This row is in a left to right paragraph. Scan it left to
27213 glyph
= r1
->glyphs
[TEXT_AREA
];
27214 end
= glyph
+ r1
->used
[TEXT_AREA
];
27217 /* Skip truncation glyphs at the start of the glyph row. */
27218 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1
))
27220 && INTEGERP (glyph
->object
)
27221 && glyph
->charpos
< 0;
27223 x
+= glyph
->pixel_width
;
27225 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
27226 or DISP_STRING, and the first glyph from buffer whose
27227 position is between START_CHARPOS and END_CHARPOS. */
27229 && !INTEGERP (glyph
->object
)
27230 && !EQ (glyph
->object
, disp_string
)
27231 && !(BUFFERP (glyph
->object
)
27232 && (glyph
->charpos
>= start_charpos
27233 && glyph
->charpos
< end_charpos
));
27236 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27237 are present at buffer positions between START_CHARPOS and
27238 END_CHARPOS, or if they come from an overlay. */
27239 if (EQ (glyph
->object
, before_string
))
27241 pos
= string_buffer_position (before_string
,
27243 /* If pos == 0, it means before_string came from an
27244 overlay, not from a buffer position. */
27245 if (!pos
|| (pos
>= start_charpos
&& pos
< end_charpos
))
27248 else if (EQ (glyph
->object
, after_string
))
27250 pos
= string_buffer_position (after_string
, end_charpos
);
27251 if (!pos
|| (pos
>= start_charpos
&& pos
< end_charpos
))
27254 x
+= glyph
->pixel_width
;
27256 hlinfo
->mouse_face_beg_x
= x
;
27257 hlinfo
->mouse_face_beg_col
= glyph
- r1
->glyphs
[TEXT_AREA
];
27261 /* This row is in a right to left paragraph. Scan it right to
27265 end
= r1
->glyphs
[TEXT_AREA
] - 1;
27266 glyph
= end
+ r1
->used
[TEXT_AREA
];
27268 /* Skip truncation glyphs at the start of the glyph row. */
27269 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1
))
27271 && INTEGERP (glyph
->object
)
27272 && glyph
->charpos
< 0;
27276 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
27277 or DISP_STRING, and the first glyph from buffer whose
27278 position is between START_CHARPOS and END_CHARPOS. */
27280 && !INTEGERP (glyph
->object
)
27281 && !EQ (glyph
->object
, disp_string
)
27282 && !(BUFFERP (glyph
->object
)
27283 && (glyph
->charpos
>= start_charpos
27284 && glyph
->charpos
< end_charpos
));
27287 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27288 are present at buffer positions between START_CHARPOS and
27289 END_CHARPOS, or if they come from an overlay. */
27290 if (EQ (glyph
->object
, before_string
))
27292 pos
= string_buffer_position (before_string
, start_charpos
);
27293 /* If pos == 0, it means before_string came from an
27294 overlay, not from a buffer position. */
27295 if (!pos
|| (pos
>= start_charpos
&& pos
< end_charpos
))
27298 else if (EQ (glyph
->object
, after_string
))
27300 pos
= string_buffer_position (after_string
, end_charpos
);
27301 if (!pos
|| (pos
>= start_charpos
&& pos
< end_charpos
))
27306 glyph
++; /* first glyph to the right of the highlighted area */
27307 for (g
= r1
->glyphs
[TEXT_AREA
], x
= r1
->x
; g
< glyph
; g
++)
27308 x
+= g
->pixel_width
;
27309 hlinfo
->mouse_face_beg_x
= x
;
27310 hlinfo
->mouse_face_beg_col
= glyph
- r1
->glyphs
[TEXT_AREA
];
27313 /* If the highlight ends in a different row, compute GLYPH and END
27314 for the end row. Otherwise, reuse the values computed above for
27315 the row where the highlight begins. */
27318 if (!r2
->reversed_p
)
27320 glyph
= r2
->glyphs
[TEXT_AREA
];
27321 end
= glyph
+ r2
->used
[TEXT_AREA
];
27326 end
= r2
->glyphs
[TEXT_AREA
] - 1;
27327 glyph
= end
+ r2
->used
[TEXT_AREA
];
27331 if (!r2
->reversed_p
)
27333 /* Skip truncation and continuation glyphs near the end of the
27334 row, and also blanks and stretch glyphs inserted by
27335 extend_face_to_end_of_line. */
27337 && INTEGERP ((end
- 1)->object
))
27339 /* Scan the rest of the glyph row from the end, looking for the
27340 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
27341 DISP_STRING, or whose position is between START_CHARPOS
27345 && !INTEGERP (end
->object
)
27346 && !EQ (end
->object
, disp_string
)
27347 && !(BUFFERP (end
->object
)
27348 && (end
->charpos
>= start_charpos
27349 && end
->charpos
< end_charpos
));
27352 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27353 are present at buffer positions between START_CHARPOS and
27354 END_CHARPOS, or if they come from an overlay. */
27355 if (EQ (end
->object
, before_string
))
27357 pos
= string_buffer_position (before_string
, start_charpos
);
27358 if (!pos
|| (pos
>= start_charpos
&& pos
< end_charpos
))
27361 else if (EQ (end
->object
, after_string
))
27363 pos
= string_buffer_position (after_string
, end_charpos
);
27364 if (!pos
|| (pos
>= start_charpos
&& pos
< end_charpos
))
27368 /* Find the X coordinate of the last glyph to be highlighted. */
27369 for (; glyph
<= end
; ++glyph
)
27370 x
+= glyph
->pixel_width
;
27372 hlinfo
->mouse_face_end_x
= x
;
27373 hlinfo
->mouse_face_end_col
= glyph
- r2
->glyphs
[TEXT_AREA
];
27377 /* Skip truncation and continuation glyphs near the end of the
27378 row, and also blanks and stretch glyphs inserted by
27379 extend_face_to_end_of_line. */
27383 && INTEGERP (end
->object
))
27385 x
+= end
->pixel_width
;
27388 /* Scan the rest of the glyph row from the end, looking for the
27389 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
27390 DISP_STRING, or whose position is between START_CHARPOS
27394 && !INTEGERP (end
->object
)
27395 && !EQ (end
->object
, disp_string
)
27396 && !(BUFFERP (end
->object
)
27397 && (end
->charpos
>= start_charpos
27398 && end
->charpos
< end_charpos
));
27401 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27402 are present at buffer positions between START_CHARPOS and
27403 END_CHARPOS, or if they come from an overlay. */
27404 if (EQ (end
->object
, before_string
))
27406 pos
= string_buffer_position (before_string
, start_charpos
);
27407 if (!pos
|| (pos
>= start_charpos
&& pos
< end_charpos
))
27410 else if (EQ (end
->object
, after_string
))
27412 pos
= string_buffer_position (after_string
, end_charpos
);
27413 if (!pos
|| (pos
>= start_charpos
&& pos
< end_charpos
))
27416 x
+= end
->pixel_width
;
27418 /* If we exited the above loop because we arrived at the last
27419 glyph of the row, and its buffer position is still not in
27420 range, it means the last character in range is the preceding
27421 newline. Bump the end column and x values to get past the
27424 && BUFFERP (end
->object
)
27425 && (end
->charpos
< start_charpos
27426 || end
->charpos
>= end_charpos
))
27428 x
+= end
->pixel_width
;
27431 hlinfo
->mouse_face_end_x
= x
;
27432 hlinfo
->mouse_face_end_col
= end
- r2
->glyphs
[TEXT_AREA
];
27435 hlinfo
->mouse_face_window
= window
;
27436 hlinfo
->mouse_face_face_id
27437 = face_at_buffer_position (w
, mouse_charpos
, &ignore
,
27439 !hlinfo
->mouse_face_hidden
, -1);
27440 show_mouse_face (hlinfo
, DRAW_MOUSE_FACE
);
27443 /* The following function is not used anymore (replaced with
27444 mouse_face_from_string_pos), but I leave it here for the time
27445 being, in case someone would. */
27447 #if 0 /* not used */
27449 /* Find the position of the glyph for position POS in OBJECT in
27450 window W's current matrix, and return in *X, *Y the pixel
27451 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
27453 RIGHT_P non-zero means return the position of the right edge of the
27454 glyph, RIGHT_P zero means return the left edge position.
27456 If no glyph for POS exists in the matrix, return the position of
27457 the glyph with the next smaller position that is in the matrix, if
27458 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
27459 exists in the matrix, return the position of the glyph with the
27460 next larger position in OBJECT.
27462 Value is non-zero if a glyph was found. */
27465 fast_find_string_pos (struct window
*w
, ptrdiff_t pos
, Lisp_Object object
,
27466 int *hpos
, int *vpos
, int *x
, int *y
, int right_p
)
27468 int yb
= window_text_bottom_y (w
);
27469 struct glyph_row
*r
;
27470 struct glyph
*best_glyph
= NULL
;
27471 struct glyph_row
*best_row
= NULL
;
27474 for (r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
27475 r
->enabled_p
&& r
->y
< yb
;
27478 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
27479 struct glyph
*e
= g
+ r
->used
[TEXT_AREA
];
27482 for (gx
= r
->x
; g
< e
; gx
+= g
->pixel_width
, ++g
)
27483 if (EQ (g
->object
, object
))
27485 if (g
->charpos
== pos
)
27492 else if (best_glyph
== NULL
27493 || ((eabs (g
->charpos
- pos
)
27494 < eabs (best_glyph
->charpos
- pos
))
27497 : g
->charpos
> pos
)))
27511 *hpos
= best_glyph
- best_row
->glyphs
[TEXT_AREA
];
27515 *x
+= best_glyph
->pixel_width
;
27520 *vpos
= MATRIX_ROW_VPOS (best_row
, w
->current_matrix
);
27523 return best_glyph
!= NULL
;
27525 #endif /* not used */
27527 /* Find the positions of the first and the last glyphs in window W's
27528 current matrix that occlude positions [STARTPOS..ENDPOS) in OBJECT
27529 (assumed to be a string), and return in HLINFO's mouse_face_*
27530 members the pixel and column/row coordinates of those glyphs. */
27533 mouse_face_from_string_pos (struct window
*w
, Mouse_HLInfo
*hlinfo
,
27534 Lisp_Object object
,
27535 ptrdiff_t startpos
, ptrdiff_t endpos
)
27537 int yb
= window_text_bottom_y (w
);
27538 struct glyph_row
*r
;
27539 struct glyph
*g
, *e
;
27543 /* Find the glyph row with at least one position in the range
27544 [STARTPOS..ENDPOS), and the first glyph in that row whose
27545 position belongs to that range. */
27546 for (r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
27547 r
->enabled_p
&& r
->y
< yb
;
27550 if (!r
->reversed_p
)
27552 g
= r
->glyphs
[TEXT_AREA
];
27553 e
= g
+ r
->used
[TEXT_AREA
];
27554 for (gx
= r
->x
; g
< e
; gx
+= g
->pixel_width
, ++g
)
27555 if (EQ (g
->object
, object
)
27556 && startpos
<= g
->charpos
&& g
->charpos
< endpos
)
27558 hlinfo
->mouse_face_beg_row
27559 = MATRIX_ROW_VPOS (r
, w
->current_matrix
);
27560 hlinfo
->mouse_face_beg_col
= g
- r
->glyphs
[TEXT_AREA
];
27561 hlinfo
->mouse_face_beg_x
= gx
;
27570 e
= r
->glyphs
[TEXT_AREA
];
27571 g
= e
+ r
->used
[TEXT_AREA
];
27572 for ( ; g
> e
; --g
)
27573 if (EQ ((g
-1)->object
, object
)
27574 && startpos
<= (g
-1)->charpos
&& (g
-1)->charpos
< endpos
)
27576 hlinfo
->mouse_face_beg_row
27577 = MATRIX_ROW_VPOS (r
, w
->current_matrix
);
27578 hlinfo
->mouse_face_beg_col
= g
- r
->glyphs
[TEXT_AREA
];
27579 for (gx
= r
->x
, g1
= r
->glyphs
[TEXT_AREA
]; g1
< g
; ++g1
)
27580 gx
+= g1
->pixel_width
;
27581 hlinfo
->mouse_face_beg_x
= gx
;
27593 /* Starting with the next row, look for the first row which does NOT
27594 include any glyphs whose positions are in the range. */
27595 for (++r
; r
->enabled_p
&& r
->y
< yb
; ++r
)
27597 g
= r
->glyphs
[TEXT_AREA
];
27598 e
= g
+ r
->used
[TEXT_AREA
];
27600 for ( ; g
< e
; ++g
)
27601 if (EQ (g
->object
, object
)
27602 && startpos
<= g
->charpos
&& g
->charpos
< endpos
)
27611 /* The highlighted region ends on the previous row. */
27614 /* Set the end row. */
27615 hlinfo
->mouse_face_end_row
= MATRIX_ROW_VPOS (r
, w
->current_matrix
);
27617 /* Compute and set the end column and the end column's horizontal
27618 pixel coordinate. */
27619 if (!r
->reversed_p
)
27621 g
= r
->glyphs
[TEXT_AREA
];
27622 e
= g
+ r
->used
[TEXT_AREA
];
27623 for ( ; e
> g
; --e
)
27624 if (EQ ((e
-1)->object
, object
)
27625 && startpos
<= (e
-1)->charpos
&& (e
-1)->charpos
< endpos
)
27627 hlinfo
->mouse_face_end_col
= e
- g
;
27629 for (gx
= r
->x
; g
< e
; ++g
)
27630 gx
+= g
->pixel_width
;
27631 hlinfo
->mouse_face_end_x
= gx
;
27635 e
= r
->glyphs
[TEXT_AREA
];
27636 g
= e
+ r
->used
[TEXT_AREA
];
27637 for (gx
= r
->x
; e
< g
; ++e
)
27639 if (EQ (e
->object
, object
)
27640 && startpos
<= e
->charpos
&& e
->charpos
< endpos
)
27642 gx
+= e
->pixel_width
;
27644 hlinfo
->mouse_face_end_col
= e
- r
->glyphs
[TEXT_AREA
];
27645 hlinfo
->mouse_face_end_x
= gx
;
27649 #ifdef HAVE_WINDOW_SYSTEM
27651 /* See if position X, Y is within a hot-spot of an image. */
27654 on_hot_spot_p (Lisp_Object hot_spot
, int x
, int y
)
27656 if (!CONSP (hot_spot
))
27659 if (EQ (XCAR (hot_spot
), Qrect
))
27661 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
27662 Lisp_Object rect
= XCDR (hot_spot
);
27666 if (!CONSP (XCAR (rect
)))
27668 if (!CONSP (XCDR (rect
)))
27670 if (!(tem
= XCAR (XCAR (rect
)), INTEGERP (tem
) && x
>= XINT (tem
)))
27672 if (!(tem
= XCDR (XCAR (rect
)), INTEGERP (tem
) && y
>= XINT (tem
)))
27674 if (!(tem
= XCAR (XCDR (rect
)), INTEGERP (tem
) && x
<= XINT (tem
)))
27676 if (!(tem
= XCDR (XCDR (rect
)), INTEGERP (tem
) && y
<= XINT (tem
)))
27680 else if (EQ (XCAR (hot_spot
), Qcircle
))
27682 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
27683 Lisp_Object circ
= XCDR (hot_spot
);
27684 Lisp_Object lr
, lx0
, ly0
;
27686 && CONSP (XCAR (circ
))
27687 && (lr
= XCDR (circ
), INTEGERP (lr
) || FLOATP (lr
))
27688 && (lx0
= XCAR (XCAR (circ
)), INTEGERP (lx0
))
27689 && (ly0
= XCDR (XCAR (circ
)), INTEGERP (ly0
)))
27691 double r
= XFLOATINT (lr
);
27692 double dx
= XINT (lx0
) - x
;
27693 double dy
= XINT (ly0
) - y
;
27694 return (dx
* dx
+ dy
* dy
<= r
* r
);
27697 else if (EQ (XCAR (hot_spot
), Qpoly
))
27699 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
27700 if (VECTORP (XCDR (hot_spot
)))
27702 struct Lisp_Vector
*v
= XVECTOR (XCDR (hot_spot
));
27703 Lisp_Object
*poly
= v
->contents
;
27704 ptrdiff_t n
= v
->header
.size
;
27707 Lisp_Object lx
, ly
;
27710 /* Need an even number of coordinates, and at least 3 edges. */
27711 if (n
< 6 || n
& 1)
27714 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
27715 If count is odd, we are inside polygon. Pixels on edges
27716 may or may not be included depending on actual geometry of the
27718 if ((lx
= poly
[n
-2], !INTEGERP (lx
))
27719 || (ly
= poly
[n
-1], !INTEGERP (lx
)))
27721 x0
= XINT (lx
), y0
= XINT (ly
);
27722 for (i
= 0; i
< n
; i
+= 2)
27724 int x1
= x0
, y1
= y0
;
27725 if ((lx
= poly
[i
], !INTEGERP (lx
))
27726 || (ly
= poly
[i
+1], !INTEGERP (ly
)))
27728 x0
= XINT (lx
), y0
= XINT (ly
);
27730 /* Does this segment cross the X line? */
27738 if (y
> y0
&& y
> y1
)
27740 if (y
< y0
+ ((y1
- y0
) * (x
- x0
)) / (x1
- x0
))
27750 find_hot_spot (Lisp_Object map
, int x
, int y
)
27752 while (CONSP (map
))
27754 if (CONSP (XCAR (map
))
27755 && on_hot_spot_p (XCAR (XCAR (map
)), x
, y
))
27763 DEFUN ("lookup-image-map", Flookup_image_map
, Slookup_image_map
,
27765 doc
: /* Lookup in image map MAP coordinates X and Y.
27766 An image map is an alist where each element has the format (AREA ID PLIST).
27767 An AREA is specified as either a rectangle, a circle, or a polygon:
27768 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
27769 pixel coordinates of the upper left and bottom right corners.
27770 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
27771 and the radius of the circle; r may be a float or integer.
27772 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
27773 vector describes one corner in the polygon.
27774 Returns the alist element for the first matching AREA in MAP. */)
27775 (Lisp_Object map
, Lisp_Object x
, Lisp_Object y
)
27783 return find_hot_spot (map
,
27784 clip_to_bounds (INT_MIN
, XINT (x
), INT_MAX
),
27785 clip_to_bounds (INT_MIN
, XINT (y
), INT_MAX
));
27789 /* Display frame CURSOR, optionally using shape defined by POINTER. */
27791 define_frame_cursor1 (struct frame
*f
, Cursor cursor
, Lisp_Object pointer
)
27793 /* Do not change cursor shape while dragging mouse. */
27794 if (!NILP (do_mouse_tracking
))
27797 if (!NILP (pointer
))
27799 if (EQ (pointer
, Qarrow
))
27800 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
27801 else if (EQ (pointer
, Qhand
))
27802 cursor
= FRAME_X_OUTPUT (f
)->hand_cursor
;
27803 else if (EQ (pointer
, Qtext
))
27804 cursor
= FRAME_X_OUTPUT (f
)->text_cursor
;
27805 else if (EQ (pointer
, intern ("hdrag")))
27806 cursor
= FRAME_X_OUTPUT (f
)->horizontal_drag_cursor
;
27807 #ifdef HAVE_X_WINDOWS
27808 else if (EQ (pointer
, intern ("vdrag")))
27809 cursor
= FRAME_DISPLAY_INFO (f
)->vertical_scroll_bar_cursor
;
27811 else if (EQ (pointer
, intern ("hourglass")))
27812 cursor
= FRAME_X_OUTPUT (f
)->hourglass_cursor
;
27813 else if (EQ (pointer
, Qmodeline
))
27814 cursor
= FRAME_X_OUTPUT (f
)->modeline_cursor
;
27816 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
27819 if (cursor
!= No_Cursor
)
27820 FRAME_RIF (f
)->define_frame_cursor (f
, cursor
);
27823 #endif /* HAVE_WINDOW_SYSTEM */
27825 /* Take proper action when mouse has moved to the mode or header line
27826 or marginal area AREA of window W, x-position X and y-position Y.
27827 X is relative to the start of the text display area of W, so the
27828 width of bitmap areas and scroll bars must be subtracted to get a
27829 position relative to the start of the mode line. */
27832 note_mode_line_or_margin_highlight (Lisp_Object window
, int x
, int y
,
27833 enum window_part area
)
27835 struct window
*w
= XWINDOW (window
);
27836 struct frame
*f
= XFRAME (w
->frame
);
27837 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
27838 #ifdef HAVE_WINDOW_SYSTEM
27839 Display_Info
*dpyinfo
;
27841 Cursor cursor
= No_Cursor
;
27842 Lisp_Object pointer
= Qnil
;
27843 int dx
, dy
, width
, height
;
27845 Lisp_Object string
, object
= Qnil
;
27846 Lisp_Object pos
IF_LINT (= Qnil
), help
;
27848 Lisp_Object mouse_face
;
27849 int original_x_pixel
= x
;
27850 struct glyph
* glyph
= NULL
, * row_start_glyph
= NULL
;
27851 struct glyph_row
*row
IF_LINT (= 0);
27853 if (area
== ON_MODE_LINE
|| area
== ON_HEADER_LINE
)
27858 /* Kludge alert: mode_line_string takes X/Y in pixels, but
27859 returns them in row/column units! */
27860 string
= mode_line_string (w
, area
, &x
, &y
, &charpos
,
27861 &object
, &dx
, &dy
, &width
, &height
);
27863 row
= (area
== ON_MODE_LINE
27864 ? MATRIX_MODE_LINE_ROW (w
->current_matrix
)
27865 : MATRIX_HEADER_LINE_ROW (w
->current_matrix
));
27867 /* Find the glyph under the mouse pointer. */
27868 if (row
->mode_line_p
&& row
->enabled_p
)
27870 glyph
= row_start_glyph
= row
->glyphs
[TEXT_AREA
];
27871 end
= glyph
+ row
->used
[TEXT_AREA
];
27873 for (x0
= original_x_pixel
;
27874 glyph
< end
&& x0
>= glyph
->pixel_width
;
27876 x0
-= glyph
->pixel_width
;
27884 x
-= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w
);
27885 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
27886 returns them in row/column units! */
27887 string
= marginal_area_string (w
, area
, &x
, &y
, &charpos
,
27888 &object
, &dx
, &dy
, &width
, &height
);
27893 #ifdef HAVE_WINDOW_SYSTEM
27894 if (IMAGEP (object
))
27896 Lisp_Object image_map
, hotspot
;
27897 if ((image_map
= Fplist_get (XCDR (object
), QCmap
),
27899 && (hotspot
= find_hot_spot (image_map
, dx
, dy
),
27901 && (hotspot
= XCDR (hotspot
), CONSP (hotspot
)))
27905 /* Could check XCAR (hotspot) to see if we enter/leave this hot-spot.
27906 If so, we could look for mouse-enter, mouse-leave
27907 properties in PLIST (and do something...). */
27908 hotspot
= XCDR (hotspot
);
27909 if (CONSP (hotspot
)
27910 && (plist
= XCAR (hotspot
), CONSP (plist
)))
27912 pointer
= Fplist_get (plist
, Qpointer
);
27913 if (NILP (pointer
))
27915 help
= Fplist_get (plist
, Qhelp_echo
);
27918 help_echo_string
= help
;
27919 XSETWINDOW (help_echo_window
, w
);
27920 help_echo_object
= w
->contents
;
27921 help_echo_pos
= charpos
;
27925 if (NILP (pointer
))
27926 pointer
= Fplist_get (XCDR (object
), QCpointer
);
27928 #endif /* HAVE_WINDOW_SYSTEM */
27930 if (STRINGP (string
))
27931 pos
= make_number (charpos
);
27933 /* Set the help text and mouse pointer. If the mouse is on a part
27934 of the mode line without any text (e.g. past the right edge of
27935 the mode line text), use the default help text and pointer. */
27936 if (STRINGP (string
) || area
== ON_MODE_LINE
)
27938 /* Arrange to display the help by setting the global variables
27939 help_echo_string, help_echo_object, and help_echo_pos. */
27942 if (STRINGP (string
))
27943 help
= Fget_text_property (pos
, Qhelp_echo
, string
);
27947 help_echo_string
= help
;
27948 XSETWINDOW (help_echo_window
, w
);
27949 help_echo_object
= string
;
27950 help_echo_pos
= charpos
;
27952 else if (area
== ON_MODE_LINE
)
27954 Lisp_Object default_help
27955 = buffer_local_value_1 (Qmode_line_default_help_echo
,
27958 if (STRINGP (default_help
))
27960 help_echo_string
= default_help
;
27961 XSETWINDOW (help_echo_window
, w
);
27962 help_echo_object
= Qnil
;
27963 help_echo_pos
= -1;
27968 #ifdef HAVE_WINDOW_SYSTEM
27969 /* Change the mouse pointer according to what is under it. */
27970 if (FRAME_WINDOW_P (f
))
27972 dpyinfo
= FRAME_DISPLAY_INFO (f
);
27973 if (STRINGP (string
))
27975 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
27977 if (NILP (pointer
))
27978 pointer
= Fget_text_property (pos
, Qpointer
, string
);
27980 /* Change the mouse pointer according to what is under X/Y. */
27982 && ((area
== ON_MODE_LINE
) || (area
== ON_HEADER_LINE
)))
27985 map
= Fget_text_property (pos
, Qlocal_map
, string
);
27986 if (!KEYMAPP (map
))
27987 map
= Fget_text_property (pos
, Qkeymap
, string
);
27988 if (!KEYMAPP (map
))
27989 cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
27993 /* Default mode-line pointer. */
27994 cursor
= FRAME_DISPLAY_INFO (f
)->vertical_scroll_bar_cursor
;
27999 /* Change the mouse face according to what is under X/Y. */
28000 if (STRINGP (string
))
28002 mouse_face
= Fget_text_property (pos
, Qmouse_face
, string
);
28003 if (!NILP (Vmouse_highlight
) && !NILP (mouse_face
)
28004 && ((area
== ON_MODE_LINE
) || (area
== ON_HEADER_LINE
))
28009 struct glyph
* tmp_glyph
;
28013 int total_pixel_width
;
28014 ptrdiff_t begpos
, endpos
, ignore
;
28018 b
= Fprevious_single_property_change (make_number (charpos
+ 1),
28019 Qmouse_face
, string
, Qnil
);
28025 e
= Fnext_single_property_change (pos
, Qmouse_face
, string
, Qnil
);
28027 endpos
= SCHARS (string
);
28031 /* Calculate the glyph position GPOS of GLYPH in the
28032 displayed string, relative to the beginning of the
28033 highlighted part of the string.
28035 Note: GPOS is different from CHARPOS. CHARPOS is the
28036 position of GLYPH in the internal string object. A mode
28037 line string format has structures which are converted to
28038 a flattened string by the Emacs Lisp interpreter. The
28039 internal string is an element of those structures. The
28040 displayed string is the flattened string. */
28041 tmp_glyph
= row_start_glyph
;
28042 while (tmp_glyph
< glyph
28043 && (!(EQ (tmp_glyph
->object
, glyph
->object
)
28044 && begpos
<= tmp_glyph
->charpos
28045 && tmp_glyph
->charpos
< endpos
)))
28047 gpos
= glyph
- tmp_glyph
;
28049 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
28050 the highlighted part of the displayed string to which
28051 GLYPH belongs. Note: GSEQ_LENGTH is different from
28052 SCHARS (STRING), because the latter returns the length of
28053 the internal string. */
28054 for (tmp_glyph
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
] - 1;
28056 && (!(EQ (tmp_glyph
->object
, glyph
->object
)
28057 && begpos
<= tmp_glyph
->charpos
28058 && tmp_glyph
->charpos
< endpos
));
28061 gseq_length
= gpos
+ (tmp_glyph
- glyph
) + 1;
28063 /* Calculate the total pixel width of all the glyphs between
28064 the beginning of the highlighted area and GLYPH. */
28065 total_pixel_width
= 0;
28066 for (tmp_glyph
= glyph
- gpos
; tmp_glyph
!= glyph
; tmp_glyph
++)
28067 total_pixel_width
+= tmp_glyph
->pixel_width
;
28069 /* Pre calculation of re-rendering position. Note: X is in
28070 column units here, after the call to mode_line_string or
28071 marginal_area_string. */
28073 vpos
= (area
== ON_MODE_LINE
28074 ? (w
->current_matrix
)->nrows
- 1
28077 /* If GLYPH's position is included in the region that is
28078 already drawn in mouse face, we have nothing to do. */
28079 if ( EQ (window
, hlinfo
->mouse_face_window
)
28080 && (!row
->reversed_p
28081 ? (hlinfo
->mouse_face_beg_col
<= hpos
28082 && hpos
< hlinfo
->mouse_face_end_col
)
28083 /* In R2L rows we swap BEG and END, see below. */
28084 : (hlinfo
->mouse_face_end_col
<= hpos
28085 && hpos
< hlinfo
->mouse_face_beg_col
))
28086 && hlinfo
->mouse_face_beg_row
== vpos
)
28089 if (clear_mouse_face (hlinfo
))
28090 cursor
= No_Cursor
;
28092 if (!row
->reversed_p
)
28094 hlinfo
->mouse_face_beg_col
= hpos
;
28095 hlinfo
->mouse_face_beg_x
= original_x_pixel
28096 - (total_pixel_width
+ dx
);
28097 hlinfo
->mouse_face_end_col
= hpos
+ gseq_length
;
28098 hlinfo
->mouse_face_end_x
= 0;
28102 /* In R2L rows, show_mouse_face expects BEG and END
28103 coordinates to be swapped. */
28104 hlinfo
->mouse_face_end_col
= hpos
;
28105 hlinfo
->mouse_face_end_x
= original_x_pixel
28106 - (total_pixel_width
+ dx
);
28107 hlinfo
->mouse_face_beg_col
= hpos
+ gseq_length
;
28108 hlinfo
->mouse_face_beg_x
= 0;
28111 hlinfo
->mouse_face_beg_row
= vpos
;
28112 hlinfo
->mouse_face_end_row
= hlinfo
->mouse_face_beg_row
;
28113 hlinfo
->mouse_face_past_end
= 0;
28114 hlinfo
->mouse_face_window
= window
;
28116 hlinfo
->mouse_face_face_id
= face_at_string_position (w
, string
,
28121 show_mouse_face (hlinfo
, DRAW_MOUSE_FACE
);
28123 if (NILP (pointer
))
28126 else if ((area
== ON_MODE_LINE
) || (area
== ON_HEADER_LINE
))
28127 clear_mouse_face (hlinfo
);
28129 #ifdef HAVE_WINDOW_SYSTEM
28130 if (FRAME_WINDOW_P (f
))
28131 define_frame_cursor1 (f
, cursor
, pointer
);
28137 Take proper action when the mouse has moved to position X, Y on
28138 frame F with regards to highlighting portions of display that have
28139 mouse-face properties. Also de-highlight portions of display where
28140 the mouse was before, set the mouse pointer shape as appropriate
28141 for the mouse coordinates, and activate help echo (tooltips).
28142 X and Y can be negative or out of range. */
28145 note_mouse_highlight (struct frame
*f
, int x
, int y
)
28147 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
28148 enum window_part part
= ON_NOTHING
;
28149 Lisp_Object window
;
28151 Cursor cursor
= No_Cursor
;
28152 Lisp_Object pointer
= Qnil
; /* Takes precedence over cursor! */
28155 /* When a menu is active, don't highlight because this looks odd. */
28156 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
28157 if (popup_activated ())
28161 if (!f
->glyphs_initialized_p
28162 || f
->pointer_invisible
)
28165 hlinfo
->mouse_face_mouse_x
= x
;
28166 hlinfo
->mouse_face_mouse_y
= y
;
28167 hlinfo
->mouse_face_mouse_frame
= f
;
28169 if (hlinfo
->mouse_face_defer
)
28172 /* Which window is that in? */
28173 window
= window_from_coordinates (f
, x
, y
, &part
, 1);
28175 /* If displaying active text in another window, clear that. */
28176 if (! EQ (window
, hlinfo
->mouse_face_window
)
28177 /* Also clear if we move out of text area in same window. */
28178 || (!NILP (hlinfo
->mouse_face_window
)
28181 && part
!= ON_MODE_LINE
28182 && part
!= ON_HEADER_LINE
))
28183 clear_mouse_face (hlinfo
);
28185 /* Not on a window -> return. */
28186 if (!WINDOWP (window
))
28189 /* Reset help_echo_string. It will get recomputed below. */
28190 help_echo_string
= Qnil
;
28192 /* Convert to window-relative pixel coordinates. */
28193 w
= XWINDOW (window
);
28194 frame_to_window_pixel_xy (w
, &x
, &y
);
28196 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
28197 /* Handle tool-bar window differently since it doesn't display a
28199 if (EQ (window
, f
->tool_bar_window
))
28201 note_tool_bar_highlight (f
, x
, y
);
28206 /* Mouse is on the mode, header line or margin? */
28207 if (part
== ON_MODE_LINE
|| part
== ON_HEADER_LINE
28208 || part
== ON_LEFT_MARGIN
|| part
== ON_RIGHT_MARGIN
)
28210 note_mode_line_or_margin_highlight (window
, x
, y
, part
);
28214 #ifdef HAVE_WINDOW_SYSTEM
28215 if (part
== ON_VERTICAL_BORDER
)
28217 cursor
= FRAME_X_OUTPUT (f
)->horizontal_drag_cursor
;
28218 help_echo_string
= build_string ("drag-mouse-1: resize");
28220 else if (part
== ON_LEFT_FRINGE
|| part
== ON_RIGHT_FRINGE
28221 || part
== ON_SCROLL_BAR
)
28222 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
28224 cursor
= FRAME_X_OUTPUT (f
)->text_cursor
;
28227 /* Are we in a window whose display is up to date?
28228 And verify the buffer's text has not changed. */
28229 b
= XBUFFER (w
->contents
);
28230 if (part
== ON_TEXT
&& w
->window_end_valid
&& !window_outdated (w
))
28232 int hpos
, vpos
, dx
, dy
, area
= LAST_AREA
;
28234 struct glyph
*glyph
;
28235 Lisp_Object object
;
28236 Lisp_Object mouse_face
= Qnil
, position
;
28237 Lisp_Object
*overlay_vec
= NULL
;
28238 ptrdiff_t i
, noverlays
;
28239 struct buffer
*obuf
;
28240 ptrdiff_t obegv
, ozv
;
28243 /* Find the glyph under X/Y. */
28244 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &dx
, &dy
, &area
);
28246 #ifdef HAVE_WINDOW_SYSTEM
28247 /* Look for :pointer property on image. */
28248 if (glyph
!= NULL
&& glyph
->type
== IMAGE_GLYPH
)
28250 struct image
*img
= IMAGE_FROM_ID (f
, glyph
->u
.img_id
);
28251 if (img
!= NULL
&& IMAGEP (img
->spec
))
28253 Lisp_Object image_map
, hotspot
;
28254 if ((image_map
= Fplist_get (XCDR (img
->spec
), QCmap
),
28256 && (hotspot
= find_hot_spot (image_map
,
28257 glyph
->slice
.img
.x
+ dx
,
28258 glyph
->slice
.img
.y
+ dy
),
28260 && (hotspot
= XCDR (hotspot
), CONSP (hotspot
)))
28264 /* Could check XCAR (hotspot) to see if we enter/leave
28266 If so, we could look for mouse-enter, mouse-leave
28267 properties in PLIST (and do something...). */
28268 hotspot
= XCDR (hotspot
);
28269 if (CONSP (hotspot
)
28270 && (plist
= XCAR (hotspot
), CONSP (plist
)))
28272 pointer
= Fplist_get (plist
, Qpointer
);
28273 if (NILP (pointer
))
28275 help_echo_string
= Fplist_get (plist
, Qhelp_echo
);
28276 if (!NILP (help_echo_string
))
28278 help_echo_window
= window
;
28279 help_echo_object
= glyph
->object
;
28280 help_echo_pos
= glyph
->charpos
;
28284 if (NILP (pointer
))
28285 pointer
= Fplist_get (XCDR (img
->spec
), QCpointer
);
28288 #endif /* HAVE_WINDOW_SYSTEM */
28290 /* Clear mouse face if X/Y not over text. */
28292 || area
!= TEXT_AREA
28293 || !MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w
->current_matrix
, vpos
))
28294 /* Glyph's OBJECT is an integer for glyphs inserted by the
28295 display engine for its internal purposes, like truncation
28296 and continuation glyphs and blanks beyond the end of
28297 line's text on text terminals. If we are over such a
28298 glyph, we are not over any text. */
28299 || INTEGERP (glyph
->object
)
28300 /* R2L rows have a stretch glyph at their front, which
28301 stands for no text, whereas L2R rows have no glyphs at
28302 all beyond the end of text. Treat such stretch glyphs
28303 like we do with NULL glyphs in L2R rows. */
28304 || (MATRIX_ROW (w
->current_matrix
, vpos
)->reversed_p
28305 && glyph
== MATRIX_ROW_GLYPH_START (w
->current_matrix
, vpos
)
28306 && glyph
->type
== STRETCH_GLYPH
28307 && glyph
->avoid_cursor_p
))
28309 if (clear_mouse_face (hlinfo
))
28310 cursor
= No_Cursor
;
28311 #ifdef HAVE_WINDOW_SYSTEM
28312 if (FRAME_WINDOW_P (f
) && NILP (pointer
))
28314 if (area
!= TEXT_AREA
)
28315 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
28317 pointer
= Vvoid_text_area_pointer
;
28323 pos
= glyph
->charpos
;
28324 object
= glyph
->object
;
28325 if (!STRINGP (object
) && !BUFFERP (object
))
28328 /* If we get an out-of-range value, return now; avoid an error. */
28329 if (BUFFERP (object
) && pos
> BUF_Z (b
))
28332 /* Make the window's buffer temporarily current for
28333 overlays_at and compute_char_face. */
28334 obuf
= current_buffer
;
28335 current_buffer
= b
;
28341 /* Is this char mouse-active or does it have help-echo? */
28342 position
= make_number (pos
);
28344 if (BUFFERP (object
))
28346 /* Put all the overlays we want in a vector in overlay_vec. */
28347 GET_OVERLAYS_AT (pos
, overlay_vec
, noverlays
, NULL
, 0);
28348 /* Sort overlays into increasing priority order. */
28349 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
28354 if (NILP (Vmouse_highlight
))
28356 clear_mouse_face (hlinfo
);
28357 goto check_help_echo
;
28360 same_region
= coords_in_mouse_face_p (w
, hpos
, vpos
);
28363 cursor
= No_Cursor
;
28365 /* Check mouse-face highlighting. */
28367 /* If there exists an overlay with mouse-face overlapping
28368 the one we are currently highlighting, we have to
28369 check if we enter the overlapping overlay, and then
28370 highlight only that. */
28371 || (OVERLAYP (hlinfo
->mouse_face_overlay
)
28372 && mouse_face_overlay_overlaps (hlinfo
->mouse_face_overlay
)))
28374 /* Find the highest priority overlay with a mouse-face. */
28375 Lisp_Object overlay
= Qnil
;
28376 for (i
= noverlays
- 1; i
>= 0 && NILP (overlay
); --i
)
28378 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
28379 if (!NILP (mouse_face
))
28380 overlay
= overlay_vec
[i
];
28383 /* If we're highlighting the same overlay as before, there's
28384 no need to do that again. */
28385 if (!NILP (overlay
) && EQ (overlay
, hlinfo
->mouse_face_overlay
))
28386 goto check_help_echo
;
28387 hlinfo
->mouse_face_overlay
= overlay
;
28389 /* Clear the display of the old active region, if any. */
28390 if (clear_mouse_face (hlinfo
))
28391 cursor
= No_Cursor
;
28393 /* If no overlay applies, get a text property. */
28394 if (NILP (overlay
))
28395 mouse_face
= Fget_text_property (position
, Qmouse_face
, object
);
28397 /* Next, compute the bounds of the mouse highlighting and
28399 if (!NILP (mouse_face
) && STRINGP (object
))
28401 /* The mouse-highlighting comes from a display string
28402 with a mouse-face. */
28406 s
= Fprevious_single_property_change
28407 (make_number (pos
+ 1), Qmouse_face
, object
, Qnil
);
28408 e
= Fnext_single_property_change
28409 (position
, Qmouse_face
, object
, Qnil
);
28411 s
= make_number (0);
28413 e
= make_number (SCHARS (object
));
28414 mouse_face_from_string_pos (w
, hlinfo
, object
,
28415 XINT (s
), XINT (e
));
28416 hlinfo
->mouse_face_past_end
= 0;
28417 hlinfo
->mouse_face_window
= window
;
28418 hlinfo
->mouse_face_face_id
28419 = face_at_string_position (w
, object
, pos
, 0, &ignore
,
28420 glyph
->face_id
, 1);
28421 show_mouse_face (hlinfo
, DRAW_MOUSE_FACE
);
28422 cursor
= No_Cursor
;
28426 /* The mouse-highlighting, if any, comes from an overlay
28427 or text property in the buffer. */
28428 Lisp_Object buffer
IF_LINT (= Qnil
);
28429 Lisp_Object disp_string
IF_LINT (= Qnil
);
28431 if (STRINGP (object
))
28433 /* If we are on a display string with no mouse-face,
28434 check if the text under it has one. */
28435 struct glyph_row
*r
= MATRIX_ROW (w
->current_matrix
, vpos
);
28436 ptrdiff_t start
= MATRIX_ROW_START_CHARPOS (r
);
28437 pos
= string_buffer_position (object
, start
);
28440 mouse_face
= get_char_property_and_overlay
28441 (make_number (pos
), Qmouse_face
, w
->contents
, &overlay
);
28442 buffer
= w
->contents
;
28443 disp_string
= object
;
28449 disp_string
= Qnil
;
28452 if (!NILP (mouse_face
))
28454 Lisp_Object before
, after
;
28455 Lisp_Object before_string
, after_string
;
28456 /* To correctly find the limits of mouse highlight
28457 in a bidi-reordered buffer, we must not use the
28458 optimization of limiting the search in
28459 previous-single-property-change and
28460 next-single-property-change, because
28461 rows_from_pos_range needs the real start and end
28462 positions to DTRT in this case. That's because
28463 the first row visible in a window does not
28464 necessarily display the character whose position
28465 is the smallest. */
28467 = NILP (BVAR (XBUFFER (buffer
), bidi_display_reordering
))
28468 ? Fmarker_position (w
->start
)
28471 = NILP (BVAR (XBUFFER (buffer
), bidi_display_reordering
))
28472 ? make_number (BUF_Z (XBUFFER (buffer
))
28473 - w
->window_end_pos
)
28476 if (NILP (overlay
))
28478 /* Handle the text property case. */
28479 before
= Fprevious_single_property_change
28480 (make_number (pos
+ 1), Qmouse_face
, buffer
, lim1
);
28481 after
= Fnext_single_property_change
28482 (make_number (pos
), Qmouse_face
, buffer
, lim2
);
28483 before_string
= after_string
= Qnil
;
28487 /* Handle the overlay case. */
28488 before
= Foverlay_start (overlay
);
28489 after
= Foverlay_end (overlay
);
28490 before_string
= Foverlay_get (overlay
, Qbefore_string
);
28491 after_string
= Foverlay_get (overlay
, Qafter_string
);
28493 if (!STRINGP (before_string
)) before_string
= Qnil
;
28494 if (!STRINGP (after_string
)) after_string
= Qnil
;
28497 mouse_face_from_buffer_pos (window
, hlinfo
, pos
,
28500 : XFASTINT (before
),
28502 ? BUF_Z (XBUFFER (buffer
))
28503 : XFASTINT (after
),
28504 before_string
, after_string
,
28506 cursor
= No_Cursor
;
28513 /* Look for a `help-echo' property. */
28514 if (NILP (help_echo_string
)) {
28515 Lisp_Object help
, overlay
;
28517 /* Check overlays first. */
28518 help
= overlay
= Qnil
;
28519 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
28521 overlay
= overlay_vec
[i
];
28522 help
= Foverlay_get (overlay
, Qhelp_echo
);
28527 help_echo_string
= help
;
28528 help_echo_window
= window
;
28529 help_echo_object
= overlay
;
28530 help_echo_pos
= pos
;
28534 Lisp_Object obj
= glyph
->object
;
28535 ptrdiff_t charpos
= glyph
->charpos
;
28537 /* Try text properties. */
28540 && charpos
< SCHARS (obj
))
28542 help
= Fget_text_property (make_number (charpos
),
28546 /* If the string itself doesn't specify a help-echo,
28547 see if the buffer text ``under'' it does. */
28548 struct glyph_row
*r
28549 = MATRIX_ROW (w
->current_matrix
, vpos
);
28550 ptrdiff_t start
= MATRIX_ROW_START_CHARPOS (r
);
28551 ptrdiff_t p
= string_buffer_position (obj
, start
);
28554 help
= Fget_char_property (make_number (p
),
28555 Qhelp_echo
, w
->contents
);
28564 else if (BUFFERP (obj
)
28567 help
= Fget_text_property (make_number (charpos
), Qhelp_echo
,
28572 help_echo_string
= help
;
28573 help_echo_window
= window
;
28574 help_echo_object
= obj
;
28575 help_echo_pos
= charpos
;
28580 #ifdef HAVE_WINDOW_SYSTEM
28581 /* Look for a `pointer' property. */
28582 if (FRAME_WINDOW_P (f
) && NILP (pointer
))
28584 /* Check overlays first. */
28585 for (i
= noverlays
- 1; i
>= 0 && NILP (pointer
); --i
)
28586 pointer
= Foverlay_get (overlay_vec
[i
], Qpointer
);
28588 if (NILP (pointer
))
28590 Lisp_Object obj
= glyph
->object
;
28591 ptrdiff_t charpos
= glyph
->charpos
;
28593 /* Try text properties. */
28596 && charpos
< SCHARS (obj
))
28598 pointer
= Fget_text_property (make_number (charpos
),
28600 if (NILP (pointer
))
28602 /* If the string itself doesn't specify a pointer,
28603 see if the buffer text ``under'' it does. */
28604 struct glyph_row
*r
28605 = MATRIX_ROW (w
->current_matrix
, vpos
);
28606 ptrdiff_t start
= MATRIX_ROW_START_CHARPOS (r
);
28607 ptrdiff_t p
= string_buffer_position (obj
, start
);
28609 pointer
= Fget_char_property (make_number (p
),
28610 Qpointer
, w
->contents
);
28613 else if (BUFFERP (obj
)
28616 pointer
= Fget_text_property (make_number (charpos
),
28620 #endif /* HAVE_WINDOW_SYSTEM */
28624 current_buffer
= obuf
;
28629 #ifdef HAVE_WINDOW_SYSTEM
28630 if (FRAME_WINDOW_P (f
))
28631 define_frame_cursor1 (f
, cursor
, pointer
);
28633 /* This is here to prevent a compiler error, about "label at end of
28634 compound statement". */
28641 Clear any mouse-face on window W. This function is part of the
28642 redisplay interface, and is called from try_window_id and similar
28643 functions to ensure the mouse-highlight is off. */
28646 x_clear_window_mouse_face (struct window
*w
)
28648 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (XFRAME (w
->frame
));
28649 Lisp_Object window
;
28652 XSETWINDOW (window
, w
);
28653 if (EQ (window
, hlinfo
->mouse_face_window
))
28654 clear_mouse_face (hlinfo
);
28660 Just discard the mouse face information for frame F, if any.
28661 This is used when the size of F is changed. */
28664 cancel_mouse_face (struct frame
*f
)
28666 Lisp_Object window
;
28667 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
28669 window
= hlinfo
->mouse_face_window
;
28670 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
28671 reset_mouse_highlight (hlinfo
);
28676 /***********************************************************************
28678 ***********************************************************************/
28680 #ifdef HAVE_WINDOW_SYSTEM
28682 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
28683 which intersects rectangle R. R is in window-relative coordinates. */
28686 expose_area (struct window
*w
, struct glyph_row
*row
, XRectangle
*r
,
28687 enum glyph_row_area area
)
28689 struct glyph
*first
= row
->glyphs
[area
];
28690 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
28691 struct glyph
*last
;
28692 int first_x
, start_x
, x
;
28694 if (area
== TEXT_AREA
&& row
->fill_line_p
)
28695 /* If row extends face to end of line write the whole line. */
28696 draw_glyphs (w
, 0, row
, area
,
28697 0, row
->used
[area
],
28698 DRAW_NORMAL_TEXT
, 0);
28701 /* Set START_X to the window-relative start position for drawing glyphs of
28702 AREA. The first glyph of the text area can be partially visible.
28703 The first glyphs of other areas cannot. */
28704 start_x
= window_box_left_offset (w
, area
);
28706 if (area
== TEXT_AREA
)
28709 /* Find the first glyph that must be redrawn. */
28711 && x
+ first
->pixel_width
< r
->x
)
28713 x
+= first
->pixel_width
;
28717 /* Find the last one. */
28721 && x
< r
->x
+ r
->width
)
28723 x
+= last
->pixel_width
;
28729 draw_glyphs (w
, first_x
- start_x
, row
, area
,
28730 first
- row
->glyphs
[area
], last
- row
->glyphs
[area
],
28731 DRAW_NORMAL_TEXT
, 0);
28736 /* Redraw the parts of the glyph row ROW on window W intersecting
28737 rectangle R. R is in window-relative coordinates. Value is
28738 non-zero if mouse-face was overwritten. */
28741 expose_line (struct window
*w
, struct glyph_row
*row
, XRectangle
*r
)
28743 eassert (row
->enabled_p
);
28745 if (row
->mode_line_p
|| w
->pseudo_window_p
)
28746 draw_glyphs (w
, 0, row
, TEXT_AREA
,
28747 0, row
->used
[TEXT_AREA
],
28748 DRAW_NORMAL_TEXT
, 0);
28751 if (row
->used
[LEFT_MARGIN_AREA
])
28752 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
28753 if (row
->used
[TEXT_AREA
])
28754 expose_area (w
, row
, r
, TEXT_AREA
);
28755 if (row
->used
[RIGHT_MARGIN_AREA
])
28756 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
28757 draw_row_fringe_bitmaps (w
, row
);
28760 return row
->mouse_face_p
;
28764 /* Redraw those parts of glyphs rows during expose event handling that
28765 overlap other rows. Redrawing of an exposed line writes over parts
28766 of lines overlapping that exposed line; this function fixes that.
28768 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
28769 row in W's current matrix that is exposed and overlaps other rows.
28770 LAST_OVERLAPPING_ROW is the last such row. */
28773 expose_overlaps (struct window
*w
,
28774 struct glyph_row
*first_overlapping_row
,
28775 struct glyph_row
*last_overlapping_row
,
28778 struct glyph_row
*row
;
28780 for (row
= first_overlapping_row
; row
<= last_overlapping_row
; ++row
)
28781 if (row
->overlapping_p
)
28783 eassert (row
->enabled_p
&& !row
->mode_line_p
);
28786 if (row
->used
[LEFT_MARGIN_AREA
])
28787 x_fix_overlapping_area (w
, row
, LEFT_MARGIN_AREA
, OVERLAPS_BOTH
);
28789 if (row
->used
[TEXT_AREA
])
28790 x_fix_overlapping_area (w
, row
, TEXT_AREA
, OVERLAPS_BOTH
);
28792 if (row
->used
[RIGHT_MARGIN_AREA
])
28793 x_fix_overlapping_area (w
, row
, RIGHT_MARGIN_AREA
, OVERLAPS_BOTH
);
28799 /* Return non-zero if W's cursor intersects rectangle R. */
28802 phys_cursor_in_rect_p (struct window
*w
, XRectangle
*r
)
28804 XRectangle cr
, result
;
28805 struct glyph
*cursor_glyph
;
28806 struct glyph_row
*row
;
28808 if (w
->phys_cursor
.vpos
>= 0
28809 && w
->phys_cursor
.vpos
< w
->current_matrix
->nrows
28810 && (row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
),
28812 && row
->cursor_in_fringe_p
)
28814 /* Cursor is in the fringe. */
28815 cr
.x
= window_box_right_offset (w
,
28816 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
28817 ? RIGHT_MARGIN_AREA
28820 cr
.width
= WINDOW_RIGHT_FRINGE_WIDTH (w
);
28821 cr
.height
= row
->height
;
28822 return x_intersect_rectangles (&cr
, r
, &result
);
28825 cursor_glyph
= get_phys_cursor_glyph (w
);
28828 /* r is relative to W's box, but w->phys_cursor.x is relative
28829 to left edge of W's TEXT area. Adjust it. */
28830 cr
.x
= window_box_left_offset (w
, TEXT_AREA
) + w
->phys_cursor
.x
;
28831 cr
.y
= w
->phys_cursor
.y
;
28832 cr
.width
= cursor_glyph
->pixel_width
;
28833 cr
.height
= w
->phys_cursor_height
;
28834 /* ++KFS: W32 version used W32-specific IntersectRect here, but
28835 I assume the effect is the same -- and this is portable. */
28836 return x_intersect_rectangles (&cr
, r
, &result
);
28838 /* If we don't understand the format, pretend we're not in the hot-spot. */
28844 Draw a vertical window border to the right of window W if W doesn't
28845 have vertical scroll bars. */
28848 x_draw_vertical_border (struct window
*w
)
28850 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
28852 /* We could do better, if we knew what type of scroll-bar the adjacent
28853 windows (on either side) have... But we don't :-(
28854 However, I think this works ok. ++KFS 2003-04-25 */
28856 /* Redraw borders between horizontally adjacent windows. Don't
28857 do it for frames with vertical scroll bars because either the
28858 right scroll bar of a window, or the left scroll bar of its
28859 neighbor will suffice as a border. */
28860 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w
->frame
)))
28863 /* Note: It is necessary to redraw both the left and the right
28864 borders, for when only this single window W is being
28866 if (!WINDOW_RIGHTMOST_P (w
)
28867 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w
))
28869 int x0
, x1
, y0
, y1
;
28871 window_box_edges (w
, &x0
, &y0
, &x1
, &y1
);
28874 if (WINDOW_LEFT_FRINGE_WIDTH (w
) == 0)
28877 FRAME_RIF (f
)->draw_vertical_window_border (w
, x1
, y0
, y1
);
28879 if (!WINDOW_LEFTMOST_P (w
)
28880 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w
))
28882 int x0
, x1
, y0
, y1
;
28884 window_box_edges (w
, &x0
, &y0
, &x1
, &y1
);
28887 if (WINDOW_LEFT_FRINGE_WIDTH (w
) == 0)
28890 FRAME_RIF (f
)->draw_vertical_window_border (w
, x0
, y0
, y1
);
28895 /* Redraw the part of window W intersection rectangle FR. Pixel
28896 coordinates in FR are frame-relative. Call this function with
28897 input blocked. Value is non-zero if the exposure overwrites
28901 expose_window (struct window
*w
, XRectangle
*fr
)
28903 struct frame
*f
= XFRAME (w
->frame
);
28905 int mouse_face_overwritten_p
= 0;
28907 /* If window is not yet fully initialized, do nothing. This can
28908 happen when toolkit scroll bars are used and a window is split.
28909 Reconfiguring the scroll bar will generate an expose for a newly
28911 if (w
->current_matrix
== NULL
)
28914 /* When we're currently updating the window, display and current
28915 matrix usually don't agree. Arrange for a thorough display
28917 if (w
->must_be_updated_p
)
28919 SET_FRAME_GARBAGED (f
);
28923 /* Frame-relative pixel rectangle of W. */
28924 wr
.x
= WINDOW_LEFT_EDGE_X (w
);
28925 wr
.y
= WINDOW_TOP_EDGE_Y (w
);
28926 wr
.width
= WINDOW_TOTAL_WIDTH (w
);
28927 wr
.height
= WINDOW_TOTAL_HEIGHT (w
);
28929 if (x_intersect_rectangles (fr
, &wr
, &r
))
28931 int yb
= window_text_bottom_y (w
);
28932 struct glyph_row
*row
;
28933 int cursor_cleared_p
, phys_cursor_on_p
;
28934 struct glyph_row
*first_overlapping_row
, *last_overlapping_row
;
28936 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
28937 r
.x
, r
.y
, r
.width
, r
.height
));
28939 /* Convert to window coordinates. */
28940 r
.x
-= WINDOW_LEFT_EDGE_X (w
);
28941 r
.y
-= WINDOW_TOP_EDGE_Y (w
);
28943 /* Turn off the cursor. */
28944 if (!w
->pseudo_window_p
28945 && phys_cursor_in_rect_p (w
, &r
))
28947 x_clear_cursor (w
);
28948 cursor_cleared_p
= 1;
28951 cursor_cleared_p
= 0;
28953 /* If the row containing the cursor extends face to end of line,
28954 then expose_area might overwrite the cursor outside the
28955 rectangle and thus notice_overwritten_cursor might clear
28956 w->phys_cursor_on_p. We remember the original value and
28957 check later if it is changed. */
28958 phys_cursor_on_p
= w
->phys_cursor_on_p
;
28960 /* Update lines intersecting rectangle R. */
28961 first_overlapping_row
= last_overlapping_row
= NULL
;
28962 for (row
= w
->current_matrix
->rows
;
28967 int y1
= MATRIX_ROW_BOTTOM_Y (row
);
28969 if ((y0
>= r
.y
&& y0
< r
.y
+ r
.height
)
28970 || (y1
> r
.y
&& y1
< r
.y
+ r
.height
)
28971 || (r
.y
>= y0
&& r
.y
< y1
)
28972 || (r
.y
+ r
.height
> y0
&& r
.y
+ r
.height
< y1
))
28974 /* A header line may be overlapping, but there is no need
28975 to fix overlapping areas for them. KFS 2005-02-12 */
28976 if (row
->overlapping_p
&& !row
->mode_line_p
)
28978 if (first_overlapping_row
== NULL
)
28979 first_overlapping_row
= row
;
28980 last_overlapping_row
= row
;
28984 if (expose_line (w
, row
, &r
))
28985 mouse_face_overwritten_p
= 1;
28988 else if (row
->overlapping_p
)
28990 /* We must redraw a row overlapping the exposed area. */
28992 ? y0
+ row
->phys_height
> r
.y
28993 : y0
+ row
->ascent
- row
->phys_ascent
< r
.y
+r
.height
)
28995 if (first_overlapping_row
== NULL
)
28996 first_overlapping_row
= row
;
28997 last_overlapping_row
= row
;
29005 /* Display the mode line if there is one. */
29006 if (WINDOW_WANTS_MODELINE_P (w
)
29007 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
29009 && row
->y
< r
.y
+ r
.height
)
29011 if (expose_line (w
, row
, &r
))
29012 mouse_face_overwritten_p
= 1;
29015 if (!w
->pseudo_window_p
)
29017 /* Fix the display of overlapping rows. */
29018 if (first_overlapping_row
)
29019 expose_overlaps (w
, first_overlapping_row
, last_overlapping_row
,
29022 /* Draw border between windows. */
29023 x_draw_vertical_border (w
);
29025 /* Turn the cursor on again. */
29026 if (cursor_cleared_p
29027 || (phys_cursor_on_p
&& !w
->phys_cursor_on_p
))
29028 update_window_cursor (w
, 1);
29032 return mouse_face_overwritten_p
;
29037 /* Redraw (parts) of all windows in the window tree rooted at W that
29038 intersect R. R contains frame pixel coordinates. Value is
29039 non-zero if the exposure overwrites mouse-face. */
29042 expose_window_tree (struct window
*w
, XRectangle
*r
)
29044 struct frame
*f
= XFRAME (w
->frame
);
29045 int mouse_face_overwritten_p
= 0;
29047 while (w
&& !FRAME_GARBAGED_P (f
))
29049 if (WINDOWP (w
->contents
))
29050 mouse_face_overwritten_p
29051 |= expose_window_tree (XWINDOW (w
->contents
), r
);
29053 mouse_face_overwritten_p
|= expose_window (w
, r
);
29055 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
29058 return mouse_face_overwritten_p
;
29063 Redisplay an exposed area of frame F. X and Y are the upper-left
29064 corner of the exposed rectangle. W and H are width and height of
29065 the exposed area. All are pixel values. W or H zero means redraw
29066 the entire frame. */
29069 expose_frame (struct frame
*f
, int x
, int y
, int w
, int h
)
29072 int mouse_face_overwritten_p
= 0;
29074 TRACE ((stderr
, "expose_frame "));
29076 /* No need to redraw if frame will be redrawn soon. */
29077 if (FRAME_GARBAGED_P (f
))
29079 TRACE ((stderr
, " garbaged\n"));
29083 /* If basic faces haven't been realized yet, there is no point in
29084 trying to redraw anything. This can happen when we get an expose
29085 event while Emacs is starting, e.g. by moving another window. */
29086 if (FRAME_FACE_CACHE (f
) == NULL
29087 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
29089 TRACE ((stderr
, " no faces\n"));
29093 if (w
== 0 || h
== 0)
29096 r
.width
= FRAME_COLUMN_WIDTH (f
) * FRAME_COLS (f
);
29097 r
.height
= FRAME_LINE_HEIGHT (f
) * FRAME_LINES (f
);
29107 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.x
, r
.y
, r
.width
, r
.height
));
29108 mouse_face_overwritten_p
= expose_window_tree (XWINDOW (f
->root_window
), &r
);
29110 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
29111 if (WINDOWP (f
->tool_bar_window
))
29112 mouse_face_overwritten_p
29113 |= expose_window (XWINDOW (f
->tool_bar_window
), &r
);
29116 #ifdef HAVE_X_WINDOWS
29118 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
29119 if (WINDOWP (f
->menu_bar_window
))
29120 mouse_face_overwritten_p
29121 |= expose_window (XWINDOW (f
->menu_bar_window
), &r
);
29122 #endif /* not USE_X_TOOLKIT and not USE_GTK */
29126 /* Some window managers support a focus-follows-mouse style with
29127 delayed raising of frames. Imagine a partially obscured frame,
29128 and moving the mouse into partially obscured mouse-face on that
29129 frame. The visible part of the mouse-face will be highlighted,
29130 then the WM raises the obscured frame. With at least one WM, KDE
29131 2.1, Emacs is not getting any event for the raising of the frame
29132 (even tried with SubstructureRedirectMask), only Expose events.
29133 These expose events will draw text normally, i.e. not
29134 highlighted. Which means we must redo the highlight here.
29135 Subsume it under ``we love X''. --gerd 2001-08-15 */
29136 /* Included in Windows version because Windows most likely does not
29137 do the right thing if any third party tool offers
29138 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
29139 if (mouse_face_overwritten_p
&& !FRAME_GARBAGED_P (f
))
29141 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
29142 if (f
== hlinfo
->mouse_face_mouse_frame
)
29144 int mouse_x
= hlinfo
->mouse_face_mouse_x
;
29145 int mouse_y
= hlinfo
->mouse_face_mouse_y
;
29146 clear_mouse_face (hlinfo
);
29147 note_mouse_highlight (f
, mouse_x
, mouse_y
);
29154 Determine the intersection of two rectangles R1 and R2. Return
29155 the intersection in *RESULT. Value is non-zero if RESULT is not
29159 x_intersect_rectangles (XRectangle
*r1
, XRectangle
*r2
, XRectangle
*result
)
29161 XRectangle
*left
, *right
;
29162 XRectangle
*upper
, *lower
;
29163 int intersection_p
= 0;
29165 /* Rearrange so that R1 is the left-most rectangle. */
29167 left
= r1
, right
= r2
;
29169 left
= r2
, right
= r1
;
29171 /* X0 of the intersection is right.x0, if this is inside R1,
29172 otherwise there is no intersection. */
29173 if (right
->x
<= left
->x
+ left
->width
)
29175 result
->x
= right
->x
;
29177 /* The right end of the intersection is the minimum of
29178 the right ends of left and right. */
29179 result
->width
= (min (left
->x
+ left
->width
, right
->x
+ right
->width
)
29182 /* Same game for Y. */
29184 upper
= r1
, lower
= r2
;
29186 upper
= r2
, lower
= r1
;
29188 /* The upper end of the intersection is lower.y0, if this is inside
29189 of upper. Otherwise, there is no intersection. */
29190 if (lower
->y
<= upper
->y
+ upper
->height
)
29192 result
->y
= lower
->y
;
29194 /* The lower end of the intersection is the minimum of the lower
29195 ends of upper and lower. */
29196 result
->height
= (min (lower
->y
+ lower
->height
,
29197 upper
->y
+ upper
->height
)
29199 intersection_p
= 1;
29203 return intersection_p
;
29206 #endif /* HAVE_WINDOW_SYSTEM */
29209 /***********************************************************************
29211 ***********************************************************************/
29214 syms_of_xdisp (void)
29216 Vwith_echo_area_save_vector
= Qnil
;
29217 staticpro (&Vwith_echo_area_save_vector
);
29219 Vmessage_stack
= Qnil
;
29220 staticpro (&Vmessage_stack
);
29222 DEFSYM (Qinhibit_redisplay
, "inhibit-redisplay");
29223 DEFSYM (Qredisplay_internal
, "redisplay_internal (C function)");
29225 message_dolog_marker1
= Fmake_marker ();
29226 staticpro (&message_dolog_marker1
);
29227 message_dolog_marker2
= Fmake_marker ();
29228 staticpro (&message_dolog_marker2
);
29229 message_dolog_marker3
= Fmake_marker ();
29230 staticpro (&message_dolog_marker3
);
29233 defsubr (&Sdump_frame_glyph_matrix
);
29234 defsubr (&Sdump_glyph_matrix
);
29235 defsubr (&Sdump_glyph_row
);
29236 defsubr (&Sdump_tool_bar_row
);
29237 defsubr (&Strace_redisplay
);
29238 defsubr (&Strace_to_stderr
);
29240 #ifdef HAVE_WINDOW_SYSTEM
29241 defsubr (&Stool_bar_lines_needed
);
29242 defsubr (&Slookup_image_map
);
29244 defsubr (&Sline_pixel_height
);
29245 defsubr (&Sformat_mode_line
);
29246 defsubr (&Sinvisible_p
);
29247 defsubr (&Scurrent_bidi_paragraph_direction
);
29248 defsubr (&Smove_point_visually
);
29250 DEFSYM (Qmenu_bar_update_hook
, "menu-bar-update-hook");
29251 DEFSYM (Qoverriding_terminal_local_map
, "overriding-terminal-local-map");
29252 DEFSYM (Qoverriding_local_map
, "overriding-local-map");
29253 DEFSYM (Qwindow_scroll_functions
, "window-scroll-functions");
29254 DEFSYM (Qwindow_text_change_functions
, "window-text-change-functions");
29255 DEFSYM (Qredisplay_end_trigger_functions
, "redisplay-end-trigger-functions");
29256 DEFSYM (Qinhibit_point_motion_hooks
, "inhibit-point-motion-hooks");
29257 DEFSYM (Qeval
, "eval");
29258 DEFSYM (QCdata
, ":data");
29259 DEFSYM (Qdisplay
, "display");
29260 DEFSYM (Qspace_width
, "space-width");
29261 DEFSYM (Qraise
, "raise");
29262 DEFSYM (Qslice
, "slice");
29263 DEFSYM (Qspace
, "space");
29264 DEFSYM (Qmargin
, "margin");
29265 DEFSYM (Qpointer
, "pointer");
29266 DEFSYM (Qleft_margin
, "left-margin");
29267 DEFSYM (Qright_margin
, "right-margin");
29268 DEFSYM (Qcenter
, "center");
29269 DEFSYM (Qline_height
, "line-height");
29270 DEFSYM (QCalign_to
, ":align-to");
29271 DEFSYM (QCrelative_width
, ":relative-width");
29272 DEFSYM (QCrelative_height
, ":relative-height");
29273 DEFSYM (QCeval
, ":eval");
29274 DEFSYM (QCpropertize
, ":propertize");
29275 DEFSYM (QCfile
, ":file");
29276 DEFSYM (Qfontified
, "fontified");
29277 DEFSYM (Qfontification_functions
, "fontification-functions");
29278 DEFSYM (Qtrailing_whitespace
, "trailing-whitespace");
29279 DEFSYM (Qescape_glyph
, "escape-glyph");
29280 DEFSYM (Qnobreak_space
, "nobreak-space");
29281 DEFSYM (Qimage
, "image");
29282 DEFSYM (Qtext
, "text");
29283 DEFSYM (Qboth
, "both");
29284 DEFSYM (Qboth_horiz
, "both-horiz");
29285 DEFSYM (Qtext_image_horiz
, "text-image-horiz");
29286 DEFSYM (QCmap
, ":map");
29287 DEFSYM (QCpointer
, ":pointer");
29288 DEFSYM (Qrect
, "rect");
29289 DEFSYM (Qcircle
, "circle");
29290 DEFSYM (Qpoly
, "poly");
29291 DEFSYM (Qmessage_truncate_lines
, "message-truncate-lines");
29292 DEFSYM (Qgrow_only
, "grow-only");
29293 DEFSYM (Qinhibit_menubar_update
, "inhibit-menubar-update");
29294 DEFSYM (Qinhibit_eval_during_redisplay
, "inhibit-eval-during-redisplay");
29295 DEFSYM (Qposition
, "position");
29296 DEFSYM (Qbuffer_position
, "buffer-position");
29297 DEFSYM (Qobject
, "object");
29298 DEFSYM (Qbar
, "bar");
29299 DEFSYM (Qhbar
, "hbar");
29300 DEFSYM (Qbox
, "box");
29301 DEFSYM (Qhollow
, "hollow");
29302 DEFSYM (Qhand
, "hand");
29303 DEFSYM (Qarrow
, "arrow");
29304 DEFSYM (Qinhibit_free_realized_faces
, "inhibit-free-realized-faces");
29306 list_of_error
= list1 (list2 (intern_c_string ("error"),
29307 intern_c_string ("void-variable")));
29308 staticpro (&list_of_error
);
29310 DEFSYM (Qlast_arrow_position
, "last-arrow-position");
29311 DEFSYM (Qlast_arrow_string
, "last-arrow-string");
29312 DEFSYM (Qoverlay_arrow_string
, "overlay-arrow-string");
29313 DEFSYM (Qoverlay_arrow_bitmap
, "overlay-arrow-bitmap");
29315 echo_buffer
[0] = echo_buffer
[1] = Qnil
;
29316 staticpro (&echo_buffer
[0]);
29317 staticpro (&echo_buffer
[1]);
29319 echo_area_buffer
[0] = echo_area_buffer
[1] = Qnil
;
29320 staticpro (&echo_area_buffer
[0]);
29321 staticpro (&echo_area_buffer
[1]);
29323 Vmessages_buffer_name
= build_pure_c_string ("*Messages*");
29324 staticpro (&Vmessages_buffer_name
);
29326 mode_line_proptrans_alist
= Qnil
;
29327 staticpro (&mode_line_proptrans_alist
);
29328 mode_line_string_list
= Qnil
;
29329 staticpro (&mode_line_string_list
);
29330 mode_line_string_face
= Qnil
;
29331 staticpro (&mode_line_string_face
);
29332 mode_line_string_face_prop
= Qnil
;
29333 staticpro (&mode_line_string_face_prop
);
29334 Vmode_line_unwind_vector
= Qnil
;
29335 staticpro (&Vmode_line_unwind_vector
);
29337 DEFSYM (Qmode_line_default_help_echo
, "mode-line-default-help-echo");
29339 help_echo_string
= Qnil
;
29340 staticpro (&help_echo_string
);
29341 help_echo_object
= Qnil
;
29342 staticpro (&help_echo_object
);
29343 help_echo_window
= Qnil
;
29344 staticpro (&help_echo_window
);
29345 previous_help_echo_string
= Qnil
;
29346 staticpro (&previous_help_echo_string
);
29347 help_echo_pos
= -1;
29349 DEFSYM (Qright_to_left
, "right-to-left");
29350 DEFSYM (Qleft_to_right
, "left-to-right");
29352 #ifdef HAVE_WINDOW_SYSTEM
29353 DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p
,
29354 doc
: /* Non-nil means draw block cursor as wide as the glyph under it.
29355 For example, if a block cursor is over a tab, it will be drawn as
29356 wide as that tab on the display. */);
29357 x_stretch_cursor_p
= 0;
29360 DEFVAR_LISP ("show-trailing-whitespace", Vshow_trailing_whitespace
,
29361 doc
: /* Non-nil means highlight trailing whitespace.
29362 The face used for trailing whitespace is `trailing-whitespace'. */);
29363 Vshow_trailing_whitespace
= Qnil
;
29365 DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display
,
29366 doc
: /* Control highlighting of non-ASCII space and hyphen chars.
29367 If the value is t, Emacs highlights non-ASCII chars which have the
29368 same appearance as an ASCII space or hyphen, using the `nobreak-space'
29369 or `escape-glyph' face respectively.
29371 U+00A0 (no-break space), U+00AD (soft hyphen), U+2010 (hyphen), and
29372 U+2011 (non-breaking hyphen) are affected.
29374 Any other non-nil value means to display these characters as a escape
29375 glyph followed by an ordinary space or hyphen.
29377 A value of nil means no special handling of these characters. */);
29378 Vnobreak_char_display
= Qt
;
29380 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer
,
29381 doc
: /* The pointer shape to show in void text areas.
29382 A value of nil means to show the text pointer. Other options are `arrow',
29383 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
29384 Vvoid_text_area_pointer
= Qarrow
;
29386 DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay
,
29387 doc
: /* Non-nil means don't actually do any redisplay.
29388 This is used for internal purposes. */);
29389 Vinhibit_redisplay
= Qnil
;
29391 DEFVAR_LISP ("global-mode-string", Vglobal_mode_string
,
29392 doc
: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
29393 Vglobal_mode_string
= Qnil
;
29395 DEFVAR_LISP ("overlay-arrow-position", Voverlay_arrow_position
,
29396 doc
: /* Marker for where to display an arrow on top of the buffer text.
29397 This must be the beginning of a line in order to work.
29398 See also `overlay-arrow-string'. */);
29399 Voverlay_arrow_position
= Qnil
;
29401 DEFVAR_LISP ("overlay-arrow-string", Voverlay_arrow_string
,
29402 doc
: /* String to display as an arrow in non-window frames.
29403 See also `overlay-arrow-position'. */);
29404 Voverlay_arrow_string
= build_pure_c_string ("=>");
29406 DEFVAR_LISP ("overlay-arrow-variable-list", Voverlay_arrow_variable_list
,
29407 doc
: /* List of variables (symbols) which hold markers for overlay arrows.
29408 The symbols on this list are examined during redisplay to determine
29409 where to display overlay arrows. */);
29410 Voverlay_arrow_variable_list
29411 = list1 (intern_c_string ("overlay-arrow-position"));
29413 DEFVAR_INT ("scroll-step", emacs_scroll_step
,
29414 doc
: /* The number of lines to try scrolling a window by when point moves out.
29415 If that fails to bring point back on frame, point is centered instead.
29416 If this is zero, point is always centered after it moves off frame.
29417 If you want scrolling to always be a line at a time, you should set
29418 `scroll-conservatively' to a large value rather than set this to 1. */);
29420 DEFVAR_INT ("scroll-conservatively", scroll_conservatively
,
29421 doc
: /* Scroll up to this many lines, to bring point back on screen.
29422 If point moves off-screen, redisplay will scroll by up to
29423 `scroll-conservatively' lines in order to bring point just barely
29424 onto the screen again. If that cannot be done, then redisplay
29425 recenters point as usual.
29427 If the value is greater than 100, redisplay will never recenter point,
29428 but will always scroll just enough text to bring point into view, even
29429 if you move far away.
29431 A value of zero means always recenter point if it moves off screen. */);
29432 scroll_conservatively
= 0;
29434 DEFVAR_INT ("scroll-margin", scroll_margin
,
29435 doc
: /* Number of lines of margin at the top and bottom of a window.
29436 Recenter the window whenever point gets within this many lines
29437 of the top or bottom of the window. */);
29440 DEFVAR_LISP ("display-pixels-per-inch", Vdisplay_pixels_per_inch
,
29441 doc
: /* Pixels per inch value for non-window system displays.
29442 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
29443 Vdisplay_pixels_per_inch
= make_float (72.0);
29446 DEFVAR_INT ("debug-end-pos", debug_end_pos
, doc
: /* Don't ask. */);
29449 DEFVAR_LISP ("truncate-partial-width-windows",
29450 Vtruncate_partial_width_windows
,
29451 doc
: /* Non-nil means truncate lines in windows narrower than the frame.
29452 For an integer value, truncate lines in each window narrower than the
29453 full frame width, provided the window width is less than that integer;
29454 otherwise, respect the value of `truncate-lines'.
29456 For any other non-nil value, truncate lines in all windows that do
29457 not span the full frame width.
29459 A value of nil means to respect the value of `truncate-lines'.
29461 If `word-wrap' is enabled, you might want to reduce this. */);
29462 Vtruncate_partial_width_windows
= make_number (50);
29464 DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit
,
29465 doc
: /* Maximum buffer size for which line number should be displayed.
29466 If the buffer is bigger than this, the line number does not appear
29467 in the mode line. A value of nil means no limit. */);
29468 Vline_number_display_limit
= Qnil
;
29470 DEFVAR_INT ("line-number-display-limit-width",
29471 line_number_display_limit_width
,
29472 doc
: /* Maximum line width (in characters) for line number display.
29473 If the average length of the lines near point is bigger than this, then the
29474 line number may be omitted from the mode line. */);
29475 line_number_display_limit_width
= 200;
29477 DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows
,
29478 doc
: /* Non-nil means highlight region even in nonselected windows. */);
29479 highlight_nonselected_windows
= 0;
29481 DEFVAR_BOOL ("multiple-frames", multiple_frames
,
29482 doc
: /* Non-nil if more than one frame is visible on this display.
29483 Minibuffer-only frames don't count, but iconified frames do.
29484 This variable is not guaranteed to be accurate except while processing
29485 `frame-title-format' and `icon-title-format'. */);
29487 DEFVAR_LISP ("frame-title-format", Vframe_title_format
,
29488 doc
: /* Template for displaying the title bar of visible frames.
29489 \(Assuming the window manager supports this feature.)
29491 This variable has the same structure as `mode-line-format', except that
29492 the %c and %l constructs are ignored. It is used only on frames for
29493 which no explicit name has been set \(see `modify-frame-parameters'). */);
29495 DEFVAR_LISP ("icon-title-format", Vicon_title_format
,
29496 doc
: /* Template for displaying the title bar of an iconified frame.
29497 \(Assuming the window manager supports this feature.)
29498 This variable has the same structure as `mode-line-format' (which see),
29499 and is used only on frames for which no explicit name has been set
29500 \(see `modify-frame-parameters'). */);
29502 = Vframe_title_format
29503 = listn (CONSTYPE_PURE
, 3,
29504 intern_c_string ("multiple-frames"),
29505 build_pure_c_string ("%b"),
29506 listn (CONSTYPE_PURE
, 4,
29507 empty_unibyte_string
,
29508 intern_c_string ("invocation-name"),
29509 build_pure_c_string ("@"),
29510 intern_c_string ("system-name")));
29512 DEFVAR_LISP ("message-log-max", Vmessage_log_max
,
29513 doc
: /* Maximum number of lines to keep in the message log buffer.
29514 If nil, disable message logging. If t, log messages but don't truncate
29515 the buffer when it becomes large. */);
29516 Vmessage_log_max
= make_number (1000);
29518 DEFVAR_LISP ("window-size-change-functions", Vwindow_size_change_functions
,
29519 doc
: /* Functions called before redisplay, if window sizes have changed.
29520 The value should be a list of functions that take one argument.
29521 Just before redisplay, for each frame, if any of its windows have changed
29522 size since the last redisplay, or have been split or deleted,
29523 all the functions in the list are called, with the frame as argument. */);
29524 Vwindow_size_change_functions
= Qnil
;
29526 DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions
,
29527 doc
: /* List of functions to call before redisplaying a window with scrolling.
29528 Each function is called with two arguments, the window and its new
29529 display-start position. Note that these functions are also called by
29530 `set-window-buffer'. Also note that the value of `window-end' is not
29531 valid when these functions are called.
29533 Warning: Do not use this feature to alter the way the window
29534 is scrolled. It is not designed for that, and such use probably won't
29536 Vwindow_scroll_functions
= Qnil
;
29538 DEFVAR_LISP ("window-text-change-functions",
29539 Vwindow_text_change_functions
,
29540 doc
: /* Functions to call in redisplay when text in the window might change. */);
29541 Vwindow_text_change_functions
= Qnil
;
29543 DEFVAR_LISP ("redisplay-end-trigger-functions", Vredisplay_end_trigger_functions
,
29544 doc
: /* Functions called when redisplay of a window reaches the end trigger.
29545 Each function is called with two arguments, the window and the end trigger value.
29546 See `set-window-redisplay-end-trigger'. */);
29547 Vredisplay_end_trigger_functions
= Qnil
;
29549 DEFVAR_LISP ("mouse-autoselect-window", Vmouse_autoselect_window
,
29550 doc
: /* Non-nil means autoselect window with mouse pointer.
29551 If nil, do not autoselect windows.
29552 A positive number means delay autoselection by that many seconds: a
29553 window is autoselected only after the mouse has remained in that
29554 window for the duration of the delay.
29555 A negative number has a similar effect, but causes windows to be
29556 autoselected only after the mouse has stopped moving. \(Because of
29557 the way Emacs compares mouse events, you will occasionally wait twice
29558 that time before the window gets selected.\)
29559 Any other value means to autoselect window instantaneously when the
29560 mouse pointer enters it.
29562 Autoselection selects the minibuffer only if it is active, and never
29563 unselects the minibuffer if it is active.
29565 When customizing this variable make sure that the actual value of
29566 `focus-follows-mouse' matches the behavior of your window manager. */);
29567 Vmouse_autoselect_window
= Qnil
;
29569 DEFVAR_LISP ("auto-resize-tool-bars", Vauto_resize_tool_bars
,
29570 doc
: /* Non-nil means automatically resize tool-bars.
29571 This dynamically changes the tool-bar's height to the minimum height
29572 that is needed to make all tool-bar items visible.
29573 If value is `grow-only', the tool-bar's height is only increased
29574 automatically; to decrease the tool-bar height, use \\[recenter]. */);
29575 Vauto_resize_tool_bars
= Qt
;
29577 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p
,
29578 doc
: /* Non-nil means raise tool-bar buttons when the mouse moves over them. */);
29579 auto_raise_tool_bar_buttons_p
= 1;
29581 DEFVAR_BOOL ("make-cursor-line-fully-visible", make_cursor_line_fully_visible_p
,
29582 doc
: /* Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
29583 make_cursor_line_fully_visible_p
= 1;
29585 DEFVAR_LISP ("tool-bar-border", Vtool_bar_border
,
29586 doc
: /* Border below tool-bar in pixels.
29587 If an integer, use it as the height of the border.
29588 If it is one of `internal-border-width' or `border-width', use the
29589 value of the corresponding frame parameter.
29590 Otherwise, no border is added below the tool-bar. */);
29591 Vtool_bar_border
= Qinternal_border_width
;
29593 DEFVAR_LISP ("tool-bar-button-margin", Vtool_bar_button_margin
,
29594 doc
: /* Margin around tool-bar buttons in pixels.
29595 If an integer, use that for both horizontal and vertical margins.
29596 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
29597 HORZ specifying the horizontal margin, and VERT specifying the
29598 vertical margin. */);
29599 Vtool_bar_button_margin
= make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN
);
29601 DEFVAR_INT ("tool-bar-button-relief", tool_bar_button_relief
,
29602 doc
: /* Relief thickness of tool-bar buttons. */);
29603 tool_bar_button_relief
= DEFAULT_TOOL_BAR_BUTTON_RELIEF
;
29605 DEFVAR_LISP ("tool-bar-style", Vtool_bar_style
,
29606 doc
: /* Tool bar style to use.
29608 image - show images only
29609 text - show text only
29610 both - show both, text below image
29611 both-horiz - show text to the right of the image
29612 text-image-horiz - show text to the left of the image
29613 any other - use system default or image if no system default.
29615 This variable only affects the GTK+ toolkit version of Emacs. */);
29616 Vtool_bar_style
= Qnil
;
29618 DEFVAR_INT ("tool-bar-max-label-size", tool_bar_max_label_size
,
29619 doc
: /* Maximum number of characters a label can have to be shown.
29620 The tool bar style must also show labels for this to have any effect, see
29621 `tool-bar-style'. */);
29622 tool_bar_max_label_size
= DEFAULT_TOOL_BAR_LABEL_SIZE
;
29624 DEFVAR_LISP ("fontification-functions", Vfontification_functions
,
29625 doc
: /* List of functions to call to fontify regions of text.
29626 Each function is called with one argument POS. Functions must
29627 fontify a region starting at POS in the current buffer, and give
29628 fontified regions the property `fontified'. */);
29629 Vfontification_functions
= Qnil
;
29630 Fmake_variable_buffer_local (Qfontification_functions
);
29632 DEFVAR_BOOL ("unibyte-display-via-language-environment",
29633 unibyte_display_via_language_environment
,
29634 doc
: /* Non-nil means display unibyte text according to language environment.
29635 Specifically, this means that raw bytes in the range 160-255 decimal
29636 are displayed by converting them to the equivalent multibyte characters
29637 according to the current language environment. As a result, they are
29638 displayed according to the current fontset.
29640 Note that this variable affects only how these bytes are displayed,
29641 but does not change the fact they are interpreted as raw bytes. */);
29642 unibyte_display_via_language_environment
= 0;
29644 DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height
,
29645 doc
: /* Maximum height for resizing mini-windows (the minibuffer and the echo area).
29646 If a float, it specifies a fraction of the mini-window frame's height.
29647 If an integer, it specifies a number of lines. */);
29648 Vmax_mini_window_height
= make_float (0.25);
29650 DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows
,
29651 doc
: /* How to resize mini-windows (the minibuffer and the echo area).
29652 A value of nil means don't automatically resize mini-windows.
29653 A value of t means resize them to fit the text displayed in them.
29654 A value of `grow-only', the default, means let mini-windows grow only;
29655 they return to their normal size when the minibuffer is closed, or the
29656 echo area becomes empty. */);
29657 Vresize_mini_windows
= Qgrow_only
;
29659 DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist
,
29660 doc
: /* Alist specifying how to blink the cursor off.
29661 Each element has the form (ON-STATE . OFF-STATE). Whenever the
29662 `cursor-type' frame-parameter or variable equals ON-STATE,
29663 comparing using `equal', Emacs uses OFF-STATE to specify
29664 how to blink it off. ON-STATE and OFF-STATE are values for
29665 the `cursor-type' frame parameter.
29667 If a frame's ON-STATE has no entry in this list,
29668 the frame's other specifications determine how to blink the cursor off. */);
29669 Vblink_cursor_alist
= Qnil
;
29671 DEFVAR_BOOL ("auto-hscroll-mode", automatic_hscrolling_p
,
29672 doc
: /* Allow or disallow automatic horizontal scrolling of windows.
29673 If non-nil, windows are automatically scrolled horizontally to make
29674 point visible. */);
29675 automatic_hscrolling_p
= 1;
29676 DEFSYM (Qauto_hscroll_mode
, "auto-hscroll-mode");
29678 DEFVAR_INT ("hscroll-margin", hscroll_margin
,
29679 doc
: /* How many columns away from the window edge point is allowed to get
29680 before automatic hscrolling will horizontally scroll the window. */);
29681 hscroll_margin
= 5;
29683 DEFVAR_LISP ("hscroll-step", Vhscroll_step
,
29684 doc
: /* How many columns to scroll the window when point gets too close to the edge.
29685 When point is less than `hscroll-margin' columns from the window
29686 edge, automatic hscrolling will scroll the window by the amount of columns
29687 determined by this variable. If its value is a positive integer, scroll that
29688 many columns. If it's a positive floating-point number, it specifies the
29689 fraction of the window's width to scroll. If it's nil or zero, point will be
29690 centered horizontally after the scroll. Any other value, including negative
29691 numbers, are treated as if the value were zero.
29693 Automatic hscrolling always moves point outside the scroll margin, so if
29694 point was more than scroll step columns inside the margin, the window will
29695 scroll more than the value given by the scroll step.
29697 Note that the lower bound for automatic hscrolling specified by `scroll-left'
29698 and `scroll-right' overrides this variable's effect. */);
29699 Vhscroll_step
= make_number (0);
29701 DEFVAR_BOOL ("message-truncate-lines", message_truncate_lines
,
29702 doc
: /* If non-nil, messages are truncated instead of resizing the echo area.
29703 Bind this around calls to `message' to let it take effect. */);
29704 message_truncate_lines
= 0;
29706 DEFVAR_LISP ("menu-bar-update-hook", Vmenu_bar_update_hook
,
29707 doc
: /* Normal hook run to update the menu bar definitions.
29708 Redisplay runs this hook before it redisplays the menu bar.
29709 This is used to update submenus such as Buffers,
29710 whose contents depend on various data. */);
29711 Vmenu_bar_update_hook
= Qnil
;
29713 DEFVAR_LISP ("menu-updating-frame", Vmenu_updating_frame
,
29714 doc
: /* Frame for which we are updating a menu.
29715 The enable predicate for a menu binding should check this variable. */);
29716 Vmenu_updating_frame
= Qnil
;
29718 DEFVAR_BOOL ("inhibit-menubar-update", inhibit_menubar_update
,
29719 doc
: /* Non-nil means don't update menu bars. Internal use only. */);
29720 inhibit_menubar_update
= 0;
29722 DEFVAR_LISP ("wrap-prefix", Vwrap_prefix
,
29723 doc
: /* Prefix prepended to all continuation lines at display time.
29724 The value may be a string, an image, or a stretch-glyph; it is
29725 interpreted in the same way as the value of a `display' text property.
29727 This variable is overridden by any `wrap-prefix' text or overlay
29730 To add a prefix to non-continuation lines, use `line-prefix'. */);
29731 Vwrap_prefix
= Qnil
;
29732 DEFSYM (Qwrap_prefix
, "wrap-prefix");
29733 Fmake_variable_buffer_local (Qwrap_prefix
);
29735 DEFVAR_LISP ("line-prefix", Vline_prefix
,
29736 doc
: /* Prefix prepended to all non-continuation lines at display time.
29737 The value may be a string, an image, or a stretch-glyph; it is
29738 interpreted in the same way as the value of a `display' text property.
29740 This variable is overridden by any `line-prefix' text or overlay
29743 To add a prefix to continuation lines, use `wrap-prefix'. */);
29744 Vline_prefix
= Qnil
;
29745 DEFSYM (Qline_prefix
, "line-prefix");
29746 Fmake_variable_buffer_local (Qline_prefix
);
29748 DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay
,
29749 doc
: /* Non-nil means don't eval Lisp during redisplay. */);
29750 inhibit_eval_during_redisplay
= 0;
29752 DEFVAR_BOOL ("inhibit-free-realized-faces", inhibit_free_realized_faces
,
29753 doc
: /* Non-nil means don't free realized faces. Internal use only. */);
29754 inhibit_free_realized_faces
= 0;
29757 DEFVAR_BOOL ("inhibit-try-window-id", inhibit_try_window_id
,
29758 doc
: /* Inhibit try_window_id display optimization. */);
29759 inhibit_try_window_id
= 0;
29761 DEFVAR_BOOL ("inhibit-try-window-reusing", inhibit_try_window_reusing
,
29762 doc
: /* Inhibit try_window_reusing display optimization. */);
29763 inhibit_try_window_reusing
= 0;
29765 DEFVAR_BOOL ("inhibit-try-cursor-movement", inhibit_try_cursor_movement
,
29766 doc
: /* Inhibit try_cursor_movement display optimization. */);
29767 inhibit_try_cursor_movement
= 0;
29768 #endif /* GLYPH_DEBUG */
29770 DEFVAR_INT ("overline-margin", overline_margin
,
29771 doc
: /* Space between overline and text, in pixels.
29772 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
29773 margin to the character height. */);
29774 overline_margin
= 2;
29776 DEFVAR_INT ("underline-minimum-offset",
29777 underline_minimum_offset
,
29778 doc
: /* Minimum distance between baseline and underline.
29779 This can improve legibility of underlined text at small font sizes,
29780 particularly when using variable `x-use-underline-position-properties'
29781 with fonts that specify an UNDERLINE_POSITION relatively close to the
29782 baseline. The default value is 1. */);
29783 underline_minimum_offset
= 1;
29785 DEFVAR_BOOL ("display-hourglass", display_hourglass_p
,
29786 doc
: /* Non-nil means show an hourglass pointer, when Emacs is busy.
29787 This feature only works when on a window system that can change
29788 cursor shapes. */);
29789 display_hourglass_p
= 1;
29791 DEFVAR_LISP ("hourglass-delay", Vhourglass_delay
,
29792 doc
: /* Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
29793 Vhourglass_delay
= make_number (DEFAULT_HOURGLASS_DELAY
);
29795 #ifdef HAVE_WINDOW_SYSTEM
29796 hourglass_atimer
= NULL
;
29797 hourglass_shown_p
= 0;
29798 #endif /* HAVE_WINDOW_SYSTEM */
29800 DEFSYM (Qglyphless_char
, "glyphless-char");
29801 DEFSYM (Qhex_code
, "hex-code");
29802 DEFSYM (Qempty_box
, "empty-box");
29803 DEFSYM (Qthin_space
, "thin-space");
29804 DEFSYM (Qzero_width
, "zero-width");
29806 DEFVAR_LISP ("pre-redisplay-function", Vpre_redisplay_function
,
29807 doc
: /* Function run just before redisplay.
29808 It is called with one argument, which is the set of windows that are to
29809 be redisplayed. This set can be nil (meaning, only the selected window),
29810 or t (meaning all windows). */);
29811 Vpre_redisplay_function
= intern ("ignore");
29813 DEFSYM (Qglyphless_char_display
, "glyphless-char-display");
29814 Fput (Qglyphless_char_display
, Qchar_table_extra_slots
, make_number (1));
29816 DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display
,
29817 doc
: /* Char-table defining glyphless characters.
29818 Each element, if non-nil, should be one of the following:
29819 an ASCII acronym string: display this string in a box
29820 `hex-code': display the hexadecimal code of a character in a box
29821 `empty-box': display as an empty box
29822 `thin-space': display as 1-pixel width space
29823 `zero-width': don't display
29824 An element may also be a cons cell (GRAPHICAL . TEXT), which specifies the
29825 display method for graphical terminals and text terminals respectively.
29826 GRAPHICAL and TEXT should each have one of the values listed above.
29828 The char-table has one extra slot to control the display of a character for
29829 which no font is found. This slot only takes effect on graphical terminals.
29830 Its value should be an ASCII acronym string, `hex-code', `empty-box', or
29831 `thin-space'. The default is `empty-box'.
29833 If a character has a non-nil entry in an active display table, the
29834 display table takes effect; in this case, Emacs does not consult
29835 `glyphless-char-display' at all. */);
29836 Vglyphless_char_display
= Fmake_char_table (Qglyphless_char_display
, Qnil
);
29837 Fset_char_table_extra_slot (Vglyphless_char_display
, make_number (0),
29840 DEFVAR_LISP ("debug-on-message", Vdebug_on_message
,
29841 doc
: /* If non-nil, debug if a message matching this regexp is displayed. */);
29842 Vdebug_on_message
= Qnil
;
29844 DEFVAR_LISP ("redisplay--all-windows-cause", Vredisplay__all_windows_cause
,
29846 Vredisplay__all_windows_cause
29847 = Fmake_vector (make_number (100), make_number (0));
29849 DEFVAR_LISP ("redisplay--mode-lines-cause", Vredisplay__mode_lines_cause
,
29851 Vredisplay__mode_lines_cause
29852 = Fmake_vector (make_number (100), make_number (0));
29856 /* Initialize this module when Emacs starts. */
29861 CHARPOS (this_line_start_pos
) = 0;
29863 if (!noninteractive
)
29865 struct window
*m
= XWINDOW (minibuf_window
);
29866 Lisp_Object frame
= m
->frame
;
29867 struct frame
*f
= XFRAME (frame
);
29868 Lisp_Object root
= FRAME_ROOT_WINDOW (f
);
29869 struct window
*r
= XWINDOW (root
);
29872 echo_area_window
= minibuf_window
;
29874 r
->top_line
= FRAME_TOP_MARGIN (f
);
29875 r
->total_lines
= FRAME_LINES (f
) - 1 - FRAME_TOP_MARGIN (f
);
29876 r
->total_cols
= FRAME_COLS (f
);
29878 m
->top_line
= FRAME_LINES (f
) - 1;
29879 m
->total_lines
= 1;
29880 m
->total_cols
= FRAME_COLS (f
);
29882 scratch_glyph_row
.glyphs
[TEXT_AREA
] = scratch_glyphs
;
29883 scratch_glyph_row
.glyphs
[TEXT_AREA
+ 1]
29884 = scratch_glyphs
+ MAX_SCRATCH_GLYPHS
;
29886 /* The default ellipsis glyphs `...'. */
29887 for (i
= 0; i
< 3; ++i
)
29888 default_invis_vector
[i
] = make_number ('.');
29892 /* Allocate the buffer for frame titles.
29893 Also used for `format-mode-line'. */
29895 mode_line_noprop_buf
= xmalloc (size
);
29896 mode_line_noprop_buf_end
= mode_line_noprop_buf
+ size
;
29897 mode_line_noprop_ptr
= mode_line_noprop_buf
;
29898 mode_line_target
= MODE_LINE_DISPLAY
;
29901 help_echo_showing_p
= 0;
29904 #ifdef HAVE_WINDOW_SYSTEM
29906 /* Platform-independent portion of hourglass implementation. */
29908 /* Cancel a currently active hourglass timer, and start a new one. */
29910 start_hourglass (void)
29912 struct timespec delay
;
29914 cancel_hourglass ();
29916 if (INTEGERP (Vhourglass_delay
)
29917 && XINT (Vhourglass_delay
) > 0)
29918 delay
= make_timespec (min (XINT (Vhourglass_delay
),
29919 TYPE_MAXIMUM (time_t)),
29921 else if (FLOATP (Vhourglass_delay
)
29922 && XFLOAT_DATA (Vhourglass_delay
) > 0)
29923 delay
= dtotimespec (XFLOAT_DATA (Vhourglass_delay
));
29925 delay
= make_timespec (DEFAULT_HOURGLASS_DELAY
, 0);
29929 extern void w32_note_current_window (void);
29930 w32_note_current_window ();
29932 #endif /* HAVE_NTGUI */
29934 hourglass_atimer
= start_atimer (ATIMER_RELATIVE
, delay
,
29935 show_hourglass
, NULL
);
29939 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
29942 cancel_hourglass (void)
29944 if (hourglass_atimer
)
29946 cancel_atimer (hourglass_atimer
);
29947 hourglass_atimer
= NULL
;
29950 if (hourglass_shown_p
)
29954 #endif /* HAVE_WINDOW_SYSTEM */